My home network, VPNing with PPP over SSH (1998)

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.