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.
If you wish to send mail through a corporate mail server, you can use a VPN to bypass these restrictions. This would require running a VPN client on your Compute Engine node, and a VPN server on your corporate network router. This would allow your Compute Engine node to appear "inside" your corporate firewall, and allow unrestricted access to your corporate mail server. There are security implications for this configuration, and you should ensure that your Compute Engine node only has access to the services it requires, and nothing more.
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:
- 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.
If you sign up for SendGrid without using the partner page linked above, the free usage tier has much lower limits of 200 messages per day (approximately 6,000 messages per month).
After 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 SMTP 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.
-
ssh into your instances:
$ gcloud compute ssh INSTANCE
-
Become a superuser and set a safe umask:
user@test-wheezy:~$ sudo su - root@test-wheezy:~# umask 077
-
Install the Postfix Mail Transport Agent. When prompted, accept the default choices for domain names but select the
Local Onlyconfiguration.root@test-wheezy:~# apt-get update 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.
-
Create a file named
/etc/postfix/sasl_passwdcontaining the credentials to be used for authentication. It should be a single line with[smtp.sendgrid.net]:2525followed 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
Note: Remember that SendGrid uses port 2525; port 25 is blocked by default on Compute Engine and cannot be used for sending email.
-
Use the
postmaputility to generate a.dbfile 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
-
Edit
/etc/postfix/main.cfand comment out the following lines:default_transport = error relay_transport = error
Next, add the following bolded lines to the file:
# See /usr/share/postfix/main.cf.dist for a commented, more complete version # Debian specific: Specifying a file name will cause the first # line of that file to be used as the name. The Debian default # is /etc/mailname. #myorigin = /etc/mailname smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) biff = no # appending .domain is the MUA's job. append_dot_mydomain = no # Uncomment the next line to generate "delayed mail" warnings #delay_warning_time = 4h readme_directory = no # TLS parameters smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key smtpd_use_tls=yes smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache # See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for # information on enabling SSL in the smtp client. myhostname = test-wheezy.c.example-project.internal alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases myorigin = /etc/mailname mydestination = test-wheezy.c.example-project.internal, localhost.c.example-project.internal, localhost relayhost = mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 mailbox_size_limit = 0 recipient_delimiter = + inet_interfaces = loopback-only #default_transport = error #relay_transport = error smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = noanonymous smtp_tls_security_level = encrypt header_size_limit = 4096000 relayhost = [smtp.sendgrid.net]:2525Save your changes.
- Make sure your SASL authentication libraries are up-to-date:
root@test-wheezy:~# apt-get install libsasl2-modules
-
Reload Postfix to pick up the configuration changes:
root@test-wheezy:~# postfix reload postfix/postfix-script: refreshing the Postfix mail system
-
Test that mail delivery is working by sending a message to an external address (replace
EMAIL@EXAMPLE.COMwith 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=sentand the successful server response code (250). -
Remove your
sasl_passwdfile.Because you no longer need this file to create your
.dbfile, remove this file.root@test-wheezy:~# rm -f /etc/postfix/sasl_passwd
-
ssh into your instance:
$ gcloud compute ssh INSTANCE
-
Become a superuser and set a safe umask:
[user@test-centos ~]$ sudo su - [root@test-centos ~]# umask 077
-
Create a file named
/etc/postfix/sasl_passwdcontaining the credentials to be used for authentication. It should be a single line with[smtp.sendgrid.net]:2525followed 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
Note: Remember that SendGrid uses port 2525; port 25 is blocked by default on Compute Engine and cannot be used for sending email.
-
Use the
postmaputility to generate a.dbfile 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
-
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 = hash:/etc/postfix/sasl_passwd smtp_sasl_security_options = noanonymous smtp_tls_security_level = encrypt header_size_limit = 4096000 relayhost = [smtp.sendgrid.net]:2525 EOF
- Make sure your authentication libraries are up-to-date:
[root@test-centos ~]# yum install cyrus-sasl-plain
-
Reload Postfix to pick up the configuration changes:
[root@test-centos ~]# postfix reload postfix/postfix-script: refreshing the Postfix mail system
-
You should be all set. Test that mail delivery is working by sending a message to an external address (replace
EMAIL@EXAMPLE.COMwith 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=sentand the successful server response code (250). -
Remove your
sasl_passwdfile.Because you no longer need this file to create your
.dbfile, 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.
-
ssh into your instance:
$ gcloud compute ssh INSTANCE
-
Become a superuser and set a safe umask:
user@test-wheezy:~$ sudo su - root@test-wheezy:~# umask 077
-
Update your package repositories:
root@test-wheezy:~# sudo apt-get update
-
Install Node.js dependencies:
root@test-wheezy:~# sudo apt-get install git-core curl build-essential openssl libssl-dev -y
-
Clone Node.js repo from github:
root@test-wheezy:~# git clone https://github.com/joyent/node.git
-
Change directory to the Node.js source tree:
root@test-wheezy:~# cd node
-
Configure node software for this OS and virtual machine:
root@test-wheezy:~# ./configure
-
Build Node.js, npm, and related objects:
root@test-wheezy:~# make
-
Install Node.js, npm, and other software in the default location:
root@test-wheezy:~# sudo make install
-
Install the mailer package:
root@test-wheezy:~# npm install mailer
-
In the node directory, create a new file named
sendmail.jsfile 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); } }); -
Execute the program to send an email message through SendGrid:
root@test-wheezy:~# node sendmail
- ssh into your instance:
$ gcloud compute ssh INSTANCE
-
Become a superuser and set a safe umask:
user@test-centos:~$ sudo su - root@test-centos:~# umask 077
-
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
-
Install Node.js dependencies:
root@test-centos:~# yum install git-core curl openssl openssl-dev -y ... root@test-centos:~# yum groupinstall "Development Tools" ...
-
Clone Node.js repository from github:
root@test-centos:~# git clone https://github.com/joyent/node.git
-
Change directory to the Node.js source tree:
root@test-centos:~# cd node
-
Configure node software for this OS and virtual machine:
root@test-centos:~# ./configure
-
Build Node.js, npm, and related objects:
root@test-centos:~# make
-
Install Node.js, npm, and other software in the default location:
root@test-centos:~# sudo make install
-
Install the mailer package:
root@test-centos:~# npm install mailer
-
In the node directory, create a new file named
sendmail.jsfile 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); } }); -
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.