Удаленное управление Ububtu без выделенных IP

in

Можно было бы использовать TeamViewer (если офисы некоммерческие :)), но дело в том, что в самих офисах люди имеют лишь обычные права пользователей, дабы использовать ПК только в рабочих целях и не лезть, куда не просят. А TeamViewer запущенный обычным пользователем будет иметь его же - обычные права.

Решение - SSH-тоннели. Придется иметь посредника - SSH сервер с выделенным внешним IP адресом. Коим, вероятно, может оказаться и ваш продвинутый роутер, перепрошитый DD-WRT (чтобы не держать компьютер постоянно включенным).

Чтобы не запутаться в понятиях "клиент", "сервер" (ведь офисный компьютер - сервер vnc и клиент ssh одновременно и т.д.). Определимся: компьютер, который стоит в офисе и к которому нужно подключаться - ПКОфис. SSH-сервер с внешним IP - "Сервер". Любой компьютер с которого мы хотим управлять ПКОфисом - "ПКДом".

ПКОфис - установка необходимых служб на Ubuntu 12.04

Основная работа будет с нашим ПКОфис, т.к. он должен инициировать обратное ssh соединение и запускать VNC сервер с root правами. Причем сам root пользователь в Ubuntu отключен.

Устанавливаем SSH-сервер

sudo apt-get install openssh-server openaah-client autossh

Дождитесь завершения установки. Теперь нужно сделать несколько изменений в конфиге ssh, в целях безопасности. Предварительно сделав резервную копию старого конфига.

sudo cp /etc/ssh/sshd_config ~
sudo gedit /etc/ssh/sshd_config

В конце файла допишем пару строк:
USERNAME - заменяем на имя пользователя, которому вы разрешаете подключаться по ssh. Если нужно разрешить доступ нескольким пользователям - пишем их login имена через пробел.

PermitRootLogin no
AllowUsers USERNAME

TCPKeepAlive yes
ClientAliveInterval 60
ClientAliveCountMax 3
## ClientAliveCountMax #####################################
#                                                          #
# Задает количество сообщений к клиентам, которые sshd     #
# посылает подряд, не получая какого либо ответа от        #
# клиента. Если пороговое значение будет достигнуто, а     #
# клиент так и не ответил - sshd отключит клиента, прервав #
# ssh сессию. Стоит отметить, что использование таких      #
# сообщений в корне отличается от директивы TCPKeepAlive.  #
# Сообщения к/от клиентов посылаются по зашифрованному     #
# каналу и поэтому не подвержены спуфингу. Сообщения же    #
# TCPKeepAlive спуфингу подвержены. Механизм client alive  #
# особо ценен в тех случаях, когда серверу и клиенту нужно #
# знать когда соединение стало неактивным. По умолчанию    #
# значение равно 3. В случае, если ClientAliveInterval     #
# задан равным 15 и ClientAliveCountMax оставлен по        #
# умолчанию, неотвечающие клиенты будут отключены примерно #
# через 45 секунд. Эта директива работает только для       #
# протокола ssh2.                                          #
#                                                          #
## ClientAliveInterval #####################################
#                                                          #
# Задает временной интервал в секундах. Если в течении     #
# этого интервала не было обмена данными с клиентом, sshd  #
# посылает сообщение по зашифрованному каналу,             #
# запрашивающее ответ от клиента. По умолчанию - 0, т.е.   #
# не посылать таких сообщений. Эта директива работает      #
# только для протокола ssh2.                               #
#                                                          #

И настройки сервера (файл /etc/ssh/ssh_conf)

PermitRootLogin no
AllowUsers USERNAME

#TCPKeepAlive yes
ServerAliveInterval 60
ServerAliveCountMax 3
StrictHostKeyChecking=no
BatchMode=yes

Желательно, также поменять порт ssh (Ports). По-умолчанию он работает на порте TCP/IP 22, поэтому множество вредоносных скриптов пытаются сканировать и взламывать этот порт. Поставив порт с большим значением усложнит процесс нахождения вашего ssh сервера. Можете поставить, например, порт 4890.

Чтобы изменения вступили в силу, нужно перезапустить ssh сервер Ubuntu. пишем в консоли:

sudo service ssh restart

Устанавливаем VNC сервер

Для начала заходим как root! так как в будущем установленные приложения будут запускаться от root при старте системы, если вы установите и настроите приложения используя просто sudo – все файлы окажутся вашими, и система не сможет их использовать.

sudo -i

Далее все комады без sudo, т.к. мы уже работаем от лица root.
Устанавливаем необходимые пакеты:

apt-get install tightvncserver xfonts-base xfonts-75dpi twm xterm

Создаем файл настроек:

pico /etc/vnc.conf

В файл прописываем строку:

$fontPath = "/usr/share/fonts/X11/75dpi/,/usr/share/fonts/X11/misc/"

Запускаем VNC сервер с параметрами

vncserver -depth 8 -geometry 800x600 -nevershared -dontdisconnect

При первом запуске vnc-сервер попросит нас задать пароль, который будет использоваться для доступа к удаленному рабочему столу. Здесь нельзя использовать длинный пароль – обычно VNC пароль длиной до 8 символов. Потом нас спросят, хотим ли мы задать view-only пароль? Или задаем или нет, по вкусу.

На данном этапе вы уже можете подключиться к VNC серверу из вашей локальной сети с помощью VNC клиента с другого компьютера, используя локальный IP ПКОфис. Советую проверить эту возможность, чтобы знать, что до этого этапа вы все делаете правильно.

Решение проблемы входа в Ubuntu - правильный пароль, черный экран

Внимание! Есть вероятность, что вы не сможете зайти под своим пользователем в Ubuntu, если сейчас разлогинитесь. Система примет ваш пароль начнет загружаться, экран потемнеет, потом появиться указатель мыши, потом вы вернетесь на экран выбора пользователя, услышав звук ошибки. Хотя ни о какой ошибке Ubuntu вас не оповестит. Причина - права доступа к файлу .Xauthority. Запишите на листочек порядок действий, и попробуйте выйти и зайти в свой акаунт.

На login screen жмем Ctrl+Alt+F3 - открывается терминал. В нем прописываем строку "ls -lah" и получаем результат:

ls -lah
. . . .
-rw-------  1 root root   53 Nov 29 10:19 .Xauthority
. . . .

Если вы видите в строке права "root root" вместо вашего логина USERNAME. Вам надо сделать следующее:

chown username:username .Xauthority

Затем нажимайте комбинацию Alt + → пока снова не увидите окно выбора пользователя. На этот раз ваш пароль "прокатит" :)

Автозапуск VNC сервера с определенным пользователем

Прописываем код для автоматического запуска VNC сервера. А так как удаленный рабочий стол автоматически загружается в root-сессию, это не очень удобно – мы ведь хотим видеть именно свой рабочий стол. Настроим сервер так, чтобы «экспортировался» рабочий стол определенного пользователя (командой su запускаем сервер от имени нужного пользователя).

Создаем файл /etc/init.d/vncserver - это будет скрипт запуска сервера от нужного пользователя с указанными настройками

pico /etc/init.d/vncserver

В файле прописываем следующее (отредактируйте имя пользователя, размеры экрана, IP внешнего ssh сервера, и название которое будет в заголовке окна, здесь это Atom). В моем случае - имя пользователя "toopro"

#!/bin/sh -e
### BEGIN INIT INFO
# Provides: vncserver
# Required-Start: networking
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
### END INIT INFO
PATH="$PATH:/usr/X11R6/bin/"
# The Username:Group that will run VNC
export USER="toopro"
#${RUNAS}
# The display that VNC will use
DISPLAY="1"
# Color depth (between 8 and 32)
DEPTH="16"
# The Desktop geometry to use.
#GEOMETRY="x"
#GEOMETRY="800x600"
GEOMETRY="1024x768"
#GEOMETRY="1280x1024"
# The name that the VNC Desktop will have.
NAME="TooProOffice1"
OPTIONS="-name ${NAME} -depth ${DEPTH} -geometry ${GEOMETRY} :${DISPLAY}"
. /lib/lsb/init-functions
case "$1" in
start)
log_action_begin_msg "Starting vncserver for user '${USER}' on localhost:${DISPLAY}"
su ${USER} -c "/usr/bin/vncserver ${OPTIONS}"
su ${USER} -c "autossh -M 0 -fNg -R 5557:localhost:5901 root@SSH_SERVER_IP_ADDRESS &" #X server
su ${USER} -c "autossh -M 0 -fNg -R 5587:localhost:80 root@SSH_SERVER_IP_ADDRESS &" #apache http
su ${USER} -c "autossh -M 0 -fNg -R 5527:localhost:22 root@SSH_SERVER_IP_ADDRESS &" #ssh console
;;
stop)
log_action_begin_msg "Stoping vncserver for user '${USER}' on localhost:${DISPLAY}"
su ${USER} -c "/usr/bin/vncserver -kill :${DISPLAY}"
killall ssh
;;
restart)
$0 stop
$0 start
;;
esac
exit 0

При соединение по ssh используем флаг -N , который сообщает, что никаких ssh-команд нам посылать не понадобится, только открыть порт. И в конце ставим символ & , чтобы нам не выпадала ssh консоль сервера, т.к. при загрузке системы это может помешать дальнейшему процессу автозагрузчика.

И присваиваем файлу бит «executable»

chmod +x /etc/init.d/vncserver

Запускаем наш созданный сервис

/etc/init.d/vncserver start

Теперь уже, так как будет стартовать рабочий стол определенного пользователя (а не root), система попросит нас ввести пароль для этой сессии. Этот НЕ ВАШ пароль профиля, а новый пароль, который VNC будет у вас запрашивать при попытку подключения к нему с помощью VNC клиента.

root@toopropc:~# /etc/init.d/vncserver start
* Starting vncserver for user 'toopro' on localhost:1...
You will require a password to access your desktops.
Password:
Verify:
Would you like to enter a view-only password (y/n)? n
xauth: creating new authority file /home/toopro/.Xauthority
New 'TooProOffice1' desktop is toopropc:1
Creating default startup script /home/toopro/.vnc/xstartup
Starting applications specified in /home/toopro/.vnc/xstartup
Log file is /home/toopro/.vnc/Atom:1.log

Как видите, создаются файлы запуска xstartup в папке вашего пользователя и введенный пароль ложится в файл .Xauthority. С xstartup нам еще придется поработать.

Теперь прописываем скрипт в автозагрузку

update-rc.d vncserver defaults

Система покажет несколько предупреждений, это связано с тем, что «runlevels» которые мы прописали в стартап-скрипте (старт S, стоп 0,6) не соответствуют ранлевелам по умолчанию.

На этом этапе можно перегрузить компьютер и снова попробовать подключиться к VNC серверу - увидеть свой рабочий стол со значками и иконками нужного вам пользователя. Но в случаем с Ubuntu 12.04 - это оказалось не так просто. Все что я увидел - мои обои рабочего стола - без меню, без тулбара и каких либо инструментов Unity. Будем решать эту проблемку :)

Решение проблемы: Ubuntu VNC нет меню, тулбара, только обои

Открываем тот самый недавно созданный xstartup файл из вашей домашней папки

gedit /home/USERNAME/.vnc/xstartup

Заменяем содержимое файла на такое:

#!/bin/sh

# VNC Server (Virtual-Mode) start-up script compatible with Ubuntu 12.04

[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey

vncconfig -iconic &

if [ -f /usr/bin/gnome-session ]; then
  # Some gnome session types won't work with Xvnc, try to pick a sensible 
  # default.
  for SESSION in "ubuntu-2d" "2d-gnome"; do
    if [ -f /usr/share/gnome-session/sessions/$SESSION.session ]; then
      DESKTOP_SESSION=$SESSION; export DESKTOP_SESSION
      GDMSESSION=$SESSION; export GDMSESSION
      STARTUP="/usr/bin/gnome-session --session=$SESSION"; export STARTUP
    fi
  done
fi

if   [ -x /etc/X11/Xsession ]; then /etc/X11/Xsession
elif [ -x /etc/X11/xdm/Xsession ]; then /etc/X11/xdm/Xsession
elif [ -x /etc/X11/xinit/Xsession ]; then /etc/X11/xinit/Xsession
elif [ -x /etc/gdm/Xsession ]; then /etc/gdm/Xsession gnome-session
elif [ -x /etc/kde/kdm/Xsession ]; then /etc/kde/kdm/Xsession
elif [ -x /usr/dt/bin/Xsession ]; then
  XSTATION=1 DTXSERVERLOCATION=local /usr/dt/bin/Xsession
elif [ -x /usr/dt/bin/dtsession ]; then /usr/dt/bin/dtsession
else
  if which twm > /dev/null 2>&1; then
    xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
    twm
  else
    xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop"
  fi
fi

vncserver -kill $DISPLAY

Если что-то пойдет не так, попробуйте проверить разрешение executable на ваш файл.
При желании, вы можете скопировать этот файл в /etc/vnc/xstartup.custom и сделать его executable, чтобы применить этот fix для всех запусков vncserver'а.

Внимание! По локальной сети VNC пароль по умолчанию передается в небезопасном виде, равно как и вводимые с клавиатуры данные. Поэтому не стоит использовать этот способ для администрирования в больших сетях или если у вас есть внешний IP на этот компьютер. Для защиты данных лучше воспользоваться SSH-туннелем.

Решение проблемы разрывов SSH туннелей

Сеть не идеальна, тем более, в моем случае подключение часто происходит с помощью wifi посредственного качества. Пакеты теряются, благодаря KeepAlive система это видит и разрывает неработающий канал. При этом его надо вновь поднимать. Есть два способа сделать это.

1. Пытаться переподключаться кроном
$ crontab -e

создаем расписание следующего вида:

TUNCMD1='ssh -f -N -R 5581:localhost:80 root@SSH_SERVER_IP_ADDRESS $'
TUNCMD2='ssh -f -N -R 5581:localhost:80 root@SSH_SERVER_IP_ADDRESS $'

*/5 * * * * pgrep -f "$TUNCMD1" &>/dev/null || $TUNCMD1
*/5 * * * * pgrep -f "$TUNCMD2" &>/dev/null || $TUNCMD2

Сохраняем и проверяем, что расписание принято

$ crontab -l
2. Использовать autossh вместо обычной команды ssh

Тогда строку из файла /etc/init.d/vncserver

su ${USER} -c "ssh -f -N -R 5555:localhost:5901 root@SSH_SERVER_IP_ADDRESS $"

вырезаем, видоизменяем и вставляем в файл /etc/init/autossh.conf

description "autossh tunnel"
author "TooPro.org"
	
start on (local-filesystems and net-device-up IFACE=eth0 and net-device-up IFACE=eth1) #eth1 - use if you have multiple interfes
stop on runlevel [016]
	
respawn
respawn limit 5 60

su toopro -c "autossh -M 0 -f -N -R 5555:localhost:5901 root@SSH_SERVER_IP_ADDRESS $"
#exec autossh -M 0 -f -N -R 10000:192.168.1.1:22 -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -o "StrictHostKeyChecking=no" -o "BatchMode=yes" -i /home/user/.ssh/id_rsa username@hostname
  • -M 0 говорит autossh не устанавливать свой мониторинг работоспособности туннеля (с помощью loopback порта), а полагаться на то, что ssh сам определит разрыв и завершит работу (для этого мы в самом начале прописали в файле sshd.config опции KeepAlive и параметры ServerAliveInterval - интервал отправки keepalive проверок и ServerAliveCountMax - кол-во потерь при которых ssh считается разорванным).
  • -N значит, что никаких команд на ssh сервере к которому мы подключаемся выполняться не планируем, просто поднимаем туннель.
  • -f спрятать ssh в фон

Решение проблемы: Ubuntu не выключается

Больше половины подобных проблем в гугле имеют одну причину - залогинено несколько пользователей. И когда один из них пытается выключить комп, то Unity считает, что без спроса другого этого сделать нельзя и молча ждет :) Поэтому, если у вас не выключается Убунту - убедитесь, что все сеансы/десктопы закрыты.

В нашем же случае - доп сеансов не видно, но он есть - это нас VNC сервер с виртуальным десктопом. Т.к. он запущен под администратором, то обычный пользователь выключить его не может, а Unity считает что это полноценный рабочий стол, который открыт кем-то, где могут быть открыты окна с данными, которые еще не сохранены, поэтому выключать комп нельзя. Признайтесь, так ведь может быть на самом деле :) Но если мы хотим, чтобы наши пользователи легко без обращений к консоли выключали свои ПК, потанцевать с бубном придется нам.

Алгоритм решения: 1. разрешаем бесправному юзеру команду shutdown; 2. перехватываем событие хард кнопки power на системнике/ноуте и запускаем консольную команду выключения компа.

Разрешаем команду sudo без пароля

Чтобы не обременять пользователя, разрешим ему выполнять команду shutdown, от лица Super User и без запрашивания пароля. В Ubuntu 12.04 для этого добавим строку в файлы sudoers

pico /etc/sudoers.d/user_name

В нашем случае, имя пользователя которому нужно дать права - user_name. Для него создается отдельный файл (если еще не создан) в директории которая инклудится к файлу sudoers. Тут вы описываете все правила относительно пользователя user_name. Пропишем такую строку:

user_name ALL=(ALL) NOPASSWD: /sbin/poweroff, /sbin/reboot, /sbin/shutdown

Сохраняем файл и возвращаемся в консоль. Если такого файла там еще не было, то он был создан с неподходящими нам привилегиями, поменяем их командой:

chmod 0440 /etc/sudoers.d/user_name

Более простой, но неправильный способ
Можно использовать команду, которая заставит файл исполняться под пользователем владельцем (то есть root в нашем случае).

sudo chmod u+s /sbin/shutdown

Тогда вызов команды shutdown кем бы то ни было приведет к нужным результатам.

Готово. Но заставить рядового пользователя открывать консоль и прописывать команды - не дело. Повесим команду на хард кнопку компьютера.

Команда терминала при нажатии хард кнопки системника (power)

С этим в Ubuntu уже работает программка acpid. Отловим ивент и пропишем свой обработчик.

pico /etc/acpi/events/power-button

В файле ивента пропишем

event=button/power
action=/etc/acpi/actions/power-button.sh %e

Теперь создаем файл обработчика команды

mkdir /etc/acpi/actions
pico /etc/acpi/actions/power-button.sh

Со следующим содержанием:

#!/bin/sh
case "$3" in
    *)  shutdown -h now
         logger "ACPI TooPro force shutdown button" ;;
esac

(PWRF - код кнопки выключения, может меняться, чтобы узнать ваш код, пропишите в консоли acpi_listen и нажмите нужную кнопку)

Разрешим запускать файл как программу

chmod +x /etc/acpi/actions/power-button.sh

SSH туннель на сервере с внешним IP

Для SSH-сервера воспользуемся прошивкой DD-WRT. Если вы хотите создать что-то подобное, то наверняка у вас есть роутер, да он вообще сейчас у многих дома стоит, чтобы не драться за компьютер с интернетом) И что самое приятное, на все популярные модели роутеров есть прошивка dd-wrt.

Прошиваем dd-wrt

Это самый простой пункт в статье. На странице http://www.dd-wrt.com/site/support/router-database вводите название своего роутера, выбираете нужный и скачиваете прошивку. Если вам повезло (как мне), и у вас в Вэб интерфейсе настройки роутера есть вкладка перепрошивки, то остальное - дело 5 минут, причем 4:30 из них вы будете плевать в потолок в ожидании появления сети :)
Напомню, что у dd-wrt адрес 192.168.1.1, а не привычный 192.168.0.1.

Проблема! На данный момент именно для моего роутера TP-LINK TL-WDR3600 оказалось, что билд (build 21061), предложенный router-database имеет проблемы именно с SSH доступом (SSHd problem) %) У кого другие роутеры можете пропустить этот абзац или вернуться к нему если "ssh -vv 192.168.1.1" выдает процесс подключения, а в конце все же пишет "Connection closed by...". Если вы еще читаете, значит вам также "повезло" как мне, но вы не потратите на это пол дня :) Все что надо сделать - зайти на ftp и скачать свежую прошивку ftp://ftp.dd-wrt.com/others/eko/BrainSlayer-V24-preSP2/ (выберите текущий год, свежий билд и свой роутер), скачайте новую прошивку, перепрошейтесь.

Настраиваем SSH-туннель на DD-WRT

В разделе "Administration" включаем "SSH Management"
В разделе "Services" в группе "Secure Shell" включаем SSHd, SSH TCP Forwarding. И ОТКЛЮЧАЕМ Password Login.
Для безопасности будем пользоваться Public key authentication (методом аутентификации с использованием ключей).

Генерируем, прописываем ключи

В Ubuntu консоли пишем ssh-keygen, при запросе имени файла введите id_rsa. В Windows генерировать лючи можно с помощью puttygen.exe из пакета PuTTy, но об этом можно легко найти информацию в сети. И это не наш случай)

user@machine:~> ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
68:1c:50:0e:76:c1:d0:c7:9e:5e:5a:65:78:20:5c:fb user@machine.example.com

Но в моем случае ключи легли в папку юзера, а не в .ssh, поэтому пришлось перенести их туда.
Ключи были сгенерированы, но надо сказать системе, чтобы она начала их использовать:

ssh-add

Если у вас приватный файл ~/.ssh/id_rsa (/home/username/.ssh/id_rsa), то система его найдет и подтянет.

Теперь надо сказать роутеру свой публичный ключ (id_rsa.pub), берите содержимое этого файла (или скопируйте ответ на команду ssh-add -L) и вставьте в поле Authorized Keys в GUI роутера, раздел Services. Это будет строка вида

ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAl1a3I7wWok2i3yMJPlCFBD8TLJrU3v33r9bOMWeFGdCj/QyqBlHExVEMHxgTtT28lscRNJLm8oVFwvOxk3oT575hdKGjW3TP3BahvLGQGWW8tLjV72xC4YWti+RdpLyP9vPhKupO4mjFyEKMAKOYQ3aIcRHOYCi56eysnS9U6gwplEKSVzMOvG0oLyHv7W9OyBmp6DrT6oRtn8ETbtNlbZ43hSXqzdxT34HcQu2JPdc1eQwdBq8oc0yrfwD+VmxYgo/oD2YyNRGxy0AgW55kkvTQNNqDqDPdQTirbvSYXZ/okgE10qltPlflIXv8NfhWUrxQv7Q== 

Сохраните изменения и перегрузите роутер.

Проверяем подключение к роутеру по SSH

После того как мы создали ключ и скормили роутеру его публичную часть, можно проверить подключение. В консоли Ubuntu из локальной сети пишем:

ssh root@192.168.1.1

Вы должны увидеть ответь роутера DD-WRT и bash строку вида

root@Router Name:~#

Поздравляю! Вы подключились к вашему роутеру по ssh и можете делать с ним все что захотите (если знаете команды :)).

Настраиваем обратный SSH-туннель

Про прямые туннели говорить особо нечего: вы делаете запрос на ssh-сервер и подключаетесь к нему, как вы это уже сделали, подключившись к своему роутеру. Но что делать, если у вас нет адреса сервера к которому надо подключиться, что если к нему вообще нельзя подключаться извне? Надо чтобы он создал подключение "наружу", и вы будете работать с этим подключением.

Для создания SSH-туннеля на ПКОфис

ssh -R 5555:localhost:5901 root@RouterExternalIP

где RouterExternalIP - IP адрес вашего SSH-сервера (по совместительству - роутера), а 5901 - стандартный порт vncserver'а, который используется для дисплея #1. Для проверки проброса портов на роутере можно выполнить команду

netstat -ntlp | grep LISTEN

Используем созданный туннель с другого ПК

У нас есть порт 5555 на роутере, который перебрасывает запросы на порт ПКОфис:5901, где бы он не находился. Теперь надо осталось подключиться к роутеру и пробросить его порт 5555 на удобный для нас.

Для легкости это можно делать и с обычного Windows компьютера, используя PuTTY. Настроив профиль следующим образом:
Host Name : RouterExternalIP
Prot: 22 (не забудьте поменять, если вы указывали другой порт в настройках роутера)
SSH-Auth-Private key file for authentication: ...путь к вашему файлу с Private Key, созданному ранее...
SSH-Tunnels: Source port 1: 5901 (для наглядности будем использовать привычный порт, на него будут транслироваться данные с router:5555)
SSH-Tunnels: Destination: localhost:5555 (адрес с которого надо взять данные для трансляции на порт 5901, в данном случае destination localhost для роутера будет он сам и его порт 5555 будет транслироваться на local source)
SSH-Tunnels: LOCAL, Auto (должно быть выбрано в радиобоксах под полем Destination)
Жмем Add и в списке Forwartded ports мы должны увидеть это:
L5901 localhost:5555

Далее жмем Open, для открытия SSH сессии. После подключения мы можем воспользоваться VNC клиентом для подключения к компьютеру ПКОфис. При этом запрос идет на локальный порт 5901, который переправляется на порт 5555 нашего роутера, который переправляет этот запрос на порт 5901 уже самого ПКОфис.

Итого для подключения из любой точки нам достаточно иметь флэшку с portable VNC клиентом, PuTTy и ключами доступа (private key). На будущее, если вы носите это все на флешке, я бы советовал поставить пароль на Private Key. Даже если вы её оставите в интернет клубе, "кулхацкеры" не смогут подключиться к вашим компьютерам.

Обращение к Apache (http) серверу, запущенному на ПКОфис

В дополнение лишние пару строчек могут помочь параллельно обращаться к http серверу, расположенному на офисном ПК за NAT. В моем случае, это актуально, т.к. Too Pro Shop (скрипт учета продаж) работает на базе CMS Drupal, и чтобы внести изменения в систему (цены, наличие, акции и т.п.) мне зачастую достаточно http доступа.

Для этого на ПКОфис (где установлен сервер) пробрасываем порт 80 на локальный порт ssh-сервера 2080

ssh -R 2080:localhost:80 root@RouterExternalIP

А при подключении через PuTTy к этому же ssh-серверу, добавляем еще одно правило в port forwarding

L2080     localhost:2080

На свой порт 80 перебрасывать не будем, чтобы не лишиться своего интернета :)
Теперь перейдя в браузере по адресу localhost:2080 вы попадаете на сервер localhost ПКОфис. Правда если вам нужно попасть на определенный сайт Apache сервера - придется прописывать hosts у себя в винде.

SSH туннель на VPS виртуальном сервере

Второй вариант, для тех, кто по богаче или каким то иным образом имеет доступ к VPS серверу. Устанавливаем на нем OpenSSH (хотя, вероятно, он уже там стоит).

Пользователь для ssh

Создаем нового пользователя, который не сможет выполнять команд, он нужен лишь для создания туннелей. И даем ему пароль.

useradd -M -s /bin/false limitedssh
passwd limitedssh

В sshd_config (/etc/ssh/sshd_config) разрешим открывать порты на всех сетевых интерфейсах, добавив опцию GatewayPorts. Без неё туннель откроется на адресе 127.0.0.1 (со стороны сервера) и без дополнительных шаманств его использовать удаленно не получится.

GatewayPorts=yes

Перезапускаем ssh

service ssh restart

Разрешения фаервола

#разрешение уже установленных соединений
iptables -A OUTPUT   -m state --state RELATED,ESTABLISHED -j ACCEPT
#запрещение всех остальных пользователю limitedssh
itpables -A OUTPUT  -m owner --uid-owner `id -u limitedssh` -j REJECT
# разрешение соединений в диапазон 5520-5599
itpables -I INPUT -p tcp --dport 5520:5599 -j ACCEPT
#Остальные настройки (политика по-умолчанию, разрешение SSH, HTTP -трафика, для при):
i#tpables  -P INPUT    DROP
#itpables -A INPUT -p tcp —dport 22 -j ACCEPT
#itpables -A INPUT -p tcp —dport 80 -j ACCEPT

Заключение

Хочется отметить, что использование роутера для ssh-тунелей может быть небезопасным, ведь приходится хранить приватный ключ на удаленных клиентах (ПКОфис'ы), и хотя доступ к файлу остается только во власти Администратора этих компьютеров все же не хочется разбрасываться Private Keys. Если организовывать все это через полноценный сервер, то можно сделать отдельного пользователя с возможностью поднимать только реверсивные ssh-туннели (которые были обращены к серверу), и не более. Тогда ssh доступ к этому бесправному акаунту будет бесполезен, но вам придется держать включенным лишний компьютер. Для владельцев нескольких сайтов перспектива более радужная, возможно, ваши сайты давно просят VPS и на нем вы также сможете развернуть свои службы. Подробнее о подобном способе тут: http://habrahabr.ru/post/137723/ (бесплатный аналог тимвьювера).

Благодарности, ссылки

Спасибо Андрею Каплуненко за шикарную статью http://kaplunenko.name/ubuntu-10-remote-desktop/ , часть которой использована тут. Алексею Жбанову за перевод статьи Jayson Broughton'а (http://rus-linux.net/MyLDP/sec/SSH-Tunneling.html). Еще хорошая статья для понимания ssh port forwarding http://avz.org.ua/wp/2010/06/29/putty-how-to-make-your-windows-useful/

P.S. Писал эту "солянку" из других статей сети больше не для людей, а для себя :) Т.к. постоянно забываю грабли на которые натыкался. А, вероятно, придется выполнять эти действия периодически. Да и в сети одной статьи для выполнения текущей задачи не было, поэтому пришлось компилировать.