Table of contents
- Introduction
- Why?
- SSH > SSH > VPN
- TOR > SSH > VPN
- HTTPS > SSH > SSH > VPN
- TOR > HTTPS > SSH > VPN
- SSH > SSH > SSH > SSH > SSH > SSH > VPN
- What's next?
- Update
Introduction
The SSH and HTTPS tunneling pages explain how to obfuscate your VPN traffic so that it doesn't look like VPN traffic, but it doesn't explain how it's also possible to chain several tunnels together. That's what this page is for.
Our multihop page explains how to do this with OpenVPN, even with different VPN providers (and/or Tor), but the downside is that each cryptostorm hop in the chain would be considered a separate session, so your session counter would increase for each hop. For people with one week or one month access tokens that are limited to one simultaneous connection, they would only be able to do one hop. You can get past that limitation by chaining our SSH tunnels instead, and you can still add Tor to the mix.
The examples below require the OpenBSD version of netcat, not the GNU one. That's because the OpenBSD version includes SOCKS support, which we'll be using. To verify that you have that one, open up a Terminal and run the commands:
df@x:~$ nc -h 2>&1|grep SOCKS -X proto Proxy protocol: "4", "5" (SOCKS) or "connect"
If you see that -X proto line there, then you've got the OpenBSD version.
You'll also need the OpenSSH client installed, but almost all Linux distributions include that already.
Also, all of these setups only work with TCP OpenVPN, NOT UDP. So make sure you're downloading the OpenVPN configs that end with "_TCP.ovpn"
If you want to mix things up and create your own chain not listed here, keep in mind that our HTTPS tunnels can only connect to the server the tunnel runs on (I.e., stunnel on paris.cstorm.is can only connect to ports on paris.cstorm.is), but the SSH tunnels can connect to any cryptostorm server.
Why?
Most people probably don't need to chain tunnels like this. It's usually unnecessary because the other users on the nodes act as a kind of plausible deniability. If you ever end up in a situation where someone's trying to track you down, and they know of a website (or whatever) that you're accessing at a certain time, and they also know that you're accessing our VPN server around the same time, and that our server is accessing that website around the same time, then in that unlikely scenario it might be enough to prove culpability, if it weren't for the other users on the server. The packets they'd have to look at between you and us would be encrypted, and your traffic is right next to the person torrenting the latest Marvel movie or whatever, so there's no way to tell if it's you accessing that website or the other users.
Even so, there's still some threat models where chaining tunnels could be useful. Each hop in the chain acts as a buffer between you and the destination, making it that much harder to figure out where you're actually coming from. Normally the VPN by itself is plenty buffer, but the above correlation example might be enough to prove culpability if you're in a region with draconian laws. In that case, it would be useful if the server you're sending your traffic to isn't the same one the internet sees your traffic coming from.
This is also true if you're on any sort of heavily monitored network. There was a famous case back in 2013 where a Harvard student wasn't prepared for a final exam, so he loaded up Tor and sent a bomb threat in hopes that the exam would be postponed. He did this from Harvard's Wi-Fi network, and since he was the only one on the network using Tor at the time, it wasn't hard to correlate the traffic. We're not condoning doing something as incredibly stupid as using our service to send out bomb threats, but hypothetically, if he would have connected to one of our SSH tunnels first, then the VPN service, then Tor, it would have been much more difficult to track him down. Most college networks have people SSHing into remote servers at all hours (especially the computer science department), so SSH traffic wouldn't have looked unusual, and since the bomb threat would have came from Tor the feds wouldn't find anything when looking on Harvard's network to see who accessed Tor at that time.
SSH SSH VPN
All of our VPN server IPs can be used to tunnel SSH on any TCP port (well, 1-29999), and each of those servers can connect to any of the other servers.
For this example, we'll use our Las Vegas node as the first hop. The full node list is at https://cryptostorm.nu/nodes.txt
Open up a Terminal window and run the command:
df@x:~$ ssh -N -D 127.0.0.1:1080 sshtunnel@vegas.cstorm.is
If this is your first time connecting it'll ask you to verify the fingerprint, just type yes then press enter to continue.
It'll ask you for the password, which is the same as the username: sshtunnel
After you type in the password and press enter, it'll appear to just sit there doing nothing, but the tunnel is active.
So leave that window open.
For the second hop, open a new Terminal window and type in the command:
df@x:~$ ssh -N -D 127.0.0.1:1081 -o"ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:1080 %h %p" sshtunnel@austria.cstorm.is
Again, accept the fingerprint, then type in the password (sshtunnel) and press enter.
Finally, grab one of the TCP OpenVPN configs from https://cryptostorm.is/configs/ (if you haven't already), open it up in a text editor and add the lines:
socks-proxy 127.0.0.1 1081
route vegas.cstorm.is 255.255.255.255 net_gateway
That route line is only needed for the first SSH session. It adds a static route that tells your system to use the current default gateway, since that gets changed after you connect to the VPN. You only need it for the first SSH session, since the second happens between the Vegas server and the Austria server, you don't actually connect to that Austria server.
Next, connect using that config like you normally would (openvpn --config whatever.ovpn, etc.)
The end result is that your traffic is going first through the Vegas tunnel, then through the Austrian tunnel, then to the VPN server.
TOR SSH VPN
This setup would help those who don't trust that our servers (or the data centers that house them) aren't logging IPs, but it also helps with the scenario where you don't want the Tor exit node to see you using a VPN protocol (only SSH).
First, load up Tor Browser like you normally would. That'll also start a local SOCKS proxy on 127.0.0.1 port 9150, so we'll connect to the SSH tunnel using that. Again, we'll use vegas.cstorm.is for this example.
Open up a Terminal and type the command:
df@x:~$ ssh -N -D 127.0.0.1:1080 -o"ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:9150 %h %p" sshtunnel@vegas.cstorm.is
Enter sshtunnel for the password and press enter. It'll idle after that so just minimize that window.
Next, grab a TCP config from https://cryptostorm.is/configs/ and add to it:
socks-proxy 127.0.0.1 1080
route $TOR_IP_CHANGEME 255.255.255.255 net_gateway
As with the above setup, you'll need to add a static route for the Tor IP that you connected to with the previous command. The $TOR_IP_CHANGEME part needs to be changed to that IP. To find it, run this command and you should see the Tor IP that you're connected to:
root@x:~# netstat -nap | grep tor
tcp 0 0 127.0.0.1:9150 0.0.0.0:* LISTEN 626/tor
tcp 0 0 127.0.0.1:9150 127.0.0.1:42474 ESTABLISHED 626/tor
tcp 0 0 10.1.10.22:44142 217.182.198.95:443 ESTABLISHED 626/tor
tcp 0 0 10.1.10.22:44138 217.182.198.95:443 ESTABLISHED 626/tor
In this example, I'd change the above $TOR_IP_CHANGEME to 217.182.198.95
After you make that edit in your OpenVPN config, connect like you normally would (openvpn --config whatever.ovpn, etc.)
The end result is that your traffic is routed through Tor, then the Vegas SSH tunnel, then to a VPN server.
HTTPS SSH SSH VPN
This setup would be useful if you're on a network where SSH and VPN traffic is blocked, but HTTPS is allowed. It also might be handy if you're on a network where you're trying to blend in with everyone else, but nobody else is using SSH or a VPN, but they are using HTTPS. The extra SSH hops in-between just put more separation from you and the VPN server.
For the first step, we'll use stunnel to connect to the HTTPS tunnel. Instead of rewriting the same instructions, just head over to https://cryptostorm.is/blog/https-tunnels and follow the steps for getting stunnel up in running (skip the OpenVPN step at the end). In the examples there the HTTPS tunnel on paris.cstorm.is is used.
Once you have stunnel up and running, it should be listening on 127.0.0.1 port 31337, forwarding to the stunnel server on paris.cstorm.is port 443 (or whatever node/port you might have changed it to).
The next step is to open up a Terminal and type the command:
df@x:~$ ssh -N -D 127.0.0.1:1080 sshtunnel@127.0.0.1 -p31337
Enter sshtunnel for the password then press enter.
Unlike our SSH tunnels (which can connect to any cryptostorm server), the HTTPS tunnels can only connect to the server running the tunnel. So for this hop, you're actually connecting to stunnel on paris.cstorm.is, then to the SSH server also on paris.cstorm.is. From that point you can connect to other cryptostorm servers.
To get to the next SSH hop, open up another Terminal window and type in:
df@x:~$ ssh -N -D 127.0.0.1:1081 -o"ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:1080 %h %p" sshtunnel@vegas.cstorm.is
Again, enter sshtunnel for the password and press enter. For this hop we're using the Las Vegas SSH tunnel.
Finally, you can connect to OpenVPN. Open a new Terminal, download any of the TCP configs from https://cryptostorm.is/configs/ and add to it:
socks-proxy 127.0.0.1 1081
route paris.cstorm.is 255.255.255.255 net_gateway
That route line is set to paris.cstorm.is because that's the server used in the example on the https tunneling tutorial. If you change the connect line in your stunnel.conf to a different server, then you would also change it here in your OpenVPN config.
Then connect like you normally would (openvpn --config whatever.ovpn, etc.)
The final result is that your traffic will look like HTTPS going to paris.cstorm.is, but it's really going through the SSH tunnel also on paris.cstorm.is, then through the SSH tunnel on vegas.cstorm.is, then finally to whichever VPN server you choose.
TOR HTTPS SSH VPN
As with the TOR SSH VPN setup above, this one would also help those who don't trust that our servers (or the data centers that house them) aren't logging IPs, but also with the scenario where you don't want the Tor exit node to see you using a VPN protocol or SSH (only HTTPS).
First, load up Tor Browser like you normally would, which starts a local SOCKS proxy on 127.0.0.1 port 9150.
The next part is tricky since stunnel doesn't actually support SOCKS proxies. To get past that, install (if you don't already have it): torsocks. It'll allow any internet client to use that SOCKS proxy Tor started, even if the client doesn't support SOCKS.
The default torsocks.conf is usually at /etc/tor/torsocks.conf (if you installed from a package manager). It defaults to the Tor server at 127.0.0.1 port 9050, but since you're using Tor Browser, that needs to be changed to port 9150.
So edit /etc/tor/torsocks.conf (or wherever torsocks.conf is) and change the TorPort 9050 line to TorPort 9150
If it's commented out, i.e. there's a # in front of it, remove that first.
Next, follow the steps from https://cryptostorm.is/blog/https-tunnels to configure stunnel, but instead of starting it with the usual `stunnel` command, you're going to start it with the command `torsocks stunnel`
Once that's all done, you'll connect to the local stunnel to start to the SSH tunnel:
df@x:~$ ssh -N -D 127.0.0.1:1081 sshtunnel@127.0.0.1 -p31337
Finally, you can connect to OpenVPN. Open a new Terminal, download any of the TCP configs from https://cryptostorm.is/configs/ and add to it:
socks-proxy 127.0.0.1 1081
route $TOR_IP_CHANGEME 255.255.255.255 net_gateway
As with the TOR SSH VPN setup, you'll need to add a static route for the Tor IP that you connected to with the torsocks stunnel command. That's what the above route line does. The $TOR_IP_CHANGEME part needs to be changed to that IP. To find it, run this command and you should see the Tor IP that you're connected to:
root@x:~# netstat -nap | grep tor
tcp 0 0 127.0.0.1:9050 0.0.0.0:* LISTEN 626/tor tcp 0 0 10.1.10.22:44142 217.182.198.95:443 ESTABLISHED 626/tor tcp 0 0 127.0.0.1:9050 127.0.0.1:42528 ESTABLISHED 626/tor
In this example, I'd change the above $TOR_IP_CHANGEME to 217.182.198.95
After that, connect like you normally would (openvpn --config whatever.ovpn, etc.)
The final result is that your traffic goes first through Tor, then from their exit node it'll look like HTTPS traffic going to paris.cstorm.is (if you didn't change the node from the example), but it's really going through the SSH tunnel also on paris.cstorm.is, then finally to whichever VPN server you choose.
SSH SSH SSH SSH SSH SSH VPN
You probably shouldn't do this (it'll be slow), but it is possible.
As with the other SSH tunnels, the password is always sshtunnel
For each hop you'll leave that window open and start a new one.
If you don't want to do that you can instead use the -f parameter with `ssh` to have each tunnel start in the background, but personally I'd rather have them all in separate windows so I can see any errors that might have broken the chain.
For the first hop, we'll use our Las Vegas node. Open up a Terminal window and run the command:
df@x:~$ ssh -N -D 127.0.0.1:1080 sshtunnel@vegas.cstorm.is
Then for the second one, we'll do Austria. Open up a new Terminal window and run the command:
df@x:~$ ssh -N -D 127.0.0.1:1081 -o"ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:1080 %h %p" sshtunnel@austria.cstorm.is
For the third, Paris. Open up a new Terminal window and run the command:
df@x:~$ ssh -N -D 127.0.0.1:1082 -o"ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:1081 %h %p" sshtunnel@paris.cstorm.is
For the fourth, Dallas. Open up a new Terminal window and run the command:
df@x:~$ ssh -N -D 127.0.0.1:1083 -o"ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:1082 %h %p" sshtunnel@dallas.cstorm.is
For the fifth, Montreal. Open up a new Terminal window and run the command:
df@x:~$ ssh -N -D 127.0.0.1:1084 -o"ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:1083 %h %p" sshtunnel@montreal.cstorm.is
For the sixth, Sweden. Open up a new Terminal window and run the command:
df@x:~$ ssh -N -D 127.0.0.1:1085 -o"ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:1084 %h %p" sshtunnel@sweden.cstorm.is
And finally, grab a TCP config from https://cryptostorm.is/configs/ and add to it:
socks-proxy 127.0.0.1 1085
route vegas.cstorm.is 255.255.255.255 net_gateway
Change the vegas.cstorm.is to whatever server you connected to in that first ssh command.
Next, just connect like you normally would (openvpn --config whatever.ovpn, etc.)
The final result is that your traffic looks like regular SSH connecting to the first hop, but it's really bouncing through each of the other 5 hops before finally ending up at whichever VPN server you choose. This "bouncing" happens server-side, so it only counts as one cryptostorm session.
What's next?
Next on the todo list is rewriting the old https://cryptostorm.is/multihop page as a blog post here, and include better instructions for adding Tor to that, as well as multihopping with WireGuard.
Update
Forgot to add to the instructions the route xxx 255.255.255.255 net_gateway part for adding static routes that keep the tunnels alive after connecting to the VPN. Updated everything above to include those steps.