From a6869cb8d70cfd2fb9c2cd0afdc71ca74f365b75 Mon Sep 17 00:00:00 2001 From: Rodrigo Martins Date: Fri, 28 Feb 2025 20:31:39 -0300 Subject: [PATCH] commit --- deploy_wg_optimizer.sh | 59 +++++++++++++++++-------- manual_wg_mtu_optimization.sh | 34 +++++++++++++++ xdp_wg_mtu_optimizer.c | 81 +++++++++++++++++++++-------------- 3 files changed, 124 insertions(+), 50 deletions(-) create mode 100644 manual_wg_mtu_optimization.sh diff --git a/deploy_wg_optimizer.sh b/deploy_wg_optimizer.sh index 595508a..525196c 100644 --- a/deploy_wg_optimizer.sh +++ b/deploy_wg_optimizer.sh @@ -4,7 +4,8 @@ echo "Compilando programa XDP de otimização para WireGuard..." clang -O2 -target bpf -c xdp_wg_mtu_optimizer.c -o xdp_wg_mtu_optimizer.o \ -I/usr/include/bpf -I/usr/include/ \ - -Wno-unused-function -D__TARGET_ARCH_arm64 + -Wno-unused-function -Wno-compare-distinct-pointer-types \ + -D__TARGET_ARCH_arm64 -g # Verificar se a compilação foi bem-sucedida if [ $? -ne 0 ]; then @@ -12,31 +13,55 @@ if [ $? -ne 0 ]; then exit 1 fi -# Implantar o programa XDP na interface WireGuard -echo "Implantando programa XDP na interface wg0..." -ip link set dev wg0 xdp object xdp_wg_mtu_optimizer.o verbose +# Gerar BTF para o programa +echo "Gerando BTF information..." +llvm-strip -g xdp_wg_mtu_optimizer.o +pahole -J xdp_wg_mtu_optimizer.o -# Verificar se carregou corretamente -if [ $? -eq 0 ]; then - echo "Programa XDP de otimização para WireGuard carregado com sucesso" +# Verificar se existe a ferramenta bpftool +if ! command -v bpftool &> /dev/null; then + echo "AVISO: bpftool não encontrado, tentando carregar sem BTF" +fi + +# Tentar várias opções para carregar o programa XDP +echo "Tentando carregar o programa XDP na interface wg0..." +LOADED=0 + +# Opção 1: Tentativa direta +if ip link set dev wg0 xdp obj xdp_wg_mtu_optimizer.o sec xdp verbose; then + LOADED=1 + echo "Programa XDP carregado com sucesso!" else - echo "ERRO: Falha ao carregar programa XDP na interface wg0" - echo "Tentando adicionar o programa em modo 'generic' (menos eficiente, mas mais compatível)..." - ip link set dev wg0 xdp object xdp_wg_mtu_optimizer.o section xdp verbose mode generic + echo "Primeira tentativa falhou, tentando com modo generic..." - if [ $? -eq 0 ]; then - echo "Programa XDP carregado em modo generic com sucesso" + # Opção 2: Modo generic + if ip link set dev wg0 xdp obj xdp_wg_mtu_optimizer.o sec xdp verbose mode generic; then + LOADED=1 + echo "Programa XDP carregado em modo generic!" else - echo "ERRO: Falha ao carregar programa XDP mesmo em modo generic" - exit 1 + echo "Tentando com interface de loopback para testes..." + + # Opção 3: Testes em interface loopback + if ip link set dev lo xdp obj xdp_wg_mtu_optimizer.o sec xdp verbose mode generic; then + echo "AVISO: Programa carregado apenas na interface loopback para testes" + echo "Por favor, resolva os problemas de compatibilidade antes de usar em produção" + LOADED=1 + else + echo "ERRO: Todas as tentativas de carregamento do XDP falharam" + fi fi fi -# Configurar MTU eficiente para WireGuard +# Verificar resultado do carregamento +if [ $LOADED -eq 0 ]; then + echo "Não foi possível carregar o programa XDP" + exit 1 +fi + +# Configurações de MTU e kernel que ainda funcionam mesmo sem o XDP totalmente carregado echo "Configurando MTU otimizado para interface WireGuard..." ip link set dev wg0 mtu 1420 -# Configurar ajustes do kernel para melhorar fragmentação IP e PMTUD echo "Aplicando ajustes de kernel para otimização de MTU..." sysctl -w net.ipv4.ip_forward=1 sysctl -w net.ipv4.tcp_mtu_probing=1 @@ -46,5 +71,3 @@ sysctl -w net.ipv4.tcp_base_mss=1024 echo "" echo "=== Otimização de MTU para WireGuard ativa ===" ip link show dev wg0 | grep -E 'mtu|xdp' -echo "" -echo "Para monitorar estatísticas: bpftool map dump name mtu_stats_map" diff --git a/manual_wg_mtu_optimization.sh b/manual_wg_mtu_optimization.sh new file mode 100644 index 0000000..4960588 --- /dev/null +++ b/manual_wg_mtu_optimization.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# Este script implementa otimizações de MTU para WireGuard +# mesmo sem o programa XDP, caso não seja possível carregá-lo + +echo "Aplicando otimizações manuais de MTU para WireGuard..." + +# 1. Definir MTU ótimo para WireGuard (padrão recomendado) +ip link set dev wg0 mtu 1420 +echo "MTU do WireGuard ajustado para 1420" + +# 2. Habilitar TCP MSS clamping via iptables +# Isso força o MSS para um valor seguro, evitando fragmentação +iptables -t mangle -A FORWARD -o wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380 +ip6tables -t mangle -A FORWARD -o wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1380 +echo "TCP MSS clamping configurado para pacotes via WireGuard" + +# 3. Otimizações de kernel para fragmentação e PMTU +sysctl -w net.ipv4.tcp_mtu_probing=1 +sysctl -w net.ipv4.ip_no_pmtu_disc=0 +sysctl -w net.ipv4.tcp_base_mss=1024 +echo "Configurações de kernel ajustadas para melhor detecção de PMTU" + +# 4. Aplicar marcação específica para pacotes WireGuard no QoS existente +tc filter add dev enp0s6 parent 1: protocol ip prio 1 u32 \ + match ip protocol 17 0xff \ + match ip dport 32100 0xffff \ + flowid 1:10 +echo "Priorização de QoS específica para WireGuard adicionada" + +echo "" +echo "=== Otimizações de MTU para WireGuard aplicadas sem código XDP ===" +echo "Status da interface wg0:" +ip link show dev wg0 | grep mtu diff --git a/xdp_wg_mtu_optimizer.c b/xdp_wg_mtu_optimizer.c index 84d32e1..213f09d 100644 --- a/xdp_wg_mtu_optimizer.c +++ b/xdp_wg_mtu_optimizer.c @@ -7,6 +7,7 @@ #include #include #include +#include // Configurações de MTU para WireGuard #define WG_OVERHEAD 60 // Overhead do WireGuard (cabeçalhos + criptografia) @@ -52,10 +53,10 @@ static __always_inline void update_stats(__u64 *stat_counter) { } } -// Função para ajustar TCP MSS -static __always_inline int adjust_tcp_mss(struct tcphdr *tcp, void *data_end, __u16 max_mss) { +// Função para ajustar TCP MSS - corrigido tipos de ponteiro +static __always_inline int adjust_tcp_mss(struct tcphdr *tcp, void *data_end_ptr, __u16 max_mss) { void *tcp_end = (void *)tcp + sizeof(struct tcphdr); - if (tcp_end > data_end) + if (tcp_end > data_end_ptr) return 0; if (!tcp->syn) @@ -65,17 +66,20 @@ static __always_inline int adjust_tcp_mss(struct tcphdr *tcp, void *data_end, __ __u8 *tcp_opt_ptr = (__u8 *)tcp + sizeof(struct tcphdr); __u8 *tcp_opt_end = (__u8 *)tcp + tcp_hdr_len; - if (tcp_opt_end > data_end) + // Corrigido: cast explícito para comparação de tipos de ponteiro + if ((void *)tcp_opt_end > data_end_ptr) return 0; // Procurar opção MSS (kind=2, len=4) nas opções TCP - #pragma unroll - for (int i = 0; i < 40; i += tcp_opt_ptr[1]) { // máximo de 40 bytes de opções - if (tcp_opt_ptr + 2 > tcp_opt_end || tcp_opt_ptr + 2 > data_end) + #pragma unroll 4 // Limite de desenrolamento para evitar erros + for (int i = 0; i < 40 && tcp_opt_ptr + 1 < tcp_opt_end; i += tcp_opt_ptr[1]) { + // Corrigido: verificações de limites com cast explícito + if ((void *)(tcp_opt_ptr + 2) > data_end_ptr || (tcp_opt_ptr + 2) > tcp_opt_end) break; if (tcp_opt_ptr[0] == 2 && tcp_opt_ptr[1] == 4) { // MSS option - if (tcp_opt_ptr + 4 > tcp_opt_end || tcp_opt_ptr + 4 > data_end) + // Corrigido: verificações de limites com cast explícito + if ((void *)(tcp_opt_ptr + 4) > data_end_ptr || (tcp_opt_ptr + 4) > tcp_opt_end) break; // Extrair valor MSS atual (network byte order) @@ -85,7 +89,11 @@ static __always_inline int adjust_tcp_mss(struct tcphdr *tcp, void *data_end, __ // Ajustar MSS se necessário if (current_mss > max_mss) { *mss_ptr = bpf_htons(max_mss); - update_stats(&((struct mtu_stats *)bpf_map_lookup_elem(&mtu_stats_map, &(__u32){0}))->mss_adjusted); + __u32 zero = 0; + struct mtu_stats *stats = bpf_map_lookup_elem(&mtu_stats_map, &zero); + if (stats) { + stats->mss_adjusted++; + } return 1; } break; @@ -104,10 +112,8 @@ static __always_inline int adjust_tcp_mss(struct tcphdr *tcp, void *data_end, __ } // Função para enviar ICMP "Fragmentation needed" para indicar Path MTU Discovery -static __always_inline int send_icmp_frag_needed(struct xdp_md *ctx, struct ethhdr *eth, - struct iphdr *iph, __u16 mtu) { - // Enviar "Pacote muito grande" / "Fragmentação necessária mas DF está ativo" - // Aqui sinalizamos ao kernel para enviar o ICMP, já que é difícil construí-lo no XDP +static __always_inline int send_icmp_frag_needed(struct iphdr *iph, __u16 mtu) { + // Simplificado para evitar problemas de compilação // Verificar se o pacote tem DF (Don't Fragment) ativo __u16 frag_off = bpf_ntohs(iph->frag_off); @@ -120,37 +126,42 @@ static __always_inline int send_icmp_frag_needed(struct xdp_md *ctx, struct ethh bpf_map_update_elem(&path_mtu_map, &dest_ip, &recommended_mtu, BPF_ANY); // Incrementar contador de PMTU - update_stats(&((struct mtu_stats *)bpf_map_lookup_elem(&mtu_stats_map, &(__u32){0}))->pmtu_triggered); + __u32 zero = 0; + struct mtu_stats *stats = bpf_map_lookup_elem(&mtu_stats_map, &zero); + if (stats) { + stats->pmtu_triggered++; + } // Sinalizar ao kernel para dropar e enviar ICMP return XDP_ABORTED; } -// Programa XDP principal para otimização de pacotes WireGuard +// Programa XDP principal para otimização de pacotes WireGuard - simplificado e corrigido SEC("xdp") int xdp_wg_optimizer(struct xdp_md *ctx) { void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; - struct ethhdr *eth; - struct iphdr *iph; - __u32 key = 0; + __u32 zero = 0; // Inicializar contadores - struct mtu_stats *stats = bpf_map_lookup_elem(&mtu_stats_map, &key); + struct mtu_stats *stats = bpf_map_lookup_elem(&mtu_stats_map, &zero); if (stats) { stats->total_packets++; } - // Validação básica dos cabeçalhos - eth = data; - if ((void*)(eth + 1) > data_end) + // Verificar tamanho mínimo para cabeçalho Ethernet + IP + if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) > data_end) return XDP_PASS; + struct ethhdr *eth = data; + // Processamos apenas tráfego IPv4 if (eth->h_proto != bpf_htons(ETH_P_IP)) return XDP_PASS; - iph = (void*)(eth + 1); + struct iphdr *iph = (void*)(eth + 1); + + // Verificar se o cabeçalho IP é válido if ((void*)(iph + 1) > data_end) return XDP_PASS; @@ -159,27 +170,32 @@ int xdp_wg_optimizer(struct xdp_md *ctx) { // 1. Verificação de MTU - pacote maior que o MTU do WireGuard? if (tot_len > MAX_WG_MTU) { - update_stats(&((struct mtu_stats *)bpf_map_lookup_elem(&mtu_stats_map, &key))->oversized_packets); + if (stats) { + stats->oversized_packets++; + } // Verificar se podemos fragmentar (sem flag DF) ou se precisamos sinalizar PMTUD __u16 frag_off = bpf_ntohs(iph->frag_off); if (frag_off & 0x4000) { // Don't Fragment está ativo - return send_icmp_frag_needed(ctx, eth, iph, MAX_WG_MTU); + return send_icmp_frag_needed(iph, MAX_WG_MTU); } else { // Pacote pode ser fragmentado, deixar para o kernel - update_stats(&((struct mtu_stats *)bpf_map_lookup_elem(&mtu_stats_map, &key))->fragmented); + if (stats) { + stats->fragmented++; + } return XDP_PASS; } } // 2. Otimização TCP MSS para sessões TCP novas if (iph->protocol == IPPROTO_TCP) { - struct tcphdr *tcp = (void*)(iph) + ip_hdr_len; + // Verificar se temos cabeçalho TCP completo + void *tcp_start = (void*)iph + ip_hdr_len; + struct tcphdr *tcp = tcp_start; + if ((void*)(tcp + 1) <= data_end) { - if (adjust_tcp_mss(tcp, data_end, MSS_CLAMPING_VALUE)) { - // MSS foi ajustado - } + adjust_tcp_mss(tcp, data_end, MSS_CLAMPING_VALUE); } } @@ -189,8 +205,9 @@ int xdp_wg_optimizer(struct xdp_md *ctx) { if (known_mtu && tot_len > *known_mtu) { // Pacote excede MTU já conhecido para este destino - if (iph->frag_off & bpf_htons(0x4000)) { // DF bit set - return send_icmp_frag_needed(ctx, eth, iph, *known_mtu); + __u16 frag_off = bpf_ntohs(iph->frag_off); + if (frag_off & 0x4000) { // DF bit set + return send_icmp_frag_needed(iph, *known_mtu); } }