Esta é uma continuação da minha pergunta anterior no envio de rotas estáticas da implementação do servidor Freeradius DHCP em combinação com o servidor Strongswan VPN.
Ao depurar o Freeradius usando o tcpdump e o Wireshark, descobri que posso enviar rotas estáticas sem classes do servidor DHCP do Freeradius adicionando DHCP-Classless-Static-Route
e DHCP-Site-specific-25
(também conhecido como rota estática da Microsoft) opções para minhas DHCP-Discover
e DHCP-Request
seções do arquivo de configuração do servidor dhcp.
No entanto: Parece que as rotas estáticas não são aceitas pelo cliente VPN da Microsoft se eu definir o gateway padrão 0.0.0.0
como sugerido pela documentação do Strongswan .
Pelo menos não consigo encontrar as rotas anunciadas no meu cliente Windows ao usar o route print -4
.
Também não consigo adicionar as rotas manualmente no cliente Windows quando estou usando 0.0.0.0
como gateway padrão sobre a interface VPN.
No entanto:
Digamos que eu queira acessar a sub -rede 192.168.200.0/24
pela VPN e meu servidor VPN atribua o endereço 192.168.201.2/24
ao meu cliente Windows. Então é realmente possível criar uma rota estática no lado do cliente Windows declarando que a sub-rede 192.168.200.0/24 é acessível via 192.168.201.2 usando o comando windows:
route add 192.168.200.0 mask 255.255.255.0 192.168.201.2
Eu sei que parece um pouco estranho, mas posso fazer ping em qualquer host na 192.168.200.0
sub-rede, então, desde que funcione, estou feliz. :-)
Mas: eu ficaria mais feliz se pudesse fazer a mesma coisa anunciando as rotas do meu servidor VPN em vez de fazê-lo manualmente em todos os clientes VPN. :-)
Isso significa que eu tenho que fazer um pouco de programação dinâmica para a configuração do DHCP no Freeradius. No meu caso, significa que tenho que fazer uma referência a um módulo perl em DHCP-Discover e DHCP-request que pega o endereço IP vpn do cliente atribuído, converte-o em octetos e combina-o com as rotas estáticas que também são fornecidas como octetos.
Um exemplo:
A sub -rede 192.168.200.0/24
será codificada como 0x18c0a8c8
a máscara de sub-rede é codificada primeiro.
O cliente 192.168.201.2/24
será codificado como se estivesse 0xc0a8c902
apenas convertendo cada número no endereço IP para hexadecimal.
A codificação final para a rota será: 0x18c0a8c8c0a8c902
pois é apenas uma concatinação das duas strings.
Então eu tenho que usar update reply
com o seguinte código:
update reply {
&DHCP-Classless-Static-Route = 0x18c0a8c8c0a8c902
&DHCP-Site-specific-25 = 0x18c0a8c8c0a8c902
}
Se houver mais rotas, todas as rotas serão concatenadas em uma longa string.
A parte complicada:
Suponha que você tenha a configuração padrão do servidor DHCP do Freeradius conforme encontrado no freeradius/3.0/sites-available/dhcp
arquivo.
A estrutura geral do arquivo para DHCP-Discover e DHCP-Request é a seguinte:
dhcp DHCP-Request {
update reply {
&DHCP-Message-Type = DHCP-Ack
}
update reply {
# General DHCP options, such as default GW, DNS, IP-address lease time etc.
}
update control {
&Pool-Name := "vpn_pool"
}
dhcp_sqlippool
ok
}
Então, pelo que entendi, preciso chamar meu módulo perl depois de dhcp_sqlippool
ter sido chamado e antes de retornar ok
, porque dhcp_sqlippool
é o módulo que atribui o endereço IP ao cliente VPN.
Isso significa que minha versão seria algo como:
dhcp DHCP-Request {
update reply {
&DHCP-Message-Type = DHCP-Ack
}
update reply {
# General DHCP options, such as default GW, DNS, IP-address lease time etc.
}
update control {
&Pool-Name := "vpn_pool"
}
dhcp_sqlippool
perl
# If perl module returned no error
if(ok) {
update reply {
# Perl-Route contains a hex encoded string with all routes.
&DHCP-Classless-Static-Route = Perl-Route
&DHCP-Site-specific-25 = Perl-Route
}
}
# Not sure if this one is needed?
update reply {
&DHCP-End-Of-Options = 255
}
ok
}
Para fazê-lo funcionar, eu tenho que habilitar o perl na freeradius/3.0/mods-enabled
pasta e modificar o nome do arquivo freeradius/3.0/mods-enabled/perl
para apontá-lo para o meu módulo perl. Como por exemplo:
filename = ${modconfdir}/${.:instance}/dhcp/Options.pm
Mas como faço para referenciar a chamada para perl da maneira correta?
Eu pensei que tinha que habilitar a linha func_post_auth = post_auth
e freeradius/3.0/mods-enabled/perl
criar uma sub post_auth
seção no meu módulo perl para lidar com chamadas do Freeradius, mas pelo que posso ver no meu log, recebo o seguinte erro no Freeradius:
(8) perl: perl_embed:: module = /etc/freeradius/3.0/mods-config/perl/dhcp/Options.pm ,
func = post_auth exit status= Undefined subroutine &main::post_auth called.
...
(8) [perl] = fail
(8) } # dhcp DHCP-Discover = fail
Então, o que é que eu não estou vendo?
Bati minha cabeça contra a parede algumas vezes, mas pelo menos consegui que o módulo perl funcionasse, embora não esteja completamente onde quero estar, já que o roteamento estático via DHCP não passa do servidor DHCP do Freeradius para o cliente VPN via Strongswan , mas depurar pacotes UDP do servidor DHCP do Freeradius implica que o problema está em outro lugar.
De qualquer forma aqui está o que eu fiz:
freeradius/3.0/mods-enabled
e defina pelo menos as seguintes linhas:freeradius/3.0/sites-enabled/dhcp
Os locais relevantes sãoDHCP-Discover
eDHCP-Request
:freeradius/3.0/mods-config/perl/dhcp/Options.pm
:O código perl pode ser ajustado a partir daqui, então a opção 121 ou a opção 249 é enviada dependendo do sistema operacional do cliente.
Deixo também a possibilidade de tornar o código mais genérico, para que as rotas estáticas possam ser definidas diretamente no arquivo de configuração do Freeradius para o leitor.