Шаги по защите нашего VPS

В этом руководстве показано, как подготовить и защитить виртуальный частный сервер (VPS) с помощью Debian GNU / Linux. Перед началом предполагается несколько вещей:

  1. У вас средний уровень знакомства с GNU / Linux.
  2. Существует VPS для личного пользования, к которому у нас есть доступ через SSH.
  3. VPS имеет выделенный внешний IPv4 250.250.250.155, а наш провайдер владеет блоком 250.250.0.0/16. (1)
  4. На нашем VPS у нас будут только службы http, https и ssh для доступа извне.
  5. Внешний DNS не будет включен, так как обычно это делается в панели нашего провайдера. (2)
  6. Он будет работать как суперпользователь.

Установка

В качестве первого шага давайте обновим сервер и установим несколько пакетов, которые нам понадобятся:

# aptitude update & aptitude safe-upgrade # aptitude -RvW install dropbear gesftpserver sslh iptables-persistent ulogd fail2ban nginx-light apache2-utils dnsutils telnet ghostscript poppler-utils zip unzip unrar-free p7zip-fullc multitail tee

конфигурация

Теперь создадим рабочего пользователя. Работа с правами root на сервере небезопасна, поэтому сначала создадим специального пользователя:

оператор adduser usermod -aG оператор sudo

Первая команда создает пользователя-оператора, вторая добавляет его в группу Sudo, что позволит запускать приложения с правами root.

Настройте разрешения для суперпользователей

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

visudo

Эта команда в основном позволяет изменять файл / и т.д. / sudoers; в котором мы должны содержать эти строки:

По умолчанию env_reset, timestamp_timeout = 0% sudo ALL = (ALL: ALL) ALL

В первой строке опция добавляется к значениям по умолчанию timestamp_timeout который позволяет вам установить время истечения (в минутах) пароля при выполнении команды sudo. По умолчанию установлено 5, но иногда это небезопасно по двум причинам:

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

Поэтому, чтобы избежать рисков, мы установили значение равным нулю, то есть каждый раз при выполнении команды sudo необходимо будет вводить пароль. Если отрицательное значение установлено как -1, то в результате срок действия пароля никогда не истечет, что приведет к результату, противоположному желаемому.

Во второй строке поясняется, что группа sudo может выполнять любую команду на любом компьютере, что обычно, хотя ее можно настроить. (3) Есть те, кто для удобства ставит строку следующим образом, чтобы не вводить пароль:

% sudo ALL = (ВСЕ: ВСЕ) NOPASSWD: ALL

Однако, как мы объясняли ранее, это рискованно и поэтому не рекомендуется.

Отключить перезапуск

В целях безопасности мы также отключим перезапуск с помощью комбинации клавиш Ctrl + Alt + Del, для чего мы должны добавить эту строку в файл / И т.д. / inittab:

ca: 12345: ctrlaltdel: / bin / echo "Ctrl + Alt + Del отключен."

Замените OpenSSH на DropBear

Большинство VPS поставляется с установленным OpenSSH, что, безусловно, очень полезно, но если нам не нужно использовать все функциональные возможности OpenSSH, есть более легкие альтернативы для VPS, такие как Медвежонок, которого обычно достаточно для регулярного использования. Однако недостатком этого приложения является то, что оно не имеет встроенного SFTP-сервера, поэтому вначале мы установили пакет гесфтпсервер.

Для настройки Dropbear внесем изменения в файл / и т.д. / по умолчанию / dropbear так что он содержит эти две строки:

NO_START = 0 DROPBEAR_EXTRA_ARGS = "- w -p 127.0.0.1:22 -I 1200 -m"

Первая строка просто включает службу, а вторая выполняет несколько действий:

  1. Избегайте корневого доступа.
  2. Это заставляет службу прослушивать порт 22 локального интерфейса (почему мы объясним позже).
  3. Устанавливает время ожидания (20 минут).

SSLH

Порт 22 (SSH) хорошо известен и обычно является одним из первых, которые пытаются взломать хакеры, поэтому вместо этого мы будем использовать порт 443 (SSL). Бывает, что этот порт используется для безопасного просмотра по HTTPS.

По этой причине мы будем использовать пакет sslh, который представляет собой не что иное, как мультиплексор, который анализирует пакеты, поступающие на порт 443, и направляет их внутри той или иной службы в зависимости от типа трафика - SSH или SSL.

SSLH не может прослушивать интерфейс, который уже прослушивается другой службой, поэтому ранее мы заставляли Dropbear прослушивать локальный интерфейс.

Теперь нам нужно указать sslh интерфейс и порт, через который он должен прослушивать и куда перенаправлять пакеты в зависимости от типа службы, и для этого мы изменим файл конфигурации. / и т.д. / по умолчанию / sslh:

DAEMON = / usr / sbin / sslh DAEMON_OPTS = "- пользовательский sslh --listen 250.250.250.155:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:443 --pidfile / var / run / sslh / sslh .pid "RUN = да

Наконец, перезапускаем службы:

остановка службы ssh && запуск службы dropbear && перезапуск службы sslh

После выполнения предыдущей команды наш безопасный сеанс, вероятно, будет прерван, и в этом случае достаточно снова войти в систему, но на этот раз с рабочим пользователем и с использованием порта 443. Если сеанс не прерывается, рекомендуется закрыть его и начать заново. с соответствующими значениями.

Если все работает правильно, мы можем продолжить работу как root и, если захотим, удалить OpenSSH:

sudo su - aptitude -r очистить openssh-server

межсетевые экраны

Следующее, что мы сделаем, это разделим логи брандмауэра в отдельный файл. /var/log/firewall.log для облегчения дальнейшего анализа, поэтому мы установили пакет ulogd при запуске. Для этого отредактируем файл /etc/logd.conf для настройки соответствующего раздела:

[LOGEMU] file = "/ var / log / firewall.log" sync = 1

Далее мы изменим файл ротации записей / и т.д. / logrotate / ulogd вести ежедневную ротацию (с датой) и сохранять сжатые залпы в каталоге / вар / журнал / ulog /:

/var/log/ulog/*.log /var/log/firewall.log {daily dateext missingok compress delaycompress sharedscripts создать 640 root adm postrotate /etc/init.d/ulogd reload mv /var/log/firewall.log-* .gz / var / log / ulog /ndscript}

Затем мы создадим правила netfilter, выполнив следующие действия:

IPT = $ (который iptables) IPEXT = 250.250.250.155 IPEXTBLK = 250.250.0.0 / 16 IPBCAST = 255.255.255.255 $ IPT -F $ IPT -X $ IPT -Z $ IPT -A INPUT -i lo -j ACCEPT $ IPT - P INPUT DROP $ IPT -P FORWARD DROP $ IPT -P OUTPUT ACCEPT $ IPT -A INPUT -m state --state INVALID -j ULOG --ulog-prefix IN_INVALID $ IPT -A INPUT -p igmp -j ULOG --ulog -prefix IN_IGMP $ IPT -A INPUT -m pkttype --pkt-type broadcast -j ULOG --ulog-prefix IN_BCAST $ IPT -A INPUT -m pkttype --pkt-type multicast -j ULOG --ulog-prefix IN_MCAST $ IPT -A ВПЕРЕД -j ULOG --ulog-prefix FORWARD $ IPT -N ICMP_IN $ IPT -A INPUT!  -i lo -p icmp -j ICMP_IN $ IPT -A ICMP_IN -p icmp -f -j ULOG --ulog-prefix IN_ICMP_FRAGMENTED $ IPT -A ICMP_IN -p icmp -m icmp -m length!  --length 28: 1322 -j ULOG --ulog-prefix IN_ICMP_INVALIDSIZE $ IPT -A ICMP_IN -p icmp -m icmp -m hashlimit --hashlimit-above 4 / sec --hashlimit-mode srcip --hashlimit-srcmask 24 - -hashlimit-name icmpflood -j ULOG --ulog-prefix IN_ICMP_FLOOD $ IPT -A ICMP_IN -p icmp -m icmp -m hashlimit --hashlimit-upto 64kb / min --hashlimit-mode srcip --hashlimit-srcmask 24 - hashlimit-name icmpattack -j ULOG --ulog-prefix IN_ICMP_FLOOD $ IPT -A ICMP_IN -p icmp -m icmp -m u32!  --u32 "0x4 & 0x3fff = 0x0" -j ULOG --ulog-prefix IN_ICMP_ATTACK $ IPT -A ICMP_IN -p icmp -m icmp!  --icmp-type echo-request -m state --state NEW -j ULOG --ulog-prefix IN_ICMP_INVALID $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type echo-request -j ULOG --ulog- префикс IN_ICMP $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type echo-request -m limit --limit 1 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type echo-reply -m limit --limit 2 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type destination-unreachable -m limit - limit 2 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type time-exceeded -m limit --limit 2 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -p icmp -m icmp --icmp-type параметр-проблема -m limit --limit 2 / sec --limit-burst 4 -j ACCEPT $ IPT -A ICMP_IN -j RETURN $ IPT -N UDP_IN $ IPT -ВХОД!  -i lo -p udp -j UDP_IN $ IPT -A UDP_IN!  -и вот!  -p udp -f -j ULOG --ulog-prefix IN_UDP_FRAGMENTED $ IPT -A UDP_IN -p udp -m udp --sport 53 -m length!  --length 28: 576 -j ULOG --ulog-prefix IN_UDP_DNS_INVALIDSIZE $ IPT -A UDP_IN -p udp -m udp --dport 53 -m -state --state NEW -j ULOG --ulog-prefix IN_UDP_DNSREQUEST $ IPT - A UDP_IN -p udp -m udp --dport 53 -m -state --state NEW -j REJECT --reject-with icmp-port-unreachable $ IPT -A UDP_IN -p udp -m udp!  --спорт 53!  -s $ IPEXTBLK!  -d $ IPBCAST -m state --state NEW -j ULOG --ulog-prefix IN_UDP $ IPT -A UDP_IN -p udp -m udp -m state --state ESTABLISHED, RELATED -j ACCEPT $ IPT -A UDP_IN -j RETURN $ IPT -N TCP_IN $ IPT -A INPUT!  -i lo -p tcp -j TCP_IN $ IPT -A TCP_IN!  -и вот!  -p tcp -f -j ULOG --ulog-prefix IN_TCP_FRAGMENTED $ IPT -A TCP_IN -p tcp -m tcp --sport 53 -m state --state ESTABLISHED, RELATED -m length!  --length 513: 1500 -j ULOG --ulog-prefix IN_TCP_DNS_INVALIDSIZE $ IPT -A TCP_IN -p tcp -m tcp --dport 53 -m state --state NEW -j ULOG --ulog-prefix IN_TCP_DNS $ IPT -A TCP_IN -p tcp -m tcp --dport 53 -m state --state NEW -j REJECT --reject-with icmp-port-unreachable $ IPT -A TCP_IN -p tcp -m tcp -m multiport!  --dports 80,443 -m состояние --state NEW -j ULOG --ulog-prefix IN_TCP $ IPT -A TCP_IN -p tcp -m tcp -m multiport --dports 80,443 -m state --state NEW -m hashlimit - hashlimit-upto 4 / sec --hashlimit-burst 16 --hashlimit-mode srcip --hashlimit-name navreq -j ACCEPT $ IPT -A TCP_IN -p tcp -m tcp -m multiport --dports 80,443 -m state - состояние УСТАНОВЛЕНО -m connlimit!  --connlimit-above 16 -j ACCEPT $ IPT -A TCP_IN -p tcp -m tcp -m multiport! 

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

Не все VPS позволяют установку дополнительных модулей для netfilter, но очень полезным является PSD, что позволяет избежать сканирования портов. К сожалению, этот модуль по умолчанию не интегрирован в netfilter, поэтому необходимо установить определенные пакеты, а затем собрать модуль:

aptitude -RvW install iptables-dev xtables-addons-source модуль-помощник модуля-помощника --verbose --text-mode auto-install xtables-addons-source

Как только все вышеизложенное будет сделано, мы можем добавить такое правило:

iptables -A INPUT -m psd --psd-weight-threshold 15 --psd-delay-threshold 2000 --psd-lo-port-weight 3 --psd-hi-ports-weight 1 -j ULOG --ulog- префикс IN_PORTSCAN

Предыдущее правило в основном означает, что мы создадим счетчик, который будет увеличиваться на 3 при каждой попытке доступа к порту ниже 1024 и на 1 каждый раз, когда делается попытка доступа к порту выше 1023, и когда этот счетчик достигает 15 дюймов. менее 20 секунд, пакеты будут зарегистрированы улог как попытка сканирования портов. Пакеты все равно можно отбросить сразу, но в этом случае мы намерены использовать fail2ban, который мы настроим позже.

После создания правил мы должны принять определенные меры, чтобы сделать их постоянными, иначе мы потеряем их при перезапуске сервера. Есть несколько способов добиться этого; В этом руководстве мы будем использовать пакет iptables-persistent, который мы установили в начале, который хранит правила в /etc/iptables/rules.v4 y /etc/iptables/rules.v6 для ipv6.

iptables-save> /etc/iptables/rules.v4

Фактически, хотя использование ipv6 на Кубе еще не получило широкого распространения, мы вполне могли бы создать несколько основных правил:

IPT = $ (which ip6tables) $ IPT -P INPUT DROP $ IPT -P FORWARD DROP $ IPT -P OUTPUT ACCEPT $ IPT -A INPUT -i lo -j ACCEPT $ IPT -A INPUT! -i lo -m state --state ESTABLISHED, RELATED -j ACCEPT unset IPT

Эти правила также можно сделать постоянными:

ip6tables-save> /etc/iptables/rules.v6

Наконец, для большей безопасности мы очищаем реестр брандмауэра и перезапускаем службы:

echo -n> /var/log/firewall.log служба logrotate перезапуск службы ulogd перезапуск службы iptables-persistent restart

Nginx

Мы будем использовать Nginx в качестве веб-сервера, потому что VPS, как правило, имеют меньший объем оперативной памяти по сравнению с реальным сервером, поэтому обычно удобно иметь что-то более легкое, чем Apache.

Перед настройкой Nginx мы создадим сертификат (без пароля) для использования по HTTPS:

cd / etc / nginx openssl genrsa -des3 -out cert.key 4096 cp -v cert.key cert.key.original openssl req -new -key cert.key -out cert.csr openssl rsa -in cert.key.original - вне cert.key openssl x509 -req -days 365 -in cert.csr -signkey cert.key -out cert.crt

Как только это будет сделано, мы создадим файл паролей для пользователя elusuario:

htpasswd -c .htpasswd пользователь

Далее мы изменим файл / и т.д. / nginx / сайты-доступные / по умолчанию , чтобы установить настройки сайта по умолчанию. Это могло выглядеть так:

сервер {server_name localhost; index index.html index.htm default.html default.htm; корень / вар / www; location / {# устанавливаем порядок проверки и страницу для загрузки, если URI не найден try_files $ uri $ uri / /index.html; }} сервер {слушайте 127.0.0.1:443; server_name localhost; index index.html index.htm default.html default.htm; корень / вар / www; ssl включен; ssl_certificate cert.crt; ssl_certificate_key cert.key; ssl_session_timeout 5 мин; # Включить HTTPS только через TLS (более безопасный, чем SSL) ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # отдавать предпочтение высоконадежным [HIGH] шифрам, # перемещать средние [MEDIUM] шифры в конец списка, # отключать низкоуровневые [LOW] шифры (40 и 56 бит) # отключать шифры с помощью алгоритмы экспорта [EXP] # отключить нулевые шифры [eNULL], без аутентификации [aNULL], SSL (версии 2 и 3) и DSS (разрешены только ключи длиной до 1024 бит) ssl_ciphers HIGH: + MEDIUM :! LOW :! EXP: ! aNULL :! eNULL :! SSLv3 :! SSLv2 :! DSS; # Предпочитать методы шифрования сервера (по умолчанию используются клиентские) ssl_prefer_server_ciphers on; location / {# enable authentication auth_basic "Login"; auth_basic_user_file /etc/nginx/.htpasswd; # установить порядок проверки и код страницы для загрузки, если URI try_files $ uri $ uri / = 404 не найден; # разрешить создание индекса для аутентифицированных пользователей autoindex on; autoindex_exact_size выключен; autoindex_localtime on; }}

Проверяем правильность конфигурации:

nginx -t

Наконец, перезапускаем службу:

перезагрузка службы nginx

Fail2Ban

Перед тем как приступить к настройке Fail2Ban, для большей безопасности останавливаем службу и очищаем реестр:

fail2ban-client остановить эхо -n> /var/log/fail2ban.log

Далее мы создаем файл конфигурации /etc/fail2ban/jail.local со следующим настраиваемым содержимым:

# Пользовательский файл конфигурации /etc/fail2ban/jail.local # [ПО УМОЛЧАНИЮ] findtime = 43200; 12 часов bantime = 86400; 1 день maxretry = 3; запрет вступит в силу после 4-й попытки [ssh] enabled = false [nginx-auth] enabled = true filter = nginx-auth action = iptables-multiport [name = NoAuthFailures, port = "http, https"] logpath = / var / log / nginx * / * ошибка * .log [nginx-badbots] enabled = true filter = apache-badbots action = iptables-multiport [name = BadBots, port = "http, https"] logpath = / var / log / nginx * /*access*.log bantime = 604800; 1 неделя maxretry = 0 [nginx-login] enabled = true filter = nginx-login action = iptables-multiport [name = NoLoginFailures, port = "http, https"] logpath = / var / log / nginx * / * доступ *. журнал bantime = 1800; 30 минут [nginx-noscript] enabled = true action = iptables-multiport [name = NoScript, port = "http, https"] filter = nginx-noscript logpath = /var/log/nginx*/*access*.log maxretry = 0 [nginx-proxy] enabled = true action = iptables-multiport [name = NoProxy, port = "http, https"] filter = nginx-proxy logpath = /var/log/nginx*/*access*.log bantime = 604800 ; 1 неделя maxretry = 0 [firewall] enabled = true action = iptables-multiport [name = Firewall] filter = firewall logpath = /var/log/firewall.log maxretry = 0

Как только это будет сделано, мы создадим в каталоге /etc/fail2ban/filters.d/ следующие файлы:

# /etc/fail2ban/filter.d/nginx-auth.conf # Фильтр аутентификации # Блокирует IP-адреса, не прошедшие аутентификацию с использованием базовой аутентификации # [Определение] failregex = для базовой аутентификации не указан пользователь / пароль. * клиент: user. * не найден в. * client: пользователь. * несоответствие пароля. * клиент: ignoreregex =
# /etc/fail2ban/filter.d/nginx-login.conf # Фильтр входа в систему # Блокирует IP-адреса, не прошедшие аутентификацию с использованием страницы входа веб-приложения # Сканировать журнал доступа для HTTP 200 + POST / sessions => неудачный вход в систему # [Определение ] failregex = ^ -. * POST / sessions HTTP / 1 \ .. "200 ignoreregex =
# /etc/fail2ban/filter.d/nginx-noscript.conf # Фильтр Noscript # Блокировать IP-адреса, пытающиеся выполнить сценарии, такие как .php, .pl, .exe и другие забавные сценарии. # Соответствует, например, # 192.168.1.1 - - "GET /something.php # [Определение] failregex = ^ -. * GET. * (\. Php | \ .asp | \ .exe | \ .pl | \ .cgi | \ scgi) ignoreregex =
# /etc/fail2ban/filter.d/proxy.conf # Фильтр прокси # Блокировать IP-адреса, пытающиеся использовать сервер в качестве прокси. # Соответствует, например, # 192.168.1.1 - - "GET http://www.something.com/ # [Определение] failregex = ^ -. * ПОЛУЧИТЬ http. * Ignoreregex =
# /etc/fail2ban/filter.d/firewall.conf # Фильтр межсетевого экрана # [Определение] failregex = ^. * IN_ (INVALID | PORTSCAN | UDP | TCP |). * SRC = . * $ ignoreregex =

Наконец, мы запускаем службу и загружаем конфигурацию:

fail2ban-service -b fail2ban-client reload

Проверка

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

Если учетная запись электронной почты не настроена на VPS, рекомендуется отключить предупреждающее сообщение, которое появляется при запуске многоадресной связи, для чего мы выполним следующую команду:

echo "check_mail: 0"> ~ / .multitailrc

Фактически, мы могли бы создать псевдоним (4) для быстрого просмотра журналов с помощью короткой команды, например, "flog":

псевдоним flog = 'multitail --follow-all /var/log/firewall.log /var/log/fail2ban.log'

1) Это фиктивные ценности.
2) Включить другие службы легко, если вы поймете, как они работают.
3) Для получения дополнительных сведений запустите man sudoers.
4) При желании можно добавить в файл ~ / .bash_aliases


Оставьте свой комментарий

Ваш электронный адрес не будет опубликован. Обязательные для заполнения поля помечены *

*

*

  1. Ответственный за данные: Мигель Анхель Гатон
  2. Назначение данных: контроль спама, управление комментариями.
  3. Легитимация: ваше согласие
  4. Передача данных: данные не будут переданы третьим лицам, кроме как по закону.
  5. Хранение данных: база данных, размещенная в Occentus Networks (ЕС)
  6. Права: в любое время вы можете ограничить, восстановить и удалить свою информацию.

  1.   MSX сказал

    Есть кое-что интересное, +1

  2.   Юкитеру сказал

    @Hugo эта строка в конфигурации:

    ssl_protocols SSLv3 TLSv1;

    Я бы удалил из него SSLv3, потому что этот протокол больше не является безопасным, даже в Debian Jessie многие службы были настроены так, чтобы избегать использования этого протокола по этой причине.

    Информация по теме здесь:

    https://www.linode.com/docs/security/security-patches/disabling-sslv3-for-poodle
    http://disablessl3.com/

    1.    Хьюго сказал

      На самом деле идея заключалась не в том, чтобы предлагать основные службы через HTTPS, а в том, чтобы объяснить, как использовать порт 443 для SSH, не теряя возможности использовать его для HTTPS, если это необходимо, но спасибо за предупреждение.

      В любом случае я обновил статью, чтобы немного изменить конфигурацию nginx и, кстати, включить некоторые комментарии, чтобы немного прояснить ситуацию с этим механизмом шифрования и исправить некоторые незначительные ошибки.

  3.   Даниэль П.З. сказал

    Спасибо большое за этот замечательный мастер-класс, теперь буду применять его на практике! :D, так держать DesdeLinux, они меня всегда удивляют, Привет из Перу.

  4.   Andekuera сказал

    Большое спасибо за обмен.

  5.   Фернандо сказал

    очень хорошее руководство, и теперь, когда я начал вести блог, он приходит ко мне как жемчуг, но тем более сейчас, когда я собираюсь установить свой первый vps, и даже со многими проблемами, но эта статья избавила меня от многих сомнений, спасибо и привет