Linux. PPP over SSH или VPN из подручных материалов.
Почему именно PPP over SSH?
Разумеется есть много способов сделать VPN подключение, есть и несколько стандартных VPN клиент-серверов,
есть IPSec, CIPE, да много еще чего, но рассказ про то как все собрать из подручных материалов за
пять минут, ведь PPP и SSH есть практически везде, устанавливать что-то новое и разбираться
с настройками не всегда возможно и необходимо.
Настройка
Настройка требуется для обоих сторон VPN соединения, сервера (куда будем ходить) и клиента
(для кого делаем VPN).
Для ясности в приглашениях в примерах ниже будут соответствующие пометки.
Сначала прикрутим SSH - транспорт для нашего VPN, а потом разберемся с PPP.
Поехали.
На сервере заводим отдельного пользователя/группу vpn:
server# groupadd vpn
server# useradd -m -d /home/vpn -g vpn vpn
Настройка SSH
На клиенте можно сделать специального пользователя, а можно и логиниться от пользователя root.
Никаких преимуществ в плане безопасности работа от специального пользователя не дает.
Сначала нужно разобраться с SSH ключами для пользователя vpn на клиенте. Идея заключается в том,
чтобы авторизация происходила именно по ключам, ведь набирать руками пароль никто не будет.
Процедуры немного отличаются для SSH версий 1 и 2.
Делаем SSH ключики для рута или используем готовые если они уже сделаны. Я оставил passphraze пустой,
если планируются другие соединения с использованием ключа, то лучше все-таки завести специального
пользователя.
SSH1:
client# ssh-keygen1
Initializing random number generator...
Generating p: ...++ (distance 32)
Generating q: .....++ (distance 50)
Computing the keys...
Testing the keys...
Key generation complete.
Enter file in which to save the key (/root/.ssh/identity): <ENTER>
Enter passphrase: <ENTER>
Enter the same passphrase again: <ENTER>
Your identification has been saved in /root/identity.
Your public key is:
1024 37 1103467.....6350851 root@domain.com
Your public key has been saved in /identity.pub
SSH2:
client# ssh-keygen2
Generating 2048-bit dsa key pair
6 Oo.oOo.ooOo.
Key generated.
2048-bit dsa, root@domain.com, Tue Mar 15 2001 16:35:50 +0200
Passphrase : <ENTER>
Again : <ENTER>
Key is stored with NULL passphrase.
(You can ignore the following warning if you are generating hostkeys.)
This is not recommended.
Don't do this unless you know what you're doing.
If file system protections fail (someone can access the keyfile),
or if the super-user is malicious, your key can be used without
the deciphering effort.
Private key saved to /root/.ssh2/id_dsa_2048_b
Public key saved to /root/.ssh2/id_dsa_2048_b.pub
Теперь нужно добавить public ключики на сервер, копируем identity.pub или id_dsa_2048_b.pub на сервер
в /home/vpn, далее на сервере:
SSH1:
server# su - vpn
server$ cd
server$ mkdir -m 0700 .ssh
server$ cat identity.pub >> .ssh/authorized_keys
SSH2:
server# su - vpn
server$ cd
server$ mkdir -m 0700 .ssh2
server$ cat id_dsa_2048_b.pub >> .ssh2/key.pub
server$ echo "key.pub" >> .ssh2/authorization
Проверяем как работает авторизация по ключу:
client# ssh vpn@my.server.com
или
client# ssh2 vpn@my.server.com
The authenticity of host 'my.server.com' can't be established.
RSA1 key fingerprint is
...bla-bla-bla...
Are you sure you want to continue connecting (yes/no)? <yes>
При повторных попытках логина на сервер ничего спрашиваться не будет, пользователя vpn
будут молча впускать, авторизуя по ключу.
Очень здравой идеей будет сравнить ключ на сервере (/etc/ssh/ssh_host_key.pub или
/etc/ssh2/hostkey.pub) и на клиенте
(~/.ssh/known_hosts или ~/.ssh2/hostkeys/key_22_my.server.com),
потому как SSH можно атаковать с помощью man-on-the-middle.
Настройка PPP
Создаем файл /etc/ppp/options:
lock
#__END__
Редактируем конфиг для соединения server, файл /etc/ppp/peers/server
# куда будем записывать логи
logfile /var/log/ppp/server.log
# после отладки можно закомментировать
debug
# адреса сторон, берем из private pool
10.10.0.2:10.10.0.1
name client
remotename server
noauth
nodefaultroute
# собственно SSH транспорт, который так старательно конфигурили
# BlowFish работает чуть быстрее
pty "ssh -P -p 22 -e none -c blowfish -t -l vpn my.server.com /usr/sbin/pppd passive"
# задержка перед PPP
connect-delay 30000
# 10 по умолчанию, на загруженных линиях недостаточно
lcp-max-configure 30
# LCP restart interval (retransmission timeout) to n sec-onds (3 по умолчанию)
lcp-restart 10
# подстраиваем MTU, после распаковки пакеты должны влезать в один ethernet frame
mtu 1200
mru 1200
# после коннекта отрубаемся от shell и в background
updetach
# постоянно держать соединение, реконнект по закрытию
persist
holdoff 60
# реконнектиться до посинения
maxfail 15
nodetach
#__END__
Окончательная проверка
Запускаем PPP руками
client# pppd call server
Если все нормально, то через некоторое время поднимется дополнительный PPP интерфес:
client# ifconfig
ppp0 Link encap:Point-to-Point Protocol
inet addr:10.10.0.2 P-t-P:10.10.0.1 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1200 Metric:1
RX packets:181854 errors:0 dropped:0 overruns:0 frame:0
TX packets:128988 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:157423266 (150.1 Mb) TX bytes:13604013 (12.9 Mb)
client# ping -c3 10.10.0.1
PING 10.10.0.1 (10.10.0.1) 56(84) bytes of data.
64 bytes from 10.10.0.1: icmp_seq=0 ttl=64 time=25.5 ms
64 bytes from 10.10.0.1: icmp_seq=1 ttl=64 time=26.8 ms
64 bytes from 10.10.0.1: icmp_seq=2 ttl=64 time=23.7 ms
С точки зрения ОС это полноправный сетевой интерфейс, ничем не отличающийся от любых других.
Можно ходить по FTP, монтировать файловые системя по NFS или SMB и так далее.
В реальной жизни не все так гладко. Иногда SSH соединения обрываются не совсем корректно и
PPP не может сразу распознать проблему и правильно перезапустить SSH. Придется ему немного помочь.
Забираем
вот такой скрипт.
Если выбранные для peer'ов IP адреса не соответствуют приведенным в примерах, правим строчку:
$remote_ip = '10.10.0.1';
Запускаем от рута
client# repppd.plx
Forked OK (2030)
Теперь скрипт будет самостоятельно запускать PPP, периодически проверять соединение и при необходимости
перезапускать PPP. Остановить VPN тоже несложно:
client# kill 2030
Дополнение: SSH через HTTP PROXY
Иногда возникает необходимость настройки ssh соединения через обычный http proxy. Понятно, что в настройках proxy дожны быть разрешены запросы CONNECT к серверу, на котором крутится SSH демон.
В таких запущенных случаях приходится использовать внешнюю программу, так называемый relay для проброса
соединения через proxy.
Идем сюда и забираем
connect.c. Эта небольшая программа
понимает как обычные HTTP PROXY, так и SOCKS. Дополнительно поддерживает авторизацию на proxy серверах.
Компилим и ставим:
> gcc -o connect connect.c
> strip connect
> mv connect /usr/local/bin
Проверяем как оно работает:
> connect -H squid.proxy.host:3128 -d my.server.com 22
DEBUG: checking my.server.com is for direct?
DEBUG: my.server.com is for not direct.
DEBUG: connecting to squid.proxy.host:3128
DEBUG: begin_http_relay()
DEBUG: >>> "CONNECT my.server.com:22 HTTP/1.0\r\n"
DEBUG: >>> "\r\n"
DEBUG: <<< "HTTP/1.0 200 Connection established\r\n"
DEBUG: connected, start user session.
DEBUG: <<< "\r\n"
DEBUG: connected
DEBUG: start relaying.
DEBUG: recv 15 bytes
SSH-2.0-2.9.12
Все работает.
Далее нужно объяснить SSH, что для коннекта на my.server.com нужно использовать connect.
В ~/.ssh/config добавляем строчки
Host my.server.com
ProxyCommand connect -H squid.proxy.host:3128 %h %p
На этом все! Удачных VPN коннектов!
Tags: linux vpn ppp crypto
Назад в оглавление
|