bol-van / zapret

DPI bypass multi platform
6k stars 520 forks source link

PFSense 2.7.2 HighLoad + Keenetic OPKG #328

Open DeAlexPesh opened 4 weeks ago

DeAlexPesh commented 4 weeks ago

Вопрос к автору, либо к знающим. Для одного клиента программа работает замечательно, как только она начинает работать на всю подсеть интернет "умирает" Есть подозрение что программа не успевает обработать все запросы, ну а часть просто повисает. Какие есть рекомендации для относительно оптимальной работы на кучку пользователей?

Возможно, что-то скажут последние строки лога... image


Оставлю здесь вариант настройки


  1. Если вы добавили общие для BSD репы и теперь у вас сломался пакетный менеджер PFSense

    pkg-static clean -ay; pkg-static install -fy pkg pfSense-repo pfSense-upgrade
  2. Установка bin`арника

    
    pkg update && \
    pkg install git nano

mkdir /opt && \ git clone https://github.com/bol-van/zapret.git /opt/zapret

cp /opt/zapret/binaries/freebsd-x64/tpws /usr/local/sbin && \ chmod +x /usr/local/sbin/tpws

rm -rf /opt/zapret


3. Листы с правилами

touch /opt/zapret.auto touch /opt/zapret.exclude

Пример для /opt/zapret.auto

youtube.com youtu.be googlevideo.com play.google.com play.google.ru yt3.ggpht.com yt3.googleusercontent.com ytimg.com facebook.com fbcdn.net fb.com messenger.com twitter.com twimg.com x.com instagram.com cdninstagram.com ajay.app gstatic.com medium.com netgate.com


4. Скрипт для запуска

nano /usr/local/etc/rc.d/tpws && chmod +x /usr/local/etc/rc.d/tpws

!/bin/sh

SERVICE_NAME="tpws" SERVICE_CMD="/usr/local/sbin/tpws" is_service_running() { pgrep -f "${SERVICE_CMD}" > /dev/null && return 0 || return 1 } mng_service() { if [ "${1}" = "start" ]; then ${SERVICE_CMD} \ --debug=1 \ --port=988 \ --bind-addr=127.0.0.1 \ --enable-pf \ --bind-linklocal=force \ --split-http-req=method \ --split-pos=2 \ --maxconn=9216 \ --hostlist=/opt/zapret.auto \ --hostlist-exclude=/opt/zapret.exclude \ | logger -t "${SERVICE_NAME}" >/dev/null 2>&1 & elif [ "${1}" = "stop" ]; then pkill -f "${SERVICE_CMD}" fi } show_service_status() { if is_service_running; then echo "Сервис ${SERVICE_NAME} запущен." else echo "Сервис ${SERVICE_NAME} не работает." fi } case "${1}" in start) mng_service start ;; stop) mng_service stop ;; status) show_service_status ;; restart) mng_service stop sleep 2 mng_service start ;; *) echo "Usage: ${SERVICE_NAME} {start|stop|status|restart}" exit 1 ;; esac


5. Правила в NAT

![image](https://github.com/user-attachments/assets/eb99c8fe-5bd5-4603-8117-b10c65db055a)

tpws - alias для порта: 988 Вместо "192.168.1.141" нужно поставить "LAN subnets" Filter rule association: None


6. Управление сервисом как обычно, log`и в Status - System Logs - General...

service tpws start # можно добавить в автозагрузку, например через плагин Shellcmd service tpws restart service tpws stop service tpws status

bol-van commented 4 weeks ago

судя по номеру fd=571 у вас очень много конектов по умолчанию лимит 512

см --maxconn

DeAlexPesh commented 4 weeks ago

см --maxconn

поставил

--maxconn=10000

больше не дает, буду наблюдать

DeAlexPesh commented 4 weeks ago

обновил tpws, перезапустил и в консоль сыпет подобным (как-то подозрительно):

image image

и еще вот такую ошибку словил:

image

geokvant commented 4 weeks ago

Оставлю здесь вариант настройки

Спасибо, добрый человек! в очередной раз полез "попытаться настроить" сие чудное творение tpws и именно эта инструкция помогла завести эту шарманку на OPNSense Правда общие FreeBSD repos я не включал, а tpws скачал в папку /usr/local/sbin/ с помощью curl c последующим chmod +x ну и хостлист положил в другое место В остальном - заработало прекрасно. Пойду YouTube посмотрю на 77" в удовольствие ) Ещё раз спасибо!

tpws #opnsense

bol-van commented 4 weeks ago

обновил tpws, перезапустил и в консоль сыпет подобным (как-то подозрительно):

image

Проверил на pfsense , стареньком, правда. Еще с 12 ядром подключил к нему виртуалку с виндой. нагнал firefox на кучу сайтов. так пытал и сяк. многими вкладками. с shutdown никаких сообщений не было

что у вас за система ? ошибки с shutdown на каждое соединение или только иногда ?

pfctl -s nat pfctl -s nat -a zapret

и еще вот такую ошибку словил:

image

Это означает , что tpws не успевает принимать входящие соединения. Их очень много единомоментно. Ничего в этом страшного нет. Единичный сбой у кого-то Если, конечно, при этом у всех все отваливается, то другой случай. процессинг tpws завис. но это вряд ли

DeAlexPesh commented 4 weeks ago

система: pfsense 2.7.2 сыпет не для всех, но часто.

pfctl -s nat -a zapret

archor'ов у меня нет, только лишь 2 правила в NAT

rdr on igb0 inet proto tcp from <LAN__NETWORK> to ! <LAN__NETWORK> port = http -> 127.0.0.1 port 988
rdr on igb0 inet proto tcp from <LAN__NETWORK> to ! <LAN__NETWORK> port = https -> 127.0.0.1 port 988

перед ними стоят правила, web'а ( *ip* - внешний статический ip )

rdr on pppoe1 inet proto tcp from any to *ip* port = http -> <docker> round-robin
rdr on igb0 inet proto tcp from any to *ip* port = http -> <docker> round-robin
rdr on igb0.11 inet proto tcp from any to *ip* port = http -> <docker> round-robin
rdr on enc0 inet proto tcp from any to *ip* port = http -> <docker> round-robin
rdr on pppoe1 inet proto tcp from any to *ip* port = https -> <docker> round-robin
rdr on igb0 inet proto tcp from any to *ip* port = https -> <docker> round-robin
rdr on igb0.11 inet proto tcp from any to *ip* port = https -> <docker> round-robin
rdr on enc0 inet proto tcp from any to *ip* port = https -> <docker> round-robin

с подключениями сейчас все ок выставил --maxconn=9216, но fd= выше 4000 не поднимается

возможно, лог

image

bol-van commented 4 weeks ago

А что за докер ? Контейнер какое-то ?

bol-van commented 4 weeks ago

Вообщем поставил 2.7.2. Проблемы не вижу Контейнеры это всегда нюансы. Народ берет миркоту, ставит туда zapret и ловит различные глюки, потому что контейнеры обрезаны в правах, имеют свой нетворк неймспейс. Я не знаю как это сделано на BSD, но вероятно там тоже с этим связано

DeAlexPesh commented 4 weeks ago

А что за докер ? Контейнер какое-то ?

это проброс портов до nginx

Контейнеры это всегда нюансы

контейнеры крутятся на другом сервере, PFSense стоит bare metal на железке с intel'ом

фраза shutdown: Permission denied и ей подобные, так понимаю означает завершение tpws по причине ошибки которая после : ? На работу сильно не влияет, но в shell срет, как-то можно ее замьютить или только в режиме демона?

bol-van commented 4 weeks ago

с подключениями сейчас все ок выставил --maxconn=9216, но fd= выше 4000 не поднимается

maxconn - это количество конектов максимальное. на каждый конект 2 сокета на BSD. На linux может быть 4 или 6. Соответственно fd может дорасти примерно до maxconn*2 и даже выше, если есть orpahned legs (связано с повисшими соединениями, на которые не отвечают, и если есть неотосланные данные)

bol-van commented 4 weeks ago

фраза shutdown: Permission denied и ей подобные, так понимаю означает завершение tpws по причине ошибки которая после : ?

Нет, это связано с вызовом shutdown() на сокет. Если он не срабатывает, то ломается логика завершения соединения, и это может приводить к плодящимся вечно висящим конектам, которые не будут никогда освобождены. Что есть критически Может поэтому так много соединений и висит. На самом деле их столько нет Запас скоро исчерпается, и будет все

DeAlexPesh commented 4 weeks ago

Что есть критически

это плохо. прав не хватает у tpws получается? судя по логу, соединения таки сбрасываются, было ~3000, в следующий момент может упасть до ~200

bol-van commented 4 weeks ago

Не думаю, что дело в правах. permission denied часто возвращается по каким-то другим причинам Может как-то связано с фаерволом. Например, в linux если запретить OUTPUT , то попытка создать сокет вернет permission denied

Так все-таки shutdown ошибка на каждое соединение или нет ? Если всех обрубить и попробовать несколько раз дернуть curl-ом, будет ли эта ошибка ?

DeAlexPesh commented 3 weeks ago

Так все-таки shutdown ошибка на каждое соединение или нет ? Если всех обрубить и попробовать несколько раз дернуть curl-ом, будет ли эта ошибка ?

Оставил правила только на себе

rdr on igb0 inet proto tcp from 192.168.1.141 to ! <LAN__NETWORK> port = http -> 127.0.0.1 port 988
rdr on igb0 inet proto tcp from 192.168.1.141 to ! <LAN__NETWORK> port = https -> 127.0.0.1 port 988

пока тишина

bol-van commented 3 weeks ago

Я понял, что обломавшийся shutdown есть критическая проблема, поэтому делаю аварийное завершение пары соединений клиент-прокси и прокси-сервер в этом случае Думал ситуация практически нереальная, но вот так оказывается

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

DeAlexPesh commented 3 weeks ago

так и тишина, вылезло только 1 раз shutdown: Socket is not connected

image

DeAlexPesh commented 3 weeks ago

получается ждем обновлений и лежим в направлении цели?

bol-van commented 3 weeks ago

Уже обновлено. Но это только разрешение аварийной ситуации, не более. Надо копать почему она возникает Экспериментировать с фаерволом и редиректами. Проблема здесь явно не в tpws. Вызов shutdown() - это стандартная непривилегированная операция, применяемая при программировании сокетов. Может какие-то лимиты достигаются из-за большого количества соединений на docker ?

DeAlexPesh commented 3 weeks ago

Может какие-то лимиты достигаются из-за большого количества соединений на docker ?

там кроме doсker'а толпа сервисов висит, вполне может быть. попробую поэкспериментирую когда нагрузки поменьше будет...

обновил, но оно всеравно лезет image

bol-van commented 3 weeks ago

обновил, но оно всеравно лезет image

Я же обьяснил, что это НЕ устранение ЭТОЙ проблемы. Это решение, позволяющее не копить бесконечно сокеты и вываливаться в итоге при возникновении этой проблемы

DeAlexPesh commented 3 weeks ago

НЕ устранение ЭТОЙ проблемы

понял, буду искать

bol-van commented 3 weeks ago

Чем чревато нерешение этой проблемы и принятия текущей ситуации. Смертельного ничего не случится. Но могут теряться концы передаваемых данных при закрытии соединения. Что может приводить к некорректной загрузке сайтов, потере стилей (изурдованная страница) Поэтому я бы не оставлял. Может испортить рабочий процесс, если напущено на целую организацию. Или хотя бы по table ограничить список IP назначения. Если нужен только ютуб - взять префиксы его ASN

DeAlexPesh commented 3 weeks ago

пока замьютил волшебным словом --daemon понаблюдаю

bol-van commented 3 weeks ago

Лучше бы для начала погонять в консоли и убедиться, что legs не растет до 500, 1000 и тд

DeAlexPesh commented 3 weeks ago

что legs не растет до 500, 1000

мжт кому пригодится:

nano /usr/local/sbin/tpws_conn && \
chmod +x /usr/local/sbin/tpws_conn
#!/bin/sh
PRD=10
ADDR=127.0.0.1.988
set -- ESTABLISHED SYN_SENT SYN_RECV FIN_WAIT_1 LISTEN CLOSING FIN_WAIT_2 LAST_ACK TIME_WAIT CLOSE_WAIT CLOSED
while :; do
  tput clear
  ALL=$(netstat -na | grep "$ADDR")
  printf "%11s | " "ALL" && echo "$ALL" | grep -c ""
  printf "%11s | -\n" "---"
  for state in "$@"; do
    printf "%11s | "  "$state" && echo "$ALL" | grep -c "$state"
  done
  sleep $((PRD - $(date "+%s") % PRD ))
done

image

zetcamp commented 2 weeks ago

Оставлю здесь вариант настройки

Присоединяюсь к тем, кому данный пример помог с полпинка завести tpws в прозрачном режиме. В моём случае (opnsense) понадобилось в правиле переадресации на порт указать для Filter rule association значение Pass в явном виде, иначе фаервол не пускал трафик. Хотя источник - локалка. Ну да ладно, главное, что завелось.

От души, как говорится, что автору ПО, что обсуждающим.

tribalRu commented 1 week ago

Оставлю здесь вариант настройки

Присоединяюсь к тем, кому данный пример помог с полпинка завести tpws в прозрачном режиме. В моём случае (opnsense) понадобилось в правиле переадресации на порт указать для Filter rule association значение Pass в явном виде, иначе фаервол не пускал трафик. Хотя источник - локалка. Ну да ладно, главное, что завелось.

От души, как говорится, что автору ПО, что обсуждающим.

а можете скрин правил выложить? А то или у меня лыжи не той версии, то ли асфальт не той модели))

zetcamp commented 1 week ago

а можете скрин правил выложить?

Screenshot_20240914-161355_Vivaldi

Для правила HTTP аналогично.

tribalRu commented 1 week ago

Для правила HTTP аналогично.

Спасибо, а DPI_hosts это список хостов из локалки?

zetcamp commented 1 week ago

Спасибо, а DPI_hosts это список хостов из локалки?

Это список IP адресов из IPSET, который заполняет dnsmasq при обращении к нему с "нужным" доменом.

Подробнее тут

DeAlexPesh commented 1 week ago

Добавлю вариант установки на Keenetic OPKG

exec sh
opkg update && \
opkg install ipset curl gzip grep git-http nano iptables \
iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter \
iptables-mod-ipopt iptables-mod-conntrack-extra ip6tables-mod-nat
git clone https://github.com/bol-van/zapret.git /opt/root/zapret
cd /opt/root/zapret && ./install_bin.sh && cd ~
nano /opt/root/zapret/zapret.auto

youtube.com
youtu.be
googlevideo.com
play.google.com
play.google.ru
yt3.ggpht.com
yt3.googleusercontent.com
ytimg.com
facebook.com
fbcdn.net
fb.com
messenger.com
twitter.com
twimg.com
x.com
instagram.com
cdninstagram.com
ajay.app
gstatic.com
medium.com
digitalocean.com
netgate.com
dl.ui.com
ui.com
ubnt.com
fw-update.ubnt.com
fw-download.ubnt.com
parsec.app
nano /opt/root/zapret/zapret.exclude
nano /opt/etc/init.d/S51tpws && chmod +x /opt/etc/init.d/S51tpws

#!/bin/sh
SERVICE_NAME="tpws"
SERVICE_CMD="/opt/root/zapret/tpws/tpws"
PIDFILE=/var/run/tpws.pid
BIND="172.168.1.252"    # замените на свои
SUBNET="172.168.0.0/16"    # замените на свои
start() {
  if [ -f $PIDFILE ] && kill -0 "$(cat $PIDFILE)"; then
    echo "Service $SERVICE_NAME is already started." >&2
    return 1
  fi
  $SERVICE_CMD \
    --debug=1 \
    --pidfile $PIDFILE \
    --daemon \
    --port=988 \
    --bind-addr=$BIND \
    --bind-linklocal=force \
    --split-http-req=method \
    --disorder \
    --tlsrec=sni \
    --split-pos=2 \
    --hostlist=/opt/root/zapret/zapret.auto \
    --hostlist-exclude=/opt/root/zapret/zapret.exclude \
    --maxconn=2048
  iptables -t nat -A PREROUTING -i br0 -p tcp -s $SUBNET ! -d $SUBNET --dport 80 -j DNAT --to-destination $BIND:988
  iptables -A FORWARD -p tcp -d $BIND --dport 988 -j ACCEPT
  iptables -t nat -A PREROUTING -i br0 -p tcp -s $SUBNET ! -d $SUBNET --dport 443 -j DNAT --to-destination $BIND:988
  iptables -A FORWARD -p tcp -d $BIND --dport 988 -j ACCEPT
  echo "Service $SERVICE_NAME started."
}
stop() {
  if [ ! -f "$PIDFILE" ] || ! kill -0 "$(cat "$PIDFILE")"; then
    echo "Service $SERVICE_NAME is already stoped." >&2
    return 1
  fi
  kill -15 "$(cat "$PIDFILE")" && rm -f "$PIDFILE"
  iptables -t nat -D PREROUTING -i br0 -p tcp -s $SUBNET ! -d $SUBNET --dport 80 -j DNAT --to-destination $BIND:988
  iptables -D FORWARD -p tcp -d $BIND --dport 988 -j ACCEPT
  iptables -t nat -D PREROUTING -i br0 -p tcp -s $SUBNET ! -d $SUBNET --dport 443 -j DNAT --to-destination $BIND:988
  iptables -D FORWARD -p tcp -d $BIND --dport 988 -j ACCEPT
  echo "Service $SERVICE_NAME stoped."
}
status() {
  if [ -f $PIDFILE ] && kill -0 "$(cat $PIDFILE)"; then
    echo "Service $SERVICE_NAME started."
  else
    echo "Service $SERVICE_NAME stoped."
  fi
}
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status
    ;;
  restart)
    stop
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart}"
esac
/opt/etc/init.d/S51tpws start && /opt/etc/init.d/S51tpws status