iptables equivalente para mac os x

56

Quero encaminhar solicitações de 192.168.99.100:80para 127.0.0.1:8000. É assim que eu faria no linux usando iptables:

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

Como faço a mesma coisa no MacOS X? Eu tentei uma combinação de ipfwcomandos sem muito sucesso:

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

(Para mim, o sucesso é apontar um navegador http://192.168.99.100e obter uma resposta de um servidor de desenvolvimento em que estou executando localhost:8000)

nafe
fonte
Estamos falando de cliente ou servidor OSX?
Scott Pacote
11
É leopardo da neve.
NAFE
Existe algum motivo para você não poder apenas configurar seu servidor da web para ouvir também 192.168.99.100:80?
Zoredache
11
A escuta na porta 80 precisa do sudo e alguns servidores da web não eliminam privilégios com rapidez suficiente para executá-los com segurança com o sudo.
Navin

Respostas:

33

Então eu descobri uma maneira de fazer isso. Não tenho certeza se é a maneira preferida, mas funciona! No seu shell favorito:

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

(O apelido para lo0parece ser a parte que falta)

Se você deseja que um domínio (falso) aponte para esse novo alias, verifique se o / etc / hosts contém a linha:

10.0.0.1 www.your-domain.com
nafe
fonte
4
O ipfw não funcionará em Yosemite (MAC) e parece um pouco obsoleto.
Vadorequest
25

Consegui fazer isso funcionar usando os comandos ifconfige pfctlno Mac 10.10.2. Com a abordagem a seguir, estou mapeando 127.0.0.1:3000com sucesso mydomain.comlocalmente na minha máquina.

Em sua linha de comando digite os dois comandos a seguir para encaminhar ligações para 127.0.0.1:3000a 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 -

Em seguida, edite seu arquivo /etc/hostsou /private/etc/hostse adicione a seguinte linha para mapear seu domínio 10.0.0.1.

10.0.0.1 mydomain.com

Depois de salvar o arquivo hosts, limpe o DNS local:

sudo discoveryutil udnsflushcaches

Agora abra mydomain.comem um navegador e você verá o servidor hospedado na porta do host local (ou seja 127.0.0.1:3000). Basicamente, esse processo mapeia um <ip>:<port>para um novo, <ip>para que você possa mapear um host com esse IP.

Kevin Leary
fonte
11
Apenas um pouco hacky, mas faz o trabalho. Bom show.
Joey Carson
6
Obrigado. Como você desfaz o alias e o encaminhamento?
Carlos Nuñez
11
Oi sudo discoveryutil udnsflushcachesme dá, command not foundmas ainda corresponde à entrada corretamente. Mas como posso mapear uma segunda porta? Tentei executar as etapas 1 + 2 com id: 10.0.0.2e outra porta, mas sempre leva apenas a última conexão. Então, se eu durar 10.0.0.1e port 3000avançar 3000, se durar 10.0.0.2e portá- 4000lo para frente 4000. No meu, /private/etc/hostseu escrevi as duas entradas com o (de acordo) id diferente.
Andi Giga
Funciona, mas preciso fazer isso novamente quando reinicio o OSX .... Alguma coisa para salvar isso permanentemente?
Kasper
11
Atualize comsudo dscacheutil -flushcache
northtree 16/08
5

Eu também tive que fazer uma coisa semelhante recentemente, e na busca encontrei esta resposta. Infelizmente, a resposta dos usos do Nafe, ipfwque agora está obsoleta e indisponível no OSX; e a resposta de Kevin Leary é realmente um pouco tola. Então eu tive que fazer algo melhor (mais limpo) e decidi compartilhá-lo aqui para a posteridade. Esta resposta é amplamente baseada na abordagem mencionada nesta essência .

Como o OP menciona, apontar um navegador para 192.168.99.100 deve obter uma resposta de um servidor em localhost: 8000. Adicionar um alias a ifconfignão é realmente necessário, por pfctlsi só é suficiente: para conseguir isso, o pf.confarquivo /etc/pf.confprecisa ser modificado.

Primeiro criamos (com sudo) um novo arquivo de âncora (vamos chamá-lo redirection) em: /etc/pf.anchors/redirection. Este é basicamente um arquivo de texto regular e contém a seguinte linha (assim como na resposta de Kevin Leary): rdr pass on lo0 inet proto tcp from any to 192.168.99.100 port = 80 -> 127.0.0.1 port 8000. Depois que o novo arquivo âncora for criado, ele precisará ser referenciado dentro do pf.confarquivo. Abra o pf.confarquivo com sudo e adicione rdr-anchor "redirection"após a última linha rdr-anchor (que é rdr-anchor "com.apple/*") e adicione load anchor "redirection" from "/etc/pf.anchors/redirection"no final.

Por fim, é assim que o arquivo pf.conf deve se parecer:

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

E é quase isso. Basta reiniciar pfctlemitindo sudo pfctl -dpara desativá-lo primeiro e depois sudo pfctl -fe /etc/pf.confiniciá-lo novamente.

Agora, se você precisar que isso aconteça automaticamente após cada reinicialização, outro pequeno trabalho precisará ser feito: o daemon de inicialização pfctlprecisa ser atualizado (a essência referenciada menciona que o pf é ativado automaticamente na inicialização, no entanto, isso não parece ser caso de olhar para o código). Abra (com sudo) System/Library/LaunchDaemons/com.apple.pfctl.pliste procure o seguinte:

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

e adicione a linha <string>-e</string>para torná-lo assim:

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

Isso deve resolver.

Advertência : A Apple não permite mais alterar os arquivos demon de inicialização assim (não com sudo, nem chmod, nem qualquer outra coisa). A única maneira é mexer com as configurações da Proteção de integridade do sistema : inicialize no modo de recuperação e inicie o terminal. Verifique o status do SIP com csrutil status, geralmente ele deve estar ativado. Desative-o csrutil disablee reinicie-o no modo normal e faça as alterações no arquivo plist conforme discutido acima. Depois de concluído, volte ao modo de recuperação e reative a proteção (está em vigor por um bom motivo) emitindo csrutil enable.

Explicação: Pode-se verificar emitindo o ifconfigcomando que 127.0.0.1já é o alias (padrão) para localhost lo0 - esse fato está sendo usado para evitar a necessidade de adicionar um alias extra para localhost e simplesmente usar o endereço padrão no pf.confarquivo.

ATUALIZAÇÃO: Infelizmente, parece que carregar o arquivo na inicialização não funciona. Ainda estou tentando obter ajuda para classificá-lo. Até lá, correr sudo pfctl -f /etc/pf.confdepois de iniciar faz o truque.

Yogesch
fonte
Obrigado por isso, isso funcionou para mim no OS X Sierra. É muito importante que o arquivo de redirecionamento termine com uma nova linha.
Kadrian 28/10
Não parece seguro substituir arquivos do sistema como System/Library/LaunchDaemons/com.apple.pfctl.plist; isso provavelmente não sobreviveria a uma atualização do sistema operacional?
Tom
1

A partir da 10.5, o OS X vem com um novo firewall orientado a aplicativos em vez de ipfw. Mas o ipfw ainda está instalado. Se você tiver problemas com sua sintaxe, consulte frontends gráficos como WaterRoofou Flying Buttress.

HTH, PEra

PEra
fonte
1

a ordem das regras é importante, verifique se não há "negar tudo" antes das regras de permissão ou algo assim.

monomito
fonte
Obrigado pelo conselho, mas acho que não tenho esse problema específico (a lista ipfw mostra apenas minha regra e 65535 allow ip from any to any).
NAFE
1

Parece que seu comando está faltando um número de regra; experimentar:

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

(se você não estiver executando como root, precisará prefixá-lo com sudo). Outra coisa a verificar é se o firewall está ativado:

sysctl net.inet.ip.fw.enable

Se retornar com o valor 0 (desativado), ative-o com:

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

... e, em seguida, solicite a reativação quando o computador reiniciar. A maneira "correta" de fazer isso é provavelmente criar um item launchd (o Lingon facilita bastante isso). Ou apenas use uma das ferramentas GUI mencionadas no PEra e deixe que ele cuide dos detalhes.

Gordon Davisson
fonte