Добрый день.
Я решил написать этот пост по нескольким причинам:
1) Иногда легче дать ссылку на статью, чем в сто первый раз рассказывать человеку, что ему необходимо сделать, и где про все это можно почитать.
2) Появилась необходимость привести знания в систему. А лучше всего это делать, если рассказываешь это другому человеку.
3) Чисто корыстный интерес — хочу инвайт.
Итак. Постановка задачи.
Есть рабочее место (W), закрытое роутером. Есть домашний компьютер (H), с которого периодически необходимо получать доступ к рабочему столу W, и который не имеет «белого» IP.
![Schema-1](https://habrastorage.org/getpro/habr/post_images/aad/888/f7b/aad888f7bbb2ae9c6d357eb36e7e8a8e.gif)
Менять что-то в настройках роутера — нельзя. Использовать TeamViewer & Co. — не наш путь.
Варианты решения.
Если отбросить сторонние программы, то вариантов решения остается только 2:
Я покажу реализацию второго варианта.
![Schema-2](https://habrastorage.org/getpro/habr/post_images/2cd/c98/569/2cdc98569426cceb75da631adc1bf199.gif)
Итак, договоримся, что для простоты все машины работают под Linux. Проброс портов будет осуществляться через SSH соединение. Поэтому в качестве промежуточного сервера подойдет даже простенький VDS.
И еще одно замечание — SSHd на VDS-е должен разрешать подключение к проброшенному порту с другого адреса. Это важно! Разрешить это можно, прописав
Схема работы выглядит следующим образом:
1) Машина W проверяет, хочет ли кто-нибудь ко мне подконнектится? (Подробности — ниже)
2) Если нет, то не делаем ничего. Если да, то устанавливаем SSH соединение с VDS сервером.
3) Машина H подключается VNC клиентом к VDS:5900 — и получает доступ к рабочему столу W.
4) Профит!
Отдельный вопрос — что может служить флагом о необходимости соединения?? Я решил этот вопрос просто. О необходимости соединения говорит наличие открытого порта (ну, например, 5995) на VDS. Если порт открыт — значит устанавливаем SSH соединение и пробрасываем порты, если закрыт — значит закрываем ненужный SSH канал до следующего сеанса.
Теперь немного скриптов:
Проверяем хочет ли кто-то доступ к столу?
проверка каждые 15 минут.
Скрипт для проверки открытого порта на python-e
Собственно bash скрипт connect_flag.sh, в котором реализована логика работы
Вот и все. На что хотелось бы обратить внимание:
Спасибо всем, кто дочитал этот пост до конца.
Я решил написать этот пост по нескольким причинам:
1) Иногда легче дать ссылку на статью, чем в сто первый раз рассказывать человеку, что ему необходимо сделать, и где про все это можно почитать.
2) Появилась необходимость привести знания в систему. А лучше всего это делать, если рассказываешь это другому человеку.
3) Чисто корыстный интерес — хочу инвайт.
Итак. Постановка задачи.
Есть рабочее место (W), закрытое роутером. Есть домашний компьютер (H), с которого периодически необходимо получать доступ к рабочему столу W, и который не имеет «белого» IP.
![Schema-1](https://habrastorage.org/getpro/habr/post_images/aad/888/f7b/aad888f7bbb2ae9c6d357eb36e7e8a8e.gif)
Менять что-то в настройках роутера — нельзя. Использовать TeamViewer & Co. — не наш путь.
Варианты решения.
Если отбросить сторонние программы, то вариантов решения остается только 2:
- «протянуть» порт 5900 до белого IP с любой стороны (W или H). Потом просто коннектиться VNC клиентом на этот адрес.
- Использовать промежуточный сервер для организации соединения. Плюсы этого варианта в том, что нет необходимости что-то менять в системе безопасности рабочего и домашнего серверов.
Я покажу реализацию второго варианта.
![Schema-2](https://habrastorage.org/getpro/habr/post_images/2cd/c98/569/2cdc98569426cceb75da631adc1bf199.gif)
Итак, договоримся, что для простоты все машины работают под Linux. Проброс портов будет осуществляться через SSH соединение. Поэтому в качестве промежуточного сервера подойдет даже простенький VDS.
И еще одно замечание — SSHd на VDS-е должен разрешать подключение к проброшенному порту с другого адреса. Это важно! Разрешить это можно, прописав
GatewayPorts yes
в sshd_config. Не забудьте после этого перегрузить сервис $ sudo /etc/init.d/ssh restart
Схема работы выглядит следующим образом:
1) Машина W проверяет, хочет ли кто-нибудь ко мне подконнектится? (Подробности — ниже)
2) Если нет, то не делаем ничего. Если да, то устанавливаем SSH соединение с VDS сервером.
3) Машина H подключается VNC клиентом к VDS:5900 — и получает доступ к рабочему столу W.
4) Профит!
Отдельный вопрос — что может служить флагом о необходимости соединения?? Я решил этот вопрос просто. О необходимости соединения говорит наличие открытого порта (ну, например, 5995) на VDS. Если порт открыт — значит устанавливаем SSH соединение и пробрасываем порты, если закрыт — значит закрываем ненужный SSH канал до следующего сеанса.
Теперь немного скриптов:
Проверяем хочет ли кто-то доступ к столу?
$ crontab -u root -e
*/15 * * * * /usr/bin/connect_flag.sh
проверка каждые 15 минут.
Скрипт для проверки открытого порта на python-e
import socket
import subprocess
def scan(host, port):
while 1:
sd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sd.connect((host, port))
except: return 0
else:
sd.close()
return 1
if __name__ == '__main__':
if scan('yourServer', 5995): print 'start'
else: print 'stop'
Собственно bash скрипт connect_flag.sh, в котором реализована логика работы
#!/bin/bash
export PATH=$PATH:/bin:/usr/bin:/usr/local/bin
PID=`/bin/ps ux | awk '/ssh -N username/ && !/awk/ {print $2}'`
FLAG=`/usr/bin/python /var/Script/portscan.py`
PARAM="-N username@yourVDS -R 5900:127.0.0.1:5900"
if [ $PID ];
then
if [ $FLAG == 'stop' ]; then `kill $PID`; fi
else
if [ $FLAG == 'start' ]; then
/usr/bin/ssh $PARAM &
fi
fi
Вот и все. На что хотелось бы обратить внимание:
- на VDS сервере — разрешаем подключение к проброшенному порту с внешнего адреса.
- на H машине — необходим только VNC клиент. И все.
- на W машине — отрабатываются все скрипты. И их отладка самая трудная часть.
- Открыть порт-флаг можно банальным nc -vv -l 5995 на VDS сервере.
Спасибо всем, кто дочитал этот пост до конца.