Total Pageviews

Thursday, 12 August 2021

Poor man's VPN using PPP over SSH


The poor man's anonymizing VPN tunnel using SSH and pppd

Want to create a quick 'n dirty secure tunnel between your computer and a remote SSH server? Now you can.

/usr/sbin/pppd pty "ssh myinternetserver.com -t -e none -o 'Batchmode yes' \
/usr/sbin/pppd" 192.168.16.1:192.168.16.254 local nodetach silent \

This is all you need to create a secure tunnel between your computer and a computer that has the SSH running (in the example, myinternetserver.com) on the Internet.

Once you run this command, both your local and your remote computers will have new PPP network interfaces:

  • Local: interface ppp0, IP address 192.168.16.1
  • Remote: interface ppp0, IP address 192.168.16.254

But a few quick and easy preparations are needed in order to run and take advantage of this kind of tunnel.

The SSH server installed on the server, pppd on both machines

This should be self-explanatory. Use your Linux distribution's package management tools to install them -- should take less than 1 minute.

The right pppd configuration

You use the /etc/ppp/options file to configure it. Most options, once set in the configuration file, cannot be overriden in the command line.

On the server's /etc/ppp/options file

lock
noauth
ipcp-accept-local
ipcp-accept-remote
noproxyarp

On the client's /etc/ppp/options file

lock
noauth
noproxyarp

The right security configuration

[root@mycompanyserver.com #] /usr/sbin/groupadd -r ppp
...(add your SSH login user name to the ppp group in /etc/group)...
chown root.ppp /usr/sbin/pppd
chmod 750 /usr/sbin/pppd
chmod +s /usr/sbin/pppd

Now only members of the ppp group (namely, you) can join the fun.

SSH public key authentication enabled

  • Put PubkeyAuthentication yes in the server's /etc/ssh/sshd_options.
  • Generate an SSH key pair in your computer.
  • Upload the public key of the generated pair to your server's ~/.ssh/authorized_keys2 file. Don't forget to chmod 600 that file, or else SSH won't even look at it.

That's it!

Now run the following command on your computer:

/usr/sbin/pppd pty "ssh myinternetserver.com -t -e none -o 'Batchmode yes' \
/usr/sbin/pppd" 192.168.16.1:192.168.16.254 local nodetach silent \

What this command basically does is start pppd locally, tell it to connect via SSH in batch mode (using the public key, so it doesn't ask for your password), start pppd on the remote server, and use the SSH connection as their conversation path.

Wait a few seconds. pppd will utter a few things:

Using interface ppp0
Connect: ppp0 <--> /dev/pts/7

You will have to confirm that the PPP interface is up:

[youruser@yourcomputer $] /sbin/ifconfig ppp0
ppp0      Link encap:Point-to-Point Protocol
          inet addr:192.168.16.1  P-t-P:192.168.16.254  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:5 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:75 (75.0 b)  TX bytes:69 (69.0 b)

Now you can ping 192.168.16.254. If pinging fails, check the firewall rules on both the server and your computer.

To interrupt the tunnel, hit Ctrl+C on the terminal that holds the running pppd command.

What next?

Bringing the tunnel up is actually one part of the deal. If you're like me, perhaps you'll want to actually carry all of your network traffic across the tunnel.

Set up the remote server to route traffic for you

This is easy. On the server, either:

  • set firewall rules that will do NAT between the PPP interface and the Internet; or
  • replace noproxyarp with proxyarp in the (server's) /etc/ppp/options file; then set aside an extra IP address in the (server's) local network; then use it as the remote endpoint in the pppd command. If your server has IP address 2.3.4.5, then provision 2.3.4.6 and use it instead of 192.168.16.254.

Set the default route to be the tunnel's remote endpoint

If you want to route all of your network traffic through your newly created PPP link, you need to do two steps in this order:

  1. Manually add a route to your server, so the SSH traffic knows the physical route it should follow. If the IP address of your current default route is 4.5.6.7, then run route add mycompanyserver.com gw 4.5.6.7
  2. Replace the default route. Run route add default gw 192.168.16.254 dev ppp0

Before you suggest the pppd's defaultroute option: no, it won't work, because it'll disrupt the only communication route between your computer and the remote SSH server.

Perhaps you'd like to add manual, shorter routes to your DNS servers -- otherwise Web browsing may get a little slow. You know, due to the latency of the tunnel and stuff...

After doing this:

  • your computer will send all (SSH) traffic to mycompanyserver.com through your regular default route, so the tunnel keeps working fine;
  • the rest of the traffic will go through the PPP interface (notice we named the remote IP address in the default route command?)

Combine this with the proxyarp option on the server, and you have a recipe to make your computer appear as a completely different computer on the Internet. Perfect for anonymizing your real computer!

from https://rudd-o.com/linux-and-free-software/mola-the-poor-mans-anonymizing-vpn-tunnel-using-ssh-and-pppd

--------------------------------

https://gist.github.com/marc-hanheide/a536fd1f7471109fe707


-------------------------------------

related post: https://briteming.blogspot.com/2021/03/pvpn.html

--------------------------------------------

My home network, VPNing with PPP over SSH 

Goals

At home, I have my own cable modem link, as well as my friends T1 link at my disposal. The cable modem only comes with 1 dynamic IP, and I only have 1 IP address on my friends T1. However, I have a class C being routed to a machine that's being co-located elsewhere (bleep).

My goal was to somehow get the extra IP space that I'm not using at bleep, routed over to my home. Neither of my ISPs (the T1 or the cable modem provider) will let me announce my IP space, so alternative methods are necessary.

Implementation

A VPN solution would be great, but due to the types of machines this is running on, anything based on IPSEC is currently out of the question due to non standardized implementations.

Running PPP over SSH works great. This is a tiny perl script I wrote to setup the tunnel. The remote side just as a user with no password, with your SSH key authorized. I also use sudo to run pppd, so this like was added to my /etc/sudoers file:

vpn ALL=(ALL) NOPASSWD: /usr/sbin/pppd

This is the /etc/ppp directory on the remote side.

Routes on the server just forward my IP block (199.79.133.240/28) to the first IP in the block (199.79.133.241), which is the machine I'm connecting to the ppp server with.

When my machine (the one making the ppp connection) boots, there are localnet routes, and a static route to an IP alias on the ppp server (199.79.133.32). Then SSH connection is made to that alias, and PPP is started. Then a default route is added with a gateway of the ppp server (199.79.133.2, via ppp0 interface). The PPP link has the endpoints 199.79.133.241 <--> 199.79.133.2.

This script is known to work with Linux, OpenBSD, and FreeBSD.

Redundancy

This setup has another goal, which is to make my home network redundantly accessible. There are actually two PPP links shown in the network map below, but only one is up at a time. If the link to bleep via the cable modem dies, then PPP is torn down and restarted over an SSH connection that goes over the T1, and vice versa.

Map

 199.79.133.2                                                       ,-------.  |
 199.79.133.32                                       199.79.133.244 | box 4 |--|
 ,-------.                                                          `-------'  |
 | bleep |  +-------------------------------------+                 ,-------.  |
 `-------'  | ------ Ethernet                     |  199.79.133.243 | box 3 |--|
     #t:    | tttttt T1 to inet                   |                 `-------'  |
     #t:    | cccccc CableModem to inet           |                 ,-------.  |
     #t:    | ###### PPP over SSH over T1         |  199.79.133.242 | box 2 |--|
     #t:    | ...... PPP over SSH over Cablemodem |                 `-------'  |
     #t:    +-------------------------------------+                 ,-------.  |
     #t:                                             199.79.133.241 | box 1 |--|
    _----__ __----__                                  206.41.10.230 `------:###|
   { # :   '        `.                              RCN IP for host        :..#|
  {  # :             }                                                       :#|
 {   # :..............}..............................,-------------..........:#|
 {   #                }cccccccccccccccccccccccccccccc| Cable modem |-----------|
  {  #   Internet     }                              `-------------'          #|
   { #               }                                    RCN IP              #|
  {  #                }                                                       #|
  {  ################}###################################,-----------.#########|
   {                }tttttttttttttttttttttttttttttttttttt| T1 router |---------|
    `--'-___,--__--'                                     `-----------'         |
                                                        206.41.10.225

Twist

All my traffic now has to go over the PPP interface now. This is fine for most traffic, but for stuff that desire high throughput (such as web), its not the most ideal solution. Standard web traffic also has the bonus that its not really necessary to have a static IP, or even reverse DNS, and also that network address translation works fine. (For https, I want my 'real' IP addresses).

So what I need to somehow say is 'take packets that have a src addr in my localnet, and dest port of 80 (for web) that are destined for ppp0, and masquerade them isntead and send them out the ethernet interface'. Normal destination addressed based routing isn't going to get me that. What I need is some form of policy routing that can filter both src and dest addresses and ports.

On BSD, the only want I can think of doing this is via IPFilter's to keyword or IPFW's fwd keyword.

Linux has policy routing, but I still need more control than just routing on src address. IPChains in LInux 2.2.x is a very powerful tool tho, and it can accomplish this very easily.

BSD IPFW Rules

/sbin/ipfw add divert natd tcp from 199.79.133.240/28 to any 80 out via ppp0
/sbin/ipfw add divert natd tcp from any 80 to any in via de0
/sbin/ipfw add fwd 206.41.10.225 all from 206.41.10.230 to any out via ppp0

Linux IPChains Rules

As far as I know, this is not possible. I spoke with the ipchains maintainer,
and he gave me some ideas to try, but nothing I could get working.
from http://ishiboo.com/~danny/Projects/vpn/

-----------------------------------------------------------------------

PPP (Point to Point Protocol) is a mechanism for running IP (Internet Protocol) over a terminal. Usually the terminal is a modem, but any tty will do. SSH creates secure ttys. Running a PPP connection over an SSH connection makes for an easy, encrypted VPN. (SSH has native tunneling support which requires root access, this method only requires root privileges on the client.)

If you run any flavor of *nix (Free/Open/NetBSD, Linux, etc), chances are everything you need is already installed (ppp and ssh). and since SSH uses a single client/server TCP connection, it NATs cleanly, easily passing through firewalls and NAT routers. It has its drawbacks though as you have PPP (TCP) inside of SSH (TCP) which is a bad idea.

On the remote end, install pppd if not already installed,

apt-get install ipppd

Enable IP Forwarding by editing /proc/sys/net/ipv4/ip\forward

echo 1 > /proc/sys/net/ipv4/ip_forward

Configure your iptables settings to enable access for PPP Clients,

iptables -F FORWARD
iptables -A FORWARD -j ACCEPT

iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE
iptables -A POSTROUTING -t nat -o ppp+ -j MASQUERADE

And make sure you can login without a password.

On the local end, start pppd, tell it to connect using SSH in batch mode, start pppd on the remote server, and use the SSH connection as the communication channel.

pppd updetach defaultroute replacedefaultroute usepeerdns noauth passive pty \
    "ssh root@$remote -o Batchmode=yes /usr/sbin/pppd nodetach notty noauth ms-dns 8.8.8.8" \
    10.0.0.1:10.0.0.2

When run, both your local and your remote computers will have new PPP network interfaces,

  • Local interface ppp0 with IP address 10.0.0.1
  • Remote interface ppp0 with IP address 10.0.0.2

Once pppd adds default route via ppp0 all traffic will be routed through the tunnel thus SSH will go down because OS will try to route the tunnel through the tunnel, to fix that we add a route to remote-host via local-gateway.

route add $remote gw $gateway

OS will send all SSH traffic to remote-host through our default gateway, so the tunnel keeps working fine, the rest of the traffic will go through the tunnel.

The script below automates all of the steps above, when run it will figure out the current gateway setup the tunnel and the routes so all traffic goes through the tunnel.

#!/bin/bash

pidfile=/var/run/ppp0.pid
pid=

remote=95.85.48.115
gateway=$(/sbin/ip route | awk '/default/ { print $3 }')

# trap ctrl-c and signal pppd to shutdown
trap close_conn INT

function close_conn(){
    echo "Closing Connection."
    kill -HUP $pid
}

function setup_conn(){
    cd ~/
    echo "Current Gateway " $gateway
    route add $remote gw $gateway
    pppd updetach defaultroute replacedefaultroute usepeerdns noauth passive pty \
        "ssh root@$remote -o Batchmode=yes /usr/sbin/pppd nodetach notty noauth ms-dns 8.8.8.8" \
        10.0.0.1:10.0.0.2
    pid=`cat $pidfile`
    echo "Public Facing IP " `curl -s 'http://checkip.dyndns.org' |
                              sed 's/.*Current IP Address: \([ 0-9\.\.]*\).*/\1/g'`
}

setup_conn

while ps -p $pid > /dev/null; 
do 
    sleep 1; 
    printf \
    "\rConnected For: %02d:%02d:%02d:%02d" \
    "$((SECONDS/86400))" "$((SECONDS/3600%24))" "$((SECONDS/60%60))" "$((SECONDS%60))"
done

route del $remote gw $gateway

from https://nakkaya.com/2012/08/20/poor-man-s-vpn-using-ppp-over-ssh/

----------------------

Poor mans VPN over SSH.

pvpn is a tool to set up layer 3 VPNs over SSH. It is mostly a wrapper around OpenSSH and pppd(8), but provides a helpful interface. Given that you fulfil the requirements (root access to local machine and SSH server, IP forwarding enabled; see REQUIREMENTS for details), you can, for example, reroute all your IP traffic through myserver with

$ pvpn root@myserver default

pvpn can use several different ways of tunneling, using the -t option: ppp over ssh (-t ppp) or the OpenSSH built-in Layer 3 tunnel (-t ssh-3). The different ways have slightly different requirements. See below for details.

pvpn is useful to protect your network communication when on a public, unencrypted network, or when you need access to a private network without any regular VPN infrastructure available.

See pvpn(8) for a complete reference.

SYNOPSIS

pvpn [OPTION] …​ SSH-HOST [ROUTE] …​

GENERAL OPTIONS

-h, --help

Show help and exit.

-v, --version

Show version and exit.

-d, --debug

Trace code execution.

CONNECT OPTIONS

-t TYPE, --type TYPE

Type of tunnel. Valid options are:

  • ppp (ppp over ssh)

  • ssh-3 (OpenSSH Layer 3)

-i IP1:IP2, --ip IP1:IP2

Use IP1 for local and IP2 for remote tunnel device IPs. Default any:any, which becomes 10.b.c.1:10.b.c.2 where b and c are random.

-s SSH-IP, --first-ssh-hop SSH-IP

Tell IP address or hostname of first SSH server. Needed when you connect through reverse tunnels or intermediate servers with ProxyCommand.

-D, --inherit-dns

Inherit DNS settings from SSH-HOST. When disconnecting, the current DNS settings will be restored.

DISCONNECT OPTIONS

-S [DEVICE], --stop [DEVICE]

Stop tunnel with client device DEVICE, or all if no DEVICE is given, then exit.

EXAMPLES

Gain access to the 192.168.xxx.yyy network at work

$ pvpn -i 10.10.0.1:10.10.0.2 root@work 192.168.0.0/16

Encrypt all IP traffic, e.g. when on a public wifi using OpenSSH Layer 3

$ pvpn -t ssh-3 root@secureproxy default

Disconnect tunnel with device ppp0

$ pvpn -S ppp0

Adding additional arguments to SSH:

$ SSH_ARGS="-i ~/.ssh/id_rsa" 10.10.0.1:10.10.0.2 root@work 192.168.0.0/16

Test that traffic is routed through your tunnel with e.g. traceroute(8).

DEPENDENCIES

  • GNU/Linux

  • OpenSSH

  • pppd

  • bash

  • iproute2

  • dnsutils (dig(1))

  • asciidoc

INSTALLATION

Configure

Edit config.mk if you need to customize your installation.

PREFIX

Directory under which pvpn will be installed as bin/pvpn

MANPREFIX

Directory under which the manpage will be installed

Install

$ make install

Uninstall

$ make uninstall

REQUIREMENTS

To establish a VPN connection through an SSH server, the following is required:

  • root access on both client and server. To enable root SSH access on the server via authentication keys, set below in /etc/ssh/sshd_config on the server.

PermitRootLogin without-password
  • Authentication through SSH authentication keys. On the client, as root, run

$ ssh-keygen

$ ssh-copy-id root@<server> -p ssh-port
  • IP forwarding enabled on server. It can be enabled by something like below, depending on your software stack.

$ sysctl net.ipv4.ip_forward = 1

$ iptables -P FORWARD ACCEPT

$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
  • iproute2 installed on client and server (ip(8)).

  • dnsutils installed on client (dig(1)).

Table 1. Tunnel type specific requirements
pppssh-3

sshd_config PermitTunnel

point-to-point or yes

Software

pppd(8) on both sides

OpenSSH 4.3+

PORTABILITY

Works-for-me™. Developed and tested on Arch Linux. I have not tested this on other systems but would like to hear from you if you have, successfully or not. Let me know at henrik@k2h.se.

LICENSE

Released under the New BSD License; see LICENSE.

FURTHER READING

from https://github.com/halhen/pvpn
------

https://code.google.com/archive/p/pvpn-for-openwrt/
https://code.google.com/archive/p/autovpn-for-openwrt/wikis/Dnsmasq_Patched.wiki
https://github.com/autovpn4openwrt/autovpn-for-openwrt

No comments:

Post a Comment