G Saunders Home Page INFO465 Home Page

Setup a CentOS 7 LAMP Stack at RackSpaceCloud, GoDaddy DNS and CA, Sendmail SMTP and Dovecot IMAP with SSL/TLS

This procedure has details for the above environment, may work in others with some problem-solving. Other OS, virtual hosting providers, domain registrars, or MTA are may be similar but will likely require some problem solving and adjustments for file locations and command dialects...

RackSpace really does a fine job with network and tech support by chat or phone and is a good option for a commercial site. GoDaddy is competitively-priced for trust-worthy SSL Certificates and DNS. Sendmail is used here because the application environment includes several components that parse /var/log/maillog and expect to have Sendmail's syntax -- Postfix is probably a better MTA. Dovecot provides secure IMAP and POP email services in many Linux distros. SSL and TLS need to be installed.

Setting up a secure mail server requires full control over DNS Zone, MX, and TXT/SPF records. RackSpace and GoDaddy provide access to the DNS & Server to make reverse DNS and these features work. So does Digital Ocean and it's half the price of RackSpace. I've been told that Linode is half the price of Digital Ocean but don't know for sure if it support reverse DNS lookup required to get your mail accepted by gmail. Free hosting providers might not allow sufficient control to operate a secure server -- check it out an let me know what you find...

The expensive piece is the SSL Certificate. If you're cheap and brave check out StartSSL or google 'free ssl certificates' and get a more-or-less trusted certificate. If you're OK with telling everybody that uses your site they'll need to add a security exception for it, you can use a self-issued certificate. Most B2B EDI uses self-issued certificates, btw...

Here are the features for this setup:

Here are some big steps:

Purchase your Domain from GoDaddy

You can economize by avoiding .com and .net TLDs. Others like .us, .info, or .me are cheaper. Get something that will be good to reference if anybody asks to see your webwork. Here, I've splurged on fraluca.net...

Hold off on purchasing the SSL certificate for the time-being. Plan on buying it from GoDaddy using the same accounts. This will hasten the delivery of the SSL certificate when you're ready for it. Using the same credit-card for your purchases helps, too.

If you browse to your new domain, pretty soon you'll find that GoDaddy has put up a banner announcing the domain hasn't been hosted quite yet. Leave it there and go to RackSpaceCloud.com and spin up the virtual server.

Setup a Virtual Server w/ CentOS 7

Get an account with RackSpace.com. The smallest CentOS 7 server, will be about $20 per month. Unless you're already familiar with name virtual hosts, plan to name your virtual server exactly the same as the domain purchased from GoDaddy, like fraluca.net is here... The PKI/SSL certificate will be issued for the one named server so it's important to get it right from the start.

On your account page at RackSpace, click Cloud Servers -> Create Server. ServerName is your domain. IAD is fine for the Region, is just up the road from here. Pick Linux, Centos 7, and slide the bar to the smallest 512MB Standard Instance. Click the Create Server button and start watching the clock, will be a little wait and the interface may sit disturbingly idle for several seconds so don't be clicking around...

When the server's ready an alert will show you the password assigned so you can access the command line via ssh. Copy/paste the password that pops up onto a note for next steps and make sure you hold onto it -- there is no recovery mechanism for it so if you klutz it away you'll need to destroy your virtual server and set out anew.

Use an ssh command line client like Putty.exe, Mac's ssh, or Chrome's ssh client to connect to your newly virtualized server. (You _could_ use RackSpace's console for your cloud server to log in, or even to complete the installation. But their Java app is not the best xTerm emulation and may complicate things for a noob...)

Log into your server with user name root and the password from above. Use passwd to set an easier to key, but difficult to guess, password.

Keep in mind, as you work, that the server's likely to be under attack so work quickly and keep your eye on /var/log/messages and /var/log/secure to see the SOBs trying to crack into your system as soon as it appears live on the subnet.

RackSpace's CentOS 7 Distro is 'minimal' and needs to have the packages installed for ssl, web and mail servers.

Cloud servers launch with very restrictive iptables firewall that limits access to practically everything but ssh so web and mail servers won't work. The defaut firewall doesn't filter IPs for port ssh access to port 22, so getting a firewall in place is a good next step.

Firewall It

RackSpace's minimum Centos distro includes a very restrictive firewall that blocks almost everything but port 22, so you can connect to it with ssh but little else. It'll need to be relaxed before you can access your web server. To see the rules in effect do

iptables -L
to flush the firewall completely do
iptables -F

Don't plan to run your server any longer than necessary without the firewall configured for your purposes! Don't leave SSH ports open to the world if you don't need to! It's not uncommon to have vigorous probes and attacks as soon as a new IP address comes up in a cloud! Check it out while you're working:

tail -f /var/log/secure
tail -f /var/log/messages
will show what's going on. Use ctrl-C to stop tailing a log.

Editing and Running the Firewall

Don't run the sample script without changing the IP address to some that you use, or you'll lock yourself out of the server and need to use the dreadful RackSpace Java terminal!

In the /root/ directory make a directory named bin, it's the expected location for binary and other executable code. Use chmod bin 700 to allow only root access to it. Change to it with cd bin, and vi Firewall. In vi's Insert mode, copy/paste the following firewall script. Edit it to suit the IP addresses you'll be using for ssh. (Google 'what is my ip address' to see the one you're using, google on iptables to learn more about the script, google is our friend...)

#Enable routing
#echo 1 > /proc/sys/net/ipv4/ip_forward

#Provide active ftp functionality, this is _not_ starting ftp as a service,
#it lets those behind the firewall use ftp if they need to
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_conntrack_ftp

#Flush tables
/sbin/iptables -F

#Upper ports are opened.  Speeds connections to clients, makes port scans take forever.
/sbin/iptables -A INPUT -p tcp --dport 1023:65535 -s 0/0 -i eth0 -j ACCEPT
/sbin/iptables -A INPUT -p udp --dport 1023:65535 -s 0/0 -i eth0 -j ACCEPT

#Incoming is always OK for established connections 
/sbin/iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
/sbin/iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT

#List IP addresses from where you'll be logging in via SSH port 22, a range might be needed for mobile but is somewhat risky
/sbin/iptables -A INPUT -p tcp --dport 22 -s -i eth0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 22 -s -i eth0 -j ACCEPT

#Other ports we'll accept since we're a web and mail server
/sbin/iptables -A INPUT -p tcp --dport 25 -s 0/0 -i eth0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 80 -s 0/0 -i eth0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 110 -s 0/0 -i lo -j ACCEPT
/sbin/iptables -A INPUT -p udp --dport 123 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 143 -s 0/0 -i lo -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 443 -s 0/0 -i eth0 -j ACCEPT
#/sbin/iptables -A INPUT -p tcp --dport 463 -s 0/0 -i eth0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 465 -s 0/0 -i eth0 -j ACCEPT
#/sbin/iptables -A INPUT -p tcp --dport 585 -s 0/0 -i eth0 -j ACCEPT
#/sbin/iptables -A INPUT -p tcp --dport 587 -s 0/0 -i eth0 -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport 993 -s 0/0 -i eth0 -j ACCEPT
#/sbin/iptables -A INPUT -p tcp --dport 995 -s 0/0 -i eth0 -j ACCEPT

#Uncomment these to receive and reply to ping echo-requests
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT

#Don't reply to anything we didn't accept
#Do log them for study
#This might be too much on a real server without a more stateful firewall than this...
/sbin/iptables -A INPUT -i eth0 -j LOG

#Drop them after logging them
/sbin/iptables -A INPUT -i eth0 -j DROP

Write and quit Firewall. Make the script executable with chmod Firewall 700 and run it from the command line. It should run 'quietly' without any error messages. Test the setup it with iptables -L to list the rules.

When you see Firewall works, reference it in /etc/rc.d/rc.local and make rc.local executable with chmod rc.local 700. This will make Firewall run at boot up. Optionally it may be set up as a service enabled for systemctl at bootup.

Reboot the server and make sure you've got access to it via ssh. If you've noobishly locked yourself out, solve problems with the cloud server's console...

Install components for HTTPS, SMTPS, IMAPS

Centos uses yum - YellowDog Update Manager to install and update most OS software. RPM - RedHat Package Manager is also used, but yum is much more likely to avoid problems with dependencies between software components. Either yum or rpm can install software packages with binary/executable components and usually get them in the right places for your distribution of Linux.

Some software doesn't distribute for either package manager. They may requires steps at the command line like make clean, make configure, and make. This uses gcc and other components to compile the application's binary code from the its original source. Some hard-core admins always compile from source, the rest of us always look for yum or rpms...

The following packages installed by yum supplement the minimal server and ssh from the RackSpace 7 Distro, which includes none of the servers we need. The best strategy for servers is to install the minimum needed to run, then add software necessary and sufficient for the purposes at hand.

The first several, gcc through bind-utils, are tools for making configuration files, dig, and other handy tools for debugging mail servers. The components for ssl are added, will be used for securing the web and mail servers. Sendmail is easiest to configure by using the sendmail-cf package. Dovecot provides IMAP and depends on mailx.

These are likely to install without error...

yum install gcc make automake autoconf libtool bind-utils openssl openssl-devel mod_ssl sendmail sendmail-cf mailx dovecot  

Enable the servers so they'll start at boot time:

systemctl enable sendmail
systemctl enable saslauthd
systemctl enable dovecot
systemctl enable httpd

Reboot and make sure everything's working un-secured before laying in the security...

Use 'systemctl status' and ps -ef to examine the stack for these services...

At this point we Need some demos here: make sure it's working from afar and locally. ping, dig, nslookup, testsaslauthd... Need to show that reverse DNS is not working yet!

Configure Reverse DNS at RackSpace and MX & TXT/SPF at GoDaddy

Without these set you don't stand much chance of getting email from your server accepted at gmail or anywhere else except servers you operate with lax email policy, and why would you want all the spam?

RackSpace's Cloud Server -> Details form has 'Reverse DNS' near the bottom. Click on the link and plug in your server's full name for both the IPv4 and IPv6. Don't disable IPv6, it's a real thing now and not running may set your mail in a spam folder or get it rejected.

Go to your account at GoDaddy and make sure MX records are set up for IPv4 and IPv6, and that the zone file has a TXT entry, aka SPF - Sender Policy Framework or lots of mail servers won't accept your mail or it'll end up in a spam folder. Edit the TXT record and put this in it:

v=spf1 mx -all
DKIM is becoming more important for avoiding the deadly Spammer diagnosis, but gmail doesn't require it yet, so it's not covered here...

Need godaddy screen shots here:

Verify from a command line at another server:

If you don't have another server on-line, or even if you do, use the tools at dnsstuff.com to see how your setup is working...

At this point, the server is set up and should be able to run an unsecure web server. We'll break now and do that, come back and configure/secure web and mail servers later...

Test SMTP from the Command Line

At this point you should be able to use the mail command to send email from your server to your gmail or other email address...

mail -s Test you@your.net
test test test

Use tail -f /var/log/maillog to follow the mail log and see what happens to your Test email...

Configure PKI/TLS/SSL for Web and Mail Servers

From your account at GoDaddy navigate to SSL Certificates and purchase your certificate. It will take some period of time before the certs are issued, usually within a half hour, sometimes in a few minutes. You've got the earlier domain transaction tied to your credit card at GoDaddy and that will count for a lot in GoDaddy's automated investigation into your identity -- there's only so much they can do for $70 so if everything doesn't line up quickly they'll decline to issue the certificate.

[[[Screenshots and narrative]]]

This is all about getting the right certificates in the right place and making sure the references are all right. This demo preserves the structure of /etc/pki/tls but others just stick all the certificates and keys in one place. Either works if the configuration files are accurate.

[[[Need to explain CSR, certs, bundles, ca-trust, contents of the zip file from GoDaddy, those strange @...]]]

To make sendmail.pem while in certs: make sendmail.pem

Note: The asterisks in the following tree listing are only to indicate the certificate files that we needed to edit into place, they should not appear in your tree. Substitute your domain for fraluca.net

[root@fraluca pki]# cd tls
[root@fraluca tls]# tree
├── cert.pem -> /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem 
├── certs
│   ├── ca-bundle.crt -> /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
│   ├── ca-bundle.trust.crt -> /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
│   ├── dovecot.pem  *
│   ├── fraluca.crt  *
│   ├── gd_bundle.crt  *
│   ├── localhost.crt  
│   ├── Makefile  
│   └── sendmail.pem  *
├── misc
│   ├── CA
│   ├── c_hash
│   ├── c_info
│   ├── c_issuer
│   └── c_name
├── openssl.cnf
└── private
    ├── fraluca.key  *
    └── localhost.key

To make dovecot.pem while in certs directory: cat fraluca.key fraluca.crt > dovecot.pem

── dovecot
│   ├── certs
│   │   └── dovecot.pem  *
│   ├── dovecot-openssl.cnf
│   └── private
│       └── dovecot.pem  *

Configure SSL for HTTP

This server has a few non-secure apps on it, so the SSL is setup as a virtual host with all its certificates and keys specified in a VirtualHost directive. Apache is the web server and it's overall configured in /etc/httpd/httpd.conf. Modules that run, like SSL, are configured in /etc/httpd/conf.modules.d/ where the .conf files are executed in alphabetic/numeric order as the httpd is started.

It's probably safest not to mess ithe /etc/httpd/httpd.conf. Instead, additions to the configuration are made in /etc/httpd/conf.modules.

/etc/httpd/conf.modules.d/virtualHostsSSL.conf has been added as below. The file is named with a 'v' to kick it to the end since the configuration files are processed alphabetically:

# Use name-based virtual hosting.

 DocumentRoot /var/www/html

 ServerName fraluca.com
 DocumentRoot /var/www/html

 ServerName info465.info
 DocumentRoot /var/www/html/info465

LoadModule ssl_module modules/mod_ssl.so
Listen 443
 ServerName fraluca.net
 SSLEngine on
 SSLCertificateFile /etc/pki/tls/certs/fraluca.crt
 SSLCertificateChainFile /etc/pki/tls/certs/gd_bundle.crt
 SSLCertificateKeyFile /etc/pki/tls/private/fraluca.key
 SSLCACertificateFile /etc/pki/tls/certs/gd_bundle.crt

Restart httpd with

systemctl restart httpd
and test that your url works with https:// as the protocol. The restart should run quietly, will give errors if debugging is needed...

Configure HTTPD to Force Browsers to SSL:

Edit httpd/conf/httpd.conf to allow overrides

# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
    AllowOverride All

Edit the following into /var/www/html/.htaccess to make it apply to all directories in the web document root. If you're run a mix of secure and non-secure named virtual domains .htaccess needs to be in the directories that need to force SSL.

RewriteEngine on
RewriteCond %{SERVER_PORT} !443$
RewriteRule ^(.*)$ https://thishere1.net:443/$1 [R=301,L]

Restart httpd with systemctl restart httpd and test that your browser's redirected to https with the plain domain name or http:// as the protocol.

Configure Sendmail

Mod /etc/mail/access

Leave this alone unless you want to force mailers to use at least 128 bit encryption. Lots don't, like LLBean, but it's shown commented out

Connect:localhost.localdomain           RELAY
Connect:localhost                       RELAY
Connect:                       RELAY
#TLS_Clt:                        ENCR:128  

If edited, need to makes access.db

Mod /etc/mail/local-host-names

# local-host-names - include all aliases for your machine here.

Mod /etc/mail/sendmail.mc & make sendmail.cf

Edit /etc/mail/sendmail.mc, find the DAEMON_OPTIONS line, comment it out, and replace it with the following line to configure any smtp port to be relayed from outside to localhost. Also comment out the accept_unresolvable_domains to cut way down on spam. Make sure to put a space after any dnl you add, # is not a comment in sendmail.mc, dnl - drop next line is:

dnl DAEMON_OPTIONS(`Port=smtp,Addr=, Name=MTA') dnl 
DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl

dnl #GSX20160819 FEATURE(`accept_unresolvable_domains')dnl

Set Paths to Certificates

Edit /etc/mail/sendmail.mc, find these lines and plug in crt locations.

define(`confCACERT_PATH', `/etc/pki/tls/certs')dnl
define(`confCACERT', `/etc/pki/tls/certs/gd_bundle.crt')dnl
define(`localCERT', `/etc/pki/tls/certs/sendmail.pem')dnl
define(`confSERVER_CERT', `/etc/pki/tls/certs/sendmail.pem')dnl
define(`confSERVER_KEY', `/etc/pki/tls/certs/sendmail.pem')dnl
define(`confCLIENT_CERT', `/etc/pki/tls/certs/sendmail.pem')dnl
define(`confCLIENT_KEY', `/etc/pki/tls/certs/sendmail.pem')dnl
dnl #

Make sendmail.cf with :

make sendmail.cf -C /etc/mail

Restart sendmail and dovecot: systemctl restart sendmail; systemctl restart dovecot

Check status: systemctl status -l sendmail; systemctl status -l dovecot. Fix any errors...

Check status of saslauthd with valid userid and password: testsaslauthd -u theuser -p thepassword. Should say OK, or fix errors.

Configure an email client like Windows or Mac's Mail client, Droid or iPhone' EMail, or Seamonkey to access your server for testing

Setup with user@domain.net, server is domain.net

Incoming: IMAP, port 993, SSL/TLS

Outgoing: SMTP, port 465, SSL/TLS

G Saunders,
Dept of Information Systems
VCU School of Business

G Saunders Wings

Content © 1999 - Today
By G Saunders
Images are Available on the Web