Pages

Sunday, 26 June 2016

ICMPTX (IP-over-ICMP tunnel)

See the current ICMPTX project home page.

Problem

You're sitting in an airport or in a cafe, and people want your money for Internet access. They do allow ICMP traffic, though (i.e., you can ping machines on the Internet). Enters ICMPTX. (If you can't use ping, but you can issue name queries, use NSTX: IP-over-DNS.) There are several resources online to point you in the right direction, most notably Case of a wireless hack by Siim Põder. There is a similar, thoroughly undocument program called itun, a simple icmp tunnel that claims to do the same thing. Also, check out PingTunnel which is not IP-over-ICMP, but rather TCP-over-ICMP and, therefore, less useful.
Once you've followed these instructions, you basically have a remote proxy, providing you with access to the Internet. Communication between you and the remote proxy is over ICMP.
Note that these instructions play nicely with NSTX. You can run both on one proxy.

Keywords

icmptx, ip-over-icmp, firewall piercing, ping, icmp, tunnel, ifconfig, route, tun/tap, tun0.

Solution: icmptx

The tarball below is based on slightly buggy code I found through Siim Põder's page. I modified it ever so slightly, but I deserve no credit at all. Also, if you destroy everything or anything using this program, I am not responsible.
You'll need two copies of icmptx-0.01.tar.gz; one copy for the server, one copy for the client.
Download and compile. For example:
$ wget -O - http://thomer.com/icmptx/icmptx-0.01.tar.gz | tar xvfz -
$ cd icmptx-0.01/
$ make

Proxy-side icmptx setup

You'll need a machine connected to the Internet to serve as your proxy. Make sure the proxy's firewall does not block ICMP traffic. If you can't simply ping the machine, icmptx will surely not work. Also, make sure your kernel supports TUN devices.
After compilation, run the icmptx server as root (assuming the proxy's end of the tunnel is going to be 10.0.1.1):
# ./icmptx -d 10.0.1.1
Now verify you have a tun device:
# /sbin/ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          POINTOPOINT NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

Configure the tun device. Also, ensure the kernel doesn't intercept and reply to pings.
# /sbin/ifconfig tun0 mtu 65536 up 10.0.1.1 netmask 255.255.255.0 
# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
You need to enable forwarding on this server. I use iptables to implement masquerading. There are many HOWTOs about this (a simple one, for example). On Debian, the configuration file for iptables is in /var/lib/iptables/active. The relevant bit is:
*nat
:PREROUTING ACCEPT [6:1596]
:POSTROUTING ACCEPT [1:76]
:OUTPUT ACCEPT [1:76]

-A POSTROUTING -s 10.0.0.0/8 -j MASQUERADE
COMMIT
Restart iptables:
/etc/init.d/iptables restart
and enable forwarding:
echo 1 > /proc/sys/net/ipv4/ip_forward
You can make sure this change (and the modification that disabled echo replies) are permanent by editing /etc/sysctl.conf, and adding:
net/ipv4/ip_forward=1
net/ipv4/icmp_echo_ignore_all=1

Client-side icmptx setup

The client's kernel also needs to support TUN devices. Assuming your proxy's IP address is 212.25.23.52, run as root:
# ./icmptx -c 212.25.23.52
Now setup the tun device:
# /sbin/ifconfig tun0 mtu 65536 up 10.0.1.2 netmask 255.255.255.0
By running /sbin/route -n, figure out what your gateway is. It's the record with the "UG" Flags field. For example:
# /sbin/route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 wlan0
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 wlan0
OK. So "192.168.1.1" is our gateway. Assuming your wireless network device is called "wlan0" (but it might well be "eth1", or whatever), run:
# /sbin/route del default
# /sbin/route add -host 212.25.23.52 gw 192.168.1.1 dev wlan0
# /sbin/route add default gw 10.0.1.1 tun0
Obviously, 212.25.23.52 should be replaced with your proxy's IP address.
If all is well, you should have Internet connection now. All traffic will be tunnelled through your proxy, via ICMP.

Problem: some connections seem to hang

Try increasing the MTU size (that is the number that comes after "mtu" when invoking /sbin/ifconfig). Do this on both the client and the server. Running it with an MTU of 65536 seems to work fine (since, if I recall correctly, that is the maximum IP packet size). If you want to be dead sure that this is not the problem, crank it up.
This problem will only occur if you are behind a firewall that blocks echo reply packets (see TODO, below). More precisely, some firewalls will only allow a single echo reply for a single echo request. If the payload that needs to be stuffed into the ICMP packet is larger than the maximum size of an ICMP packet, you're out of luck. ssh will probably work, fetching small web pages might still work, but your only hope is increasing the MTU.
Bernd Michael Helm wrote in an email to me:
I managed to get around the *hanging connection* problem and speed up icmptx very much: just open a new console and start ping -f 10.0.1.1 (gateway node) so the client will flood the gateway with icmp requests (which will not be answered).With this I was able to get stable connections and improve the http download speed to 210 kb/s which is the full physical bandwith of my internet connection.

Open problems

Note that I do not maintain the code. Please see the current ICMPTX project home page.
As of 2006, three things still needed to happen.
First, icmptx needs to be packaged (preferably for Debian), similar to the Debian nstx package.
Secondly, icmptx needs to deal with small MTUs. Right now you're in trouble if an IP packet is larger than the tun device's MTU. Setting the MTU to 65536 works fine for me, but we need to deal with the situation where that does not work (if intermediate routers refuse large ICMP packets, for example). To compound the problem, a lot of NATs seem to allow only one ICMP echo reply packet per ICMP echo request packet.
An idea that arose in a conversation with Bryan Ford is for the proxy to not only wrap the IP packet in the ICMP packet, but to include an additional header that contains the number of additional ICMP packets required to complete the current IP packet; call this number N. If the IP packet is small enough to fit in one ICMP packet, this number will be zero. If, however, the number is greater than zero, the client responds by sending N ICMP echo requests to the proxy. The proxy uses the N ICMP reply packets to transmit the remaining fragments of the IP packet. This solves both the MTU problem and avoids an intermediate NAT blocking multiple ICMP echo reply packets for one ICMP echo request packet.
Finally, I think the client needs to probe the proxy (similar to NSTX) for pending packets. Currently, only the client can initiate connections. The implementation of this may overlap with the previous point. (Note that John Plaxco seems to have resolved this problem, see the ICMPTX project home page.)

from http://thomer.com/icmptx/
----------------


This is the ICMPTX program.

This software is most recently available from http://github.com/jakkarth/icmptx

ICMPTX is a program that allows a user with root privledges to create a
virtual network link between two computers, encapsulating data inside of
ICMP packets.

-- basic usage instructions --

First, make sure you have the tun module from your 2.6 kernel loaded up
or compiled into your kernel on both ends of your tunnel.

Second, compile the code on both the client machine and the server you
wish to tunnel your traffic between.

Third, on the server side, do something like

./icmpx -s 1.2.3.4 &
sleep 1
ifconfig tun0 10.0.3.1 netmask 255.255.255.0

Fourth, on the client side, do something like

./icmptx -c 1.2.3.4 &
sleep 1
ifconfig tun0 10.0.3.2 netmask 255.255.255.0

Replace 1.2.3.4 with your internet-accessible IP on the server. At this
point you should have a simple link between the client and server. On
the client, you should be able to ping 10.0.3.1 and get a response. Note
that there are several levels of irony involved in receiving the responses.
SSH tunneling can be used at this point for secure communication over the
channel. Note that there is no encryption capability provided directly by
ICMPTX.

Once you've confirmed that the tunnel does in fact work, routing should be
easily accomplished. The tun interfaces are just like any other ethernet
devices on your system and can be used as such, for example:

route add -net 192.168.0.0/24 gw 10.0.3.1

executed on the client could add a route to your server's DMZ segment.
Access to systems on the 192.168.0.0/24 subnet from the client would
then be transparently tunneled through the ICMPTX connection.

-- who's to blame for all this? --

ICMPTX has an interesting lineage. The code for the ICMP handling was
originally included from the itunnel program. Tun interface handling
was included from the VTun project, originally authored by Maxim
Krasnyansky. The two were brought together by edi / teso. From there,
Siim Põder cleaned up the code and wrote a short article about it,
possibly still available at http://www.linuxexposed.com/content/view/153/52/ .
That seems to be where Thomer Gil found it, after which he further cleaned
it up and presented it at http://thomer.com/icmptx/, which is where I,
John Plaxco, came across it. 
from http://github.com/jakkarth/icmptx
 
类似的项目:https://github.com/pechy/icmptun
不过icmptun和ICMPTX 一样,都只支持linux桌面系统,不支持mac.
https://sourceforge.net/projects/itun/
-------------
 
fraud-bridge 
ICMP and DNS tunneling.

Initially, this project was named cloud-bridge when I realized
that this name was already registered with a lot of companies.
It was of course actually not made to do what the name might suggest.
fraud-bridge does nothing new and can well be substituted by already
exiting tools like icmptx, iodine, ozzyman DNS, nstx etc.

So when I was forced to look for a new name for my project,
something that might sounds similar to "cloud", I ended up
at "fraud." (In german "Maut" may also would make sense, but
nobody would get the joke!)

So why yet another tunneling tool? Why should I use fraud-bridge instead
of icmptx/nstx etc, you might ask?
Answer: You shouldnt. Stick with what works for you. This project
is just for my own understanding of kernel (tuntap) internals and
protocol playings.

fraud-bridge allows to tunnel TCP connections through ICMP, ICMPv6, DNS
via UDP or DNS via UDP6.

It automatically patches TCP MSS option to achieve a non-fragmented stream
of packets. It also uses MD5 to (HMAC-)integrity protect the tunnel
from evil injected TCP packets. If you need privacy, you must use encryption
yourself. Its assumed that you use SSH over the tunnel anyways.
(Either directly or with the SSH proxy option if you need HTTP tunneled.)

fraud-bridge also uses EDNS0 extension headers to put as many bytes into
the TXT reply as possible. In my tests, as it tries to answer any timing
packets, it produces no logs in a bind9 system logfile. If you change
the EDNS0 (-E), you need to do it on both ends with the same value.
(As inside announces maximum UDP payload size to the nameserver and outside
endpoint calculates the MSS from that what was given with -E.)

fraud-bridge also includes some other techniques to cope with
certain bind limitations, e.g. quotas/limiting.

After start, it opens a point-to-point tunnel 1.2.3.4 <-> 1.2.3.5
You then need to start "inside.sh" on the inside and "outside.sh"
on the outside (on outside it can be at any given time before,
it basically prevents kernel from ICMP replies and assigns the IPs).

Looks like so:

# ./fraud-bridge -u -R 127.0.0.1 -D f.sub.dnstunnel.com -k key
(and starting inside.sh)

And on outside end of tunnel (e.g. the internet):
# ./fraud-bridge -u -L 192.168.2.222 -D f.sub.dnstunnel.com -k key
(and starting outside.sh)

for a DNS tunnel with a local (127.0.0.1) named running and
the outside peer being at 192.168.2.222. As said, outside part of
tunnel can (and actually needs to) be started beforehand and will just
listen for the peer to open the tunnel. Example zonefiles are included.

You can then use "ssh -x -v 1.2.3.5" to get a SSH connection to
192.168.2.222.

You can also do that with ICMP (-i) and ICMP on IPv6 (-I) or DNS on UDP via
IPv6 (-U).
It's also possible to switch tunnel from DNS to ICMP beyond your SSH connection,
as the TCP state is kept in local and remote kernel and not in the bridge.

fraud-bridge will leave stdout open for reporting errors or verbose messages,
so you need to run it on a screen or redirect output to /dev/null if you need it running in background.
 
from https://github.com/stealth/fraud-bridge
---------- 
 
相关帖子:
http://briteming.blogspot.com/2012/03/icmp-tunnelvpnpython.html