Вихідний трафік на різних інтерфейсах на основі порту призначення


23

Моє запитання в основному те саме, що дозволяти лише певний вихідний трафік на певних інтерфейсах .

У мене два інтерфейси eth1(10.0.0.2) та wlan0(192.168.0.2). Мій маршрут за замовчуванням призначений для eth1. Скажімо, я хочу, щоб весь https-трафік проходив wlan0. Тепер, якщо я скористаюся рішенням, запропонованим в іншому питанні, https трафік буде проходити wlan0, але все ще матиме вихідну адресу eth1(10.0.0.2). Оскільки ця адреса не призначена для wlan0шлюзу, відповіді ніколи не повернуться. Найпростішим способом було б просто встановити bind-addr належним чином у додатку, але в цьому випадку це не застосовується.

Я думаю, мені потрібно переписати src-addr:

# first mark it so that iproute can route it through wlan0
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2

Тепер tcpdump бачить вихідні пакети просто чудовими, а вхідні пакети надходять за 192.168.0.2, однак вони, ймовірно, ніколи не закінчуються в додатку, тому що все, що я коли-небудь бачу, - це те, що програма надсилає SYN-пакет, хоча SYN- ACK вже отримано.

Тому я подумав, можливо, мені теж потрібно переписати вхідну адресу:

iptables -A PREROUTING -t nat -i wlan0 -p tcp --sport 443 -j DNAT --to 10.0.0.2

але і це не спрацювало. Тож я тут якось застряг. Будь-які пропозиції?

Відповіді:


24

Ти поруч.

Фактична причина того, що програма не бачить зворотного трафіку, пов’язана з захистом ядра, вбудованим в IP-підробку. Тобто, зворотний трафік не відповідає таблиці таблиці маршрутизації, і тому випадає. Ви можете виправити це, вимкнувши захист від підробки таким чином:

sudo sysctl net.ipv4.conf.wlan0.rp_filter=0

Але я б не рекомендував це. Більш правильним способом є створення альтернативного екземпляра маршрутизації.

  1. Позначка необхідна. Тримай це.
  2. Джерело NAT також необхідне.
  3. Кінцевий DNAT непотрібний, тому його можна видалити.

Переконайтеся, що у вас встановлений iprouteпакет. Якщо у вас є ipкоманда, тоді ви встановлені (це схоже на те, що ви робите, але якщо не отримати це першим).

Відредагуйте /etc/iproute2/rt_tablesта додайте нову таблицю, додавши наступний рядок:

200 wlan-route

Потім потрібно налаштувати нову таблицю маршрутизації, названу wlan-routeза допомогою шлюзу за замовчуванням, та створити правила для умовного надсилання трафіку до цієї таблиці. Я припускаю, що ваш шлюз за замовчуванням - 192.168.0.1. Природно, це має відповідати вашій фактичній мережі, а не лише моїм припущенням.

ip route add default via 192.168.0.1 dev wlan0 table wlan-route
ip rule add fwmark 0x1 table wlan-route

Ваш остаточний анотований сценарій виглядатиме так:

# Populate secondary routing table
ip route add default via 192.168.0.1 dev wlan0 table wlan-route
# Anything with this fwmark will use the secondary routing table
ip rule add fwmark 0x1 table wlan-route
# Mark these packets so that iproute can route it through wlan-route
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2

Дякуємо, що знайшли час для розгляду цього питання. Однак це вже те, що я використовував (як описано в іншому запитанні), тому у мене встановлений додатковий маршрут, але він все одно той самий. SYN-ACK повертаються до 192.168.0.2, але, очевидно, ніколи не дістаються до програми.
румпель

Поверніться і ще раз прочитайте мою відповідь. Я звернувся до цього.
bahamat

Частина про захист від підробки? Ніяких змін навіть після спроб. Вибачте, прочитав його назад і назад пару разів, але ще не отримав те, що мені не вистачає.
rumpel

Потрібно додати srcдо ip routeкоманд опцію, щоб вказати правильну адресу джерела.
Девід Шварц

@DavidSchwartz: POSTROUTING SNATволя подбає про це.
bahamat

8

рішення багама правильне; однак зауважте, що єдиний спосіб зробити цю роботу - відключити rp_filter для кожного інтерфейсу в системі, а не лише двох (у цьому випадку eth1 та wlan0), які беруть участь у NATING.

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done
echo 1 > /proc/sys/net/ipv4/route/flush

(Див ВАЖЛИВЕ примітка в кінці цієї сторінки: Advanced Routing Howto - посилання розміщене там більше не існує, але я знайшов його через Вайбак машини)


Дякую за цю відповідь, я також міг лише отримати рішення, що працює на бахамах, враховуючи вашу відповідь.
Диналон

для мене на досить стандартному вікні ubuntu 12.04 LTS, крім того, щоб відключити rp_filter і промити кеш маршруту, мені також довелося викреслити назву інтерфейсу з аргументів iptables. не вистачило часу на розслідування чому.
Costin Gușă

0

Одна пропозиція: ви завжди повинні використовувати --sportзамість --dportвихідного ланцюга.

NAT змінити, dportі це зробить ваше правило непридатним.


2
Чи є щось, чого я не отримую? Депорт, як у порту призначення, не може змінитися. Це порт сервісу, до якого намагається досягти сеанс, наприклад, http, ssh, smtp. Або ви заплуталися у спорті та у спорті, або я пропускаю щось очевидне. : P
Хтось

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.