Минимальные настройки безопасности в Linux
Начнем немного с теории. Если не поставить нормальный пароль, не защитить порты, или разрешен вход под root - то: 1) Боты сканируют SSH-порты и подбирают простые пароли (admin, 123456, qwerty). И вас могут забрутфорсить китайцы. А там установить рассылку спама, майнеры, фишинг и прочее плохое, за придется отвечать вам. 2) В случае если не стоит файрвол - злоумышленники видят открытые службы (SSH, базы данных, RPC). Могут украсть данные через открытые порты PostgreSQL/MySQL/MongoDB, или использовать RCE-уязвимости для тех служб которые у вас видны без файрвола. Крч это как если бы стены вашего дома были из стекла. И всем вокруг видно что у вас там дома есть. 3) Разрешен вход под root - компрометация пароля root — мгновенный полный контроль. Это достаточно опасно при условии если ваш пароль от рута слабый. В подобном случае взлом за минуты, а может даже и секунды вам обеспечен.
Это еще конечно не все. Есть много других примеров безалаберности. Но это база. Поставим файрвол, закроем вход под рутом, добавим вход только по ssh-ключам
На практике
1. Обновляем программное обеспечение
- ОС и пакеты: Начнем с обновления пакетов.
[!Заметка] Дальнейшие команды выполняется от рута. Поэтому выполняются без sudo. Символы
#
или$
решил не добавлять, так как не вижу в них смысла если многие просто копируют команду из поля.
1
2
apt update -y
apt upgrade -y
- Автоматизация: Можно настроить автоматические обновления безопасности (например,
unattended-upgrades
).
2. Защита SSH-доступа
SSH-доступ к серверу самая необходимая его свойство, по крайней мере, на ранних этапах, когда на нем ничего нет. Поэтому сразу же защищаемся.
- Смените порт по умолчанию (22):
1 2
# В файле /etc/ssh/sshd_config Port 2222
Я иногда предпочитаю оставлять стандартный порт 22, хотя насколько всем известно боты сканируют всё в сети на наличие стандартных связок логин/пароль - root/password на порту 22. Не совсем как страшилка, а как действительность.
[!Заметка] Не ставьте короткий и слабый пароль на рута. Опасно.
- Отключите вход под root:
1
PermitRootLogin no
Чтобы нельзя зайти на сервер сразу из под рута, а только для уже авторизованных пользователей.
- Используйте ключи вместо паролей:
1
PasswordAuthentication no
Эта настройка запрещает подключаться без ssh-ключа.
[!Заметка] Делайте для ssh-ключей pass-code, на случай если ваши ключи могут увести с вашей рабочей машинки.
- Установите Fail2Ban:
1
sudo apt install fail2ban
Это блокирует IP-адреса после множества неудачных попыток входа.
3. Создаем пользователя с правами админа
Создание пользователя правильная практика. Просто потому что мы не должны заходить под рутом, а также потому что руту разрешено по умолчанию все.
В нашем случае мы настраиваем Ubuntu 24.04 поэтому будем использовать adduser
(интерактивно):
1
adduser имя_пользователя
adduser
после выполнения команды попросит:
- Пароль
- Полное имя
- Номер комнаты
- Телефоны (рабочий и домашний)
- Другую информацию
К тому же:
- Автоматически создаст домашнюю директорию
- Установит стандартную оболочку (обычно
/bin/bash
) - Создаст одноименную группу
Для сервисных пользователей (от которых допустим будет работать какой-нибудь ваш самописный сервис) вы можете создать с помощью useradd
:
1
useradd -m -s /bin/bash имя_пользователя
Здесь useradd
:
-m
: создает домашнюю директорию (/home/имя_пользователя
)-s
: задает оболочку (указывайте/sbin/nologin
для сервисных пользователей)
4. Ограничьте доступ
- Принцип минимальных привилегий:
- Пользователи должны иметь доступ только к необходимым ресурсам.
- Используйте
sudo
вместо полного root-доступа.
- Сегментируйте сеть:
- Отделите публичные сервисы (веб-сервер) от внутренних (базы данных). Также подобное можно и реализовать на уровне сетей Docker.
- Используейте прокси - Traefik / Envoy / Niginx Proxy Manager. И проксируйте запросы всех внутренних сервисов.
5. Настройте файрвол
[!Важно] Если неправильно настроите себе файрвол можете закрыть свое текущее подключение к серверу и возможность повторно подключиться.
Для файрвола лучше использовать iptables
. Можно и конечно использовать ufw
, который проще в настройке (хотя я считаю не сильно), у есть минус - он не работает нативно с Docker’ом.
[!Внимание] Следующую команду, если выполняете, выполняйте её как единую, не надо дробить на отдельные.
Команда для настройки Iptables:
1
2
3
4
5
6
7
8
9
iptables -F && iptables -X \
&& iptables -P INPUT DROP \
&& iptables -P FORWARD DROP \
&& iptables -P OUTPUT ACCEPT \
&& iptables -A INPUT -i lo -j ACCEPT \
&& iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT \
&& iptables -A INPUT -p tcp --dport 22 -j ACCEPT \
&& iptables -A INPUT -p tcp --dport 80 -j ACCEPT \
&& iptables -A INPUT -p tcp --dport 443 -j ACCEPT
Сначала сбрасываем все правила (iptables -F && iptables -X
). Потом все входящие (INPUT
) подключения блокируем. Потом все переадресуемые (INPUT
) подключения блокируем. Исходящее (OUTPUT
) разрешаем. Далее разрешаем localhost(INPUT -i lo
). Разрешаем входящие пакеты для УЖЕ установленных соединений (INPUT -m conntrack --ctstate ESTABLISHED,RELATED
), чтобы сервер мог отвечать. И последние три: 1) Разрешаем порт 22 на котором обычно работает ssh (INPUT -p tcp --dport 22
) 2) Разрешаем порт 80 на котором работает HTTP (INPUT -p tcp --dport 80
) 3) Разрешаем порт 443 на котором работает HTTPS (INPUT -p tcp --dport 443
)
[!Заметка] Иногда нужно открыть какие-нибудь другие порты. Допустим стандартный порт для сервера Minecraft Java Edition -
25565
. Это не считая дополнительных серверов и прокси. Здесь же - минимум портов подходящие для большинства интернет-ресурсов -22
,80
,443
.
Далее проверим получилось ли настроить iptables
1
iptables -L -n -v
Если вывод похож на этот - то это то что файрфол настроен корректно
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
Все же если решили использовать UFW вот команды для настройки.
- Разрешайте только необходимые порты:
1 2 3 4 5 6 7 8 9
ufw --force reset && \ ufw default deny incoming && \ ufw default allow outgoing && \ ufw allow in on lo && \ ufw allow out on lo && \ ufw allow 22/tcp && \ ufw allow http && \ ufw allow https && \ ufw --force enable
Далее перезапускаем сервис ufw:
1
2
sudo systemctl restart sshd
sudo ufw disable && sudo ufw enable
Так как я из России и, пока, не делаю больших сервисов, мы обойдемся только IPv4. Для IPv6 есть аналогичная ip6tables
. Мб когда-нибудь напишу эту часть.
Заключение
В целом это все что нужно было настроить. Этого явно мало, но для старта вполне хватает. Позже попробую обернуть подобные настройки в bash-скрипт. Спасибо за уделенное время. Пост пишу для себя в основном как заметку.