/*
A while back, I set up a
transparent Squid proxy at my border to limit my exposure to "drive-by downloads." It's a pretty standard setup; Squid running on the gateway/firewall, and iptables configured to route all tcp/80 traffic back into itself on port 3128.
An unfortunate side effect of this is that tcptraceroute breaks. As port 80 is the default port that tcptraceroute uses (as the destination port), you end up with a traceroute that looks something like this:
(root@desktop1) ~# tcptraceroute www.ebay.com
Selected device eth0, address 172.25.X.XXX, port 39068 for outgoing packets
Tracing the path to www.ebay.com (66.135.200.145) on TCP port 80 (www), 30 hops max
1 hp-core.ebay.com (66.135.200.145) [open] 0.558 ms 0.384 ms 0.315 ms
I can assure you, I'm not 1 hop off from www.ebay.com. Since iptables is mangling the packet at the very first hop, my gateway/firewall, I'm receiving the SYN-ACK from that first hop.
Keep in mind, tcptraceroute will use any destination port you specify, but the default is port 80 since it's usually allowed through most firewalls, and often open.
Given that the default TTL of a Linux-based computer is 64, I can use the TTL match in iptables to selectively capture what tcp/80 traffic goes to the proxy and what does not. Consider the following rule:
iptables -t nat -A PREROUTING -i $IF_INT -p tcp --dport 80 \
-j DNAT --to-destination 172.25.X.XXX:3128
This is the rule that routes all outbound traffic, originating on the internal network, to the Squid proxy. Now if we change that rule to match only packets with a TTL larger than, say, 48, we end up with the following:
iptables -t nat -A PREROUTING -m ttl --ttl-gt 48 -i $IF_INT -p tcp --dport 80 \
-j DNAT --to-destination 172.25.X.XXX:3128
With this rule in place, a tcptraceroute headed for www.ebay.com on tcp/80 looks more like the following:
(root@desktop1) ~# tcptraceroute -f6 www.ebay.com
Selected device eth0, address 172.25.X.XXX, port 57684 for outgoing packets
Tracing the path to www.ebay.com (66.135.200.145) on TCP port 80 (www), 30 hops max
6 so-1-2-0.gar2.chi1.bbnplanet.net (4.79.74.1) 76.668 ms 23.024 ms 30.840 ms
7 ae-31-55.ebr1.Chicago1.Level3.net (4.68.101.158) 57.014 ms 34.438 ms 36.097 ms
8 ae-68.ebr3.Chicago1.Level3.net (4.69.134.58) 25.716 ms 22.857 ms 32.941 ms
9 ae-3.ebr2.Denver1.Level3.net (4.69.132.61) 84.660 ms 49.091 ms 40.722 ms
10 ae-1-100.ebr1.Denver1.Level3.net (4.69.132.37) 79.996 ms 52.921 ms 52.897 ms
11 ae-3.ebr2.SanJose1.Level3.net (4.69.132.57) 71.323 ms 70.999 ms 71.651 ms
12 ae-82-82.csw3.SanJose1.Level3.net (4.69.134.218) 66.468 ms 70.863 ms 72.099 ms
13 ae-32-89.car2.SanJose1.Level3.net (4.68.18.132) 65.688 ms 62.794 ms 59.597 ms
14 EBAY-INC.car2.SanJose1.Level3.net (166.90.140.134) 60.576 ms 65.507 ms 58.566 ms
15 10.6.1.158 71.070 ms 59.413 ms 59.670 ms
16 10.6.1.146 61.397 ms 88.846 ms 68.280 ms
17 hp-core.ebay.com (66.135.200.145) [open] 84.341 ms 59.523 ms 62.286 ms
Now that looks a little more reasonable. Given that I'm 1 hop off from the gateway/firewall, and Linux uses a default TTL of 64, then all of my packets generated by, say, Firefox, will come into $IF_INT with a TTL of 64. With 64 > 48, the DNAT rule matches, and the request gets routed through the Squid. As tcptraceroute works like any other traceroute tool, only using TCP SYN packets, the first packet will only have a TTL of 1. With 1 < 48, it does not match the DNAT rule, and passes through unchanged. The second packet will have a TTL of 2, with 2 < 48, and so on. As most all destinations on the internet are reachable in 30 hops or less, this guarantees that my browser generated requests are proxied, while my diagnostic requests are passed through unchanged.
You can view/change your default TTL as such:
(root@desktop1) ~# cat /proc/sys/net/ipv4/ip_default_ttl
64
Needless to say, the IP addresses have been changed to protect the innocent. ;)
*/