Regras do iptables para permitir tráfego HTTP em apenas um domínio

20

Preciso configurar minha máquina para permitir apenas o tráfego HTTP de / para serverfault.com. Todos os outros sites, portas de serviços não estão acessíveis. Eu vim com estas regras do iptables:

#drop everything
iptables -P INPUT DROP
iptables -P OUTPUT DROP

#Now, allow connection to website serverfault.com on port 80
iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

#allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

Não funciona muito bem:

  • Depois de largar tudo e seguir para a regra 3:

    iptables -A OUTPUT -p tcp -d serverfault.com --port 80 -j ACEITAR

Eu recebo este erro:

iptables v1.4.4: host/network `serverfault.com' not found
Try `iptables -h' or 'iptables --help' for more information.

Você acha que está relacionado ao DNS? Devo permitir também? Ou devo apenas colocar endereços IP nas regras? Você acha que o que estou tentando fazer poderia ser alcançado com regras mais simples? Quão?

Gostaria de receber qualquer ajuda ou dicas sobre isso. Muito obrigado!

Zenet
fonte
2
Não se esqueça do sstatic.net e de outros. serverfault.com não inteiramente vêm de serverfault.com
Zoredache
Você pode executar um proxy em outro sistema? Esta é a melhor / mais fácil solução: serverfault.com/questions/215134
mattdm

Respostas:

29

Com as regras do IPTables, o pedido é importante. As regras são adicionadas e aplicadas em ordem. Além disso, ao adicionar regras manualmente, elas são aplicadas imediatamente. Assim, no seu exemplo, todos os pacotes passando pelas cadeias INPUT e OUTPUT começam a ser descartados assim que a política padrão é definida. Aliás, também é por isso que você recebeu a mensagem de erro que recebeu. O que está acontecendo é o seguinte:

  1. A política DROP padrão é aplicada
  2. IPTables recebe um nome de host como destino
  3. O IPTables tenta uma pesquisa de DNS em 'serverfault.com'
  4. A pesquisa de DNS é bloqueada pela ação DROP

Embora as opções de origem / destino aceitem nomes de host, isso é altamente desencorajado. Para citar a página de manual,

Os nomes de host serão resolvidos apenas uma vez, antes que a regra seja enviada ao kernel. Observe que especificar um nome a ser resolvido com uma consulta remota como DNS é uma péssima idéia.

Slillibri bateu na unha na cabeça que sua resposta, você perdeu a regra de DNS ACEITAR. No seu caso, isso não importa, mas geralmente eu definiria a política padrão posteriormente no processo. A última coisa que você deseja é trabalhar remotamente e permitir o SSH após ativar uma negação padrão.

Além disso, dependendo da sua distribuição, você poderá salvar suas regras de firewall para que sejam aplicadas automaticamente na hora de início.

Sabendo de tudo isso e reorganizando seu script, eis o que eu recomendaria.

# Allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

# Allow DNS
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

# Now, allow connection to website serverfault.com on port 80
iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Drop everything
iptables -P INPUT DROP
iptables -P OUTPUT DROP
Scott Pack
fonte
3
Resposta bonita e bem trabalhada.
precisa saber é o seguinte
11
Eu aprecio isso, embora você também deva ter perdido o meu erro. Opa
Scott Pack
3
Na verdade, você pode colocar suas iptables -Pdeclarações em qualquer lugar do seu script, pois as políticas de cadeia são aplicadas apenas quando os pacotes "caem" no final de uma cadeia. Normalmente, coloco as instruções de política (normalmente DROPpolíticas) na parte superior dos meus scripts do iptables.
Steven segunda-feira
11
@ Steven: Você está absolutamente certo. O OP parece estar digitando-os interativamente. Vamos fingir que você está conectado ao seu host pelo SSH e sua primeira regra é para a política DROP. Sua conexão SSH será interrompida antes que você possa digitar mais regras. Este é o mesmo problema de tempo, se uma manifestação diferente, do que ela encontrou.
Scott pacote de
Obrigado. Estava tentando isso. Mas não funcionou sem adicionar sudo iptables -I OUTPUT 1 -o lo -j ACCEPT. Isso não deveria ser adicionado?
Kiran
7

Adicionar

iptables -A OUPUT -p udp --dport 53 -j ACCEPT

para permitir pesquisas de DNS.

slillibri
fonte
5

Esse tipo de requisito pode ser melhor tratado com um proxy da web e / ou filtro. Dansgaurdian pode ser configurado para fazer isso. Você precisará usar regras NAT para forçar seu tráfego através do filtro.

Usar o iptables para filtrar permitirá que todos os sites estejam disponíveis nos endereços IP relevantes. Normalmente, esse é um pequeno subconjunto de toda a web.

BillThor
fonte
11
Concordo totalmente com isso. iptablesé provavelmente a ferramenta errada a ser usada aqui, pois não lida particularmente bem com nomes DNS. Um proxy da web com configurações de filtro apropriadas é um ajuste muito melhor.
Steven segunda-feira
2

Receio que o iptables não funcione nesse nível, ele se preocupa apenas com o endereço IP, não com o nome do host. Se você deseja bloquear o acesso a outros hosts virtuais de nomes no mesmo IP, precisará colocar arquivos .htaccess.

Niall Donegan
fonte
O problema é que, quando tento a regra 3 sem "largar tudo", ela funciona bem com o iptables!
Zenet
2
hmm, eu interpretei mal a pergunta. Certo, o que está acontecendo em segundo plano é que o iptables resolverá serverfault.com para 64.34.119.12 (consulte a resposta do slillibri para entender por que a resolução não estava funcionando). No entanto, como o iptables não entende os nomes de host e apenas permite o ip, você poderá se conectar a qualquer site nesse ip, se ele tiver vários sites.
Niall Donegan
2
@ Emily, pode funcionar bem, na medida em que a regra é adicionada, mas se o IP do serverfault.com mudar, o tráfego não será permitido. Permitir um site como o google.com, com centenas de endereços que são alterados com frequência, não funcionaria.
Zoredache
1

Você precisa configurar isso no seu servidor da web. O iptables é um filtro de pacotes. As transações HTTP enviam o nome do site (ou seja, stackoverflow) como parte da carga útil do TCP (ou seja, não como parte do cabeçalho TCP, que é o que o iptables lê facilmente).

Dado isso, e o fato de que as transações HTTP quase certamente se espalharão por vários pacotes (ou seja, você não pode simplesmente corresponder a uma sequência no cabeçalho HTTP), isso é muito melhor tratado pela configuração do servidor da Web ou por um proxy à frente. disso.

Seria útil conhecer o raciocínio por trás disso, existem algumas outras alternativas:

  1. Redirecione para o URL correto se eles inserirem o URL errado (por exemplo, redirecione para stackoverflow.com se eles inserirem www.stackoverflow.com)
  2. Diga ao seu servidor da web para não servir hosts que não sejam stackoverflow.com
  3. Coloque o site em um IP separado para o qual nada mais resolve e faça com que seu servidor da Web ouça apenas isso.
Philip Reynolds
fonte
Olá Phil, não sei se entendi qual servidor da web? Eu não tenho um servidor web. Estou fazendo essa configuração no meu computador.
Zenet