Tunnel Daemons are stubs for server-side runit-based services providing various means of tunneling ssh traffic.
- htun/htstun provide an stunnel wrapped httptunnel
- iodine deploys a DNS based tunnel
- icmptx provides tunneling via ICMP
- cptun provides tunneling using CurveCP over UDP/53
from https://github.com/stef/tunnel-daemons
-------
客户机器上的Tunnel daemons
Various methods of tunneling ssh connections to pierce through restrictive firewalls. The following setups are evaluated:
- HTTPTunnel+stunnel4, moderately difficult to setup, but once installed it appears as legitimate HTTPS traffic.
- Iodine, setup needs the most effort, however when done and the network allows DNS queries it works quite reliably.
- CurveCP, setup is quite easy, when done the link is encrypted and fast. However the firewalls that allow UDP/53 to pass are somewhat limited.
- ICMPTX, setup is quite easy, however there is no encryption, use it only to tunnel encrypted traffic like ssh and such.
- TOR, setup is easy, usage is a bit delayed due to the latency of the Tor network, requests look like normal HTTPS traffic.
Over HTTPS
This method is generally useful in heavily restricted networks, where
you can only use the web for browsing, but no other services are
allowed.
We use the fine tool httptunnel for masking our ssh connection.
However httptunnel is not encrypted, and thus also the ssh
handshake can be identified in the traffic. To avoid that, we
put a tunnel into our tunnel using stunnel.
On the server
First we need to generate the SSL certificate:openssl req -new -x509 -days 365 -nodes \ -out htcert.pem -keyout htcert.pemSet up an stunnel, make sure to set the ip address, and the user and group exist:
/usr/bin/stunnel -f -r 127.0.0.1:8888 \ -d <public ip address>:443 \ -p htcert.pem -s stunnel4 \ -g stunnel4 -P ''When this is done, we can run httptunnel to connect the sshd with the stunnel:
/usr/bin/hts -w -F 127.0.0.1:22 127.0.0.1:8888
On the client
Get the generated certificate from the server (don't forget to remove
the private key part). You need to rename the cert to it's hash value
and append a '.0':
mv htcert.pem $(openssl x509 -noout -hash -in htcert.pem).0Now start the stunnel:
sudo stunnel -c -d 127.0.0.1:8888 \ -r <server-address>:443 \ -s stunnel4 -g stunnel4 -P '' -a . -v 3We need to set the server address (can be IP or name-based), make sure the user, group exist.
start the httptunnel:
htc -F <httptunnel-port> 127.0.0.1:8888The tunnel will listen on httptunnel-port. Enjoy your ssh-over-https:
ssh -p <httptunnel-port> 127.0.0.1
Over DNS
In some cases internet access is blocked however DNS traffic is
allowed to pass, allowing us to tunnel through DNS.
If you can setup a special DNS entry for this, tunneling through DNS
is very easy using the excellent iodine tool. Follow the
straight-forward installation instructions.Use this method if the network allows resolving of names, even if a local DNS server is forced on us, the tunnel will still work due to recursive queries hitting your "authoritative server".
Hint: you can manage and delegate a DNS zone for free on affraid.org, if you don't have your own.
Using CurveCP on UDP/53
The drawbacks of using any DNS protocol based tunnel like iodine, are
that the tunnel has size-wise a huge protocol overhead, you need to
setup a slightly uncommon DNS configuration and domain names you
control are usually registered on your real name. If the firewall does
not force the usage of a local DNS server and it allows traffic to
UDP/53, then CurveCP tunnel is a preferred option.
Alternatively you could also run on UDP/80 or other allowed UDP ports.On the server
Note: During testing I had to recompile CurveCP as the address family
was missing from the bind call, see the patch at the end of this post.
Create a server key:curvecpmakekey serverkeyconvert the key to hex, and store it on the client in serverkey.hex:
curvecpprintkey serverkey > serverkey.hexrun the curvecpserver:
curvecpserver <your host name> \ serverkey \ <your ip address> \ 53 \ 00000000000000000000000000000000 \ curvecpmessage /usr/sbin/sshd -i
On the client
This depends on socat the excellent swiss-army knife of socket
handling.
Store the serverkey.hex that you generated on the server and run the
client:curvecpclient <curvecpserver hostname> \ $(cat serverkey.hex) \ <curvecpserver ip address> \ 53 \ 00000000000000000000000000000000 \ curvecpmessage \ -C sh -c "/usr/bin/socat tcp4-listen:9999,bind=127.0.0.1,reuseaddr,fork - <&6 >&7"Start your ssh-over-curvecp:
ssh -p 9999 127.0.0.1
Over ICMP
Using ICMPTX you can set up tun devices that tunnel over ICMP, which
is quite handy as in some cases it's not filtered and allows to pierce
through the blockades. ICMPTX creates a local network device, so
tunneling anything is quite easy after setup.
On the server
Simply run(sleep 1; ifconfig tun0 10.0.99.1 netmask 255.255.255.0 )&; icmptx -s <server ip address>
On the client
Simply run
(sleep 1; ifconfig tun0 10.0.99.2 netmask 255.255.255.0 )&; icmptx -c <server ip address>sshing to your box is then a simple:
ssh 10.0.99.1
Using Tor
Tor is great for hiding traffic, it's latency is a bit bigger than usual, but it's quite possible to get work done through tor tunnels even with ssh. If you configure your client-side tor proxy to use a tor bridge that runs on port 443, then the tunnel looks like casual HTTPS traffic.There's two options, you can connect from a tor exit node to your normal ssh server, in this case skip the "On the server" part, and use your normal hostname instead of the .onion address referenced there.
On the server
If you want to run your ssh tunnel as a tor hidden service you simply have to add the following two linesHiddenServiceDir /var/lib/tor/sshtun/ HiddenServicePort 22 127.0.0.1:22to your /etc/tor/torrc. And find out the hostname of your new hidden service with:
cat /var/lib/tor/sshtun/
On the client
You simply need to call the torified ssh:
torify ssh <.onion hostname from server>
Code
Stubs for running the server-side daemons using the excellent runit tool can be found on github. These can be most easily installed using deamonize.sh. For client-side setup use the instructions in this post.curvecp patch
curvecpserver had to be patched, as the address family in the bind call was uninitialized, the patch is below:diff -urw nacl-20110221/curvecp/socket_bind.c nacl-20110221-new/curvecp/socket_bind.c --- nacl-20110221/curvecp/socket_bind.c 2011-02-21 02:49:34.000000000 +0100 +++ nacl-20110221-new/curvecp/socket_bind.c 2012-08-19 02:52:25.000000000 +0200 @@ -9,6 +9,7 @@ { struct sockaddr_in sa; byte_zero(&sa,sizeof sa); + sa.sin_family = AF_INET; byte_copy(&sa.sin_addr,4,ip); byte_copy(&sa.sin_port,2,port); return bind(fd,(struct sockaddr *) &sa,sizeof sa);
from https://www.ctrlc.hu/~stef/blog/posts/Tunnel_daemons.html
No comments:
Post a Comment