iptables эквивалент для Mac OS X


56

Я хочу пересылать запросы от 192.168.99.100:80к 127.0.0.1:8000. Вот как я бы сделал это в Linux, используя iptables:

iptables -t nat -A OUTPUT -p tcp --dport 80 -d 192.168.99.100 -j DNAT --to-destination 127.0.0.1:8000

Как мне сделать то же самое в MacOS X? Я попробовал комбинацию ipfwкоманд без особого успеха:

ipfw add fwd 127.0.0.1,8000 tcp from any to 192.168.99.100 80

(Для меня успех - указать браузер http://192.168.99.100и получить ответ от сервера разработки, на котором я работаю localhost:8000)


Мы говорим о клиенте или сервере OSX?
Скотт Пак

1
Это снежный барс.
Нафе

Есть ли какая-то причина, по которой вы не можете просто настроить свой веб-сервер на прослушивание 192.168.99.100:80?
Зоредаче

1
@Zoredache Для прослушивания порта 80 требуется sudo, а некоторые веб-серверы не сбрасывают привилегии достаточно быстро, чтобы безопасно запускать их с помощью sudo.
Навин

Ответы:


33

Так я узнал , что есть способ сделать это. Я не уверен, что это предпочтительный способ, но он работает! На вашей любимой оболочке:

sudo ifconfig lo0 10.0.0.1 alias
sudo ipfw add fwd 127.0.0.1,9090 tcp from me to 10.0.0.1 dst-port 80

(Псевдоним, lo0кажется, недостающая часть)

Если вы хотите, чтобы (поддельный) домен указывал на этот новый псевдоним, убедитесь, что в / etc / hosts есть строка:

10.0.0.1 www.your-domain.com

4
ipfw не будет работать на Yosemite (MAC) и, похоже, устарел
Vadorequest

25

Я был в состоянии получить эту работу , используя ifconfigи pfctlкоманды на Mac 10.10.2. При следующем подходе я успешно картографирование 127.0.0.1:3000к mydomain.comлокально на моей машине.

В командной строке введите следующие две команды для переадресации соединений 127.0.0.1:3000на 10.0.0.1:

sudo ifconfig lo0 10.0.0.1 alias
echo "rdr pass on lo0 inet proto tcp from any to 10.0.0.1 port 80 -> 127.0.0.1 port 3000" | sudo pfctl -ef -

Затем отредактируйте файл /etc/hostsили /private/etc/hostsфайл и добавьте следующую строку, чтобы сопоставить свой домен 10.0.0.1.

10.0.0.1 mydomain.com

После сохранения файла hosts очистите локальный DNS:

sudo discoveryutil udnsflushcaches

Теперь откройте mydomain.comв браузере, и вы увидите сервер, расположенный на вашем локальном порту (то есть 127.0.0.1:3000). По сути, этот процесс сопоставляет <ip>:<port>новое с <ip>тем, чтобы вы могли затем сопоставить хост с этим IP.


1
Просто немного хакер, но выполняет свою работу. Хорошее шоу.
Джои Карсон,

6
Спасибо. Как бы вы отменили псевдоним и переадресацию?
Карлос Нуньес

1
Привет sudo discoveryutil udnsflushcachesдает мне, command not foundно он по-прежнему соответствует записи правильно. Но как я могу сопоставить второй порт? Я попытался сделать шаги 1 + 2 с id: 10.0.0.2и другим портом, но он всегда принимает только последнее соединение. Так что, если я сделаю последний 10.0.0.1и port 3000это вперед 3000, если я сделаю последний 10.0.0.2и перенесу 4000это вперед 4000. По моему /private/etc/hostsя написал обе записи с (соответственно) разными идентификаторами.
Энди Гига

Работает, но мне нужно это снова, когда я перезагружаю OSX .... Любая вещь, чтобы сохранить это навсегда?
Каспер

1
Пожалуйста, обновите сsudo dscacheutil -flushcache
Northtree

5

Недавно мне тоже пришлось сделать нечто подобное, и при поиске натолкнулся на этот ответ. К сожалению, ответ Nafe использует, ipfwкоторый в настоящее время устарел и недоступен в OSX; и ответ Кевина Лири действительно немного хакерский. Поэтому я должен был сделать что-то лучше (чище) и решил поделиться этим здесь для потомков. Этот ответ в значительной степени основан на подходе, упомянутом в этой сущности .

Как упоминается в OP, указание браузера на 192.168.99.100 должно получить ответ от сервера по адресу localhost: 8000. Добавление псевдонима в ifconfigдействительности не является необходимым, pfctlодного достаточно: для достижения этого необходимо изменить pf.confфайл /etc/pf.conf.

Сначала мы создаем (с Судо) новый файл якорный (назовем его redirection) по адресу: /etc/pf.anchors/redirection. В основном это обычный текстовый файл и содержит следующую строку (так же , как в ответ Кевин Лири): rdr pass on lo0 inet proto tcp from any to 192.168.99.100 port = 80 -> 127.0.0.1 port 8000. Как только новый файл привязки был создан, на него нужно ссылаться в pf.confфайле. Откройте pf.confфайл с помощью sudo и добавьте rdr-anchor "redirection"после последней строки rdr-anchor (которая есть rdr-anchor "com.apple/*") и добавьте load anchor "redirection" from "/etc/pf.anchors/redirection"в конце.

В конечном итоге, так должен выглядеть файл pf.conf:

scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
rdr-anchor "redirection"  #added for redirection/port forwarding
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
load anchor "pow" from "/etc/pf.anchors/redirection"  #added for redirection/port forwarding

И это почти все. Просто перезапустите pfctl, sudo pfctl -dвыполнив сначала команду, чтобы отключить ее, а затем sudo pfctl -fe /etc/pf.confснова запустить.

Теперь, если вам нужно, чтобы это происходило автоматически после каждого перезапуска, нужно выполнить еще одну крошечную часть работы: pfctlнеобходимо обновить демон запуска для (ссылка на gist указывает на то, что pf включается автоматически при загрузке, однако это не похоже на случай с просмотром кода). Откройте (с помощью sudo) System/Library/LaunchDaemons/com.apple.pfctl.plistи посмотрите на это:

<array>
          <string>pfctl</string>
          <string>-f</string>
          <string>/etc/pf.conf</string>
</array>

и добавьте строку, <string>-e</string>чтобы в конечном итоге сделать это так:

<array>
         <string>pfctl</string>
         <string>-e</string>
         <string>-f</string>
         <string>/etc/pf.conf</string>
</array>

Это должно сделать это.

Предостережение : Apple больше не позволяет изменять файлы запуска демона просто так (не с помощью sudo, ни chmod, ни чего-либо еще). Только путь повозиться с системой защиты от целостности настроек: загрузиться в режиме восстановления и запуска терминала. Проверьте состояние SIP с помощью csrutil status, как правило, он должен быть включен. Отключите его csrutil disableи перезагрузите в обычном режиме, а затем внесите изменения в файл plist, как описано выше. После этого вернитесь в режим восстановления и снова включите защиту (она установлена ​​по уважительной причине), выдав команду csrutil enable.

Объяснение: Можно проверить, введя ifconfigкоманду, которая 127.0.0.1уже является псевдонимом (по умолчанию) для localhost lo0 - этот факт используется, чтобы избежать необходимости добавлять дополнительный псевдоним для localhost и просто использовать адрес по умолчанию в pf.confфайле.

ОБНОВЛЕНИЕ: К сожалению, кажется, что загрузка файла при запуске не работает. Я все еще пытаюсь получить помощь, чтобы разобраться. До тех пор, бег sudo pfctl -f /etc/pf.confпосле запуска делает свое дело.


Спасибо за это, это работало для меня в OS X Sierra. Однако очень важно, чтобы файл перенаправления заканчивался символом новой строки.
Кадриан

Кажется небезопасным перезаписывать системные файлы, такие как System/Library/LaunchDaemons/com.apple.pfctl.plist; это, вероятно, не переживет обновление ОС?
Том

4

Это хорошо сработало для меня:


1

Начиная с 10.5, OS X поставляется с новым, ориентированным на приложения межсетевым экраном вместо ipfw. Но ipfw все еще установлен. Если у вас есть проблемы с его синтаксисом, проверьте графические интерфейсы, такие как WaterRoofили Flying Buttress.

HTH, PEra


1

порядок правил важен, убедитесь, что не существует «запретить все» до того, как вы разрешите правила, или что-то подобное.


Спасибо за совет, но я не думаю, что у меня есть эта конкретная проблема (список ipfw только показывает мое правило и 65535 allow ip from any to any).
Нафе

1

Кажется, в вашей команде отсутствует номер правила; пытаться:

ipfw add 100 fwd 127.0.0.1,8000 tcp from any to 192.168.99.100 80

(если вы не работаете с правами root, вам придется использовать префикс sudo). Еще одна вещь, чтобы проверить, что брандмауэр включен:

sysctl net.inet.ip.fw.enable

Если он возвращается со значением 0 (выкл), включите его с помощью:

sysctl -w sysctl net.inet.ip.fw.enable=1

... и затем подготовьте его к включению после перезагрузки компьютера. «Правильный» способ сделать это, вероятно, создать элемент launchd ( Lingon делает это довольно легко). Или просто используйте один из инструментов GUI, упомянутых PEra, и пусть он позаботится о деталях.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.