OpenVPN, quanto nesta palavra. Um servidor VPN de código aberto gratuito, com várias plataformas, configurável de maneira flexível e flexível, que na verdade é o padrão padrão para organizar o acesso a redes corporativas internas. A maioria dos administradores o usa com configurações padrão ou com configurações típicas amplamente descritas em diferentes HOW-TOs. Mas o OpenVPN é tão simples quanto parece à primeira vista? Neste artigo, consideraremos os mecanismos internos do OpenVPN, ocultos aos olhos, que alteram drasticamente a ideia de suas capacidades.
O servidor OpenVPN é distribuído na forma de código-fonte ou pacotes compilados prontos para instalar para vários sistemas operacionais. O OpenSSL é usado como uma biblioteca que fornece criptografia.
A maioria das configurações para conectar clientes ao servidor, bem como entre servidores, envolve o uso de várias chaves privadas ou privadas / públicas para garantir a segurança do tráfego interno. Para redes corporativas no modo MultiPoint-para-SinglePoint, geralmente é usada uma autoridade de certificação PKI, fácil de construir usando easy-rsa ou XCA . Para comunicação entre servidores ponto a ponto, uma configuração de chave compartilhada é usada principalmente. Lembre-se dos mecanismos e recursos básicos e conhecidos.
Principais mecanismos e capacidades
Autenticação de certificado
Uma enorme quantidade de documentação foi escrita sobre isso. O ponto é simples. Está sendo criada uma autoridade de certificação que emite certificados de usuário. Com a ajuda de uma autoridade de certificação, é fornecido controle para conectar usuários ao servidor OpenVPN. Quando o certificado expira ou é revogado, o acesso do usuário é bloqueado. As chaves privadas com uma senha definida nelas, emitida em conjunto com o certificado, fornecem segurança contra conexões não autorizadas a recursos internos.
Chaves ponto a ponto privadas
Do ponto de vista de conectar apenas um usuário / servidor aos recursos da empresa, um esquema com chaves privadas é usado. Uma chave é gerada em um dos hosts, que é compartilhado entre o servidor e o cliente.
Em todos os casos de conexão para segurança do handshake "handshake" entre o cliente e o servidor, o protocolo Diffie-Hellmann é usado.
Autenticação de usuário externo
Para simplificar o controle sobre as conexões do usuário, em vez de um esquema com sua própria PKI, você pode usar um esquema com autenticação de usuário externo por login / senha . Esse esquema é conveniente para autenticar usuários por, digamos, um login / senha de domínio. Para conectar-se ao servidor, o certificado do servidor e a chave de assinatura do pacote HARDENING OPENVPN SECURITY são adicionados ao arquivo de configuração do cliente.
exemplo de configuração do cliente
dev tun proto udp # IP OpenVPN remote 172.16.111.166 # Port port 1200 client resolv-retry infinite tls-client key-direction 1 auth SHA1 cipher BF-CBC #comp-lzo persist-key persist-tun # auth-user-pass c:/temp/pass.txt # # just create a file with name pass.txt # and put to it two lines # ------------- #username #password # ------------- #auth-user-pass verb 3 <ca> -----BEGIN CERTIFICATE----- MIIE5jCCA86gAwIBAgIJAOt3kFH7PxA0MA0GCSqGSIb3DQEBCwUAMIGjMQswCQYD .... -----END CERTIFICATE----- </ca> <tls-auth> -----BEGIN OpenVPN Static key V1----- 83ddd29fa82212f3059d85a41490134c .... a4f2c7df3a22364a49093bca102dedeb -----END OpenVPN Static key V1----- </tls-auth>
Parte da configuração do servidor para autenticação do cliente via arquivo
Usando métodos de autenticação alternativos
verify-client-cert none #client-cert-not-required username-as-common-name tls-server tls-auth /usr/local/etc/openvpn/ssl/tlsauth.key key-direction 0 tls-timeout 120 auth SHA1 cipher BF-CBC auth-user-pass-verify /usr/local/etc/openvpn/auth/auth-static-file.pl via-file
Esse esquema é conveniente, mas muito inseguro.
PAM
Para aumentar a segurança, você pode usar plug-ins que fornecem verificação de login / senha em sistemas externos. O método mais comum é o PAM do sistema (Módulos de autenticação conectáveis).
Adicione a linha ao arquivo de configuração OpenVPN
plugin /usr/share/openvpn/plugin/lib/openvpn-auth-pam.so login
Encaminhamento
Porque A principal tarefa do servidor é fornecer aos usuários / servidores remotos acesso a recursos internos; o servidor permite determinar o roteamento estático dos clientes para o servidor e do servidor para os clientes. Do ponto de vista do acesso do cliente aos recursos internos, o servidor que usa DHCP e as diretivas "rota" ou "rota de envio" permitem transferir rotas de rede internas para o cliente. Para notificar o próprio servidor sobre redes remotas no lado do cliente, é usado "dir de configuração do cliente" (ccd), um mecanismo que permite usar a diretiva "iroute" para descrever a lista de redes internas do cliente que devem estar na tabela de roteamento do servidor para trafegar o tráfego para elas.
Nesse recurso "comum", amplamente utilizado, termina a personalização local e final para cada caso específico.
Recursos adicionais do OpenVPN
Considere os recursos adicionais do OpenVPN, dos quais alguém já deve ter ouvido falar, mas, na realidade, não viu ou usou.
Segurança de rede / filtragem de pacotes
Porque O OpenVPN direciona o tráfego, possui dois modos de operação regulares mutuamente exclusivos. O primeiro modo é o roteamento dentro do servidor OpenVPN, o segundo modo é o roteamento nuclear entre interfaces. No primeiro caso, o OpenVPN é responsável por alternar e filtrar pacotes entre clientes / redes; no segundo caso, qualquer filtro de pacote do sistema suportado no host (pf, iptables, etc).
Poucas pessoas sabem que o OpenVPN possui um filtro de pacotes interno que permite permitir ou isolar conexões entre usuários e redes.
Sim sim Você leu certo. O OpenVPN possui seu próprio filtro de pacotes embutido. A capacidade de filtrar o tráfego foi implementada em 2010 .
O filtro de pacotes OpenVPN é controlado pela interface de gerenciamento ou por plug-ins conectados ao OpenVPN.
As regras de tráfego são gerenciadas através de um arquivo. O formato do arquivo é simples.
[CLIENTS DROP|ACCEPT] {+|-}common_name1 {+|-}common_name2 . . . [SUBNETS DROP|ACCEPT] {+|-}subnet1 {+|-}subnet2 . . . [END]
As diretivas de bloco (ACCEPT / DENY) definem a ação padrão para todos os clientes não especificados dentro do bloco.
Por exemplo, arquivo para o usuário user2
[CLIENTS DROP] +user1 [SUBNETS DROP] [END]
bloqueará o tráfego para todos os usuários e redes, mas permitirá o tráfego para o cliente1. Se o usuário1 não descrever explicitamente a permissão para transferir tráfego para o usuário2, o tráfego seguirá apenas em uma direção user2-> user1.
Ou outro exemplo.
Desative tudo, exceto o acesso entre usuários e o servidor DNS localizado na rede local e o circuito de teste na rede 192.168.0.0/24
[CLIENTS DROP] +user1 +user2 [SUBNETS DROP] +10.150.0.1 +10.150.1.1 +192.168.0.0/24 [END]
O mecanismo de filtragem é ativado por meio do arquivo de configuração ou ao conectar o plug-in que "define" o sinalizador "OPENVPN_PLUGIN_ENABLE_PF".
Discutiremos essa oportunidade mais tarde.
O segundo modo de filtragem de tráfego é o filtro de pacotes embutido no sistema. Para ativá-lo, a configuração não deve ter uma diretiva "cliente para cliente". Do ponto de vista da automação da ativação / desativação das regras necessárias ao conectar / desconectar clientes, é mais conveniente usar inserções separadas na lista de regras, implementadas por meio de CHAINS in Iptables (Linux) ou em Anchors in PF (FreeBSD). A ativação / desativação de regras geralmente é feita por meio das diretivas de conexão / desconexão do cliente no arquivo de configuração do servidor, que chamam os scripts correspondentes quando o usuário se conecta / desconecta.
Autenticação avançada de PAM
A autenticação estendida do PAM significa alterar a lógica do login do usuário e da verificação de senha. Isso é obtido instalando os plug-ins apropriados para o OpenVPN, que fornecem leitura e verificação de dados em fontes externas, ou conectando bibliotecas ao sistema que permitem que qualquer lógica seja script. Uma dessas bibliotecas é o pam_python , que ajuda a criar scripts para qualquer lógica de verificação de login / senha por meio de scripts Python.
Se for usada, a sequência de verificação do usuário será alterada da seguinte maneira.
plugin openvpn-plugin-auth-pam.so pam_python login USERNAME password PASSWORD domain mydomain.com
Como o “under the hood” do PAM são os algoritmos de diálogo do sistema com o usuário ou as bibliotecas externas, esses diálogos podem ser controlados. Por exemplo, conecte tokens OTP ao sistema . A biblioteca LinOTP é tomada simplesmente como exemplo, porque Perdi minha própria biblioteca auto-escrita durante os testes em algum lugar ¯ \ (ツ) / ¯
Além disso, os exemplos são facilmente pesquisados pela palavra "pam_python".
O principal problema ao trabalhar com módulos PAM externos é a incapacidade de obter o ambiente de sessão do OpenVPN dentro do Python chamado ou qualquer outro script chamado através do pam do sistema. I.e. o script fornece apenas as funções para verificar o login / senha atribuídos a ele.
Autenticação Adiada
O servidor OpenVPN suporta a chamada autenticação "atrasada". A autenticação "atrasada" é usada nos casos em que o serviço de autenticação não pode atender à solicitação de verificação de login / senha em tempo real.
Plugins OpenVPN
Este é um universo paralelo separado, sobre o qual pode ser conhecido, mas, devido a alguma confusão, eles não conseguem ou têm medo de usar. De fato, escrever um plug-in funcional para o OpenVPN requer programação em C com tudo o que isso implica. Exemplos de plugins simples estão incluídos na árvore de código-fonte do OpenVPN ou , por exemplo, existe um plug - in para demonstrar as chamadas de método do OpenVPN .
Vamos tentar descobrir como os plugins funcionam no OpenVPN.
Funções e parâmetros usados para trabalhar com plugins são descritos em um arquivo separado
A principal tarefa do plug-in, quando é inicializada pelo servidor OpenVPN, é transferir a lista de funções suportadas pelo plug-in e, ao chamar qualquer uma das funções, retornar o código de resposta correto, que ficará claro para o servidor.
#define OPENVPN_PLUGIN_FUNC_SUCCESS 0 #define OPENVPN_PLUGIN_FUNC_ERROR 1 #define OPENVPN_PLUGIN_FUNC_DEFERRED 2
Vamos nos aprofundar mais em cada grupo. Vamos considerar a lógica do trabalho com base na autenticação de senha do usuário.
Quando o servidor inicia, após a leitura do arquivo de configuração, o servidor chama as funções OPENVPN_PLUGIN_UP e OPENVPN_PLUGIN_ROUTE_UP. No ambiente variável das funções chamadas, os principais parâmetros do servidor em execução são transferidos.
OPENVPN_PLUGIN_UP { "route_netmask_1":"255.255.0.0", "daemon_start_time":"1545994898", "ifconfig_remote":"10.150.0.2", "local_1":"172.16.100.139", "script_context":"init", "config":"/usr/local/etc/openvpn/server150.conf", "link_mtu":"1622", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "verb":"2", "daemon_pid":"626", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "daemon_log_redirect":"1", "daemon":"1", "route_net_gateway":"172.16.100.1", "dev_type":"tun", "route_gateway_1":"10.150.0.2", "remote_port_1":"1200", "dev":"tun150", "pluginid":"0", "local_port_1":"1200", "route_network_1":"10.150.0.0" }
OPENVPN_PLUGIN_ROUTE_UP { "route_netmask_1":"255.255.0.0", "daemon_start_time":"1545994898", "redirect_gateway":"0", "ifconfig_remote":"10.150.0.2", "local_1":"172.16.100.139", "script_context":"init", "config":"/usr/local/etc/openvpn/server150.conf", "link_mtu":"1622", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "verb":"2", "daemon_pid":"626", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "daemon_log_redirect":"1", "daemon":"1", "route_net_gateway":"172.16.100.1", "dev_type":"tun", "route_gateway_1":"10.150.0.2", "remote_port_1":"1200", "dev":"tun150", "pluginid":"2", "local_port_1":"1200", "route_network_1":"10.150.0.0" }
Essas funções podem ser usadas para alertas na inicialização do servidor ou alterações na configuração.
Ao conectar um cliente, o OpenVPN solicita a capacidade de ativar um filtro de pacotes interno.
OPENVPN_PLUGIN_ENABLE_PF { "route_netmask_1":"255.255.0.0", "daemon_start_time":"1545994898", "redirect_gateway":"0", "ifconfig_remote":"10.150.0.2", "local_1":"172.16.100.139", "script_context":"init", "config":"/usr/local/etc/openvpn/server150.conf", "link_mtu":"1622", "pf_file":"/tmp/openvpn_pf_b7a18ca8fac838679ca87ada6b8a356.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "verb":"2", "daemon_pid":"626", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "daemon":"1", "daemon_log_redirect":"1", "dev_type":"tun", "route_gateway_1":"10.150.0.2", "remote_port_1":"1200", "dev":"tun150", "pluginid":"11", "local_port_1":"1200", "route_network_1":"10.150.0.0" }
Como você pode ver no dump, a variável pf_file apareceu. Este arquivo deve conter as regras do filtro de pacotes interno para a sessão atual que está sendo processada.
Em seguida, o nome de usuário e a senha do usuário são verificados na função OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "IV_NCP":"2", "IV_COMP_STUB":"1", "daemon_start_time":"1545994898", "IV_LZ4":"1", "redirect_gateway":"0", "ifconfig_remote":"10.150.0.2", "untrusted_port":"1200", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "link_mtu":"1622", "pf_file":"/tmp/openvpn_pf_b7a18ca8fac838679ca87ada6b8a356.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_a3d0650a43b88ca1b5f305ce2c8f682.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"2", "IV_PLAT":"win", "daemon_pid":"626", "password":"12312312312312", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "remote_port_1":"1200", "dev":"tun150", "pluginid":"5", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" }
Este é o único local em que a senha no ambiente variável está presente de forma clara.
O resultado desta função deve ser três respostas possíveis.
#define OPENVPN_PLUGIN_FUNC_SUCCESS 0 #define OPENVPN_PLUGIN_FUNC_ERROR 1 #define OPENVPN_PLUGIN_FUNC_DEFERRED 2
Se o servidor receber uma resposta OPENVPN_PLUGIN_FUNC_DEFERRED, o mecanismo de autenticação "atrasada" entra em operação. Como vemos, a variável "auth_control_file" apareceu no ambiente da variável, o conteúdo dessa variável contém o nome do arquivo no qual uma resposta do sistema de autenticação será esperada. A resposta é o símbolo 0 (para permitir acesso), 1 (para negar acesso) colocado no arquivo especificado. O parâmetro do servidor "janela manual" determina o tempo limite em segundos, durante os quais o servidor aguardará uma resposta. Enquanto aguarda, o tráfego de outros clientes não é interrompido.
Como trabalhamos com autenticação de senha, a função de verificação de certificado OPENVPN_PLUGIN_TLS_VERIFY não é chamada. Em vez disso, OPENVPN_PLUGIN_TLS_FINAL é chamado imediatamente, confirmando o estabelecimento da sessão.
OPENVPN_PLUGIN_TLS_FINAL { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "IV_NCP":"2", "IV_COMP_STUB":"1", "daemon_start_time":"1545994898", "IV_LZ4":"1", "redirect_gateway":"0", "ifconfig_remote":"10.150.0.2", "untrusted_port":"1200", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "link_mtu":"1622", "pf_file":"/tmp/openvpn_pf_b7a18ca8fac838679ca87ada6b8a356.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_a3d0650a43b88ca1b5f305ce2c8f682.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"2", "IV_PLAT":"win", "daemon_pid":"626", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "remote_port_1":"1200", "dev":"tun150", "pluginid":"10", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" }
Em seguida, é chamada a chamada OPENVPN_PLUGIN_IPCHANGE, que é chamada antes de alterar o endereço IP do cliente.
OPENVPN_PLUGIN_IPCHANGE { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "trusted_ip":"172.16.111.168", "link_mtu":"1622", "IV_COMP_STUB":"1", "daemon_start_time":"1547319280", "IV_LZ4":"1", "redirect_gateway":"0", "common_name":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "ifconfig_remote":"10.150.0.2", "IV_NCP":"2", "untrusted_port":"1200", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "trusted_port":"1200", "pf_file":"/tmp/openvpn_pf_4fcad505693b33f97c4fe105df8681cb.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_321bb12075dc0e1b5440d227220bac5d.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"3", "IV_PLAT":"win", "daemon_pid":"52435", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "remote_port_1":"1200", "dev":"tun150", "pluginid":"3", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" }
A função OPENVPN_PLUGIN_CLIENT_CONNECT_V2 é chamada quando o endereço IP é definido pelo servidor DHCP interno.
OPENVPN_PLUGIN_CLIENT_CONNECT_V2 { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "trusted_ip":"172.16.111.168", "link_mtu":"1622", "IV_COMP_STUB":"1", "daemon_start_time":"1547319280", "IV_LZ4":"1", "dev":"tun150", "common_name":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "time_ascii":"Sat Jan 12 18:54:48 2019", "ifconfig_remote":"10.150.0.2", "IV_NCP":"2", "untrusted_port":"1200", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "trusted_port":"1200", "pf_file":"/tmp/openvpn_pf_4fcad505693b33f97c4fe105df8681cb.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_321bb12075dc0e1b5440d227220bac5d.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"3", "IV_PLAT":"win", "daemon_pid":"52435", "time_unix":"1547319288", "redirect_gateway":"0", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "remote_port_1":"1200", "ifconfig_pool_local_ip":"10.150.0.5", "pluginid":"9", "ifconfig_pool_remote_ip":"10.150.0.6", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" }
Em um ambiente variável, as variáveis aparecem contendo os parâmetros do túnel "ifconfig_pool_local_ip" e "ifconfig_pool_remote_ip".
A função OPENVPN_PLUGIN_LEARN_ADDRESS é chamada quando o servidor OpenVPN aprende a conexão de endereços IP e as rotas para eles. Depois de sair dessa função, o procedimento para aplicar as configurações do filtro de pacotes do arquivo é ativado. A variável de ambiente OPENVPN_PLUGIN_LEARN_ADDRESS nesse caso corresponde à fase OPENVPN_PLUGIN_CLIENT_CONNECT_V2.
fa56bf61-.../172.16.111.168:1200 ----- pf_check_reload : struct pf_context ----- fa56bf61-.../172.16.111.168:1200 enabled=1 fa56bf61-.../172.16.111.168:1200 filename='/tmp/openvpn_pf_343330698e4acdea34c8a8c7fb87d861.tmp' fa56bf61-.../172.16.111.168:1200 file_last_mod=1547319124 fa56bf61-.../172.16.111.168:1200 n_check_reload=1 fa56bf61-.../172.16.111.168:1200 reload=[1,15,1547319125] fa56bf61-.../172.16.111.168:1200 ----- struct pf_set ----- fa56bf61-.../172.16.111.168:1200 kill=0 fa56bf61-.../172.16.111.168:1200 ----- struct pf_subnet_set ----- fa56bf61-.../172.16.111.168:1200 default_allow=ACCEPT fa56bf61-.../172.16.111.168:1200 ----- struct pf_cn_set ----- fa56bf61-.../172.16.111.168:1200 default_allow=DROP fa56bf61-.../172.16.111.168:1200 12345678-90da-11e8-bf33-005056a12a82-1234567 ACCEPT fa56bf61-.../172.16.111.168:1200 fa56bf61-90da-11e8-bf33-005056a12a82-1234567 ACCEPT fa56bf61-.../172.16.111.168:1200 ---------- fa56bf61-.../172.16.111.168:1200 fa56bf61-90da-11e8-bf33-005056a12a82-1234567 ACCEPT fa56bf61-.../172.16.111.168:1200 12345678-90da-11e8-bf33-005056a12a82-1234567 ACCEPT fa56bf61-.../172.16.111.168:1200 --------------------
Quando um cliente é desconectado, a função OPENVPN_PLUGIN_CLIENT_DISCONNECT é chamada.
OPENVPN_PLUGIN_CLIENT_DISCONNECT { "route_netmask_1":"255.255.0.0", "route_gateway_1":"10.150.0.2", "trusted_ip":"172.16.111.168", "link_mtu":"1622", "IV_COMP_STUB":"1", "daemon_start_time":"1547319280", "IV_LZ4":"1", "dev":"tun150", "common_name":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "time_ascii":"Sat Jan 12 18:54:48 2019", "bytes_received":"30893", "IV_NCP":"2", "untrusted_port":"1200", "ifconfig_remote":"10.150.0.2", "IV_LZ4v2":"1", "local_1":"172.16.100.139", "script_context":"init", "untrusted_ip":"172.16.111.168", "config":"/usr/local/etc/openvpn/server150.conf", "username":"fa56bf61-90da-11e8-bf33-005056a12a82-1234568", "trusted_port":"1200", "pf_file":"/tmp/openvpn_pf_4fcad505693b33f97c4fe105df8681cb.tmp", "ifconfig_local":"10.150.0.1", "tun_mtu":"1500", "auth_control_file":"/tmp/openvpn_acf_4bdddbada2885cde42cd3cb1b85d77e5.tmp", "daemon":"1", "IV_COMP_STUBv2":"1", "verb":"3", "IV_PLAT":"win", "daemon_pid":"52435", "time_unix":"1547319288", "redirect_gateway":"0", "route_vpn_gateway":"10.150.0.2", "proto_1":"udp", "route_net_gateway":"172.16.100.1", "IV_PROTO":"2", "daemon_log_redirect":"1", "time_duration":"3781", "dev_type":"tun", "IV_VER":"2.4.3", "IV_LZO":"1", "bytes_sent":"22684", "remote_port_1":"1200", "ifconfig_pool_local_ip":"10.150.0.5", "pluginid":"7", "ifconfig_pool_remote_ip":"10.150.0.6", "local_port_1":"1200", "IV_TCPNL":"1", "route_network_1":"10.150.0.0" }
Em um ambiente variável, a duração da conexão e o tráfego do usuário são adicionados.
Como você pode ver, devido à abundância de dados em diferentes chamadas, escrever e depurar um plug-in na linguagem de programação C (C ++) será uma tarefa bastante demorada.
Para expandir a funcionalidade, decidiu-se fazer um "milagre" primeiro para o projeto interno e depois publicá-lo :)
Após uma longa leitura dos códigos fonte do OpenVPN e vários exemplos de plugins altamente especializados, foi criado um projeto que usa o Python como a linguagem de programação para a lógica de processamento da sessão. O código é um plug-in na linguagem C que se conecta ao OpenVPN, que envia todas as solicitações ao plug-in, envia o módulo para Python através da referência c-api .
OpenVPN plugin proxy python
Por que o módulo Python?
A referência c-api do Python, trabalhando diretamente com arquivos python, não funciona corretamente com o carregamento de bibliotecas python.
Como isso funciona?
Quando o plugin é inicializado no OpenVPN, ele retorna uma lista mascarada de todas as funções que ele pode servir. Quando a próxima fase da conexão ou evento interno ocorrer, o OpenVPN chama as funções correspondentes do plug-in. O plug-in converte a variável de ambiente e os parâmetros passados para a função em uma estrutura, inicializa o python e passa a estrutura para o procedimento correspondente do módulo python. O procedimento retorna uma das três respostas ao plug-in (0 - Sucesso, 1 - Erro, 2 - Adiado). A resposta é transformada e retornada pelo OpenVPN.
Observe que todas as chamadas do módulo são "sem estado", o que significa que os procedimentos não se lembram e não sabem o que aconteceu anteriormente em outras chamadas. Você pode focar apenas no ambiente variável passado para o plug-in do OpenVPN.
Dentro do módulo python, você pode implementar qualquer lógica conectando as bibliotecas e os recursos necessários. Se você não tiver certeza da velocidade das verificações, use as confirmações "pendentes".
Usando o agrupamento de usuários conectados ao serviço, através do pf_file, você pode ajustar bastante a interação da rede entre usuários e outros recursos. Por sua vez, conectando o plug-in para monitoramento, sempre será possível gerenciar sessões do cliente por meio da interface de gerenciamento OpenVPN.
Durante o teste do projeto, um mecanismo de geração de senha foi desenvolvido, semelhante aos tokens jwt, mas com um tamanho menor.
O ponto é simples. O token contém o identificador do cliente e a data de validade do acesso. Para assinar o token, é utilizado o HMAC_SHA1 com uma chave privada. Após a assinatura do token, o conteúdo do texto é corrompido pela assinatura e convertido em base64. Assim, a "vedação" do token é obtida. Um token selado é usado como senha do usuário. Se ocorrer uma alteração não autorizada de um bloco de dados, xor interrompe, se xor interrompe, a verificação de assinatura é interrompida. Sem uma chave privada, a assinatura não pode ser alterada.
Se você não deseja controlar manualmente o horário da senha, gere esse token e verifique a validade dentro do plug-in sem chamar serviços externos. Esse esquema é muito conveniente para a geração de senha da sessão por um determinado período. Ao mesmo tempo, você pode transferir o conteúdo do token para um sistema de controle externo e ele se configurará para desconectar o usuário após a expiração do token.
Espero que as informações neste artigo tenham sido úteis para você.
Obrigado por reservar um tempo para lê-lo.
Se você tiver alguma dúvida, tentarei responder o que puder.
© Aborche 2019
