O artigo discute a configuração do OpenVPN com recursos adicionais:
- Certificados de token para autenticação primária (Rutoken como exemplo)
- Back-end LDAP para autenticação secundária (usando o ActiveDirectory como exemplo)
- filtrando recursos internos disponíveis para os usuários (via iptables)
Também descreve como configurar clientes para Linux, Windows e MacOS.
Configuração do servidor
Instale o OpenVPN
Pegue o script
Nyr / openvpn-install , execute a partir do root.
git clone https://github.com/Nyr/openvpn-install.git cd openvpn-install
O processo de inicialização fará algumas perguntas.
- protocolo udp
- porta 1194
- Servidores DNS - Local
- endereço de gateway IP externo na Internet através do qual o servidor VPN estará disponível
Há também uma versão com segurança aprimorada do script original -
github.com/Angristan/OpenVPN-install . Possui mais configurações de criptografia com explicações sobre o porquê.
Gerenciamento de usuários
AdicionandoSe os tokens não forem usados, o usuário será adicionado através do mesmo script. O script basicamente gera uma configuração ovpn personalizada e insere um certificado assinado pelo certificado raiz lá.
Se tokens forem usados (consulte a seção sobre tokens abaixo), o certificado será gravado manualmente com base na solicitação do certificado que é gerado no token. A configuração do usuário deve ser feita manualmente a partir do modelo existente (do mesmo a partir do qual o script de configuração é gerado). O modelo está aqui
/etc/openvpn/client-common.txt
. Ele não está incluído no pacote openvpn e é gerado pelo script durante o processo de configuração.
ExcluirA remoção de usuários é feita através do mesmo script de instalação. O certificado é adicionado à
CRL , a nova CRL é enviada por push ao servidor vpn. O servidor considera todos os certificados que estão na CRL inválidos e se recusa a aceitar.
Como revogar um certificado manualmente:
cd /etc/openvpn/easyrsa # ./easyrsa revoke $CLIENT # crl ./easyrsa gen-crl # crl rm -rf /etc/openvpn/crl.pem # cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem # openvpn crl, nobody chown nobody:nobody /etc/openvpn/crl.pem
Filtrando hosts disponíveis para clientes
Os clientes precisam ser limitados pelos hosts que eles podem acessar na rede quando se conectam ao openvpn.
ManualmenteA idéia é pegar pacotes mesmo na interface
tun0
, na qual eles vêm de clientes e filtrá-los antes de entrar no NAT. Após o NAT, não haverá motivo para filtrá-los - todos terão um endereço IP do servidor openvpn na rede interna. Antes de entrar no NAT, os pacotes para cada usuário têm seu próprio endereço IP exclusivo (para a correspondência de endereços IP e usuários, consulte o arquivo
/etc/openvpn/ipp.txt
).
Pacotes que passam pelo sistema (não vêm diretamente dele e não são recebidos, ou seja, são roteados pelo sistema) são processados pela tabela FORWARD. As tabelas no iptables são processadas de cima para baixo, se nenhuma das regras da tabela levar a uma decisão sobre o destino do pacote, a regra padrão será acionada.
Preparando a tabela FORWARD:
# iptables -F FORWARD # FORWARD - iptables -P FORWARD DROP # iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
Regras de exemplo para um cliente específico. Como a regra padrão da tabela é DROP, resta apenas permitir os pares host + porta onde você puder. Permitir acesso à porta no host + executar ping no próprio host:
iptables -I FORWARD -s 10.8.0.3 -i tun0 -d 10.0.2.3 -p tcp --dport 443 -j ACCEPT iptables -I FORWARD -s 10.8.0.3 -i tun0 -d 10.0.2.3 -p icmp --icmp-type echo-request -j ACCEPT
No exemplo acima, o host 10.8.0.3 tem acesso permitido à porta 443 do host 10.0.2.3.
Como fechar o acesso:
# iptables -L FORWARD --line-numbers # iptables -D FORWARD { }
Então você precisa encontrar todas as regras para um cliente específico e excluí-las.
Durante a depuração, é conveniente verificar quais regras funcionam. Cada regra possui um contador de pacotes processados.
# , watch iptables -nvL FORWARD # iptables -Z FORWARD
AutomaticamenteUm servidor openvpn tem a capacidade de executar scripts para determinadas ações. Em particular, ao conectar e desconectar clientes. Os scripts podem ser escritos em qualquer coisa, se forem executáveis. Dentro do script, as variáveis de ambiente transmitem todos os tipos de parâmetros para a conexão atual. Estamos interessados em variáveis:
common_name
(nome do proprietário do certificado; o que leva ao campo de nome comum ao criar o certificado)ifconfig_pool_remote_ip
(endereço IP do cliente em tun0)script_type
(qual evento aconteceu - conecte ou desconecte).
Você precisa de privilégios de root para gerenciar o iptables. O Openvpn depois de conectar redefine os direitos a ninguém e executa scripts a partir dele. É ruim permitir que ninguém faça algo com o sudo e é melhor não usar um asterisco nas regras, mas de alguma forma você precisa permitir que o usuário controle as tabelas de ip.
Na configuração do servidor, você precisa adicionar permissão para executar arquivos de terceiros e ativar dois ganchos responsáveis por conectar e desconectar o usuário.
script-security 2 client-connect /etc/openvpn/bin/hosts.rb client-disconnect /etc/openvpn/bin/hosts.rb
O próprio script, que lê as configurações e aplica as regras para o iptables. O script funciona com os mesmos princípios descritos na seção anterior.
As regras são armazenadas em arquivos correspondentes ao nome comum dos certificados na pasta
/etc/openvpn/hosts
. Eles especificam exatamente quais endereços IP estão disponíveis para um cliente específico. Separador - um número arbitrário de espaços. O endereço IP, a porta e o protocolo (tcp ou udp) são gravados através do separador.
10.0.0.24 53 udp 10.0.0.25 53 udp 10.0.2.3 443 tcp
Como resultado, a seguinte estrutura deve
/etc/openvpn
na pasta
/etc/openvpn
├── bin
Hosts └── hosts.rb
Hosts── anfitriões
│ ├── user1
2 ├── user2
Everybody └── todo mundo
Server── server.conf
└── ...
User1
e
user2
são arquivos no formato acima. Eles descrevem a quais hosts o usuário com o nome comum correspondente tem acesso.
Há outro arquivo
everybody
adicional, ele contém regras que se aplicam a todos os clientes, desde que exista um arquivo de configuração separado para esses clientes. Ou seja, se o usuário tiver uma lista de hosts para onde ele pode ir, essa lista e os hosts listados em
everybody
aplicados. Caso contrário,
everybody
não
everybody
aplicável. Por exemplo, é conveniente colocar um servidor DNS nesse arquivo.
RegistoO script de instalação inclui apenas o registro de conexões atuais (parâmetro
status)
. Para que um log comum apareça, você precisa adicionar uma linha à configuração do servidor (
/etc/openvpn/server.conf
):
log-append /var/log/openvpn.log
LDAPExiste um plugin
openvpn-auth-ldap que permite autenticar um usuário novamente via LDAP.
Entrega do pacote:
sudo yum install openvpn-auth-ldap
Adicione ao server.conf:
plugin /usr/lib64/openvpn/plugin/lib/openvpn-auth-ldap.so "/etc/openvpn/ldap.conf"
Crie uma configuração para o ldap no
/etc/openvpn/ldap.conf
:
<LDAP> URL ldaps://{LDAP_DOMAIN_HERE} Timeout 15 TLSEnable no FollowReferrals yes BindDN "BIND_DN_HERE" Password "BIND_PASSWORD_HERE" </LDAP> <Authorization> BaseDN "{BASE_DN_HERE}" SearchFilter "(&(sAMAccountName=%u)(objectClass=organizationalPerson)(objectCategory=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))" RequireGroup false </Authorization>
Adicione a linha à configuração ovpn personalizada:
auth-user-pass
Assim, primeiro o usuário será solicitado a fornecer o nome de usuário e a senha do domínio, depois o PIN do token. Se uma dessas etapas falhar, a conexão não será estabelecida.
A descrição das opções para o ldap.conf
está no repositório do plug-in . Ele suporta autenticação por associação ao grupo, mas eu não o testei.
Velocidade
O maior aumento na velocidade fornece a inclusão do modo udp. Isso é recomendado em todos os manuais. O ponto é que não faz sentido iniciar uma conexão de cliente tcp em um canal tcp. Um tcp no cliente é suficiente para fazer a entrega correta dos pacotes. Se os pacotes forem perdidos no canal udp, a conexão tcp do cliente controlará o ajuste de entrega.
A velocidade aumentará pelo menos porque não há necessidade de aguardar a confirmação da entrega de cada pacote no canal. Há um segundo problema com o tcp - um pacote tcp do cliente provavelmente não se encaixa em um pacote do canal vpn. O MTU é o mesmo, mas os cabeçalhos precisam ser adicionados ao pacote do cliente. Como resultado, você deve enviar dois pacotes dentro do canal vpn por pacote de usuário.
O TCP faz sentido usar quando é impossível de outra maneira. Por exemplo, quando o vpn funciona através do canal ssh.
Exemplo de uma configuração completa do servidor
example-server.conf port 1194 proto tcp dev tun sndbuf 0 rcvbuf 0 ca ca.crt cert server.crt key server.key dh dh.pem tls-auth ta.key 0 topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 10.0.0.25" push "dhcp-option DNS 10.0.0.24" keepalive 10 120 cipher AES-256-CBC comp-lzo user nobody group nobody persist-key persist-tun status openvpn-status.log verb 3 crl-verify crl.pem log-append /var/log/openvpn.log script-security 2 client-connect /etc/openvpn/bin/hosts.rb client-disconnect /etc/openvpn/bin/hosts.rb
Configuração de token
Biblioteca PKCS # 11
Para trabalhar com tokens, você precisa de uma biblioteca especial. A biblioteca é necessária para criar pares de chaves e para a conexão real.
Baixe para todas as plataformas pelo link .
Onde quer que o librtpkcs11ecp.so seja encontrado posteriormente - esta é a própria biblioteca que precisa ser baixada e colocada em algum lugar em um local conveniente.
Criando um certificado em um token
Gere um par de chaves no token. O parâmetro id aqui é o número de série do slot no token onde o par de chaves se encaixa.
pkcs11-tool --module /usr/lib64/librtpkcs11ecp.so --keypairgen --key-type rsa:2048 -l --id 01
Faça uma solicitação de certificado para a chave pública. No processo de criação de uma solicitação de certificado, a vida útil do certificado e o nome comum são definidos, usados para filtrar os endereços IP disponíveis na rede. O nome comum deve corresponder ao logon no ActiveDirectory para que não haja confusão.
openssl openssl> engine -t dynamic -pre SO_PATH:/usr/lib64/openssl/engines/pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/lib64/librtpkcs11ecp.so openssl> req -engine pkcs11 -new -key slot_0-id_01 -keyform engine -out /home/john/good.req
A solicitação recebida deve ser movida para a
/etc/openvpn/easy-rsa/pki/reqs/
. A extensão do arquivo deve ser necessária.
Convertendo uma solicitação em um certificado:
cd /etc/openvpn/easy-rsa/ ./easyrsa sign-req client good
Depois disso, um certificado com o mesmo nome, mas com a extensão
crt
, aparecerá na pasta
/etc/openvpn/easy-rsa/pki/issued/
.
Antes da gravação, o certificado deve ser convertido em DER:
openssl x509 -in /home/user/user-cert.pem -out /home/user/user-cert.crt -outform DER
Escrevendo um certificado para um token:
pkcs11-tool --module /usr/lib/librtpkcs11ecp.so -l -y cert -w /home/user/user-cert.crt --id 45 --label TEST
Está escrito com base no artigo
“Usando o Rutoken EDS com OpenSSL (RSA)” .
Usando token para autenticação
Localize o ID do certificado a ser apresentado ao servidor:
$ openvpn --show-pkcs11-ids /usr/lib64/librtpkcs11ecp.so The following objects are available for use. Each object shown below may be used as parameter to --pkcs11-id option please remember to use single quote mark. Certificate DN: /CN=User1 Serial: 490B82C4000000000075 Serialized id: aaaa/bbb/41545F5349474E415455524581D2A1A1B23C4AA4CB17FAF7A4600
Estamos interessados no ID serializado aqui.
Opções que devem ser inseridas na configuração ovpn para que os tokens sejam selecionados:
pkcs11-providers /usr/lib64/librtpkcs11ecp.so pkcs11-id 'aaaa/bbb/41545F5349474E415455524581D2A1A1B23C4AA4CB17FAF7A4600'
A opção
pkcs11-id
deve estar entre aspas simples.Este manual faz sentido em todas as plataformas. Você precisa especificar o caminho para a biblioteca e o ID do certificado no token. A biblioteca pode ser chamada de maneira um pouco diferente, seja
.dll
, não
.so
, mas o significado é o mesmo.
Nesse caso, você precisa remover as seções
cert
e
key
do arquivo ovpn, porque o certificado e a chave privada serão retirados do token.
A configuração completa do cliente (para Windows) fica assim:
client.ovpnclient
dev tun
proto tcp
sndbuf 0
rcvbuf 0
remote 78.47.37.247 22222
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
comp-lzo
setenv opt block-outside-dns
key-direction 1
verb 3
pkcs11-providers "c://Windows//System32//rtPKCS11ECP.dll"
pkcs11-id 'Aktiv\x20Co\x2E/Rutoken\x20ECP/342b871d/Rutoken/01'
-----BEGIN CERTIFICATE-----
{CERT_HERE}
-----END CERTIFICATE-----
<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
{KEY_HERE}
-----END OpenVPN Static key V1-----
</tls-auth>
Escrito com base em
"Como adicionar autenticação de fator duplo a uma configuração OpenVPN usando cartões inteligentes do lado do cliente" .
Configuração do cliente
Linux
O Openvpn possui um bug que impede o usuário de inserir o código PIN a partir do token, se o pacote for construído com o suporte ao systemd. Como o systemd está em toda parte ultimamente, todos os pacotes que já estão disponíveis nos repositórios são compilados com seu suporte. Clientes no Linux precisam coletar o pacote por conta própria. Aqui está um exemplo de configuração que funcionou para mim no Arch Linux:
./configure \ --prefix=/usr \ --sbindir=/usr/bin \ --enable-iproute2 \ --enable-pkcs11 \ --enable-plugins \ --enable-x509-alt-username
Você pode verificar se o openvpn foi criado com ou sem systemd usando o seguinte comando:
openvpn --version | grep --color enable_systemd
Mas os
No Mac OS, existe apenas um cliente gratuito -
Tunnelblink .
Ele não sabe como inserir um código PIN a partir de um token da GUI. O erro é descrito, por exemplo, aqui -
https://groups.google.com/forum/#!topic/tunnelblick-discuss/f_Rp_2nV-x8 Ignorado iniciando o openvpn a partir do console. Isso não é surpreendente, já que o cliente oficial do Windows também não sabe disso.
Também no Mac OS (ao contrário do Windows), são necessários scripts adicionais para configurar a rede. Se você simplesmente executar o openvpn a partir do console, o DNS não funcionará (talvez algo mais, apenas o DNS aparecerá).
O TunnelBlick possui esses scripts de configuração de rede, eles só precisam ser chamados ao estabelecer e desconectar a conexão. O que você precisa adicionar à configuração ovpn:
script-security 2 up "/Applications/Tunnelblick.app/Contents/Resources/client.up.tunnelblick.sh -9 -d -f -m -w -ptADGNWradsgnw" down "/Applications/Tunnelblick.app/Contents/Resources/client.down.tunnelblick.sh -9 -d -f -m -w -ptADGNWradsgnw"
Um script de exemplo para iniciar uma conexão openvpn, que pode ser colocada na área de trabalho e cutucada com o mouse:
#!/bin/bash tunnelblick=/Applications/Tunnelblick.app/Contents/Resources/openvpn/openvpn-2.4.2-openssl-1.0.2k sudo $tunnelblick/openvpn --config $tunnelblick/user.ovpn
Windows
Sob as janelas, tudo parece funcionar. O cliente oficial não sabe como inserir o código PIN a partir do token, ele consegue abrir o VPN manualmente à mão no console.
O mais importante é fazer tudo sob o administrador. Execute o instalador do cliente como administrador. Inicie um terminal no qual o openvpn também inicie com direitos de administrador, caso contrário não poderá controlar a interface de rede.
No Windows, o caminho da biblioteca para trabalhar com tokens deve ser registrado por meio de barras duplas. Isso se aplica às opções ovpn config e
--show-pkcs11-ids
na linha de comandos.
pkcs11-providers "c://Windows//System32//rtPKCS11ECP.dll" pkcs11-id 'Aktiv\x20Co\x2E/Rutoken\x20ECP/342b871d/Rutoken/01'