Google Compute Engine

Sending Email from an Instance

Google Compute Engine does not allow outbound connections on ports 25, 465, and 587 but you can still set up your instances to send mail through ports 587 and 465 using servers provided through partner services, such as SendGrid. This document discusses how to set up your instances to send email using SendGrid.

SendGrid is a partner service that provides Google Compute Engine customers with a free or paid SendGrid account that you can use to send mail from Google Compute Engine instances. SendGrid offers a number of advantages:

  • A free tier* to Google Compute Engine customers that includes 25,000 transactional email messages per month
  • Ability to send emails from addresses other than @gmail.com
  • No daily limit on the number of transactional email messages

Prerequisites

Before you can use SendGrid, you must first sign up for the service from SendGrid's Google partner page.* When signing up, provide the domain and email address from which you would like to send email messages. This may or may not be the same domain and email you used to sign up for Google Compute Engine.

If you use an email account that doesn't match your specified domain e.g. a Gmail account, you will need to provide more information to SendGrid before they can provision your account. Complete the sign up process and SendGrid will contact you for more information, if necessary.

Once you have signed up and your account has been provisioned by SendGrid, follow some of the examples below to set up your mail configuration. If you don't see your email solution in this list of examples, SendGrid provides extensive documentation for integration with most common STMP servers, libraries, and frameworks. See SendGrid's documentation for more examples.


Here are the SendGrid-specific SMTP settings that are used to configure clients, for your reference:

  • Host: smtp.sendgrid.net
  • Port: 2525

  • Note that the port is different from the standard port 25 and port 587.

    Postfix

    To set up Postfix on your instances to use SendGrid, follow the instructions below.

    Postfix on Debian Wheezy
    1. ssh into your instances:
      gcutil --project=<project-id> ssh <instance-name>
    2. Become a superuser and set a safe umask:

      user@test-wheezy:~$ sudo su -
      root@test-wheezy:~# umask 077
      
    3. Install the Postfix Mail Transport Agent. When prompted, accept the default choices for domain names but select the Local Only configuration.

      root@test-wheezy:~# apt-get install postfix
      Reading package lists... Done
      Building dependency tree
      Reading state information... Done
      The following extra packages will be installed:
        ssl-cert
      Suggested packages:
        procmail postfix-mysql postfix-pgsql postfix-ldap postfix-pcre sasl2-bin dovecot-common resolvconf postfix-cdb mail-reader ufw postfix-doc openssl-blacklist
      The following NEW packages will be installed:
        postfix ssl-cert
      0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
      Need to get 1611 kB of archives.
      After this operation, 3653 kB of additional disk space will be used.
      Do you want to continue [Y/n]? Y
      
      ...
      
      [ ok ] Stopping Postfix Mail Transport Agent: postfix.
      [ ok ] Starting Postfix Mail Transport Agent: postfix.
      
    4. Create a file named /etc/postfix/sasl_passwd containing the credentials to be used for authentication. It should be a single line with [smtp.sendgrid.net]:2525 followed by your username and password, separated by a colon:

      root@test-wheezy:~# cat > /etc/postfix/sasl_passwd << EOF
      [smtp.sendgrid.net]:2525 YOUR_SENDGRID_USERNAME:YOUR_SENDGRID_PASSWORD
      EOF
      
    5. Use the postmap utility to generate a .db file from the plaintext file you just created:

      root@test-wheezy:~# postmap /etc/postfix/sasl_passwd
      root@test-wheezy:~# ls -l /etc/postfix/sasl_passwd*
      -rw------- 1 root root    68 Jun  1 11:42 /etc/postfix/sasl_passwd
      -rw------- 1 root root 12288 Jun  1 11:42 /etc/postfix/sasl_passwd.db
      
    6. Edit /etc/postfix/main.cf and comment out the following lines:

      default_transport = error
      relay_transport = error

      Next, add the following contents to the file:

      smtp_sasl_auth_enable = yes
      smtp_sasl_password_maps = static:<yourSendGridUsername>:<yourSendGridPassword>
      smtp_sasl_security_options = noanonymous
      smtp_tls_security_level = may
      header_size_limit = 4096000
      relayhost = [smtp.sendgrid.net]:2525
      

      Save your changes.

    7. Reload Postfix to pick up the configuration changes:

      root@test-wheezy:~# postfix reload
      postfix/postfix-script: refreshing the Postfix mail system
      
    8. Test that mail delivery is working by sending a message to an external address (replace EMAIL@EXAMPLE.COM with your own address):

      root@test-wheezy:~# printf 'Subject: test\r\n\r\npassed' | sendmail EMAIL@EXAMPLE.COM
      root@test-wheezy:~# tail -n 5 /var/log/syslog
      Aug 13 07:44:55 sendgrid postfix/pickup[17927]: 5CB31B6: uid=0 from=<root>
      Aug 13 07:44:55 sendgrid postfix/cleanup[18762]: 5CB31B6: message-id=<20130813074455.5CB31B6@sendgrid.c.testproject121.internal>
      Aug 13 07:44:55 sendgrid postfix/qmgr[17926]: 5CB31B6: from=<root@sendgrid.c.myproject.internal>, size=325, nrcpt=1 (queue active)
      Aug 13 07:44:56 sendgrid postfix/smtp[18764]: 5CB31B6: to=<EMAIL@EXAMPLE.COM>, relay=smtp.sendgrid.net[50.97.69.148]:2525, delay=0.66, delays=0.03/0/0.44/0.18, dsn=2.0.0, status=sent (250 Delivery in progress)
      Aug 13 07:44:56 sendgrid postfix/qmgr[17926]: 5CB31B6: removed

      Note the status=sent and the successful server response code (250).

    9. Remove your sasl_passwd file.

      Since you no longer need this file to create your .db file, remove this file.

      root@test-wheezy:~# rm -f /etc/postfix/sasl_passwd
    Postfix on CentOS
    1. ssh into your instance:

      gcutil --project=<project-id> ssh <instance-name>
    2. Become a superuser and set a safe umask:

      [user@test-centos ~]$ sudo su -
      [root@test-centos ~]# umask 077
      
    3. Create a file named /etc/postfix/sasl_passwd containing the credentials to be used for authentication. It should be a single line with [smtp.sendgrid.net]:2525 followed by your SendGrid username and password generated in the previous step, separated by a colon:

      [root@test-centos ~]# cat > /etc/postfix/sasl_passwd << EOF
      [smtp.sendgrid.net]:2525 YOUR_SENDGRID_USERNAME:YOUR_SENDGRID_PASSWORD
      EOF
      
    4. Use the postmap utility to generate a .db file from the plaintext file you just created:

      [root@test-centos ~]# postmap /etc/postfix/sasl_passwd
      [root@test-centos ~]# ls -l /etc/postfix/sasl_passwd*
      -rw------- 1 root root    68 Jun  1 10:50 /etc/postfix/sasl_passwd
      -rw------- 1 root root 12288 Jun  1 10:51 /etc/postfix/sasl_passwd.db
      
    5. Append the following block of configuration to the end of /etc/postfix/main.cf:

      [root@test-centos ~]# cat >> /etc/postfix/main.cf << EOF
      smtp_sasl_auth_enable = yes
      smtp_sasl_password_maps = static:<yourSendGridUsername>:<yourSendGridPassword>
      smtp_sasl_security_options = noanonymous
      smtp_tls_security_level = may
      header_size_limit = 4096000
      relayhost = [smtp.sendgrid.net]:2525
      EOF
      EOF
      
    6. Reload Postfix to pick up the configuration changes:

      [root@test-centos ~]# postfix reload
      postfix/postfix-script: refreshing the Postfix mail system
      
    7. You should be all set. Test that mail delivery is working by sending a message to an external address (replace EMAIL@EXAMPLE.COM with your own address):

      [root@test-centos ~]# echo test | mail -s test EMAIL@EXAMPLE.COM
      [root@test-centos ~]# tail -n 5 /var/log/maillog
      Aug 13 08:10:23 sendgridcentos postfix/cleanup[2167]: D043824EE: message-id=<20130813081023.D043824EE@sendgridcentos.localdomain>
      Aug 13 08:10:23 sendgridcentos postfix/qmgr[2160]: D043824EE: from=<root@sendgridcentos.localdomain>, size=454, nrcpt=1 (queue active)
      Aug 13 08:10:24 sendgridcentos postfix/smtp[2169]: D043824EE: to=<EMAIL@EXAMPLE.COM>, relay=smtp.sendgrid.net[75.126.83.211]:2525, delay=0.91, delays=0.08/0.24/0.41/0.18, dsn=2.0.0, status=sent (250 Delivery in progress)
      Aug 13 08:10:24 sendgridcentos postfix/qmgr[2160]: D043824EE: removed
      ...
      

      Note the status=sent and the successful server response code (250).

    8. Remove your sasl_passwd file.

      Since you no longer need this file to create your .db file, remove this file.

      root@test-centos:~# rm -f /etc/postfix/sasl_password

    Java

    The following Java sample uses the javax.mail library to construct and send an email message through SendGrid. The lines in bold are settings for your SendGrid account.

    import java.util.Properties;
    
    import javax.mail.Authenticator;
    import javax.mail.BodyPart;
    import javax.mail.Message;
    import javax.mail.Multipart;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeBodyPart;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMultipart;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class SendGridDemoHandler extends HttpServlet {
    
      @Override
      public void doPost(HttpServletRequest request, HttpServletResponse response) {
        System.out.println(getClass().getResource("/javax/mail/Address.class"));
        try {
          send(request);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    
      private static final String SMTP_HOST_NAME = "smtp.sendgrid.net";
      private static final String SMTP_AUTH_USER = "<YOUR_SENDGRID_USERNAME>";
      private static final String SMTP_AUTH_PWD = "<YOUR_SENDGRID_PASSWORD>";
      private static final int SMTP_PORT = 2525;
    
      private void send(HttpServletRequest request) throws Exception {
        Properties props = new Properties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.auth", "true");
    
        Authenticator auth = new SMTPAuthenticator();
        Session mailSession = Session.getDefaultInstance(props, auth);
        Transport transport = mailSession.getTransport();
    
        MimeMessage message = new MimeMessage(mailSession);
    
        Multipart multipart = new MimeMultipart("alternative");
    
        // Sets up the contents of the email message
        BodyPart part1 = new MimeBodyPart();
        part1.setText(request.getParameter("Message"));
    
        multipart.addBodyPart(part1);
    
        message.setContent(multipart);
        message.setFrom(new InternetAddress("me@yourdomain.com"));
        message.setSubject(request.getParameter("Subject"));
        message.addRecipient(
            Message.RecipientType.TO, new InternetAddress(request.getParameter("To")));
    
        // Sends the email
        transport.connect(SMTP_HOST_NAME, SMTP_PORT, SMTP_AUTH_USER, SMTP_AUTH_PWD);
        transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
        transport.close();
      }
    
      // Authenticates to SendGrid
      private class SMTPAuthenticator extends javax.mail.Authenticator {
        @Override
        public PasswordAuthentication getPasswordAuthentication() {
          String username = SMTP_AUTH_USER;
          String password = SMTP_AUTH_PWD;
          return new PasswordAuthentication(username, password);
        }
      }
    }

    node.js

    The following instructions describe how to use SendGrid with node.js on Debian Wheezy and CentOS.

    Debian Wheezy
    1. ssh into your instance:
      gcutil --project=<project-id> ssh <instance-name>
    2. Become a superuser and set a safe umask:
      user@test-wheezy:~$ sudo su -
      root@test-wheezy:~# umask 077
    3. Update your package repositories:
      root@test-wheezy:~# sudo apt-get update
    4. Install node.js dependencies:
      root@test-wheezy:~# sudo apt-get install git-core curl build-essential openssl libssl-dev -y
    5. Clone node.js repo from github:
      root@test-wheezy:~# git clone https://github.com/joyent/node.git
    6. Change directory to the node.js source tree:
      root@test-wheezy:~# cd node
    7. Configure node software for this OS and virtual machine:
      root@test-wheezy:~# ./configure
    8. Build node.js, npm, and related objects:
      root@test-wheezy:~# make
    9. Install node.js, npm, and other software in the default location:
      root@test-wheezy:~# sudo make install
    10. Install the mailer package:
      root@test-wheezy:~# npm install mailer
    11. In the node directory, create a new file named sendmail.js file containing the following Javascript:
      var email = require('mailer');
      
      email.send({
          host: 'smtp.sendgrid.net',
          port : '2525',
          domain: 'smtp.sendgrid.net',
          authentication: 'login',
          username: '<YOUR_SENDGRID_USERNAME>',
          password: '<YOUR_SENDGRID_PASSWORD>',
          to : 'EMAIL@EXAMPLE.COM',
          from : 'ANOTHER_EMAIL@ANOTHER_EXAMPLE.COM',
          subject : 'test email from node.js on a Compute Engine VM',
          body : 'Hello!\n\nThis a test email from node.js on a VM.',
        },
        // Callback function in case of error.
        function(err, result){
          if(err){ console.log(err); }
        });
    12. Execute the program to send an email message through SendGrid:
      root@test-wheezy:~# node sendmail
      
    CentOS
    1. ssh into your instance:
      gcutil --project=<project-id> ssh <instance-name>
    2. Become a superuser and set a safe umask:
      user@test-centos:~$ sudo su -
      root@test-centos:~# umask 077
    3. Update package repositories:
      root@test-centos:~# yum update
      ...
      Install       9 Package(s)
      Upgrade     218 Package(s)
      
      Total download size: 124 M
      Is this ok [y/N]: y
    4. Install node.js dependencies:
      root@test-centos:~# yum install git-core curl openssl openssl-dev -y
      ...
      root@test-centos:~# yum groupinstall "Development Tools"
      ...
    5. Clone node.js repository from github:
      root@test-centos:~# git clone https://github.com/joyent/node.git
    6. Change directory to the node.js source tree:
      root@test-centos:~# cd node
    7. Configure node software for this OS and virtual machine:
      root@test-centos:~# ./configure
    8. Build node.js, npm, and related objects:
      root@test-centos:~# make
    9. Install node.js, npm, and other software in the default location:
      root@test-centos:~# sudo make install
    10. Install the mailer package:
      root@test-centos:~# npm install mailer
    11. In the node directory, create a new file named sendmail.js file containing the following Javascript:
      var email = require('mailer');
      
      email.send({
          host: 'smtp.sendgrid.net',
          port : '2525',
          domain: 'smtp.sendgrid.net',
          authentication: 'login',
          username: '<YOUR_SENDGRID_USERNAME>',
          password: '<YOUR_SENDGRID_PASSWORD>',
          to : 'EMAIL@EXAMPLE.COM',
          from : 'ANOTHER_EMAIL@ANOTHER_EXAMPLE.COM',
          subject : 'test email from node.js on a Compute Engine VM',
          body : 'Hello!\n\nThis a test email from node.js on a VM.',
        },
        // Callback function in case of error.
        function(err, result){
          if(err){ console.log(err); }
        });
    12. Execute the program to send an email message through SendGrid:
      root@test-centos:~# node sendmail
      
    * Google will be compensated for customers who sign up for a non-free account.

    Authentication required

    You need to be signed in with Google+ to do that.

    Signing you in...

    Google Developers needs your permission to do that.