На FreeBSD 4.8 на ipnat у меня настроен rdr на лок машину. Если люди заходят из инета то всё ок, а вот если с лок машины то проблемы. Нашёл решение для такой проблемы для iptables но надо для фри
А теперь посмотрим, что произойдет, если запрос посылается с узла, расположенного в той же локальной сети. Для простоты изложения примем адрес клиента в локальной сети равным $LAN_BOX.
Пакет покидает $LAN_BOX.
Поступает на брандмауэр.
Производится подстановка адреса назначения, однако адрес отправителя не подменяется, т.е. исходный адрес остается в пакете без изменения.
Пакет покидает брандмауэр и отправляется на HTTP сервер.
HTTP сервер, готовясь к отправке ответа, обнаруживает, что клиент находится в локальной сети (поскольку пакет запроса содержал оригинальный IP адрес, который теперь превратился в адрес назначения) и поэтому отправляет пакет непосредственно на $LAN_BOX.
Пакет поступает на $LAN_BOX. Клиент путается, поскольку ответ пришел не с того узла, на который отправлялся запрос. Поэтому клиент "сбрасывает" пакет ответа и продолжает ждать "настоящий" ответ.
Проблема решается довольно просто с помощью SNAT. Ниже приводится правило, которое выполняет эту функцию. Это правило вынуждает HTTP сервер передавать ответы на наш брандмауэр, которые затем будут переданы клиенту.
iptables -t nat -A POSTROUTING --dst $HTTP_IP --dport 80 -j SNAT --to-source $LAN_IP
Запомните, цепочка POSTROUTING обрабатывается самой последней и к этому моменту пакет уже прошел процедуру преобразования DNAT, поэтому критерий строится на базе адреса назначения $HTTP_IP.
Если вы думаете, что на этом можно остановиться, то вы ошибаетесь! Представим себе ситуацию, когда в качестве клиента выступает сам брандмауэр. Тогда, к сожалению, пакеты будут передаваться на локальный порт с номером 80 самого брандмауэра, а не на $HTTP_IP. Чтобыразрешить и эту проблему, добавим правило
iptables -t nat -A OUTPUT --dst $INET_IP --dport 80 -j DNAT --to-destination $HTTP_IP
Теперь никаких проблем, с доступом к нашему WEB-серверу, уже не должно возникать.