tl;dr: acessando (ex. ) é redirecionado (internamente) para (onde é qualquer número de porta) (ex. o comando anterior é o mesmo que ); por que isso acontece e como bloquear conexões destinadas a ?0.0.0.0
:port
curl http://0.0.0.0:443
127.0.0.1:port
port
curl
curl http://127.0.0.1:443
0.0.0.0
UPDATE2: Encontrei uma maneira de bloqueá-lo corrigindo o kernel do Linux (versão 6.0.9):
--- .orig/usr/src/linux/net/ipv4/route.c
+++ /usr/src/linux/net/ipv4/route.c
@@ -2740,14 +2740,17 @@ struct rtable *ip_route_output_key_hash_
}
if (!fl4->daddr) {
- fl4->daddr = fl4->saddr;
+ rth = ERR_PTR(-ENETUNREACH);
+ goto out;
+ /* commenting out the rest:
+ fl4->daddr = fl4->saddr; // if you did specify src address and dest is 0.0.0.0 then set dest=src addr
if (!fl4->daddr)
- fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
+ fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK); // if you didn't specify source address and dest address is 0.0.0.0 then make them both 127.0.0.1
dev_out = net->loopback_dev;
fl4->flowi4_oif = LOOPBACK_IFINDEX;
res->type = RTN_LOCAL;
flags |= RTCF_LOCAL;
- goto make_route;
+ goto make_route; END of COMMENTed out block */
}
err = fib_lookup(net, fl4, res, 0);
Resultado: Para onde vão os pacotes enviados para IP 0.0.0.0?:
$ ip route get 0.0.0.0
RTNETLINK answers: Network is unreachable
...eles não!
Um cliente tenta se conectar de 127.1.2.18:5000 a 0.0.0.0:80
$ nc -n -s 127.1.2.18 -p 5000 -vvvvvvvv -- 0.0.0.0 80
(UNKNOWN) [0.0.0.0] 80 (http) : Network is unreachable
sent 0, rcvd 0
(se você não aplicou o patch do kernel, precisará de um servidor como o seguinte para que o cliente acima possa se conectar com sucesso: (como root, no bash) while true; do nc -n -l -p 80 -s 127.1.2.18 -vvvvvvvv -- 127.1.2.18 5000; echo "------------------$(date)";sleep 1; done
)
Patched ping
(ou seja, um ping
que não define o endereço de destino como o mesmo endereço de origem quando o endereço de destino é 0.0.0.0, ou seja, comente as 2 linhas abaixo // special case for 0 dst address
que você vê aqui ):
$ ping -c1 0.0.0.0
ping: connect: Network is unreachable
instante. No entanto, se especificar o endereço de origem, levará um tempo limite (de 10 segundos) até terminar:
$ ping -I 127.1.2.3 -c1 -- 0.0.0.0
PING 0.0.0.0 (0.0.0.0) from 127.1.2.3 : 56(84) bytes of data.
--- 0.0.0.0 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
ATUALIZAÇÃO1:
A parte do porquê é explicada aqui, mas estou esperando um pouco mais de detalhes sobre por que isso acontece, por exemplo (graças ao usuário com apelido anyone
no canal liberachat #kernel):
$ ip route get 0.0.0.0
local 0.0.0.0 dev lo src 127.0.0.1 uid 1000
cache <local>
Isso mostra que, de alguma forma, os pacotes destinados a 0.0.0.0
serem roteados para a interface localhost lo
e obtêm o ip de origem 127.0.0.1
(se estou interpretando corretamente) e porque essa rota não aparece nesta lista:
$ ip route list table local
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 169.254.6.5 dev em1 proto kernel scope host src 169.254.6.5
broadcast 169.254.6.255 dev em1 proto kernel scope link src 169.254.6.5
local 192.168.0.17 dev em1 proto kernel scope host src 192.168.0.17
broadcast 192.168.255.255 dev em1 proto kernel scope link src 192.168.0.17
isso significa que deve ser de alguma forma interno ao kernel do Linux. ou seja codificado
Para você ter uma ideia, veja como fica um IP que está na internet (usei o quad1 como IP de exemplo):
$ ip route get 1.1.1.1
1.1.1.1 via 192.168.1.1 dev em1 src 192.168.0.17 uid 1000
cache
onde 192.168.1.1
está meu gateway, ou seja.:
$ ip route
default via 192.168.1.1 dev em1 metric 2
169.254.6.0/24 dev em1 proto kernel scope link src 169.254.6.5
192.168.0.0/16 dev em1 proto kernel scope link src 192.168.0.17
Como iptables
não pode ser usado para detectar (e, portanto, bloquear/descartar) essas conexões destinadas a 0.0.0.0 que são roteadas de alguma forma para 127.0.0.1, pode ser difícil encontrar uma maneira de bloqueá-las... encontre uma maneira, a menos que alguém já conheça uma.
@Stephen Kitt (nos comentários) sugeriu uma maneira de bloquear nomes de host que residem em /etc/hosts, portanto, em vez de:
0.0.0.0 someblockedhostname
você pode ter
127.1.2.3 someblockedhostname
127.1.2.3 someOTHERblockedhostname
(qualquer coisa diferente de 127.0.0.1, mas pode usar o mesmo IP para cada nome de host bloqueado, a menos que você deseja diferenciar)
qual IP você pode bloquear usando iptables
.
No entanto, se o seu resolvedor de DNS (ou seja, NextDNS , ou 1.1.1.3 ) retornar 0.0.0.0
para nomes de host bloqueados (em vez de NXDOMAIN
), você não poderá fazer isso (a menos, é claro, que queira adicionar cada host manualmente em /etc/hosts
, porque /etc/hosts tem precedência - assumindo que você não mudou a linha hosts: files dns
de /etc/nsswitch.conf
)
ANTIGO: (embora editado)
No Linux (eu tentei Gentoo e Pop OS!, mais recente) se você tiver esta linha em /etc/hosts
:
0.0.0.0 somehosthere
e você executa isso como root (para emular um servidor localhost ouvindo na porta 443),
# nc -l -p 443 -s 127.0.0.1
então você acessa seu navegador (Firefox e Chrome/Chromium testado) e coloca isso na barra de endereço:
https://somehosthere
ou
0.0.0.0:443
ou
https://0.0.0.0
então o terminal onde você começou nc
(também conhecido como netcat) mostra uma tentativa de conexão (algum texto lixo incluindo o texto simples somehosthere
se você o usou no url)
ou em vez do navegador, você pode tentar:
curl https://somehosthere
ou se quiser ver a solicitação de texto simples:
curl http://somehosthere:443
Isso não parece ser mitigável, mesmo ao usar, dnsmasq
desde que 0.0.0.0 somehosthere
esteja em /etc/hosts
, mas ao usar dnsmasq
e seu resolvedor de DNS (ou seja, NextDNS ou Cloudflare's 1.1.1.3 ) retorna 0.0.0.0
em vez de NXDOMAIN
( true no momento em que este artigo foi escrito) e esse nome de host não está no seu /etc/hosts
(E no que você disse dnsmasq
é /etc/hosts
para usar), há duas maneiras de mitigá-lo (um ou ambos funcionarão):
- usar
dnsmasq
arg--stop-dns-rebind
--stop-dns-rebind
Reject (and log) addresses from upstream nameservers which are in
the private ranges. This blocks an attack where a browser behind
a firewall is used to probe machines on the local network. For
IPv6, the private range covers the IPv4-mapped addresses in pri‐
vate space plus all link-local (LL) and site-local (ULA) ad‐
dresses.
- linha de uso
bogus-nxdomain=0.0.0.0
na/etc/dnsmasq.conf
qual se fazdnsmasq
retornarNXDOMAIN
para qualquer nome de host resolvido0.0.0.0
(exceto, mais uma vez, se esse nome de host estava em /etc/hosts (ignora o dnsmasq) e o que você disse ao dnsmasq para usar como/etc/hosts
(se o fez))
Então, a segunda parte desta questão é como impedir que os acessos a 0.0.0.0 sejam redirecionados para 127.0.0.1? Eu quero isso porque ao usar NextDNS (ou cloudflare 1.1.1.3 ) como resolvedor de DNS, ele retorna 0.0.0.0
para hostnames bloqueados, em vez de NXDOMAIN, portanto, ao carregar páginas da web, partes delas (que estão localizadas em hostnames bloqueados) tentarão acessar meu localhost servidor executando na porta 443 (se houver) e carregue páginas dele em vez de apenas ser bloqueado.
Problemas públicos relevantes específicos do navegador cientes disso (que 0.0.0.0 mapeia para 127.0.0.1):
Chrome/Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=1300021
Firefox: https ://bugzilla.mozilla.org/show_bug.cgi?id=1672528#c17