К новому году я хотел запустить какой-нибудь публично доступный проект - и тогда мне пришла в голову идея написать CLI-приложение и “раздать” доступ к нему по SSH. В этой статье разберемся, как такое сделать без рисков безопасности для сервера
Будьте внимательны! Часть действий в статье может вас лишить доступа к серверу. Действия выполняются на Debian 12

¶ Как это работает?
Для реализации такого процесса, мы будем использовать директиву ForceCommand. Она позволяет установить команду для выполнения вне зависимости от желания подключаемого пользователя. Попутно, обеспечим безопасность сервера при помощи выключения ряда функций SSH-сервера.
Реализация позволяет установить для разных пользователей и групп разные команды.
¶ Устанавливаем SSH сервер
Если у вас есть доступ к консоли сервера, то потребуется в первую очередь вообще установить SSH-сервер.
Для выполнения команды требуется sudo или root-доступ.
&&
¶ Клонируем SSH-сервер
Наверняка, вы захотите оставить себе доступ по SSH. Поэтому, нам придется запустить два SSH-сервера, один из которых мы будем использовать под наше приложение. Найдем, где лежит файл сервиса systemd, отвечающий за SSHD.
Скопируем этот файл чтобы создать свою копию сервера. Копию создадим в директории /etc/systemd/system/sshd-copy.service. Используем флаг --dereference для того, чтобы не создать символьную ссылку на файл.
Для выполнения команды требуется sudo или root-доступ.
# одной командой
Отредактируем полученный файл, потребуется отредактировать строку ExecStart=, где мы явно укажем конфигурационный файл, который нужно будет использовать
Description=OpenBSD
Documentation=man:sshd())
After=network.target
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd
ExecStart=/usr/sbin/sshd
ExecReload=/usr/sbin/sshd
ExecReload=/bin/kill
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755
WantedBy=multi-user.target
Alias=sshd-ny.service
Создадим теперь нужный нам конфигурационный файл.
Для выполнения команды требуется sudo или root-доступ.
Теперь нам нужно определиться на каком порту будет работать каждый из SSH серверов. Для того чтобы поменять порт оригинального сервера, через который вы будете далее подключаться к серверу откройте файл /etc/ssh/sshd_config и отредактируйте строку Port (возможно, потребуется раскомментировать). Откройте порты при помощи фаерволла перед этим действием!. В данной статье, я перенесу оригинальный SSH сервер на 23 порт.
Для выполнения команды требуется sudo или root-доступ.
Конфиг будет выглядеть примерно так:
/etc/ssh/sshd_config.d/*.conf
23
После разрешения конфликтов c портами, можем ввести в работу оба сервера:
Для выполнения команды требуется sudo или root-доступ.
¶ Дополнительные настройки SSH
¶ Ограничиваем пользователей (необязательно)
В первую очередь, стоит ограничить список пользователей, которые смогут зайти. В нашем примере, создадим пользователя demo и разрешим подключение только для него.
Для выполнения команды требуется sudo или root-доступ.
Установите пароль по желанию командой passwd demo или установите пустой командой passwd -d demo.
Для ограничения списка пользователей допишите в /etc/ssh/sshd_config_copy:
demo
Для ограничения по принципу групп пользователей, используйте AllowGroups.
¶ Отключаем вход для root (необязательно)
Для ограничения входа пользователя root через наш сервер найдите строку PermitRootLogin в файле /etc/ssh/sshd_config_copy и приведите к виду
no
¶ Отключаем форвадинг портов и X-приложений
Добавьте в /etc/ssh/sshd_config_copy строку
no
и приведите строку X11Forwarding к виду:
no
¶ Отключаем передачу файлов по SFTP
Закомментируйте в /etc/ssh/sshd_config_copy строку:
sftp /usr/lib/openssh/sftp-server
¶ Разрешаем вход по пустому паролю
Добавьте в /etc/ssh/sshd_config_copy строку:
yes
¶ Устанавливаем запуск приложения
Не забудьте перезагрузить SSH-сервер после смены настроек командой systemctl restart sshd-copy!
Для установки глобальной команды запуска поместите директиву ForceCommand в корень конфигурационного файла. Например, при помощи этой команды можно каждые 5 секунд выводить дату и время
watch -n 5 echo 'Today is $(date)'
Если требуется для отдельного пользователя установить свою команду, то используйте ForceCommand с конструкцией Match
User admin
/bin/sh
Также есть фильтр по группе.
Group monitoring
/usr/bin/top