Iptables Configuration
To list existing rules type the following command(as root):
$ iptables -L
If it wasn't previously configured, output should be:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Which, in short words, means "accept everything" or that firewall isn't active.
Let's configure firewall to accept only the traffic we need and then save it.
Basic commands:
-I
-Insert
rule(it would be first)-A
-Append
rule(it would be last)-D
-Delete
rule-p
- Connectionprotocol
(tcp
/udp
/icmp
/all
)--dport
- Destinationport
-j
- Action(ACCEPT
/REJECT
/DROP
/LOG
)-P
- Policy-m
- Allow filter rules to match based on connection state
Accessible ports configuration
First of all, you want to allow ssh
access, which is tcp
port 22
$ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
To accept http
traffic, you need to open tcp
port 80
$ iptables -A INPUT -p tcp --dport 80 -j ACCEPT
$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
To permit the return traffic(you will be unable to use apt-get
or aptitude
without this):
$ iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
If you have incoming ftp
traffic, open tcp
ports 20
and 21
:
$ iptables -A INPUT -p tcp --dport 20 -j ACCEPT
$ iptables -A INPUT -p tcp --dport 21 -j ACCEPT
$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp-data
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
To accept range of ports(for example if ftp is configured to use passive mode with pasv_min_port=10090
and pasv_max_port=10100
):
$ iptables -A INPUT -p tcp --dport 10090:10100 -j ACCEPT
$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp-data
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp
ACCEPT tcp -- anywhere anywhere tcp dpts:10090:10100
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
How to set drop policy
Now we can either block all other ports by appending corresponding rule:
$ iptables -A INPUT -j DROP
$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp-data
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp
ACCEPT tcp -- anywhere anywhere tcp dpts:10090:10100
DROP all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Or(which is much better and the correct way) by specifying DROP
policy:
$ iptables -P INPUT DROP
$ iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp-data
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp
ACCEPT tcp -- anywhere anywhere tcp dpts:10090:10100
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Now in Chain INPUT
we list accessible ports, all other connections will be dropped.
To remove the rule you can use -D
with insertion line or specify rule number:
$ iptables -D INPUT -p tcp --dport 10090:10100 -j ACCEPT
OR
$ iptables -D INPUT 6
$ iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp-data
ACCEPT tcp -- anywhere anywhere tcp dpt:ftp
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
How to save iptables
After the first reboot all changes will be gone, this is intended behavior since you can specify DROP policy
or add the DROP all
rule in clean Chain INPUT
which will log you out and permanently forbid server access.
If you are satisfied with your rules and want them to be applied automatically after the reboot, the best way is to install iptables-persistent
package with
aptitude install iptables-persistent
and then save the rules into a special file, for IPv4
and IPv6
correspondingly:
$ iptables-save > /etc/iptables/rules.v4
$ ip6tables-save > /etc/iptables/rules.v6
References:
Ubuntu documentation: IptablesHowTo
Ubuntu forum: iptables howto/tips
25 most used rules