Practice
Please run the following command:
ifconfig
Before you start creating a new set of rules, you may want to flush out the default rules and any existing rules. Use the IPtables flush command as shown below to do this.
iptables -F (or) iptables --flush
The default chain policy is ACCEPT. Change this to DROP for all the INPUT, FORWARD, and OUTPUT chains, as shown below.
iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP
When you set both the INPUT and the default OUTPUT chain policy to DROP, for every firewall rule requirement you have, you'll need to define two rules. i.e. one for incoming and one for outgoing.
In all of our examples below, we have two rules for every scenario, since we've set DROP as the default policy for both the input and output chains.
If you trust your internal users, you can omit the last line above. i.e. don't DROP all outgoing packets by default. In that case, for every firewall rule requirement you have, you only need to define a single rule. i.e. define a rule only for incoming, and let outgoing be ACCEPT for all packets.
Before we move on to other examples, if you want to block a specific IP address, you should do it first, as shown below. Change "XXXX" in the following example to the specific IP address you want to block.
BLOCK_THIS_IP="XXXX" iptables -A INPUT -s "$BLOCK_THIS_IP" -j DROP
This is useful when you've found some strange activity from a specific IP address in your log files, and you want to temporarily block that IP address while you do further research.
Alternatively, you can use one of the following options, which blocks only TCP traffic on eth0 connections for that IP address.
iptables -A INPUT -i eth0 -s "$BLOCK_THIS_IP" -j DROP iptables -A INPUT -i eth0 -p tcp -s "$BLOCK_THIS_IP" -j DROP
The following rules allow all incoming SSH connections on the eth0 interface.
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
The following rules allow an incoming SSH connection only from the 192.168.100.X network.
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
In the example above, instead of /24, you can also use the full subnet mask. i.e. "192.168.100.0/255.255.255.0".
The following rules allow all incoming web traffic. i.e. HTTP traffic on port 80.
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
The following rules allow all incoming secure web traffic. i.e. HTTPS traffic on port 443.
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
When you allow incoming connections from the outside world to several ports, instead of writing a separate rule for every port, you can combine them together using the multiport extension, as shown below.
The following example allows all incoming SSH, HTTP and HTTPS traffic.
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
The following rules allow outgoing SSH connections. i.e. when you SSH out from inside to an external server.
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
Please note that this is slightly different from the incoming rule. i.e. we allow both the NEW and ESTABLISHED state on the output chain, and only the ESTABLISHED state on the input chain. For the incoming rule, it's the reverse.
The following rules allow an outgoing SSH connection only to a specific network. i.e. you can SSH only to the 192.168.100.0/24 network from the inside.
iptables -A OUTPUT -o eth0 -p tcp -d 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
The following rules allow outgoing secure web traffic. This is useful if you want internet traffic for your users. On servers, these rules are also useful if you want to use Wget to download files from outside.
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
Note: For outgoing HTTP web traffic, add two more rules as shown above, and change 443 to 80.
You can also load-balance your incoming internet traffic using Iptables firewall rules.
This uses the IPtables nth extension. In the following example, the load is balanced for HTTPS traffic across three different IP addresses. For every 3rd packet, it load-balances to the corresponding server (using a counter of 0).
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 0 -j DNAT --to-destination 192.168.1.101:443 iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 1 -j DNAT --to-destination 192.168.1.102:443 iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 2 -j DNAT --to-destination 192.168.1.103:443
The following rules allow external users to be able to ping your server.
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
The following rules allow you to ping any external servers from the inside.
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
You should allow full loopback access on your servers. i.e. access using 127.0.0.1
iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT
On a firewall server, where one network card is connected to the outside and another network card is connected to the internal servers, use the following rules to let the internal network talk to the external network.
In this example, eth1 is connected to the external network (Internet), and eth0 is connected to the internal network (e.g., 192.168.1.x).
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
The following rules allow outbound DNS connections.
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
If you're running NIS to manage user accounts, you need to allow NIS connections. Even if the SSH connection is allowed, if you don't allow the appropriate ypbind NIS connections, users won't be able to log in.
NIS ports are dynamic. i.e. when ypbind starts, it allocates ports.
First, run rpcinfo -p as shown below to get the port numbers. In this example, it uses ports 853 and 850.
rpcinfo -p | grep ypbind
Now allow the incoming connection to port 111, as well as the ports used by ypbind.
iptables -A INPUT -p tcp --dport 111 -j ACCEPT iptables -A INPUT -p udp --dport 111 -j ACCEPT iptables -A INPUT -p tcp --dport 853 -j ACCEPT iptables -A INPUT -p udp --dport 853 -j ACCEPT iptables -A INPUT -p tcp --dport 850 -j ACCEPT iptables -A INPUT -p udp --dport 850 -j ACCEPT
The above won't work after ypbind restarts, since it will have different port numbers each time.
There are two solutions to this: 1) Use a static IP address for NIS, or 2) Use some clever shell scripting to automatically capture the dynamic port number from the output of the "rpcinfo -p" command, and use it in the Iptables rules above.
The following rules allow Rsync only from a specific network.
iptables -A INPUT -i eth0 -p tcp -s 192.168.101.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT
If you're running MySQL, you typically don't want to allow a direct connection from outside. In most cases, you'll have a web server running on the same server as the MySQL database.
However, DBAs and developers may need to log into MySQL directly from their laptop or desktop using a MySQL client. In that case, you can allow your internal network to talk to MySQL directly, as shown below.
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 3306 -m state --state ESTABLISHED -j ACCEPT
The following rules allow mail traffic. This could be Sendmail or Postfix.
iptables -A INPUT -i eth0 -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
The following rules allow IMAP/IMAP2 traffic.
iptables -A INPUT -i eth0 -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT
The following rules allow IMAPS traffic.
iptables -A INPUT -i eth0 -p tcp --dport 993 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 993 -m state --state ESTABLISHED -j ACCEPT
The following rules allow POP3 access.
iptables -A INPUT -i eth0 -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT
The following rules allow POP3S access.
iptables -A INPUT -i eth0 -p tcp --dport 995 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 995 -m state --state ESTABLISHED -j ACCEPT
The following Iptables rule will help you prevent a denial-of-service (DoS) attack on your web server.
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
In the example above:
The following example routes all traffic arriving on port 422 to port 22. This means an incoming SSH connection can come in via both port 22 and port 422.
iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to 192.168.102.37:22
If you use the above, you also need to explicitly allow incoming connections on port 422.
iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT
You can also log all dropped packets. These rules should be at the bottom.
First, create a new logging chain.
iptables -N LOGGING
Next, make sure all remaining incoming connections jump to the LOGGING chain, as shown below.
iptables -A INPUT -j LOGGING
Next, log these packets by specifying a custom "log-prefix".
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: " --log-level 7
And finally, drop these packets.
iptables -A LOGGING -j DROP
Comments