Создание vpn туннеля в Linux.
Опубликовано : 25-06-2009 | Автор : admin | Категория : Linux, Компьютерные сети
Имеем: Две отдельных сети с доступом в интернет:
Центральный офис: сеть 10.0.0.0/24,
10.0.0.2 - сервер, подключенный к интернет, также шлюз локальной сети. В нашей связке будет выступать в роли сервера.
81.81.81.1 - внешний адрес того же сервера.
teo.mynetwork.ru - внешнее dns имя этого сервера
Дополнительный офис: сеть 10.9.0.0/24
10.9.0.2 - сервер, подключенный к интернет, также шлюз локальной сети. В нашей связке будет выступать в роли клиента.
82.82.82.2 - внешний адрес того же сервера.
astra.mynetwork.ru - внешнее dns имя этого сервера. Это имя, как и внешний ip адрес, указаны для определённости и в настройках роли не играют.
Хотим: Организовать защищённый канал между сетями с возможностью обращаться напрямую (минуя файрвол) на компьютеры обоих сетей, расширив таким образом локальную сеть.
Делаем: Такой канал можно получить настроив VPN (Virtual Private Networks) туннель.Рассмотрим два метода создания VPN в Linux:
1) OpenVPN
2) PPP + SSH
VPN через OpenVPN
Устанавливаем из репозитория:
# apt-get install openvpn openvpn-docs
Копируем директорию со скриптами /usr/share/doc/openvpn-docs-2.0.9/easy-rsa в /etc/openvpn/ для более удобного использования. Редактируем файл с переменными /etc/openvpn/easy-rsa/vars и создаём главный единый для всех сертификат (master Certificate Authority (CA) ), которым затем будем подписывать остальные сертификаты:
# source ./vars
# ./clean-all
# ./build-ca
Скрипт вызывает openssl с соответсвующими ключами и параметрами, создавая подкаталог keys с сертификатом и ключом.
Чтобы создать сертификат вручную нужно было бы запустить команду:
# openssl req -nodes -new -x509 -keyout ca.key -out ca.crt
Создаём для сервера сертификат с ключом и параметры Диффи Хелмана:
# ./build-key-server server
# ./build-dh
Создаём сертификат и ключ для клиента:
# ./build-key client
Вместо server и client можно указать имена компьютеров, чтобы потом не путаться, т.к. ключи не имеют отношения к роли хоста, и сервер в одном соединении, используя те же ключи, может быть клиентом в другом.
Настроим сервер.
В качестве транспортной сети будем использовать 10.11.11.0/24. То есть из этой подсети будут выделяться адреса для хостов, образующих VPN. В нашем случае один сервер и один клиент
Скопируем в /etc/openvpn/keys/ созданные файлы ca.crt, dh1024.pem, server.crt, server.key. В Debian вместо расширений crt и key используется pem.
Скопируем в /etc/openvpn/ шаблонный конфигурационный файл /usr/share/doc/openvpn-docs-2.0.9/sample-config-files/server.conf и отредактируем его. У меня без комментариев остались следующие строки:
port 1194
proto tcp
dev tun
server 10.11.11.0 255.255.255.0
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh2048.pem
user nobody
group nogroup
persist-key
persist-tun
ifconfig-pool-persist /var/log/openvpn-ipp.txt
push “route 10.11.11.0 255.255.255.0″
push “route 10.0.0.0 255.255.255.0″
client-config-dir /etc/openvpn/ccd
route 10.9.0.0 255.255.255.0
status /var/log/openvpn-status.log
log-append /var/log/openvpn.log
client-to-client
tun-mtu 1500
tun-mtu-extra 32
mssfix 1450
keepalive 15 120
comp-lzo
verb 4
mute 20
У пользователя nobody может быть другая группа. Проверим командой:
# id nobody
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Создаём каталог /etc/openvpn/ccd (для Alt Linux см дальше)и в нём файл с именем Common Name сертификата клиента, которое мы указывали при создании сертификата. Уточнить это имя можно посмотрев в созданном сертификате поле CN. Пусть это будет OrgName, тогда в файле/etc/openvpn/ccd/OrgName указываем:
iroute 10.9.0.0 255.255.255.0
В Alt Linux openvpn чрутится, поэтому нужно создать ссылку на /etc/openvpn/ccd:
# ln -s /var/lib/openvpn/etc/openvpn/ccd /etc/openvpn/ccd
То, что он чрутиться именно сюда можно узнать в стартовом скрипте /etc/init.d/openvpn, найдя переменную CHROOTDIR, или выполнив этот скрипт глянуть параметр –chroot в информации о процессе:
# ps ax | grep vpn
Настроим клиента.
Скопируем в /etc/openvpn/client-name/ созданные файлы ca.crt, client.crt, client.key.
Скопируем в /etc/openvpn/ шаблонный конфигурационный файл /usr/share/doc/openvpn-docs-2.0.9/sample-config-files/client.conf и отредактируем его. У меня без комментариев остались следующие строки:
client
dev tun
proto tcp
remote 81.81.81.1 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca /etc/openvpn/client_name/ca.crt
cert /etc/openvpn/client_name/client.crt
key /etc/openvpn/client_name/client.key
comp-lzo
verb 4
mute 20
status /var/log/openvpn-client_name-stat.log
log-append /var/log/openvpn-client_name.log
Если у нас на этом компьютере больше нет openvpn серверов или клиентов, то можно запустить инициализирующий (стартовый) скрипт:
# /etc/init.d/openvpn start
Если же есть, то запускаем отдельной командой:
# openvpn /etc/openvpn/client.conf &
Если не указывать амперсент (&), то запустив команду мы потереям контроль над консолью, а указав, запустим команду в фоновом режиме. Остановить можно, удалив процесс:
# ps ax | grep vpn
12468 ? Ss 0:28 /usr/sbin/openvpn /etc/openvpn/client.conf
# kill -9 12468
Для диагностики могут помочь следующие команды:
# ps ax | grep vpn
# route | grep tun
# /etc/init.d/openvpn status
Последняя команда работает в Alt Linux, в Debian и Suse нет, а в остальных не знаю.
Полезные ссылки:
http://openvpn.net/index.php/documentation/howto.html - официальное Howto по установке и настройке на английском
VPN через PPP + SSH
Эта статья является переработкой статьи Скота Бронсона (Scott Bronson) VPN PPP-SSH Mini-HOWTO со значительным сокращением (теории и отступлений) и небольшими дополнениями.
Будем использовать пакеты ppp и ssh.
- Проверяем, поддерживает ли наше ядро протокол ppp. Проверяем и для сервера и для клиента. Для этого смотрим подключенные модули:
# lsmod
- Если нет, то нужно подключить. Смотрим есть ли у нас эти модули:
# find /lib/modules -name *ppp*
/lib/modules/2.4.22-std-up-alt22/kernel/drivers/net/ppp_async.o
/lib/modules/2.4.22-std-up-alt22/kernel/drivers/net/ppp_deflate.o
/lib/modules/2.4.22-std-up-alt22/kernel/drivers/net/ppp_generic.o
…
видим, что есть. Подключаем:
# modprobe ppp_deflate
# modprobe ppp_async
# modprobe ppp_generic
- Для подключения этих модулей при загрузке компьютера, добавляем в конец файла /etc/modules:
ppp_deflate
ppp_async
ppp_generic
- Так же на обоих компьютерах должны быть установлены пакеты ppp и ssh. Проверяем:
# rpm -qa | grep ppp
ppp-2.4.2-alt6
# rpm -qa | grep ssh
openssh-clients-3.6.1p2-alt6
openssh-server-3.6.1p2-alt6
openssh-3.6.1p2-alt6
В Debian можно проверить одной командой:
# dpkg -l ppp ssh
Видим, что всё нормально, но, если не установлено, то устанавливаем:
# apt-get install ppp
- Так как vpn туннель слегка сужает канал, то могут возникнуть проблемы с почтовой программой. Если такое случилось, то уменьшим максимальный размер пакетов для внешней сетевой карты (у меня eth1):
# ifconfig eth1 mtu 1350
И пропишем эту команду в автозагрузку /etc/rc.d/rc:
ifconfig eth1 mtu 1350
- Далее будем отдельно настраивать сервер и клиент.
Настройка сервера.
- Добавляем пользователя vpn
server# adduser -p vpn
- Проверяем, что завели пользователя корректно. С клиентской машины выполняем:
client# ssh vpn@teo.mynetwork.ru
vpn@teo.mynetwork.ru password:
- Чтобы не нужно было каждый раз набирать пароль, настроим RSA аутентификацию. Создадим публичный ключ root’a на клиенте (пароль пустой):
client# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
…
- Скопируем содержимое файла id_rsa.pub (публичная часть ключа, одна строка) на сервер в файл /home/vpn/.ssh/authorized_keys:
server# cd ~vpn
server# mkdir .ssh
server# chown root.vpn .ssh
server# chmod 755 .ssh
server# cd .ssh
server# touch authorized_keys
server# chown root.vpn authorized_keys
server# chmod 644 authorized_keys
Если будем ещё создавать vpn туннели, то в этот файл будем добавлять публичные ключи каждого клиента, по одному на строку.
- Проверяем работоспособность. На клиенте выполняем:
client# ssh vpn@teo.mynetwork.ru
Должен пустить без запроса пароля.
- Теперь нам нужно, зайдя пользователем vpn, запустить pppd от имени root’a. Для этого используем утилиту sudo. Добавляем в конец файла/etc/sudoers:
Cmnd_Alias VPN=/usr/sbin/pppd
vpn ALL=NOPASSWD: VPN
- Проверяем:
server# su - vpn
server$ sudo /usr/sbin/pppd noauth
~Ъ}#ю!}!}!} }4}”}&} } } } }%}&JoУ`}
Появление всякого мусора в течении ~30 сек говорит о том, что pppd запущен нормально. Прервать можно, нажав Ctrl+C.
- Чтобы остальные пользователи нашей сети могли пользоваться туннелем, добавляем маршрут и заносим его в файл /etc/ppp/ip-up.local, который исполняется при ppp подключении. В этот файл будем добавлять маршруты для каждного туннеля.
server# route add -net 10.9.0.0/24 gw 10.9.0.2
server# touch /etc/ppp/ip-up.local
server# chmod +x /etc/ppp/ip-up.local
/sbin/route add -net 10.9.0.0/24 gw 10.9.0.2
- Сервер не обязательно должен быть шлюзом всей нашей сети. Сейчас мы его сделали шлюзом к подсети 10.9.0.0 и на общесетевом шлюзе нужно будет прописать соответствующий маршрут.
Настройка клиента.
- Т.к. ssh и ppp уже установлены, то здесь осталось лишь запустить скрипт для соединения. Создаём /etc/ppp/vpn_up.sh:
#!/bin/sh
# This script initiates a ppp-ssh vpn connection.
SERVER_HOSTNAME=teo.mynetwork.ru
SERVER_USERNAME=vpn
SERVER_IFIPADDR=10.0.0.2
CLIENT_IFIPADDR=10.9.0.2
ROUTE_ADD=’route add -net 10.0.0.0/24 gw 10.0.0.2′
#
# The rest of this file should not need to be changed.
#
PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11/:
#
# required commands…
#
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
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}
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
Обратим внимание, что с клиентской стороны маршрут добавляется только в подсеть 10.0.0.0/24. Если хотим сделать доступными и другие подсети, то для каждой нужно добавить соответствующий маршрут. Тогда скрипт будет выглядеть следующим образом:
…
ROUTE_ADD=’route add -net 10.0.0.0/24 gw 10.0.0.2′
ROUTE_ADD2=’route add -net 10.0.10.0/24 gw 10.0.0.2′
…
${ROUTE_ADD}
${ROUTE_ADD2}
…
- Делаем скрипт исполняемым:
client# chmod +x /etc/ppp/vpn_up.sh
- Проверяем:
client# /etc/ppp/vpn_up.sh start
Using interface ppp0
Connect: ppp0 <–> /dev/pts/2
Deflate (15) compression enabled
local IP address 10.9.0.2
remote IP address 10.0.0.2
- Прекратить соединение можно соответствующей командой:
client# /etc/ppp/vpn_up.sh stop
Stopping vpn to teo.mynetwork.ru: Killed by signal 15.
Terminated
которая уберёт соответствующие маршруты с клиентской стороны. Сервер через некоторое время тоже удалит маршруты связанные с этим соединением.
- Поднимаем туннель при загрузке компьютера. Добавляем в конец файла /etc/rc.d/rc:
/etc/ppp/vpn_up.sh start
На этом всё.
Первый предпочтительней, так как являясь более молодым, он в то же время более надёжен и реализован для разных ОС, включая Windows. Оба метода были проверены на Alt Linux и Debian.
