iptables rules that every Linux user should have - part one
Tags: iptables, cybersecurity, linux, firewall
Published: 2023-04-17 14:49:11

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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0w8w9xrqiq216ohub4b4.png)


## 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:
1. 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._
2. 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._
3. 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](https://yaacov.dev/#/articles/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)