OpenVPN com hierarquia de CA de duas camadas

Recentemente, encontrei a tarefa de criar uma hierarquia de dois níveis de Autoridade de Certificação para OpenVPN no debian. Muitas vezes tive a chance de levantar o OpenVPN com uma autoridade de certificação e entendi perfeitamente como deveria ser em teoria com dois CAs, mas na prática enfrentei o fato de que não entendia o que e onde assinar. O Google não me deu respostas que seriam adequadas para Linux (ou eu não fiz o google) e comecei a descobrir. Abaixo, forneci um manual que compilei no processo de criação e configuração.



Quero observar imediatamente que aqui coloco mais ênfase na configuração do CA do que no OpenVPN.



Antes de começarmos, direi a alguém que pode usá-lo com meu exemplo.



Tive a tarefa de criar um sistema para uma grande empresa de forma que apenas uma pessoa assinasse os certificados do servidor OpenVPN, existem muitos servidores VPN, vários servidores VPN foram instalados para cada departamento. Há ainda mais funcionários (clientes) e controle (emissão / revogação) de certificados toda vez que um funcionário entra / sai de um fardo muito pesado (sem falar nos temporários). Os colaboradores de cada departamento são supervisionados pelo responsável do departamento, que emite ou revoga os certificados dos novos / antigos colaboradores, respetivamente.



Para que certificados e chaves digitais são necessários, muito se disse e não repetirei outros autores, mas resumidamente:



  • para verificar a confiabilidade (ocorre um "aperto de mão duplo"), o cliente e o servidor se certificam de quem são, se podem confiar um no outro e estabelecer uma conexão;
  • criptografia / descriptografia;
  • exceções "Man in the middle (MITM)" para se certificar de que alguém não está interceptando mensagens / tráfego;
  • para criar senhas criptografadas, o que aumenta a segurança e dificulta o acesso dos invasores ao host.


O princípio de operação da hierarquia de CA de vários níveis é que o CA de nível superior (RootCA) assina seu certificado por um período de tempo suficientemente longo (mas esta é uma questão puramente individual), cada próximo inferior na hierarquia de CA ou serviço assina seus certificados com um CA superior (usual burocracia) com a condição de que o certificado de nível inferior deve ter um período de validade não superior a metade do período de validade do certificado de nível superior.







Ao criar um CA, dois arquivos são criados: ca.crt - a chave pública e ca.key - a chave privada.

A chave privada deve ser protegida e não deve ser compartilhada com terceiros.



Quando precisamos criar uma CA subordinada / assinante, criamos uma chave privada nela e uma solicitação de assinatura do RootCA.



Como os computadores e usuários em todo o mundo saberão que podem confiar em um serviço ou site, você pergunta? É simples (bem, em teoria), a Chave Pública da CA (RootCA) é colocada nos computadores dos usuários e esses computadores confiam em todos os certificados emitidos por esta CA. Na prática, isso é certamente mais difícil e não barato. Mas, dentro de sua própria empresa, isso é muito fácil de fazer.



Para implementação, precisamos de três servidores. Neste tutorial usaremos o debian 9. Nomearemos os servidores de acordo com sua aplicação: OpenVPN, SubCA, RootCA.



Todas as ações são realizadas sob o usuário não root.



Para fazer isso, seu usuário deve estar no grupo sudo.



Se o sudo não estiver instalado no servidor, faça login como root:



# su - root
# apt-get install sudo -y
# usermod -aG sudo username
# exit


Instalamos os utilitários necessários em todos os servidores (os utilitários podem diferir dependendo das crenças e crenças, wget, ufw, vim são obrigatórios, já que aqui dei comandos com esses utilitários):



# sudo apt-get update
# sudo apt-get upgrade
# sudo apt-get install wget curl net-tools ufw vim -y
# cd ~
# wget -P ~/ https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.4/EasyRSA-3.0.4.tgz
# tar xvf EasyRSA-3.0.4.tgz


Instale openvpn no servidor OpenVPN:



# sudo apt-get install openvpn -y


Vá para o servidor RootCA. Aqui precisamos criar um arquivo do qual o easyrsa pegará os valores das variáveis:



# mv ~/EasyRSA-3.0.4 ~/easyrsa/
# cd ~/easyrsa/
# cp vars.example vars
# vim vars


Encontre o bloco, apague # e substitua nossos valores. Para não inserir nossos dados ao assinar certificados, vamos escrevê-los aqui:



#set_var EASYRSA_REQ_COUNTRY	"US"
#set_var EASYRSA_REQ_PROVINCE	"California"
#set_var EASYRSA_REQ_CITY	"San Francisco"
#set_var EASYRSA_REQ_ORG	"Copyleft Certificate Co"
#set_var EASYRSA_REQ_EMAIL	"me@example.net"
#set_var EASYRSA_REQ_OU		"My Organizational Unit"


Em seguida, encontre as configurações a seguir, exclua # e edite seus valores. Essas diretivas são responsáveis ​​pela vida útil dos certificados (a primeira é pela vida útil do certificado CA, a segunda é pela vida útil do certificado que está sendo assinado):



#set_var EASYRSA_CA_EXPIRE	3650         #-->  3650
#set_var EASYRSA_CERT_EXPIRE	3650         #-->  1825


Mais longe:



# ./easyrsa init-pki


Executar o próximo comando solicitará CN. Você pode deixar o padrão, mas é melhor inserir um nome de identificação do hostname (RootCA). O valor "nopass" significa que você não precisa criar uma senha:



# ./easyrsa build-ca nopass


Vá para o servidor SubCA e siga as mesmas etapas com pequenas alterações:



# mv ~/EasyRSA-3.0.4 ~/easyrsa/
# cd ~/easyrsa/
# cp vars.example vars
# vim vars


Encontre o bloco, exclua # e substitua nossos valores:



#set_var EASYRSA_REQ_COUNTRY	"US"
#set_var EASYRSA_REQ_PROVINCE	"California"
#set_var EASYRSA_REQ_CITY	"San Francisco"
#set_var EASYRSA_REQ_ORG	"Copyleft Certificate Co"
#set_var EASYRSA_REQ_EMAIL	"me@example.net"
#set_var EASYRSA_REQ_OU		"My Organizational Unit"


Em seguida, encontramos as seguintes configurações, excluímos # e editamos seus valores:



#set_var EASYRSA_CA_EXPIRE	3650         #-->  1825
#set_var EASYRSA_CERT_EXPIRE	3650         #-->  365


Mais longe:



# ./easyrsa init-pki


Executar o próximo comando solicitará CN. Você pode deixar o padrão, mas é melhor inserir um nome de identificador de host (SubCA). O valor "subca" indica que estamos criando uma CA subordinada e precisamos criar uma solicitação de assinatura de certificado:



# ./easyrsa build-ca subca nopass


Em seguida, encontramos o arquivo ~ / easyrsa / pki / reqs / ca.req (esta é a própria solicitação) e o transferimos para o servidor RootCA (você pode usar dois métodos: WinSCP e scp):



# scp ~/easyrsa/pki/reqs/ca.req user@ip_RootCA:/tmp


Vá para o servidor RootCA e assine a solicitação. Antes de assinar a solicitação, devemos importá-la para o diretório de trabalho. para assinar o certificado para a CA subordinada, usamos o atributo "ca" e o nome do certificado (você pode chamá-lo de ca, mas para não ficar confuso, vamos chamá-lo de nome do servidor para o qual estamos assinando, e quando o transferirmos para o servidor, iremos renomeá-lo):



# cd ~/easyrsa/
# ./easyrsa import-req /tmp/ca.req SubCA
# ./easyrsa sign-req ca SubCA


A confirmação será solicitada, você deve digitar "sim".

Devolvemos o certificado assinado SubCA.



# scp ~/easyrsa/pki/issued/SubCA.crt user@ip_SubCA:/tmp


Vá para o servidor SubCA e mova o certificado para o diretório de trabalho easyrsa:



# mv /tmp/SubCA.crt ~/easyrsa/pki/ca.crt


Neste ponto, já temos uma CA raiz e uma CA raiz secundária assinada.

Agora vamos entrar no servidor OpenVPN. Ao configurá-lo, algumas das etapas anteriores são repetidas. Vá para o servidor OpenVPN.



# cd ~/easyrsa/
# ./easyrsa init-pki


Agora vamos começar a criar certificados para assinatura. Criaremos uma chave Diffie-Hellman (dh.pem / dh2048.pem / dh1024.pem) para ser usada na troca de chaves e criaremos uma assinatura HMAC (ta.key) para aprimorar a função de verificação de integridade TLS.



Assinaremos certificados para o servidor OpenVPN em RootCA e assinaremos certificados para usuários em SubCA. Crie imediatamente um diretório onde adicionaremos chaves, certificados e configurações de cliente.



# mkdir -p ~/client-configs/files/
# mkdir ~/client-configs/keys/
# chmod 700 ~/client-configs/
# sudo mkdir /etc/openvpn/vpnsrv1/

# ./easyrsa gen-req vpnsrv1 nopass
# ./easyrsa gen-req dumasti nopass
# ./easyrsa gen-dh
# sudo openvpn --genkey --secret ta.key
# cp /home/dumasti/easyrsa/pki/private/dumasti.key ~/client-configs/keys/
# sudo cp /home/dumasti/easyrsa/pki/dh.pem /etc/openvpn/vpnsrv1/
# sudo cp /home/dumasti/easyrsa/ta.key /etc/openvpn/vpnsrv1/
# sudo cp /home/dumasti/easyrsa/ta.key ~/client-configs/keys/
# sudo cp /home/dumasti/easyrsa/pki/private/vpnsrv1.key /etc/openvpn/vpnsrv1/
# scp ~/easyrsa/pki/reqs/vpnsrv1.req user@ip_RootCA:/tmp
# scp ~/easyrsa/pki/reqs/dumasti.req user@ip_SubCA:/tmp


Vá para o servidor RootCA e assine o certificado. Para assinar o certificado para o servidor, usamos o atributo "server", para o cliente "client":



# cd ~/easyrsa/
# ./easyrsa import-req /tmp/vpnsrv1.req vpnsrv1
# ./easyrsa sign-req server vpnsrv1


A confirmação será solicitada, você deve digitar "sim".



# scp ~/easyrsa/pki/issued/vpnsrv1.crt user@ip_OpenVPN:/tmp
# scp ~/easyrsa/pki/ca.crt user@ip_OpenVPN:/tmp/RootCA.crt


Vá para o servidor SubCA e assine o certificado:



# cd ~/easyrsa/
# ./easyrsa import-req /tmp/dumasti.req dumasti
# ./easyrsa sign-req client dumasti


A confirmação será solicitada, você deve digitar "sim".



# scp ~/easyrsa/pki/issued/dumasti.crt user@ip_OpenVPN:/tmp
# scp ~/easyrsa/pki/ca.crt user@ip_OpenVPN:/tmp/SubCA.crt


Retornamos ao servidor OpenVPN e transferimos os certificados assinados para os diretórios necessários:



# cd /tmp


Para que o servidor OpenVPN aceite as chaves do cliente, devemos combinar as chaves públicas do cliente e a CA subordinada / assinante em um arquivo:



# cat dumasti.crt SubCA.crt > ~/client-configs/keys/dumasti.crt
# cp /tmp/RootCA.crt ~/client-configs/keys/ca.crt
# sudo mv /tmp/RootCA.crt /etc/openvpn/vpnsrv1/
# sudo mv /tmp/vpnsrv1.crt /etc/openvpn/vpnsrv1/


Agora temos todas as certificações necessárias nos lugares certos. Resta criar a configuração do servidor e cliente OpenVPN (cada um pode ter suas próprias crenças e pontos de vista neste assunto, mas para um exemplo, haverá a seguinte configuração).



Você pode usar o modelo de configuração de servidor e cliente e editar por si mesmo:



# sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
# sudo gzip -d /etc/openvpn/server.conf.gz
# cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf


Mas a seguir darei o conteúdo dos arquivos de configuração prontos (símbolos; e # comente a linha):



# sudo cat /etc/openvpn/vpnsrv1.conf

port 1194
proto udp
dev tun
ca vpnsrv1/RootCA.crt
cert vpnsrv1/vpnsrv1.crt
key vpnsrv1/vpnsrv1.key
dh vpnsrv1/dh.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"
;client-config-dir ccd
;client-config-dir ccd
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
client-to-client
;duplicate-cn
keepalive 10 120
tls-auth vpnsrv1/ta.key 0
key-direction 0
cipher AES-256-CBC
auth SHA256
max-clients 100
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
;mute 20
explicit-exit-notify 1

# cat ~/client-configs/base.conf

client
dev tun
proto udp
remote your_server_ip 1194
;remote my-server-2 1194
;remote-random
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
remote-cert-tls server
;tls-auth ta.key 1
cipher AES-256-CBC
auth SHA256
key-direction 1
verb 3
;mute 20
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf


Também precisamos configurar o firewall e o encaminhamento de pacotes. É possível configurar o iptables, mas aqui veremos o ufw.



Primeiro, vamos descobrir o nome da nossa interface:



# ip addr 


Vamos abrir as seguintes portas (tenho ssh na porta 22 e openvpn na 1194, se você tiver outras, aja de acordo):



# sudo ufw allow 1194
# sudo ufw allow 22


Em seguida, abra o arquivo de configuração ufw e cole o seguinte antes do início da cadeia de filtros (substitua meus valores pelos seus):



# sudo vim /etc/ufw/before.rules

# START OPENVPN RULES

# NAT table rules

*nat

:POSTROUTING ACCEPT [0:0]

# Allow traffic from OpenVPN client to eth0 (change to the interface you discovered!)

-A POSTROUTING -s 10.8.0.0/8 -o ens192 -j MASQUERADE

COMMIT

# END OPENVPN RULES


Antes disso:



# Don't delete these required lines, otherwise there will be errors
*filter


Você precisa habilitar o encaminhamento de pacotes UFW por padrão. Encontre a linha necessária e altere o valor "DROP" para "ACCEPT":



# sudo vim /etc/default/ufw

DEFAULT_FORWARD_POLICY="ACCEPT"


Configurando o encaminhamento de pacotes. Encontre a linha # net.ipv4.ip_forward = 0 ou # net.ipv4.ip_forward = 1, exclua #, se o valor for 0, altere-o para 1:



# sudo vim /etc/sysctl.conf

net.ipv4.ip_forward=1

# sudo sysctl -p
# sudo ufw enable


A seguir, lançamos nosso VPN:



# sudo systemctl start openvpn@vpnsrv1


Verificando o lançamento:



# ip addr


Deve haver uma nova interface de rede tun0 com ip 10.8.0.1



# sudo systemctl status openvpn@vpnsrv1


Se precisar que a VPN inicie por conta própria após a reinicialização, adicione o serviço para execução automática:



# sudo systemctl enable openvpn@vpnsrv1


A seguir, criamos uma configuração de cliente. Anteriormente, colocamos todas as chaves e certificados no diretório ~ / client-configs / keys /.



Vamos criar um script que irá coletar configurações, chaves e certificados em um arquivo user.ovpn:



# cd ~/client-configs/
# vim configs-maker.sh

#!/bin/bash
# First argument: Client identifier
KEY_DIR=/home/dumasti/client-configs/keys
OUTPUT_DIR=/home/dumasti/client-configs/files
BASE_CONFIG=/home/dumasti/client-configs/base.conf
cat ${BASE_CONFIG} \
	<(echo -e '<ca>') \
	${KEY_DIR}/ca.crt \
	<(echo -e '</ca>\n<cert>') \
	${KEY_DIR}/${1}.crt \
	<(echo -e '</cert>\n<key>') \
	${KEY_DIR}/${1}.key \
	<(echo -e '</key>\n<tls-auth>') \
	${KEY_DIR}/ta.key \
	<(echo -e '</tls-auth>') \
	> ${OUTPUT_DIR}/${1}.ovpn


Este script pegará arquivos com o nome que você deu durante a inicialização e configurará um arquivo no diretório de arquivos.



Vamos tornar o arquivo executável:



# chmod +x configs-maker.sh


Vamos executar:



# sudo ./configs-maker.sh dumasti


Agora transferimos a configuração do cliente para o seu computador do diretório / home / dumasti / client-configs / files /



. Inicie o VPN.



Por motivos de segurança, os servidores que hospedam a CA devem ser desligados e ligados apenas para assinar certificados.



Não iremos ignorar a revogação de certificados. Para revogar o certificado, vamos ao servidor CA em que o certificado foi assinado e fazemos o seguinte (por exemplo, revogaremos o certificado do usuário (dumasti) que assinamos no servidor SubCA). Vamos para o servidor SubCA:



# cd ~/easyrsa/
# ./easyrsa revoke dumasti


Você será solicitado a confirmar a revogação, digite "sim"



# ./easyrsa gen-crl


O arquivo crl.pem foi gerado. Precisamos colocá-lo no servidor OpenVPN e adicionar a diretiva e o caminho para o arquivo na configuração do servidor:



# scp ~/easyrsa/pki/crl.pem user@ip_OpenVPN:/tmp


Vá para o servidor OpenVPN:



# sudo mv /tmp/crl.pem /etc/openvpn/vpnsrv1/
# sudo vim /etc/openvpn/vpnsrv1.conf


Adicione a seguinte linha onde as chaves e certificados são gravados:



crl-verify vpnsrv1/crl.pem


Reinicie openvpn:



# sudo systemctl restart openvpn@vpnsrv1


Agora, o cliente dumasti não conseguirá se conectar à VPN.



Obrigado pela atenção!



All Articles