Дата поста: 21-01-2018
Итак, перед нами стоит задача – обеспечить доступ к своему серверу по SSH через окно браузера. Почему именно так? Да просто потому, что такой подход – самый универсальный. Существует огромное количество сетей, в которых закрыты все порты, которые администратор (или его начальство) посчитал нужным закрыть, в том числе и 22 – стандартный порт для протокола SSH. Но порты 80 (HTTP) и 443 (HTTPS) практически всегда открыты. По крайней мере, радикалов, перекрывающих и эти порты я пока не встречал – зачем тогда вообще предоставлять доступ в Интернет?
HTTP я настоятельно не рекомендую использовать, поскольку весь трафик (в том числе имя пользователя и пароль) в этом случае передаются в незашифрованном виде и доступны почти любому желающему. Хотя и такой доступ можно настроить, этот вариант не будем даже рассматривать. А жаждущие экстрима пусть лучше оставляют ключи от квартиры на гвоздике возле двери. Так, по крайней мере, для окружающих вреда меньше :).
С преамбулой заканчиваем, переходим к делу. Что нам понадобится для осуществления задуманного? Во-первых, сам сервер, без него никак. В этой заметке неявно подразумевается что на сервере установлен GNU/Linux. Во-вторых, необходимо, чтобы на нём был установлен SSH-сервер. В подавляющем большинстве дистрибутивов установлен по умолчанию. Ну и наконец, я представляю нашего сегодняшнего героя – замечательную программу shellinabox. Вообще говоря, есть ещё несколько программ с подобными возможностями (о них я упомяну позже), но shellinabox мне лично нравится намного больше, так как работает заметно быстрее аналогов и поддерживает UTF-8, что лично для меня важно. shellinabox абсолютно бесплатна в использовании и распространяется под лицензией GNU GPL v2.
Соберём данный проект из исходников:
-
Установим зависимости (для deb-систем)
apt-get install git libssl-dev libpam0g-dev zlib1g-dev dh-autoreconf
или для redhat систем
yum install git openssl-devel pam-devel zlib-devel autoconf automake libtool
-
Клонируем исходники и переходим в директорию проекта
git clone https://github.com/shellinabox/shellinabox.git && cd shellinabox
-
Запускаем autotools в директории проекта
autoreconf -i
-
Запускаем configure и make в директории проекта
./configure && make
Debian пакет
Для сборки и установки .deb
пакетов вы можете использовать команды указанные ниже. Все зависимости указанные выше так же необходимы и в этом шаге.
-
Собираем пакет
dpkg-buildpackage -b
-
И Теперь установим его
dpkg -i ../shellinabox_{ver}_{arch}.deb
Проследите, чтобы shellinabox собрался с поддержкой ssl – пригодится ;). Более подробно про инсталляцию из исходных кодов можно посмотреть здесь (файл INSTALL из архива с исходниками). Хочу также заметить, что команда make uninstall
отрабатывает корректно. Если у вас на сервере установлена FreeBSD, то shellinabox есть в портах (/usr/ports/www/shellinabox).
Если вы установили shellinabox из deb-пакета, то, скорее всего, сразу после установки он сразу запустился, а в /etc/init.d уже лежит скрипт приблизительно вот с таким содержимым:
# Set some default values
SHELLINABOX_DATADIR="${SHELLINABOX_DATADIR:-/var/lib/shellinabox}"
SHELLINABOX_PORT="${SHELLINABOX_PORT:-4200}"
SHELLINABOX_USER="${SHELLINABOX_USER:-shellinabox}"
SHELLINABOX_GROUP="${SHELLINABOX_GROUP:-shellinabox}"
#
# Function that starts the daemon/service.
#
d_start() {
if [ -z "$SHELLINABOX_DAEMON_START" -o \
"$SHELLINABOX_DAEMON_START" = "0" ]; then
return 0
fi
eval start-stop-daemon --start --oknodo --pidfile "'$PIDFILE'" \
--exec "'$DAEMON'" -- -q --background="'$PIDFILE'" \
-c "'${SHELLINABOX_DATADIR}'" -p "'${SHELLINABOX_PORT}'" \
-u "'${SHELLINABOX_USER}'" -g "'${SHELLINABOX_GROUP}'" \
$(for i in $(ls /etc/shellinabox/options-enabled/*.css |
sed -e \
's/.*[/]\([0-9]*\)[-_+][^/:,;]*[.]css/\1/'|
sort -u); do
for j in /etc/shellinabox/options-enabled/"$i"*.css; do
echo -n "$j" |
sed -e 's/\(.*[/]\)\([0-9]*\)\([-_+]\)\([^/:,;]*\)[.]css/\4:\3\1\2\3\4.css,/
s/:_/:-/'
done |
sed -e 's/,$/;/'
done |
sed -e 's/;$//
//b
s/.*/--user-css "\0"/') \
"${SHELLINABOX_ARGS}"
}
#
# Function that stops the daemon/service.
#
d_stop() {
start-stop-daemon --stop --oknodo --pidfile "$PIDFILE"
rm -f "$PIDFILE"
}
#
# Function that stops the daemon/service.
#
d_stop() {
start-stop-daemon --stop --oknodo --pidfile "$PIDFILE"
rm -f "$PIDFILE"
}
#
# Function that reloads the config file for the daemon/service.
#
d_reload() {
# Only reload if there are no active sessions running
[ -r "$PIDFILE" ] &&
[ `ps o pid= --ppid "\`cat "$PIDFILE"\`\`ps o pid= --ppid \
\\\`cat "$PIDFILE"\\\`|
xargs -r -n 1 printf ',%s'\`" |
wc -l` -gt 1 ] &&
return 1
d_stop
d_start
}
#
# Function that check the status of the daemon/service.
#
d_status() {
[ -r "$PIDFILE" && kill -0 `cat "$PIDFILE"` ] &&
echo "$DESC is running" || echo "$DESC is not running"
}
case "$1" in
start)
log_daemon_msg "Starting $DESC" "$NAME"
d_start
log_end_msg $?
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME"
d_stop
log_end_msg $?
;;
reload)
log_daemon_msg "Reloading services for $DESC" "$NAME"
d_reload
log_end_msg $?
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
d_stop
d_start
log_end_msg $?
;;
status)
d_status
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|reload}" >&2
exit 1
;;
esac
exit 0
Если после установки процесс shellinaboxd не запущен (проверяем ps -ef | grep shellinaboxd
), то запускаем его /etc/init.d/shellinaboxd start
или даже просто shellinaboxd
. Сразу после этого можно проверить, набрав а адресной строке браузера https://my.server.domain:4200
. Если всё сделано правильно, то вы увидите в окне браузера приглашение ввести имя пользователя. Примерно вот такое:
Если всё так, то нас уже можно поздравить :). Но всё же, это немного не то, чего нам хотелось бы – нам нужно использовать 443 порт, чтобы даже через самый «злобный» прокси-сервер мы могли бы получить доступ к терминалу нашего сервера. И вот тут появляются нюансы.
Вариант первый – в системе нет web-сервера или есть, но он не использует 443 порт. В этом случае в приветённом выше скрипте инициализации (или в том, который вы написали по аналогии с этим) меняем строку SHELLINABOX_PORT="${SHELLINABOX_PORT:-4200}"
на SHELLINABOX_PORT="443"
(либо в файле /etc/defaults/shellinabox заменить SHELLINABOX_PORT=4200
на SHELLINABOX_PORT=4200
) и перезапускаем демон shellinaboxd. Всё! Осталась только настроить опции запуска (в Debian – в файле /etc/defaults/shellinabox. И фаервол для разрешения/запрета подключения с различных адресов.
В том случае, если web-сервер используется, я рекомендую настроить прокси. Например, в случае использования apache это выглядить так:
Подключаем mod_proxy:
a2enmod mod_proxy
a2enmod mod_proxy_http
В конфигурационный файл apache в секцию <VirtualHost *:443>
(или аналогичную) добаляем такие строчки:
<Proxy *>
Order Deny,allow
Allow from all
</Proxy>
ProxyPass /shell/ http://127.0.0.1:4200/
ProxyPassReverse /shell/ http://127.0.0.1:4200/
И перезапускаем apache. При такой настройке shell будет доступен по адресу https://my.server.domain/shell
. Также полезно будет добавить такие опции запуска shellinaboxd, как –localhost-only (чтобы демон слушал только на loopback интерфейсе) и –disable-ssl (если демон работает только на локальном интерфейсе, то ни к чему повышать нагрузку на процессор дополнительным шифрованием, если оно и так выполняется апачем). Рекомендую ещё усилить безопасность, настроив apache таким образом, чтобы он запрашивал имя пользователя и пароль при обращении по этому URL.
Теперь, как я и обещал, отмечу альтернативные web-ssh клиенты.
Из заслуживающих внимания я нашёл всего два.
Это ajaxterm – написанный на python клиент, существенным (для меня) недостатком которого является то, что он не поддерживает юникод и последняя версия 2006 год(!).
И b374k-shell.