Назад | Перейти на главную страницу

DNAT до 127.0.0.1 с iptables / Управление доступом к месту назначения для прозрачного прокси-сервера SOCKS

У меня есть сервер, работающий в моей локальной сети, который действует как маршрутизатор для компьютеров в моей сети. Сейчас я хочу добиться, чтобы исходящие TCP-запросы к определенным IP-адресам туннелировались через SSH-соединение, не давая людям из моей сети возможности использовать этот SSH-туннель для подключения к произвольным хостам.

Подход, который я имел в виду до сих пор, заключался в том, чтобы иметь экземпляр красные носки прослушивание localhost и перенаправление всех исходящих запросов на IP-адреса, которые я хочу перенаправить на этот экземпляр redsocks. Я добавил следующее правило iptables:

iptables -t nat -A PREROUTING -p tcp -d 1.2.3.4 -j DNAT --to-destination 127.0.0.1:12345

Очевидно, ядро ​​Linux считает пакеты, приходящие с адреса, отличного от 127.0.0.0 / 8, на адрес 127.0.0.0/8, как «марсианские пакеты» и отбрасывает их. Что сработало, так это то, что redsocks слушали eth0 вместо lo, а затем вместо этого iptables DNAT передавали пакеты на адрес eth0 (или с использованием правила REDIRECT). Проблема в том, что каждый компьютер в моей сети может использовать экземпляр redsocks для подключения к каждому хосту в Интернете, но я хочу ограничить его использование только определенным набором IP-адресов.

Есть ли способ сделать пакеты iptables DNAT на 127.0.0.1? В противном случае, есть ли у кого-нибудь идеи, как я могу достичь своей цели, не открывая туннель для всех?

Обновить: Я также безуспешно пытался изменить источник пакетов:

iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.0/24 -d 1.2.3.4 -j SNAT --to-source 127.0.0.1
iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.0/24 -d 127.0.0.1 -j SNAT --to-source 127.0.0.1

Вы не можете проделать этот трюк с сетью 127/8, так как она выполняется специально внутри ядра Linux. Но вы можете создать фиктивный сетевой интерфейс, назначить ему IP-адрес, привязать свою службу к этому адресу и выполнить NAT.

root@vm8583:~# ip link add bogus type dummy
root@vm8583:~# sysctl net.ipv4.conf.eth0.arp_ignore=3
root@vm8583:~# ip addr add 10.0.0.1/32 bogus scope host
root@vm8583:~# ip link set bogus up
root@vm8583:~# ip link show bogus
4: bogus: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT 
    link/ether 5e:8b:38:f3:46:ce brd ff:ff:ff:ff:ff:ff

Обратите внимание, вам может потребоваться установить net.ipv4.conf.eth0.arp_ignore=3 Так что ваши сервер не отвечает на ARP-запросы для 10.0.0.1, входящие через eth0:

arp_ignore - INTEGER
    Define different modes for sending replies in response to
    received ARP requests that resolve local target IP addresses:
. . .
    3 - do not reply for local addresses configured with scope host,
    only resolutions for global and link addresses are replied
    4-7 - reserved

Я нашел решение моей ошибки dnat to 127.0.0.1 (loopback), получил ответ на IRC-канале netfilter.

Существует настройка sysctl, позволяющая dnat выполнять закольцовывание. Позволить это

sysctl -w net.ipv4.conf.eth0.route_localnet=1

и проверить настройку

cat /proc/sys/net/ipv4/conf/eth0/route_localnet  

Вы можете попробовать отключить фильтрация обратного пути вместо этого (что AFAICT означает термин «марсианин»). Вы можете сделать это с помощью echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter как корень. (Вы можете отключить его только на lo интерфейс, но сначала я бы попробовал полностью отключить его.)