Hi,
I'm experimenting with a new GL-X3000 and would like to have traffic use a TTL of 64 going out of the modem. Normal behavior is for clients to use a TTL of 64, which is decremented by 1 by the router, causing packets to leave the modem interface with TTL value 63. I'd need that to be 64.
This can quite easily be achieved by setting a TTL value of 64 on the modem interface (through the GUI), or adding an iptables rule like this:
iptables -t mangle -I POSTROUTING 1 -j TTL --ttl-set 64
This works as expected. All outgoing packets have their TTL reset/forced to a value of 64.
However. Obviously, exactly as expected, this means that the TTL is always set to a value of 64. This also applies to traffic types where the application (on the client device) actually relies on using a different TTL value to function. Most obvious example is traceroute, which uses TTL to determine the hops in between client and target. A packet with TTL=1 will cause the first router to respond, TTL=2 will cause the second one to respond, and so on. That's how traceroute determines the path that packets are taken throughout the network/internet.
By forcing the TTL to always be 64 that no longer works. The first traceroute packet sees its TTL updated from 1 to 64... causing the packet to reach the destination (rather than only the first router) and traceroute to report that the destination is directly available in the local LAN. Which, obviously, is incorrect. This is the case for traceroute, but applies to all applications that rely on a non-standard TTL.
What I'd want to do is update the outgoing TTL ONLY if the TTL equals 63 (Linux/Mac clients) or 127 (Windows clients). That's regular traffic, and only that traffic should see the TTL be set to 64. Other traffic should not be changed as it was purposefully using a non-standard TTL.
So, how can we achieve this. The most straightforward method would be by adding a filter to the mangle command. And we'll need two rules rather than just one, for Linux and Windows clients:
iptables -t mangle -I POSTROUTING 1 -j TTL --match ttl --ttl-eq 63 --ttl-set 64
iptables -t mangle -I POSTROUTING 1 -j TTL --match ttl --ttl-eq 127 --ttl-set 64
Resulting in the following rules:
root@GL-X3000:~# iptables -L -t mangle | grep -i ttl
[...] TTL match TTL == 127 TTL set to 64
[...] TTL match TTL == 63 TTL set to 64
root@GL-X3000:~#
I have tested the above and can confirm that this works. Normal traffic from clients has TTL 64, while special traffic (like traceroute) using non-standard TTL values passes through without being affected.
However from what I understand it is also bad practice to apply filters in the mangle table. Perhaps there is a better/smarter way of doing this? Any suggestions?