LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (https://www.linuxquestions.org/questions/linux-security-4/)
-   -   Help with iptables for a DNS server. (https://www.linuxquestions.org/questions/linux-security-4/help-with-iptables-for-a-dns-server-4175735785/)

princessgentoo 04-07-2024 03:14 PM

Help with iptables for a DNS server.
 
Hello everyone, I hope all of you are having a great day!
I have a dnsmasq server open to public internet in a VPS because I like to make custom domain modifications there. But many ips connected to my server is reducing my network speed. That is why I want' to limit the use of my dnsmasq server to specific Ips. Since i use many vpns, specifying ips will filter my traffic neatly.
So I added some rules to the INPUT openvpn ip rules I used for my VPN to block all traffic except SSH, VPN and port 53.

In the code I replaced some ips for privacy, IP1 is the ip of my other VPN (which is not the current server), IP2 is the Ip of a server. And SERVERIP is the current server IP. I'm using Ubuntu Jammy Jellyfish with the DNSMasq.

I used some code I found on internet, because by simple logic, if "/usr/sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT" it just working for SSH, something similar must work for DNS just replacing the port. But then tried another code that also included sport and state. I added the 8.8.8.8 which is the Google DNS nameserver, i don't think it goes here but it won't harm the rule adding it.

Code:

[Unit]
Before=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to SERVERIP
ExecStart=/usr/sbin/iptables -P INPUT DROP
ExecStart=/usr/sbin/iptables -A INPUT -p udp --dport 1194 -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -p tcp --dport 22  -j ACCEPT
ExectStart=/usr/sbin/iptables -A INPUT -p udp --dport 53 -s IP1,IP2,8.8.8.8,8.8.4.4 --sport 1024:65535 -d SERVERIP -m state --state NEW,ESTABLISHED -j ACCEPT
ExectStart=/usr/sbin/iptables -A INPUT -p udp --dport 53 -s IP1,IP2,8.8.8.8,8.8.4.4 --sport 53 -d SERVERIP -m state --state NEW,ESTABLISHED -j ACCEPT

ExecStart=/usr/sbin/iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
ExecStart=/usr/sbin/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ExecStop=/usr/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 212.227.145.229
ExecStop=/usr/sbin/iptables -D INPUT -p udp --dport 1194 -j ACCEPT
ExecStop=/usr/sbin/iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT
ExecStop=/usr/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

When I run dig in both the server and the computer connected to VPN IP1.
Code:

dig @SERVERIP google.com
I get:
Code:

;; communications error to SERVERIP#53: timed out
;; communications error to SERVERIP#53: timed out
;; communications error to SERVERIP#53: timed out

The default policies on iptables is accepting except for INPUT which the default policy is Drop.

What I'm doing wrong?

Ser Olmy 04-08-2024 07:21 PM

Not exactly sure what's wrong with your setup (other than the misspelling of "ExecStart" in two places), as you seem to have gotten the port numbers correct. But your ruleset is very strangely ordered and lacks at least one vital component, which may or may not affect the operations of the DNS server:
  • You absolutely need a loopback interface rule in the INPUT chain, as many processes communicate using lo.

  • You should add general rules at the top to allow all ESTABLISHED and RELATED traffic in the INPUT and FORWARD chains respectively. Think about it: For traffic to match these criteria, there would have to have been initial packets that were allowed by other rules.

My suggestions:
Code:

[Unit]
Before=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/iptables -F INPUT
ExecStart=/usr/sbin/iptables -A INPUT -i lo -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -p udp --dport 53 -s IP1,IP2,8.8.8.8,8.8.4.4 --sport 53 -d SERVERIP -m state --state NEW -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -p udp --dport 53 -s IP1,IP2,8.8.8.8,8.8.4.4 --sport 1024:65535 -d SERVERIP -m state --state NEW -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -p udp --dport 1194 -m state --state NEW -j ACCEPT
ExecStart=/usr/sbin/iptables -P INPUT DROP
ExecStart=/usr/sbin/iptables -P OUTPUT ACCEPT
ExecStart=/usr/sbin/iptables -F FORWARD
ExecStart=/usr/sbin/iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
ExecStart=/usr/sbin/iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT
ExecStart=/usr/sbin/iptables -P FORWARD DROP
ExecStart=/usr/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to SERVERIP

ExecStop=/usr/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 212.227.145.229
ExecStop=/usr/sbin/iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT
ExecStop=/usr/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

I added a DROP policy for the FORWARD chain and an ACCEPT policy for the OUTPUT chain, as well as commands to flush the existing ruleset. You may also want to add an interface condition to the FORWARD rule, as your existing ruleset contains a theoretical vulnerability to IP spoofing. I say theoretical, as most (if not all) ISPs will typically drop packets with RFC 1918 source addresses, but I wouldn't want to rely on that.

Also, bear in mind that the server will return an error if the DNS reply doesn't fit inside a single UDP packet, and the client will then switch to TCP/53 which your current ruleset doesn't allow.

princessgentoo 04-10-2024 12:34 AM

Quote:

Originally Posted by Ser Olmy (Post 6494922)
Not exactly sure what's wrong with your setup (other than the misspelling of "ExecStart" in two places), as you seem to have gotten the port numbers correct. But your ruleset is very strangely ordered and lacks at least one vital component, which may or may not affect the operations of the DNS server:
  • You absolutely need a loopback interface rule in the INPUT chain, as many processes communicate using lo.

  • You should add general rules at the top to allow all ESTABLISHED and RELATED traffic in the INPUT and FORWARD chains respectively. Think about it: For traffic to match these criteria, there would have to have been initial packets that were allowed by other rules.

My suggestions:
Code:

[Unit]
Before=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/iptables -F INPUT
ExecStart=/usr/sbin/iptables -A INPUT -i lo -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -p udp --dport 53 -s IP1,IP2,8.8.8.8,8.8.4.4 --sport 53 -d SERVERIP -m state --state NEW -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -p udp --dport 53 -s IP1,IP2,8.8.8.8,8.8.4.4 --sport 1024:65535 -d SERVERIP -m state --state NEW -j ACCEPT
ExecStart=/usr/sbin/iptables -A INPUT -p udp --dport 1194 -m state --state NEW -j ACCEPT
ExecStart=/usr/sbin/iptables -P INPUT DROP
ExecStart=/usr/sbin/iptables -P OUTPUT ACCEPT
ExecStart=/usr/sbin/iptables -I FORWARD -F
ExecStart=/usr/sbin/iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
ExecStart=/usr/sbin/iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
ExecStart=/usr/sbin/iptables -P FORWARD DROP
ExecStart=/usr/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to SERVERIP

ExecStop=/usr/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 212.227.145.229
ExecStop=/usr/sbin/iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT
ExecStop=/usr/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target

I added a DROP policy for the FORWARD chain and an ACCEPT policy for the OUTPUT chain, as well as commands to flush the existing ruleset. You may also want to add an interface condition to the FORWARD rule, as your existing ruleset contains a theoretical vulnerability to IP spoofing. I say theoretical, as most (if not all) ISPs will typically drop packets with RFC 1918 source addresses, but I wouldn't want to rely on that.

Also, bear in mind that the server will return an error if the DNS reply doesn't fit inside a single UDP packet, and the client will then switch to TCP/53 which your current ruleset doesn't allow.

thank you a lot.
The first thing I did was to correct the ExecStart entries I had wrong, and moved the lines like your suggested code, and added the rule for lo interface as well, it was very important the Accept policy in Output. Everything is well with your code, but then I had issues and solved adding this additional line before the Input drop:
Code:

ExecStart=/usr/sbin/iptables -I  INPUT  -i ens6 -m state --state RELATED,ESTABLISHED -j ACCEPT
The issue I was having I wasn't able to connect to websites or query dns from the server itself, therefore, also the DNS service was failing too, however the VPN server was working perfect.


All times are GMT -5. The time now is 03:17 AM.