Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 May 2005 09:41:14 -0600
From:      Tim Pushor <timp@crossthread.com>
To:        Rob Zietlow <Rob@the-rob.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: pppd pty equivilent in FBSD
Message-ID:  <4291F99A.1070007@crossthread.com>
In-Reply-To: <200505232031.15516.Rob@the-rob.com>
References:  <200505231957.23014.Rob@the-rob.com> <4291D817.40407@crossthread.com> <200505232031.15516.Rob@the-rob.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Rob, I had a cursory look through your scripts, and seems like you 
handle most of the logic. I don't know anything about pppd for Linux (is 
it based on the same code?). I let pppd manage retries & setting routes. 
It will also drop and dry to reconnect if either side can't talk to the 
other (via lqr).

It looks simple, but with rsa only authentication on the sshd, it has 
proven to be solid and reasonably secure.

Good luck,
Tim

Rob Zietlow wrote:

>On Monday 23 May 2005 08:18 am, Tim Pushor wrote:
>
>hmm, Thanks for the response, Tim.  
>
>I wouldn't personally recommend vpn over ssh for anyone either, but i'm kind 
>of stuck with it.  I'm the sole bsd user at my company, and the ppp over ssh 
>was implemented years before I came and has worked fine for them.  They're 
>not really willing to change it at the moment and it's on a system I have 
>zero control over within our organization.  
>
>If I had the option to set this up like you have below it would have been put 
>in place a long while ago.  Tim,  I thank you for your scripts and time. 
>
>Here's the scripts I use.
>
>Actual bash script I call: 
>
>! /usr/local/bin/bash
>#
># This script controls starting and stopping
># the VPN run over ssh.  It's functions are:
>#
># start stop on off
>#
># start and stop control the actuall ppp interface,
># while on and off turn the routes to the VPN on and off.
># In this way, you can bring up the interface, but turn
># the VPN on and off without affecting the ppp connection.
>#
>#
># --------- configuration ------------
># This is the other end of the VPN
>VPNHOST="$WORK"
>
># This is for editing /etc/resolv.conf
>DOMAIN=" $DOMAIN_NAME"
>#DNSSERVER="10.10.X.X"
>DNSSERVER="10.10.X.Y"
>
># ------------------------------------
># Defaults should be okay
># ------------------------------------
>CONFFILE="/etc/resolv.conf"
>
># tempfile, needs to be writable
>TMP=/tmp/file.$$
>
># This is to give us time for the ppp
># connection to come up
>timeout=5
>
># This is the command to start pppd
>CMD="/usr/sbin/pppd file /usr/home/rob/vpn/options.vpn"
>
>
># A place for control files
>svcdir="$HOME/.pppssh"
>
># A place for pids to keep track of processes
>rundir="$svcdir/run"
>
># ------ end configuration -----------
>
># Some things to check before we begin
>USER=`id -u`
>PPPD=`find /usr/sbin -perm 4755 -name pppd`
>ROUTE=`find /sbin -perm 4755 -name route`
>IFCONFIG=`find /sbin -perm 4755 -name ifconfig`
>
>if [ \( $USER -ne 0 \) -a \( -z "$PPPD" -o -z "$ROUTE" -o -z "$IFCONFIG" \) ]; 
>then
>        echo "You must be root, or the following must be suid:"
>        echo "/sbin/pppd, /sbin/route, /sbin/ifconfig"
>        exit 1
>fi
>
>case "$1" in
>    start)
>        # Make a control directory
>        if [ ! -d $svcdir ]; then
>                mkdir -p $svcdir
>        fi
>        if [ ! -d $rundir ]; then
>                mkdir -p $rundir
>        fi
>
>        # make sure it doesn't core dump anywhere; while this could mask
>        # problems with the daemon, it also closes some security problems
>        ulimit -c 0
>
>        echo -n $VPNHOST > "$svcdir/host"
>       echo Waiting for connection...
>
>        # Look for unused ppp device.
>        # But default to ppp0
>        dev=0
>        for i in `jot 9 0 `; do
>                if [ ! -f /var/run/ppp$i.pid ] ; then
>                        echo Using interface ppp$i
>                        dev=$i
>                        break
>                fi
>        done
>
>        # See if we're already running
>        if [ ! -f $svcdir/lock ]; then
>                $CMD
>        else
>                echo Link appears up
>                echo Lock file in $svcdir
>                echo Use $0 restart
>                exit 1
>        fi
>
>        if [ $? -eq 0 ]; then
>                sleep $timeout
>                ifconfig ppp$dev
>                echo ppp$dev > $svcdir/device
>                echo $VPNHOST > $svcdir/host
>                touch $svcdir/lock
>
>                # Routes to be added for the inside network
>                $0 on
>        else
>                echo Connection Failed
>        fi
>        ;;
>    stop)
>       # Find the pid of the pppd, kill it, remove the route
>        VPNIF=`head $svcdir/device`
>        ppppid=`head /var/run/$VPNIF.pid`
>        sshpid=`head $rundir/sshpppd.pid`
>
>        # Removing routes if possible
>        echo Removing routes...
>        $0 off
>
>        echo Killing processes...
>        kill -s SIGTERM $ppppid
>        kill -s SIGTERM $sshpid
>        echo Killed ssh[$sshpid]
>        echo Killed pppd[$ppppid]
>
>        # Bring down interface
>        echo Bringing down interface: $VPNIF
>        /sbin/ifconfig $VPNIF down
>
>        echo Removing control files...
>        # Remove control files
>        rm -f "$svcdir/device"
>        rm -f "$svcdir/host"
>        rm -f "$rundir/sshpppd.pid"
>        rm -f "$svcdir/lock"
>        echo Done.
>        ;;
>    on)
>        if [ ! -f "$svcdir/lock" ]; then
>                echo VPN does not appear to be up
>                exit 1
>        elif [ -f "$svcdir/on" ]; then
>                echo VPN looks like it is already active
>                exit 1
>        else
>                # Routes are specified in /etc/ppp/routes.vpn
>                grep -v '^#' /etc/ppp/routes.vpn |\
>                         while read NET NETMASK GATEWAY ; do
>                        /sbin/route add -net $NET netmask $NETMASK gw $GATEWAY
>                done
>
>                # Make changes to the resolv.conf file
>                # We may not want this to be standard equipment
>        #       if [ $USER -eq 0 ]; then
>                  # insert search domain
>                  MATCH=$( grep -cq "search" $CONFFILE )
>                  #if [ "$MATCH" = "0" ]; then
>                  #  # Add one if there isn't one
>                  #  { echo "search $DOMAIN" ; cat $CONFFILE } > $TMP
>                  #  mv -f $TMP $CONFFILE
>                  #else
>                  #  # Edit one if needed
>                  #  grep -q "search.*$DOMAIN" $CONFFILE
>                  #  if [ "$?" != "0" ]; then
>                  #  perl -pi -e "s/(search.+)\s+/\$1 $DOMAIN\n/" $CONFFILE
>                  #  fi
>                 # fi
>                #
>                #  # insert server if needed
>                #  # it needs to be first in the list
>                #  MATCH=$( grep -cq "nameserver.*$DNSSERVER" $CONFFILE )
>                #  if [ "$MATCH" = "0" ]; then
>                #    perl -pi -e "s/(search.+)\s+/\$1\nnameserver 
>$DNSSERVER\n/" $CONFFILE
>                #  fi
>
>                  #touch $svcdir/resolver
>        #       fi
>                touch $svcdir/on;
>        fi
>        ;;
>    off)
>        if [ ! -f $svcdir/lock ]; then
>                echo VPN does not appear to be up
>                exit 1
>       elif [ ! -f "$svcdir/on" ]; then
>                echo VPN does not appear to be active
>                exit 1
>        else
>                grep -v '^#' /etc/ppp/routes.vpn |\
>                        while read NET NETMASK GATEWAY ; do
>                        /sbin/route del -net $NET netmask $NETMASK gw $GATEWAY
>                done
>        fi
>
>        ## Remove changes made to /etc/resolv.conf
>        if [ $USER -eq 0 ]; then
>           if [ -f $svcdir/resolver ]; then
>                perl -pi -e "s/(search.+?)\s+$DOMAIN\s+/\$1\n/" $CONFFILE
>                perl -pi -e "s/^nameserver\s+$DNSSERVER\s+//" $CONFFILE
>                rm -f $svcdir/resolver
>           fi
>        fi
>        rm -f $svcdir/on
>        ;;
>    restart)
>        $0 stop
>        $0 start
>        ;;
>    *)
>        echo "usage: telnetd {start|stop|on|off}"
>        ;;
>esac
>
>options.vpn: 
>
>lock
>noipdefault
>defaultroute
>updetach
>lcp-echo-interval 5
>lcp-echo-failure 10
>pty /home/rob/vpn/pppssh
>call server.vpn
>
>
>!/usr/bin/perl -w
>
># Taken from Olaf Titz's ppp over ssh script.
># pppd starts up ppp connection, but ssh hangs
># and prevents pppd from taking over the terminal
># this script gives ssh a little kick.
>
>#use strict
>
># ---- configuration ----- #
># Your user login here
>$user="$USER_NAME";
>
># ------------------------ #
># Customize if necessary
>
>$home=$ENV{HOME};
>$svcdir="$home/.pppssh";
>$rundir="$svcdir/run";
>$ssh="/usr/bin/ssh";
>$timeout=10;
>$host=`head $svcdir/host`;
>
># ------------------------ #
>
>if ( ! defined($host)) {
>    print "No host given\n";
>    exit 1;
>}
>
># subroutine to handle sshd hang bug.
>&bugdaemon($timeout) if ($timeout);
>
># Write pid to control file
>open FD, ">$rundir/sshpppd.pid" or die $!;
>printf FD $$;
>close FD;
>
># exec ssh to start pppd on remote host
>exec $ssh, "-t", "-l$user", $host, "-p 24";
>die "exec $ssh: $!";
>
># -------------------------------------------- #
># This cures a "hang" of the local ssh process
>sub bugdaemon
>{
>    local($secs)=@_;
>    local($p)=fork;
>    # fork returns 0 to child, pid to parent, and undefined to parent if 
>failed.
>    if (!defined($p)) {
>       warn "can't fork, no bug daemon";
>       return;
>    }
>    # Return if I'm the child to execute ssh
>    return if (!$p);
>    # returning the child avoids a zombie
>    # Parent sleeps to allow the child to exec ssh
>    if ($secs) {
>        sleep $secs;
>    } else {
>        sleep 10;
>    }
>    # If I'm the parent, give ssh a kick
>    kill "STOP", $p;
>    sleep 1;
>    kill "CONT", $p;
>    exit 0;
>}
>
>
>
>
>
>  
>
>>You don't need the pty. I don't recommend vpn over ssh, unless its
>>absolutely necessary. OpenVPN is much better ...
>>
>>I've set it up (as it was absolutely necessary :-), and here is a config
>>from the 'client'.
>>
>>default:
>>        set timeout 0
>>        set log phase chat connect lcp ipcp
>>        set dial
>>        set login
>>
>>cli:
>>        set device "!ssh -l cli -i /etc/ppp/ppp.key server.domain.com
>>/usr/sbin/ppp -direct srv"
>>        set ifaddr 10.0.4.4 10.0.4.3 255.255.255.255
>>        add! 192.168.x.0/24 HISADDR
>>        set lqrperiod 60
>>        enable lqr
>>
>>'client' is enabled by running ppp -ddial cli from rc script.
>>
>>Then the 'Server' - of course, 'cli' needs a user account on the system,
>>and all the ssh stuff setup (authorized keys, etc).
>>
>>default:
>>
>>    set log Phase Chat LCP IPCP CCP tun command
>>
>>srv:
>>
>>        allow user cli
>>        set ifaddr 10.0.4.3 10.0.4.4 255.255.255.255
>>        set timeout 0
>>        add! 192.168.y.0/24 HISADDR
>>        set lqrperiod 60
>>        enable lqr
>>        accept lqr
>>
>>Rob Zietlow wrote:
>>    
>>
>>>Good day List,
>>>
>>>I have a question about pppd.  We use ppp over ssh for a VPN solution into
>>>work. The script works on linux, but not in freebsd because the
>>>implementation of pppd that comes with freebsd does not recognize the pty
>>>command.  When I attempt to connect up I get the following.
>>>
>>>testee# bash bin/vpn.init start
>>>Waiting for connection...
>>>Using interface ppp0
>>>/usr/sbin/pppd: In file /usr/home/rob/vpn/options.vpn: unrecognized option
>>>'pty'
>>>Connection Failed
>>>
>>>This appears to be the last piece of the puzzle for me in order to get
>>>this to work. So it leaves me to ask Is there an equivalent in Freebsd?
>>>
>>>      
>>>
>>>From the pppd man page on a linux machine.
>>    
>>
>>>      pty script
>>>             Specifies that the command script is to be used to
>>>communicate rather  than  a  specific terminal  device.   Pppd will
>>>allocate itself a pseudo-tty master/slave pair and use the slave as its
>>>terminal device.  The script will be  run  in  a  child  process  with 
>>>the  pseudo-tty  master as its standard input and output.  An explicit
>>>device name may not be given if this option is used.  (Note: if the
>>>record option is used  in conjuction  with the pty option, the child
>>>process will have pipes on its standard input and output.)
>>>
>>>The fbsd pppd's man page doesn't list anything for pty, and a google
>>>doesn't turn up much.
>>>
>>>Thanks for your time.
>>>
>>>Rob
>>>_______________________________________________
>>>freebsd-net@freebsd.org mailing list
>>>http://lists.freebsd.org/mailman/listinfo/freebsd-net
>>>To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"
>>>      
>>>
>>_______________________________________________
>>freebsd-net@freebsd.org mailing list
>>http://lists.freebsd.org/mailman/listinfo/freebsd-net
>>To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"
>>    
>>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4291F99A.1070007>