Pull to refresh

CodingFuture + Puppet. Часть VI: актуальные чёрные списки и защищённый стук

Reading time 7 min
Views 4.9K

use cases


Вкратце:


  1. Защита сервисов и открытие портов по стуку криптографически стойким и не воспроизводимым Single Packet Authorization (SPA) с fwknop 2.6.9+.
  2. Динамически настраиваемое обновление чёрных списков с All Cybercrime IP Feeds by FireHOL.
  3. Полноценная поддержка ipset в cfnetwork.
  4. Поддержка собственных чёрных списков.
  5. Типичные варианты применения.


Тематический цикл:



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


Port-knocking или открытие доступа через "простукивание" портов


Предназначение


Любой публично доступный сервис априори подвержен взлому или просто отказу в обслуживании из-за ограниченных ресурсов на обработку соединений. Самый типичны пример — это SSHd, который весьма просто поддаётся DoS'у со сбоями в доступе для администратора. VPN не является панацеей и сам встаёт под атаку.


Самый эффективный способ — это ограничение доступа на уровне сети по исходящим адресам, но далеко не всегда это возможно: доступ в дороге, динамичные адреса, временные сотрудники и т.п.


История


По некоторым отсылкам тема стала более освещена Martin Krzywinski в 2003 году. Первоначально в конце 90-х для динамического открытия доступа был придуман механизм посылки пакетов в определённой последовательности в ограниченном интервале времени, прям как в остросюжетных фильмах с секретным стуком в дверь. На стороне сервера были различные варианты реализации обработки таких пакетов и открытия доступа. Такой механизм имеет все недостатки общего пароля, передаваемого в открытом виде, и должен быть предан анафеме как telnet и rsh, хотя в некоторых вариантах и поддерживаются временные пароли и некое хэширование.


Множество вариантов реализации перечислено на www.portknocking.org.


Впоследствии, всё же додумались притянуть полноценную криптографию с целью защиты от подслушивания, воспроизведения, подмены данных и поддержки отдельных пользователей. Используя секретные ключи для подписи сообщения и синхронизацию времени с допустимым отклонением, появилась возможность достаточно надёжно посылать команды одним пакетом. Первые публичные отсылки "Single Packet Authorization" (далее SPA) идут к июльской сходке BlackHat в 2005 году.


fwknop — FireWall KNock OPerator


Первый релиз проекта был в 2004 году и он до сих пор поддерживается. Стандартные пакеты присутствуют в различных дистрибутивах. Изначальный подход был в прослушивании трафика через pcap, что несколько сомнительно. Далее было накручено множество фич, вплоть до удалённого запуска команд, а-ля poor man's ssh.


Разумеется, даже несмотря на качественный аудит кода, все прибамбасы вызывают опасения для использования, особенно с правами супер-пользователя. Однако, поддержка множества пользователей и поддержка SPA являются серьёзными плюсами.


Только в 2014 году в v2.6.4 был добавлен режим "UDP сервера" без необходимости в pcap, а в конце 2015-го в v2.6.8 добавили поддержку запуска абстрактных команд открытия и закрытия доступа вместо прямого кромсания сетевого фильтра. Именно эти две фичи позволили снять некоторые опасения для применения.


Интеграция fwknop с модулем cffirehol


Сервис fwknop настраивается и запускается с ограниченными привилегиями и ресурсами для большей безопасности. При удачной аутентификации допускается лишь добавлять необходимый адрес в заранее подготовленные списки (ipset рассмотрен далее), а по истечению времени удалять из них.


1. Генерируем секретные ключи на клиенте:


$ server="my_new_host"; \
    fwknop --key-gen --key-gen-file ~/.ssh/fwknop_id_${server}; \
    cat ~/.ssh/fwknop_id_${server}
[+] Wrote Rijndael and HMAC keys to: .../.ssh/fwknop_id_my_new_host
KEY_BASE64: WB8/Hh9imafehfoJC/+XF5a2gOuK3zVvGnPVG6ELtLc=
HMAC_KEY_BASE64: AuWdYzJ5MSgrM3gbELS9YyhUYLUW5jqlIRson2MhKn0ZL/5AdSSTbJnrgb5Rqhe1cs4nYFJIeBJzKG5FAqBaMg==

2. Добавляем пользователей


# включаем поддержку fwknop
cffirehol::fwknop::enable: true
# порт по умолчанию, следует поменять
cffirehol::fwknop::port: 62201
# добавляем пользователей
cffirehol::knockers:
    portable:
        timeout: 3600
        key_b64: 'WB8/Hh9imafehfoJC/+XF5a2gOuK3zVvGnPVG6ELtLc='
        hmac_key_b64: 'AuWdYzJ5MSgrM3gbELS9YyhUYLUW5jqlIRson2MhKn0ZL/5AdSSTbJnrgb5Rqhe1cs4nYFJIeBJzKG5FAqBaMg=='
    home:
        timeout: 43200
        ipset:
            - cfauth_admin
            - other_purpose
        key_b64: '<OTHER KEY>'
        hmac_key_b64: '<OTHET_HMAC_KEY>'

3. Развёртываем puppet на сервере


$ sudo /opt/puppetlabs/bin/puppet agent --test

4. Создаём файл конфигурации fwknop клиента.


Требуется fwknop-client 2.6.4+ с поддержкой "UDP сервера", который доступен в Debian 9+ и Ubuntu 17+, а для всех остальных .deb систем должны подойти сборки с LaunchPad — именно они используются в модуле.


[default]
WGET_CMD /usr/bin/wget
SPA_SERVER_PROTO udp
USE_HMAC Y
HMAC_DIGEST_TYPE sha256
RESOLVE_IP_HTTPS Y
# just a placeholder for SPA format
ACCESS tcp/1

[my_new_host]
SPA_SERVER 128.1.2.3
SPA_SERVER_PORT 62201
SPOOF_USER portable
KEY_BASE64 WB8/Hh9imafehfoJC/+XF5a2gOuK3zVvGnPVG6ELtLc=
HMAC_KEY_BASE64 AuWdYzJ5MSgrM3gbELS9YyhUYLUW5jqlIRson2MhKn0ZL/5AdSSTbJnrgb5Rqhe1cs4nYFJIeBJzKG5FAqBaMg==

Внимание: в формате файла нет двоеточия, как в файле из первого пункта.


5. Тестируем открытие доступ


fwknop -n my_new_host

Примечание


  • Обычно, папка .ssh в домашнем каталоге одно из самых защищённых мест. Поэтому используется для примера.
  • Не следует делать глобальных настроек cffirehol::knockers для избежания утечки информации на все системы в каталогах Puppet.
  • Для каждого узла у пользователя должны быть отдельные ключи из банальных соображений управления симметричными ключами.
  • Сразу используется два ключа для подписи сообщения и для шифрования, хотя это может казаться несколько излишним.
  • В зависимости от типа устройства и условий использования следует выбирать подходящий временной интервал для открытия доступа.
  • Подразумевается использование совместно с модулем cfauth — поэтому по умолчанию используется список cfauth_admin, но допустимо использовать и иные.
  • Сервер требует указание явного IP, не полагаясь на заголовок UDP пакета.

Чёрные списки


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


Во-вторых, не стоит прописывать адреса в виде отдельных правил сетевого фильтра. Это неэффективно. Для решения данной проблемы в Linux существует поддержка IP sets в рамках проекта netfilter (он же iptables).


Глобальные списки нежелательных адресов


На просторах интернета существует множество платных и открытых постоянно обновляющихся списков адресов разного качества. Одним из замечательных объединяющих проектов является All Cybercrime IP Feeds by FireHOL.


Отметим, что будет легкомысленно накидывать все возможные списки. Некоторые могут быть крайне сомнительного качества или весьма субъективны: например, адреса интернет-троллей.


Собственные чёрные списки


Подобные списки составляются как вручную, так и автоматически по результатам работ систем обнаружения вторжения (IDS). Хорошо известный пример fail2ban. В "ручном режиме" списки адресов могут браться из баз данных с заблокированными пользователями и т.п.


Поддержка списков IP-адресов в модуле cfnetwork


Был добавлен новый тип cfnetwork::ipset и концепция частичной конфигурации, когда на этапе развёртывания множество списков с единым префиксом объединяются в один. Пример:


  • vpn_access — основное определение списка и его параметров. Это название используется для ссылки.
  • vpn_access:hardcoded, vpn_access:static — или любое другое название может задаваться в конфигурации или других модулях.
  • vpn_access-net4 vpn_access-net6 — такое будет реальное имя списка созданное для семейства IPv4 и IPv6 соответственно

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


Во все конфигурации портов, где возможно указать IP-адрес или имя хоста, возможно сослаться и на именованный список с префиксом "ipset:".


Списки могут включать в себя другие списки, но это имеет смысл только для заранее заданных адресов. Пример:


cfnetwork::ipsets:
    locations:
        addr:
            - '128.1.2.3'
            - 'somehost.example.com'
            - "2001:db8::/32"
    puppet_access:
        addr: 'ipset:locations'
    vpn_access:
        addr:
            - 'ipset:locations'
            - 'ipset:cfauth_admin'
    'whitelist:static':
        addr:
            - 'trusted.example.com'
cfnetwork::service_ports:
    'main:puppet':
        src: 'ipset:puppet_access'

Примечание: список cfauth_admin автоматически добавляется в whitelist.


Поддержка актуальных чёрных списков в модуле cffirehol


Проект чёрных списков от FireHOL имеет собственный инструмент update-ipsets, который позволяет обновлять списки с проверкой возраста, манипулировать ими и обновлять их в ядре. Несмотря на это, работа с такими комплексными операциями под супер-пользователем показалась опасной. Поэтому вся подготовка списков проходит под непривилегированным пользователем, а сохранение и обновление в ядре уже делается собственными средствами.


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


Параметры cffirehol::dynblacklist::blacklists4 и cffirehol::dynblacklist::blacklists6 — позволяют выбрать именованные списки. По умолчанию используется рекомендованный список firehol-level1 с наименьшим количеством ложных срабатываний.


Параметр cffirehol::dynblacklist::addon_ipsets — позволяет добавить конфигурацию собственных списков для update-ipsets.
На крайний случай, существует параметры cffirehol::dynblacklist::custom_* для более гибкого получения собственных чёрных списков.


Минимально для включения актуальных чёрных списков достаточно:


cffirehol::dynblacklist::enable: true

Что имеем в итоге


Во-первых, для целей удобного администрирования расширен функционал cfnetwork, что позволяет без лишних проблем совмещать работу с IPv4 и IPv6 адресами. А так же, поддерживаются наследуемые списки, концепция которых отсутствует в инструментах более низкого уровня. Это позволяет логически делить адреса на группы без излишнего дублирования.


Во-вторых, внедрён дополнительный легковесный уровень защиты сервисов. В первую очередь, он позволяет закрывать такие "тяжёлые" сервисы как SSH и VPN от нежелательных соединений. Такой подход находит своё применение и для доступа в среду разработки со стороны внештатных сотрудников с персональным ключом для каждого.


В-третьих, теперь поддерживаются динамические постоянно обновляемые чёрные списки как с глобальных централизованных ресурсов, так и с собственных источников.

Tags:
Hubs:
+5
Comments 0
Comments Leave a comment

Articles