Обычно, после покупки сервера на почту приходит письмо с IP-адресом и паролем пользователя root. Этого хватает чтобы подключиться к серверу по ssh и начать его настраивать.
Всего 3 шага:
- Обновление системы
- Настройка ssh
- Настройка nftables
Нулевой шаг - подготовить ключи ssh и конфиг для сервера. Чтобы выпустить ключи выполнить:
s0k0l:~$ ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/~/.ssh/id_ed25519):Предлагается указать путь для ключа. Можно просто ввести желаемое имя ключа и пара будет создана в директории откуда запустили команду. Первый раз можно пропустить и нажать Enter.
Второй вопрос про пароль на доступ к ключу. Для ssh ключей от продакшен инфраструктуры лучше поставить. Если нет желания, то щелкаем Enter.
После того как хостер поднимет сервер, прокидываем ключ командой
s0k0l:~$ ssh-copy-id root@<ip>
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 3 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@<ip>'s password: Введите пароль и должно появиться сообщение об успехе с предложением выполнить подключение к серверу, что и нужно сделать. Но сначала добавьте в файл ~/.ssh/config новую конфигурацию:
Host <name>
HostName <ip>
Port 22
IdentityFile ~/.ssh/id_ed25519Теперь можно подключаться по имени
ssh <name>На сервере первым делом запускаем обновление:
apt update && apt dist-upgrade -y && rebootЭто выполнит обновление всей системы и отправит систему в перезагрузку. Ждите примерно 5 минут и можно пробовать подключиться назад.
Теперь нужно настроить ssh, чтобы никто больше не мог подключиться к серверу по стандартному порту и использовать пароль для входа. Это самое важное.
Открываем на редактирование файл /etc/ssh/sshd_config и ищем в нем параметры указывающие на адрес прослушивания и порт.
Port 5872
AddressFamily inet
ListenAddress <ip>
#ListenAddress ::Ставим такие настройки, чтобы строго определить каким путем можно подключаться к серверу. У нас на руках ipv4 адрес, так что можно строго указать его в конфиге. А порт нужно поменять на рандомный в диапазоне от 1024 до 65535. Чтобы проверить какие порты не заняты выполните команду:
ss -tlnupЕсли желаемого порта в выводе нет, то он свободен.
Далее ищем в конфиге ssh следующее:
PermitRootLogin prohibit-password
PubkeyAuthentication yes
PasswordAuthentication noЭти настройки отключат авторизацию по паролю на ssh для всех пользователей включая root (PermitRootLogin).
После сохранения конфига нужно перезапустить сервис ssh. Оставайтесь в сессии пока не подключитесь параллельно.
systemctl restart sshОткройте соседний терминал, в конфиге поправьте порт ~/.ssh/config и подключитесь к серверу. Если подключение прошло, то первый терминал можно закрыть. SSH готов.
Последний шаг - настройка nftables. Это стандартный фаервол в Debian, iptables уже не нужен.
Правила живут в одном файле /etc/nftables.conf. Принцип строгого конфига простой: все входящее запрещено, разрешаем только то, что реально нужно. Исходящее оставляем открытым, иначе сломаются обновления и DNS.
Открываем /etc/nftables.conf и заменяем содержимое целиком:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# уже установленные соединения пропускаем, мусор режем
ct state established,related accept
ct state invalid drop
# локальный интерфейс
iif lo accept
# ping, но не больше 5 в секунду
ip protocol icmp icmp type echo-request limit rate 5/second accept
ip protocol icmp accept
meta l4proto ipv6-icmp accept
# ssh на нашем порту, не больше 10 новых подключений в минуту с одного ip
tcp dport 5872 ct state new meter ssh_limit { ip saddr limit rate 10/minute } accept
# раскомментировать, если на сервере будет сайт
# tcp dport { 80, 443 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}Порт 5872 поменяйте на тот, что указали в sshd_config. Это самое важное место в конфиге, ошибка в нем закроет вам доступ к серверу.
Сначала проверяем конфиг на ошибки, ничего не применяя:
nft -c -f /etc/nftables.confЕсли команда ничего не вывела, синтаксис в порядке. Теперь страховка на случай, если все таки закроем себе доступ. Запускаем таймер, который через 2 минуты сбросит все правила:
(sleep 120 && nft flush ruleset) &И применяем конфиг:
nft -f /etc/nftables.confДальше как с ssh, открываем соседний терминал и подключаемся. Если зашли, значит все хорошо, отменяем таймер:
kill %1Если не зашли, просто ждем 2 минуты, правила сбросятся сами и можно спокойно искать ошибку.
Посмотреть что сейчас реально применено можно командой:
nft list rulesetОсталось включить автозагрузку правил, иначе после перезагрузки сервер окажется без фаервола:
systemctl enable --now nftablesЕсли на сервере будет Docker, то учтите, что он пишет свои правила и может открыть порты контейнеров в обход вашего конфига. Это тема для отдельной статьи.
На этом все. Сервер обновлен, ssh пускает только по ключу и на нестандартном порту, а фаервол закрывает все, что мы явно не разрешили. С этого уже можно начинать ставить свои сервисы.
Дисклеймер: прикол с таймером нужен, потому что firewall может оборвать даже уже установленное соединение. В конфиге из пример есть строчка ct state established,related accept, что означает “разрешать подключения, которые уже установлены”. Т.е. по идее разрыва не должно быть.
