I am installing a fresh new VPS (from linode.com, if that matters) with Ubuntu 16.04 LTS. I wrote the following script for iptables:


iptables -F

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

iptables -A INPUT -i eth0 -p tcp -m multiport --dports 22,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m multiport --sports 22,80,443 -m state --state ESTABLISHED -j ACCEPT

iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
iptables -A FORWARD -j DROP

This script should only allow 22, 80 and 443. It also allows outgoing DNS resolves.

I created and named this script iptables.sh as root and put it in /etc/network/if-pre-up.d. I did also chmod +x.

Now, after reboot, this script does not seem to be applied. I verified this by executing iptables -S, which gives:


How do I progress from here? I am quite stuck right now.


I have no idea why, but after renaming uptables.sh to iptables, I cannot log in into my server anymore after a reboot. This makes me think that now the script is actually executed (and when it has .sh file extension not, why?) during boot and there is an error in my script. I am so confused.

  • "I cannot log in into my server anymore after a reboot". I think the line iptables -A OUTPUT -o eth0 -p tcp -m multiport --dports 22,80,443… should use --sports, because in OUTPUT you want to allow response from port 22 etc. Notice UDP/53 has dport/sport rules corresponding to each other, not dport/dport nor sport/sport. – Kamil Maciorowski Nov 20 '17 at 21:32
  • Oh, ofcourse! I will try again, THANKS A LOT for that tip. – Dave Teezo Nov 20 '17 at 21:33
  • This not working :(. I updated the script in my question, so its clears what my current version is. – Dave Teezo Nov 20 '17 at 21:40
  • Are you sure the interface is eth0? Modern Ubuntu may use something like enpXsY. Why is my network interface named enp0s25 instead of eth0? – Kamil Maciorowski Nov 20 '17 at 21:48
  • It's indeed eth0 in my case. I verified by running ifconfig, which gives eth0 and lo. – Dave Teezo Nov 20 '17 at 21:50

NEW is by itself and RELATED,ESTABLISHED go together. When you connect via ssh the destination maybe port 22, but the source port is random that is why rule #2 in output does function as expected.

iptables -I INPUT 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -I OUTPUT 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Once these rules are in place your DNS request are part of the RELATED,ESTABLISHED traffic and you can delete your port 53 references.

  • I appreciate your feedback. I don't think it's a good idea to do such things on all ports? Also, shouldn't it be something like NEW, ESTABLISHED for the to flow and ESTABLISHED, RELATED for the from flow? – Dave Teezo Nov 21 '17 at 9:05
  • I also don't understand your remark regarding 53. Isn't an outgoing DNS resolve a NEW request? – Dave Teezo Nov 21 '17 at 9:30
  • @DaveTeezo You can allow OUTBOUND port 53, but INPUT 53 is handled by RELATED,ESTABLISHED. RELATED,ESTABLISHED on all ports is a lot easier than trying to do it per service. Also the packet has to make it through the OUTPUT chain to become RELATED,ESTABLISHED, so if you block the connection in the OUTPUT chain it will never become RELATED or ESTABLISHED. – cybernard Nov 21 '17 at 12:53

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.