I've had a bit of help but I'm still a bit unsure. I have an nginx webserver with SSH only required. I wrote this rule set based on information I found on the internet:


# Flush all rules
$i -F
$i -X

# Setup default filter policy

$i -A INPUT -i lo -j ACCEPT
$i -A INPUT -p icmp --icmp-type any -j ACCEPT

# Force SYN checks
$i -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# Drop all fragments
$i -A INPUT -f -j DROP

# Drop XMAS packets
$i -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# Drop NULL packets
$i -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# Allow established connections

# Allow unlimited traffic on loopback
$i -A INPUT -i lo -j ACCEPT
$i -A OUTPUT -o lo -j ACCEPT

# Open nginx
$i -A INPUT -p tcp --dport 443 -j ACCEPT
$i -A INPUT -p tcp --dport 80 -j ACCEPT

# Open SSH
$i -A INPUT -p tcp --dport 22 -j ACCEPT

Can anyone please tell me if I am taking the right approach here, and if I can improve it in any way?


Scripts should have a shebang line. If you happen to be running in a shell other than 'sh' or compoatible, then this script will fail. Add:


as the very first line.

The rest of the script looks fine enough.

The script has a duplicate declaration:

$i -A INPUT -i lo -j ACCEPT

That line says that, if the computer is talking to itself (on the lo interface , the 'localhost'...), that it is allowed to listen to itself.

The other line:

$i -A INPUT -p icmp --icmp-type any -j ACCEPT

says that the computer will listen and respond to 'ping' requests.

The computer will also allow the two standard webserver ports (http and https) but that assumes your webserver is running on those ports.

Also allowed is ssh (port 22).

In essence, the script is doing what you need. You have a server that can listen on the standard http, https and ssh ports only on the public interfaces. You can also ping it.

What is unusual is the very restrictive outbound rules. This is nice, if you can live with it, but, for example, your computer will not be able to connect to anything else, so, it cannot use:

  • NTP
  • DNS
  • send mail
  • ping other computers
  • ssh out
  • etc.

It is recommended practice to have a default-DROP policy for OUTPUT, but, in practice, I have seen very few servers that actually do that.... it is hard to live with.

  • \$\begingroup\$ You should make sure that your web-server logging does not try to log host names instead of IP addresses for the web logs, as the names will not resolve and will be very slow \$\endgroup\$
    – rolfl
    Jun 6 '14 at 12:26
  • \$\begingroup\$ Is this only because I don't have the DNS outbound? \$\endgroup\$
    – Jimmy
    Jun 6 '14 at 12:28
  • \$\begingroup\$ That is the primary reason I mentioned it though. I would actually recommend allowing outbound connections to DNS servers. Consider: stackoverflow.com/a/11487142/1305253 which shows how to accept both in and out bound DNS requests on UDP. You need this because you need to DNS response too \$\endgroup\$
    – rolfl
    Jun 6 '14 at 12:49

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.