Доступ до DNAT'ted веб-сервера зсередини локальної мережі


12

У мене є невелика мережа з маршрутизатором, яка підтримує з'єднання з Інтернетом, сервером та деякими робочими станціями в локальній мережі.

Карта мережі

Призначений доступ до сервера через Інтернет, і в iptables маршрутизатора встановлено кілька записів DNAT, наприклад:

-A PREROUTING -i ppp0 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10

Зовнішні пакети надходять на маршрутизатор через ppp0інтерфейс, а внутрішні - з них br-lan, що насправді включає комутатор та адаптер WLAN. Проблема полягає в тому, що зовнішній доступ працює нормально, але спроба отримати доступ до сервера зсередини локальної мережі за допомогою DNS-зовнішнього IP-адреси (призначеного ppp0) не вдається.

Єдине рішення, яке мені вдалося винайти, - це додати статичні записи до /etc/hostsвказівника маршрутизатора до внутрішнього IP, але оскільки немає ніяких підказок (і у мене є щонайменше три домену верхнього рівня, призначені для цієї системи, не рахуючи десятки субдоменів), це досить хрусткий і схильний до відмов. Можете запропонувати щось краще?

Я лише знайшов це питання , яке було не дуже корисним.

Якщо це доречно, маршрутизатор працює OpenWRT 10.03 Kamikaze з dnsmasq.


Яка версія OpenWRT?
Corey S.

@Corey 10.03 Стабільний, але це не має нічого спільного з самим openwrt, чи не так?
whitequark

Відповіді:


3

Я здивований, що майже через 8 років ніхто не пояснив, як це зробити правильно, використовуючи систему конфігурації UCI, використовувану за замовчуванням у OpenWRT.

Відповідь Стівена Понеділка правильна, але вона використовує iptablesкоманди безпосередньо, що є нижчим шаром, ніж система конфігурації UCI, і найкраще залишати не торканою більшість користувачів OpenWRT, якщо це можливо.

Правильний спосіб доступу до внутрішніх серверів через їхні загальнодоступні комбінації IP / портів від іншого внутрішнього хоста в UCI - це включення параметра налаштування reflectionпід кожну конкретну ціль DNAT у файлі /etc/config/firewall. Така поведінка документовано тут .

Наприклад:

config redirect option target 'DNAT' option src 'wan' option dest 'lan' option proto 'tcp' option src_dport '44322' option dest_ip '192.168.5.22' option dest_port '443' option name 'apache HTTPS server' option reflection '1'

Примітка: Відповідно до зазначеної документації на OpenWRT, reflectionвона включена за замовчуванням. У моєму тестуванні це було не так.


15

Я видалив свою оригінальну відповідь, оскільки не був повністю впевнений, що вона правильна. З тих пір я мав певний час створити трохи віртуальної мережі віртуальних машин, щоб імітувати цю мережу. Ось набір правил брандмауера, які працювали для мене (у iptables-saveформаті, лише для natтаблиці):

-A PREROUTING -d 89.179.245.232/32 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10
-A POSTROUTING -s 192.168.2.0/24 -o ppp0 -j MASQUERADE
-A POSTROUTING -s 192.168.2.0/24 -d 192.168.2.10/32 -p tcp -m multiport --dports 22,25,80,443 -j MASQUERADE

Перше POSTROUTINGправило - це простий спосіб спільного доступу до Інтернету з локальною мережею. Я залишив його там для повноти.

PREROUTINGПравило і друге POSTROUTINGправило разом встановлюють відповідні NATs, так що підключення до сервера через зовнішній IP - адреса може статися, незалежно від того , з'єднання відбуваються з - за меж або всередині локальної мережі. Коли клієнти в локальній мережі підключаються до сервера через зовнішню IP-адресу, сервер сприймає з'єднання як внутрішні IP-адреси маршрутизатора (192.168.2.1).

Цікаво, що виявляється, що існує пару варіантів другого правила ПОСТРОЙТУВАННЯ, які також працюють. Якщо ціль буде змінено на -j SNAT --to-source 192.168.2.1, ефект (не дивно) такий же, як MASQUERADE: сервер бачить з'єднання локальних клієнтів локальної мережі як джерела з внутрішньої IP-адреси маршрутизатора . З іншого боку, якщо ціль буде змінена -j SNAT --to-source 89.179.245.232, то NAT все ще працює, але цього разу сервер бачить з'єднання локальних клієнтів локальної мережі як джерела зовнішньої IP-адреси маршрутизатора (89.179.245.232).

Нарешті, зауважте, що ваше оригінал PREROUTING/ DNATправило з -i ppp0не працює, оскільки правило ніколи не відповідає пакетам, що надходять від клієнтів локальної мережі (оскільки вони не входять в маршрутизатор через ppp0інтерфейс). Можна було б змусити його працювати, додавши друге PREROUTINGправило лише для внутрішніх клієнтів локальної мережі, але це було б неелегантно (IMO) і все одно потрібно було б чітко посилатися на зовнішню IP-адресу.

Тепер, навіть після того, як виклав рішення "шпильки NAT" (або "петління NAT", або "відбиття NAT", або як би хто вважає за краще це), я все ще вважаю, що рішення DNS з розділеним горизонтом ... -за зовнішніми клієнтами, які вирішують зовнішній IP, і внутрішніми клієнтами, що вирішують внутрішній IP ---, було б більш доцільним шляхом. Чому? Оскільки більшість людей розуміють, як працює DNS, ніж розуміють, як працює NAT, і значна частина створення хороших систем вирішує використовувати деталі, які є ремонтом. Настройка DNS швидше зрозуміла та, таким чином, правильно підтримується, ніж таємна установка NAT (звичайно, IMO).


Це прекрасно працює, велике дякую! Я погоджуюся з тим, що налаштування DNS краще, але ви не можете пересилати різні порти на одному зовнішньому IP-адресі на різні машини в локальній мережі з ним. У всякому разі, я єдиний, хто коли-небудь підтримуватиме цю налаштування, тому це добре.
whitequark

Я радий почути, що це працювало для тебе!
Стівен у понеділок

Що таке "ІМО"? Міжнародна метеорна організація www.imo.net?
Джонатан Комар

@ macmadness86 IMO == На мій погляд
Стівен, понеділок,

3

Поширене рішення - вказати внутрішніх хостів на локальний DNS-сервер, який повертає правильну "внутрішню" адресу для цих імен хостів.

Ще одне рішення - і ми використовуємо це там, де я працюю над брандмауерами Cisco - це переписати відповіді DNS на брандмауер, які відповідають цим адресам. Я не думаю, що є інструменти для Linux, які роблять це зараз.

Ви повинні мати можливість налаштувати маршрутизацію на своєму шлюзі, щоб зробити все правильно. Можливо, вам знадобиться налаштувати сервери, щоб вони були в курсі їх ip-адреси, зовнішньо відображеної (наприклад, шляхом присвоєння йому фіктивного інтерфейсу). При такій конфігурації зв'язок від однієї внутрішньої системи до іншої внутрішньої системи - використовуючи її "зовнішню" адресу - проходитиме через маршрутизатор.


Хм. Отже, ви пропонуєте додати зовнішній IP до інтерфейсів сервера, а потім налаштувати маршрутизатор, щоб він пересилав усі пакети до зовнішнього IP, що надходить зсередини локальної мережі на цей сервер? Цікаво, я тестую це незабаром.
whitequark

Чи можете ви запропонувати конфігурацію? Я спробував це: ip rule add to 89.179.245.232 dev br-lan table 10; ip route add 89.179.245.232 via 192.168.2.10 dev br-lan table 10і це не працює.
whitequark

Що в таблиці 10 маршрутизації? На внутрішніх серверах ви, мабуть, хочете, щоб вони мали як основний інтерфейс 192.168.xx (для локального спілкування), так і загальнодоступну адресу (як псевдонім).
larsks

2

Те, що ви просите зробити, називається, NAT Loopbackі це вимагає, щоб ви додали правило SNAT, щоб пакети, що походять з вашої локальної мережі на ваш сервер, повернулися через маршрутизатор:

-A POSTROUTING -p tcp -s 192.168.2.0/24 -d 192.168.2.10 -m multiport --dports 22,25,80,443 -j SNAT --to-source 89.179.245.232

На жаль, це не працює. Я спочатку пропустив -i ppp0варіант у моєму правилі, про яке йде мова, оскільки цим керував інший ланцюжок; це правило перешкоджатиме маршрутизації пакетів, що надходять з локальної мережі (і якщо я б це дозволив, пакети перейдуть з неправильного джерела і будуть відхилені).
whitequark

Ви пробували? Це вплине лише на пакети з вашої локальної мережі, що надходять до IP вашого сервера на тих дуже конкретних портах.
SiegeX

Так. (І я спробував змінити перше правило теж). Наприклад, Dig відправляє пакет на 192.168.2.1 # 53, а потім отримує несподівану відповідь від 192.168.2.10 # 53, з вашим правилом або без нього.
whitequark

0

larsks коментують розміщення внутрішньої версії простору імен \ домену, як правило, як я вирішував цю проблему в минулому. Звичайно, для цього вам потрібен DNS-сервер.


Так, я писав, що використовую dnsmasq. Будь-які ідеї щодо налаштування автоматичної заміни?
whitequark

Я нічого не знаю про OpenWRT та Kamikaze, але виходячи з того, що я читаю - що робити, якщо ви додали наступне до свого /etc/dnsmasq.conf "cname = ext-hostname.domain.com, int-hostname.domain.com"
CurtM

Ну, наскільки мені вдалося визначити, dnsmasq's cnameне підтримує маски, і, отже, не застосовується для мене через кількість піддоменів.
whitequark

0

Я придумав таке рішення, щоб дозволити моїй гостьовій мережі підключитися до портів, які були переадресовані від моєї мережі WAN до LAN. Цей сценарій розміщений у розділі "Мережа -> Брандмауер -> Спеціальні правила":

# lookup the public IP (DDNS resolves to this)
wanip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

# Guest network to LAN
# srcname is the guest network name, this needs to match for iptables
srcname=guest
# CIDR notation of guest and lan networks
srcnet=192.168.15.0/24
tgtnet=192.168.10.0/24
# router (openwrt) IP on lan network
tgtrouter=192.168.10.1
# host on lan network where ports are normally forwarded
tgthost=192.168.10.5
# ports to forward as a list or range
tcpports=8080,9090
udpports=12345

prechain=prerouting_${srcname}_rule
postchain=postrouting_${srcname}_rule

# reset the tables to prevent duplicate rules
iptables -t nat -F ${prechain}
iptables -t nat -F ${postchain}

iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p tcp -m tcp -m multiport --dports ${tcpports} -m comment --comment "${srcname} NAT reflection TCP SNAT" -j SNAT --to-source ${tgtrouter}
iptables -t nat -A ${prechain} -s ${srcnet} -d ${wanip}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP DNAT" -j DNAT --to-destination ${tgthost}
iptables -t nat -A ${postchain} -s ${srcnet} -d ${tgthost}/32 -p udp -m udp -m multiport --dports ${udpports} -m comment --comment "${srcname} NAT reflection UDP SNAT" -j SNAT --to-source ${tgtrouter}

Щоб підтримати перезавантаження, мені потрібно було виконати наступне з командного рядка ssh на openwrt (інакше, я вважаю, є умова перегону, коли деякі правила були додані, а потім очищені під час перезавантаження):

uci set firewall.@include[0].reload="1"
uci commit firewall

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

Внутрішній DNS міг би використовуватися замість цього, але лише у тому випадку, якщо всі переадресації порту переходять лише до одного хоста. Якщо у вас є кілька хостів, куди ви пересилаєте різні порти, ви можете повторити правила для різних портів до різних tgthostIP-адрес і портів.


У поточних ядрах є conntrackмодуль відповідності. І все, що вам потрібно для вирішення питання, це використовувати єдине правило:iptables -t nat -A POSTROUTING --dst <lan-net> ! --src <lan-gw-ip> -m conntrack --ctstate DNAT --ctorigdst <wan-gw-ip> -j MASQUERADE
Антон Данилов

@AntonDanilov приємно, мені це подобається. Правила, які я використовував, базувалися на відображенні NAT-правил, які вже є у OpenWRT, для з'єднань з тієї ж підмережі. Не впевнений, чи були у них якісь інші причини, крім того, що, можливо, написано до того, як з'явився контрактер.
BMitch
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.