Прозрачный заворот https на роутере через socks

Tor поддерживает "из коробки" режим transparent proxy. Это можно использовать в теории, но практически - только на роутерах с 128 мб памяти и выше. Таких роутеров не так много. В основном объем памяти 32 или 64 мб. И тор еще и тормозной.
Другой вариант напрашивается, если у вас есть доступ к какой-нибудь unix системе с SSH, где сайты не блокируются. Например, у вас есть VPS вне России. Именно так и поступил.
Понятийно требуются следующие шаги :
1) Выделять IP, на которые надо проксировать трафик. У нас уже имеется ipset "zapret", технология создания которого отработана.
2) Сделать так, чтобы все время при загрузке системы на некотором порту возникал socks.
3) Установить transparent соксификатор. Redsocks прекрасно подошел на эту роль.
4) Завернуть через iptables трафик с порта назначения 443 и на ip адреса из ipset 'zapret' на соксификатор
Буду рассматривать систему на базе openwrt, где уже установлена система обхода dpi "zapret".
По крайней мере нужно иметь заполненный ipset 'zapret', устанавливать tpws или nfqws не обязательно.
Более того, если они на вашей системе не срабатывают, то можно соксифицировать не только https, но и http.

* Сделать так, чтобы все время при загрузке системы на некотором порту возникал socks

Т.к. дефолтный dropbear клиент не поддерживает создание socks, то для начала придется заменить dropbear ssh client на openssh : пакеты openssh-client и openssh-client-utils.
Устанавливать их нужно с опцией opkg --force-overwrite, поскольку они перепишут ssh клиент от dropbear.
После установки пакетов расслабим неоправданно жестокие права : chmod 755 /etc/ssh.
Следует создать пользователя, под которым будем крутить ssh client. Допустим, это будет 'proxy'.
Сначала установить пакет shadow-useradd.
------------------
useradd -d /home/proxy proxy
mkdir -p /home/proxy
chown proxy:proxy /home/proxy
------------------
Openssh ловит разные глюки, если у него нет доступа к /dev/tty.
Добавим в /etc/rc.local строчку : "chmod 666 /dev/tty"
Сгенерируем для него ключ RSA для доступа к ssh серверу.
------------------
su proxy
cd
mkdir -m 700 .ssh
cd .ssh
ssh-keygen
ls
exit
------------------
Должны получиться файлы id_rsa и id_rsa.pub.
Строчку из id_rsa.pub следует добавить на ssh сервер в файл $HOME/.ssh/authorized_keys.
Более подробно о доступе к ssh через авторизацию по ключам : https://beget.com/ru/articles/ssh_by_key
Предположим, ваш ssh сервер - vps.mydomain.com, пользователь называется 'proxy'.
Проверить подключение можно так : ssh -N -D 1098 -l proxy vps.mydomain.com.
Сделайте это под пользователем "proxy", поскольку при первом подключении ssh спросит о правильности hostkey.
Соединение может отвалиться в любой момент, поэтому нужно зациклить запуск ssh.
Для этого лучший вариант - использовать procd - упрощенная замена systemd на openwrt версий BB и выше.
--- /etc/init.d/socks_vps ---
#!/bin/sh /etc/rc.common
START=50
STOP=50
USE_PROCD=1
USERNAME=proxy
COMMAND="ssh -N -D 1098 -l proxy vps.mydomain.com"
start_service() {
    procd_open_instance
    procd_set_param user $USERNAME
    procd_set_param respawn 10 10 0
    procd_set_param command $COMMAND
    procd_close_instance
}
-----------------------------
Этому файлу нужно дать права : chmod +x /etc/init.d/socks_vps
Запуск : /etc/init.d/socks_vps start
Останов : /etc/init.d/socks_vps stop
Включить автозагрузку : /etc/init.d/socks_vps enable
Проверка : curl -4 --socks5 127.0.0.1:1098 https://rutracker.org

* Организовать прозрачную соксификацию

Установить пакет redsocks.
Конфиг :
-- /etc/redsocks.conf : ---
base {
	log_debug = off;
	log_info = on;
	log = "syslog:local7";
	daemon = on;
	user = nobody;
	group = nogroup;
	redirector = iptables;
}
redsocks {
        local_ip = 127.0.0.1;
        local_port = 1099;
        ip = 127.0.0.1;
        port = 1098;
        type = socks5;
}
---------------------------
После чего перезапускаем : /etc/init.d/redsocks restart
Смотрим появился ли листенер : netstat -tnlp | grep 1099
Автостарт redsocks при таком конфиге не работает, потому что на момент запуска сеть не инициализирована, и у нас даже нет 127.0.0.1.
Вместо штатного автостарта будем вешаться на события поднятия интерфейса. Разберем это позже.
Пока что отключим автостарт : /etc/init.d/redsocks disable

* Завертывание соединений через iptables

Будем завертывать любые tcp соединения на ip из ipset "ipban" и https на ip из ipset "zapret".

--- /etc/firewall.user -----
SOXIFIER_PORT=1099

. /opt/zapret/init.d/openwrt/functions

create_ipset no-update

network_find_wan_all wan_iface
for ext_iface in $wan_iface; do
    network_get_device ext_device $ext_iface
    ipt OUTPUT -t nat -o $ext_device -p tcp --dport 443 -m set --match-set zapret dst -j REDIRECT --to-port $SOXIFIER_PORT
    ipt OUTPUT -t nat -o $ext_device -p tcp -m set --match-set ipban dst -j REDIRECT --to-port $SOXIFIER_PORT
done

network_get_device DEVICE lan
sysctl -w net.ipv4.conf.$DEVICE.route_localnet=1
ipt prerouting_lan_rule -t nat -p tcp --dport 443 -m set --match-set zapret dst -j DNAT --to 127.0.0.1:$SOXIFIER_PORT
ipt prerouting_lan_rule -t nat -p tcp -m set --match-set ipban dst -j DNAT --to 127.0.0.1:$SOXIFIER_PORT
----------------------------

Внести параметр "reload" в указанное место :
--- /etc/config/firewall ---
config include
        option path '/etc/firewall.user'
        option reload '1'
----------------------------

Перезапуск : /etc/init.d/firewall restart
Все, теперь можно проверять :
/etc/init.d/redsocks stop
curl -4 https://rutracker.org
# должно обломаться с надписью "Connection refused". если не обламывается - значит ip адрес rutracker.org не в ipset,
# либо не сработали правила фаервола. например, из-за не установленных модулей ipt
/etc/init.d/redsocks start
curl -4 https://rutracker.org
# должно выдать страницу

* Автозапуск redsocks

Небольшой скриптик, вешающийся на события поднятия и опускания интерфейсов.

--- /etc/hotplug.d/iface/99-exec-on-updown ---
#!/bin/sh
if [ "$ACTION" = ifup ]; then
cmd=$(uci get network.$INTERFACE.exec_on_up)
[ -n "$cmd" ] && $cmd
fi
if [ "$ACTION" = ifdown ]; then
cmd=$(uci get network.$INTERFACE.exec_on_down)
[ -n "$cmd" ] && $cmd
fi
----------------------------------------------

Теперь можно в описания интерфейсов внести в соответствующий раздел :
--- /etc/config/nework ---
config interface 'wan'
        ........
        option exec_on_up '/etc/init.d/redsocks start'
--------------------------
reboot. Заходим снова, смотрим, что есть redsocks, есть ssh, опять проверяем curl -4 https://rutracker.org.
Пробуем зайти на https://rutracker.org с компа внутри локалки.
