Chegou a tarefa de organizar a emissão de endereços IP para os assinantes. Condições da tarefa:
- Não forneceremos um servidor separado para autorização - você gerenciará;)
- Os assinantes devem receber configurações de rede via DHCP
- A rede é diversa. Este é um equipamento PON e comutadores comuns com opção 82 e base WiFi configuradas com pontos
- Se os dados não se enquadrarem em nenhuma das condições de emissão de IP, é necessário emitir o IP da rede “convidada”
Desde o bem: existe um servidor no FreeBSD que pode "funcionar", mas está "longe";), não "diretamente nesta rede".
Há também um maravilhoso dispositivo Mikrotik. O diagrama geral da rede é mais ou menos assim:

Após um pouco de reflexão, decidiu-se usar os assinantes do FreeRadius para emitir as configurações de rede. Em princípio, o esquema é o habitual: no Microtick, ligamos o servidor DHCP, nele o mesmo Radius Client. Nós configuramos um monte de servidor DHCP -> Cliente Radius -> servidor Radius.
Parece não ser difícil. Mas! O diabo está nos detalhes. Ou seja:
- Quando o PON OLT é autorizado de acordo com esse esquema, uma solicitação é enviada ao FreeRadius com um Nome de usuário igual ao endereço MAC da estação principal, ID do circuito do agente igual ao MAC do MAC Onu e uma senha vazia.
- Ao autorizar com comutadores com a opção 82, chega ao FreeRadius uma solicitação com um Nome de usuário vazio igual ao dispositivo MAC do assinante e os atributos adicionais adicionais Agent-Circuit-Id e Agent-Remote-Id que contêm, novamente, o comutador de relé MAC e a porta à qual o assinante está conectado.
- Alguns assinantes com pontos WiFI são autorizados através dos protocolos PAP-CHAP
- Alguns assinantes com pontos WIFI são autorizados com um Nome de usuário igual ao endereço MAC do ponto WIFI, sem uma senha.
Antecedentes históricos: O que é a opção 82 para DHCP
Essas são opções adicionais para o protocolo DHCP que permitem transferir informações adicionais, por exemplo, nos campos ID do circuito do agente e ID remota do agente. Geralmente é usado para transmitir o endereço MAC do comutador de relé e a porta à qual o assinante está conectado. No caso de equipamentos PON ou estações base WIFI, o campo Agent-Circuit-Id não carrega informações úteis (não há porta de assinante). Nesse caso, o esquema geral do DHCP nesse caso é o seguinte:

Passo a passo, esse esquema funciona assim:
- O equipamento do assinante faz uma solicitação DHCP de broadcast para configurações de rede
- O dispositivo (por exemplo, um comutador, uma estação base WiFi ou PON) à qual o equipamento do assinante está diretamente conectado "intercepta" esse pacote e o modifica, introduzindo as opções adicionais do endereço IP do agente Opção 82 e de retransmissão nele e o transfere ainda mais pela rede.
- O servidor DHCP aceita a solicitação, forma uma resposta e a envia para o dispositivo de retransmissão
- O dispositivo de retransmissão encaminha o pacote de resposta ao dispositivo do assinante
Portanto, tudo isso simplesmente não funciona, é claro, você precisa da configuração apropriada do equipamento de rede.
Instale o FreeRadius
Com as definições de configuração do FreeRadius, é claro, você pode conseguir tudo isso, mas é difícil e não está claro ... especialmente quando você bisbilhota depois de N meses "tudo funciona". Portanto, foi decidido escrever seu módulo de autorização para o FreeRadius em Python. Tomaremos os dados para autorização do banco de dados MySQL. Não faz sentido descrever sua estrutura, de qualquer maneira, todos farão isso "por si mesmos". Particularmente, peguei a estrutura proposta com o módulo sql para o FreeRadius e a alterei levemente adicionando o campo mac e port para cada assinante, além da senha de login.
Portanto, para iniciantes, instale o FreeRadius:
cd /usr/ports/net/freeradius3 make config make install clean
Nas configurações, marcamos para instalação:

Criamos um link simbólico para o módulo python (ou seja, ativamos):
ln -s /usr/local/etc/raddb/mods-available/python /usr/local/etc/raddb/mods-enabled
Instale um módulo adicional para python:
pip install mysql-connector
Nas configurações do módulo python para o FreeRadius, você precisa especificar os caminhos de pesquisa do módulo na variável python_path. Por exemplo, eu tenho isso:
python_path="/usr/local/etc/raddb/mods-config/python:/usr/local/lib/python2.7:/usr/local/lib/python27.zip:/usr/local/lib/python2.7:/usr/local/lib/python2.7/plat-freebsd12:/usr/local/lib/python2.7/lib-tk:/usr/local/lib/python2.7/lib-old:/usr/local/lib/python2.7/lib-dynload:/usr/local/lib/python2.7/site-packages"
Os caminhos podem ser encontrados executando o interpretador python e inserindo os comandos:
root@phaeton:/usr/local/etc/raddb/mods-enabled
Se você não seguir esta etapa, os scripts escritos em python e executados pelo FreeRadius não encontrarão os módulos listados na importação. Além disso, é necessário descomentar as funções de autorização e contabilidade nas configurações do módulo. Por exemplo, este módulo tem a seguinte aparência:
python { python_path="/usr/local/etc/raddb/mods-config/python:/usr/local/lib/python2.7:/usr/local/lib/python2.7/site-packages:/usr/local/lib/python27.zip:/usr/local/lib/python2.7:/usr/local/lib/python2.7/plat-freebsd12:/usr/local/lib/python2.7/lib-tk:/usr/local/lib/python2.7/lib-old:/usr/local/lib/python2.7/lib-dynload:/usr/local/lib/python2.7/site-packages" module = work mod_instantiate = ${.module} mod_detach = ${.module} mod_authorize = ${.module} func_authorize = authorize mod_authenticate = ${.module} func_authenticate = authenticate mod_preacct = ${.module} func_preacct = preacct mod_accounting = ${.module} func_accounting = accounting mod_checksimul = ${.module} mod_pre_proxy = ${.module} mod_post_proxy = ${.module} mod_post_auth = ${.module} mod_recv_coa = ${.module} mod_send_coa = ${.module} }
O script work.py (e todos os outros) deve ser colocado em / usr / local / etc / raddb / mods-config / python Existem três scripts no total.
Como você pode ver no código, estamos tentando, por todos os meios disponíveis, identificar o assinante por seus endereços MAC ou pacotes Opção 82, obviamente conhecidos, e se isso não der certo, emitiremos o endereço IP mais antigo usado na rede “convidada”. Resta configurar o script padrão na pasta habilitada para sites para que as funções necessárias do script python se contraiam nos horários indicados. De fato, basta trazer o arquivo para o formulário:
padrão server default { listen { type = auth ipaddr = * port = 0 limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } listen { ipaddr = * port = 0 type = acct limit { } } listen { type = auth port = 0 limit { max_connections = 1600 lifetime = 0 idle_timeout = 30 } } listen { ipv6addr = :: port = 0 type = acct limit { } } authorize { python filter_username preprocess expiration logintime } authenticate { Auth-Type PAP { pap python } Auth-Type CHAP { chap python } Auth-Type MS-CHAP { mschap python } eap } preacct { preprocess acct_unique suffix files } accounting { python exec attr_filter.accounting_response } session { } post-auth { update { &reply: += &session-state: } exec remove_reply_message_if_eap Post-Auth-Type REJECT { attr_filter.access_reject eap remove_reply_message_if_eap } Post-Auth-Type Challenge { } } pre-proxy { } post-proxy { eap } }
Tentamos executar e ver o que voa para o log de depuração:
/usr/local/etc/rc.d/radiusd debug
O que mais. Ao configurar o FreeRadius, é conveniente testar sua operação usando o utilitário radclient. Por exemplo, autorização:
echo "User-Name=4C:5E:0C:2E:7F:15,Agent-Remote-Id=0x9845623a8c98,Agent-Circuit-Id=0x00010006" | radclient -x 127.0.0.1:1812 auth testing123
Ou contabilidade:
echo "User-Name=4C:5E:0C:2E:7F:15,Agent-Remote-Id=0x00030f26054a,Agent-Circuit-Id=0x00010002" | radclient -x 127.0.0.1:1813 acct testing123
Quero avisar que é impossível usar um esquema e scripts semelhantes "sem alterações" em uma escala "industrial". Pelo menos impressionante:
- possível endereço MAC "falso". É suficiente que o assinante registre um MAC estrangeiro para ele e haverá problemas
- a lógica de emitir redes de convidados está abaixo de todas as críticas. Não há sequer uma verificação "você já pode ter clientes com esse endereço IP?"
É apenas uma "solução no joelho" para trabalhar especificamente nas minhas condições, nada mais. Não julgue estritamente;)