NAT translation timeout for DNS on linux - dns

In cisco routers they seem to be able to change the NAT translation timeout for DNS separately from udp.
When port translation is configured, there is finer control over translation entry timeouts, because each entry contains more context about the traffic using it. Non-DNS UDP translations time out after 5 minutes; DNS times out in 1 minute. TCP translations time out after 24 hours, unless a RST or FIN is seen on the stream, in which case it times out in 1 minute.
from: https://community.cisco.com/t5/networking-documents/quot-ip-nat-translation-timeout-quot-command/ta-p/3137012
How can I do this on linux?
When I do sysctl net.netfilter I can find conntrack timeout viables for each protocol such as
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 120
but I can't find any settings for DNS.
Is there a way to change the DNS conntrack timeout viable independently from other udp traffic?
If this is not possible by changing the conntrack settings how can I change the DNS conntrack timeout? (I just want to try this for fun no big reason) Should I write some C code to check each udp packet that goes through the NAT using netfilter and then use conntrack to add it to the table with a different timeout variable?
I'm using Ubuntu 20.04

I was able to change the DNS timeout by using nfct
First create a special contrack timeout policy:
sudo nfct add timeout dns-timeout-test inet udp unreplied 20 replied 20
Then refer to this policy for DNS packages:
iptables -I PREROUTING -t raw -p udp --dport 53 -j CT --timeout dns-timeout-test
Then check the DNS conntrack entry with conntrack -E
Packets with dport 53 will have timeout of 20 instead of the default 30.
[NEW] udp 17 20 src=someaddress dst=someaddress sport=someport dport=53 [UNREPLIED] src=someaddress dst=someaddress sport=53 dport=someaport

Related

Why i see DST="127.0.0.53" on -j REDIRECTed packets?

I am confused about situation in my NATed network. I start dnsmasq on router, with listen-address=192.168.100.1 and -p 5353 option for DNS port. Afterwards, i add iptables rule for hosts inside that network:
iptables -t nat -I PREROUTING -s 192.168.100.0/24 \
-d 192.168.100.1 -p udp --dport 53 -j REDIRECT --to-ports 5353
But this didn't work first time, since my INPUT policy is DROP: when i add this rule, everything starts to work:
iptables -I INPUT -p udp --dport 53 -d 127.0.0.53 -j ACCEPT
I discovered this address with help of -j LOG on my INPUT chain, where i saw packets dropped like SRC=127.0.0.1 DST=127.0.0.53 ..., when NATed host is trying to resolve hostname.
As i am writing automated script that generates correct netfilter rules for situation, i need to know from where this 127.0.0.53 could come from.
I see the same address in /etc/resolv.conf. But i don't understand who's routing this packet to this address when it is "redirected", if even close to understanding what happens.
systemd-resolved sets up a stub listener for dns requests locally on 127.0.0.53:53
try disabling it to proceed sudo systemctl disable systemd-resolved

In-kernel packet forwarding from one port to multiple ports

On a Linux-based system I need data incoming on a TCP port to be automatically redirected to other 50 local ports without going through user-space's send/recv. Each port needs to receive a copy of all incoming traffic. All ports are local to the same machine.
I've discarded the splice syscall due to the limit of one endpoint being a file. I guess that iptables is the right tool for this purpose, but I can't figure out the right syntax for this purpose. It should be something similar to:
iptables -t nat -A PREROUTING -p tcp --dport <in_port> -j REDIRECT --to-ports <out_port1>-<out_port50>
I wonder e.g. if the option -m multiport is needed.

How to packet drop based on tcp option field in linux

I want to drop incoming traffic of my Linux host based on TCP option field.
Like TCP option 30 Multi path TCP.
If packet contain multi-path tcp notation or option field 30, then my Linux host needs drop the connection or packet.
My setup is host 1 <-> host 2 <-> host 3.
Host 1 sends packet via host 2 to host 3.
Host 2 have two interfaces eth0 and eth1.
eth0 connects host 1 and eth1 connects host 3.
When incoming eth 0 packets contains option field 30, I just want to cancel the connection or drop the packets.
I tried iptables string compare, but it didn't works.
The command is,
sudo iptables -I INPUT -j DROP -p tcp -s 0.0.0.0/0 -m string --string "Multipath TCP" --algo bm.
But above rule doesnot stop the multipath TCP to send and receive via host 2 eth0, eth1.
host 2 not able to drop the multi-path TCP (option field 30) traffic.
Is it possible to drop a specif TCP packet based on option field.
First, you need to add the rule in FORWARDING chain on host2 (the reason is the packets are not targeted to host2 and will not hit the INPUT chain).
There is an option available in iptables to match the TCP options. Please try the following iptables command:
iptables -I FORWARD -p tcp --tcp-option 30 -j DROP

Simulate dropped packets on Linux, based on protocol (UDP, TCP etc)

I know I can use tc and netem to do
tc qdisc add dev eth0 root netem loss 50%
This would drop 50% of packets in all of eth0 traffic. However, I would like to specify a protocol (UDP, TCP etc), so only packets of this protocol would be dropped.
This is an annoying feature of iptables. Even though the docs say that DROP silently drops the packet on the floor, it still tells the calling program, causing sendmsg (or whatever) to return setting errno to ENETUNREACH or EPERM. There doesn't seem to be a feature "no really silently drop the packet and don't tell anyone about it".
I have found the following workaround, however: if the packets are going to be leaving your local machine, you can set the TTL to 0 in the mangle table:
iptables -t mangle -A SomeChain -m ttl -j TTL --ttl-gt 0 --ttl-set 0
I have successfully used this to deal with a DoS reflection attack.
Use iptables instead - it has a probability option that should allow you to do this, for example:
iptables -A INPUT -m statistic -p tcp --mode random --probability 0.5 -j DROP
Adjust the various values to match the desired traffic/direction/probability.

Iptables or something to redirect IP in gateway (GNU/Linux)

Im writing a bash scripting to account traffic in my network server:
WAN:eth1 -> GNU/Linux Server:eth0 -> Users
The GNU/Linux server uses squid, bind, QoS, mysql, lighttpd.
After an IP exceed the established quota a new QoS rule is applied for that IP (user) too exist one "flag" to decide when is restored the IP counter to Zero.
Some IPs and subnets work without quotas, other gruop of ips/subnets work with new QoS after quota is exceeded, and now I wanna work with a third group with redirection after quota is exceeded.
When an IP exceed the established quota all http traffic must be redirected to host (lighttpd runing on GNU/Linux ) and DROP all other traffic generated for that IP. In webserver exist a webpage with: "You exceed your daily quote of traffic, please wait "x" hours or call to your provider to purchase an extra navigation package" or something like that.
Is possible using a chain, or how can I do that?.
The most topics that I found in Internet, are related to block all and create a new chain to let out to Internet (not work for me). And other redirect only IP by IP, but how can I create something that a "chain" and attach the IPs to must me redirected to can after restore that IPs easly?
Thanks for help and sorry for my poor English :S.
Are you looking for something like this?
iptables -t nat -A PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -I INPUT 1 -i lo -s 192.168.100.66 -j ACCEPT
iptables -I INPUT 2 -i eth1 -d 192.168.100.66 -j DROP
This will redirect packets from 192.168.100.66 on port 80 to the local webserver on the loopback interface, allow that conversation, then reject all other packets being routed to 192.168.100.66 on the WAN interface.
To restore the connection back to normal you will want to delete those firewall entries:
iptables -t nat -D PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -D INPUT -i lo -s 192.168.100.66 -j ACCEPT
iptables -D INPUT -i eth1 -d 192.168.100.66 -j DROP
Note that iptables itself (well, the xtables-addons extension set providing quota2) can already do the quota matching magic and you can (re)set the values through procfs, combined with REDIRECT as #resmon6 says:
-t nat -s user1addr -m quota2 --name user1 ! --quota 0 -j REDIRECT...
-t nat -s user2addr -m quota2 --name user2 ! --quota 0 -j REDIRECT...
The syntax is a arguably a little odd right now (0 is the initial value only and is independent from the runtime quota test involving the negational !. Noticing this just now, a patch may make it in to unroll this confusing syntax in the future).

Resources