Como eu permito DNS através de filtragem de interfaces usando iptables no Ubuntu Headless

1

Eu já vi algumas perguntas referentes a DNS estáticos, push do servidor openVPN, etc., mas nenhum deles realmente se aplica ou eles exigem ferramentas de GUI e estou usando um Ubuntu Core sem cabeçalho no qual eu sou SSH.

root@redacted:~# lsb_release -a
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.3 LTS
Release:        14.04
Codename:       trusty

Quando a máquina é conectada somente através da eth0 à rede local, tudo funciona bem. Eu posso fazer ping de IPs diretamente (8.8.8.8) e resolver nomes de domínio (google.com).

wget -q -O - ipecho.net/plain #Shows my ISPs provided Public IP

Quando a máquina está conectada através de tun0 usando a rede VPN, posso fazer ping de IPs diretamente (8.8.8.8) e resolver nomes de domínio (google.com).

wget -q -O - ipecho.net/plain #Shows my VPNs provided Public IP

Tudo como esperado até agora ...

Agora vem o problema ... Eu adiciono as seguintes regras iptables para forçar um usuário específico a só poder usar o adaptador tun0:

sudo iptables -A OUTPUT -m owner --gid-owner vpnonly -o lo -j ACCEPT
sudo iptables -A OUTPUT -m owner --gid-owner vpnonly -o eth0 -p tcp -d 192.168.x.x/24 --sport xxxx -j ACCEPT
sudo iptables -A OUTPUT -m owner --gid-owner vpnonly \! -o tun0 -j REJECT

Caso você esteja curioso, a segunda regra permite que uma UI baseada na web seja acessível em minha rede local que é executada como o usuário.

Então, agora, quando executo processos que não quero poder comunicar através do meu IP público, evitando vazamentos se a VPN for desconectada / etc / etc, simplesmente os executo rapidamente, cujo único grupo é vpnonly . NO ENTANTO quando executo um processo como vpnonly, posso fazer ping de IPs diretamente (8.8.8.8) mas não consigo resolver nomes de domínio (google.com).

root@redacted:~# sudo -u vpnonly ping -c 2 google.com
ping: unknown host google.com

Mesmo que eu consiga resolvê-lo novamente, isso seria satisfatório, mas o que eu realmente gostaria de fazer é definir a VPN para usar um DNS separado e específico, deixando a eth0 para usar 8.8.8.8 8.8.4.4.

Eu pesquisei tudo o que posso pensar relacionado a isso e não consigo resolvê-lo ... Espero ter adicionado detalhes suficientes, mas agradeço adicionar mais a pedido

EDIT 1: iptables completos

root@redacted:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             owner GID match vpnonly
ACCEPT     tcp  --  anywhere             192.168.x.x/24       owner GID match vpnonly tcp spt:xxxx
REJECT     all  --  anywhere             anywhere             owner GID match vpnonly reject-with icmp-port-unreachable

-

root@redacted:~# iptables -L -v
Chain INPUT (policy ACCEPT 16407 packets, 12M bytes)
 pkts bytes target     prot opt in     out     source               destination   

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination   

Chain OUTPUT (policy ACCEPT 6230 packets, 675K bytes)
 pkts bytes target     prot opt in     out     source               destination   
 3751 2800K ACCEPT     all  --  any    lo      anywhere             anywhere             owner GID match vpnonly
 6635 3332K ACCEPT     tcp  --  any    eth0    anywhere             192.168.x.x/24       owner GID match vpnonly tcp spt:xxxx
    4   224 REJECT     all  --  any    !tun0   anywhere             anywhere             owner GID match vpnonly reject-with icmp-port-unreachable

Editar 2:

Tudo funciona corretamente até que as regras do iptables sejam adicionadas, ponto no qual o único problema que eu sofro é a resolução do nome de domínio. Meu vpn também fornece DNS não-registro. A solução para isso seria alterar a minha entrada de servidor de nomes / etc / network / interfaces de 192.168.x.1 para o endereço IP de DNS fornecido pela minha VPN e, em seguida, permitir todas as conexões com esse IP de DNS antes da rejeição? Eu queria perguntar antes de tentar, um para ter certeza de que era tão seguro quanto eu acredito que fosse logicamente, e dois eu estou oferecendo uma recompensa de qualquer maneira. Eu quero ter certeza de que não há vazamentos, e não quero introduzir um via DNS ...

Depois de mais esclarecimentos, ao invés de modificar interfaces, eu deveria simplesmente permitir 192.168.x.1 e o IP DNS da VPN explicitamente antes da rejeição?

O que eu realmente gostaria de fazer é forçar essas consultas DNS através do adaptador tun0, fazer qualquer comunicação com o mundo exterior do usuário "vpnonly" passar pela VPN, se possível.

    
por DeeJayh 04.11.2015 / 00:39

2 respostas

0

Uma maneira fácil é criar um serviço .conf que irá persistir todas as regras do iptables que você quiser.

Você pode instalar um pacote para fazer isso, mas o modo manual é assim:

sudo vi /etc/init/persist-iptables.conf

Você pode nomear como quiser, apenas certifique-se de que está em /etc/init/ e termine com .conf

Então você deseja inserir as seguintes linhas:

description "Persist IPTables on Boot"

start on runlevel [2345]

script
        # Accept all loopback traffic localhost or 127.0.0.1
        iptables -A INPUT -i lo -j ACCEPT
        iptables -A OUTPUT -o lo -j ACCEPT

        # Accept any DNS traffic, I use a DD-WRT router with
        # Force DNS Redirection to a non-logging DNS
        iptables -A OUTPUT -d 255.255.255.255 -j ACCEPT
        iptables -A INPUT -s 255.255.255.255 -j ACCEPT

        # Accept all local traffic from 192.168.1.1-192.168.1.255
        iptables -A INPUT -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT
        iptables -A OUTPUT -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT

        # Forward all eth0, eth1, etc through tun interfaces
        iptables -A FORWARD -i eth+ -o tun+ -j ACCEPT
        iptables -A FORWARD -i tun+ -o eth+ -j ACCEPT

        # Postroute masquerade through tun interfaces
        iptables -t nat -A POSTROUTING -o tun+ -j MASQUERADE

        # Drop any other traffic through eth adapters
        iptables -A OUTPUT -o eth+ ! -d a.b.c.d -j DROP
end script

Agora, quando o sistema for reinicializado (o que limpa suas tabelas de IP), isso será executado automaticamente para atualizar o iptables novamente. Você também pode ligar para você mesmo com sudo service persist-iptables start

Este arquivo permitirá todo o tráfego localhost, permitir todo o tráfego DNS (cabe a você ter certeza de que é o DNS DIREITO vindo do seu roteador), permitir todo o tráfego local, encaminhar tráfego dos adaptadores eth para o adaptador tun e postrate masq e, finalmente, eliminar qualquer outro tráfego.

    
por DeeJayh 07.11.2015 / 08:14
0

Primeira pergunta, você pode acessar seu servidor DNS? Se você está bloqueando o acesso a todos, exceto o tun0, você pode estar bloqueando o acesso ao DNS.

Se você estiver executando algum tipo de servidor DNS localmente que esteja cheio no Bind, ou algo como dnsmasq, esse serviço também precisará ser capaz de acessar a Internet.

Sugiro adicionar uma entrada de log ao seu iptables, antes de rejeitar, para ver qual tráfego está sendo rejeitado.

Usar a porta 53 é uma maneira padrão de derrotar a segurança, portanto, a abertura *: 53 provavelmente é imprudente, portanto, será melhor indicar especificamente seu servidor DNS (local e upstream) como destinos aceitáveis para o tráfego. Eu suponho por --sport xxxx você quis dizer que você está usando uma porta não padrão em vez de: 80 para o seu serviço da web. Se não, você deve especificar isso em sua regra 192.168 (idem para o IP, deve ser um endereço / 32 completo).

Além disso, não se esqueça de que, se você quiser usar o ping para testar, precisará configurar as entradas do iptable para o ICMP. O ICMP 8 (echo) é um ping, o ICMP 0 é uma resposta de ping.

Também vale a pena considerar as rotas que você tem, pois você precisará garantir que a rota padrão para o tráfego seja tun0. Se tun0 é a única interface permitida, você precisa garantir que todas as rotas que você precisa enviar tráfego assim.

Se isso não diagnosticar seus problemas, use o ethtool para fazer um sniffing de rede, ver quais conversas estão fazendo e quais não estão. Pode ser algo estranho, como o REQ é permitido, mas o ACK não está recebendo de volta.

    
por sibaz 06.11.2015 / 15:20