portrait

Поиск



[software] [catdoc] [tcl] [geography] [old things]

По ssh через firewall-ы

Нет ничего сложного в том, чтобы зайти по ssh на машину за файрволл-ом с NAT, если у вас есть логин на сам firewall. Особенно, если на этом firewall-е установлен netcat.

У openssh есть полезная опция ProxyCommand, которая может быть использована для этой цели. Например можно написать в свой .ssh/config

 Host *.intranet.mycompany.com
 ProxyCommand ssh firewall.mycompany.com nc -q 0 %h 22

После этого при попытке пойти по ssh на любой хост в домене intranet.mycompany.com будет производиться запуск netcat на машине firewall.mycompany.com, который и будет доставлять информацию от вашего ssh на 22 порт требуемой машины (обратите внимание на опцию -q 0).

Проблемы возникают если ваша машина — ноутбук, и находится то в корпоративном интранете, то только снаружи.

Нижеприведенный шелловский скрипт эту проблему решает. К нему имеется файл конфигурации, в котором описывается список nat-сетей, в которые хочется ходить по ssh.

Предусмотрены две директивы:

add_domain domain host...
Задает список хостов, которые принадлежат некоторой сети. В случае если скрипт вызван с указанием одного из этих хостов без домена, считать, что хост принадлежит указанному домену
proxy proxy_host domain_mask
Указывает на какой машине следует запускать netcat для доступа к хостам указанного домена. domain_mask может содержать звездочки и другие метасимволы, допустимые в команде case shell. С маской сопоставляются имена хостов, дополненные доменными именами в соответствии с командой add_domain.
#!/bin/sh
host=$1
shift
declare -a OPTIONS
myhost=`hostname -f`
add_domain() {
    domain=$1
    shift
    for i do
        if [ "$i" = "$host" ]; then
            host=$host.$domain
            return
        fi
    done
}
proxy() {
    [ -n "$OPTIONS" ] && return
    case "$host" in
    $2)
        case "$myhost" in
        $2)
            OPTIONS=""
        ;;
        *)
        OPTIONS="-o \"ProxyCommand /usr/bin/ssh $1 nc -q 0 %h 22\""
        ;;
        esac
    ;;
    *) OPTIONS=""
    ;;
    esac
}
source ${HOME}/.rsrc

[ -n "$1" ] || set exec '$SHELL' --login
eval exec "/usr/bin/ssh -t ${OPTIONS}  "$host" LANG=\$LANG \"\$@\""
Файл .rsrc может выглядеть, например, вот так:
add_domain home.ru dragon vasilisk hydra
add_domain kontora.ru elk ibex bear wolf
proxy gw.home.ru *.home.ru
proxy firewall.kontora.ru *.kontora.ru
В результате использования такого файла
  1. Короткие имена хостов dragon, vasilisk и hydra будут расширятся до dragon.home.ru, vasilisk.home.ru etc, независимо от того, в какой сети сейчас машина.
  2. Аналогично имена хостов elk, ibex etc будут искаться в домене kontora.ru
  3. Обращения к хостам домена kontora.ru будет происходить через прокси gw.kontora.ru, если только мы не в локальной сети конторы (и по dhcp нам не отдали доменное имя kontora.ru)
  4. Обращения к хостам home.ru будут происходить через gw.home.ru, если только мы не в локальной сети home.ru