четверг, 7 июля 2011 г.

ssh и vpn

Есть такая отвратительная, глючная и тупая штука, как VPN. Делает она следующее, как бы устраивает туннель между двумя сетями, причем так, что бы другие в него не ломились.

Вообще эта технология называет tunneling и известна достаточно давно. Сегодня расскажу по такую замечательную вещь, как ssh.
- Стоп, ты о ней уже говорил!
- Говорил, но не о всем же вкусном в нем.

В общем есть у ssh ключик, который позволяет в рамках ssh сессии прокинуть туннель.
Что мы будем иметь в сухом остатке:

  • Безопасность, т.к. всё шифруется.
  • Удобство.
  • Авто вход.



А теперь представляю вам чудо.
~# ssh root@somehost.com -w 0:0
Эта команда в дальнейшем позволит инициализировать два tun устройства, которые будут общать по средство peer-to-peer. Проблема в том, что для того, что бы поднять эти два устройства требуется пароль рута (возможно рут и не требуется, но для начала делается именно так). Т.е. говорим вышеизложенную команду, вводим пароль и ... пока пустота. Никаких настроенных tun устройств вы не увидите(ip addr show - поможет увидеть просто устройства).
И Проблема ещё в том, что для автоматизации хочется не вводить пароль.

У ssh для этих целей есть метод авторизации по ключам.
На клиентской машине говорим
root: ~# ssh-keygen
Нажать два раза enter и ... в каталоге /root/.ssh/ будут лежать как минимум два файла
id_rsa и id_rsa.pub
id_rsa.pub - это публичная часть ключа, её можно даже потерять, не беда, она восстанавливается.
Все дальнейшие действия как на стороне сервера, так и клиента будут происходить от имени рута
Дальше зададим права только для id_rsa
cd /root/.ssh
chmod 400 id_rsa
Теперь копируем на сервер id_rsa.pub
scp id_rsa.pub root@somehost.com:/root/.ssh/id_rsa.pub
Внимание, должна быть включена возможность входа по руту через ssh ( в /etc/ssh/sshd_config)
PermitRootLogin YES
Удаляем id_rsa.pub
И заходим на сервер
cd /root/.ssh
cat id_rsa.pub >> authorized_keys
rm id_rsa.pub
Теперь мы спокойно войдем без пароля, но только под рутом. И можем поменять настройки ssh:
PermitRootLogin without-password
PermitTunnel yes
Теперь немного теории. Когда ты скажешь ssh root@somehost.com -w 0:0, то на сервере и клиенте уже можно сказать
ip addr show
и мы увидим устройство tun0

Дальше на сервере
ifconfig tun0 10.0.0.1/30 pointopoint 10.0.0.2
А теперь на клиенте
ifconfig tun0 10.0.0.2/30 pointopoint 10.0.0.1
Ну и последнее, что необходимо это дать доступ клиенту к подсети сервера, допустим она
192.168.50.0/24
route add -net 192.168.50.0/24 gw 10.0.0.1
Теперь клиент видит подсеть сервера.

- А где тут "вход автоматом"?
- Это сейчас мы и сделаем.

Нам надо сделать след. при поднятии tun0 устройства, клиент должен залезть на сервер по ssh
А сервер, при заходе конкретно этого клиента должен поднять своё tun устройство.

На сервере в файле authorized_keys припишем к нашему ключ
tunnel="0",command="/sbin/ifdown tun0;/sbin/ifup tun0" ssh-rsa
И отредактируем /etc/network/interfaces
iface tun0 inet static
      address 10.0.0.1
      netmask 255.255.255.252
      pointopoint 10.0.0.2
В /etc/sysctl.conf
net.ipv4.conf.default.forwarding=1
И заставим перепрочесть sysctl.conf
sysctl -p

На стороне клиента в /etc/network/interfaces
iface tun0 inet static
      pre-up ssh -S /var/run/ssh-vpn-tunnel-control -M -f -w 0:0 root@somehost.com true
      pre-up sleep 5
      address 10.0.0.2
      pointopoint 10.0.0.1
      netmask 255.255.255.252
      up route add -net 192.168.50.0 netmask 255.255.255.0 gw 10.0.0.1 tun0
      post-down ssh -S /var/run/ssh-vpn-tunnel-control -O exit root@somehost.com
Собственно вся красота в действии.
На стороне клиента говорим ifup tun0 и радуемся.

P.S.: Что мне не нравится в этом конфиге.
Хочется, что бы при инициализации tun устройств не требовалось рута.
Допустим какая-нибудь группа аккаунтов vpn. Если вход осуществлен под этой группой, то сразу же поднимать tun устройства. Но для начала это излишки.

Комментариев нет: