how to set up a ssh vpn tunnel

on vpn:

dave@vpn [~]$ sudo ip tuntap add dev tun0 mode tun
dave@vpn [~]$ ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          POINTOPOINT NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

dave@vpn [~]$ sudo ifconfig tun0 10.1.1.1 pointopoint 10.1.1.2 netmask 255.255.255.252
dave@vpn [~]$ ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.1.1.1  P-t-P:10.1.1.2  Mask:255.255.255.252
          UP POINTOPOINT NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

sudo sh -c 'echo "PermitTunnel yes" >>/etc/ssh/sshd_config'
# reload sshd (kill -HUP the proc group leader)

# fix dns (resolvconf): /etc/dhcp/dhclient.conf -
supersede domain-name "example.com";
prepend domain-name-servers 172.100.0.1;
request subnet-mask, broadcast-address, time-offset, routers,
    domain-name, domain-name-servers, domain-search, host-name,
        interface-mtu, ntp-servers;

on laptop:

laptop ~ $ sudo ip tuntap add dev tun0 mode tun
laptop ~ $ sudo ifconfig tun0 10.1.1.2 pointopoint 10.1.1.1 netmask 255.255.255.252
laptop ~ $ ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.1.1.2  P-t-P:10.1.1.1  Mask:255.255.255.252
          UP POINTOPOINT NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

laptop ~ $ ssh -f -w 0:0 vpn true
laptop ~ $ ssh -fnN -w 0:0 vpn
laptop ~ $ ps aux | grep 'f -w'
dave     29238  0.0  0.0  48572  1192 ?        Ss   12:35   0:00 ssh -f -w 0:0 vpn true

sudo route add -net 172.31.0.0/16 gw 10.1.1.1

laptop ~ $ netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG        0 0          0 eth0
10.1.1.0        0.0.0.0         255.255.255.252 U         0 0          0 tun0
172.31.0.0      10.1.1.1        255.255.0.0     UG        0 0          0 tun0
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0

laptop ~ $ ping 172.31.9.0
PING 172.31.9.0 (172.31.9.0) 56(84) bytes of data.
64 bytes from 172.31.9.0: icmp_seq=1 ttl=64 time=62.7 ms

laptop ~ $ ssh -p 22222 172.31.9.0 hostname
vpn.example.com

laptop ~ $ ssh -p 22222 172.100.0.1 hostname
example.com

and on VPN:

dave@vpn [~]$ ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=29.2 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=30.0 ms

# automate & fix dns (resolvconf).
# can then use ifup/ifdown tun0:
cat /etc/network/interfaces.d/tun0.cfg:
auto tun0
iface tun0 inet static
        pre-up ssh -f -w 0:0 vpn true
        pre-up sleep 5
        address 10.1.1.2
        pointopoint 10.1.1.1
        netmask 255.255.255.252
        dns-nameservers 172.100.0.1
        dns-search example.com foo.example.com
        up route add -net 172.100.0.0/16 gw 10.1.1.1

from "man ssh(1)":

SSH-BASED VIRTUAL PRIVATE NETWORKS
     ssh contains support for Virtual Private Network (VPN) tunnelling using the tun(4) network pseudo-device, allowing two networks to be joined
     securely.  The sshd_config(5) configuration option PermitTunnel controls whether the server supports this, and at what level (layer 2 or 3 traffic).

     The following example would connect client network 10.0.50.0/24 with remote network 10.0.99.0/24 using a point-to-point connection from 10.1.1.1 to
     10.1.1.2, provided that the SSH server running on the gateway to the remote network, at 192.168.1.15, allows it.

     On the client:

           # ssh -f -w 0:1 192.168.1.15 true
           # ifconfig tun0 10.1.1.1 10.1.1.2 netmask 255.255.255.252
           # route add 10.0.99.0/24 10.1.1.2

     On the server:

           # ifconfig tun1 10.1.1.2 10.1.1.1 netmask 255.255.255.252
           # route add 10.0.50.0/24 10.1.1.1

     Client access may be more finely tuned via the /root/.ssh/authorized_keys file (see below) and the PermitRootLogin server option.  The following
     entry would permit connections on tun(4) device 1 from user "jane" and on tun device 2 from user "john", if PermitRootLogin is set to
     "forced-commands-only":

       tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane
       tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john

     Since an SSH-based setup entails a fair amount of overhead, it may be more suited to temporary setups, such as for wireless VPNs.  More permanent
     VPNs are better provided by tools such as ipsecctl(8) and isakmpd(8).

from: https:_help.ubuntu.com/community/SSH_VPN#Automating_it_all_with_ifup.2Fdown

/etc/network/interfaces:

Machine A:

 iface tun0 inet static
        pre-up sleep 5
        address 10.0.0.100
        pointopoint 10.0.0.200
        netmask 255.255.255.0
        up arp -sD 10.0.0.200 eth0 pub

Machine B:

 iface tun0 inet static
        pre-up ssh -f -w 0:0 1.2.3.4 'ifdown tun0; ifup tun0'
        pre-up sleep 5
        address 10.0.0.200
        pointopoint 10.0.0.100
        netmask 255.255.255.255
        up ip route add 10.0.0.0/24 via 10.0.0.200
        up ip route add 1.2.3.4/32 via 192.168.0.1
        up ip route replace default via 10.0.0.1
        down ip route replace default via 192.168.0.1
        down ip route del 10.0.0.0/24 via 10.0.0.200
        down ip route del 1.2.3.4/32 via 192.168.0.1