Когда вы разворачиваете новый Linux-сервер, он похож на только что купленный смартфон — всё работает из коробки, но настройки безопасности далеки от идеала. SSH открыт для всего мира, root логинится напрямую, лишние сервисы весело крутятся в фоне. Эта статья — пошаговый гайд по hardening'у: от первого входа до полноценно защищённого продакшн-сервера.
Шаг 1. Первый вход и базовая гигиена
Обновление системы — это не опционально
Первое, что делаем после подключения:
apt update && apt upgrade -y # Debian/Ubuntu
dnf update -y # RHEL/CentOS/Fedora
Звучит банально, но большинство взломов происходит через известные уязвимости, для которых патчи уже давно вышли. Настройте автоматические обновления безопасности:
# Ubuntu/Debian
apt install unattended-upgrades -y
dpkg-reconfigure --priority=low unattended-upgrades
Файл конфигурации /etc/apt/apt.conf.d/50unattended-upgrades — проверьте, что там включены только security-обновления, а не всё подряд. Автоапгрейд всего и сразу на продакшне — риск, обновления безопасности — необходимость.
Создание непривилегированного пользователя
Работать под root — это как ходить с заряженным пистолетом в кармане без предохранителя. Создаём обычного пользователя и даём ему sudo:
adduser deploy
usermod -aG sudo deploy
# Или на RHEL-системах
useradd -m -G wheel deploy
passwd deploy
Проверяем, что sudo работает:
su - deploy
sudo whoami # должен вернуть root
Шаг 2. Настройка SSH — главные ворота на сервер
SSH-демон — самое атакуемое место на любом публичном сервере. Посмотрите на логи нового сервера через сутки после запуска:
grep "Failed password" /var/log/auth.log | wc -l
Тысячи попыток — это норма. Потому что боты сканируют интернет 24/7.
Ключи вместо паролей
Генерируем ключ на локальной машине (если ещё нет):
ssh-keygen -t ed25519 -C "your_email@example.com"
# ed25519 современнее и быстрее RSA-4096, при той же безопасности
Копируем публичный ключ на сервер:
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@your-server-ip
Или вручную:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ваш_публичный_ключ" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
Конфигурация sshd
Редактируем /etc/ssh/sshd_config:
# Порт — меняем с дефолтного 22
# Это не security через obscurity, а просто уменьшение шума в логах
Port 2222
# Запрещаем root-логин категорически
PermitRootLogin no
# Только ключи, никаких паролей
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
# Только наш пользователь
AllowUsers deploy
# Отключаем X11 forwarding если не нужен
X11Forwarding no
# Ограничиваем попытки аутентификации
MaxAuthTries 3
MaxSessions 5
# Таймаут для неактивных сессий (секунды)
ClientAliveInterval 300
ClientAliveCountMax 2
# Более современные алгоритмы
KexAlgorithms curve25519-sha256,diffie-hellman-group14-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512,hmac-sha2-256
Перезапускаем sshd — но сначала проверяем конфиг:
sshd -t # тест конфига без перезапуска
systemctl restart sshd
Важно: не закрывайте текущую сессию, пока не убедитесь, что можете подключиться с новыми настройками в отдельном окне терминала.
Двухфакторная аутентификация через Google Authenticator
Для особо важных серверов добавляем TOTP:
apt install libpam-google-authenticator -y
# Запускаем от имени пользователя deploy
su - deploy
google-authenticator
Отвечаем на вопросы (рекомендую: yes, yes, no, yes), сохраняем QR-код и backup-коды.
В /etc/pam.d/sshd добавляем:
auth required pam_google_authenticator.so
В sshd_config:
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Шаг 3. Firewall — iptables vs nftables vs ufw
UFW — простой вариант для Ubuntu
apt install ufw -y
# Политика по умолчанию — всё запрещено входящее
ufw default deny incoming
ufw default allow outgoing
# Разрешаем только то, что нужно
ufw allow 2222/tcp # наш SSH порт
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
# Включаем
ufw enable
ufw status verbose
nftables — современный и мощный подход
nftables — замена iptables, доступная в современных дистрибутивах. Конфиг в /etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Разрешаем established соединения
ct state established,related accept
# Loopback
iif "lo" accept
# ICMP (ping) — ограниченно
ip protocol icmp icmp type echo-request limit rate 5/second accept
# SSH на нашем порту только с определённых IP
ip saddr 1.2.3.4 tcp dport 2222 accept
# HTTP/HTTPS
tcp dport { 80, 443 } accept
# Логируем всё остальное перед дропом
log prefix "nftables-drop: " level warn
drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
systemctl enable nftables
systemctl start nftables
nft list ruleset # проверяем
Защита от брутфорса — fail2ban
fail2ban анализирует логи и банит IP-адреса, которые ломятся брутфорсом:
apt install fail2ban -y
Создаём /etc/fail2ban/jail.local:
[DEFAULT]
bantime = 3600 ; 1 час бана
findtime = 600 ; окно в 10 минут
maxretry = 3 ; 3 неудачных попытки
# Белый список
ignoreip = 127.0.0.1/8 ::1 ваш_офисный_ip
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400 ; сутки для особо настойчивых
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
[nginx-limit-req]
enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
systemctl enable fail2ban
systemctl start fail2ban
fail2ban-client status # проверяем статус
fail2ban-client status sshd # статус конкретного jail
Шаг 4. Минимизация поверхности атаки
Отключаем ненужные сервисы
Смотрим, что запущено:
systemctl list-units --type=service --state=running
Типичные кандидаты на отключение на серверах без GUI:
systemctl disable --now avahi-daemon # mDNS — нужен только в локалке
systemctl disable --now cups # принтеры — зачем на сервере?
systemctl disable --now bluetooth # очевидно
systemctl disable --now ModemManager # модемы на сервере?
Удаляем ненужные пакеты
apt autoremove --purge
apt purge telnet rsh-client rsh-redone-client # старые небезопасные протоколы
Ограничиваем права на критичные файлы
# Проверяем SUID/SGID файлы — потенциальные векторы privilege escalation
find / -perm /4000 -o -perm /2000 2>/dev/null | grep -v proc
# Устанавливаем строгие права на критичные файлы
chmod 600 /etc/shadow
chmod 644 /etc/passwd
chmod 644 /etc/group
chmod 600 /boot/grub/grub.cfg
Настройка sysctl — параметры ядра
Редактируем /etc/sysctl.d/99-security.conf:
# Защита от IP spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Отключаем принятие source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# Игнорируем ICMP redirect
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Защита от SYN flood
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
# Логируем подозрительные пакеты
net.ipv4.conf.all.log_martians = 1
# Отключаем IPv6 если не используется
# net.ipv6.conf.all.disable_ipv6 = 1
# ASLR включён по умолчанию, но проверяем
kernel.randomize_va_space = 2
# Ограничиваем дамп core только root
fs.suid_dumpable = 0
# Защита от переполнения буфера
kernel.exec-shield = 1 # если поддерживается
sysctl -p /etc/sysctl.d/99-security.conf
Шаг 5. Аудит и мониторинг безопасности
auditd — аудит системных вызовов
apt install auditd audispd-plugins -y
# Пример правил в /etc/audit/rules.d/audit.rules
-w /etc/passwd -p wa -k user-modify
-w /etc/shadow -p wa -k user-modify
-w /etc/sudoers -p wa -k sudo-modify
-w /var/log/auth.log -p wa -k auth-log
-a always,exit -F arch=b64 -S execve -k command-exec
AIDE — контроль целостности файлов
AIDE создаёт базу данных хешей критичных файлов и сигнализирует об изменениях:
apt install aide -y
aideinit # инициализируем базу (занимает время)
cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Проверка (запускаем по крону ежедневно)
aide --check
Добавляем в cron:
0 4 * * * root /usr/bin/aide --check | mail -s "AIDE check $(hostname)" admin@example.com
Проверяем открытые порты и соединения
# Смотрим что слушает
ss -tlnp # лучше чем netstat
# или
netstat -tlnp
# Открытые соединения
ss -tnp state established
# Проверяем на rootkits
apt install rkhunter chkrootkit
rkhunter --update
rkhunter --check
chkrootkit
Шаг 6. AppArmor и SELinux — мандатный контроль доступа
AppArmor (Ubuntu/Debian)
AppArmor ограничивает приложения набором разрешённых действий:
apt install apparmor apparmor-utils -y
systemctl enable apparmor
aa-status # проверяем статус профилей
# Переводим профили в enforce mode
aa-enforce /etc/apparmor.d/*
# Создаём профиль для приложения
aa-genprof /usr/sbin/nginx
SELinux (RHEL/CentOS)
# Проверяем статус
getenforce # Enforcing/Permissive/Disabled
# Включаем если выключен
setenforce 1
# В /etc/selinux/config: SELINUX=enforcing
# Просматриваем нарушения
audit2why < /var/log/audit/audit.log
# Создаём разрешающий модуль из нарушений (осторожно!)
audit2allow -a -M mypolicy
semodule -i mypolicy.pp
Шаг 7. Шифрование и безопасность данных
Шифрование диска — LUKS
Лучше делать при установке, но можно и на существующей системе (с резервным копированием!):
# Создаём зашифрованный контейнер
cryptsetup luksFormat /dev/sdb1
# Открываем
cryptsetup luksOpen /dev/sdb1 encrypted_data
# Монтируем
mkfs.ext4 /dev/mapper/encrypted_data
mount /dev/mapper/encrypted_data /mnt/secure
Безопасное хранение секретов
Никогда не кладите пароли и ключи в переменные окружения напрямую или в конфиги в git. Варианты:
# HashiCorp Vault
vault kv put secret/myapp db_password="supersecret"
vault kv get secret/myapp
# Systemd credentials (systemd 250+)
systemd-creds encrypt --name=db-password - > /etc/credstore/db-password.cred
# В unit-файле:
# LoadCredential=db-password:/etc/credstore/db-password.cred
Чеклист: что проверить перед деплоем
Финальный чеклист для продакшн-сервера:
[ ] Система обновлена, настроены автоматические security-патчи
[ ] Создан непривилегированный пользователь, root-вход запрещён
[ ] SSH: только ключи, нестандартный порт, AllowUsers
[ ] Firewall настроен, открыты только нужные порты
[ ] fail2ban запущен и настроен
[ ] Отключены ненужные сервисы
[ ] sysctl параметры безопасности установлены
[ ] auditd запущен, правила аудита настроены
[ ] AIDE инициализирован, проверка по расписанию
[ ] AppArmor/SELinux в enforcing mode
[ ] Секреты не хранятся в открытом виде
[ ] Настроено оповещение о нарушениях безопасности
Инструменты автоматической проверки
# Lynis — комплексный аудит безопасности
apt install lynis
lynis audit system
# OpenSCAP — проверка соответствия стандартам (CIS Benchmarks)
apt install libopenscap8 ssg-base
oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_cis \
/usr/share/xml/scap/ssg/content/ssg-ubuntu2004-ds.xml
# Nmap — сканируем себя снаружи
nmap -sV -p- --script vuln your-server-ip
Безопасность — это не состояние, это процесс. Регулярно проверяйте логи, обновляйте систему, пересматривайте правила по мере изменения инфраструктуры. И помните: самое уязвимое звено всегда находится между монитором и креслом.
Create an account or sign in to leave a review
There are no reviews to display.