Skip to content

Instantly share code, notes, and snippets.

@evanscottgray
Last active November 8, 2017 13:47
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evanscottgray/51346ee0a34c935ecaa4 to your computer and use it in GitHub Desktop.
Save evanscottgray/51346ee0a34c935ecaa4 to your computer and use it in GitHub Desktop.
Getting UDP out from behind a restrictive firewall.

Mosh + OpenVPN = Love

Okay. Let's pretend here for a sec that you work in an office where UDP is filtered outbound, but we really want to use UDP for mosh.

Here's the plan at a high level.

  1. Spin up a cloud server
  2. Install Docker
  3. Start OpenVPN Container
  4. Grab .ovpn config
  5. Modify .ovpn config to a include static route to your UDP-enabled destination
  6. Install Tunnelblick and enjoy your mosh goodness

Server Side Config

We'll pretend you already have an Ubuntu 12.04 cloud server spun up at 1.1.1.1, and a server that has mosh installed spun up at 2.2.2.2.

Install Docker

curl get.docker.io | sh

Startup OpenVPN, don't control+c this!

CID=$(docker run -d --privileged -p 1194:1194/udp -p 443:443/tcp jpetazzo/openvpn)
docker run -t -i -p 8080:8080 --volumes-from $CID jpetazzo/openvpn serveconfig

The previous command will give you a URL to hit... Should look something like https://1.1.1.1:8080 or something. This URL is currently serving your OpenVPN config that was dynamically generated.

From a server that can reach that address and port, you need to do this to pull down a copy:

curl -k https://1.1.1.1:8080 > vpn.ovpn

Once you have that vpn.ovpn file on your laptop/mac/desktop/whatever, we're pretty much done with the server side config.

Go back to your SSH session where you have the OpenVPN config thing running, and Ctrl+C the process, that way you are no longer serving your .ovpn config to the world. Don't worry, the OpenVPN container itself will stay running.

Take steps to harden this server however you see fit, typically I change the SSH port and disable root login, etc.

Once you've done that just exit out of that ssh session. Let's modify our vpn.ovpn.

Client Side Config

Open up your vpn.ovpn config file, it should look something like this:

client
nobind
dev tun
redirect-gateway def1

<key>
-----BEGIN RSA PRIVATE KEY-----
Blah
-----END RSA PRIVATE KEY-----
</key>
<cert>
-----BEGIN CERTIFICATE-----
Blah
-----END CERTIFICATE-----
</cert>
<ca>
-----BEGIN CERTIFICATE-----
Blah
-----END CERTIFICATE-----
</ca>
<dh>
-----BEGIN DH PARAMETERS-----
Blah
-----END DH PARAMETERS-----
</dh>

<connection>
remote 1.1.1.1 1194 udp-client
</connection>

<connection>
remote 1.1.1.1 443 tcp-client
</connection>

We need to add the following under redirect-gateway def1

; Mosh Server!!!
route 2.2.2.2 255.255.255.255

This will force our VPN Client to route all traffic destined to the 2.2.2.2/32 network over the VPN tunnel. Yay!

Note, you can also add other networks to this list if you know what you're doing. :D

Since we're also in an office that filters UDP outbound, we'll need to remove the portion about the udp-client so that our vpn client uses TCP. Delete this whole thing:

<connection>
remote 1.1.1.1 1194 udp-client
</connection>

When we're done, it should look something like this:

client
nobind
dev tun
redirect-gateway def1
; Mosh Server!!!
route 2.2.2.2 255.255.255.255

<key>
-----BEGIN RSA PRIVATE KEY-----
Blah
-----END RSA PRIVATE KEY-----
</key>
<cert>
-----BEGIN CERTIFICATE-----
Blah
-----END CERTIFICATE-----
</cert>
<ca>
-----BEGIN CERTIFICATE-----
Blah
-----END CERTIFICATE-----
</ca>
<dh>
-----BEGIN DH PARAMETERS-----
Blah
-----END DH PARAMETERS-----
</dh>

<connection>
remote 1.1.1.1 443 tcp-client
</connection>

Cool. You're done.

Installing a VPN Client

Go grab a copy of Tunnelblick and then import your newly modified vpn.ovpn file, click connect, and you should be good to go!

Now all traffic destined to 2.2.2.2/32 will travel over your OpenVPN tunnel.

Try mosh!

mosh user@2.2.2.2

Protips™

  1. Try traceroute-ing to your server to make sure you're going over your VPN tunnel.
  2. If you're using Tunnelblick, make sure that you turn off 'Validate Public IP Changes'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment