VPN

В наше время firewall все чаще и чаще используется в Интернете и частных сетях. В связи с этим построение надежных Виртуальных Частных Сетей VPN очень важно. Здесь сосредоточил весь свой опыт в этой области. Я приветствую любые отзывы/критику/предложения по этому поводу.

Термины

Я использую здесь термины "вызывающая сторона" и "отвечающая сторона", хотя VPN никоим образом не имеет отношения к соединениям по телефонным линиям. Я просто использую их для разделения активной и пассивной стороны при установлении соединения. Машина, устанавливающая соединение, называется "вызывающая", а та, которая отвечает, называется "отвечающей".

Процедура

Планирование

Перед тем, как вы начнете настраивать свою систему, вы должны уточнить детали, касающиеся сети. Я предполагаю, что у вас имеются две интрасети, каждая из которых защищена от внешней сети своим firewall. Соответственно, у вас имеются, как минимум, два сетевых интерфейса на каждом firewall. Возьмите листок бумаги и карандаш, и запишите их IP-адреса и маски. Вам потребуется также еще один IP-адрес на каждый firewall из сетевого пространства, создаваемого вами в VPN. Эти адреса не должны входить в пространство ни одной из существующих сетей. Я предлагаю вам использовать "частные" адреса. Вот их список:

10.0.0.0 - 10.255.255.255

172.16.0.0 - 172.31.255.255

192.168.0.0 - 192.168.255.255

Например, у вас может быть такая конфигурация: Две крепости firewall называются fellini и polanski. На каждом из них имеется интернет-интерфейс (-out), интранет-интерфейс (-in), и vpn-интерфейс (-vpn). Адреса и маски:

fellini-out: 193.6.34.12 255.255.255.0

fellini-in: 193.6.35.12 255.255.255.0

fellini-vpn: 192.168.0.1 point-to-point

polanski-out: 193.6.36.12 255.255.255.0

polanski-in: 193.6.37.12 255.255.255.0

polanski-vpn: 192.168.0.2 point-to-point

Итак, план у нас есть.

Что вам понадобится

Вам понадобится

Linux firewall

ядро

самая минимальная конфигурация

ipfwadm

fwtk

Утилиты VPN

ssh

pppd

sudo

pty-redir

Сборка и установка

Соберите или установите уже собранные утилиты. Прочитайте документацию к каждой из них. Прочитайте "Howto: Firewall". Теперь у нас есть утилиты.

Настройка других подсистем

Настройте необходимые вам правила firewall, и т.п.. Вам надо будет разрешить трафик ssh между двумя машинами. Это означает, что вам надо разрешить вызывающей машине соединение с портом 22 на отвечающей. Запустите sshd на отвечающей машине, и проверьте, можете ли вы соединиться с ней с вызывающей. Этот шаг я не проверял - если возникнут проблемы, пишите.

Заводим псевдо-пользователя для VPN

Создайте на отвечающей машине псевдо-пользователя для VPN, используя свою любимую утилиту (vi, mkdir, chown, chmod). Вы можете создать его и на вызывающей машине, но, я думаю, вы будете устанавливать соединение при загрузке системы, поэтому хватит и root-а. Кто-нибудь сможет указать мне на проблемы с использованием root на вызывающей машине?

Создаем ключ ssh для вызывающей стороны

Используйте программу ssh-keygen. Установите пустой пароль, если вы хотите автоматически устанавливать соединение с VPN.

Настраиваем автоматическую авторизацию на отвечающей стороне

Скопируйте только что созданный ключ на отвечающую машину в каталог .ssh/authorized_keys и установите следующие разрешения:

drwx------ 2 slave slave 1024 Apr 7 23:49 ./ 
drwx------ 4 slave slave 1024 Apr 24 14:05 ../ 
-rwx------ 1 slave slave 328 Apr 7 03:04 authorized_keys 
-rw------- 1 slave slave 660 Apr 14 15:23 known_hosts 
-rw------- 1 slave slave 512 Apr 21 10:03 random_seed 

Первая строка - это каталог ~slave/.ssh, вторая - ~slave.

Усиляем меры безопасности ssh на обеих сторонах.

Усилить - значит указать в sshd_conf следующее:

PermitRootLogin no 
IgnoreRhosts yes 
StrictModes yes 
QuietMode no 
FascistLogging yes 
KeepAlive yes 
RhostsAuthentication no 
RhostsRSAAuthentication no 
RSAAuthentication yes 
PasswordAuthentication no 
PermitEmptyPasswords no

Парольная авторизация выключена, поэтому вход возможен только при использовании авторизованных ключей. (Вы, конечно, выключили telnet и 'r'-команды).

Разрешаем запуск ppp и route для обеих сторон.

В моем случае на вызывающей стороне работает root - ничего делать не надо. На отвечающей добавьте следующие строки в файл /etc/sudoers:

Cmnd_Alias VPN=/usr/sbin/pppd,/usr/local/vpn/route 
slave ALL=NOPASSWD: VPN 

Как вы видите, я использую скрипты для запуска ppp и настройки таблицы маршрутов на отвечающей машине.

Пишем скрипты

На вызывающей стороне я написал настоящий init-скрипт:

#! /bin/sh

PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11/:
PPPAPP=/home/slave/ppp
ROUTEAPP=/home/slave/route
PPPD=/usr/sbin/pppd
NAME=VPN
REDIR=/usr/local/bin/pty-redir
SSH=/usr/bin/ssh
MYPPPIP=192.168.0.1
TARGETIP=192.168.0.2
TARGETNET=193.6.37.0
MYNET=193.6.35.0
SLAVEWALL=polanski-out
SLAVEACC=slave

test -f $PPPD || exit 0

set -e

case "$1" in
start)
echo setting up vpn
echo Установка связи с VPN
$REDIR $SSH -o 'Batchmode yes' -t -l $SLAVEACC $SLAVEWALL sudo $PPPAPP >/tmp/device
TTYNAME=`cat /tmp/device`
echo tty is $TTYNAME
sleep 10s
if [ ! -z $TTYNAME ]
then
$PPPD $TTYNAME ${MYPPPIP}:${TARGETIP}
else
echo ОШИБКА!
logger "Соединение VPN установить не удалось"
fi
sleep 5s
route add -net $TARGETNET gw $TARGETIP
$SSH -o 'Batchmode yes' -l $SLAVEACC $SLAVEWALL sudo $ROUTEAPP
;;
stop)
ps -ax | grep "ssh -t -l $SLAVEACC " | grep -v grep | awk '{print $1}' | xargs kill
;;
*)
# echo "Usage: /etc/init.d/$NAME {start|stop|reload}"
echo "Usage: /etc/init.d/$NAME {start|stop}"
echo "Использование: /etc/init.d/$NAME {start|stop}"
exit 1
;;
esac

exit 0

На отвечающей потребовался только скрипт, добаляющий строку в таблицу маршрутизации (/usr/local/vpn/route):

#!/bin/bash 
/sbin/route add -net 193.6.35.0 gw 192.168.0.1 

а в файл .ppprc я записал следующее:

passive 

Что же на самом деле происходит?

Вызывающая сторона заходит в отвечающую, запускает pppd и переназначает все на локальный pty. Для этого он проделывает следующее:

создает новое pty

соединяется с отвечающей машиной при помощи ssh

запускает на отвечающей машине pppd

запускает pppd на этом новом локальном pty

настраивает таблицу маршрутов на обеих машинах.

Существуют небольшие задержки, поэтому используется 'sleep 10s'.

Делаем это вручную

Заходим в систему

Вы ведь уже попробовали, работает ли ssh? Если отвечающая машина не позволяет вам войти в систему, читайте системные журналы. Возможно проблема состоит в неправильных правах на файлы, или неправильно настроен sshd.

Запускаем ppp

Зайдите в отвечающую машину и выполните команду: sudo /usr/sbin/pppd passive

Вы должны увидеть на экране мусор. Если это так - это хорошо. Если нет - значит возникла проблема с sudo, или с pppd. Посмотрите на текст ошибки, просмотрите журналы, файлы /etc/ppp/options и .ppprc . Если все нормально - запишите слово 'passive' в файл .ppprc, и попытайтесь снова. Чтобы избавиться от мусора, нажмите Enter,'~' и '^Z'. После этого вы получите приглашение командной строки вызывающей машины - дайте команду kill %1. Читайте главу "Подстройка", если хотите подробнее узнать о специальных символах.

И второй тоже

Теперь команда ssh -l slave polanski sudo /usr/sbin/pppd

должна работать, и вы снова увидите тот же самый мусор.

Переназначаем Pty

Попробуйте переназначить сразу все командой /usr/local/bin/pty-redir /usr/bin/ssh -l slave polanski sudo /usr/sbin/pppd

Красивая длинная команда, не так ли? Вы должны использовать полный путь к программе ssh, так как программа переназначения pty позволяет только такую форму - это сделано из соображений безопасности. Теперь у вас есть имя устройства - его вам сказала программа. Предположим, что это /dev/ttyp0. Вы можете использовать команду ps, чтобы узнать, что же случилось. Ищите 'p0'

Как дела на устройстве?

Попробуйте дать команду /usr/sbin/pppd /dev/ttyp0 local 192.168.0.1:192.168.0.2

чтобы установить соединение. Проверьте наличие интерфейса при помощи команды ifconfig. Проверьте сеть при помощи ping.

Настройка таблицы маршрутов

Настройте таблицу маршрутов на вызывающей и отвечающей машине. После этого у вас должна работать команда ping с любой машины в одной сети на любую машину в другой. Задайте дополнительные правила firewall. Теперь у вас есть VPN, и вы можете настроить все правила, учитывая связь двух интрасетей.

Подстройка

Подстройка конфигурации

Как я уже говорил, это HOWTO - набор записок на тему "Как я настраивал VPN". В этой конфигурации есть вещи, с которыми я не экспериментировал. Все встанет на свое место, когда я все испытаю, или кто-то скажет мне "это должно работать так-то". Самое главное - соединение, которое использует ppp, до сих пор не является 8-битным. Я думаю, что надо что-то сделать с конфигурацией ssh или pty. На данный момент ssh использует символ "тильда" (~) в качестве служебного. Это может привести к замедлению или разрыву соединения - каждое сочетание символов Enter-~ будет вызывать системное приглашение ssh. В документации к ssh сказано: <В большинстве случаев отключение служебного символа даст полностью прозрачное соединение, как будто используется tty.> Соответствующий флаг ssh - '-e', вы можете устанавливать его в конфигурационном файле.

Пропускная способность и загруженность систем

Все виртуальное всегда использует реальные ресурсы. VPN требует пропускной способности канала и вычислительных ресурсов. Цель- установить баланс между ними. Вы можете достичь его, подобрав настройку флага '-C' или опции 'CompressionLevel'. Вы даже можете использовать другой компрессор-шифрователь, но я бы этого не рекомендовал. Заметьте, что время прохождения может уменьшиться при увеличении степени компрессирования. Творите, выдумывайте, пробуйте.

Анализ уязвимости

Я попытаюсь описать незащищенные места этой настройки, и VPN вообще. Все комментарии горячо приветствуются.

sudo: Да, я использую sudo. Но я все же считаю, что это надежнее, чем устанавливать биты setuid. Эти биты до сих пор являются спорной вещью в Linux. Ждем совместимости с рекомендациями POSIX.6 <http://www.xarius.demon.co.uk/software/posix6/>. Что может быть хуже запуска скриптов при помощи sudo? Брррр. Есть какие-нибудь идеи?

pppd: У него тоже есть флаг suid root. Его можно настроить при помощи пользовательского файла .ppprc. Он может вызвать переполнения буферов. Результат: защитите псевдо-пользовательский вход на отвечающей машине настолько, насколько возможно.

ssh: Знайте, что у ssh версий ранее 1.2.20 есть проблемы с системой защиты. Что может быть хуже - пользователи на обеих машинах открыты, две программы используют sudo. Это все потому, что я отказался от пароля на секретном ключе вызывающей машины в пользу автоматического установления связи с VPN.

firewall: Если неправильно настроить правила firewall на одной из машин, вы откроете снаружи доступ к обеим сетям. Я рекомендую использовать IP-маскарадинг (неправильная настройка маршрутов встречается реже), и хорошо следить за VPN-интерфейсами.