Postfix
smtp Vs smtpd
- postfix/smtp
- The SMTP daemon is for sending emails to the Internet (outgoing mail server).
- postfix/smtpd
- The SMTP daemon is for receiving emails from the Internet (incoming mail server).
TLS
Encryption on mail transport is what we call: opportunistic. If both parties (sender’s outgoing mail server & recipient’s incoming mail server) agree to exchange encryption keys, then a secure connection may be used. Otherwise a plain connection will be established. Plain as in non-encrypted aka cleartext over the wire.
SMTP - Outgoing Traffic
In the begging there where only three options in postfix:
- none
- may
- encrypt
The default option on a Centos 6x is none:
# postconf -d | grep smtp_tls_security_level smtp_tls_security_level =
Nowadays, postfix supports more options, like:
- dane
- verify
- secure
Here is the basic setup, to enable TLS on your outgoing mail server:
smtp_tls_security_level = may smtp_tls_loglevel = 1
From postfix v2.6 and later, can you disable weak encryption by selecting the cipher suite and protocols you prefer to use:
smtp_tls_ciphers = export smtp_tls_protocols = !SSLv2, !SSLv3
You can also define where the file that holds all the root certificates on your linux server is, and thus to verify the certificate that provides an incoming mail server:
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
I dont recommend to go higher with your setup, cause (unfortunately) not everyone is using TLS on their incoming mail server!
SMTPD - Incoming Traffic
To enable TLS in your incoming mail server, you need to provide some encryption keys aka certificates!
I use letsencrypt on my server and the below notes are based on that.
Let’s Encrypt
A quick explanation on what exists on your letsencrypt folder:
# ls -1 /etc/letsencrypt/live/example.com/ privkey.pem ===> You Private Key cert.pem ===> Your Certificate chain.pem ===> Your Intermediate fullchain.pem ===> Your Certificate with Your Intermediate
Postfix
Below you can find the most basic configuration setup you need for your incoming mail server.
smtpd_tls_ask_ccert = yes smtpd_tls_security_level = may smtpd_tls_loglevel = 1
Your mail server is asking for a certificate so that a trusted TLS connection can be established between outgoing and incoming mail server.
The servers must exchange certificates and of course, verify them!
Now, it’s time to present your own domain certificate to the world. Offering only your public certificate cert.pem isnt enough. You have to offer both your certificate and the intermediate’s certificate, so that the sender’s mail server can verify you, by checking the digital signatures on those certificates.
smtpd_tls_cert_file = /etc/letsencrypt/live/example.com/fullchain.pem smtpd_tls_key_file = /etc/letsencrypt/live/example.com/privkey.pem smtpd_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt smtpd_tls_CApath = /etc/pki/tls/certs
CAfile & CApath helps postfix to verify the sender’s certificate by looking on your linux distribution file, that holds all the root certificates.
And you can also disable weak ciphers and protocols:
smtpd_tls_ciphers = high smtpd_tls_exclude_ciphers = aNULL, MD5, EXPORT smtpd_tls_protocols = !SSLv2, !SSLv3
Logs
Here is an example from gmail:
SMTPD - Incoming Mail from Gmail
You can see that there is a trusted TLS connection established From google:
Jun 4 11:52:07 kvm postfix/smtpd[14150]: connect from mail-oi0-x236.google.com[2607:f8b0:4003:c06::236] Jun 4 11:52:08 kvm postfix/smtpd[14150]: Trusted TLS connection established from mail-oi0-x236.google.com[2607:f8b0:4003:c06::236]: TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits) Jun 4 11:52:09 kvm postfix/smtpd[14150]: 4516420F32: client=mail-oi0-x236.google.com[2607:f8b0:4003:c06::236] Jun 4 11:52:10 kvm postfix/smtpd[14150]: disconnect from mail-oi0-x236.google.com[2607:f8b0:4003:c06::236]
SMTP - Outgoing Mail from Gmail
And this is the response To gmail :
Jun 4 12:01:32 kvm postfix/smtpd[14808]: initializing the server-side TLS engine Jun 4 12:01:32 kvm postfix/smtpd[14808]: connect from example.com[2a00:1838:20:1::XXXX:XXXX] Jun 4 12:01:33 kvm postfix/smtpd[14808]: setting up TLS connection from example.com[2a00:1838:20:1::XXXX:XXXX] Jun 4 12:01:33 kvm postfix/smtpd[14808]: example.com[2a00:1838:20:1::XXXX:XXXX]: TLS cipher list "aNULL:-aNULL:ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH:!aNULL:!MD5:!EXPORT:!aNULL" Jun 4 12:01:33 kvm postfix/smtpd[14808]: Anonymous TLS connection established from example.com[2a00:1838:20:1::XXXX:XXXX]: TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits) Jun 4 12:01:35 kvm postfix/smtpd[14808]: disconnect from example.com[2a00:1838:20:1::XXXX:XXXX]
As you can see -In both cases (sending/receiving)- the mail servers have established a trusted secure TLSv1.2 connection.
The preferred cipher (in both scenarios) is : ECDHE-RSA-AES128-GCM-SHA256
IPv6
Tell postfix to prefer ipv6 Vs ipv4 and use TLS if two mail servers support it !
#IPv6 smtp_address_preference = ipv6
So … it seems that some router gives dhcp ipv6 prefixes for specific lans.
The default behaviour of CentOS is to autoconfigure the network interface with ifup script.
We havent finished our #ipv6 schema/deployment so we need to disable this ipv6 autoconfigure feature.
global
# vim /etc/sysconfig/network
NETWORKING_IPV6=no
IPV6FORWARDING=no
IPV6_AUTOCONF=no
interface
# vim /etc/sysconfig/network-scripts/ifcfg-eth0
IPV6INIT=no
Flushing
# ip -6 addr flush eth0
# ip -6 route flush scope global
and finally restart
# service restart network
Although it feels really lonely … not a lot content yet.
All you need is an ISP that gives you an IPv6 address space, pppd and some free time !
You need to find out that your CPE can work like a modem so that PPPoE can pass through.
Point-to-Point Protocol Daemon
/etc/ppp/peers/ipv6
+ipv6 ipv6cp-use-ipaddr
noip
-chap
defaultroute
usepeerdns
mtu 1492
# debugging
debug
dump
# authentication
name “USERNAME@DOMAIN.gr”
hide-password
noauth
# device
plugin rp-pppoe.so
eth0
The noip means no IPv4 ip
+ipv6 means IPv6
” If the ipv6cp-use-ipaddr option is given, the local identifier is the local IPv4 address “
You should replace the USERNAME & DOMAIN according your credentials.
you need to edit /etc/ppp/pap-secrets to add your password for your account:
USERNAME@DOMAIN.gr * PASSWORD
ip6tables
/etc/iptables/ip6tables.rules
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
COMMIT
Be aware that IPv6 will give/configure your network device, through ICMPv6 router advertisements, so you MUST fix your firewall
IPv6 DNS
If your ISP doesnt provide you with IPv6 DNS servers, edit your /etc/resolv.conf to add opendns servers:
2620:0:ccc::2
2620:0:ccd::2
Connect
# pon ipv6
Plugin rp-pppoe.so loaded.
RP-PPPoE plugin version 3.8p compiled against pppd 2.4.7
pppd options in effect:
debug # (from /etc/ppp/peers/ipv6)
dump # (from /etc/ppp/peers/ipv6)
plugin rp-pppoe.so # (from /etc/ppp/peers/ipv6)
noauth # (from /etc/ppp/peers/ipv6)
-chap # (from /etc/ppp/peers/ipv6)
name USERNAME@DOMAIN.gr # (from /etc/ppp/peers/ipv6)
eth0 # (from /etc/ppp/peers/ipv6)
eth0 # (from /etc/ppp/peers/ipv6)
asyncmap 0 # (from /etc/ppp/options)
mtu 1492 # (from /etc/ppp/peers/ipv6)
lcp-echo-failure 4 # (from /etc/ppp/options)
lcp-echo-interval 30 # (from /etc/ppp/options)
hide-password # (from /etc/ppp/peers/ipv6)
noip # (from /etc/ppp/peers/ipv6)
defaultroute # (from /etc/ppp/peers/ipv6)
proxyarp # (from /etc/ppp/options)
usepeerdns # (from /etc/ppp/peers/ipv6)
+ipv6 # (from /etc/ppp/peers/ipv6)
noipx # (from /etc/ppp/options)
Networking
# clear ; ip -6 a && ip -6 r
the result:
1: lo:
mtu 65536
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: ppp0:mtu 1492 qlen 3
inet6 2a02:580:31a:0:744e:f2f1:bc63:dbdd/64 scope global mngtmpaddr dynamic
valid_lft 3465sec preferred_lft 2865sec
inet6 fe80::744e:f2f1:bc63:dbdd/10 scope link
valid_lft forever preferred_lft forever
2a02:580:31a::/64 dev ppp0 proto kernel metric 256 expires 3464sec
fe80::/10 dev ppp0 metric 1
fe80::/10 dev ppp0 proto kernel metric 256
default via fe80::90:1a00:1a0:80be dev ppp0 proto ra metric 1024 expires 1664sec
Verify
http://ipv6-test.com/ipv6-test
It was time for me to start using the #IPv6.
My VPS hosting provider: edis have already allocated me a
2a01:7a0:10:158:255:214:14:0/112
and some extra info
Gateway:
2a01:7a0:10::1
Nameserver:
2a03:f80:ed15:ed15:ed15:ed15:d8b9:da76
2a03:f80:ed15:ca7:ea75:b12d:7b0:3e5b
I have two network cards (I run my own AUTH-NS server and some greek registrars require two different IPs for that).
I have split up the above /112 to two /113 subnets.
2a01:7a0:10:158:255:214:14::/113
2a01:7a0:10:158:255:214:14:8000/113
My settings are based on CentOS 6.6 as the time of this article.
Part Zero: kernel
First thing first, tell kernel to support ipv6 by editing: /etc/sysctl.conf
comment (if there is) the below line:
# net.ipv6.conf.all.disable_ipv6=1
This mean that next time you reboot your machine, ipv6 will be enabled.
There is another way, if you dont want to reboot your vps, by running as root:
sysctl net.ipv6.conf.all.disable_ipv6=0
Part One: Network
Edit your ifcfg-eth* files:
/etc/sysconfig/network-scripts/ifcfg-eth0
IPV6INIT=yes
IPV6ADDR=2a01:7a0:10:158:255:214:14::/123
IPV6ADDR_SECONDARIES=”2a01:7a0:10:158:255:214:14:80/123”
IPV6_DEFAULTGW=2a01:7a0:10::1
/etc/sysconfig/network-scripts/ifcfg-eth1
IPV6INIT=yes
IPV6ADDR=2a01:7a0:10:158:255:214:14:8000/113
IPV6_DEFAULTGW=2a01:7a0:10::1
PLZ dont get confused about eth0. I will circle back to this.
Restart your network:
/etc/init.d/network restart
and verify your network settings:
ip -6 a
ip -6 r
Part Two: Firewall
My default policy is DROP everything and open only the ports you are running services.
Same rule applies for IPv6 too.
:INPUT DROP [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -j REJECT –reject-with icmp6-adm-prohibited
:FORWARD DROP [0:0]
-A FORWARD -j REJECT –reject-with icmp6-adm-prohibited
:OUTPUT ACCEPT [0:0]
At this moment, i only accept PING6 to my VPS server.
Testing this from another machine (with ipv6 support):
ping6 -c3 2a01:7a0:10:158:255:214:14::
and the result is something like this:
PING 2a01:7a0:10:158:255:214:14::(2a01:7a0:10:158:255:214:14:0) 56 data bytes
64 bytes from 2a01:7a0:10:158:255:214:14:0: icmp_seq=1 ttl=60 time=72.5 ms
64 bytes from 2a01:7a0:10:158:255:214:14:0: icmp_seq=2 ttl=60 time=66.9 ms
64 bytes from 2a01:7a0:10:158:255:214:14:0: icmp_seq=3 ttl=60 time=66.3 ms— 2a01:7a0:10:158:255:214:14:: ping statistics —
3 packets transmitted, 3 received, 0% packet loss, time 2067ms
rtt min/avg/max/mdev = 66.355/68.618/72.573/2.822 ms
At this point we are very happy with our selfs (ipv6 related)!
Part Three: Web Server
What’s the point of having an ipv6 server and not apply some services on ?
Lets start with the apache web server.
I’ve split up my eth0 to /123 subnets cause i want to use different IPs for every service i have.
Thats way my eth0 is like that.
I chose the 2a01:7a0:10:158:255:214:14:80 as my ipv6 ip for my site.
Our web server needs to listen to ipv6.
This is tricky cause apache on ipv6 is using : as a delimiter.
So my http changes are something like these:
Listen 158.255.214.14:80
Listen [2a01:7a0:10:158:255:214:14:80]:80
to support virtual hosts:
NameVirtualHost 158.255.214.14:80
NameVirtualHost [2a01:7a0:10:158:255:214:14:80]:80
To dual stack my site:
‹ VirtualHost 158.255.214.14:80 [2a01:7a0:10:158:255:214:14:80]:80 ›
restart your apache:
/etc/init.d/httpd restart
Dont forget to manipulate your firewall settings:
-A INPUT -m state –state NEW -m tcp -p tcp -d 2a01:7a0:10:158:255:214:14:80/123 –dport 80 -j ACCEPT
restart your firewall:
/etc/init.d/ip6tables restart
Part Four: DNS
The only thing that is left for us to do, is to add a AAAA resource record in our dns zone:
in my bind-file format zone: balaskas.gr
@ IN AAAA 2a01:7a0:10:158:255:214:14:80
you have to increment the SERIAL number in your zone and then reload your zone.
I use PowerDNS so it’s:
# pdns_control reload balaskas.gr
Ok
Part Five: Validate
To validate your dual stack web site, you use go through:
UPDATE: 2015 03 23
Part Six: Mail Server
Imap Server
I use dovecot for imap server. To enable IPv6 in dovecot is really easy. You just uncomment or edit Listen parameter:
listen = *, ::
restart dovecot service and check the dovecot conf:
# doveconf | grep ^listen
listen = *, ::
I use STARTTLS, so my firewall settings should be like these:
-A INPUT -m state –state NEW -m tcp -p tcp -d 2a01:7a0:10:158:255:214:14::/112 –dport 143 -j ACCEPT
Just dont forget to restart and verify your ip6table !
SMTP Server
It’s really easy for postfix (my SMTP server) too. You just have to remember that you need to use brackets for [b]IPv6[/url].
## mynetworks = 127.0.0.0/8 158.255.214.14/31
mynetworks = 127.0.0.0/8 158.255.214.14/31 [2a01:7a0:10:158:255:214:14::]/112## inet_protocols = ipv4
inet_protocols = all
restart your smtp service and you are OK.
Firewall settings: /etc/sysconfig/ip6tables
-A INPUT -m state –state NEW -m tcp -p tcp -d 2a01:7a0:10:158:255:214:14::/112 –dport 25 -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp -d 2a01:7a0:10:158:255:214:14::/112 –dport 587 -j ACCEPT