В данном разделе опишу как использовать возможности OpenSSH для создания Layer 3 туннелей, применительно к OS Debian GNU/Linux (наверняка без особых проблем заработает и в Ubuntu).

Примерно так выглядит схема, которую мы построим:

----------        /\_/-\/\/-\       -----------------
| Клиент |~~~~~~~/ Интернет /~~~~~~~|    Сервер     |
----------       \_/-\/\_/\/      / -----------------
||\                           \          ||\
|| {tun0}                      {vlan8}   || {tun1}
||                                       ||
\-================= tunnel ==============-/

    * vlan8 - 212.90.160.1/27
    * tun0 - 10.254.254.2/30
    * tun1 - 10.254.254.1/30


Подготовительные работы на клиентской стороне.

В нашей схеме будем использовать аутентификацию по ключу, для этого сначала сгенерируем сам ключ (тип ключа rsa, размер 4Кбита) и скопируем его в учётную запись root'а на сервере (на сервере, при этом, придётся на время открыть возможность логиниться root'ом — PermitRootLogin yes):

# sudo ssh-keygen -t rsa -b 4096
# ssh-copy-id -i .ssh/id_rsa.pub root@212.90.160.1


На этом этапе мы уже будем иметь сохранённый ключ ssh в .ssh/known_hosts, дав ответ «yes» примерно на такой вопрос:

The authenticity of host '212.90.160.1 (212.90.160.1)' can't be established.
RSA key fingerprint is aa:fe:a0:38:7d:11:78:60:01:b0:80:78:90:ab:6a:d2.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '212.90.160.1' (RSA) to the list of known hosts.


и уже скопированный в .ssh/authorized_keys на стороне сервера ключ авторизации клиента.

Далее прописываем на стороне клиента сам интерфейс в /etc/network/interfaces:

auto tun0
iface tun0 inet static
pre-up ssh -S /var/run/ssh-myvpn-tunnel-control -M -f -w 0:1 212.90.160.1 true
pre-up sleep 5
post-up ip l s tun0 mtu 1300
address 10.254.254.2
netmask 255.255.255.252
pointopoint 10.254.254.1
post-down ssh -S /var/run/ssh-myvpn-tunnel-control -O exit 212.90.160.1


На этом этапе прекратим работы с клиентом и приступим к серверу.

Подготовительные работы на стороне сервера.

На стороне сервера перво-наперво вносим следующие изменения в /etc/ssh/sshd_config:

PermitTunnel point-to-point
PermitRootLogin forced-commands-only


Теперь отредактируем /root/.ssh/authorized_keys, добавив в него команду на организацию туннеля:

tunnel="1",command="/sbin/ifdown tun1;/sbin/ifup tun1" ssh-rsa AAAA......X9vc= root@ipclub


После этого отредактируем /etc/network/interfaces:

auto vlan8
iface vlan8 inet static
address 212.90.160.1
netmask 255.255.255.224
network 212.90.160.0
broadcast 212.90.160.31
gateway 212.90.160.30
vlan_raw_device eth0
mtu 1400

iface tun1 inet static
address 10.254.254.1
netmask 255.255.255.252
pointopoint 10.254.254.2
post-up ip l s tun0 mtu 1300


Не забываем определить в /etc/sysctl.conf состояние net.ipv4.conf.default.forwarding:
Код

net.ipv4.conf.default.forwarding=1


ну или перед использование туннеля:

$ sudo sysctl net.ipv4.conf.default.forwarding=1


Важно! Если не устанавливать net.ipv4.conf.default.forwarding в значение 1, то туннели подниматься не будут!

Собственно на этом этапе все подготовительные работы закончены. Пробуем поднять наш туннель со стороны клиента:

$ sudo ifup tun0
$ ip a l dev tun0
9: tun0:  mtu 1300 qdisc pfifo_fast qlen 500
link/[65534]
inet 10.254.254.2 peer 10.254.254.1/30 scope global tun0
$ ping -c2 10.254.254.1
PING 10.254.254.1 (10.254.254.1): 56 data bytes
64 bytes from 10.254.254.1: icmp_seq=0 ttl=64 time=15.116 ms
64 bytes from 10.254.254.1: icmp_seq=1 ttl=64 time=16.454 ms
--- 10.254.254.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 15.116/15.785/16.454/0.669 ms


И наблюдаем icmp трафик на стороне сервера:

$ sudo tshark -tad -pni tun1
Running as user "root" and group "root". This could be dangerous.
Capturing on tun1
2009-03-10 11:25:53.927598 10.254.254.2 -> 10.254.254.1 ICMP Echo (ping) request
2009-03-10 11:25:53.927649 10.254.254.1 -> 10.254.254.2 ICMP Echo (ping) reply
2009-03-10 11:25:54.567857 10.254.254.2 -> 10.254.254.1 ICMP Echo (ping) request
2009-03-10 11:25:54.567910 10.254.254.1 -> 10.254.254.2 ICMP Echo (ping) reply


Дальше можете работать с этими интерфейсами как с обычными eth, vlan, gre и т.д. Маршрутизировать трафик через них, настраивать правила фильтрации и т.д. и т.п. Полёт мысли ограничивается лишь фантазией wink.gif Однако не забываем, что туннель всё-таки построен на третьем уровне поэтому маркирование пакетов QoS вряд-ли даст тот результат который хотелось бы ожидать.

Собственно на этом можно было бы и закончить, но хочется обратить внимание на один «скользкий» момент, для тех кто хочет поднимать несколько SSH Layer 3 туннелей.
Клиент: pre-up ssh -S /var/run/ssh-myvpn-tunnel-control -M -f -w 0:1 212.90.160.1 true
Сервер: tunnel=«1»,command="/sbin/ifdown tun1;/sbin/ifup tun1" ssh-rsa AAAA......X9vc= root@ipclub
0 — это номер туннеля на стороне клиента
1 — это номер туннеля на стороне сервера

Вот, чуть не забыл.
Есть ещё один неприятный момент. Соединение, периодически может «отваливаться». Посему неплохо будет озаботиться где нидудь в cron'е выполнить примерно такой сценарий, на стороне клиента:

$ cat /etc/cron.d/tun0
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/5 *     * * *     root   fping -c4 10.254.254.1 || ( /sbin/ifdown tun0; sleep 5; /sbin/ifup tun0 )
$ sudo /etc/init.d/cron restart