Iptables: network security and packet filtering

So, today we will figure out what kind of beast this IPTables is and how to fight, defeat and curb it? :)

IPTables - a command line utility, is a standard interface for managing the operation of the NETFilter firewall (firewall or firewall) for Linux kernels starting from version 2.4. Superuser (root) privileges are required to use the IPTables utility.

Sometimes the word IPTables refers to the NETFilter firewall itself. With its help, you can manage quite flexibly (in this case, the processing of packets coming to us or outgoing from us).

For example, you can deny one computer access to the Internet, allow another to access only websites, “forward” (assign) a predetermined port to a third, and send “suspicious” packets back to the sender (let it break itself). You can replace service information of IP packets “on the fly” (sender, recipient, TTL, etc.) and much more that you wouldn’t think of right away.

What you should know about firewalls, for starters, is that they are designed for protection, so you need to firmly remember that the last rule ( policy) should be "prohibit the rest". Second, but no less important, always edit rules or Telnet carefully.

Cases where rules were configured remotely, and after applying the rules, an inattentive administrator found himself “cut off” from the server are not isolated! And it’s good if the server is two steps away, but what if it’s somewhere in the distant kingdom?


How a firewall works

When a packet arrives at our firewall, it first gets to , is intercepted by the appropriate driver and then transmitted to the kernel. Next, the packet passes through a number of tables and is then transferred either to a local application or forwarded to another machine.

The package order is shown in the table below:

Step Table Chain Note
1 Cable (i.e. Internet)
2 Network interface (eg eth0)
3 mangle PREROUTING Typically this chain is used to make changes to the packet header, such as changing TOS bits, etc.
4 nat PREROUTING This chain is used for Destination Network Address Translation. Source Network Address Translation is performed later, in another chain. Any kind of filtering in this chain can only be done in exceptional cases
5 Deciding on further routing, i.e. at this point it is decided where the packet will go - to a local application or to another network node.
6 mangle FORWARD The packet then enters the FORWARD chain of the mangle table, which should only be used in exceptional cases when it is necessary to make some changes to the packet header between two routing decision points.
7 Filter FORWARD Only those packets that go to another host enter the FORWARD chain. All filtering of transit traffic should be performed here. Don't forget that traffic flows through this chain in both directions. Be sure to take this circumstance into account when writing filtering rules.
8 mangle POSTROUTING This chain is intended to make changes to the packet header after the last routing decision has been made.
9 nat POSTROUTING This chain is primarily intended for Source Network Address Translation. Do not use it for filtering unless absolutely necessary. Masquerading is also performed here.
10 Output network interface (for example, eth1)
11 Cable (let it be LAN)

As you can see, the packet goes through several stages before it is transmitted further. At each stage the packet can be stopped, be it by the iptables chain or something else, but we are mainly interested in iptables.

Note that there are no interface-specific chains or anything like that. ALL packets that move through our firewall router go through the FORWARD chain. Don't use the INPUT chain to filter transit packets; they simply don't get there. Only data destined for the same host moves through this chain.


iptables rules

Let me give an example of part of my router config: vlan332 is the interface through which I access the Internet, vlan333 is access to the provider’s local network, and 172.30.2.5 is my computer.

#NAT
iptables -t nat -A POSTROUTING -o vlan332 -j MASQUERADE
iptables -t nat -A POSTROUTING -o vlan333 -j MASQUERADE

#Torrent
iptables -A PREROUTING -t nat -p tcp --dport 9000 -i vlan332 -j DNAT --to 172.30.2.5

#Open port
iptables -A INPUT -p tcp --dport 53 -j ACCEPT #DNS TCP
iptables -A INPUT -p udp --dport 53 -j ACCEPT #DNS UDP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT #WEB server

#All other incoming “drop” (delete)
iptables -A INPUT -i vlan332 -j DROP

What does all of this mean? First of all, for ease of reading, I divided the config into “sections” with comments, i.e. in one section there are rules for NAT, in another - port forwarding (PAT), in a third - we allow server ports, etc.

Let's consider the first and second rules (they differ only in network interfaces):

iptables -t nat -A POSTROUTING -o vlan332 -j MASQUERADE

Based on it, we add a new rule to the nat table (-t nat) for the postrouting chain (-A POSTROUTING), which will be the last at the time the command is executed in the chain (i.e., to the end). The rule will be applied on the outgoing interface vlan332 (-o vlan332) and will be passed to MASQUERADE (-j MASQUERADE) those NAT.

In human terms, everything that will come out of the vlan332 interface must be hidden behind NAT. This means that when leaving our router, the sender address will be our server, and not the end user’s computer from which the request was sent. When the response arrives upon request, the reverse procedure will be carried out and the packet will be transferred to the original sender. Why this will be necessary will be described in detail in the article about NAT.

Let's move on to the next group of rules, namely the section marked as "torrent". This section specifies the rules for port forwarding (PAT - Port Adress Translation), i.e. so that from the Internet side you can connect to the port on the computer behind our router. Without this, many applications will not be able to work correctly, for example file-sharing networks torrent, DC++ and some applications that require incoming connections from the Internet. Let's look at the rule using the example of forwarding (assigning) ports for a Torrent client

iptables -A PREROUTING -t nat -p tcp --dport 9000 -i vlan332 -j DNAT --to 172.30.2.5

As in the previous rule, we specify the table and chain (-A PREROUTING -t nat), specify the valid protocol type. In the current TCP rule (-p tcp) (in another UDP rule, although they can be specified in one rule, unfortunately, this did not work out for me even with the official literature and I have not yet found a solution).

Destination port 9000 (--dport 9000), incoming interface vlan332. Using the DNAT action (-j DNAT) we indicate that we need to replace the recipient address with 172.30.2.5 (--to 172.30.2.5) i.e. - our computer. It turns out: redirect all incoming connections via TCP to port 9000 to IP 172.30.2.5.

iptables -A INPUT -p tcp --dport 53 -j ACCEPT #DNS TCP

We indicate the INPUT chain, the TCP protocol, port number 53 (used for DNS services) and the action - allow. You may notice that UDP is used for DNS queries and this will be correct. TCP is used to transmit information about zones (domains), and since my server is the primary server for several zones, I allowed access via TCP.

The last rule, as I said above, should be to prohibit everything else that does not fall under the filters. I wrote iptables -A INPUT -i vlan332 -j DROP those. Delete all incoming packets to the vlan332 interface.

Since this firewall does not have a permanent config, the rules must be entered manually when rebooting. This is not a problem, since there are shell scripts (analogous to bat and cmd files in Windows) and when executed, they will run the commands written in them.

To do this, create a file in the etc directory with the name firewall.sh using the nano /etc/firewall.sh command, i.e. Let's open it immediately in the editor. Let's enter all the rules we need there and save it by pressing Ctrl+X.

Here are some working config rules that may be useful to you in everyday use. The first line (#!/bin/sh) is required because it specifies how these instructions should be interpreted.

#!/bin/sh
PATH=/usr/sbin:/sbin:/bin:/usr/bin

# Remove all existing rules from all tables and chains
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X

# Allow any traffic
iptables -A INPUT -i lo -j ACCEPT#Loopback
iptables -A INPUT -i eth0 -j ACCEPT#Internal interface to LAN
iptables -A INPUT -i eth2 -j ACCEPT#Internal interface to LAN 2

#NAT
iptables -t nat -A POSTROUTING -o vlan332 -j MASQUERADE#Enable NAT towards the Internet
iptables -t nat -A POSTROUTING -o vlan333 -j MASQUERADE#Enable NAT towards the provider (provider network)

#PORT FORWARDING
#Torrent
iptables -A PREROUTING -t nat -p tcp --dport 9000 -i vlan332 -j DNAT --to 172.30.2.5#Port forwarding to IP
iptables -A PREROUTING -t nat -p udp --dport 9000 -i vlan332 -j DNAT --to 172.30.2.5

#VPN connections, allowing connections via PPP, etc.
iptables -A INPUT -p tcp -m tcp --dport 1723 -j ACCEPT
iptables -A INPUT -p gre -m state --state RELATED,ESTABLISHED -j ACCEPT

#Open server ports
iptables -A INPUT -p tcp --dport 23 -j ACCEPT #Allow access via SSH

#Delete everything else incoming ("drop" - discard)
iptables -A INPUT -i vlan332 -j DROP

# Enable forwarding, without this packet routing will not occur
echo 1 > /proc/sys/net/ipv4/ip_forward

After this we make the file executable, i.e.:
chmod +x /etс/firewall.sh(eXecute).

In order for this file to be processed automatically when loading, we will write the path to it in the “autoload” file. Open nano /etс/rc.local and add the line /etс/firewall.sh before exit 0. If you need to use VLAN (virtual interfaces and networks), then you need to write this line in the file /etс/network/interfaces in the form up sh /etс /firewall.sh to the vlan interface, for example:

# VLAN to INET
auto vlan332
iface vlan332 inet static
address xxx.xxx.xxx.xxx
netmask 255.255.255.252
# gateway xxx.xxx.xxx.xxx
vlan_raw_device eth1
up sh /etс/firewall.sh

This is necessary because “autoload” will take place first, and only after a while our VLAN interfaces will come up, and if there is no interface, then the rule will not be created.

Unfortunately, I don’t have the opportunity to fully describe the operation of this wonderful firewall, but there is excellent documentation on it in Russian (translation of the original developer’s manual), here is its address.

It won’t be very difficult, after reading even part of it or setting a specific task, to solve most of the issues related to this firewall and writing the rules yourself.

Greetings to all! In continuation, I publish this practical article about Linux network filter. In the article I will consider typical examples of implementing iptables rules in Linux, and also consider ways saving the created iptables configuration.

Setting up netfilter/iptables for a workstation

Let's start with an elementary task - implementation of a Linux firewall on a desktop. In most cases, on desktop Linux distributions there is no urgent need to use a firewall, because Such distributions do not run any services that listen to network ports, but for the sake of prevention, it would not be superfluous to organize protection. Because the core is also not immune to holes. So, we have Linux, with eth0, no matter via DHCP or statically...

For settings firewall I try to adhere to the following policy: ban everything, and then what needs to be allowed. That's what we'll do in this case. If you have a freshly installed system and you have not tried to configure a network filter on it, then the rules will look something like this:

Netfilter:~# iptables -L 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

This means that the default policy for filter tables in all chains - ACCEPT and there are no other rules prohibiting anything. So let's first ban EVERYTHING, including packages(don’t even try to do this remotely, you’ll immediately lose access):

Netfilter:~# iptables -P INPUT DROP netfilter:~# iptables -P OUTPUT DROP netfilter:~# iptables -P FORWARD DROP

With these commands we install DROP default. This means that any packet that does not explicitly have a rule that allows it is automatically discarded. Since we have not yet set a single rule, all packets that arrive on your computer will be rejected, as well as those that you try to send to the network. As a demonstration, you can try pinging your computer through the loopback interface:

Netfilter:~# ping -c2 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. ping: sendmsg: Operation not permitted ping: sendmsg: Operation not permitted --- localhost ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1004ms

In fact, this is a completely non-functioning network and this is not very good, because... Some daemons use a loopback interface to communicate with each other, which no longer functions after the actions have been taken. This may disrupt the operation of such services. Therefore, first of all, it is imperative let's allow packets to be transmitted through the incoming loopback interface and outgoing loopback interface in the INPUT tables(to be able to receive sent packages) and OUTPUT(for the ability to send packages) accordingly. So, be sure to do:

Netfilter:~# iptables -A INPUT -i lo -j ACCEPT netfilter:~# iptables -A OUTPUT -o lo -j ACCEPT

After this, ping to localhost will work:

Netfilter:~# ping -c1 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1 (127.0.0.1): icmp_seq=1 ttl=64 time=0.116 ms --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 116ms rtt min/ avg/max/mdev = 0.116/0.116/0.116/0.116 ms

If you are not too fanatical about setting up the firewall, you can allow the ICMP protocol to work:

Netfilter:~# iptables -A INPUT -p icmp -j ACCEPT netfilter:~# iptables -A OUTPUT -p icmp -j ACCEPT

It would be safer to specify the following similar iptables command:

Netfilter:~# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT netfilter:~# iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT netfilter:~# iptables -A OUTPUT -p icmp -j ACCEPT

This command will allow the ICMP packet types to be echo request and echo reply, which will improve security.

Knowing that our computer is not infected (is it?) and it only establishes secure outgoing connections. And also, knowing that secure connections are connections from the so-called. ephemeral range of ports, which is specified by the kernel in a file /proc/sys/net/ipv4/ip_local_port_range, Can allow outgoing connections from these secure ports:

Netfilter:~# cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000 netfilter:~# iptables -A OUTPUT -p TCP --sport 32768:61000 -j ACCEPT netfilter:~# iptables -A OUTPUT -p UDP -- sport 32768:61000 -j ACCEPT

If you are not paranoid about limiting outgoing packets, then you could limit yourself to one command iptables allowing all outgoing connections op to all protocols and ports:

Netfilter:~# iptables -A OUTPUT -j ACCEPT netfilter:~# # or simply set the default ACCEPT policy for the OUTPUT chain netfilter:~# iptables -P OUTPUT ACCEPT

Further, knowing that in netfilter network connections have 4 states ( NEW,ESTABLISHEDRELATED andINVALID) and new outgoing connections from the local computer (with the NEW state) are allowed in the last two iptables commands, that already established connections and additional ones have states ESTABLISHED andRELATED accordingly, and also knowing that the local system is accessed through , we can allow only those TCP and UDP packets that were requested by local applications to reach our computer:

Netfilter:~# iptables -A INPUT -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT netfilter:~# iptables -A INPUT -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT

That's all, actually! If some kind of network service is still running on the desktop, then you need to add appropriate rules for incoming connections and for outgoing ones. For example, for running the ssh server which accepts and sends requests on TCP port 22, you need to add the following iptables rules:

Netfilter:~# iptables -A INPUT -i eth0 -p TCP --dport 22 -j ACCEPT netfilter:~# iptables -A OUTPUT -o eth0 -p TCP --sport 22 -j ACCEPT

Those. for any service, you need to add one rule to the INPUT and OUTPUT chains, allowing, respectively, the reception and sending of packets using this port for a specific network interface (if you do not specify an interface, then it will be allowed to receive/send packets on any interface).

Configuring netfilter/iptables to allow multiple clients to connect to one connection.

Let's now look at our Linux as a gateway for a local network to the external Internet. Let's pretend that interface eth0 is connected to the Internet and has IP 198.166.0.200, and interface eth1 is connected to the local network and has IP 10.0.0.1. By default, in the Linux kernel forwarding packets via the FORWARD chain(packages not intended for the local system) is disabled. To enable this feature, you must set the value 1 in the file :

Netfilter:~# echo 1 > /proc/sys/net/ipv4/ip_forward

To packet forwarding saved after reboot, must be in the file /etc/sysctl.conf uncomment (or just add) the line net.ipv4.ip_forward=1.

So, we have an external address (198.166.0.200), there are a number of hypothetical clients on the local network that have and send requests to the external network. If these clients send requests to the external network through the gateway “as is”, without conversion, then the remote server will not be able to respond to them, because the return address will be the recipient from the "local network". In order for this scheme to work correctly, it is necessary to replace the sender's address with the external address of the Linux gateway. This is achieved through (masquerading) in , in .

Netfilter:~# iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT netfilter:~# iptables -A FORWARD -m conntrack --ctstate NEW -i eth1 -s 10.0.0.1/24 -j ACCEPT netfilter: ~# iptables -P FORWARD DROP netfilter:~# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

So, in order from top to bottom, we resolve already established connections in chain FORWARD, filter table, then we allow new connections to be established in chain FORWARD, filter table, which came from the eth1 interface and from the 10.0.0.1/24 network. All other packets that pass through FORWARD chain- discard. Next, we perform masking (substitution of the packet sender address in the headers) of all packets originating from the eth0 interface.

Note. There is a general recommendation: use the -j MASQUERADE rule for interfaces with a dynamically obtained IP (for example, via DHCP from the provider). With a static IP, -j MASQUERADE can be replaced with a similar -j SNAT -to-source IP_interface_eth0. In addition, SNAT can “remember” about established connections in the event of a short-term unavailability of the interface. Comparison of MASQUERADE and SNAT in the table:

In addition to the specified rules, you can also add rules for filtering packets destined for the local host - as described in. That is, add prohibiting and allowing rules for incoming and outgoing connections:

Netfilter:~# iptables -P INPUT DROP netfilter:~# iptables -P OUTPUT DROP netfilter:~# iptables -A INPUT -i lo -j ACCEPT netfilter:~# iptables -A OUTPUT -o lo -j ACCEPT netfilter:~# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT netfilter:~# iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT netfilter:~# iptables -A OUTPUT -p icmp -j ACCEPT netfilter:~# cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000 netfilter:~# iptables -A OUTPUT -p TCP --sport 32768:61000 -j ACCEPT netfilter:~# iptables -A OUTPUT -p UDP -- sport 32768:61000 -j ACCEPT netfilter:~# iptables -A INPUT -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT netfilter:~# iptables -A INPUT -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT

As a result, if one of the local network hosts, for example 10.0.0.2, tries to contact one of the Internet hosts, for example, 93.158.134.3 (ya.ru), with , their source address will be replaced with the external gateway address in the chain POSTROUTING table nat, that is, the outgoing IP 10.0.0.2 will be replaced by 198.166.0.200. From the point of view of the remote host (ya.ru), it will look as if the gateway itself is communicating with it directly. When the remote host starts transmitting data back, it will address it specifically to the gateway, that is, 198.166.0.200. However, at the gateway the destination address of these packets will be changed to 10.0.0.2, after which the packets will be transmitted to the real recipient on the local network. For such a reverse transformation, no additional rules need to be specified - this will be done by the same operation MASQUERADE, which remembers which host on the local network sent the request and which host needs to return the received response.

Note: preferably tacitly accepted, before all iptables commands clear chains to which rules will be added:

Netfilter:~# iptables -F CHAINNAME

Providing access to services on the gateway

Let's assume that a certain service is running on our gateway, which should respond to requests coming from the Internet. Let's say it works on some TCP port nn. To provide access to this service, it is necessary to modify the filter table in the INPUT chain (to allow receiving network packets addressed to the local service) and the filter table in the OUTPUT chain (to allow responses to incoming requests).

So, we have, which masquerades (replaces the sender's address with an external one) packets to an external network. And allows accepting all established connections. Providing access to the service will be carried out using the following allowing rules:

Netfilter:~# iptables -A INPUT -p TCP --dport nn -j ACCEPT netfilter:~# iptables -A OUTPUT -p TCP --sport nn -j ACCEPT

These rules allow incoming TCP connections to port nn and outgoing TCP connections from port nn. In addition, you can add additional restrictive parameters, for example, allow incoming connections only from the external interface eth0 (key -i eth0) and so on.

Providing access to services on the local network

Let's assume that on our local network there is some host with IP X.Y.Z.1, which must respond to network requests from the external network on TCP port xxx. In order for a correct service response from the local network to occur when a remote client accesses an external IP port xxx, it is necessary to forward requests coming to the external IP port xxx to the corresponding host on the local network. This is achieved by modifying the recipient address in the packet arriving at the specified port. This action is called DNAT and is applied in the PREROUTING chain in the nat table. And also allow the passage of these packets in the FORWARD chain in the filter table.

Again, let's take the path. So, we have, which masquerades (replaces the sender's address with an external one) packets to an external network. And allows accepting all established connections. Providing access to the service will be carried out using the following allowing rules:

Netfilter:~# iptables -t nat -A PREROUTING -p tcp -d 198.166.0.200 --dport xxx -j DNAT --to-destination X.Y.Z.1 netfilter:~# iptables -A FORWARD -i eth0 -p tcp -d X.Y.Z. 1 --dport xxx -j ACCEPT

Saving entered rules on reboot

All rules entered in the console will be reset to their original state after the OS is rebooted (read - deleted). In order to save all entered iptables commands, there are several ways. For example, one of them is to set all the firewall rules in the initialization file. But this method has a significant drawback: the entire period of time from the start of the network subsystem, until the start of the last service and then the rc.local script from SystemV, the operating system will not be protected. Imagine a situation, for example, if some service (for example NFS) starts last and some failure occurs when it starts and before the rc.local script is launched. Accordingly, rc.local never starts, and our system turns into one big hole.

Therefore, the best idea would be initialize netfilter/iptables rules while loading . Debian has a great tool for this - the directory /etc/network/if-up.d/, in which you can place scripts that will be launched when the network starts. There are also teams iptables-save And iptables-restore, which save create a dump of netfilter rules from the kernel on and restore the rules from the kernel accordingly.

So, The iptables saving algorithm is approximately the following:

  • We configure the firewall to suit your needs using
  • create a dump of the created rules using the command iptables-save > /etc/iptables.rules
  • create import script created dump when the network starts (in the /etc/network/if-up.d/ directory) and don’t forget to make it executable:
# cat /etc/network/if-up.d/firewall #!/bin/bash /sbin/iptables-restore< /etc/iptables.rules exit 0 # chmod +x /etc/network/if-up.d/firewall

Rules dump received iptables-save command It has a text format and is therefore suitable for editing. The output syntax for the iptables-save command is as follows:

# Generated by iptables-save v1.4.5 on Sat Dec 24 22:35:13 2011 *filter:INPUT ACCEPT :FORWARD ACCEPT ....... # comment -A INPUT -i lo -j ACCEPT -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT ........... -A FORWARD -j REJECT COMMIT # Completed on Sat Dec 24 22:35:13 2011 # Generated by iptables-save v1 .4.5 on Sat Dec 24 22:35:13 2011 *raw ...... COMMIT

Lines starting with # - comments, lines on * - this is the name of the tables, between the table name and the word COMMIT contains parameters passed to the iptables command. COMMIT parameter- indicates the completion of the parameters for the above table. Lines starting with a colon define chains that contain this table in the format:

:chain policy [packets:bytes]

Where chain- chain name, policy- the default chain policy for this table, and then the packet and byte counters at the time the command is executed.

At RedHat iptables command storage functions executed when the network starts and stops executes the file /etc/sysconfig/iptables. And management of this file lies with the iptables daemon.

As another option for saving rules, you can consider using the parameter up in file /etc/network/interfaces with an argument in the form of a file storing iptables commands that set the necessary rules.

Bottom line

That will be enough for today. I will definitely publish more complex firewall implementations in future articles.

Best regards, McSim!

Introduction and history

Netfilter- a firewall (aka firewall, aka firewall, aka firewall...) has been built into the Linux kernel since version 2.4. Netfilter is controlled by the utility iptables(For IPv6 - ip6tables). Before netfilter/iptables was Ipchains, which was included in the Linux 2.2 kernels. Before ipchains in Linux there was the so-called ipfw (IPV4 firewall), ported from BSD. Management utility - ipfwadm. The netfilter/iptables project was founded in 1998. The author is Rusty Russell (he also led past developments). In 1999, the Netfilter Core Team (abbreviated as coreteam) was formed. The developed firewall was officially named netfilter. In August 2003, Harald Welte became the head of coreteam.

Projects ipchains And ipfwadm changed the operation of the Linux kernel protocol stack, since before the advent of netfilter There was no provision in the kernel architecture for adding additional package management modules. iptables kept the main idea ipfwadm- a list of rules consisting of criteria and an action that is performed if the packet meets the criteria. IN ipchains a new concept was introduced - the ability to create new chains of rules and transfer packets between chains, and in iptables the concept was expanded to four tables (in modern netfilter - more than four), delimiting chains of rules by task: filtering, NAT, and packet modification. Also, iptables has expanded Linux's state detection capabilities, allowing the creation of firewalls that operate at the session level.

Netfilter/iptables architecture

Prerequisites ()

As mentioned above, for Netfilter to work, you need kernel version 2.6 (or at least 2.3.15). In addition, if necessary, the following settings are available: CONFIG_NETFILTER, CONFIG_IP_NF_IPTABLES, CONFIG_IP_NF_FILTER (filter table), CONFIG_IP_NF_NAT (nat table), CONFIG_BRIDGE_NETFILTER, as well as numerous additional modules: CONFIG_IP_NF_CONNTRACK (connection tracking), CONFIG_IP_NF_FTP (auxiliary module for tracking FTP connections), CONFIG_IP _NF_MATCH_* ( additional types of packet matching patterns: LIMIT, MAC, MARK, MULTIPORT, TOS, TCPMSS, STATE, UNCLEAN, OWNER), CONFIG_IP_NF_TARGET_* (additional actions in rules: REJECT, MASQUERADE, REDIRECT, LOG, TCPMSS), CONFIG_IP_NF_COMPAT_IPCHAINS for compatibility with ipchains, CONFIG_BRIDGE_NF_EBTABLES and CONFIG_BRIDGE_EBT_* for working in bridge mode, others CONFIG_IP_NF_* and CONFIG_IP6_NF_*. It is also useful to specify CONFIG_PACKET.

As seen, nat table And mangle can modify the recipient or sender of a network packet. This is why the network packet is checked several times against the routing table.

State detection mechanism (conntrack)

Above in the text, the concept of “state definition” was mentioned several times; it deserves a separate topic for discussion, but nevertheless, I will briefly touch on this issue in the current post. In general, the mechanism for determining states (aka state machine, aka conn ection track ing, aka conntrack) is part of the packet filter and allows you to determine which connection/session a packet belongs to. Conntrack analyzes the state of all packages except those marked as NOTRACK in raw table. Based on this state, the package belongs to is determined new connection (state NEW), already established connection (state ESTABLISHED), additional to an already existing one ( RELATED), or to " to another" (undetectable) connection (state INVALID). The state of the packet is determined by analyzing the headers of the transmitted TCP packet. conntrack module allows you to implement a session-level (fifth) firewall. To control this mechanism, use the utility conntrack, as well as the iptables utility parameter: -m conntrack or -m state(obsolete). conntrack stores the states of current connections in the kernel. They can be viewed in the file /proc/net/nf_conntrack (or /proc/net/ip_conntrack) .

To prevent thoughts from turning into mush, I think this brief information will be enough to understand further material.

Managing Netfilter network filtering rules (using the iptables command)

iptables utility is an interface for control netfilter firewall. This command allows you to edit table rules, tables and chains. As I already said - every rule is a record/string containing a selection of network packets and packets that match a given rule. iptables command Requires root rights to operate.

In general, the command format is as follows:

Iptables [-t ]

All parameters in square brackets - optional. Default is filter table, if you need to specify another table, then you should use the key -t indicating name. After the table name is indicated that defines the action ( For example: insert a rule, or add a rule to the end of the chain, or delete a rule). For example sets selection parameters.

indicates what action should be performed if the selection criteria in the rule match (

: pass the packet to another chain of rules, “drop” the packet, issue an error message to the source...). Below are the commands and parameters of the iptables utility: Parameter
Description
Example Teams --append (-A)
Add the specified rule to the END of the list in the specified chain and specified table. iptables -A FORWARD criteria -j action --delete (-D)
Removes the rule(s) specified by the number(s) or rule(s). The first example deletes all rules with numbers 10,12 in all chains, in the filter tables, the second example deletes the specified rule from the mangle table in the PREROUTING chain.
iptables -D 10.12 iptables -t mangle -D PREROUTING criteria -j action --rename-chain (-E)
Change chain name. iptables -E OLD_CHAIN ​​NEW_CHAIN --flush (-F)
Clears all rules of the current table. For all packets that relate to already established connections, apply the terminal action ACCEPT - skip iptables -F --insert (-I)
Inserts the specified rule at the location specified by the number. iptables -I FORWARD 5 criteria -j action --list (abbreviated -L)
View existing rules (without explicitly specifying the table - the filter table of all chains is displayed). iptables -L --policy (-P)
Sets the default policy for the given chain. iptables -t mangle -P PREROUTING DROP --replace (-R)
Replaces the rule specified by the number with the one specified in the criteria. iptables -R POSROUTING 7 | criteria -j action --delete-chain (-X)
--zero (-Z) Resets the counters of transmitted data in the chain. iptables -Z INPUT
Options
--numeric (-n) Does not resolve addresses and protocols during output.
--line-numbers Specify rule numbers in output (can be used in conjunction with -L). iptables -L --line-numbers
--help (-h) where would we be without her?
-t table Specifies the name of the table on which the action needs to be performed. The example resets the nat table in all chains. iptables -t nat -F
--verbose (-v) Detailed conclusion. iptables -L -v

Criteria (parameters) for selecting network packets of the iptables command

Criteria for selecting network packets are secretly divided into several groups: General criteria, Implicit criteria, Explicit criteria. can be used in any rules, they do not depend on the protocol type and do not require loading extension modules.(I would call it non-general), those criteria that are loaded implicitly and become available, for example, when specifying a general criterion --protocol tcp|udp|icmp. Before use, you need to connect additional expansion(these are peculiar plugins for netfilter). Additional extensions loaded using the parameter -m or --match. So for example, if we are going to use the criteria -m state state , then we must explicitly specify this in the rule line: And to the left of the criterion used. Difference between obvious

implicit non-general The criteria is that explicit ones need to be loaded explicitly, and implicit ones are loaded automatically. Can be used in all criteria sign!. before the criterion value. This will mean that this rule covers all packets that do not correspond to this parameter For example : criterion--protocol ! tcp will mean that all packets that Not are TCP protocols are subject to the rule. However, the latest versions of iptables (in particular, 1.4.3.2 and higher) no longer support this syntax and require the use of --protocol ! tcp, A

! --protocol tcp

, giving the following error: Using intrapositioned negation (`--option ! this`) is deprecated in favor of extrapositioned (`! --option this`).

: pass the packet to another chain of rules, “drop” the packet, issue an error message to the source...). Below are the commands and parameters of the iptables utility: Parameter
Below are given in table form
Commonly used packet selection parameters:
Common parameters
--protocol (abbreviated -p)
Defines the protocol. Options tcp, udp, icmp, all or any other protocol defined in /etc/protocols
iptables -A INPUT -p tcp
--source
  • (-s, --src)
  • IP address of the packet source. Can be defined in several ways:

It is strongly recommended not to use domain names that require DNS queries for resolution, since netfilter DNS may not work correctly during the configuration stage. Also, note that names are resolved only once - when adding a rule to the chain. Subsequently, the IP address corresponding to this name may change, but this will not affect the already written rules (the old address will remain in them). If you specify a domain name that resolves to several IP addresses, a separate rule will be added for each address.

iptables -A INPUT -s 10.10.10.3
--destination
(-d)
IP address of the packet's destination. Can be defined in several ways (see --source). iptables -A INPUT --destination 192.168.1.0/24
--in-interface
(-i)
Identifies the interface on which the packet arrived. Useful for NAT and machines with multiple network interfaces. Used in INPUT, FORWARD and PREROUTING chains. It is possible to use the "+" sign, then it means the use of all interfaces starting with the name + (for example, eth+ - all eth interfaces). iptables -t nat -A PREROUTING --in-interface eth0
--out-interface
(-o)
Defines the interface from which the packet will leave. Useful for NAT and machines with multiple network interfaces. Used in OUTPUT, FORWARD and POSTROUTING chains. It is possible to use the "+" sign. iptables -t nat -A POSTROUTING --in-interface eth1
Implicit (non-shared) parameters
-p proto -h displaying help on implicit parameters of the proto protocol. iptables -p icmp -h
--source-port
(--sport)
Source port, only possible for --protocol tcp, or --protocol udp protocols iptables -A INPUT --protocol tcp --source-port 25
--destination-port
(--dport)
Destination port, only possible for --protocol tcp, or --protemocol udp protocols iptables -A INPUT --protocol udp --destination-port 67
Explicit Parameters
-m state --state (deprecated)
aka
-m conntrack --ctstate

Connection status. Available options:

  • NEW(All packages establishing a new connection)
  • ESTABLISHED(All packets belonging to the established connection)
  • RELATED(Packets that do not belong to an established connection, but are associated with it. For example, FTP in active mode uses different connections to transfer data. These connections are associated.)
  • INVALID(Packets that cannot be identified for one reason or another. For example, ICMP errors that do not belong to existing connections)
  • etc. (more details in the documentation)
iptables -A INPUT -m state --state NEW,ESTABLISHEDiptables -A INPUT -m conntrack --ctstate NEW,ESTABLISHED
-m mac --mac-source Specifies the MAC address of the network node that sent the packet. The MAC address must be specified in the form XX:XX:XX:XX:XX:XX. -m mac --mac-source 00:00:00:00:00:0

Actions on packages

This title would be more correctly rephrased as " Actions on packages that match the selection criteria". So, to accomplish any actions on packages, you need to specify the key -j (--jump) and indicate what specific action to take.

Actions on packages can take the following values:

  • ACCEPT- the packet leaves this chain and is transferred to the next one (literally - ACCEPT).
  • DROP- discard a packet that satisfies the condition, while the packet is not transmitted to other tables/chains.
  • REJECT- discard the packet by sending an ICMP message to the sender, while the packet is not transmitted to other tables/chains.
  • RETURN- return the packet to the previous chain and continue its passage starting from the next rule.
  • SNAT source in the package. Can only be used in chains POSTROUTING and OUTPUT in nat tables.
  • DNAT- apply address translation appointments in the package. Can be used in a chain PREROUTING in the nat table. (in exceptional cases - in the OUTPUT chain)
  • LOG- log the packet (sent to the daemon) and process it with other rules.
  • MASQUERADE- used instead SNAT if there is a connection with a dynamic IP (it is allowed to indicate only in the chain POSTROUTING nat tables).
  • MARK- used to set labels on packets and passed on to further rules for processing.
  • and etc.

In addition to these actions, there are others that can be found in the documentation (perhaps I will soon supplement the article as I develop the topic). Some actions have additional parameters.

The table below provides examples and descriptions of additional parameters:

: pass the packet to another chain of rules, “drop” the packet, issue an error message to the source...). Below are the commands and parameters of the iptables utility: Parameter
DNAT (Destination Network Address Translation)
--to-destination specifies which IP address should be substituted as the destination address. In the example, in all tcp protocol packets arriving at address 1.2.3.4, this address will be replaced by 4.3.2.1. iptables -t nat -A PREROUTING -p tcp -d 1.2.3.4 -j DNAT --to-destination 4.3.2.1
LOG
--log-level Used to set the logging level (). In the example, the maximum logging level is set for all tcp packets in the filter table of the FORWARD chain. iptables -A FORWARD -p tcp -j LOG --log-level debug
--log-prefix Specifies the text (prefix) that will precede all messages iptables. (very convenient for later) The prefix can contain up to 29 characters, including spaces. In the example, all tcp packets in the filter table of the INPUT chain with the INRUT-filter prefix are sent to syslog. iptables -A INPUT -p tcp -j LOG --log-prefix "INRUT-filter"
--log-ip-options Allows you to enter various information from the IP packet header. iptables -A FORWARD -p tcp -j LOG --log-ip-options
and etc...

This concludes the theory about the netfilter/iptables network filter. In the next article I will give practical examples for mastering this theory.

Summary

In this article, we looked very briefly at the basic concepts of a network filter in Linux. So, the netfilter/iptables subsystem is part of the Linux kernel and is used to organize various filtering schemes and manipulate network packets. In this case, each packet passes from the network interface to which it arrived and further along a certain chain route, depending on whether it is intended for a local system or a “non-local” one. Each chain consists of a set of tables containing a sequential set of rules. Each rule consists of a certain criterion/criteria for selecting a network packet and some action with the packet that meets these criteria. In accordance with the given rules, any action can be performed on the packet (For example, transfer to the next/other chain, packet reset, modification of contents or headers, etc.). Each chain and each table has its own purpose, functionality and place in the package path. For example, to filter packets, the filter table is used, which is contained in three standard chains and can be contained in chains specified by the user. The packet's path ends either at the outgoing network interface or by delivery to a local process/application.

Literature

Quite a lot of interesting information in Russian is contained here:

  • http://www.opennet.ru/docs/RUS/iptables/
  • http://ru.wikibooks.org/wiki/Iptables

More in-depth material is available in bourgeois language here:

  • http://www.frozentux.net/documents/ipsysctl-tutorial/
  • http://www.netfilter.org/documentation/index.html

Best regards, McSim!

Educational program

Despite the fact that the Internet is full of articles about Iptables, quite often I see requests to suggest a set of rules for a specific situation. Since the situations are quite typical, you can provide a link to this note without explanation. I repeat, this is not a retelling, which is required reading. It is already good enough, but only sets of rules for beginners with minimal comments.
Something, of course, is worth saying for understanding:
Policy, key -P. Quote from the tutorial:

Sets the default policy for the given chain. The default policy determines the action applied to packets that are not covered by any of the rules in the chain. The default policy is DROP and ACCEPT.

In other words, if a packet arriving on a network interface is not described by any rule, then it is processed by the default policy. It follows from this that you can configure Iptables (and any firewall) in two ways/policies:
1. Everything that is not prohibited is permitted. Those. Everything is allowed.
2. Everything is prohibited except what is explicitly permitted.
Obviously, the second approach is more correct, which will be discussed further. I suggest leaving the policy for OUTPUT as ACCEPT, otherwise you will have to deal with a lot of glitches. When you know Iptables well enough, you will understand why and can configure it in DROP.
And one more important note. It is understood that the rules are applied by the script, and not entered from the console one by one. In the latter case, after the command iptable -P INPUT DROP the connection of the established SSH session will be lost. When applying rules by script, the session will not break, because Next comes the rule for allowing to accept already established connections.

Before applying rules, you must clear all existing chains, tables, and policies:

Iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT iptables -t nat -P PREROUTING ACCEPT iptables -t nat -P POSTROUTING ACCEPT iptables -t nat -P OUTPUT ACCEPT iptables -t mangle -P PREROUTING ACCEPT iptables -t mangle -P OUTPUT ACCEPT iptables -F iptables -t nat -F iptables -t mangle -F iptables -X iptables -t nat -X iptables -t mangle -X

Minimum set of iptables rules for desktop

Task: block all incoming connections. Outgoing calls are unlimited.

# Default rules iptable -P INPUT DROP iptable -P FORWARD DROP iptable -P OUTPUT ACCEPT # Allow incoming connections from the localhost iptables -A INPUT -i lo -j ACCEPT # Allow already established incoming connections iptables -A INPUT -m state -- state ESTABLISHED,RELATED -j ACCEPT

Minimum set of iptables rules for a server with an application

Task: provide access to a service, let it be a web server running on port 80, deny everything else.
Since this is a server, it is necessary to allow a connection for management via SSH. By analogy, you can open any desired port or sets of ports.

# Default rules iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # Allow incoming connections from the localhost iptables -A INPUT -i lo -j ACCEPT # Allow already established incoming connections iptables -A INPUT -m state -- state ESTABLISHED,RELATED -j ACCEPT # Allow SSH iptables -A INPUT -p TCP --dport 22 -j ACCEPT # Allow HTTP port iptables -A INPUT -p TCP --dport 80 -j ACCEPT

Minimum set of iptables rules for a gateway

Task: 1. Distribute the Internet to the local network using NAT. 2. Allow machines from the local network to access external HTTP, HTTPS and DNS servers 3. Forward the port to a web server located on this local network.

### Variables # Interface looking to the Internet INET_IF="eth0" # White IP address belonging to $INET_IF INET_IP="x.x.x.x" # TCP ports through which machines from the local network are allowed to access the Internet FORWARD_TCP_PORTS="53,80,443" # UDP ports through which machines from the local network are allowed to access the Internet FORWARD_UDP_PORTS="53" # Local network LOCAL_NET="192.168.0.0/24" # IP address of the local web server WEB_SERVER="192.168.0.10" # Path to sysctl SYSCTL=" /sbin/sysctl -w" # Enable forward IPv4 packets in the kernel if [ "$SYSCTL" = "" ] then echo "1" > /proc/sys/net/ipv4/ip_forward else $SYSCTL net.ipv4.ip_forward=" 1" fi ### Default rules iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT ### INPUT # Allow incoming connections from the localhost iptables -A INPUT -i lo -j ACCEPT # Allow accepting connections already established iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow SSH iptables -A INPUT -p TCP --dport 22 -j ACCEPT ### FORWARD # Allow already established forward connections iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow local network machines to access the Internet on specified TCP ports iptables -A FORWARD -p TCP -s $LOCAL_NET -m multiport --dport $FORWARD_TCP_PORTS -j ACCEPT iptables -A FORWARD -p TCP -d $LOCAL_NET -m multiport --dport $FORWARD_TCP_PORTS -j ACCEPT # Allow local network machines to access the Internet on the specified UDP ports iptables -A FORWARD -p UDP -s $LOCAL_NET -m multiport --dport $FORWARD_UDP_PORTS -j ACCEPT iptables -A FORWARD -p UDP -d $LOCAL_NET -m multiport --dport $FORWARD_UDP_PORTS -j ACCEPT ### NAT # Enable NAT for the local subnet iptables -t nat -A POSTROUTING -s $LOCAL_NET -o $INET_IF -j SNAT - -to-source $INET_IP # Forward the port to the local web server iptables -t nat -A PREROUTING -p TCP -d $INET_IP --dport 80 -j DNAT --to-destination $WEB_SERVER:80

It should be noted that if a port other than the $FORWARD_TCP_PORTS list is forwarded, then it must be added there, because it will be dropped by the default policy.
As a result, the iptables script for the gateway will look like this. Different from previous rules.

#!/bin/sh # Clear all iptables rules -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT iptables -t nat -P PREROUTING ACCEPT iptables -t nat -P POSTROUTING ACCEPT iptables -t nat -P OUTPUT ACCEPT iptables -t mangle -P PREROUTING ACCEPT iptables -t mangle -P OUTPUT ACCEPT iptables -F iptables -t nat -F iptables -t mangle -F iptables -X iptables -t nat -X iptables -t mangle -X ### Variables # Interface looking to the Internet INET_IF="eth0" # White IP address belonging to $INET_IF INET_IP="x.x.x.x" # Local network LOCAL_NET="192.168.0.0/24" # IP address of the local web server WEB_SERVER="192.168.0.10" # Enable in the kernel forward IPv4 packets # Path to sysctl SYSCTL="/sbin/sysctl -w" if [ "$SYSCTL" = "" ] then echo "1" > /proc/sys/net/ipv4/ip_forward else $SYSCTL net. ipv4.ip_forward="1" fi ### Default rules iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT ### INPUT # Allow incoming connections from the localhost iptables -A INPUT -i lo -j ACCEPT # Allow accepting already established connections iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow SSH only from the local network iptables -A INPUT -p TCP -s $LOCAL_NET --dport 22 -j ACCEPT # Allow requests to caching DNS server only from the local network iptables -A INPUT -p TCP -s $LOCAL_NET --dport 53 -j ACCEPT iptables -A INPUT -p UDP -s $LOCAL_NET --dport 53 -j ACCEPT ### FORWARD # Allow already established forwarding connections iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # TCP ports on which machines from the local network are allowed to access the Internet FORWARD_TCP_PORTS="80,443" # Allow machines on the local network to access the Internet on the specified TCP ports iptables -A FORWARD -p TCP -s $LOCAL_NET -m multiport --dport $FORWARD_TCP_PORTS -j ACCEPT iptables -A FORWARD -p TCP -d $LOCAL_NET -m multiport --dport $FORWARD_TCP_PORTS -j ACCEPT ### NAT # Enable NAT for the local subnet iptables -t nat -A POSTROUTING -s $LOCAL_NET -o $INET_IF -j SNAT --to-source $INET_IP # Forward a port to the local web server to a non-standard port iptables -t nat -A PREROUTING -p TCP - d $INET_IP --dport 80 -j DNAT --to-destination $WEB_SERVER:8090

Output of current rules

View the rules for the filter table, i.e. the command will show the basic iptables rules:

Iptables -L -n

For a specific table, for example nat and mangle:

Iptables -t nat -L -n iptables -t mangle -L -n

The key concepts of iptables are:

    Rule - consists of a criterion, an action and a counter. If the packet meets the criteria, an action is taken on it and it is counted in the counter. There may not be a criterion - then the criterion “all packets” is implicitly assumed. It is also not necessary to specify an action - in the absence of an action, the rule will only work as a counter. The rules for each chain are triggered in the order they appear, so the order is important.

    • Criteria - a logical expression that analyzes the properties of a packet and/or connection and determines whether this particular packet is subject to the current rule. The criteria are connected by logical “AND”.

      Action - a description of the action that needs to be done with the packet and/or connection if they fall within the scope of this rule. The actions will be described in more detail below.

      A counter is a component of a rule that provides accounting of the number of packets that fall under the criteria of a given rule. The counter also takes into account the total volume of such packets in bytes.

    A chain is an ordered sequence of rules. Chains can be divided into custom and basic.

    • The base chain is the chain created by default when a table is initialized. Each packet, depending on whether it is intended for the host itself, generated by it or is transit, must go through the set of basic chains of various tables assigned to it. In addition, the basic chain differs from the user chain in the presence of a “default policy”. This action applies to those packets that have not been processed by other rules in this chain and the chains called from it. Base chain names are always written in upper case (PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING).

      User chain - a chain created by a user. Can only be used within its own table. It is recommended not to use uppercase names for such chains to avoid confusion with base chains and built-in actions.

    A table is a collection of basic and user chains united by a common functional purpose. The names of tables (as well as criteria modules) are written in lower case, since in principle they cannot conflict with the names of user chains. When calling the iptables command, the table is specified in the format -t table_name. If not explicitly specified, the filter table is used.

Parsing:

# Dump filter table rules$ sudo iptables-save -c -t filter # Table filter * filter # INPUT, FORWARD, OUTPUT chains, their policies and counters:INPUT ACCEPT [ 19302 :9473669 ] :FORWARD ACCEPT [ 0 :0 ] :OUTPUT ACCEPT [ 5462736 :4247599532 ] # Rule: "" - rule counter, "-A INPUT" - chain, "-i em1 -p tcp -m tcp --dport 22" - criteria, "-j ACCEPT" - action[ 17 :1020 ] -A INPUT -i em1 -p tcp -m tcp --dport 22 -j ACCEPT COMMIT

Architecture

In the netfilter system, packets are passed through chains. A chain is an ordered list of rules, and each rule can contain criteria and an action or transition. When a packet passes through the chain, the netfilter system checks one by one whether the packet meets all the criteria of the next rule, and if so, it performs an action (if there are no criteria in the rule, then the action is performed for all packets passing through the rule). There are a lot of possible criteria. For example, a packet matches the –source 192.168.1.1 criterion if the packet header indicates that the source is 192.168.1.1. The simplest type of jump, –jump, simply forwards the packet to the beginning of another chain. You can also specify an action using –jump. Standard actions available in all chains are ACCEPT (skip), DROP (delete), QUEUE (send to an external program for analysis), and RETURN (return to the previous chain for analysis). For example, commands

Iptables -A INPUT --source 192.168.1.1 --jump ACCEPT iptables -A INPUT --jump other_chain

mean “add the following rules to the end of the INPUT chain: skip packets from 192.168.1.1, and send everything that remains for analysis to the other_chain.”

Chains

There are 5 types of standard chains built into the system:

    PREROUTING - for initial processing of incoming packets.

    INPUT - for incoming packets addressed directly to the local process (client or server).

    FORWARD - for incoming packets forwarded to the output (note that forwarded packets first go through the PREROUTING chain, then FORWARD and POSTROUTING).

    OUTPUT - for packets generated by local processes.

    POSTROUTING - for final processing of outgoing packets.

You can also create and destroy your own chains using the iptables utility.

Tables

The chains are organized into 4 tables:

    Raw - viewed before transmitting the packet to the state detection system. Rarely used, for example to mark packets that should NOT be processed by the state detection system. To do this, the rule specifies the NOTRACK action. Contains PREROUTING and OUTPUT chains.

    Mangle - contains rules for modifying (usually the header) IP packets. Among other things, it supports TTL (Time to live), TOS (Type of Service), and MARK actions (for changing the TTL and TOS fields, and for changing packet markers). Rarely necessary and may be dangerous. Contains all five standard chains.

    Nat - Looks only at packets that create a new connection (according to the state detection system). Supports DNAT, SNAT, MASQUERADE, REDIRECT actions. Contains PREROUTING, OUTPUT, and POSTROUTING chains.

    Filter - main table, used by default if the table name is not specified. Contains the INPUT, FORWARD, and OUTPUT chains.

Chains with the same name, but in different tables, are completely independent objects. For example, raw PREROUTING and mangle PREROUTING usually contain a different set of rules; packets first go through the raw PREROUTING chain, and then through the mangle PREROUTING chain.

States

In the netfilter system, each packet passing through the state mechanism can have one of four possible states:

    NEW - the package opens a new session. A classic example is a TCP packet with the SYN flag.

    ESTABLISHED - The packet is part of an already existing session.

    RELATED - The package opens a new session associated with an already open session. For example, during a passive FTP session, the client connects to port 21 of the server, the server tells the client the number of a second, randomly selected port, after which the client connects to the second port to transfer files. In this case, the second session (file transfer on the second port) is associated with an already existing session (the original connection to port 21).

    INVALID - all other packages.

Diagram of the passage of tables and chains

Simplified diagram of the passage of tables and chains:

Detail diagram:

Basic configuration

Below is an example of a basic static iptables configuration. When saving and loading such a configuration, you must take into account the possibility of changes to it from other services, for example Fail2ban. Additionally, when using IPv6 addressing, configuration for IPv6 should be done independently of IPv4.

IPv4

sudo iptables-save

Create a script with a dump of iptables rules:

sudo nano / etc/ network/ if-up.d/ iptables-rules

Copy the following code:

#!/sbin/iptables-restore -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -m conntrack -- ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -p icmp -j ACCEPT -A FORWARD -j REJECT --reject-with icmp-host-prohibited #-A OUTPUT -p icmp -j ACCEPT #-A OUTPUT -o lo - j ACCEPT #-A OUTPUT -j REJECT --reject-with icmp-host-prohibited COMMIT

We supplement with the necessary rules taking into account iptables-save.

sudo chmod +x / etc/ network/ if-up.d/ iptables-rules sudo / etc/ network/ if-up.d/ iptables-rules

IPv6

View current configuration:

sudo ip6tables-save

Create a script with a dump of ip6tables rules:

sudo nano / etc/ network/ if-up.d/ ip6tables-rules

Copy the following code:

#!/sbin/ip6tables-restore # The filter table and its chains* filter:INPUT ACCEPT [ 0 :0 ] :FORWARD ACCEPT [ 0 :0 ] :OUTPUT ACCEPT [ 0 :0 ] # Allow connected and established connections-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # Allow service icmp traffic-A INPUT -p ipv6-icmp -j ACCEPT # Allow trusted traffic to the loopback interface-A INPUT -i lo -j ACCEPT # Additional rules for the INPUT chain can be inserted here # Disable everything else for INPUT-A INPUT -j REJECT --reject-with icmp6-adm-prohibited # The order and meaning of the rules for the FORWARD and OUTPUT chains is similar to INPUT-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -p ipv6-icmp -j ACCEPT -A FORWARD -j REJECT --reject-with icmp6-adm-prohibited # Filtering the OUTPUT chain is strongly discouraged #-A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT #-A OUTPUT -p ipv6-icmp -j ACCEPT#-A OUTPUT -o lo -j ACCEPT #-A OUTPUT -j REJECT --reject-with icmp6-adm-prohibited COMMIT

We supplement with the necessary rules taking into account ip6tables-save.

Save and close: Ctrl + O, Enter, Ctrl + X

Make the script executable and load the iptables rules:

sudo chmod +x / etc/ network/ if-up.d/ ip6tables-rules sudo / etc/ network/ if-up.d/ ip6tables-rules

Additional rules

Below are some relatively commonly used rules. INPUT/OUTPUT chains are used to filter local traffic. For transit traffic, you must use the FORWARD chain.

Remote access

# remote.ssh -A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 22 -j ACCEPT # remote.rdp -A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 3389 -j ACCEPT # remote.vnc -A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 5900 -j ACCEPT

Web and file services

# web.http, web.https -A INPUT -p tcp -m conntrack --ctstate NEW -m multiport -A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 21 -j ACCEPT

Mail and instant messages

# mail.pop3, mail.pop3s -A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 110,995 -j ACCEPT # mail.imap, mail.imaps -A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 143 ,993 -j ACCEPT # mail.smtp, mail.smtps -A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 25 ,465 -j ACCEPT # im.xmpp -A INPUT -p tcp -m conntrack --ctstate NEW -m multiport --dports 5222 ,5223 -j ACCEPT # im.icq.oscar -A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 5190 -j ACCEPT

Network Services

# network.openvpn.vpn -A INPUT -p udp -m conntrack --ctstate NEW -m udp --dport 1194 -j ACCEPT # network.squid.proxy -A INPUT -p udp -m conntrack --ctstate NEW -m udp --dport 3128 -j ACCEPT # network.dns -A INPUT -p tcp -m conntrack --ctstate NEW -m tcp --dport 53 -j ACCEPT -A INPUT -p udp -m conntrack --ctstate NEW -m udp --dport 53 -j ACCEPT # network.ntp -A INPUT -p udp -m conntrack --ctstate NEW -A INPUT -p udp -m conntrack --ctstate NEW -m udp --dport 69 -j ACCEPT # network.dhserver.dhcp.discover-request-A INPUT -p udp -m conntrack --ctstate NEW -m udp --sport 68 --dport 67 -j ACCEPT # network.dhclient.dhcp.discover-request #-A OUTPUT -p udp -m conntrack --ctstate NEW -m udp --sport 68 --dport 67 -j ACCEPT # network.dhserver.dhcp.offer-ack #-A OUTPUT -p udp -m conntrack --ctstate NEW -m udp --sport 67 --dport 68 -j ACCEPT

Testing and Debugging

View the current configuration for IPv4 and IPv6:

sudo iptables-save sudo ip6tables-save

Logging

Tracing

Kernel modules

View loaded modules:

lsmod |

grep -E "^ip|^nf" |

sort