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:
- 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.
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 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.
-
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
-
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
-
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 myhostname = <yourHostName> mydomain = <yourDomainName>
Save your changes.
-
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 protected]
with your own address):root@test-wheezy:~# printf 'Subject: test\r\n\r\npassed' | sendmail [email protected] 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=<[email protected]> Aug 13 07:44:55 sendgrid postfix/qmgr[17926]: 5CB31B6: from=<[email protected]>, size=325, nrcpt=1 (queue active) Aug 13 07:44:56 sendgrid postfix/smtp[18764]: 5CB31B6: to=<[email protected]>, 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
). -
Remove your
sasl_passwd
file.Because you no longer need this file to create your
.db
file, 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_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
-
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
-
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
-
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 protected]
with your own address):[root@test-centos ~]# echo test | mail -s test [email protected] [root@test-centos ~]# tail -n 5 /var/log/maillog Aug 13 08:10:23 sendgridcentos postfix/cleanup[2167]: D043824EE: message-id=<[email protected]> Aug 13 08:10:23 sendgridcentos postfix/qmgr[2160]: D043824EE: from=<[email protected]>, size=454, nrcpt=1 (queue active) Aug 13 08:10:24 sendgridcentos postfix/smtp[2169]: D043824EE: to=<[email protected]>, 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
). -
Remove your
sasl_passwd
file.Because 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("[email protected]")); 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.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 protected]', 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.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 protected]', 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.