IPTABLES: Negar acesso ao domínio a todos, exceto a uma pequena lista de IPs

IPTABLES: Negar acesso ao domínio a todos, exceto a uma pequena lista de IPs

Eu tenho alguns servidores públicos e algumas máquinas Ubuntu domésticas. Eu mantenho alguns domínios especificamente para monitorar coisas como MySQL e Memcache. Idealmente, eu seria capaz de me conectar ao MySQL, Memcache, etc. de minhas máquinas domésticas, negando acesso a todos os outros.

Então meus iptables atualmente são:

ACCEPT     tcp  --  home ip              0.0.0.0/0            tcp dpt:3306
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:222
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
ACCEPT     all  --  server 1 ip          0.0.0.0/0
ACCEPT     all  --  server 2 ip          0.0.0.0/0
ACCEPT     all  --  server 3 ip          0.0.0.0/0
DROP       all  --  198.245.49.225       0.0.0.0/0
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Gostaria de estender meu iptables para poder acessar tudo de casa. Acho que provavelmente é uma boa prática adicionar uma linha para o meu IP inicial para cada porta que desejo, em vez de fornecer ao meu IP inicial acesso a todas as portas. Mas talvez isso não importe. Além disso, quero executar coisas como o phpMemcachedAdmin sem exigir uma senha.

Então, fiz algumas pesquisas no Google sobre como negar acesso a um domínio para o mundo inteiro. Acho que coloquei uma linha permitindo meu ip na porta 80 logo acima da linha negando acesso ao domínio para o mundo inteiro e (dedos cruzados) deveria estar bloqueando todos menos eu.

As postagens que vi em minhas pesquisas no Google diziam que você poderia bloquear um domínio via -m string "Host: domain.com"ou via --string "domain.com". Nenhum dos dois parece funcionar. Aqui está o que eu tentei:

sudo iptables -I 9 -p tcp --dport 80 -m string "Host: domain.com" --algo bm -j DROP
sudo iptables -I 9 -p tcp --dport 80 -m string "domain.com" --algo bm -j DROP
sudo iptables -I 9 -p tcp --dport 80 --string "domain.com" --algo bm -j DROP

Os dois primeiros erros com argumento incorreto 'Host:...' e o último erro na opção desconhecida "--string".

Para complicar um pouco mais as coisas, meu IP doméstico é dinâmico e não estático. Portanto, seria bom ter (mas não essencial) a capacidade de permitir meu IP doméstico por meio de um domínio DynDNS que configurei. Eu tenho um script para parar e iniciar o iptables, então, se precisar, posso sempre parar e reiniciá-lo para forçar a atualização do IP. (Li em vários lugares que o iptables apenas verifica um IP para o domínio na inicialização.)

Agradeço qualquer conselho relacionado à segurança sobre o uso de iptables também para seu servidor web padrão.

Obrigado


17/03/14 Adições: Encontrei o erro de sintaxe na minha linha iptables - -m stringdeveria ser -m string --string. Agora parece que tenho o iptables reconhecendo o domínio do qual quero manter as pessoas fora. No entanto, o problema passou a ser a ordem das regras do iptables.

Meu novo iptables se tornou:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  Server 1 IP          0.0.0.0/0
ACCEPT     all  --  Server 2 IP          0.0.0.0/0
ACCEPT     all  --  Server 3 IP          0.0.0.0/0
DROP       all  --  198.245.49.225       0.0.0.0/0
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 STRING match  "str_for_matching" ALGO name bm TO 65535
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:222
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

A ideia seria pegar meu IP antes do DROP que corresponde à string. Se DROP for a primeira linha, ele a captura e recebo um erro 502. No entanto, se os iptables forem como listei, as solicitações serão processadas - meu IP residencial ainda não está na tabela de regras.

O que funciona é assim:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  Server 1 IP          0.0.0.0/0
ACCEPT     all  --  Server 2 IP          0.0.0.0/0
ACCEPT     all  --  Server 3 IP          0.0.0.0/0
ACCEPT     all  --  My Home IP           0.0.0.0/0
ACCEPT     all  --  My Laptop IP         0.0.0.0/0
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 STRING match  "str_to_match" ALGO name bm TO 65535
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
DROP       all  --  198.245.49.225       0.0.0.0/0
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:222
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Consegui incluir meus IPs dinâmicos simplesmente usando seu nome de domínio DynDNS em vez de um IP.

Provavelmente eu poderia responder assim, mas gostaria de alguns conselhos sobre as melhores práticas em relação a esse problema.

informação relacionada