Just a couple of examples of simple iptables rules for fun and profit.
This was tested on RHEL 6.
See the chapter on iptables in the Red Hat Enterprise Linux (RHEL) Security Guide here. If using a different version of RHEL or Fedora, be sure to check any doc specific to the distribution and version.
The iptables utility is used to manage the packet filter rules for the Linux kernel. By default RHEL is only configured to allow access to port 22 (ssh). Everything else is blocked.
Note that the default, at least on RHEL, is that anything not explicitly permitted is excluded.
To restrict access to port 636 to all but two specific IP addresses (say, an application server and your workstation):
iptables -I INPUT -p tcp -m tcp -s 192.168.4.20 --dport 636 -j ACCEPT iptables -I INPUT -p tcp -m tcp -s 10.2.11.67 --dport 636 -j ACCEPT
The above assumes you don’t have any “DROP” or “REJECT” rules otherwise allowing or rejecting access to port 636. Note that adding the subnet mask for an address (e.g. 192.168.4.0/16), will be interpreted as a direction to allow access to a subnet.
A note on syntax: when issuing an iptables command, take “-I” to mean “Insert at top”, while “-A” means “Append”. Because most tables will have their exclusionary rules at the bottom you’ll want to use the “-I” switch when creating new exceptions. Some manual adjustment may be needed later on for clarity or to tune firewall behavior.
To save the configuration so it survives the next reboot:
The actual file would look something like this:
# Generated by iptables-save v1.4.7 on Mon Feb 25 15:17:41 2013 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [38:11824] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -s 192.168.4.20 -p tcp -m tcp --dport 636 -j ACCEPT -A INPUT -s 10.2.11.67 -p tcp -m tcp --dport 636 -j ACCEPT -A INPUT -s 172.16.0.0/16 -p tcp -m tcp --dport 636 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT # Completed on Mon Feb 25 15:17:41 2013
In the table above those lines beginning with “-A” are “Added” to the table at their location (recall that the command used to created them employed the “-I”, or “Insert”, switch). I did manually edit this table a bit for clarity.
That third “-s” directive above allows access to any host on the 172.16.0.0/16 network.
Note that the iptables-save command can be run without piping to a file to see what would be written.
The above is tidied up a bit from the raw output of iptables-save. In particular I moved the ACCEPT statements for those two specific hosts to put them just after the ACCEPT for the lo interface.
To effect changes made directly to the file simply bounce the iptables service. On RHEL 6:
service iptables restart
Notice that new rules are added to the top of the file by default. Remember this when you’re creating DROP or REJECT rules. If you want to avoid trouble move those to the bottom of the rule list so your ACCEPT rules will take precedence (you could also add your blocking rules first, if you plan that far ahead — my own preference is to edit the tables file directly and then apply). For example, take a look at this:
-A INPUT -s 192.168.4.20 -p tcp -m tcp --dport 636 -j ACCEPT -A INPUT -s 10.2.11.67 -p tcp -m tcp --dport 636 -j ACCEPT -A INPUT -s 172.16.0.0/16 -p tcp -m tcp --dport 636 -j ACCEPT -A INPUT -p tcp -m tcp --dport 636 -j DROP
Everything will work fine so long as you remember to allow first, deny after.
Google around a bit and you’ll find even more.