Skip to content

Instantly share code, notes, and snippets.

@voidlizard
Created March 19, 2024 14:53
Show Gist options
  • Save voidlizard/d7f424cb8031e3bad64646627a5fa58c to your computer and use it in GitHub Desktop.
Save voidlizard/d7f424cb8031e3bad64646627a5fa58c to your computer and use it in GitHub Desktop.

hexcapt

Краткое описание работы

Сервис hexcapt осуществляет работу captive portal следующим образом:

  • Маркирует сетевые соединения, используя заданный при помощи API уровень доступа (см.конфигурирование)
  • Запускает заданное число DNS прокси с заданными настройками, для осуществления различного разрешения адресов в зависимости от заданных режимов
  • Осуществляет перенаправление (DNAT) DNS запросов на заданный инстанс DNS прокси в зависимости от заданного для MAC адреса (пользователя) уровня доступа
  • Осуществляет фильтрацию проходящего наружу трафика в зависимости от уровня доступа (см. modes/mode/forward )
  • Осуществляет перенаправление (DNAT) входящего для заданных портов на локальный сервис, в случае, если это указано в настройках режимов

Таким образом, для конфигурации по умолчанию выполняется следующее:

Пользователи с уровнем доступа по умолчанию (0):

  • DNS запросы перенаправляются на локальный DNS прокси
  • Все адреса разрешаются на локальный адрес портала (192.168.2.1)
  • Все HTTP запросы перенаправляются на локальный сервер на порту 81
  • Соединения наружу блокируются

Пользователи с уровнем доступа 1:

  • DNS запросы перенаправляются на локальный DNS прокси
  • Адреса (кроме исключений) разрешаются вышестоящим DNS
  • Адреса (исключения) разрешаются на локальный адрес портала (192.168.2.1)
  • Все HTTP запросы наружу разрешены (кроме списка исключений, по DNS(!))
  • Прочие соединения наружу блокируются

Пользователи с уровнем доступа 2:

  • DNS запросы перенаправляются на локальный DNS прокси
  • Адреса (кроме исключений) разрешаются вышестоящим DNS
  • Разрешены HTTP, HTTPS соединения наружу
  • Прочие соединения наружу блокируются

Данное поведение является настраиваемым, например, для добавления перенаправления HTTP на локальный сервер в режиме 1 необходимо добавить:

	redirect:
		- [tcp, 80, 81]

в соответствующую секцию конфига:

modes:
    - mode:
        marks: [1]
        redirect:
            - [tcp, 80, 81]
        forward:
            - [tcp, 443]

Сервис самостоятельно создает необходимые цепочки и правила iptables в следующих таблицах:

  • mangle / PREROUTING (маркирование трафика)
  • nat / PREROUTING (DNAT)
  • filter / INPUT (фильтр входящих соединений)
  • filter / FORWARD (разрешение роутинга в зависимости от режимов)

Компоненты

hexcapt

Основной сервис. Реализует API, создает необходимые правила iptables/netfilter

hexcapt-client

Клиент для сервиса. Взаимодействует с сервисом по протоколу HTTP через API (см. ниже)

hexcapt.yaml

Конфигурационный файл сервиса (см. ниже)

hexcapt.service

Файл сервиса systemd.

ndnproxy

Конфигурируемый, легковесный DNS прокси, использующийся для организации Captive Portal.

libndm.so

Shared library, необходимая ndnproxy (должна находиться в LD_PATH).

API

Для управления сервисом существует HTTP API:


HTTP GET http://URL:PORT/hexcapt/set-access?mac-addr=MAC&mark=MARK

Пример:


curl -i http://localhost:10011/hexcapt/set-access?mac-addr=fe:66:3f:e6:e5:e3&mark=1

Либо можно использовать консольный клиент:


hexcapt-client

Usage: hexcapt-client [--url ARG] --mac ARG --access ARG
  hexcapt client utility

Available options:
  -h,--help                Show this help text
  --url ARG                hexcapt API URL
  --mac ARG                MAC address to set acess
  --access ARG             access mark


Пример:

hexcapt-client --mac C1:34:2D:51:C4:E4 --access 1

Данный клиент по умолчанию считает, что сервис hexcapt работает на той же машине, что и клиент. Порт API, на котором слушает сервер, hexcapt-client ищет в конфигурационных файлах hexcapt.yaml в тех же местах, и в той же последовательности, что и сервис.

Возможно явно задать URL API при помощи параметра --url в виде http://URL:PORT.

Установка

  • Скопировать nexcapt в /usr/bin или /usr/local/bin
  • Скопировать nexcapt-client в /usr/bin или /usr/local/bin
  • Скопировать hexcapt.yaml в /etc
  • Скопировать ndnproxy в /usr/bin или /usr/local/bin
  • Скопировать libndm.so в /usr/lib или /usr/local/lib
  • Запустить ldconfig
  • Убедиться, что libndm.so доступен в LD_PATH
  • Скопировать hexcapt.service в /etc/systemd/system
  • Проверить, что путь к hexcapt в hexcapt.service соответствует реальному положению дел
  • Выполнить systemctl daemon-reload
  • Выполнить systemctl enable hexcapt

Запуск

Сервис должен стартовать автоматически при загрузке системы при помощи systemd. Ручной старт/стоп/перазапуск осуществляются при помощи команды systemctl start|stop|restart hexcapt

Конфигурирование

  1. Убедиться, что бинарник ndnproxy находится в системном пути и доступен
  2. Настройки сервиса находятся в файле hexcapt.yaml

Настройки hexcapt.yaml


# порт, на котором слушает HTTP API
listen: 10011

# адрес, к которому биндится HTTP API
bind: 0.0.0.0

# частота обновления таблицы mangle
sleep: 1.0

# интерфейс локальной сети роутера
input-iface: br0

# локальный IP роутера
local-ip:  192.168.2.1

# режимы работы сервиса
modes:

    - mode:
	    
# без определенных марок - режим по умолчанию.
# (некоторые) настройки отсюда добавляются в прочие режимы,
# например, local-domains

        marks: []

#  данные домены будут резолвится на локальный адрес
#  для указанных режимов (если марка не задана - то для всех режимов)
#  при задании домена в виде: *.zaycev.net
#  резолвится как сам домен, так и его поддомены.

        local-domains:
            - "clients3.google.com"
            - "connectivitycheck.android.com"
            - "geowalk.ru"
            - "start.tutu.tv"
            - "tilestream.geowalk.ru"
            - "tutu.tv"
            - "video.tutu.tv"
            - "www.geowalk.ru"
            - "www.msftncsi.com"
            - "www.tutu.tv"
            - "www.video.tutu.tv"


    - mode:
# марки,  определенныё для режима - может быть несколько
        marks: [0]

# DNAT-ы для данного режима (протокол, порт источника, порт назначения)
# может быть несколько
        redirect:
            - [tcp, 80, 81]

        local-domains: []

    - mode:
        marks: [2]
        local-domains: []
        forward:
            - [tcp, 443]
            - [tcp, 80]


# инстансы ndnproxy
ndnproxy:


    - instance:
# TCP порт, на котором слушает прокси
        tcp-port: 10053

# UDP порт, на котором слушает прокси
        udp-port: 10053
# марки, по которым выполняется перенаправление (DNAT)
# на этот инстанс прокси
        marks: [0]

# заданные статические адреса (маски поддерживаются)
        static-a:
            - ['*', 192.168.2.1]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment