Давно хотел написать что-то по этому поводу, но наконец-то накипело.
Если пойти копаться по этим вашим интернетам в поисках "как обезопасить доступ к серверу по SSH", то начинаются сыпться достаточно обычные и, как правило, очевидно-бесполезные советы: поставьте сложный пароль, установите fail2ban, перевесьте SSH на другой порт и далее по списку.
Из более-менее адекватного в таком списке можно воспринимать только совет перевесить демона на другой порт и запрет логина рута. Все остальное по сути своей мусор. Глядя на все это я давно хотел описать, как настроенна безопасность у меня на сервере. Постараюсь из этого создать что-то мануала, по которому можно идти прям по пунктам.
Итак, мы поставили на наш сервер SSH-демона и его настраиваем. Для начала, первым делом, последуем советам из интернета и запретим логин рута. Но на этом мы не остановимся, а полностью отключим парольную авторизацию. Зачем она в конце четверти 21 века - непонятно. Сейчас весь мир начал уходить на беспорольную аутентификацию везде где можно, последуем примеру. Оставим авторизацию только по ключу. Если очень сильно хочется, можно еще и порт поменять.
Следующим шагом я настоятельно рекомендую отключить проброс X-сервера. Скорее всего, сервер у вас без графики и эта опция вот вообще не нужна.
А вот дальше начинается самое интересное. Если у вас есть статический IP - проблем вообще нет, просто через iptables/nftables запрещаем все коннекты к SSH-порту с IP, отличных от ваших.
Если же статического IP нет, то настраиваем DDNS. Сам пользуюсь Cloudflare, полет нормальный. Как его настраивать подробно описывать не буду, благо существует овердофига мануалов в сети. Если вкратце - по вашему домену должен резолвится ваш домашний IP. Можно проверить, выполнив на VPS команду dig +short ВАШ_DDNS_ДОМЕН
. Далее на сервере проверяем наличие ipset
, при необходимости добываем. После чего в crontab
/юнит systemd вешаем следующий скрипт:
#!/bin/bash
# Update ipset to let my dynamic IP in
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set=whitelist
host=ВАШ_DDNS_ДОМЕН
me=$(basename "$0")
ip=$(dig +short $host)
if [ -z "$ip" ]; then
logger -t "$me" "IP for '$host' not found"
exit 1
fi
# make sure the set exists
ipset -exist create $set hash:ip
if ipset -q test $set $ip; then
logger -t "$me" "IP '$ip' already in set '$set'."
else
logger -t "$me" "Adding IP '$ip' to set '$set'."
ipset flush $set
ipset add $set $ip
fi
Суть скрипта - он резолвит домен и создает ipset с соответствующим ipшником. После чего опять-таки через доступный фаервол запрещаем все коннекты, кроме ip из списка.
По сути, на текущий момент сервер обезопашен от всяких Васянов и иже с ними. Понятно, что можно доупарываться еще, можно повесить SSH за Nginx, который будет нужным людям отдавать какую-то заглушку, а кому нужно - пробрасывать SSH, но это все уже зависит исключительно от фантазии.