iptables is a firewall built into the Linux kernel. It is used to limit or transfer communication on that host. Although IPv4 is assumed here, IPv6 also has ip6tables that can be used in almost the same way.
A detailed explanation will be given later with an example of the iptables configuration file.
/etc/iptables/iptables.rules
#As a general rule, all input and transfer are prohibited
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
#All connections from loopback are allowed
-A INPUT -i lo -j ACCEPT
#Allows pings to be received, but limits the frequency to about once per second per client
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-name t_echo --hashlimit-mode srcip --hashlimit-upto 1/s --hashlimit-burst 5 --hashlimit-htable-expire 10000 -j ACCEPT
#Already established communication is allowed regardless of port number
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
#Allow SSH connection but limit the frequency to about once per minute per client
-A INPUT -m state --state NEW -m tcp -p tcp --syn --dport 22 -m hashlimit --hashlimit-name t_sshd --hashlimit-mode srcip --hashlimit-upto 1/m --hashlimit-burst 5 --hashlimit-htable-expire 600000 -j ACCEPT
#Allow response reception from DNS server
-A INPUT -p udp --sport 53 -j ACCEPT
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
As a general rule, all packet reception and forwarding are prohibited, and transmission is allowed. Of course, I don't want to receive packets at all, so I'll set an exception for this policy after this.
#All connections from loopback are allowed
-A INPUT -i lo -j ACCEPT
Linux may use sockets for interprocess communication as well as for communication with other hosts. Communication closed to such a host is called loopback. If you limit the loopback communication, there is a high possibility that various programs will not operate normally, so we allow it entirely.
Ping
#Allows pings to be received, but limits the frequency to about once per second per client
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-name t_echo --hashlimit-mode srcip --hashlimit-upto 1/s --hashlimit-burst 5 --hashlimit-htable-expire 10000 -j ACCEPT
Allows the host to respond to pings. However, the frequency is limited as a countermeasure against ICMP Flood (Ping Flood), which puts a load on the system by sending a large number of Pings. Use the hashlimit module to limit the frequency with which packets are received (or forwarded or sent).
--hashlimit-name
is the name of the hash table. Since it is necessary to record the packet reception history etc. in order to use this module, set the file name of the save destination so that it does not overlap with other rules.
--hashlimit-mode
specifies in what units the frequency of receiving packets is limited. Since srcip
is set here, the reception of packets is restricted for each source IP address. There are other flags such as dstip`` srcport
dstport
. You can also combine multiple flags. If you omit this option, the system as a whole limits the frequency with which packets are received, regardless of the source or destination.
--hashlimit-upto
and --hashlimit-burst
specifically set how often packets are allowed to be received. To understand the meaning of these two settings, it is helpful to compare the frequency with which packets are allowed to be received to the capacity of a bucket. Imagine that you need to remove a liter of water from a bucket to receive a single packet. The system boots when the bucket is full, but when there is not enough water it will not be able to receive packets. --hashlimit-upto 1 / s
means that you are pouring 1 liter of water into the bucket per second. However, --hashlimit-burst 5
means that the bucket has only 5 liters of capacity. This means that no matter how short the packet arrives, you can receive it up to 5 times without any problems, but you have to wait until the bucket is filled with water again in order to receive more packets in a row.
--hashlimit-htable-expire
specifies the expiration date of records in the hash table in milliseconds. If you do not set a value larger than $ \ frac {hashlimit-burst} {hashlimit-upto} $, the reception frequency will not be limited as expected. Here, we set it to 10000 milliseconds, which is twice the calculation result (5 seconds) with a margin.
TCP
#Already established communication is allowed regardless of port number
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
After establishing a connection with TCP once, allow any packet to be received on that port. The SSH server settings described below only allow connections to the server, but this setting also allows communication after a successful connection to pass through the firewall.
Also, I'm allowed to connect to the server as a client with the : OUTPUT ACCEPT [0: 0]
mentioned above, but it's this setting that allows me to receive packets after a successful connection.
#Allow SSH connection but limit the frequency to about once per minute per client
-A INPUT -m state --state NEW -m tcp -p tcp --syn --dport 22 -m hashlimit --hashlimit-name t_sshd --hashlimit-mode srcip --hashlimit-upto 1/m --hashlimit-burst 5 --hashlimit-htable-expire 600000 -j ACCEPT
Allows connections to TCP port 22. Like Ping, it uses the hashlimit module to limit the frequency of connections. You can apply it for other purposes by changing --dport 22
to another port number. For example, allow communication on port 80 for HTTP and port 443 for HTTPS. However, for HTTP and HTTPS, the hashlimit limit should be set a little looser.
#Allow response reception from DNS server
-A INPUT -p udp --sport 53 -j ACCEPT
DNS uses TCP / UDP or both. For TCP, : OUTPUT ACCEPT [0: 0]
-A INPUT -p tcp -m state --state ESTABLISHED, RELATED -j ACCEPT
is already allowed. There is no concept of connectivity for UDP, so you need to explicitly allow packets sent from port 53 to be received.
Please restart iptables. If you are using systemd such as Arch Linux:
# systemctl restart iptables
Recommended Posts