Search code examples
linuxiptables

iptables --sport vs --dport. INPUT vs OUTPUT


I am having some trouble understanding iptables. I know it acts as a filter but something isn't clicking because it isn't working the way I think it should. Let me start by saying that I'm creating a white list, so all policies (INPUT, FORWARD, OUTPUT) default to DROP.

I have the following rules related to SMTP:

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p tcp --dport 25 -j ACCEPT -A OUTPUT -p tcp --dport 25 -j ACCEPT //needed for receiving? -A OUTPUT -p tcp --sport 25 -j ACCEPT //needed for sending?

*these 3 lines also exist verbatim for ports 587 & 465

If I remove the first OUTPUT line then my server won't receive emails & if I remove the last line it won't send emails. What I don't understand is why. Shouldn't:

-A INPUT -p tcp --dport 25 -j ACCEPT -A OUTPUT -p tcp --sport 25 -j ACCEPT

be enough to let everything through? AFAIK all SMTP communication should go over 25, 587 or 465. My current understanding says an SMTP packet should always match one of these two rules. All input packets should come to port 25, and all output packets be sent from 25? What am I missing?


Solution

  • For SMTP you don't need any --sport rule. The source and destination don't depend on direction - they're match on the packet's source and destination ports. Every connection will have a random source port, so there's nothing to match on.

    If I remove the first OUTPUT line then my server won't receive emails & if I remove the last line it won't send emails.

    This is wrong. Only the INPUT line matters for receiving emails. Also, only the OUTPUT --dport 25 line matters for sending emails. So these rules should be enough:

    -A INPUT -p tcp --dport 25 -j ACCEPT
    -A OUTPUT -p tcp --dport 25 -j ACCEPT
    

    The problem may be that you set OUTPUT to default to DROP, but allowed established connection on INPUT only. Usually people leave OUTPUT defaulting to ACCEPT. If you want to continue using a whitelist for OUTPUT, you'll have to add:

    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    

    Also, please read up on SMTP ports. Some of those you listed are only needed for email submissions and deprecated encryption, not for server-to-server communication. This may change how you plan your rules.