Acredito que estou lidando com um problema de roteamento no meu sistema (que é uma instalação padrão do Ubuntu 22), mas realmente não consigo entender como abordar a depuração desse problema.
Seguindo o tutorial do Kernel's Transparent Proxy , estou tentando implementar um proxy transparente para todo o tráfego UDP de saída com porta de destino 53 (ou seja, estou tentando filtrar todas as solicitações de DNS no meu sistema).
Depois de muitos tutoriais online, aqui está a configuração que acho que deveria funcionar (mas na verdade não funciona):
# iptables -t mangle -N DIVERT
# iptables -t mangle -A PREROUTING -p udp -m socket -j DIVERT
# iptables -t mangle -A DIVERT -j MARK --set-mark 1
# iptables -t mangle -A DIVERT -j ACCEPT
# ip rule add fwmark 1 lookup 100
# ip route add local 0.0.0.0/0 dev lo table 100
# iptables -t mangle -A PREROUTING -p udp --dport 53 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 5354
O código C para o soquete UDP real que aguarda o tráfego de entrada:
void intercept()
{
int fd;
ssize_t bytes_received_len;
char buffer[BUFFER_SIZE];
struct sockaddr_in inbound_addr, forward_server_addr;
socklen_t addr_len = sizeof(inbound_addr);
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("inbound socket creation failed");
exit(EXIT_FAILURE);
}
int val = 1;
setsockopt(fd, SOL_IP, IP_TRANSPARENT, &val, sizeof(val));
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(5354);
bind(fd, (struct sockaddr *)&addr, sizeof(addr));
for (;;)
{
printf("waiting on port 5354\n");
bytes_received_len = recvfrom(fd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&inbound_addr, &addr_len);
printf("received %zd bytes\n", bytes_received_len);
if (bytes_received_len == 0)
{
continue;
}
}
}
Todo o tratamento de erros foi ignorado para maior clareza.
Como você pode ver nos comandos do iptables, estou tentando enviar tráfego para a porta 53 no meu proxy local em 127.0.0.1: 5354. Na verdade, nunca recebo nada útil, recvfrom
mesmo quando faço solicitações de DNS no meu sistema e elas funcionam, mas elas parecem ignorar o proxy completamente.
Estou esquecendo de algo muito óbvio?
Eu dei uma olhada em todos esses artigos:
- Tutorial do kernel mencionado acima
- Esta questão: https://stackoverflow.com/questions/42738588/ip-transparent-usage
- Mesmo que seja sobre Rust, ainda foi útil: https://serverfault.com/questions/1143600/tproxy-is-not-redirecting-all-traffic-to-a-specified-port
- go-tproxy: https://github.com/KatelynHaworth/go-tproxy
Qualquer dica seria super útil. Realmente parece que estou esquecendo de algo muito óbvio.