Базовая настройка безопасности Linux-систем

В этом руководстве будут рассмотрены базовые аспекты защиты операционных систем Debian / Ubuntu, CentOS / Fedora от несанкционированного доступа: установка прав пользователей, управление аутентификацией при удаленном подключении, настройка firewall и другие. Материал написан для людей, минимально знакомых с администрированием Linux, но может быть полезен и более опытным пользователям как инструмент самопроверки.

 

Содержание:

  1. Автообновления безопасности
  2. Добавление пользователя с ограниченными правами
  3. Безопасное подключение через SSH
  4. Конфигурация Fail2Ban для защиты SSH-подключений
  5. Настройка firewall
  6. Добавление, изменение и удаление правил iptables

 

Автообновления безопасности

Поддержание версий ПО в актуальном состоянии – один из основных способ обеспечения безопасности любой операционной системы. Обновления программного обеспечения, как правило, направлены не только на исправление обнаруженных багов, но и на устранение критических уязвимостей, ставших известными к моменту апдейта. Существуют аргументы за и против автоматических обновлений серверных ОС. По нашему мнению, риски сбоев в результате апдейтов можно свести к минимуму, если настроить систему только на автообновление безопасности. Тем не менее, решение зависит, в первую очередь, от специфики использования вами сервера.

Обратите внимание, что автоматические обновления применимы только в отношении пакетов, установленных из репозиториев, а не скомпилированных самостоятельно.

 

Добавление пользователя с ограниченными правами

Если к моменту чтения этого материала вы все еще подключаетесь к вашему серверу от имени пользователя root, обращаем ваше внимание на то, что он имеет неограниченные права на выполнение любых команд, даже если они приводят к критическим системным ошибкам. Рекомендуем создать пользователя с ограниченными правами и всегда работать через него. Задачи администрирования могут выполняться через sudo (substitute user and do) – временное повышение прав пользователя до уровня администратора.

 

Создание нового пользователя:

Debian/Ubuntu:

  1. Создайте пользователя, заменив 1cloud на желаемое имя и укажите пользовательский пароль в ответ на соответствующий запрос. Обратите внимание на то, что пароль вводится вслепую, т.е. вводимые символы не отображаются в командной строке. Для подтверждения введеного пароля используется клавиша Enter:
    adduser 1cloud
  2. Добавьте пользователя в группу sudo для наделения его правами суперпользователя:
    adduser 1cloud sudo

Теперь вы можете подключаться к вашему серверу от имени нового пользователя. Для выполнения команд, требующих прав администратора, используйте префикс sudo. Например:

sudo apt-get install htop

CentOS/Fedora:

  1. Создайте пользователя, заменив 1cloud на желаемое имя, и создайте пароль для его аккаунта:
    useradd 1cloud && passwd 1cloud
  2. Добавьте пользователя в группу wheel для передачи ему прав sudo:
    usermod –aG wheel 1cloud

Безопасное подключение через SSH

По умолчанию, для подключения к хосту по SSH используется аутентификация по паролю. Но есть более безопасный способ – вход по паре криптографических ключей. В этом случае вместо пароля используется закрытый ключ, который гораздо более устойчив к подбору методом грубой силы (brute-force).

Давайте создадим пару ключей для нового пользователя и настроим сервер на запрет SSH-аутентификации по паролю.

  1. Генерация пары ключей для аутентификации:
    Это действие должно выполняться на вашем локальном компьютере, а не на удаленном сервере. В процессе создания пары 4096-битных RSA ключей вам будет предложено указать пароль для доступа к ним. Вы можете оставить это поле пустым, но в таком случае не сможете использовать созданную пару ключей до сохранения ее в keychain-менеджер локального компьютера. Лучше защитить ваши ключи сложным паролем для обеспечения дополнительной безопасности.
    Linux / MacOS:
    Внимание! Если вы ранее уже сгенерировали пару RSA ключей, приведенная ниже команда перезапишет их, что может привести к потере доступа к другим хостам с использованием данных ключей. В случае наличия ранее созданных ключей, пропустите следующую команду. Для проверки наличия существующих ключей, выполните: ls ~/.ssh/id_rsa* Для генерации нового комплекта ключей введите: ssh-keygen –b 4096 Windows:
    Вы можете использовать утилиту PuTTY. Скачайте ее отсюда, распакуйте и запустите ssh-keygen.

    Выбираем ключ ssh-rsa и длину 2048 бит. Жмем «Generate».

    Ключ готов, заполняем кодовую фразу и комментарий к нему. Сохраняем приватный ключ как mykey.ppk и публичный как id_rsa.pub

  2. Загрузка публичного ключа на сервер:
    Замените 1cloud на имя пользователя-владельца ключа, а 1.1.1.1 на ip-адрес вашего сервера.
    Linux:
    С локального компьютера выполните: ssh-copy-id 1cloud@1.1.1.1 Mac OS:
    На сервере (войдя от имени пользователя-владельца ключа) выполните: mkdir –p ~/.ssh && sudo chmod –R 700 ~/.ssh/ Затем введите в терминале локального компьютера Mac: scp ~/.ssh/id_rsa.pub 1cloud@1.1.1.1:~/.ssh/authorized_keys Windows:
    Способ 1: Вы можете воспользоваться WinSCP. В окне входа введите ip-адрес вашего сервера, а также имя пользователя и пароль пользователя-владельца ключей. Нажмите Login.
    При успешном подключении вы увидите две секции: слева список локальных файлов, справа – файлы на удаленном сервере. В левой секции выберите файл созданного открытого ключа и нажмите «Загрузить» (Upload) в верхней панели. Укажите директорию на сервере, в которую вы хотите сохранить файл, заменив 1cloud на имя вашего пользователя: /home/1cloud/.ssh/authorized_keys Способ 2: Экспортируйте открытый ключ напрямую из PuTTY KeyGen в окно терминала Putty, в котором осуществлено подключение к удаленному серверу под соответствующим пользователем. Из этого терминала введите:
    mkdir ~/.ssh; nano ~/.ssh/authorized_keys Приведенная выше команда откроет пустой файл authorized_keys в текстовом редакторе. Скопируйте содержимое файла открытого ключа в созданный документ (обратите внимание, что вставка должна быть идентичной, одной строкой). Затем нажмите CTRL+X , Y , и Enter.
    Редактирование прав доступа к загруженному ключу.
    Последнее, что нужно сделать с загруженным ключом – предоставить требуемые разрешения. На сервере введите: sudo chmod 700 -R ~/.ssh && chmod 600 ~/.ssh/authorized_keys Группа команд выше добавляет дополнительный уровень безопасности, запрещая другим пользователям доступ к файлу ключа.
  3. Проверка соединения:
    Отключитесь от сервера и повторно подключитесь к нему. Теперь вход должен осуществляться по сгенерированной паре ключей. Если при их создании вы указывали пароль – введите его в ответ на соответствующий запрос.

Конфигурация службы SSH:

  1. Запрет ssh-подключения от имени root-пользователя:
    Это действие приведет к приему сервером ssh-подключений от всех пользователей, кроме root. Для получения прав суперпользователя после подключения к серверу используйте sudo в начале команды или переключитесь на root-пользователя командой su – или sudo –s
    На сервере откройте файл /etc/ssh/sshd_config
    Найдите параметр PermitRootLogin и замените его значение на no:
  2. Запрет ssh-аутентификации по паролю:
    Это действие отключит ssh-подлючение через ввод пароля – теперь каждый пользователь должен будет использовать пару ключей.
    Откройте файл /etc/ssh/sshd_config . В зависимости от Linux-дистрибутива, строка PasswordAuthentification может присутствовать в файле в закомментированном виде (# в начале строки) или отсутствовать – соответственно раскомментируйте или добавьте ее.
    Команда для Debian/Ubuntu: nano /etc/ssh/sshd_config
    ...
    PasswordAuthentication no
    Примечание: В случае, если вы подключаетесь к серверу с большого количества разных устройств, вы можете оставить аутентификацию по паролю включенной – тогда вход сможет осуществляться как по ключам, так и по паролям пользователей.
  3. Перезапустите ssh-демон для применения конфигурации
  4. Если ваш дистрибутив Linux использует systemctl (CentOS 7, Debian 8, Fedora, Ubuntu 15.10 и старше): sudo systemctl restart sshd Если дистрибутив использует System V или Upstart (CentOS 6, Debian 7, Ubuntu 14.04) sudo service ssh restart

 

Конфигурация Fail2Ban для защиты SSH-подключений:

Fail2Ban – утилита, блокирующая ssh-подключения с определенного ip-адреса при превышении установленного числа неверных попыток подключения с него. Так как реальный пользователь обычно не нуждается более чем в трех попытках для ввода верного пароля (в случае с ssh-ключами редко требуется больше одной попытки), «забрасывание» сервера большим количеством запросов может быть попыткой несанкционированного доступа.

Fail2Ban может осуществлять мониторинг различных протоколов, включая SSH, HTTP, FTP и SMTP. При стандартных настройках утилиты контролируется только SSH, так как этот протокол является уязвимым (постоянный прием сервером ssh-подключений с любого ip-адреса).

Примечение: если вы используете Linux-сервер, предоставленный сервисом 1cloud.ru, то пакет Fail2Ban уже предустановлен и контролирует ssh-активность. Информацию об установке и дополнительной конфигурации Fail2Ban вы найдете здесь.

Настройка Firewall

 

Использование фаервола для блокирования нежелательного входящего трафика на сервере – важнейший инструмент повышения уровня защищенности системы. Фильтрация трафика предотвращает различные типы вторжений, особенно из-за пределов вашей локальной сети. Рекомендуемый подход при настройке firewall – разрешить только действительно необходимый трафик и полностью запретить остальной.

Iptables – контроллер для netfilter, стандартного фрейморка фильтрации пакетов для Linux. Он включен в большинство дистрибутивов по умолчанию. Тем не менее, этот инструмент позиционируется, как средство расширенной настройки для опытных пользователей. К счастью, существует несколько дополнительных утилит, призванных упросить общение пользователя с iptables. Самые популярные из них: UFW для Debian/Ubuntu, FirewallD для Fedora. Возможно, эти решение являются более подходящими для реализации ваших задач.

В этой статье мы будем рассматривать настройку непосредственно самого iptables.

Просмотр действующих параметров iptables:

IPv4:

sudo iptables -L

IPv6:

sudo ip6tables -L

По умолчанию iptables разрешает все входящие, исходящие и переадресованные подключения:

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Базовая конфигурация iptables:

Конкретные правила фаервола зависят от сервисов, используемых на вашем сервере. Ниже приведен пример правил, подразумевающих использование вами веб-сервера. Прежде, чем применять правила iptables, спланируйте их исходя из вашей вашей конфигурации:

IPv4 (файл /tmp/v4):

*filter
# Allow all loopback (lo0) traffic and reject traffic
# to localhost that does not originate from lo0.
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT

# Allow ping.
-A INPUT -p icmp -m state --state NEW --icmp-type 8 -j ACCEPT

# Allow SSH connections.
-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

# Allow HTTP and HTTPS connections from anywhere
# (the normal ports for web servers).
-A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT
-A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT

# Allow inbound traffic from established connections.
# This includes ICMP error returns.
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Log what was incoming but denied (optional but useful).
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables_INPUT_denied: " --log-level 7

# Reject all other inbound.
-A INPUT -j REJECT

# Log any traffic that was sent to you
# for forwarding (optional but useful).
-A FORWARD -m limit --limit 5/min -j LOG --log-prefix "iptables_FORWARD_denied: " --log-level 7

# Reject all traffic forwarding.
-A FORWARD -j REJECT

COMMIT

IPv6 (/tmp/v6):

*filter

# Allow all loopback (lo0) traffic and reject traffic
# to localhost that does not originate from lo0.
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s ::1/128 -j REJECT

# Allow ICMP
-A INPUT -p icmpv6 -j ACCEPT

# Allow HTTP and HTTPS connections from anywhere
# (the normal ports for web servers).
-A INPUT -p tcp --dport 80 -m state --state NEW -j ACCEPT
-A INPUT -p tcp --dport 443 -m state --state NEW -j ACCEPT

# Allow inbound traffic from established connections.
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Log what was incoming but denied (optional but useful).
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "ip6tables_INPUT_denied: " --log-level 7

# Reject all other inbound.
-A INPUT -j REJECT

# Log any traffic that was sent to you
# for forwarding (optional but useful).
-A FORWARD -m limit --limit 5/min -j LOG --log-prefix "ip6tables_FORWARD_denied: " --log-level 7

# Reject all traffic forwarding.
-A FORWARD -j REJECT

COMMIT

 

Применение приведенных выше правил на различных дистрибутивах Linux:

Arch Linux:

  1. Создайте файлы /etc/iptables/iptables.rules и /etc/iptables/ip6tables.rules . Вставьте правила из примеров выше (/tmp/v4 и /tmp/v4) в созданные документы соответственно.
  2. Импортируйте эти правила для немедленного применения iptables: sudo iptables-restore < /etc/iptables/iptables.rules sudo ip6tables-restore < /etc/iptables/ip6tables.rules
  3. По умолчанию в Arch iptables не запущен. Запустите его: sudo systemctl start iptables && sudo systemctl start ip6tables sudo systemctl enable iptables && sudo systemctl enable ip6tables
  4. Используйте конфигурацию pre-network.conf с ArchWiki чтобы iptables стартовал до подключения сервера к сети.

CentOS / Fedora:

Примечание: применяемые правила хранятся в файлах /etc/sysconfig/iptables и /etc/sysconfig/ip6tables

В этих дистрибутивах FirewallD предлагается для управления правилами фаервола вместо непосредственного администрирования iptables.

CentOS 6 / Fedora 19 и ниже:

sudo service iptables save
sudo service ip6tables save

Создайте файлы /tmp/v4 и /tmp/v6. Вставьте содержимое приведенных выше примеров (/tmp/v4 и /tmp/v6) в созданные документы.

Импортируйте правила из этих временных файлов:

sudo iptables-restore < /tmp/v4
sudo ip6tables-restore < /tmp/v6

Сохраните параметры.

CentOS 7 / Fedora 20 и выше:

Debian / Ubuntu:

Вы можете управлять iptables вручную или использовать утилиту UFW. Ниже рассмотрен первый вариант:

  1. Создайте файлы /tmp/v4 и /tmp/v6 . Вставьте содержимое приведенных выше примеров (/tmp/v4 и /tmp/v6) в созданные документы.
  2. Импортируйте добавленные правила для их немедленного применения:
    sudo iptables-restore < /tmp/v4 sudo ip6tables-restore < /tmp/v6
  3. Пакет iptables-persistent автоматизирует загрузку правил iptables при запуске Debian/Ubuntu сервера. Установите его из репозиториев:
    sudo apt-get install iptables-persistent Ответьте yes в ответ на появляющиеся запросы о сохранении текущих правил фаервола.

Проверка правил iptables

Проверьте правила фаервола вашего сервера на применение внесенных изменений:

В результате должны отобразиться следующие правила:

IPv4:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo any anywhere anywhere
0 0 REJECT all -- !lo any loopback/8 anywhere reject-with icmp-port-unreachable
0 0 ACCEPT icmp -- any any anywhere anywhere icmp destination-unreachable
0 0 ACCEPT icmp -- any any anywhere anywhere icmp echo-request
0 0 ACCEPT icmp -- any any anywhere anywhere icmp time-exceeded
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:ssh state NEW
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:http state NEW
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:https state NEW
0 0 ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED
0 0 LOG all -- any any anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables_INPUT_denied: "
0 0 REJECT all -- any any anywhere anywhere reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 LOG all -- any any anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "iptables_FORWARD_denied: "
0 0 REJECT all -- any any anywhere anywhere reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination

IPv6:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all lo any anywhere anywhere
0 0 REJECT all !lo any localhost anywhere reject-with icmp6-port-unreachable
0 0 ACCEPT ipv6-icmp any any anywhere anywhere
0 0 ACCEPT tcp any any anywhere anywhere tcp dpt:http state NEW
0 0 ACCEPT tcp any any anywhere anywhere tcp dpt:https state NEW
0 0 ACCEPT all any any anywhere anywhere state RELATED,ESTABLISHED
0 0 LOG all any any anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "ip6tables_INPUT_denied: "
0 0 REJECT all any any anywhere anywhere reject-with icmp6-port-unreachable

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 LOG all any any anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix "ip6tables_FORWARD_denied: "
0 0 REJECT all any any anywhere anywhere reject-with icmp6-port-unreachable

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
  1. Перезагрузите сервер: sudo reboot
  2. Введите эти команды для отображения действующих правил: sudo iptables -vL
    sudo ip6tables –vL

Теперь мы убедились в том, что добавленные правила firewall активны. В дальнейшем при установке новых пакетов, требующих доступ к сети, не забудьте внести соответствующие изменения в конфигурацию iptables.

 

Добавление, изменение и удаление правил iptables

Правила iptables работают последовательно от первого к последнему. Это означает, что добавление новых правил не может осуществляться с помощью команд. iptables –A ip6tables –A Для этого необходимо использовать: iptables –I или ip6tables –I

Добавление правил:

Добавляемые правила должны размещаться в последовательном порядке с учетом других правил в цепочке. Для отображения нумерованного списка правил введите:

sudo iptables –L –line-numbers

Допустим, мы хотим добавить новое правило в приведенный выше пример (/tmp/v4) для разрешения входящих подключений на порту 8080 TCP. Добавим его на позицию 9 цепочки INPUT:

sudo iptables -I INPUT 9 -p tcp --dport 8080 -j ACCEPT

Замена правил:

Процедура замены правил очень похожа на их добавление, но для этого используется команда: iptables –R Предположим, вы хотите изменить параметр сохранения списка заблокированных подключений в лог с пяти записей в минуту до трех, а правило LOG находится на 11-й позиции цепочки INPUT. Соответствующая команда будет выглядеть следующим образом:

sudo iptables -R INPUT 11 -m limit --limit 3/min -j LOG --log-prefix "iptables_INPUT_denied: " --log-level 7

Удаление правил:

Удаление правил iptables также происходит с указанием номера позиции удаляемого правила. Например, чтобы удалить параметр, который мы ранее добавляли (см. выше) для разрешения подключений на порту 8080 TCP, необходимо ввести команду:

sudo iptables -D INPUT 9

Важно: измененные правила не вступают в силу автоматически. Для их применения совершите действия в соответствии с процедурой, используемой для вашего дистрибутива Linux (см. пункт «Базовая конфигурация iptables»).

На этом базовую конфигурацию инструментов обеспечения безопасности вашего Linux-сервера можно считать завершенной, но тему нельзя считать исчерпанной – в наших будущих материалах мы будем рассматривать и другие способы повышения уровня безопасности Linux-систем.

P. S. Другие инструкции:

Последнее обновление: 12.09.2022