iptables rules that every Linux user should have - part one
Or Yaacov
Posted on April 17, 2023
After that I read about another cyber attack, again, as a software engineer in Zero Networks, I asked myself what the hell is going on in my network? who tries, or even worse succeeds communicating with my machine? and is my machine trying to talk to specious servers without me knowing? Well, let's create some iptables rules that will help answer those questions
Step 1 - Log chains
iptables has 3 action chains, Drop, Reject, and Accept. Let's create 3 new chains, which will log any NEW connection attempt, and then perform the wanted action:
sudo iptables -N LOG_AND_ACCEPT
sudo iptables -A LOG_AND_ACCEPT -m conntrack --ctstate "NEW,RELATED" -j LOG --log-prefix '[OY-A]:' --log-level 7
sudo iptables -A LOG_AND_ACCEPT -j ACCEPT
sudo iptables -N LOG_AND_DROP
sudo iptables -A LOG_AND_DROP -m conntrack --ctstate "NEW,RELATED" -j LOG --log-prefix '[OY-D]:' --log-level 7
sudo iptables -A LOG_AND_DROP -j DROP
sudo iptables -N LOG_AND_REJECT
sudo iptables -A LOG_AND_REJECT -m conntrack --ctstate "NEW,RELATED" -j LOG --log-prefix '[OY-R]:' --log-level 7
sudo iptables -A LOG_AND_REJECT -j REJECT
by running those commands, we are generating the following 3 new chains which logging (with special prefix [{two letters}-{ACTION}]):
chain: LOG_AND_ACCEPT, log prefix: [OY-A]
chain: LOG_AND_DROP, log prefix: [OY-D]
chain: LOG_AND_REJECT, log prefix: [OY-R]
the log prefix will help us find our records, or even to separate our records to another file using rsyslog
(please let me know if you wish me to write a guide on how to do that)
Converting existing rules
If you already have rules, all you need to do is to convert any existing rule target from:
ACCEPT -> LOG_AND_ACCEPT
DROP -> LOG_AND_DROP
REJECT -> LOG_AND_REJECT
Step 2 - Inbound
well, I'm using my system76 machine (powered by arch ❤) as a client, so I don't expect any kind of EXTERNAL INBOUND traffic at all, so let's see how to block it without affecting internal machine communication (e.g. docker containers)
Log and drop incoming external traffic
before that, we will add our inbound protection rule, let's take it apart and see how it works:
- Match new inbound connections only - since iptables operate at the packet level, we don't wish to drop packets that are a response to our own initiated outbound communication. e.g. we are initiating a DNS query to resolve yaacov.dev address, we do not wish to block the response to that request.
- DROP vs Reject both DROP and REJECT actions will prevent packets from being processed, but using REJECT will show attackers that your machine exists and refuse to accept packets. by using DROP we simply ignore the packets, and the attackers won't know that your machine exists or is "online" and will usually timeout.
- Network devices well, lots are going on our machines, and programs such as docker are creating iptables rules to make everything work behind the scenes. Instead of dropping all of the new inbound packets, we need to drop only packets that come from our ethernet/wifi or another network device that connect us to the network. Internal loopback/docker or any other virtual interface will stay untouched.
you can list your networks devices by running the following command:
ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
link/ether ff:ff:ff:ff:ff:ff brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether ff:ff:ff:ff:ff:ff brd ff:ff:ff:ff:ff:ff
since I'm using my Wifi I'll use wlan0
So, after understanding all of that let's create our first real firewall rule!
sudo iptables -A INPUT -m conntrack --ctstate "NEW,RELATED" -i wlan0 -j LOG_AND_DROP
- -m conntrack - ctstate "NEW,RELATED": use the conntrack module to apply this rule only on:
NEW: Represents the start of a new connection. It is typically used to track the initial packet of a new connection attempt.
RELATED: Represents related connections, such as those associated with an existing connection. For example, FTP data connections are considered RELATED to the original FTP control connection
- -i : networks interface (you can add multiple rules for multiple network devices)
Step 3 - Outbound
so since I'm using my machine as a client and I'm over 18, I don't wish to restrict myself from imitating any kind of communication, but I surely want to know about each one of them, and make sure that my machine doesn't talk to other machines that I don't want it to talk to.
we can do that by setting an outbound rule of LOG_AND_ACCEPT, this way, any new communication will be logged and we could examine it later.
sudo iptables -A OUTPUT -m conntrack --ctstate "NEW,RELATED" -j LOG_AND_ACCEPT
Step 4 - Persistence
well iptables, isn't persistence, which means that after a restart all of the rules that you had will disappear. But there are a few ways to make iptables persistent. you can read about here: 3 ways to make iptables persistent
Step 5 - analyze
I will create a complete guide and share some of my own scripts about how to analyze your iptables logs and see when and with who our machine talked or tried to talk at least. (Please let me know if you wish another guide about how to analyze and personal tools)
Posted on April 17, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.