Соединяем два удаленных сервера средствами ppp

Представьте ситуацию, у нас есть два удаленных сервера, у каждого их них свой интернет канал, и вам необходимо соединить их посредством VPN канала, есть много способов как это сделать и один из них это при помощи стандартного ppp. И так, сначала нам нужно выбрать кто из серверов будет сервером, а кто клиентом, затем на обоих компьютерах проверить настройки ppp:

lsmod|grep ppp

ответ будет приблизительно такой —

ppp_deflate 39233 0
zlib_deflate 52825 1 ppp_deflate
ppp_generic 62689 1 ppp_deflate
slhc 39745 1 ppp_generic

если ответа не будет, то запускаем

modprobe ppp_deflate

Теперь, необходимо проверить установлены ли пакеты ssh и ppp

rpm -qa | grep ppp
rpm -qa | grep ssh

ответ должен быть приблизительно вот такой, могут быть немного другие версии

ppp-2.4.4-2.el5
openssh-server-4.3p2-41.el5_5.1
openssh-4.3p2-41.el5_5.1
openssh-clients-4.3p2-41.el5_5.1

Если у вас нет некоторых пакетов, просто запустите

yum install openssh* ppp

Теперь перейдем к настройке сервера. Первое, что мы сделаем это с генерируем RSA ключи для пользователя root

 
ssh-keygen -t rsa

Копируем содержимое файла id_rsa.pub на сервер в файл /home/vpn/.ssh/authorized_keys

Обязательно проверьте работоспособность на клиенте:

ssh -l root <имя сервера или его IP>

Теперь перейдем к настройке клиента. В принципе, все что нам нужно, это создать вот такой скрипт с именем vpn.sh:

#!/bin/sh
# This script initiates a ppp-ssh vpn connection.
#s script initiates a ppp-ssh vpn connection.
#Ip or name where we going to connect
SERVER_HOSTNAME=80.91.175.92
SERVER_USERNAME=root
SERVER_IFIPADDR=10.0.0.2
CLIENT_IFIPADDR=10.10.10.2
#Route what we adding on clietn.
ROUTE_ADD='route add -net 172.16.0.0 netmask 255.255.0.0 gw 10.0.0.2'
#Route what we adding on server.
ROUTE_SERV='route add -net 172.16.100.0 netmask 255.255.255.0 gw 10.10.10.2'
PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11/:
#
PPPD=/usr/sbin/pppd
SSH=/usr/bin/ssh

if ! test -f $PPPD ; then echo "can't find $PPPD"; exit 3; fi
if ! test -f $SSH ; then echo "can't find $SSH"; exit 4; fi
case "$1" in

route)
${SSH} ${LOCAL_SSH_OPTS} ${SERVER_HOSTNAME}    -l${SERVER_USERNAME} -o Batchmode=yes   ${ROUTE_SERV}
;;

start)
echo -n "Starting vpn to $SERVER_HOSTNAME: "
${PPPD} updetach noauth passive pty "${SSH} ${LOCAL_SSH_OPTS}   ${SERVER_HOSTNAME}    -l${SERVER_USERNAME} -o Batchmode=yes sudo ${PPPD}   nodetach notty noauth" ipparam vpn   ${CLIENT_IFIPADDR}:${SERVER_IFIPADDR}
${SSH} ${LOCAL_SSH_OPTS} ${SERVER_HOSTNAME}    -l${SERVER_USERNAME} -o Batchmode=yes   ${ROUTE_SERV}
echo "connected."
${ROUTE_ADD}
;;

stop)
echo -n "Stopping vpn to $SERVER_HOSTNAME: "
PID=`ps ax | grep ppp | grep -v passive | grep -v grep | awk '{print $1}'`
if [ "${PID}" != "" ]; then
kill $PID
echo "disconnected."
else
echo "Failed to find PID for the connection"
fi
;;

config)
echo "SERVER_HOSTNAME=$SERVER_HOSTNAME"
echo "SERVER_USERNAME=$SERVER_USERNAME"
echo "SERVER_IFIPADDR=$SERVER_IFIPADDR"
echo "CLIENT_IFIPADDR=$CLIENT_IFIPADDR"
;;

*)
echo "Usage: vpn_up {start|stop|config}"
exit 1
;;

esac
exit 0

Далее, делаем этот скрипт исполняемым:

chmod +x vpn.sh

Что бы запустить скрипт, нужно выполнить

./vpn.sh start

Остановить

./vpn.sh stop

А теперь добавим к этому всему скрипт с пингом, и сделаем так, что бы если соединение пропадает, то скрипт автоматически пытался заново соединиться. Создайте новый файл ping.sh и добавьте туда:

#!/bin/bash
#Ip of Server where we connecting, its can be som internal Ip on this server, on IP what u used fo VPN
HOSTS="10.0.0.2"
#Ip adress of some host on server side, its needed to cheak route from server to client
HOSTTWO="172.16.1.1"
DATE=`date +'%m-%d-%Y'`
#Amount of pings
COUNT=5
#Log directory
LOGDIR="/var/log/ping/"
for myHost in $HOSTS
do
count=$(ping -c $COUNT $myHost | grep 'received' | awk -F',' '{ print $2 }' | awk '{ print $1 }')
if [ $count -eq 0 ]; then
sh /etc/ppp/vpn.sh stop
sh /etc/ppp/vpn.sh start
echo "-----------------------" 1>>$LOGDIR/$DATE-ping.log
echo "`date` [ping]: New connection created" 1>>$LOGDIR/$DATE-ping.log
fi
done

for myHost in $HOSTTWO
do
count=$(ping -c $COUNT $myHost | grep 'received' | awk -F',' '{ print $2 }' | awk '{ print $1 }')
if [ $count -eq 0 ]; then
sh /etc/ppp/vpn.sh route
echo "-----------------------" 1>>$LOGDIR/$DATE-ping.log
echo "`date` [ping]: New connection created" 1>>$LOGDIR/$DATE-ping.log
fi
done

Все что надо сделать, это добавить этот скрипт в cron

К сожалению, если вы хотите использовать маршрутизацию, то вам будет необходимо все исполнять от root-a, но если вам нужно всего на всего соединить 2 компьютера, то можно использовать специального пользователя например vpn, для этого сначала создадим его:

adduser -p vpn

И теперь для этого пользователя генерируем RSA ключи, так что бы нам не было необходимости вводить пароль.

su — vpn
ssh-keygen -t rsa

Копируем содержимое файла id_rsa.pub на сервер в файл /home/vpn/.ssh/authorized_keys

Обязательно проверьте работоспособность на клиенте:

ssh -l vpn <имя сервера или его IP>

Теперь, в файле /etc/sudoers добавте :

Cmnd_Alias VPN=/usr/sbin/pppd
vpn ALL=NOPASSWD: VPN

Проверяем, что мы можем запустить pppd от имени vpn:

su — vpn
sudo /usr/sbin/pppd noauth

Если начнется вывод всякой неразберихи, то все нормально, pptpd заработал.

Если вы все же не хотите использовать root, то можно добавлять маршрутизацию не через ssh, а непосредственно на сервере. Для этого нам понадобиться скрипт, который надо запускать регулярно через крон, так что бы в случаи обрыва, а затем восстановления линии, маршрутизацию так же не пришлось долго ждать. Вот скрипт:

#!/bin/bash
REMOUTE_NETWORK="172.16.100.0"
REMOUTE_NETMASL="255.255.255.0"
CLIENT_IFIPADDR="10.10.10.2"

route -n|grep $REMOUTE_NETWORK
if [ $? -ne 0 ]; then
route add -net $REMOUTE_NETWORK netmask $REMOUTE_NETMASK gw $CLIENT_IFIPADDR

fi

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>