Skip to content
/ SOSVPN Public

Create a VPN that tunnels over socat over ssh to evade firewalls

License

Notifications You must be signed in to change notification settings

ngaro/SOSVPN

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 

Repository files navigation

SOSVPN

Create a VPN that tunnels over socat which tunnels over ssh to evade extremely strict firewalls

SOSVPN ( or SOcatSshVPN ) is a VPN-service that has 2 features that most others lack:

  • Only extremely strict firewalls can block it. The only allowed traffic needed is:
    • Outgoing ssh-traffic on the clientside
    • Incoming ssh-traffic on the serverside
  • Even a deep packet inspection firewall can't recognize the traffic as VPN-traffic, it will only see ssh-packets

And a couple of features (some, but not all) other VPN-software has:

  • Traffic from the client meant for the internal network will stay in the internal network
  • All other traffic will be sent over the VPN to the internet with the server acting as gateway

It works by:

  • Creating a virtual network
  • ... that's tunnelled over a socat-tunnel
  • ... that's tunneled over a ssh-tunnel This explains the name SOcatSshVPN.
    Not only is it just as fast as regular ssh-traffic, but by using ssh-compression you can even make it faster then many other VPN's.

This is still version 0.1, here I'm only explaining how to set it up manually.
Interpreted (or compiled) code will follow later.

Example assumptions about your network setup

(Change the settings to match your usecase)

Server

  • Has a user named someuser
  • Has the ip 1.2.3.4
  • Has a networkcard named eths connected to the internet
  • Has a sshserver running on tcp/22789 which is reachable from the internet.
    (It doesn't matter if everything else is blocked)
  • Is not yet using the virtual networkdevice tun0 for other purposes
  • Is not yet connected to a network that overlaps the 192.168.255.0/24 range
  • Is not yet listening on tcp/22001
  • Uses the DNS servers 5.6.7.8 and 9.10.11.12

Client

  • Has the ip 13.14.15.16
  • Has a networkcard named ethc connected to the internet
  • Can create a ssh-connection with the server.
    (It doesn't matter if everything else is blocked)
  • Is not yet using the virtual networkdevice tun0 for other purposes
  • Is not yet connected to a network that overlaps the 192.168.255.0/24 range
  • Is not yet listening on tcp/22002
  • Uses the gateway 13.14.0.254
  • Is on a network containing subnets 13.14.0.0/16 and 15.16.17.0/24 that has the name mylocal.net
  • Is using the DNS servers 15.16.17.1 and 15.16.17.2

Preliminary setup

  • Install the necessary software (iptables, socat, ssh and screen) on the server.
    On debian-based system this can be done with: sudo apt install iptables socat ssh screen
  • Make sure the ssh server runs on the server:
    Check sudo systemctl status ssh and run sudo systemctl restart ssh if you didn't see active (running) in the output.

    From now on you never need physical access to the server anymore.

  • Install the necessary software (route, socat, ssh and screen) on the client.
    On debian-based system this can be done with: sudo apt install net-tools socat ssh screen

Creating the VPN on the client

  • Run screen because we'll need to run different things at the same time
  • Run ssh -L 22002:127.0.0.1:22001 -p 22789 [email protected] inside this screen session
    A ssh session will be opened in window 0 of screen:
    • We can now use this session to run commands on the server without having physical access.
    • The -L option is used for local portwarding to make sure that when the server sends traffic to itself on TCP/22001 it will be encrypted inside ssh-packets and end up at TCP/22002 on the client.
  • Run screen inside this ssh-session.
    We now have a screen session on the client with 1 window (number 0) and inside it a screen session on the server.
    This also has 1 window that is numbered 0.
    This screen session is also needed because we run different things at the same time in the server.
  • Run sudo socat -d -d TCP-LISTEN:22001,reuseaddr TUN:192.168.255.1/24,up inside window 0 of the server on screen. The result:
    • A virtual network device tun0 with ip 192.168.255.1 and netmask 255.255.255.0 will be created
    • The system will start listening to TCP/22001 for traffic from the server itself and interpret it as traffic from a virtual network with the descriptions above.
    • This traffic will be sent to the system over tun0
    • The portforwarding means that it's actually listening to traffic sent to TCP/22002 on the client by the client itself
    • It works bi-directional, so traffic sent out by the system to a system on 192.168.255.0/24 will leave using tun0, will be packed into TCP-packets and these will be tunneled over the ssh-connection to finally end up at TCP/22002 on the client. (-d -d is used for reasonably verbose debug info in case something goes wrong)
  • Press ctrl-a followed by a a and a c to create another window (number 1) in the screen session on the server.
    We will use this to make sure that traffic from the client meant for the outside world will be passed on by the system and is NAT-ed:
sudo iptables -t nat -A POSTROUTING -s 192.168.255.0/24 -j MASQUERADE
sudo iptables -A FORWARD -i tun0 -o eths -j ACCEPT
sudo iptables -A FORWARD -o tun0 -i eths -j ACCEPT
  • Press ctrl-a followed by a c to create another window (number 1) in the screen session on the client.
    Run sudo socat -d -d TCP:127.0.0.1:22002 TUN:192.168.255.2/24,up here. This will create the other endpoint of the tunnel.
    Note that the ip is different (192.168.255.2) but still in the same network as the one on the server (192.168.255.0/24).
    This is necessary to make sure that communication is possible.
  • Press ctrl-a followed by a c to create another window (number 1) in the screen session on the client.
    We will use this make sure traffic is routed correctly:
# Make sure that the server itself is not routed over the VPN:
sudo route add 1.2.3.4 gw 13.14.0.254
# Make sure that the traffic sent to the gateway is sent out using the real network device:
sudo route add 13.14.0.254 dev ethc
# Make sure that traffic meant for our network stays in our network:
for net in 13.14.0.0/16 15.16.17.0/24 ; do sudo route add -net $net gw 13.14.0.254 ; done
# Make sure that all other traffic is sent over the VPN instead of the regular network
sudo route add default gw 192.168.255.1 && sudo route del default gw 13.14.0.254

Setup DNS for the VPN

You probably want your client to resolve internal names using the dnsservers on your network, and the rest of the network using external dnsservers (the ones on your server).
You can do this like this:

  • Install bind (sudo apt install bind9 on debian-based systems)
  • Add the following to /etc/bind/named.conf.local:
zone "mylocal.net" IN {
  type forward;
  forwarders {
    15.16.17.1; 15.16.17.2;
  };
};
  • Place the following in the options {}; section in /etc/bind/named.conf.options:
forwarders { 5.6.7.8; 9.10.11.12; };
allow-recursion { 127.0.0.1; };
querylog yes;
  • Restart your local dns-server: systemctl restart named
  • Make sure you use 127.0.0.1 as dns-server. (The "clean" procedure differs from system to system, the "ugly" sollution of commenting everything in /etc/resolv.conf and adding the line nameserver 127.0.0.1 should work everywhere)

Destroying the VPN

The short version: Use all the steps you used to create the VPN in reverse.

The long version:

  • Attach the screen session with screen -r if it's no longer on your terminal, jump to window 2 with ctrl-a followed by 2.
    You can reset the routing on the client here:
sudo route del default gw 192.168.255.1 && sudo route add default gw 13.14.0.254
for net in 13.14.0.0/16 15.16.17.0/24 ; do sudo route del -net $net gw 13.14.0.254 ; done
sudo route del 13.14.0.254 dev ethc
sudo route del 1.2.3.4 gw 13.14.0.254
exit
  • Jump to window 0 with ctrl-a followed by 0 where the screen session in the ssh-session is running.
    Now jump now to window 1 in this screen session with ctrl-a followed by a followed by 1 and reset iptables here:
sudo iptables -t nat -D POSTROUTING -s 192.168.255.0/24 -j MASQUERADE
sudo iptables -D FORWARD -i tun0 -o eths -j ACCEPT
sudo iptables -D FORWARD -o tun0 -i eths -j ACCEPT
exit
  • You will now end up in window 0 of the screen-session on the server, press ctrl-c here to kill socat. This will also kill the endpoint of the tunnel at the client. Now run the exit command a couple of times until all windows in both screen sessions are killed.
  • Use your original DNS configuration again by:
    • Stopping bind with systemctl stop named
    • Changing your dnsservers back to 15.16.17.1 and 15.16.17.2.
      Again, multiple ways to do this are possible. Placing nameserver 15.16.17.1 and nameserver 15.16.17.2 in /etc/resolv.conf and commenting out the rest should work as "ugly" solution.



SOSVPN is created by Nikolas Garofil and licensed under GPLv3, see the License file for details.

About

Create a VPN that tunnels over socat over ssh to evade firewalls

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published