I found an iptables rule on an answer on ServerFault and thought that it included a good idea.
In general, when you open a port, you do so with a rule as follow:
-A INPUT -p tcp -m tcp --dport 80 --syn -j ACCEPT
This allows connection to port 80, usually an HTTP server.
That rule actually included an additional check like so:
-A INPUT -p tcp -m tcp ! --sport 0-1023 --dport 80 --syn -j ACCEPT
What this says, is that if the source port is between 0 and 1023 (a reserved port) then don't allow the connection.
I think that would apply to all services I possibly have, so I was thinking that I could just drop any incoming packet with a source port between 0 and 1023:
-A INPUT -p tcp -m tcp --sport 0-1023 -j DROP
-A INPUT -p udp -m udp --sport 0-1023 -j DROP
This causes problems with the DNS since it may use a source port of 53 between the primary and secondary. Easy enough, I can open that service before these two rules. A more complete set of rules would then be:
-A INPUT -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT
-A INPUT -p tcp -m tcp --sport 0-1023 -j DROP
-A INPUT -p udp -m udp --sport 0-1023 -j DROP
-A INPUT -p tcp -m tcp --dport 80 --syn -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 --syn -j ACCEPT
-A INPUT -p tcp -m tcp --dport XXX --syn -j ACCEPT # any additional services benefit from the DROP of ports 0 to 1023
Will such a setup unwittingly block packets that would otherwise be legal? To me, it doesn't seem to be the case. However, I think I can see invalid packets with such source. I'm thinking that when my server connects to another server (say it does a wget ...
), then I may end up with a broken established/related reply and thus semi-legal packet (which would anyway get drop). Is that correct? Because if so, I do not want to block those source IP addresses. i.e. instead of just using -j DROP
, I want to use the recent
extension and save the packet in a set, then any further communication from that IP address gets dropped immediately--but if such packets can come from what was legal traffic, then I don't want to block that IP address at all.
For reference, this is done this way:
-A INPUT -m recent --update --name denylist --seconds 3600 -j DROP
-A INPUT -m recent --remove --name denylist
...
-A INPUT -p tcp -m tcp --sport 0-1023 -j add_to_denylist
-A INPUT -p udp -m udp --sport 0-1023 -j add_to_denylist
...
And the add_to_denylist
chain is just one rule like so:
-A add_to_denylist -m recent --set --name denylist -j DROP