Давайте проведем, так сказать, мысленный эксперимент. Представьте, что вы работаете в месте, где с рабочего компьютера очень сложно попасть во вне - вы ограничены только стандартными портами для HTTP, NTLM-аутентификацией и другими штуками, которые делают ваше пребывание в Сети не очень комфортным. Тем не менее, вам кровь из носу нужно достучаться по SSH до домашней (любой другой) машины. В этой заметке я постараюсь рассказать о том, как можно миновать вышеперечисленные ограничения.
Описанный ниже способ не претендует на единственность и оригинальность - это лишь один из вариантов. Например, можно еще поиграться с cntlm и proxytunnel. Но... тут речь пойдет не об этом. Здесь мы попробуем установить на целевую машину Anyterm и сделать его доступным по HTTPS с базовой аутентификацией.
Итак, мне нужно было достучаться до моего домашнего сервачка, на котором установлена Ubuntu 11.04, Apache 2 и остальной зоопарк разного ненужного, а сам он находится за NAT ADSL-роутера. Для того, чтобы он все время был доступен по одному адресу, я зарегистрировал домен третьего уровня на http://dlinkddns.com/.
Для начала Anyterm нужно скачать (http://anyterm.org/download/index.html). Я забирал последнюю dev-версию (1.1.29), так что все описанное справедливо именно для нее. Скачиваем, выполняя, например, такую команду:
svn co http://svn.anyterm.org/anyterm/tags/releases/1.1/1.1.29/ anyterm-1.1.29
Результатом ее выполнения будет папка anyterm-1.1.29, созданная в директории, откуда эта команда исполнялась. Т.к. были скачаны исходные кода, а сама программа написана на C++ с использованием библиотек Boost, то нужно убедиться, что у вас установлено все необходимое для успешного компилирования исходников, а именно: пакеты build-essential, libboost1.42-dev и zlib1g-dev. Все скопом можно установить, выполнив следующую команду:
sudo apt-get install build-essential libboost1.42-dev zlib1g-dev
Теперь, вроде, можно компилировать. Переходим в ранее созданную директорию anyterm-1.1.29 и, скрестя пальцы, выполняем команду:
make
К сожалению, скрещенные пальцы тут не помогут, т.к. процесс компиляции завершится неудачно - все дело в том, что в файле anyterm-1.1.29/libpbe/src/SmtpClient.cc отсутствует строка, которая подключает стандартную библиотеку языка. Её нужно добавить куда-нибудь в начало файла:
#include //Missed string
После добавления этой пропущенной строки, необходимо выполнить команды:
make clean; make
Дожидаемся окончания процесса компиляции - на выходе получим исполняемый файл anytermd, который было бы полезно скопировать в какую-нибудь директорию типа /usr/local/bin (мой именно там и лежит).
Попробуем провести тестовый запуск свежескомпилированного демона командой:
anytermd -p 7777 --local-only
Запускаем браузер и переходим по адресу http://localhost:7777. Если вы увидели окошко терминала, то все ок и можно продолжать. Теперь необходимо сделать этот терминал доступным извне.
Для этого, как я уже писал выше, понадобится установленный веб-сервер Apache 2 с включенными модулями mod_proxy, mod_proxy_http, mod_ssl и mod_auth_basic. Включить их можно такой командой:
sudo a2enmod proxy proxy_http ssl auth_basic
Модули включили, теперь нужно создать самодписной SLL-сертификат и файл с данными для basic-аутентификации.
Этапы создания сертификата следующие: создание ключа, создание CSR (запроса на сертификат, в котором содержаться некоторые данные о сервере), подписание сертификата. Создаем какую-нибудь директорию для этого добра, переходим в нее и начинаем последовательно выполнять команды:
sudo openssl genrsa -des3 -out server.key 1024 #В конце два раза вводим парольную фразу
sudo openssl req -new -key server.key -out server.csr #Можно просто вводить пустые ответы
sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Теперь необходимо перенести созданное в правильные папки:
sudo cp server.crt /etc/ssl/certs
sudo cp server.key /etc/ssl/private
Далее, создадим файл с данными для basic-аутентификации. Для этого выполним команду:
htpasswd -mbc /var/www/anyterm/.htpasswd username PassWord #где username - имя пользователя, а PassWord - его пароль
Обратите внимание, что файл .htpasswd создастся в директории /var/www/anyterm, которая должна существовать. Предпоследний шаг - настроить веб-сервер так, чтобы он принимал соединения на 443 порт по HTTPS и перенаправлял их демону Anyterm. Для этого в директории /etc/apache2/sites-available (предварительно веб-сервер должен уметь работать с виртуальными хостами и прослушивать 443 порт) создадим файл anyterm, выполнив команду:
sudo touch /etc/apache2/sites-available/anyterm
Теперь, добавим в свеженький файл строки конфигурации примерно такого содержания:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName server
<Location /anyterm>
Allow from all
ProxyPass http://localhost:8022 ttl=60
ProxyPassReverse http://localhost:8022
AuthType Basic
AuthName "Anyterm"
AuthUserFile /var/www/anyterm/.htpasswd
Require valid-user
</Location>
SSLEngine on
SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
</VirtualHost>
</IfModule>
Ффух... осталось соовсем немного, потерпите. Дадим веб-серверу знать, что мы добавили новый хост и сделаем ему рестарт:
sodu a2ensite anyterm
sudo /etc/init.d/apache2 restart
Обратите внимание, что сервер попросит вас ввести парольную фразу для ssl-ключа. Теперь остается последний шаг - правильный запуск демона Anyterm. Помните, что мы выполняли тестовый запуск на 7777 порту? Так вот, надо бы остановить его выполнение. Самый простой способ - это посмотреть идентификатор процесса при помощи:
ps ax | grep anyterm
И его дальнейшее убийство командой kill:
kill идентификатор_процесса_anyterm
Запустим демона заново:
anyterm -p 8022 --user username #где username - имя пользователя, из-под которого будет вестись работа в терминале
Теперь, сидя на работе, вы спокойно можете постучаться на домашнюю машину. Для этого достаточно в адресной строке браузера вбить https://ваш_ip-адрес/anyterm (или https://ваш_домен.служба_динамических_dns:проброшеный_порт, если у вас ADSL без статичного IP и сервер находится за NAT) - и вы увидите родной терминал. :)
Вот, вроде, и все. Кончено, я мог что-то упустить, но вы можете задавать вопросы, которые могут появиться по ходу выполнения описанного процесса, и мы вместе восстановим справедливость и найдем истину.