Trying to configure iptables for my Server

My friends,
I’m trying to configure iptables on my Docker Server with Debian Bookworm and kernel 6.12.

I’ve been studying a lot and I’ve “worked a lot” with AI, because I didn’t even know how to work with iptables, but it’s difficult and I needed to go a little further. That’s why I’m asking for your help on a very basic matter.

I want to block full access to the server with the following exceptions:

  • General access to ports 53 (DNS: UDP and TCP), 80 (http: TCP), 443 (https: TCP);
  • Access to port 22 (SSH) via local IP and loopback;
  • Access to the loopback;
  • Two-way communications:
  • Access to a specific port by a specific PC from the local IP (TCP and UDP).

Note: the port number “22” for SSH is just an example because I’m using another port as a security measure

This is the configuration I created:

#!/usr/bin/bash
#Script to configure server iptables

# Flush existing rules:
#iptables -F
#iptables -X

# Set default rules:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow port 53 (DNS: UDP and TCP):
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT

# Allow port 80 and 443 (TCP):
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Allow port  22 (SSH: TCP) only from localhost and local IPs:
iptables -A INPUT -p tcp --dport 22 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 192.168.0.0/24 -j ACCEPT

# Allow loopback interface:
iptables -A INPUT -i lo -j ACCEPT

# Allow established and related connections:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allows access to a specific port of a specific PC from the local IP (TCP and UDP):
iptables -A INPUT -s 192.168.0.20 -p tcp --dport 10000 -j ACCEPT
iptables -A INPUT -s 192.168.0.20 -p udp --dport 10000 -j ACCEPT

# Save the rules:
netfilter-persistent save

# List the rules:
iptables -nvL


This is the list of rules that have already been implemented:
Chain INPUT (policy DROP 39 packets, 8272 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     0    --  lo     *       0.0.0.0/0            0.0.0.0/0           
  735 57814 ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     17   --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    0     0 ACCEPT     6    --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
    0     0 ACCEPT     6    --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    0     0 ACCEPT     6    --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443
    0     0 ACCEPT     6    --  *      *       127.0.0.1            0.0.0.0/0            tcp dpt:22
    1    88 ACCEPT     6    --  *      *       192.168.0.0/24       0.0.0.0/0            tcp dpt:22
    0     0 ACCEPT     6    --  *      *       192.168.0.20         0.0.0.0/0            tcp dpt:10000

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 715 packets, 113K bytes)
 pkts bytes target     prot opt in     out     source               destination

For now, my initial doubt is whether what I've done is really right

I’m not sure if I should use conntrack in connections. From everything I’ve read, it’s recommended for those who use Docker. Do you think otherwise?

I know that the rules I’ve made can be an aberration for those who work with iptables.
What would you change or how would you do it if it were for you?

Thank you in advance for any help you can give me

Jorge

6 Likes

If you want to be really paranoid, I’d put ssh behind port knocking and only turn it on when someone sends the correct knock sequence. Once the user logs off, you could turn ssh off again – it’s kind of hard to hack a server which isn’t running.

4 Likes

Hi Xander,
thank you very much for your reply.

When I read your post my reaction was “WHAT?!”, Port knocking? I’ve heard that before!

I accepted the challenge and went to study what it was and how to implement it.

The concept is very interesting and it’s really as you described:

  • knocks on predefined ports with a predefined sequence, and the SSH port is added to iptables;
  • After the SSH port has finished being used, knock on other predefined ports with another predefined sequence and the SSH port is deleted in iptables.

I’ve just implemented it, but I’m getting an “error”: every time I run the sequence to open port 22 on the client side, the server creates a new rule in iptables to open port 22.
If I run the sequence 10 times, I have to run the close sequence 10 times to close port 22.

This is the example I’m using:

/etc/knockd.conf file

[openSSH]
    sequence = 15000,14000,13000
    seq_timeout = 5
    command = /usr/bin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    tcpflags = syn

[closeSSH]
    sequence = 13000,14000,15000
    seq_timeout = 5
    command = /usr/bin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    tcpflags = syn

I’ve seen lots of examples and they’re all very similar, I’ve even tested with the [opencloseSSH] config, but I keep opening another SSH port.

Note: I don’t have the Server allowing ping replies

Any idea what might be wrong?

Thanks

Jorge

2 Likes

This is interesting indeed - I’d like to try this out - until quite recently I could SSH (non-standard TCP port) to at least one of my RPi4 devices from the world wild intertubes - also running fail2ban…

But - it all stopped working - i.e. NAT rules on my VDSL router. I can only think my ISP started blocking them - why? I’ve logged a ticket anyway. It’s not a service I need them to do for me!

So - if I get this resolved - I’m going to try out port knocking - fascinating stuff!

4 Likes

Hi Daniel,
And from what I’ve tested, you don’t even need to open any more doors to use the knock.
Imagine you have ports 80 and 443 open and both accept TCP and udp.
You can create the sequence with these ports, with udp and tcp, for example:

# open SSH (client side)
knock <server_ip> 80:tcp 443:udp 80:udp 443:tcp

Jorge

4 Likes

Wow!

Logged a ticket with my ISP - within the hour they’ve given me a static IP address and my NAT is working again.

I don’t need a static IP address - as I’m using Dynamic DNS (paid for yearly subscription plan with NoIP).

But I’m not going to complain unless they start charging me extra for a fixed IP address (as this is something you normally pay extra for downunder).

Since they changed my plan - I can see fail2ban logging lots of attempts to SSH (even though I’m not using port 22) and jails being deployed to isolate and ban them (actually just one IP address - registered to AFRINIC - an African IP address registrar I gather)…

So - if I get bored tomorrow - I might have a play with knockd and knock!

Had enough of Linux geek stuff today - got a callout at midnight for an issue on a Linux server - everything was working for me - but the user (an actual Service Desk user) was unable to run the monitoring web URL for one customer - but it was working fine for me - even after I restarted it… So - that lasted till about 2:30 am - and then I didn’t manage to get back to sleep till nearly 5 am…

4 Likes