0

I have some problems with making ssh-based VPN.

Situation:

LOCAL ->            GATE                 -> SERVICES 
                (ssh server)     (Many other servers with some services)
192.168.0.10     10.1.0.154             172.26.106.0/24
255.255.255.0    255.255.0.0

From LOCAL I can login through the ssh to the GATE and then from here I have access to all of the SERVICES servers.

However i want to access services directly from my LOCAL computer. How can I acheive this?

Here is what i tried to do after reading ssh manual:

On LOCAL:

# ssh -f -w 1:2 root@GATE true
# ifconfig tun1 10.66.1.1 10.66.1.2 netmask 255.255.255.252
# route add -net 172.26.106.0 netmask 255.255.255.0 gw 10.66.1.2 

On GATE:

# ifconfig tun2 10.66.1.2 10.66.1.1 netmask 255.255.255.252

It doesn't work. I get timeouts when i try to ssh to some SERVICE from LOCAL ;-(

2
  • 1
    Have you tried this script: github.com/oicu/vpn-over-ssh/blob/master/svpn.sh it uses a few more options than you did, which might work better. – Jeff Meden Jun 6 '16 at 16:18
  • thaaanks! Script itself did not worked for me. But I figured that I needed also to set some rules in iptables to make it work. I adjusted it to my needs, and finally it worked ;-). My script is in the answer below – devstructor Jun 7 '16 at 14:19
2

Thanks to Jeff Meden comment I managed to do it. I adjusted that script: github.com/oicu/vpn-over-ssh/blob/master/svpn.sh to my needs, and finally it worked:

My version:

#!/bin/bash
PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin
export PATH

[ "$(whoami)" != 'root' ] && echo "Run it as root." && exit 1

SERVER_SSH_PORT="22"
SERVER_SSH_IP="10.1.0.154"
CLIENT_TUNNEL="tun5"
SERVER_TUNNEL="tun4"
CLIENT_TUN_IP="192.168.55.5"
SERVER_TUN_IP="192.168.55.4"
TUN_NETMASK="255.255.255.0"
CLIENT_ETHERNET="enp12s0"
SERVER_ETHERNET="eth0"
ROUTES=("172.26.100.0/24" "172.26.106.0/24" "172.26.103.0/24")


function start() {
    ssh -NTCf -w "${CLIENT_TUNNEL#tun}:${SERVER_TUNNEL#tun}"  root@${SERVER_SSH_IP} -p ${SERVER_SSH_PORT}
    if [ $? -ne 0 ]; 
        then exit 1; 
    fi
    echo "ssh tunnel is working."
    ssh -T root@${SERVER_SSH_IP} -p ${SERVER_SSH_PORT}  << eeooff
        ifconfig ${SERVER_TUNNEL} ${SERVER_TUN_IP} pointopoint ${CLIENT_TUN_IP} netmask ${TUN_NETMASK}
        iptables -t nat -A POSTROUTING -s ${CLIENT_TUN_IP}/32 -o ${SERVER_ETHERNET} -j MASQUERADE
        iptables -A FORWARD -p tcp --syn -s ${CLIENT_TUN_IP}/32 -j TCPMSS --set-mss 1356
        exit
eeooff

    for ROUTE in ${ROUTES[*]}
    do
        ssh -T root@${SERVER_SSH_IP} -p ${SERVER_SSH_PORT} "iptables -t nat -A POSTROUTING -s $ROUTE -o ${CLIENT_TUNNEL} -j MASQUERADE"
    done


    if [ $? -ne 0 ]; 
        then exit 1; 
    fi
    echo "remote start."
    ifconfig ${CLIENT_TUNNEL} > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo 1 > /proc/sys/net/ipv4/ip_forward
        ifconfig ${CLIENT_TUNNEL} ${CLIENT_TUN_IP} pointopoint ${SERVER_TUN_IP} netmask ${TUN_NETMASK}

        for ROUTE in ${ROUTES[*]}
        do
            ip route add $ROUTE via ${CLIENT_TUN_IP} metric 102
            printf "Adding route: %s\n" $ROUTE
        done

        iptables -t nat -A POSTROUTING -s ${SERVER_TUN_IP}/32 -o ${CLIENT_ETHERNET} -j MASQUERADE
        iptables -A FORWARD -p tcp --syn -s ${SERVER_TUN_IP}/32 -j TCPMSS --set-mss 1356
        for ROUTE in ${ROUTES[*]}
        do
            iptables -t nat -A POSTROUTING -s $ROUTE -o ${CLIENT_TUNNEL} -j MASQUERADE
        done


        ping ${SERVER_TUN_IP} -i 60 > /dev/null 2>&1 & echo "local start."
    else
        exit 1
    fi
}


function  stop(){
    echo "Flushing iptables on server..."
    ssh -T root@${SERVER_SSH_IP} -p ${SERVER_SSH_PORT} "iptables -F"

    echo "Flushing iptables on localhost..."
    iptables -F

    echo "Killing ssh tunnel..."
    CLIENT_SSH_PID=`ps -ef | grep "ssh -NTCf -w ${CLIENT_TUNNEL#tun}:${SERVER_TUNNEL#tun}" | grep -v grep | head -n1 | awk '{print $2}'`
    if [ -n "${CLIENT_SSH_PID}" ]; then 
        kill -9 ${CLIENT_SSH_PID}
    fi
    if [ -n "`pidof ping`" ]; then 
        pidof ping | xargs kill -9 
    fi
}

function usage(){
    echo "usage:"
    echo "    $0 -start"
    echo "    $0 -stop"
    echo ""
    echo "for ssh:"
    echo "    nohup $0 -start > /dev/null 2>&1"
}

case $1 in
    "--start" | "-start")
        start
        ;;
    "--stop" | "-stop")
        stop
        ;;
    *)
        usage
        ;;
esac
1

Two and half year left since I asked that question... Now I found another solution which is extremely simple. You can just use tool called sshuttle.

From sshuttle manual:

sshuttle allows you to create a VPN connection from your machine to any remote server that you can connect to via ssh, as long as that server has python 2.3 or higher.

i.e.:

sshuttle -r user@gate 172.26.100.0/24 172.26.106.0/24 172.26.103.0/24

Then in another terminal you can do ssh to any server from routed subnets directly:

i.e.:

ssh xyz@172.26.100.1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.