iptables --set-mark - Маршрутизувати порти через різні інтерфейси


16

Коротка історія,
3 інтерфейси, eth0 (LAN), eth1 (ADSL), eth2 (4G).
eth0 -> eth1: працює
(порти 80, 443, 4070) eth0 -> eth2: не відбувається


Це графічне зображення ідеї:

Порт 80 і 443 через eth2
мураха, а решта через eth1
введіть тут опис зображення

Netscheme:

eth0: -ip 10.0.0.1 -net 10.0.0.0/8 -gw 10.0.0.1 (the servers own intf) 
eth1: -ip 192.168.1.74 -net 192.168.1.0/24 -gw 192.168.1.254 
eth2: -ip 192.168.1.91 -net 192.168.0.0/24 -gw 192.168.0.1 






Я думаю, що цей новий сценарій перенаправляє 22 та 4070 у відповідну таблицю.
Однак, потрапивши до цієї таблиці, вона не переспрямовується на eth2.




Цей сценарій працює, за винятком 22 та 4070!

(Порт 80 не коментований, він працює, але через eth1, що неправильно.)

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F PREROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
# This next line restores any issues trying to connect to something
# if you get weird ACK packets when trying to connect (at least i did)!
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
ip route flush table main

iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 22 -j MARK --set-mark 1
###  iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 4070 -j MARK --set-mark 1

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
## -- Does the same as ip route below? route add default gw 192.168.1.254


echo "201 eth2.out" >> /etc/iproute2/rt_tables

ip rule add fwmark 1 table eth2.out
ip route add default via 192.168.0.1 dev eth2 table eth2.out
ip route add default via 192.168.1.254 dev eth1



## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE









Старий сценарій:


  Ignore everything below unless you're interested in retracing my steps!!




Я створив сценарій router.sh, щоб налаштувати своє оточення на випадок, якщо я роблю щось погане. У мене є 3 порти, які я хочу надіслати на 4G-з'єднання, а решта через стаціонарний ADSL-з'єднання. Для цього я доручив iptables мангалювати пакети за маршрутом за замовчуванням та надсилати їх через мій інтерфейс 4G, якщо --dport == 443 | 80 | 4070

Однак це не працює; Я все одно переїжджаю через свій стаціонарний телефон, незалежно від того.

Ось так виглядає мій сценарій:

#!/bin/bash

## routing tables
# wireless = 4G via eth2
# adsl = adsl via eth1

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
ip route flush table main
ip route flush table wireless
ip route flush table adsl

## Setup routing tables
# ADSL
ip route add table adsl to 192.168.1.0/24 dev eth1
# 4G
ip route add table wireless to 192.168.0.0 dev eth2
ip rule add fwmark 0x1 table wireless

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
route add default gw 192.168.1.254


## Forward ports into the LAN
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.0.3:80


## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -j LOG
#iptables --table nat --append POSTROUTING --out-interface eth2 --jump SNAT --to-source "192.168.1.74"
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

Я також намагався додати ці 3 до нижньої частини сценарію:

iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 80 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 443 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 4070 -j SNAT --to "192.168.0.91"

Також спробував без успіху:

iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1

І останнє, але не менш важливе:

## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

Маршрутизація працює, я можу переглядати Інтернет, слухати музику і що ні, але я роблю це через неправильний інтерфейс. Я довгий час гуляв навколо і знаходив шматочки і шматочки, щоб зрозуміти, що я роблю і чому це роблю. Я міг би зробити трафік через tc, але якщо це можливо за допомогою маркування пакетів в iptables, це допоможе мені довгий шлях.

Я здогадуюсь, що я виконую замовлення неправильно за різними правилами, головним чином, частиною MASQUERADE ? або якщо це навіть має бути там?

Чи може хтось пояснити, як скажіть порт DNAT , tcp: 80 від зовнішнього інтерфейсу (або одного, або протоколу BOTH) до внутрішнього адресного простору 10.0.0.0?



Виходи:

root@Netbridge:~# route -n Kernel IP routing table Destination    

Gateway         Genmask         Flags Metric Ref    Use Iface<br>
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 eth1<br>
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0<br>
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth2<br>
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1


root@Netbridge:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:4e  
          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0

eth1      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:58  
          inet addr:192.168.1.74  Bcast:192.168.1.255  Mask:255.255.255.0

eth2      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:62  
          inet addr:192.168.0.91  Bcast:192.168.0.255  Mask:255.255.255.0

Дотримуйтесь цих інструкцій:
вихід-трафік-на-різних-інтерфейсах-заснованих-на-призначення-пор
iptables-вперед-конкретних-порт-в-конкретних-nic
Серед кількох інших пов'язаних ниток.


Вибачте, але чи є причина не прив’язувати apache лише до localhostадреси та eth2інтерфейсу?
Ян Марек

@JanMarek: Тут не згадується апаш. А для вашої інформації прив'язка сокета ethXдо ip-адреси ip перешкоджатиме хостам на ethXлокальному сервері отримувати доступ до локального сервера за допомогою ethYip-адреси ip та не заважатиме хостам ethYотримувати доступ до сервера за допомогою ethXip-адреси ip. Пам'ятайте, що Linux використовує слабку модель хоста.
BatchyX

Гаразд, можливо більше веб-серверів, не тільки апач-сервер ... Я хоч, що прив'язувати веб-сервер до інтерфейсу eth2 може бути простим рішенням. Але я можу помилятися, я знаю.
Ян Марек

Відповіді:


6

BatchyX вже дає дуже хороші пояснення щодо iptables та маршрутизації, тому я буду проявляти свою лінь і переходити безпосередньо до сценарію.

Він повинен NAT весь трафік до порту 80,443,22,4070 по 192.168.0.91. Всі інші будуть NAT через 192.168.1.254.

Я повторно проходжу тестування і закінчуюсь цим керівництвом . Чого не вистачає в цьому посібнику - це останні 3 рядки мого сценарію. Що я дізнався з іншого порту, але я втратив слід від цього посилання.

Це перевірений робочий сценарій.

Потрібний маршрут за замовчуванням

Одне, що я не вкладав у сценарій, - це налаштування маршруту за замовчуванням. Вона повинна бути

route add default gw 192.168.1.254

Коли ви це зробите route -n, це повинен бути єдиний маршрут за замовчуванням (ціль: 0.0.0.0)

0.0.0.0    192.168.1.254    0.0.0.0    UG    0    0    0    eth1

fw-router.sh

# Скидання / змивання iptables
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P ВПЕРЕД АКЦЕПТУ
iptables -P ВИХІД ACCEPT

# Скидання / змивання / налаштування маршруту IP (таблиця 4)
ip route tape 4
ip route show table main | grep -Ev ^ за замовчуванням | під час читання ROUTE; ip route додати таблицю 4 $ ROUTE; зроблено
ip route додати таблицю 4 за замовчуванням через 192.168.0.1

# Марк Пакет із відповідним D.Port
iptables -t mangle -A ПЕРЕВІРЕННЯ -p tcp --dport 22 -s 10.0.0.0/24 -j MARK - set-mark 4
iptables -t mangle -A ПЕРЕВІРЕННЯ -p tcp --dport 80 -s 10.0.0.0/24 -j MARK - set-mark 4
iptables -t mangle -A ПЕРЕВІРЕННЯ -p tcp --portport 443 -s 10.0.0.0/24 -j MARK - set-mark 4
iptables -t mangle -A ПЕРЕВІРЕННЯ -p tcp --dport 4070 -s 10.0.0.0/24 -j MARK - set-mark 4

#SNAT Правила
iptables -t nat -A РОЗВ'ЯЗАННЯ -o eth1 -j SNAT --to-source 192.168.1.74
iptables -t nat -A РОЗМІСТАННЯ -o eth2 -j SNAT - до-джерело 192.168.0.91

#IP Маршрут
ip правило, додайте Fwmark 4 таблиці 4
ip route flusche cache

#IP стек
#Це відсутня частина в путівнику
echo 1> / proc / sys / net / ipv4 / ip_forward
для f в / proc / sys / net / ipv4 / conf / * / rp_filter; робити відлуння 0> $ f; зроблено
echo 0> / proc / sys / net / ipv4 / route / flush

PS1: Коротше кажучи, MASQUERADEне працює (в більшості випадків і, безумовно, у вашому випадку) для NAT з декількома зовнішніми IP-адресами, яким потрібна якась балансування навантаження або потрібна DNAT для обробки вхідного трафіку. Вам потрібно SNATдля управління напрямком.

PS2: Чистих iptables недостатньо.


Перш за все, привіт, що ви перейдете безпосередньо до сценарію :) Я спробую це сьогодні ввечері, як повернусь до середовища, в якому це буде працювати!
Тортується

хм, може знадобитися важкий перегляд. Дайте мені знати результат.
Джон Сіу

Переглянуто, має працювати зараз.
Джон Сіу

Мила, повернемося до вас за короткий час: D
Тортується

Я люблю тебе, стільки головного болю, і ти це вирішив! Дякую!
Тортується

6

Примітка: Я розглядав лише перший сценарій, ігноруючи старий.

  • Вам не потрібно моделювати модулі netfilter вручну з поточними iptables. Це потрібно лише для користувальницьких трекерів підключення.
  • Не змішуйте routeі ip route. Це чисте зло. Просто використовуйте ipвсюди і забудьте про ifconfigіroute
  • /etc/iproute2/rt_tablesне скидається через перезавантаження. Додавання одного і того ж запису знову і знову не є хорошою ідеєю, робити це потрібно лише один раз. Пам'ятайте, що rt_tablesпросто визначте псевдоніми імен на числові значення, це не змінює жодної конфігурації.

  • Тепер про iptables: У вашому FORWARDланцюжку ви скидаєте пакети, що надходять з локальної мережі в 4G. Це погано. FORWARDгачок використовується після маршрутизації виконується. На цьому етапі проводиться вся маршрутизація політики, і вже відомо, чи слід відправляти пакет на 4G або ADSL. Не проводиться перенаправлення в FORWARDабо після FORWARD(ну, технічно, перенаправлення може бути зроблено після POSTROUTINGу важких випадках, але повернутися до суті).

Тепер для вашої маршрутизації: пам’ятайте, що Ubuntu за замовчуванням дозволяє фільтрувати зворотний шлях. Фільтрація зворотного шляху працює так: Коли ядро ​​отримує пакет (може він пересилається чи ні) від інтерфейсу А, він інвертує адресу джерела та адресу призначення та перевіряє, чи повинен бути отриманий пакет направлений через інтерфейс А. Якщо це не так, пакет випадає як спроба підробки адреси.

Для пакетів, отриманих від eth0, це не є проблемою. Для пакетів, отриманих від eth1, це також не є проблемою, тому що, коли повертається вихідна IP-адреса та IP-адреса призначення, ядро ​​буде його маршрутом за замовчуванням у таблиці main. Для пакетів, отриманих від eth2, які ви не позначаєте, це проблема, тому що ядро ​​потрапить до таблиці за замовчуванням у таблиці main, і вважайте, що ці пакети повинні були бути отримані від eth1. Найпростіше рішення - відключити фільтрацію зворотного шляху на eth1:

sysctl -w net.ipv4.conf.eth1.rp_filter=0

Всі чудові коментарі, і так, з моєї сторони є певна помилкова логіка, наприклад, додавання до rt_tables кожного разу, особливо, не очищення певних таблиць, як слід, але я повинен туди потрапити :) якщо це працює, якщо так, то +50 для вас, і найголовніше, що ви врятували людину позаду від рубання на шматочки та персики! :)
Тортується

1
Нижче сценарій працює, але ви, сер, заслуговуєте також всієї подяки, ви дали мені щось подумати і rp_filter = 0 допоміг довго! : D
Тортується

@BatchyX дуже інформативний, голосуйте і для вас.
Джон Сіу

@Torxed Допис, про який я бачив, згадував rp_filter для ВСІХ інтерфейсів, потрібно відключити. Я не впевнений, чи працює це інакше.
Джон Сіу

@JohnSiu: Вам просто потрібно відключити rp-фільтр на інтерфейсах, де це проблематично. У цьому випадку це eth1, тому що до цього інтерфейсу немає маршруту, коли позначки не встановлені. eth2 не має такої проблеми, оскільки маршрут за замовчуванням йде в цей інтерфейс. Для eth0 насправді корисно увімкнути фільтр rp, інакше хтось із локальної мережі може сформувати IP-пакет з адресою джерела в Інтернеті та адресою призначення в локальній мережі, і маршрутизатор із задоволенням прийме його та пересилатиме повернутися до ... eth0.
BatchyX
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.