Corrige e previne o timeout do OpenVPN Connect no macOS causado por uma
bypass route /32 órfã que sobra na tabela de roteamento quando o app é
encerrado de forma "suja" (sleep, troca de rede ou crash com a VPN conectada).
O endereço do servidor não fica no código — é descoberto em runtime a partir
dos perfis .ovpn instalados pelo próprio OpenVPN Connect.
No log do OpenVPN Connect
(~/Library/Application Support/OpenVPN Connect/log/ovpn_full.log):
Connecting to [vpn.example.com]:1197 (X.X.X.X) via UDPv4
UDP send exception: send: Can't assign requested address
... (repete a cada segundo) ...
Server poll timeout, trying next remote entry...
EVENT: RECONNECTING
O servidor e os demais usuários ficam normais — é estado local da máquina.
Com a VPN desligada, a rota órfã ainda aparece (S = estática, não removida):
$ netstat -rn -f inet | grep <IP-do-servidor>
X.X.X.X/32 <gateway-da-LAN> UGSc en0 # app DESCONECTADO, rota sobrou
Encerre o OpenVPN Connect (Disconnect + Quit) e rode:
sudo bash openvpn-route-fix.sh # corrige agora + instala prevenção
sudo bash openvpn-route-fix.sh --no-daemon # só corrige agora
sudo bash openvpn-route-fix.sh --status # mostra estado (servidores, VPN, daemon, rotas)
sudo bash openvpn-route-fix.sh --uninstall # remove a prevençãoDepois reabra o OpenVPN Connect e conecte normalmente.
Não precisa clonar. Como o repositório é público, o raw.githubusercontent.com
serve o script sem autenticação:
# corrige agora + instala a prevenção
curl -fsSL https://raw.githubusercontent.com/luancamara/openvpn-route-fix/main/openvpn-route-fix.sh | sudo bashPara passar flags via pipe, use bash -s --:
curl -fsSL https://raw.githubusercontent.com/luancamara/openvpn-route-fix/main/openvpn-route-fix.sh | sudo bash -s -- --status
curl -fsSL https://raw.githubusercontent.com/luancamara/openvpn-route-fix/main/openvpn-route-fix.sh | sudo bash -s -- --uninstallRecomendado: fixar numa versão (tag) para não executar código que possa ter
mudado no main:
curl -fsSL https://raw.githubusercontent.com/luancamara/openvpn-route-fix/v1.0.0/openvpn-route-fix.sh | sudo bash- Repositório público — é o que permite o
raw.githubusercontent.comservir o arquivo sem token. (Em repo privado o raw exige autenticação e o one-liner não funciona; aí use o clone com acesso concedido.) curlesudo— ambos já vêm no macOS. Nada mais a instalar.
curl | sudo bash executa código remoto como root. Se preferir revisar antes:
curl -fsSLO https://raw.githubusercontent.com/luancamara/openvpn-route-fix/v1.0.0/openvpn-route-fix.sh
less openvpn-route-fix.sh # revise o conteúdo
sudo bash openvpn-route-fix.shgit clone https://github.com/luancamara/openvpn-route-fix.git
cd openvpn-route-fix
sudo bash openvpn-route-fix.sh-
Detecta o(s) servidor(es) lendo as linhas
remotedos perfis.ovpndo OpenVPN Connect e resolvendo o IP. Serve pra qualquer perfil, inclusive múltiplos servidores. Nada de endereço chumbado no código. -
Remove a rota
/32órfã de cada servidor — apenas com a VPN desligada (trava de segurança: recusa rodar se a default route estiver viautun). -
Instala um LaunchDaemon (consciente do estado, a cada 30s) que lê o último
EVENTdo log do OpenVPN Connect e só remove o órfão quando a sessão estáDISCONNECTED. DuranteWAIT/RESOLVE/RECONNECTING/CONNECTED/PAUSEele não toca em nada — isso elimina a corrida em que o daemon apagava a bypass route legítima durante o handshake e derrubava conexões saudáveis. Também descobre o servidor em runtime pelos perfis, então segue válido se o perfil mudar.Por que ler o estado: a bypass route precisa apontar pro gateway atual. Se ela sobra após um encerramento sujo, quando a rede/gateway muda ela vira órfã e trava a conexão. Limpando-a sempre que o OpenVPN fica ocioso, ela nunca sobrevive a uma troca de rede — mas nunca durante um connect em andamento.
Compatível com o bash 3.2 de fábrica do macOS e ciente de sudo
(SUDO_USER) para encontrar os perfis no home do usuário real.
Opcional: OVPN_FIX_SERVER_IPS="1.2.3.4 5.6.7.8" sudo -E bash openvpn-route-fix.sh
força IPs adicionais quando não houver perfil instalado.
A bypass route (host route remote/32 via o gateway físico, criada quando o
redirect-gateway está ativo) é instalada com um route add simples. Após um
encerramento sujo, a rota sobra. Na reconexão o route add falha com
File exists; o core do OpenVPN 3 marca a ação como falha e descarta o delete
pareado da lista de teardown, então a rota nunca é limpa. Como ela ainda aponta
para o gateway da rede anterior, quando esse gateway sai do ar todo envio ao
servidor falha com EADDRNOTAVAIL (Can't assign requested address).
O OpenVPN Connect é proprietário, mas o motor (openvpn3) é open source e o
bug está nele. Correção proposta no upstream:
- PR: OpenVPN/openvpn3#436
- Patch:
upstream/0001-tun-mac-make-server-bypass-route-idempotent-to-avoid.patch(torna a bypass route idempotente:route deletebest-effort antes doadd).
Enquanto o fix não chega num release do OpenVPN Connect, este script é a mitigação prática.