Пошаговое руководство по усилению безопасности Linux-сервера, охватывающее безопасность SSH, межсетевые экраны, обнаружение вторжений, аудит и настройку системы для уменьшения поверхности атаки и улучшения защиты.
Развивающееся руководство по обеспечению безопасности Linux-сервера, которое, надеюсь, также научит вас немного основам безопасности и объяснит, почему это важно.
(Содержание создано с помощью nGitHubTOC)
Цель этого руководства — научить вас обеспечивать безопасность Linux-сервера.
Существует множество способов защитить Linux-сервер, и это руководство постарается охватить как можно больше из них. Дополнительные темы/материалы будут добавляться по мере моего обучения или поступления вклада от участников.
Ansible playbooks для этого руководства доступны в репозитории How To Secure A Linux Server With Ansible от moltenbit.
Я предполагаю, что вы используете это руководство, потому что, надеюсь, уже понимаете, почему хорошая безопасность важна. Это обширная тема сама по себе, и её детальное рассмотрение выходит за рамки данного руководства. Если вы не знаете ответа на этот вопрос, рекомендую сначала изучить его.
На высоком уровне: как только устройство, например сервер, оказывается в публичном доступе — то есть видимо для внешнего мира — оно становится целью для злоумышленников. Незащищённое устройство — это игровая площадка для злоумышленников, которые хотят получить доступ к вашим данным или использовать ваш сервер как ещё один узел для масштабных DDOS-атак.
Что ещё хуже, без хорошей безопасности вы можете никогда не узнать, что ваш сервер был скомпрометирован. Злоумышленник мог получить несанкционированный доступ к вашему серверу и скопировать ваши данные, ничего не изменив, так что вы бы и не узнали. Или ваш сервер мог быть частью DDOS-атаки, и вы бы не знали об этом. Посмотрите на многие масштабные утечки данных в новостях — компании часто обнаруживали утечку или вторжение лишь спустя долгое время после того, как злоумышленники уже ушли.
Вопреки распространённому мнению, злоумышленники не всегда хотят что-то изменить или заблокировать вам доступ к данным ради выкупа. Иногда им просто нужны данные с вашего сервера для их хранилищ данных (в больших данных большие деньги) или чтобы скрытно использовать ваш сервер для своих неблаговидных целей.
Это руководство может показаться дублирующим/излишним, потому что в интернете бесчисленное множество статей, рассказывающих как защитить Linux, но информация разбросана по разным статьям, которые охватывают разные вещи и разными способами. У кого есть время просматривать сотни статей?
Когда я проводил исследование для своей сборки Debian, я делал заметки. В итоге я понял, что вместе с тем, что я уже знал, и тем, что я изучал, у меня получилось нечто похожее на руководство. Я решил выложить его в интернет, чтобы помочь другим учиться и экономить время.
Я никогда не встречал одного руководства, которое охватывало бы всё — это руководство — моя попытка.
Многие вещи, описанные в этом руководстве, могут быть довольно базовыми/тривиальными, но большинство из нас не устанавливает Linux каждый день, и легко забыть эти базовые вещи.
Существует множество руководств от экспертов, лидеров отрасли и самих дистрибутивов. Невозможно, а иногда и запрещено авторским правом, включать сюда всё из этих руководств. Рекомендую ознакомиться с ними перед началом работы с этим руководством.
Это руководство...
Существует множество типов серверов и различных сценариев использования. Хотя я хочу, чтобы это руководство было максимально общим, некоторые вещи могут не подходить для всех/других сценариев. Используйте своё лучшее суждение при прохождении этого руководства.
Чтобы дать контекст многим темам, рассматриваемым в этом руководстве, мой сценарий использования/конфигурация:
Я очень ленив и не люблю редактировать файлы вручную, если в этом нет необходимости. И я предполагаю, что все остальные такие же. :)
Поэтому, когда и где это возможно, я предоставил фрагменты кода для быстрого выполнения необходимого, например, добавления или изменения строки в конфигурационном файле.
Фрагменты кода используют базовые команды, такие как echo, cat, sed, awk и grep. Как работают фрагменты кода, например, что делает каждая команда/часть, выходит за рамки этого руководства — страницы man вам в помощь.
Примечание: Фрагменты кода не проверяют/подтверждают, что изменение прошло — то есть строка была фактически добавлена или изменена. Я оставлю проверку на ваше усмотрение. Шаги в этом руководстве включают создание резервных копий всех файлов, которые будут изменены.
Не все изменения можно автоматизировать с помощью фрагментов кода. Эти изменения требуют хорошего, старого, ручного редактирования. Например, вы не можете просто добавить строку в файл типа INI. Используйте ваш любимый текстовый редактор Linux.
Я хотел разместить это руководство на GitHub, чтобы упростить совместную работу. Чем больше людей внесут вклад, тем лучше и полнее станет это руководство.
Чтобы внести вклад, вы можете сделать форк и отправить pull request или создать новую задачу.
Перед началом вам нужно определить свои принципы. Какова ваша модель угроз? Вот что стоит обдумать:
Это лишь несколько вещей, которые стоит обдумать. Прежде чем начать защищать свой сервер, вы должны понять, от чего вы пытаетесь защититься и почему, чтобы знать, что вам нужно делать.
Это руководство предназначено быть независимым от дистрибутива, чтобы пользователи могли использовать любой дистрибутив по своему желанию. Тем не менее, есть несколько моментов, которые стоит учитывать:
Вам нужен дистрибутив, который...
Установка Linux выходит за рамки этого руководства, потому что каждый дистрибутив делает это по-своему, и инструкции по установке обычно хорошо документированы. Если вам нужна помощь, начните с документации вашего дистрибутива. Независимо от дистрибутива, общий процесс обычно выглядит так:
Где это применимо, используйте опцию экспертной установки, чтобы иметь более строгий контроль над тем, что запущено на вашем сервере. Устанавливайте только то, что вам абсолютно необходимо. Я лично не устанавливаю ничего, кроме SSH. Также отметьте опцию шифрования диска.
sudo apt update && sudo apt upgrade в системах на базе Debian)./etc/fstabmanapt, которые должны работать во всех дистрибутивах на основе Debian. Если кто-то захочет предоставить соответствующие команды для других дистрибутивов, я их добавлю.Ansible playbooks для этого руководства доступны в репозитории How To Secure A Linux Server With Ansible.Убедитесь, что вы отредактировали переменные в соответствии со своими потребностями и прочитали все задачи заранее, чтобы убедиться, что это не нарушит работу вашей системы. После запуска playbooks убедитесь, что все настройки настроены по вашему желанию!
Измените все переменные в *group_vars/variables.yml* в соответствии с вашими потребностями.
6. Включите SSH-доступ от root перед запуском playbooks: ```
nano /etc/ssh/sshd_config
[...]
PermitRootLogin yes
[...]
Запустите плейбук требований, используя пароль root, который вы указали при установке сервера:
ansible-playbook --inventory hosts.yml --ask-pass requirements-playbook.yml
Запустите основной плейбук с паролем нового пользователя, который вы указали в файле variables.yml:
ansible-playbook --inventory hosts.yml --ask-pass main-playbook.yml
Если вам нужно запускать плейбуки несколько раз, не забудьте использовать SSH-ключ и новый SSH-порт:
ansible-playbook --inventory hosts.yml -e ansible_ssh_port=SSH_PORT --key-file /PATH/TO/SSH/KEY main-playbook.yml
Настоятельно рекомендуется держать второе окно терминала, подключённое к вашему серверу до того, как вы внесёте и примените изменения в настройках SSH. Таким образом, если вы заблокируете себя в первом сеансе терминала, у вас останется ещё один сеанс, через который вы сможете исправить ситуацию.
Спасибо Sonnenbrand за эту идею.
Использование публичных/приватных ключей SSH более безопасно, чем использование пароля. Это также упрощает и ускоряет подключение к нашему серверу, поскольку вам не нужно вводить пароль.
Обратитесь к ссылкам ниже для получения более подробной информации, но на высоком уровне публичные/приватные ключи работают, используя пару ключей для проверки личности.
Для SSH на клиенте создаётся публичный и приватный ключ. Вы должны хранить оба ключа в безопасности, особенно приватный ключ. Несмотря на то, что публичный ключ предназначен для распространения, разумно убедиться, что ни один из ключей не попадёт в чужие руки.
Когда вы подключаетесь к SSH-серверу, SSH ищет публичный ключ, соответствующий клиенту, с которого вы подключаетесь, в файле ~/.ssh/authorized_keys на сервере, к которому вы подключаетесь. Обратите внимание, что файл находится в домашней папке учётной записи, под которой вы пытаетесь подключиться. Итак, после создания публичного ключа его нужно добавить в ~/.ssh/authorized_keys. Один из подходов — скопировать его на USB-накопитель и физически перенести на сервер. Другой подход — использовать ssh-copy-id для передачи и добавления публичного ключа.
После того как ключи созданы и публичный ключ добавлен в ~/.ssh/authorized_keys на хосте, SSH использует публичный и приватный ключи для проверки личности и установления защищённого соединения. То, как проверяется личность, — сложный процесс, но у Digital Ocean есть очень хорошее описание того, как это работает. На высоком уровне личность проверяется сервером: он шифрует проверочное сообщение публичным ключом, затем отправляет его клиенту. Если клиент не может расшифровать проверочное сообщение приватным ключом, личность не может быть подтверждена, и соединение не будет установлено.
Они считаются более безопасными, потому что для установления SSH-соединения требуется приватный ключ. Если вы установите PasswordAuthentication no в /etc/ssh/sshd_config, то SSH не позволит вам подключиться без приватного ключа.
Вы также можете установить кодовую фразу для ключей, что потребует ввода кодовой фразы ключа при подключении с использованием публичных/приватных ключей. Имейте в виду, что это делает ключ непригодным для автоматизации, поскольку у вас не будет способа отправить кодовую фразу в ваших скриптах. ssh-agent — это программа, которая поставляется со многими дистрибутивами Linux (и обычно уже запущена) и позволяет хранить расшифрованный приватный ключ в памяти в течение настраиваемого времени. Просто выполните ssh-add, и он запросит вашу кодовую фразу. Вас не будут снова запрашивать кодовую фразу до истечения настраиваемого времени.
Мы будем использовать ключи Ed25519, которые, согласно https://linux-audit.com/:
Использует схему подписи на эллиптических кривых, что обеспечивает лучшую безопасность, чем ECDSA и DSA. В то же время она также обладает хорошей производительностью.
man ssh-keygenman ssh-copy-idman ssh-addНа компьютере, который вы будете использовать для подключения к вашему серверу, на клиенте, а не на самом сервере, создайте ключ Ed25519 с помощью ssh-keygen:
ssh-keygen -t ed25519
Generating public/private ed25519 key pair. Enter file in which to save the key (/home/user/.ssh/id_ed25519): Created directory '/home/user/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_ed25519. Your public key has been saved in /home/user/.ssh/id_ed25519.pub. The key fingerprint is: SHA256:F44D4dr2zoHqgj0i2iVIHQ32uk/Lx4P+raayEAQjlcs user@client The key's randomart image is: +--[ED25519 256]--+ |xxxx x | |o.o +. . | | o o oo . | |. E oo . o . | | o o. o S o | |... .. o o | |.+....+ o | |+.=++o.B.. | |+..=**=o=. | +----[SHA256]-----+
Примечание: Если вы установили кодовую фразу, вам нужно будет вводить её каждый раз при подключении к серверу с использованием этого ключа, если вы не используете ssh-agent.
Теперь вам нужно добавить публичный ключ ~/.ssh/id_ed25519.pub с вашего клиента в файл ~/.ssh/authorized_keys на вашем сервере. Поскольку мы, скорее всего, всё ещё в домашней локальной сети, мы, вероятно, в безопасности от атак MIM, поэтому мы воспользуемся ssh-copy-id для передачи и добавления публичного ключа:
ssh-copy-id user@server
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub" The authenticity of host 'host (192.168.1.96)' can't be established. ECDSA key fingerprint is SHA256:QaDQb/X0XyVlogh87sDXE7MR8YIK7ko4wS5hXjRySJE. Are you sure you want to continue connecting (yes/no)? yes /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: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys user@host's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'user@host'" and check to make sure that only the key(s) you wanted were added.
Сейчас хорошее время для выполнения любых задач, специфичных для вашей настройки.
Чтобы упростить управление доступом к SSH на сервер. Используя группу, мы можем быстро добавлять/удалять учётные записи в/из группы, чтобы быстро разрешать или запрещать SSH-доступ к серверу.
Мы будем использовать опцию AllowGroups в конфигурационном файле SSH /etc/ssh/sshd_config, чтобы указать SSH-серверу разрешать вход только тем пользователям, которые являются членами определённой группы UNIX. Любой, кто не входит в группу, не сможет войти через SSH.
/etc/ssh/sshd_config для ограничения тех, кто может подключаться к серверу по SSHAllowGroup, устанавливаемой в Secure /etc/ssh/sshd_config.man groupaddman usermodСоздайте группу:
sudo groupadd sshusers
Добавьте учётные записи в группу:
sudo usermod -a -G sshusers user1
sudo usermod -a -G sshusers user2
sudo usermod -a -G sshusers ...
Это нужно сделать для каждой учётной записи на вашем сервере, которой требуется SSH-доступ.
/etc/ssh/sshd_configSSH — это дверь на ваш сервер. Особенно это актуально, если вы открываете порты на своём маршрутизаторе, чтобы иметь возможность подключаться к серверу по SSH из-за пределов домашней сети. Если он не настроен должным образом, злоумышленник может использовать его для получения несанкционированного доступа к вашей системе.
/etc/ssh/sshd_config — это файл конфигурации по умолчанию, который использует SSH-сервер. Мы будем использовать этот файл, чтобы указать, какие опции должен использовать SSH-сервер.
man sshd_configСделайте резервную копию конфигурационного файла OpenSSH-сервера /etc/ssh/sshd_config и удалите комментарии, чтобы его было легче читать:
sudo cp --archive /etc/ssh/sshd_config /etc/ssh/sshd_config-COPY-$(date +"%Y%m%d%H%M%S")
sudo sed -i -r -e '/^#|^$/ d' /etc/ssh/sshd_config
Отредактируйте /etc/ssh/sshd_config, затем найдите и отредактируйте или добавьте следующие настройки, которые должны применяться независимо от вашей конфигурации/настройки:
Примечание: SSH не любит дублирующиеся противоречащие настройки. Например, если у вас есть ChallengeResponseAuthentication no, а затем ChallengeResponseAuthentication yes, SSH будет учитывать первую настройку и игнорировать вторую. В вашем файле /etc/ssh/sshd_config уже могут быть некоторые из перечисленных ниже настроек/строк. Чтобы избежать проблем, вам нужно будет вручную просмотреть файл /etc/ssh/sshd_config и устранить любые дублирующиеся противоречащие настройки.
Примечание: Если вы используете OpenSSH 9.1 или новее, раскомментируйте строку RequiredRSASize 3072 в конфигурации ниже. Это устанавливает минимальный размер RSA-ключа в 3072 бит и будет отклонять более короткие RSA-ключи при аутентификации. Это касается только RSA-ключей. Если вы используете ключи ED25519 или ECDSA, это вас не касается. Вы можете проверить тип и размер вашего ключа с помощью ssh-keygen -l -f ~/.ssh/id_rsa. На более старых версиях OpenSSH оставьте строку закомментированной, так как это помешает запуску sshd.
########################################################################################################
# start settings from https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67 as of 2019-01-01
########################################################################################################
# Supported HostKey algorithms by order of preference.
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
KexAlgorithms [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected]
# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear audit track of which key was using to log in.
LogLevel VERBOSE
# Use kernel sandbox mechanisms where possible in unprivileged processes
# Systrace on OpenBSD, Seccomp on Linux, seatbelt on MacOSX/Darwin, rlimit elsewhere.
# Note: This setting is deprecated in OpenSSH 7.5 (https://www.openssh.com/txt/release-7.5)
# UsePrivilegeSeparation sandbox
########################################################################################################
# end settings from https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67 as of 2019-01-01
########################################################################################################
# don't let users set environment variables
PermitUserEnvironment no
# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise.
Subsystem sftp internal-sftp -f AUTHPRIV -l INFO
# disable X11 forwarding as X11 is very insecure
# you really shouldn't be running X on a server anyway
X11Forwarding no
# disable port forwarding
AllowTcpForwarding no
AllowStreamLocalForwarding no
GatewayPorts no
PermitTunnel no
# don't allow login if the account has an empty password
PermitEmptyPasswords no
# ignore .rhosts and .shosts
IgnoreRhosts yes
# verify hostname matches IP
UseDNS yes
Compression no
# TCP keepalive is spoofable (runs outside the encrypted channel)
# Use ClientAlive instead (runs inside the encrypted channel)
TCPKeepAlive no
AllowAgentForwarding no
PermitRootLogin no
# don't allow .rhosts or /etc/hosts.equiv
HostbasedAuthentication no
# OpenSSH 9.1 and later
# Enforce a minimum RSA key size of 3072 bits
# https://www.keylength.com/en/compare/
# RequiredRSASize 3072
# https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/115
HashKnownHosts yes
Затем найдите и отредактируйте или добавьте следующие настройки и укажите значения в соответствии с вашими требованиями:
Убедитесь, что нет дублирующихся настроек, которые противоречат друг другу. Следующая команда не должна выводить ничего.
awk 'NF && $1!~/^(#|HostKey)/{print $1}' /etc/ssh/sshd_config | sort | uniq -c | grep -v ' 1 '
Перезапустите ssh:
sudo service sshd restart
Вы можете проверить конфигурацию с помощью sshd -T и убедиться в правильности вывода:
sudo sshd -T
port 22 addressfamily any listenaddress [::]:22 listenaddress 0.0.0.0:22 usepam yes logingracetime 30 x11displayoffset 10 maxauthtries 2 maxsessions 2 clientaliveinterval 15 clientalivecountmax 3 streamlocalbindmask 0177 permitrootlogin no ignorerhosts yes ignoreuserknownhosts no hostbasedauthentication no ... subsystem sftp internal-sftp -f AUTHPRIV -l INFO maxstartups 2:30:2 permittunnel no ipqos lowdelay throughput rekeylimit 0 0 permitopen any
Согласно рекомендациям Mozilla по OpenSSH для OpenSSH 6.7+, «все модули Диффи-Хеллмана должны быть длиной не менее 3072 бит».
Алгоритм Диффи-Хеллмана используется SSH для установления безопасного соединения. Чем больше модуль (размер ключа), тем надёжнее шифрование.
man moduliСделайте резервную копию файла модулей SSH /etc/ssh/moduli:
sudo cp --archive /etc/ssh/moduli /etc/ssh/moduli-COPY-$(date +"%Y%m%d%H%M%S")
Удалите короткие модули:
sudo awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.tmp
sudo mv /etc/ssh/moduli.tmp /etc/ssh/moduli
Хотя SSH является довольно хорошим стражем безопасности для ваших дверей и окон, это всё же видимая дверь, которую злоумышленники могут заметить и попытаться подобрать пароль brute-force. Fail2ban будет отслеживать такие попытки brute-force, но не бывает слишком много безопасности. Требование двух факторов добавляет дополнительный уровень безопасности.
Использование двухфакторной аутентификации (2FA) / многофакторной аутентификации (MFA) требует от каждого входящего иметь два ключа для входа, что затрудняет действия злоумышленников. Два ключа:
Без обоих ключей они не смогут попасть внутрь.
Многим пользователям такой процесс может показаться громоздким или раздражающим. Кроме того, доступ к системе зависит от сопутствующего приложения-аутентификатора, которое генерирует код.
В Linux за аутентификацию отвечает PAM. У PAM есть четыре задачи, о которых вы можете прочитать на https://en.wikipedia.org/wiki/Linux_PAM. В этом разделе рассматривается задача аутентификации.
Когда вы входите на сервер (напрямую через консоль или через SSH), дверь, через которую вы прошли, отправляет запрос на задачу аутентификации PAM, и PAM запрашивает и проверяет ваш пароль. Вы можете настроить правила для каждой двери. Например, у вас может быть один набор правил при входе напрямую через консоль и другой набор правил при входе через SSH.
В этом разделе мы изменим правила аутентификации для входа через SSH, чтобы требовался как пароль, так и 6-значный код.Мы будем использовать PAM-модуль libpam-google-authenticator от Google для создания и проверки TOTP-ключа. В статьях https://fastmail.blog/2016/07/22/how-totp-authenticator-apps-work/ и https://jemurai.com/2018/10/11/how-it-works-totp-based-mfa/ очень хорошо описана работа TOTP.
Мы сделаем так: настроим конфигурацию PAM для SSH на сервере таким образом, чтобы сначала запрашивался пароль, а затем числовой токен. PAM проверит пароль пользователя и, если он верен, направит запрос аутентификации к libpam-google-authenticator, который запросит и проверит ваш 6-значный токен. Только если всё в порядке, аутентификация будет успешной, и пользователь получит доступ к входу.
Установите libpam-google-authenticator.
В системах на основе Debian:
sudo apt install libpam-google-authenticator
Убедитесь, что вы вошли под тем ID, для которого хотите включить 2FA/MFA, и выполните google-authenticator, чтобы создать необходимые данные токена:
google-authenticator
Вы хотите, чтобы токены были привязаны ко времени (y/n) y https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/user@host%3Fsecret%3DR4ZWX34FQKZROVX7AGLJ64684Y%26issuer%3Dhost ... Ваш новый секретный ключ: R3NVX3FFQKZROVX7AGLJUGGESY Ваш проверочный код: 751419 Ваши аварийные коды для восстановления: 12345678 90123456 78901234 56789012 34567890 Обновить файл "/home/user/.google_authenticator" (y/n) y Запретить повторное использование одного и того же токена? Это ограничит вас одним входом примерно каждые 30 секунд, но повысит шансы заметить или предотвратить атаки «человек посередине» (y/n) y По умолчанию токены действительны 30 секунд. Для компенсации возможного расхождения времени между клиентом и сервером мы разрешаем использовать дополнительный токен до и после текущего времени. Если у вас проблемы с плохой синхронизацией времени, вы можете увеличить окно с размера по умолчанию +-1 мин (размер окна 3) до примерно +-4 мин (размер окна 17 допустимых токенов). Вы хотите это сделать? (y/n) y Если компьютер, на который вы входите, не защищён от атак перебором, вы можете включить ограничение скорости для модуля аутентификации. По умолчанию это ограничивает атакующих не более чем 3 попытками входа каждые 30 секунд. Включить ограничение скорости? (y/n) y
Обратите внимание: это не выполняется от root.
Выберите вариант по умолчанию (y в большинстве случаев) для всех вопросов и не забудьте сохранить аварийные коды для восстановления.
Сделайте резервную копию конфигурационного файла PAM для SSH /etc/pam.d/sshd:
sudo cp --archive /etc/pam.d/sshd /etc/pam.d/sshd-COPY-$(date +"%Y%m%d%H%M%S")
Теперь необходимо включить его как метод аутентификации для SSH, добавив эту строку в /etc/pam.d/sshd:
auth required pam_google_authenticator.so nullok
Примечание: Значение nullok описано здесь.
echo -e "\nauth required pam_google_authenticator.so nullok # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/pam.d/sshd
Сообщите SSH, чтобы он использовал это, добавив или отредактировав эту строку в /etc/ssh/sshd_config:
ChallengeResponseAuthentication yes
sudo sed -i -r -e "s/^(challengeresponseauthentication .*)$/# \1 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/I" /etc/ssh/sshd_config
echo -e "\nChallengeResponseAuthentication yes # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ssh/sshd_config
Перезапустите ssh:
sudo service sshd restart
sudo позволяет учётным записям выполнять команды от имени других учётных записей, включая root. Мы хотим быть уверены, что только нужные учётные записи могут использовать sudo.
Debian создаёт группу sudo. Чтобы просмотреть пользователей, входящих в эту группу (имеющих привилегии sudo):
cat /etc/group | grep "sudo"
RedHat создаёт группу wheel
sudo не требует пароля. Спасибо sbrl за информацию.Создайте группу:
sudo groupadd sudousers
Добавьте учётную запись(и) в группу:
sudo usermod -a -G sudousers user1
sudo usermod -a -G sudousers user2
sudo usermod -a -G sudousers ...
Это нужно сделать для каждой учётной записи на вашем сервере, которой требуются привилегии sudo.
Сделайте резервную копию файла конфигурации sudo /etc/sudoers:
sudo cp --archive /etc/sudoers /etc/sudoers-COPY-$(date +"%Y%m%d%H%M%S")
Отредактируйте файл конфигурации sudo /etc/sudoers:
sudo visudo
Сообщите sudo, что только пользователи из группы sudousers могут использовать sudo, добавив эту строку, если её ещё нет:
%sudousers ALL=(ALL:ALL) ALL
su также позволяет учётным записям выполнять команды от имени других учётных записей, включая root. Мы хотим быть уверены, что только нужные учётные записи могут использовать su.
Создайте группу:
sudo groupadd suusers
Добавьте учётную запись(и) в группу:
sudo usermod -a -G suusers user1
sudo usermod -a -G suusers user2
sudo usermod -a -G suusers ...
Это нужно сделать для каждой учётной записи на вашем сервере, которой требуются привилегии sudo.
Сделайте так, чтобы только пользователи из этой группы могли выполнять /bin/su:
sudo dpkg-statoverride --update --add root suusers 4750 /bin/su
Для многих приложений гораздо лучше работать в изолированной среде.
Браузеры (особенно закрытые) и почтовые клиенты настоятельно рекомендуется запускать в песочнице.
Установите программное обеспечение:
sudo apt install firejail firejail-profiles
Примечание: для Debian 10 Stable рекомендуется официальный Backport:
sudo apt install -t buster-backports firejail firejail-profiles
Разрешите приложению (установленному в /usr/bin или /bin) запускаться только в песочнице (см. несколько примеров ниже):
sudo ln -s /usr/bin/firejail /usr/local/bin/google-chrome-stable
sudo ln -s /usr/bin/firejail /usr/local/bin/firefox
sudo ln -s /usr/bin/firejail /usr/local/bin/chromium
sudo ln -s /usr/bin/firejail /usr/local/bin/evolution
sudo ln -s /usr/bin/firejail /usr/local/bin/thunderbird
Запустите приложение как обычно (через терминал или лаунчер) и проверьте, работает ли оно в jail:
firejail --list
Чтобы разрешить приложению, запущенному в песочнице, снова работать как прежде (пример: firefox):
sudo rm /usr/local/bin/firefox
Многие протоколы безопасности используют системное время. Если время на вашей системе неверно, это может негативно сказаться на работе сервера. NTP-клиент решает эту проблему, синхронизируя системное время с глобальными NTP-серверами.
NTP расшифровывается как Network Time Protocol (протокол сетевого времени). В контексте этого руководства NTP-клиент на сервере используется для обновления времени сервера с официальных серверов. Список всех публичных NTP-серверов доступен на https://www.pool.ntp.org/en/.
Примечание: Начиная с Debian 13 (Trixie) классический пакет
ntpудалён. Выполнениеsudo apt install ntpзавершится ошибкой "Package ntp has no installation candidate". Поскольку в этом руководстве NTP используется только как клиент (для синхронизации часов сервера), начиная с Debian 13 рекомендуется использоватьsystemd-timesyncd, который уже предустановлен и не требует дополнительных пакетов. См. шаги для Debian 13+ ниже.
systemd-timesyncd — это лёгкий SNTP-клиент, уже включённый в Debian. В отличие от полного демона ntpd, он не прослушивает порты, что уменьшает поверхность атаки. Для целей этого руководства — синхронизации часов вашего сервера — его вполне достаточно.
Включите синхронизацию NTP:
sudo timedatectl set-ntp true
Проверьте, что она работает:
timedatectl status
В выводе должно быть NTP service: active и System clock synchronized: yes.
Настройте доверенные NTP-серверы. Сделайте резервную копию файла конфигурации, затем отредактируйте его:
sudo cp --archive /etc/systemd/timesyncd.conf /etc/systemd/timesyncd.conf-COPY-$(date +"%Y%m%d%H%M%S")
Отредактируйте /etc/systemd/timesyncd.conf и раскомментируйте/задайте секцию [Time]:
[Time]
NTP=pool.ntp.org
FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org
sudo sed -i -r -e "s/^#?NTP=.*$/NTP=pool.ntp.org # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
sudo sed -i -r -e "s/^#?FallbackNTP=.*$/FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
Перезапустите службу для применения изменений:
sudo systemctl restart systemd-timesyncd
Проверьте статус синхронизации:
timedatectl timesync-status
Server: 108.61.56.35 (pool.ntp.org) Poll interval: 32s (min: 32s; max: 34min 8s) Leap: normal Version: 4 Stratum: 2 Reference: C342F10A Precision: 1us (2^0) Root distance: 24.054ms (max: 5s) Offset: +2.156ms Delay: 48.567ms Jitter: 1.452ms Packet count: 3
Примечание: Эти шаги применимы только к Debian 12 и более ранним версиям. На Debian 13+ пакет
ntpбольше не доступен — используйте вместо него шаги для systemd-timesyncd.
Установите ntp.
В системах на основе Debian:
sudo apt install ntp
Сделайте резервную копию конфигурационного файла NTP-клиента /etc/ntp.conf:
sudo cp --archive /etc/ntp.conf /etc/ntp.conf-COPY-$(date +"%Y%m%d%H%M%S")
Конфигурация по умолчанию, по крайней мере в Debian, уже достаточно безопасна. Единственное, что нужно сделать — убедиться, что используется директива pool, а не server. Директива pool позволяет NTP-клиенту прекратить использование сервера, если он не отвечает или выдаёт неверное время. Для этого закомментируйте все директивы server и добавьте в /etc/ntp.conf следующее:
pool pool.ntp.org iburst
sudo sed -i -r -e "s/^((server|pool).*)/# \1 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/ntp.conf
echo -e "\npool pool.ntp.org iburst # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ntp.conf
Пример /etc/ntp.conf:
driftfile /var/lib/ntp/ntp.drift statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable restrict -4 default kod notrap nomodify nopeer noquery limited restrict -6 default kod notrap nomodify nopeer noquery limited restrict 127.0.0.1 restrict ::1 restrict source notrap nomodify noquery pool pool.ntp.org iburst # добавлено пользователем 2019-03-09 в 10:23:35
Перезапустите ntp:
sudo service ntp restart
Проверьте статус службы ntp:
sudo systemctl status ntp
● ntp.service - LSB: Start NTP daemon Loaded: loaded (/etc/init.d/ntp; generated; vendor preset: enabled) Active: active (running) since Sat 2019-03-09 15:19:46 EST; 4s ago Docs: man:systemd-sysv-generator(8) Process: 1016 ExecStop=/etc/init.d/ntp stop (code=exited, status=0/SUCCESS) Process: 1028 ExecStart=/etc/init.d/ntp start (code=exited, status=0/SUCCESS) Tasks: 2 (limit: 4915) CGroup: /system.slice/ntp.service └─1038 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 108:113 Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 0 v6wildcard [::]:123 Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 1 v4wildcard 0.0.0.0:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 2 lo 127.0.0.1:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 3 enp0s3 10.10.20.96:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 4 lo [::1]:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 5 enp0s3 [fe80::a00:27ff:feb6:ed8e%2]:123 Mar 09 15:19:46 host ntpd[1038]: Listening on routing socket on fd #22 for interface updates Mar 09 15:19:47 host ntpd[1038]: Soliciting pool server 108.61.56.35 Mar 09 15:19:48 host ntpd[1038]: Soliciting pool server 69.89.207.199 Mar 09 15:19:49 host ntpd[1038]: Soliciting pool server 45.79.111.114
Проверьте статус ntp:
sudo ntpq -p
remote refid st t when poll reach delay offset jitter ============================================================================== pool.ntp.org .POOL. 16 p - 64 0 0.000 0.000 0.000 *lithium.constan 198.30.92.2 2 u - 64 1 19.900 4.894 3.951 ntp2.wiktel.com 212.215.1.157 2 u 2 64 1 48.061 -0.431 0.104
Заглянув в
/proc, вы обнаружите множество файлов и каталогов. Многие из них — просто числа, представляющие информацию о конкретном идентификаторе процесса (PID). По умолчанию системы Linux развёрнуты так, что все локальные пользователи могут видеть всю эту информацию. Сюда входит информация о процессах других пользователей, что может включать конфиденциальные данные, которыми вы, возможно, не хотите делиться. Применив некоторые настройки файловой системы, мы можем изменить это поведение и повысить безопасность системы.
Примечание: Это может сломаться на некоторых системах с systemd. Подробнее см. https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/37. Спасибо nlgranger за информацию.
/proc смонтирован с параметром hidepid=2, чтобы пользователи видели информацию только о своих процессахСделайте резервную копию /etc/fstab:
sudo cp --archive /etc/fstab /etc/fstab-COPY-$(date +"%Y%m%d%H%M%S")
Добавьте эту строку в /etc/fstab, чтобы /proc монтировался с hidepid=2:
proc /proc proc defaults,hidepid=2 0 0
echo -e "\nproc /proc proc defaults,hidepid=2 0 0 # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/fstab
Перезагрузите систему:
sudo reboot now
Примечание: Как вариант, можно перемонтировать /proc без перезагрузки с помощью sudo mount -o remount,hidepid=2 /proc.
По умолчанию учётные записи могут использовать любые пароли, включая ненадёжные. pwquality/pam_pwquality устраняет этот пробел безопасности, предоставляя «способ настройки стандартных требований к качеству паролей для системных паролей» и проверяя «их надёжность по системному словарю и набору правил для выявления неудачных вариантов».
В Linux PAM отвечает за аутентификацию. Существует четыре задачи PAM, о которых можно прочитать на https://en.wikipedia.org/wiki/Linux_PAM. Этот раздел рассказывает о задаче пароля.Когда возникает необходимость установить или изменить пароль учётной записи, задачу пароля PAM обрабатывает этот запрос. В этом разделе мы укажем задаче пароля PAM передавать запрошенный новый пароль в libpam-pwquality, чтобы убедиться, что он соответствует нашим требованиям. Если требования выполнены, он используется/устанавливается; если нет — возникает ошибка, и пользователь уведомляется.
Установите libpam-pwquality.
В системах на основе Debian:
sudo apt install libpam-pwquality
Сделайте резервную копию файла конфигурации паролей PAM /etc/pam.d/common-password:
sudo cp --archive /etc/pam.d/common-password /etc/pam.d/common-password-COPY-$(date +"%Y%m%d%H%M%S")
Укажите PAM использовать libpam-pwquality для принудительного применения надёжных паролей, отредактировав файл /etc/pam.d/common-password и изменив строку, которая начинается так:
password requisite pam_pwquality.so
на это:
password requisite pam_pwquality.so retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec
Приведённые выше параметры означают:
retry=3 = запрашивать у пользователя 3 раза перед возвратом ошибки.minlen=10 = минимальная длина пароля с учётом любых кредитов (или дебетов) от:
dcredit=-1 = должен содержать хотя бы одну цифруucredit=-1 = должен содержать хотя бы одну заглавную буквуlcredit=-1 = должен содержать хотя бы одну строчную буквуocredit=-1 = должен содержать хотя бы один не буквенно-цифровой символdifok=3 = как минимум 3 символа нового пароля не должны были быть в старом паролеmaxrepeat=3 = разрешено не более 3 повторяющихся символов подрядgecoschec = не допускать пароли, содержащие имя учётной записиsudo sed -i -r -e "s/^(password\s+requisite\s+pam_pwquality.so)(.*)$/# \1\2 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")\n\1 retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/pam.d/common-password
Важно поддерживать сервер в актуальном состоянии с последними критическими исправлениями безопасности и обновлениями. В противном случае вы рискуете столкнуться с известными уязвимостями, которые злоумышленники могут использовать для получения несанкционированного доступа к вашему серверу.
Если вы не планируете проверять сервер каждый день, вам понадобится способ автоматического обновления системы и/или получения писем о доступных обновлениях.
Не стоит выполнять все обновления, так как с каждым обновлением есть риск что-то сломать. Важно устанавливать критические обновления, но всё остальное может подождать, пока у вас не будет времени сделать это вручную.
Автоматические и неконтролируемые обновления могут нарушить работу системы, и вас может не оказаться рядом с сервером, чтобы это исправить. Это было бы особенно проблематично, если бы они нарушили ваш SSH-доступ.
В системах на основе Debian можно использовать:
Мы будем использовать unattended-upgrades для применения критических исправлений безопасности. Также можно применять стабильные обновления, поскольку они уже тщательно протестированы сообществом Debian.
/etc/apt/apt.conf.d/50unattended-upgradesУстановите unattended-upgrades, apt-listchanges и apticron:
sudo apt install unattended-upgrades apt-listchanges apticron
Теперь нужно настроить unattended-upgrades для автоматического применения обновлений. Обычно это делается редактированием файлов /etc/apt/apt.conf.d/20auto-upgrades и /etc/apt/apt.conf.d/50unattended-upgrades, созданных пакетами. Однако, поскольку эти файлы могут быть перезаписаны при будущем обновлении, мы создадим новый файл. Создайте файл /etc/apt/apt.conf.d/51myunattended-upgrades и добавьте в него следующее:
// Включить скрипт обновления/апгрейда (0=отключить)
APT::Periodic::Enable "1";
// Автоматически выполнять "apt-get update" каждые n дней (0=отключить)
APT::Periodic::Update-Package-Lists "1";
// Выполнять "apt-get upgrade --download-only" каждые n дней (0=отключить)
APT::Periodic::Download-Upgradeable-Packages "1";
// Выполнять "apt-get autoclean" каждые n дней (0=отключить)
APT::Periodic::AutocleanInterval "7";
// Отправлять отчёт по почте root
// 0: не отправлять отчёт (или пустая строка)
// 1: отчёт о прогрессе (фактически любая строка)
// 2: + вывод команд (убрать -qq, убрать 2>/dev/null, добавить -d)
// 3: + трассировка APT::Periodic::Verbose "2";
APT::Periodic::Unattended-Upgrade "1";
// Автоматически обновлять пакеты из этих
Unattended-Upgrade::Origins-Pattern {
"o=Debian,a=stable";
"o=Debian,a=stable-updates";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
};
// Здесь можно указать собственные пакеты, которые НЕ будут автоматически обновляться
Unattended-Upgrade::Package-Blacklist {
};
// Запускать dpkg --force-confold --configure -a, если обнаружено грязное состояние dpkg, чтобы гарантировать установку обновлений, даже если система была прервана во время предыдущего запуска
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
// Выполнять обновление, когда машина работает, так как мы не будем часто выключать сервер
Unattended-Upgrade::InstallOnShutdown "false";
// Отправлять письмо на этот адрес с информацией о обновлённых пакетах.
Unattended-Upgrade::Mail "root";
// Всегда отправлять письмо
Unattended-Upgrade::MailOnlyOnError "false";
// Удалять все неиспользуемые зависимости после завершения обновления
Unattended-Upgrade::Remove-Unused-Dependencies "true";
// Удалять любые новые неиспользуемые зависимости после завершения обновления
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
// Автоматически перезагружать БЕЗ ПОДТВЕРЖДЕНИЯ, если после обновления найден файл /var/run/reboot-required.
Unattended-Upgrade::Automatic-Reboot "true";
// Автоматически перезагружать, даже если пользователи вошли в систему.
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
Примечания:
/usr/lib/apt/apt.systemd.daily для получения подробной информации о параметрах APT::PeriodicUnattended-UpgradeВыполните пробный запуск unattended-upgrades, чтобы убедиться, что ваш конфигурационный файл корректен:
sudo unattended-upgrade -d --dry-run
Если всё в порядке, вы можете позволить ему запускаться по расписанию или принудительно запустить с помощью unattended-upgrade -d.
Настройте apt-listchanges по своему усмотрению:
sudo dpkg-reconfigure apt-listchanges
Для apticron настройки по умолчанию достаточно хороши, но вы можете проверить их в /etc/apticron/apticron.conf, если хотите изменить. Например, моя конфигурация выглядит так:
EMAIL="root" NOTIFY_NO_UPDATES="1"
WIP
WIP
WIP
Установите rng-tools.
В системах на основе Debian:
sudo apt-get install rng-tools
Теперь нужно указать аппаратное устройство, используемое для генерации случайных чисел, добавив это в /etc/default/rng-tools:
HRNGDEVICE=/dev/urandom
echo "HRNGDEVICE=/dev/urandom" | sudo tee -a /etc/default/rng-tools
Перезапустите службу:
sudo systemctl stop rng-tools.service
sudo systemctl start rng-tools.service
Проверьте случайность:
Хороший инструмент для добавления дополнительной защиты паролем от физических атак (лично) — методы вымогательства/ограбления/нападения.
pamduress добавит пользователю X вторичный пароль (панический пароль). Когда этот пароль совпадает, запускается скрипт (этот скрипт делает то, что вы хотите, чтобы пользователь делал при входе с ЭТИМ паническим паролем).
Практический и реальный пример: "Некий грабитель проникает в дом и крадёт сервер (содержащий ВАЖНЫЕ резервные копии бизнеса, личные воспоминания и т.д.). Никакого шифрования дисков/загрузки нет. Грабитель запускает сервер в своей 'безопасной зоне' и начинает атаку перебором. Он взломал локальный пароль по SSH с пользователя sudoer 'admin' успешно, да, слабый пароль, не надёжный/основной. Он начинает сессию SSH/физическую сессию с этим взломанным слабым/паническим паролем от пользователя sudoer 'admin'. Он начинает замечать, что сервер кажется слишком загруженным менее чем за 2 минуты, пока не зависает... 'что за чёрт?! давайте перезагрузим и продолжим красть информацию...' извини, друг. все данные и система были уничтожены.". Заключение: грабитель взломал слабый/панический/вторичный пароль, и с этим паролем связан скрипт, который удалит все файлы, конфигурацию, систему, загрузчик, а затем начнёт загружать RAM и CPU, чтобы вынудить грабителя перезагрузить систему.
Предотвратить доступ злоумышленника к информации сервера в случае получения пароля принудительным путём (нападение, оружие, выкуп). Конечно, это полезно и в других ситуациях.
cat > "$ScriptFile" <<-EOF #!/bin/bash sudo rm -rf /home
EOF ####################################################### } echo "Lets Config a PANIC PASSWORD ;)" && sleep 1 read -r -p "Want you REALLY configure A PANIC PASSWORD?? Write [ OK ] : " PAMDUR if [[ "$PAMDUR" = "OK" ]]; then echo "Lets Config a PANIC USER, PASSWORD and SCRIPT ;)" && sleep 1 while [ -z "$PANICUSR" ] do read -r -p "WRITE a Panic User to your pam-duress user [ root ]: " PANICUSR PANICUSR=${PANICUSR:=root} done if [ -z "$ScriptLoc" ]; then read -r -p "SET Script Directory with FULL PATH [ /root/.duress ]: " ScriptLoc ScriptLoc=${ScriptLoc:=/root/.duress} ScriptFile="$ScriptLoc/PanicScript.sh" fi else echo "NOT Use PAM DURESS aKa Panic Password!!! Bye" exit 1 fi
sudo apt install -y git build-essential libpam0g-dev libssl-dev
cd "$HOME" || exit 1 git clone https://github.com/nuvious/pam-duress.git cd pam-duress || exit 1 make sudo make install make clean #make uninstall
mkdir -p $ScriptLoc sudo mkdir -p /etc/duress.d myownscript duress_sign $ScriptFile chmod -R 500 $ScriptLoc chmod 400 $ScriptLoc/*.sha256 chown -R $PANICUSR $ScriptLoc
sudo cp --preserve /etc/pam.d/common-auth /etc/pam.d/common-auth.bck
echo " auth [success=2 default=ignore] pam_unix.so nullok_secure auth [success=1 default=ignore] pam_duress.so auth requisite pam_deny.so auth required pam_permit.so " | sudo tee /etc/pam.d/common-auth
read -r -p "Press Key to Finish PAM DURESS Script!" exit 0
([Содержание](#table-of-contents))
## Сеть
### Брандмауэр с UFW (Uncomplicated Firewall)
#### Зачем
Можете считать меня параноиком, и вы не обязаны соглашаться, но я хочу запретить весь входящий и исходящий трафик на моем сервере, кроме того, что я явно разрешаю. Зачем моему серверу отправлять трафик, о котором я не знаю? И зачем внешнему трафику пытаться получить доступ к моему серверу, если я не знаю, кто или что это? Когда речь идет о хорошей безопасности, я считаю, что лучше отклонять/запрещать по умолчанию, а разрешать в порядке исключения.
Конечно, если вы не согласны, это совершенно нормально, и вы можете настроить UFW под свои нужды.
В любом случае, обеспечение того, чтобы разрешался только явно нами разрешенный трафик — это задача брандмауэра.
#### Как это работает
Ядро Linux предоставляет возможности для мониторинга и управления сетевым трафиком. Эти возможности становятся доступны конечному пользователю через утилиты брандмауэра. В Linux самым распространенным брандмауэром является [iptables](https://en.wikipedia.org/wiki/Iptables). Однако iptables довольно сложен и запутан (на мой взгляд). Здесь на помощь приходит UFW. Думайте о UFW как о интерфейсе для iptables. Он упрощает процесс управления правилами iptables, которые сообщают ядру Linux, что делать с сетевым трафиком.
**UFW** работает, позволяя вам настраивать правила, которые:
- **разрешают** или **запрещают**
- **входящий** или **исходящий** трафик
- **на** или **с** портов
Вы можете создавать правила, явно указывая порты или с помощью конфигураций приложений, которые указывают порты.
#### Цели
- весь сетевой трафик, входящий и исходящий, заблокирован, кроме того, что мы явно разрешаем
#### Примечания
- По мере установки других программ, вам нужно будет включать необходимые порты/приложения.
#### Ссылки
- https://launchpad.net/ufw
#### Шаги
1. Установите ufw.
На системах на основе Debian:
``` bash
sudo apt install ufw
```
1. Запретите весь исходящий трафик:
``` bash
sudo ufw default deny outgoing comment 'deny all outgoing traffic'
```
> ```
> Default outgoing policy changed to 'deny'
> (be sure to update your rules accordingly)
> ```
Если вы не так параноидальны, как я, и не хотите запрещать весь исходящий трафик, вы можете его разрешить:
``` bash
sudo ufw default allow outgoing comment 'allow all outgoing traffic'
```
1. Запретите весь входящий трафик:
``` bash
sudo ufw default deny incoming comment 'deny all incoming traffic'
```
1. Очевидно, мы хотим разрешить SSH-подключения. Использование `limit` вместо `allow` автоматически заблокирует подключения с IP-адреса, если он попытается установить 6 или более подключений за 30-секундный интервал:
``` bash
sudo ufw limit in ssh comment 'allow SSH connections in'
```
> ```
> Rules updated
> Rules updated (v6)
> ```
1. Разрешите дополнительный трафик по вашему усмотрению. Некоторые распространенные примеры использования:
``` bash
# allow traffic out to port 53 -- DNS
sudo ufw allow out 53 comment 'allow DNS calls out'
# allow traffic out to port 123 -- NTP
sudo ufw allow out 123 comment 'allow NTP out'
# allow traffic out for HTTP, HTTPS, or FTP
# apt might needs these depending on which sources you're using
sudo ufw allow out http comment 'allow HTTP traffic out'
sudo ufw allow out https comment 'allow HTTPS traffic out'
sudo ufw allow out ftp comment 'allow FTP traffic out'
# allow whois
sudo ufw allow out whois comment 'allow whois'
# allow mails for status notifications -- choose port according to your provider
sudo ufw allow out 25 comment 'allow SMTP out'
sudo ufw allow out 587 comment 'allow SMTP out'
# allow traffic out to port 68 -- the DHCP client
# you only need this if you're using DHCP
sudo ufw allow out 67 comment 'allow the DHCP client to update'
sudo ufw allow out 68 comment 'allow the DHCP client to update'
```
**Примечание**: Вам нужно будет разрешить HTTP/HTTPS для установки пакетов и многих других вещей.
1. Запустите ufw:
``` bash
sudo ufw enable
```
> ```
> Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
> Firewall is active and enabled on system startup
> ```
1. Если хотите увидеть статус:
``` bash
sudo ufw status
```
> ```
> Status: active
>
> To Action From
> -- ------ ----
> 22/tcp LIMIT Anywhere # allow SSH connections in
> 22/tcp (v6) LIMIT Anywhere (v6) # allow SSH connections in
>
> 53 ALLOW OUT Anywhere # allow DNS calls out
> 123 ALLOW OUT Anywhere # allow NTP out
> 80/tcp ALLOW OUT Anywhere # allow HTTP traffic out
> 443/tcp ALLOW OUT Anywhere # allow HTTPS traffic out
> 21/tcp ALLOW OUT Anywhere # allow FTP traffic out
> Mail submission ALLOW OUT Anywhere # allow mail out
> 43/tcp ALLOW OUT Anywhere # allow whois
> 53 (v6) ALLOW OUT Anywhere (v6) # allow DNS calls out
> 123 (v6) ALLOW OUT Anywhere (v6) # allow NTP out
> 80/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTP traffic out
> 443/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTPS traffic out
> 21/tcp (v6) ALLOW OUT Anywhere (v6) # allow FTP traffic out
> Mail submission (v6) ALLOW OUT Anywhere (v6) # allow mail out
> 43/tcp (v6) ALLOW OUT Anywhere (v6) # allow whois
> ```
или
``` bash
sudo ufw status verbose
```
> ```
> Status: active
> Logging: on (low)
> Default: deny (incoming), deny (outgoing), disabled (routed)
> New profiles: skip
>
> To Action From
> -- ------ ----
> 22/tcp LIMIT IN Anywhere # allow SSH connections in
> 22/tcp (v6) LIMIT IN Anywhere (v6) # allow SSH connections in
>
> 53 ALLOW OUT Anywhere # allow DNS calls out
> 123 ALLOW OUT Anywhere # allow NTP out
> 80/tcp ALLOW OUT Anywhere # allow HTTP traffic out
> 443/tcp ALLOW OUT Anywhere # allow HTTPS traffic out
> 21/tcp ALLOW OUT Anywhere # allow FTP traffic out
> 587/tcp (Mail submission) ALLOW OUT Anywhere # allow mail out
> 43/tcp ALLOW OUT Anywhere # allow whois
> 53 (v6) ALLOW OUT Anywhere (v6) # allow DNS calls out
> 123 (v6) ALLOW OUT Anywhere (v6) # allow NTP out
> 80/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTP traffic out
> 443/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTPS traffic out
> 21/tcp (v6) ALLOW OUT Anywhere (v6) # allow FTP traffic out
> 587/tcp (Mail submission (v6)) ALLOW OUT Anywhere (v6) # allow mail out
> 43/tcp (v6) ALLOW OUT Anywhere (v6) # allow whois
> ```
7. Если нужно удалить правило
``` bash
sudo ufw status numbered
[...]
sudo ufw delete 3 #номер строки правила, которое вы хотите удалить
```
#### Приложения по умолчанию
ufw поставляется с некоторыми приложениями по умолчанию. Вы можете их увидеть с помощью:``` bash
sudo ufw app list
```
```
> ```
> Available applications:
> AIM
> Bonjour
> CIFS
> DNS
> Deluge
> IMAP
> IMAPS
> IPP
> KTorrent
> Kerberos Admin
> Kerberos Full
> Kerberos KDC
> Kerberos Password
> LDAP
> LDAPS
> LPD
> MSN
> MSN SSL
> Mail submission
> NFS
> OpenSSH
> POP3
> POP3S
> PeopleNearby
> SMTP
> SSH
> Socks
> Telnet
> Transmission
> Transparent Proxy
> VNC
> WWW
> WWW Cache
> WWW Full
> WWW Secure
> XMPP
> Yahoo
> qBittorrent
> svnserve
> ```
Чтобы получить подробную информацию о приложении, например, какие порты оно включает, введите:``` bash
sudo ufw app info [app name]
```
> ``` bash
> sudo ufw app info DNS
> ```
>
> ```
> Profile: DNS
> Title: Internet Domain Name Server
> Description: Internet Domain Name Server
>
> Port:
> 53
> ```
#### Пользовательское приложение
Если вы не хотите создавать правила, явно указывая номера портов, вы можете создать свои собственные конфигурации приложений. Для этого создайте файл в `/etc/ufw/applications.d`.
Например, вот что вы бы использовали для [Plex](https://support.plex.tv/articles/201543147-what-network-ports-do-i-need-to-allow-through-my-firewall/):``` bash
cat /etc/ufw/applications.d/plexmediaserver
```
> ```
> [PlexMediaServer]
> title=Plex Media Server
> description=This opens up PlexMediaServer for http (32400), upnp, and autodiscovery.
> ports=32469/tcp|32413/udp|1900/udp|32400/tcp|32412/udp|32410/udp|32414/udp|32400/udp
> ```
Затем вы можете включить его, как и любое другое приложение:```bash
sudo ufw allow plexmediaserver
```
([Содержание](#table-of-contents))
### Обнаружение и предотвращение вторжений iptables с помощью PSAD
#### Зачем
Даже если у вас есть брандмауэр, охраняющий ваши двери, всё равно возможны попытки грубой силы проникнуть через охраняемые двери. Мы хотим отслеживать всю сетевую активность, чтобы обнаруживать потенциальные попытки вторжения, такие как повторные попытки войти, и блокировать их.
#### Как это работает
Я не смогу объяснить это лучше, чем пользователь [FINESEC](https://serverfault.com/users/143961/finesec) с https://serverfault.com/ сделал на: https://serverfault.com/a/447604/289829.
> Fail2BAN просматривает файлы журналов различных приложений, таких как apache, ssh или ftp, и автоматически блокирует IP-адреса, проявляющие признаки вредоносной активности, например автоматические попытки входа. PSAD, с другой стороны, сканирует сообщения журнала iptables и ip6tables (обычно /var/log/messages), чтобы обнаруживать и при необходимости блокировать сканирование и другие виды подозрительного трафика, такие как DDoS или попытки определения отпечатков ОС. Использование обеих программ одновременно допустимо, так как они работают на разных уровнях.
И, поскольку мы уже используем [UFW](#ufw-uncomplicated-firewall), мы последуем отличным инструкциям от [netson](https://gist.github.com/netson) на https://gist.github.com/netson/c45b2dc4e835761fbccc, чтобы заставить PSAD работать с UFW.
#### Ссылки
- http://www.cipherdyne.org/psad/
- http://www.cipherdyne.org/psad/docs/config.html
- https://www.thefanclub.co.za/how-to/how-install-psad-intrusion-detection-ubuntu-1204-lts-server
- https://serverfault.com/a/447604/289829
- https://serverfault.com/a/770424/289829
- https://gist.github.com/netson/c45b2dc4e835761fbccc
- Спасибо [moltenbit](https://github.com/moltenbit) за обнаружение проблемы ([#61](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/61)) с `psadwatchd`.
#### Шаги
1. Установите psad.
В системах на основе Debian:
``` bash
sudo apt install psad
```
1. Сделайте резервную копию конфигурационного файла psad `/etc/psad/psad.conf`:
``` bash
sudo cp --archive /etc/psad/psad.conf /etc/psad/psad.conf-COPY-$(date +"%Y%m%d%H%M%S")
```
1. Просмотрите и обновите параметры конфигурации в `/etc/psad/psad.conf`. Обратите особое внимание на следующие:
|Настройка|Установить как
|--|--|
|[`EMAIL_ADDRESSES`](http://www.cipherdyne.org/psad/docs/config.html#EMAIL_ADDRESSES)|ваш(и) адрес(а) электронной почты|
|`HOSTNAME`|имя хоста вашего сервера|
|`EXPECT_TCP_OPTIONS`|`EXPECT_TCP_OPTIONS Y;`|
|`ENABLE_PSADWATCHD`|`ENABLE_PSADWATCHD Y;`|
|[`ENABLE_AUTO_IDS`](http://www.cipherdyne.org/psad/docs/config.html#ENABLE_AUTO_IDS)|`ENABLE_AUTO_IDS Y;`|
|`ENABLE_AUTO_IDS_EMAILS`|`ENABLE_AUTO_IDS_EMAILS Y;`|
Проверьте конфигурационный файл и документацию psad по адресу http://www.cipherdyne.org/psad/docs/config.html для получения дополнительных сведений.
1. <a name="psad_step4"></a>Теперь нам нужно внести некоторые изменения в ufw, чтобы он работал с psad: сообщить ufw, чтобы он регистрировал весь трафик, чтобы psad мог его анализировать. Для этого отредактируйте **два файла** и добавьте эти строки **в конце, но перед строкой COMMIT**.
Сделайте резервные копии:
``` bash
sudo cp --archive /etc/ufw/before.rules /etc/ufw/before.rules-COPY-$(date +"%Y%m%d%H%M%S")
sudo cp --archive /etc/ufw/before6.rules /etc/ufw/before6.rules-COPY-$(date +"%Y%m%d%H%M%S")
```
Отредактируйте файлы:
- `/etc/ufw/before.rules`
- `/etc/ufw/before6.rules`
И добавьте это **в конце, но перед строкой COMMIT**:
```
# log all traffic so psad can analyze
-A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
-A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
```
**Примечание**: Мы добавляем префикс журнала ко всем записям iptables. Это понадобится нам для [выделения журналов iptables в отдельный файл](#separate-iptables-log-file).
Например:
> ```
> ...
>
> # log all traffic so psad can analyze
> -A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
> -A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
>
> # don't delete the 'COMMIT' line or these rules won't be processed
> COMMIT
> ```
1. Теперь необходимо перезагрузить/перезапустить ufw и psad, чтобы изменения вступили в силу:
``` bash
sudo ufw reload
sudo psad -R
sudo psad --sig-update
sudo psad -H
```
1. Проанализируйте правила iptables на наличие ошибок:
``` bash
sudo psad --fw-analyze
```
> ```
> [+] Parsing INPUT chain rules.
> [+] Parsing INPUT chain rules.
> [+] Firewall config looks good.
> [+] Completed check of firewall ruleset.
> [+] Results in /var/log/psad/fw_check
> [+] Exiting.
> ```
**Примечание**: Если возникли какие-либо проблемы, вы получите электронное письмо с ошибкой.
1. Проверьте состояние psad:
``` bash
sudo psad --Status
```
> ```
> [-] psad: pid file /var/run/psad/psadwatchd.pid does not exist for psadwatchd on vm
> [+] psad_fw_read (pid: 3444) %CPU: 0.0 %MEM: 2.2
> Running since: Sat Feb 16 01:03:09 2019
>
> [+] psad (pid: 3435) %CPU: 0.2 %MEM: 2.7
> Running since: Sat Feb 16 01:03:09 2019
> Command line arguments: [none specified]
> Alert email address(es): root@localhost
>
> [+] Version: psad v2.4.3
>
> [+] Top 50 signature matches:
> [NONE]
>
> [+] Top 25 attackers:
> [NONE]
>
> [+] Top 20 scanned ports:
> [NONE]
>
> [+] iptables log prefix counters:
> [NONE]
>
> Total protocol packet counters:
>
> [+] IP Status Detail:
> [NONE]
>
> Total scan sources: 0
> Total scan destinations: 0
>
> [+] These results are available in: /var/log/psad/status.out
> ```
([Содержание](#table-of-contents))
### Обнаружение и предотвращение вторжений приложений с помощью Fail2Ban
#### Зачем
| Настройка | Допустимые значения | Пример | Описание | Примечания |
|---|
| AllowGroups | имя локальной группы UNIX | AllowGroups sshusers | группа, которой разрешён доступ по SSH | |
| ClientAliveCountMax | число | ClientAliveCountMax 3 | максимальное количество сообщений клиенту о поддержании активности без ответа | |
| ClientAliveInterval | число секунд | ClientAliveInterval 15 | тайм-аут в секундах перед запросом ответа | |
| ListenAddress | разделённый пробелами список локальных адресов |
| локальные адреса, которые sshd должен прослушивать | См. Issue #1 для важных деталей. |
| LoginGraceTime | число секунд | LoginGraceTime 30 | время в секундах до истечения времени входа | |
| MaxAuthTries | число | MaxAuthTries 2 | максимальное количество разрешённых попыток входа | |
| MaxSessions | число | MaxSessions 2 | максимальное количество открытых сессий | |
| MaxStartups | число | MaxStartups 2 | максимальное количество сессий входа | |
| PasswordAuthentication | yes или no | PasswordAuthentication no | разрешён ли вход с паролем | |
| Port | любой открытый/доступный номер порта | Port 22 | порт, который sshd должен прослушивать |
Обратитесь к man sshd_config для получения более подробной информации о значении этих настроек.