↓ Перейти к основному содержимому

Первичная настройка сервера Debian

·823 слов·4 минут
Alexander Sokolov aka s0k0l
Автор
Alexander Sokolov aka s0k0l
Имитирую поведение пользователей, добываю данные и защищаю информацию. Довожу проекты от идеи до релиза.

Обычно, после покупки сервера на почту приходит письмо с IP-адресом и паролем пользователя root. Этого хватает чтобы подключиться к серверу по ssh и начать его настраивать.

Всего 3 шага:

  1. Обновление системы
  2. Настройка ssh
  3. Настройка 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, что означает “разрешать подключения, которые уже установлены”. Т.е. по идее разрыва не должно быть.