Total Pageviews

Wednesday 27 June 2018

Tunnel Daemons

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
Warning, these are only the server side end-points of the tunnels, for client-side setup pls see: http://www.ctrlc.hu/~stef/blog/posts/Tunnel_daemons.html

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.
The setup with the most effort seems to be also the most reliable, an iodine based link over DNS can break out of a lot of networks. If we can use HTTP to browse but other services are restricted then the httptunnel is adequate. For less setup-hassle but increased latency Tor tunnels also deliver reliably. The usefulness of ICMP and CurveCP tunnels depend on the firewall configuration, but if they work, they're pretty fast.

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.pem
Set 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).0
Now start the stunnel:
sudo stunnel -c -d 127.0.0.1:8888 \
       -r <server-address>:443 \
       -s stunnel4 -g stunnel4 -P '' -a . -v 3
We 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:8888
The 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 serverkey
convert the key to hex, and store it on the client in serverkey.hex:
curvecpprintkey serverkey > serverkey.hex
run 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 lines
HiddenServiceDir /var/lib/tor/sshtun/
HiddenServicePort 22 127.0.0.1:22
to 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