I have a mail server which I'd like to secure by only allowing OUTBOUND connections on the various ports it uses. The inbound rules are working fine - they are handled by the VM host.

I've not been able to find out much about this, and while the script below almost works, it's dropping packets, for example here for port 993:

Mar 25 16:08:11 lorina kernel: [200590.714226] IPTables-Dropped: IN= OUT=ens18 SRC=[local IP here] DST=[remote IP here] LEN=148 TOS=0x00 PREC=0x00 TTL=64 ID=37253 DF PROTO=TCP SPT=993 DPT=14826 WINDOW=243 RES=0x00 ACK PSH FIN URGP=0

Here's the script. Note that ens19 is the LAN interface (which I'd like to keep open), and ens18 is the WAN.

iptables -A OUTPUT -o lo -p all -j ACCEPT
iptables -A OUTPUT -o ens19 -p all -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp -m owner --uid-owner systemd-timesync -j ACCEPT

ip6tables -A OUTPUT -o lo -p all -j ACCEPT
ip6tables -A OUTPUT -p icmpv6 -j ACCEPT
ip6tables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport 53 -j ACCEPT
ip6tables -A OUTPUT -p udp --dport 53 -j ACCEPT
ip6tables -A OUTPUT -p udp -m owner --uid-owner systemd-timesync -j ACCEPT

while read h; do
        ip6tables -A OUTPUT -m conntrack --ctstate NEW -d $h -j ACCEPT &> /dev/null
        iptables -A OUTPUT -m conntrack --ctstate NEW -d $h -j ACCEPT
done < /usr/local/etc/hosts-to-allow.list

while read p; do
        ip6tables -A OUTPUT -m conntrack --ctstate NEW -p tcp --dport $p -j ACCEPT
        iptables -A OUTPUT -m conntrack --ctstate NEW -p tcp --dport $p -j ACCEPT
done < /usr/local/etc/ports-to-allow.list

ip6tables -A OUTPUT -o ens18 -j LOGGING
ip6tables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
iptables -A OUTPUT -o ens18 -j LOGGING
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4

iptables -A OUTPUT -o ens18 -j REJECT
ip6tables -A OUTPUT -o ens18 -j REJECT

Interesting footnote

The dropped packets from these rules may be normal and I'm still seeing them occasionally. An explanation was provided for this by user Doug S on the Ubuntu Support Forums:

Your log line example is for a packet that is not "NEW". You can tell from the TCP flags at the end of the line.

My best guess it that this is a lingering packet from an already closed and forgotten TCP session, otherwise it would have traversed the RELATED,ESTABLISHED path.

This happens a lot with iptables, depending on your router and/or other stuff in the packets travels. Why? Because for TCP connections, Linux tends to use a "half-duplex" close sequence where either side of the session can initiate connection termination via a single 2 way FIN-ACK handshake (which puts the connection into the CLOSE_WAIT state), instead of a full 4 way FIN-ACK handshake.

Always observe the flags to know for sure what is going on. I think you are O.K.

So far in today's /var/log/syslog file I have 115 entries that end in "RES=0x00 ACK FIN URGP=0", and 93 of those are from my LAN.

  • I tried removing the -m conntrack --ctstate NEW condition on the allowed ports, thinking that may have been restrictive, but it seems to have made no difference. Perhaps it's not a port-related rule that's causing a problem? Mar 25, 2019 at 17:40
  • Your intention is unclear, and the script seems very flawed to me. do you have an incoming rule allowing established traffic? Is thus machine a mail client or server? I suspect that you may not realise you cant treat inckming and outgoing rules as unrelated as a tcp connection requires both. Its also not clear why you are not limiting on port.
    – davidgo
    Mar 25, 2019 at 18:45
  • is port 14826 on your list of accepted ports?
    – cybernard
    Mar 25, 2019 at 19:14

1 Answer 1


I am guessing your ports-to-allow.list contains port 993, which is why you did not expect the log entry you quoted. Note, however, that you seem to be using the port list for whitelisting destination port whereas your log shows 993 as the source port of the blocked packet.

  • Thanks. I've added both --dport and --sport to the port rules now and I think that may have fixed it. Will monitor a bit more before I'm sure (I thought I'd tried that before and it didn't' work, but maybe I was wrong). Mar 26, 2019 at 7:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.