O problema com o Anyconnect é que ele primeiro modifica a tabela de roteamento, depois cuida e corrige manualmente. Eu encontrei uma solução para isso. Funciona com a versão 3.1.00495, 3.1.05152, 3.1.05170 e provavelmente com qualquer outra coisa na família 3.1. Pode funcionar com outras versões, pelo menos uma ideia semelhante deve funcionar, supondo que o código não seja reescrito. Felizmente para nós, a Cisco colocou a babysitter chamada "baby is awake" em uma biblioteca compartilhada. Então a ideia é que nós previnamos a ação do vpnagentd via LD_PRELOAD.
-
Primeiro, criamos um arquivo
hack.c
:#include <sys/socket.h> #include <linux/netlink.h> int _ZN27CInterfaceRouteMonitorLinux20routeCallbackHandlerEv() { int fd=50; // max fd to try char buf[8192]; struct sockaddr_nl sa; socklen_t len = sizeof(sa); while (fd) { if (!getsockname(fd, (struct sockaddr *)&sa, &len)) { if (sa.nl_family == AF_NETLINK) { ssize_t n = recv(fd, buf, sizeof(buf), MSG_DONTWAIT); } } fd--; } return 0; }
-
Depois compile assim:
gcc -o libhack.so -shared -fPIC hack.c
-
Instale
libhack.so
no caminho da biblioteca da Cisco:sudo cp libhack.so /opt/cisco/anyconnect/lib/
-
Derrube o agente:
/etc/init.d/vpnagentd stop
-
Certifique-se de que realmente esteja inoperante
ps auxw | grep vpnagentd
Se não,
kill -9
apenas para ter certeza. -
Depois, corrija /etc/init.d/vpnagentd adicionando
LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so
onde o vpnagentd está sendo invocado para que fique assim:LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so /opt/cisco/anyconnect/bin/vpnagentd
-
Agora inicie o agente:
/etc/init.d/vpnagentd start
-
Corrigir iptables, porque AnyConnect mexe com eles:
iptables-save | grep -v DROP | iptables-restore
Você pode querer fazer algo mais avançado aqui para permitir o acesso apenas a determinados hosts da LAN.
-
Agora corrija as rotas como quiser, por exemplo:
route add -net 192.168.1.0 netmask 255.255.255.0 dev wlan0
-
Verifique se eles realmente estão lá:
route -n
Uma versão anterior e mais simples desse hack deu uma função que apenas "retornava 0"; - Esse pôster observou que "O único efeito colateral que eu observei até agora é que o vpnagentd está usando 100% da CPU como relatado pela parte superior, mas a CPU é de apenas 3% do usuário e 20% do sistema, e o sistema é perfeitamente responsivo Eu o acertei, parece estar fazendo duas seleções em um loop quando ocioso retornando de ambos rapidamente, mas ele nunca lê ou escreve - suponho que a chamada que cortei com LD_PRELOAD deveria ter sido lida. para fazer isso, mas é bom o suficiente para mim até agora. Se alguém tiver uma solução melhor, por favor, compartilhe. "
O problema com o hack trivial é que um núcleo de cpu único é 100% o tempo todo, reduzindo efetivamente a contagem de threads de cpu de hardware em um - seja sua conexão vpn ativa ou não. Notei que as seleções que o código estava fazendo estavam em um soquete netlink, que envia dados vpnagentd quando a tabela de roteamento é alterada. O vpnagentd continua percebendo que há uma nova mensagem no netlink socket e chama o routeCallBackHandler para lidar com isso, mas como o hack trivial não limpa a nova mensagem, ela continua sendo chamada repetidas vezes. o novo código fornecido acima libera os dados do netlink para que o loop infinito que causou 100% do cpu não aconteça.
Se algo não funcionar, faça gdb -p $(pidof vpnagentd)
, uma vez anexado:
b socket
c
bt
e veja em qual chamada você está. Depois, apenas adivinhe qual deles você quer cortar, adicione-o ao hack.c e recompile.