assignment 3 enunciado
This commit is contained in:
575
assignment2/relatorio/relatorio.tex
Normal file
575
assignment2/relatorio/relatorio.tex
Normal file
@@ -0,0 +1,575 @@
|
||||
\documentclass[11pt,a4paper]{article}
|
||||
\usepackage[portuguese]{babel}
|
||||
\usepackage[lining]{ebgaramond}
|
||||
\usepackage{style}
|
||||
|
||||
\setlength{\parindent}{0em}
|
||||
\setlength{\parskip}{2ex}
|
||||
|
||||
\title{Practical Assignment \#2}
|
||||
\author{
|
||||
João Neto -- 2023234004\\[1em]
|
||||
Vasco Alves -- 2022228207
|
||||
}
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
\newpage
|
||||
\tableofcontents
|
||||
|
||||
\newpage
|
||||
|
||||
\section{Introdução}
|
||||
|
||||
Este projeto tem como âmbito implementar, uma rede virtual privada (VPN) num cenário
|
||||
de road-warrior, configurar \textit{two-factor authentication} (2FA) com os serviços
|
||||
OpenVPN e Apache, e gerir certificados X.509 utilizando OCSP.
|
||||
|
||||
% NOTE(vasco): Eu acho que basta explicar o cenario e explicar como decidimos
|
||||
% implementar <- yeah agree, also esta introdução acho que é boa fala sobre o objetivo
|
||||
% e o cenario, e porque é que o nosso cenario é como é. Não sei se a parte das razões de
|
||||
%segurança devia estar nesta parte ou na conclusão como perpetiva futura e reflexão, mas aqui
|
||||
%também não está mal.
|
||||
|
||||
% Para tal, foi implementado um servidor e um cliente OpenVPN, certificados por uma
|
||||
% autoridade central (CA) que em si é \textit{self-signed}. Para além disto, foi implementado
|
||||
% um sistema de autenticação de dois factores através do plugin
|
||||
% \textit{google-authenticator} para o OpenVPN e para o servidor de Apache.
|
||||
|
||||
Decidimos utilizar apenas três máquinas virtuais: o cliente (ou \textit{road warrior}),
|
||||
a \textit{gateway} que utiliza OpenVPN e um servidor interno com OpenSSL e Apache.
|
||||
Isto simplifica a elaboração do projecto, mas por razões de segurança poderia querer
|
||||
separar a máquina de OpenSSL de outras máquinas destinadas a serviços da rede interna,
|
||||
pois esta contém o \textit{certificate authority} (CA).
|
||||
|
||||
% Ambos o OpenVPN eo servidor Apache utilizam 2FA,
|
||||
% recebendo o utilizador, e uma password que é uma concatenação da palavra-passe do utilizador
|
||||
% e de uma password temporária (TOTP) de 6 dígitos. O servidor de Apache implementa a mesma autenticação.
|
||||
|
||||
\begin{tabular}{l l l}
|
||||
{\bf Nome} & {\bf Script} & {\bf Rede} \\\toprule
|
||||
Road Warrior & VM\_ROAD\_WARRIOR.sh & Rede Externa 193.168.0.0/24 \\
|
||||
VPN Gateway & VM\_OPENVPN\_GATEWAY.sh & Router \\
|
||||
OpenSSL / Apache & VM\_OPENSSL\_APACHE.sh & Rede Interna 10.60.0.0/24 \\
|
||||
\end{tabular}
|
||||
|
||||
\section{Preparação Inicial}
|
||||
|
||||
\subsection{Criação de Certificados}
|
||||
|
||||
Os certificados utilizados foram auto-certificados por uma autoridade central que ``pertence''
|
||||
à máquina de OpenSSL. Esta mesma faz a gestão da lista de revogação.
|
||||
|
||||
Todas as chaves foram criadas no mesmo computador, com as variáveis que estão
|
||||
neste código. Aspetos importantes para mais tarde serão os parâmetros de Comon Name (CN)
|
||||
pois servem para a validação do certificado ambos pelo OpenSSL e pelo browser.
|
||||
|
||||
Nós optamos por assumir que num cenário real, teríamos acesso físico às máquinas, por isso em vez
|
||||
de utilizar, por exemplo SCP ou FTP, escolhemos partilhar os ficheiros a partir da máquina host. No entanto, outra abordagem também estaria correta.
|
||||
|
||||
\begin{codeblock}[bash]{create\_all\_keys.sh}
|
||||
cert_ca="/C=PT/ST=Coimbra/L=Coimbra/O=UC/CN=CoimbraVPN"
|
||||
cert_vpn="/C=PT/ST=Coimbra/L=Coimbra/O=UC/CN=gateway"
|
||||
cert_user="/C=PT/ST=Coimbra/L=Coimbra/O=UC/CN=warrior"
|
||||
cert_apache="/C=PT/ST=Coimbra/L=Coimbra/O=UC/CN=apache.coimbra"
|
||||
|
||||
openssl genrsa -out "ca.key" 2048
|
||||
openssl req -x509 -nodes -days 365 -key "ca.key" -out "ca.crt" -subj "$cert_ca"
|
||||
openssl genrsa -out "vpn.key" 2048
|
||||
openssl req -new -key "vpn.key" -out "vpn.csr" -subj "$cert_vpn"
|
||||
openssl ca -batch -in "vpn.csr" -cert "ca.crt" -keyfile "ca.key" -out "vpn.crt" -config cheese.cfg
|
||||
openssl dhparam -out "dh2048.pem" 2048
|
||||
openvpn --genkey secret "ta.key"
|
||||
openssl genrsa -out user.key
|
||||
openssl req -new -key user.key -out user.csr -subj "$cert_user"
|
||||
openssl ca -batch -in "user.csr" -cert "ca.crt" -keyfile "ca.key" -out "user.crt" -config cheese.cfg
|
||||
openssl genrsa -out apache.key
|
||||
openssl req -new -key apache.key -out apache.csr -subj "$cert_apache" -addext "subjectAltName = IP:10.60.0.1,DNS:apache"
|
||||
openssl ca -batch -in "apache.csr" -cert "ca.crt" -keyfile "ca.key" -out "apache.crt" -config cheese.cfg
|
||||
openssl --genkey secret ta.key
|
||||
\end{codeblock}
|
||||
|
||||
Como o CA foi criado ``\textit{in place}'', e não na sua pasta prédefinida, foi necessário utilizar
|
||||
um configuração própria para definir os ficheiros \textit{index.txt} e \textit{serial}.
|
||||
|
||||
\begin{codeblock}[bash]{cheese.cfg}
|
||||
[ ca ]
|
||||
default_ca = CA_default
|
||||
[ CA_default ]
|
||||
default_days = 365
|
||||
database = index.txt
|
||||
serial = serial
|
||||
copy_extensions = copy
|
||||
new_certs_dir = .
|
||||
default_md = sha256
|
||||
policy = policy_any
|
||||
[ policy_any ]
|
||||
commonName = supplied
|
||||
\end{codeblock}
|
||||
|
||||
\subsection{Configuração geral}
|
||||
Para evitar repetição e redundancia; e para garantir consistencia na elaboração do projeto criamos varios shell scripts, um destinado a cada maquina virtual.
|
||||
|
||||
Para configurar as VMs era preciso introduzir os mesmos comandos várias vezes, o que levava muitas vezes a erros de escrita,
|
||||
ou a correr o mesmo comando várias vezes, por isso criamos vários ficheiros .sh para conseguir facilitar o processo.
|
||||
A utilização de ficheiros .sh também vem com outros positivos pois facilita a testagem, e a recriação do cenário rapidamente.
|
||||
|
||||
No entanto para os serviços que configuramos, instalar, desativar e dar flush às iptables não foi suficiente, tivemos que criar
|
||||
pastas e sincronizar os relógios de todas as VMs visto que elas estarem ligeiramente atrasadas nunca conseguíamos acertar na
|
||||
password do google-authenticator visto que utiliza o tempo local para calcular a sua chave.
|
||||
|
||||
\begin{codeblock}[bash]{VM\_CONFIG.sh}
|
||||
yum install -y epel-release
|
||||
yum install -y openvpn iptables-services dhcp-client
|
||||
systemctl stop firewalld
|
||||
systemctl disable firewalld
|
||||
systemctl mask firewalld
|
||||
systemctl enable iptables
|
||||
iptables -F
|
||||
|
||||
CA_DIR="/etc/pki/CA"
|
||||
mkdir -p "${CA_DIR}/newcerts"
|
||||
mkdir -p "${CA_DIR}/private"
|
||||
touch "${CA_DIR}/index.txt"
|
||||
cp ca/serial "${CA_DIR}/serial"
|
||||
|
||||
mkdir -p /etc/openvpn/server
|
||||
mkdir -p /etc/openvpn/client
|
||||
|
||||
# NOTE(vasco): tive problemas com a sincronizacao de tempo
|
||||
# se nao tiver sincronizado, o TOTP nao funciona
|
||||
systemctl stop chronyd
|
||||
ntpdate pool.ntp.org
|
||||
systemctl start chronyd
|
||||
\end{codeblock}
|
||||
|
||||
|
||||
\section{VPN Gateway}
|
||||
|
||||
\subsection{Configuração da Máquina}
|
||||
|
||||
Como já foi dito anteriormente, cada máquina vem com um \textit{script}
|
||||
que instala toda a configuração necessária.
|
||||
|
||||
Para que a gateway funcione como router entre a rede externa e a rede interna,
|
||||
foi necessário ativar o \textit{IP forwarding} no kernel e configurar as regras
|
||||
de \textit{iptables} para permitir o tráfego da VPN e realizar o mascaramento
|
||||
de IP (NAT).
|
||||
|
||||
% NOTA(vasco): Não temos regras de DROP a packets
|
||||
% talvez deviamos mudar isso nao sei <- não diz nada no enunciado ¯\_(ツ)_/¯
|
||||
% também o trabalho não é sobre ip tables por isso it does make sense não fazer drop
|
||||
%e utilizar as regras apenas para encaminhar corretamente.
|
||||
% Colocar isso na conclusão tho
|
||||
|
||||
\begin{codeblock}[bash]{VM\_VPN\_GATEWAY.sh}
|
||||
#!/bin/bash
|
||||
|
||||
# --- configuracao --- #
|
||||
source VM_CONFIG.sh
|
||||
yum install -y google-authenticator qrencode ntpsec
|
||||
|
||||
# --- forwarding --- #
|
||||
if_fora="enp0s8"
|
||||
ip_fora="193.136.212.1"
|
||||
if_dentro="enp0s9"
|
||||
ip_dentro="10.60.0.3"
|
||||
mega_tunel="tun0"
|
||||
ip_mega_tunel="10.8.0.0/24"
|
||||
|
||||
ifconfig $if_fora $ip_fora netmask 255.255.255.0
|
||||
ifconfig $if_dentro $ip_dentro netmask 255.255.255.0
|
||||
|
||||
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
|
||||
sysctl -p /etc/sysctl.conf
|
||||
|
||||
iptables -I INPUT 1 -p udp --dport 1194 -j ACCEPT
|
||||
iptables -I FORWARD 1 -i $mega_tunel -o $if_dentro -j ACCEPT
|
||||
iptables -I FORWARD 1 -i $if_dentro -o $mega_tunel -j ACCEPT
|
||||
iptables -I FORWARD 1 -i $mega_tunel -o $if_fora -j ACCEPT
|
||||
iptables -I FORWARD 1 -i $if_fora -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
iptables -t nat -A POSTROUTING -s $ip_mega_tunel -o $if_fora -j MASQUERADE
|
||||
iptables-save > /etc/sysconfig/iptables
|
||||
|
||||
# --- vpn server --- #
|
||||
vpn_dir="/etc/openvpn/server"
|
||||
cp ca/ta.key $vpn_dir
|
||||
cp ca/ca.crt $vpn_dir
|
||||
cp ca/vpn.key $vpn_dir
|
||||
cp ca/vpn.crt $vpn_dir
|
||||
cp ca/dh2048.pem $vpn_dir
|
||||
cp conf/vpn.conf $vpn_dir
|
||||
cp conf/ocsp-verify.sh $vpn_dir
|
||||
cp conf/totp /etc/pam.d/
|
||||
|
||||
# --- utilizador --- #
|
||||
id -u john &>/dev/null || useradd john
|
||||
echo "password" | passwd --stdin john
|
||||
|
||||
openvpn --config /etc/openvpn/server/vpn.conf
|
||||
\end{codeblock}
|
||||
|
||||
\subsection{Configuração do Serviço OpenVPN}
|
||||
|
||||
|
||||
O servidor OpenVPN utiliza um certificado X.509 assinado pelo nosso \textit{Certificate Authority} (CA).
|
||||
E faz uso de um script \texttt{oscp-verify.sh} para validar ou revogar os certificados através do servidor OCSP.
|
||||
|
||||
\begin{codeblock}{vpn.conf}
|
||||
local 193.136.212.1
|
||||
port 1194
|
||||
proto udp
|
||||
dev tun
|
||||
|
||||
verb 4
|
||||
|
||||
ca /etc/openvpn/server/ca.crt
|
||||
cert /etc/openvpn/server/vpn.crt
|
||||
key /etc/openvpn/server/vpn.key
|
||||
dh /etc/openvpn/server/dh2048.pem
|
||||
|
||||
topology subnet
|
||||
server 10.8.0.0 255.255.255.0
|
||||
push "route 10.60.0.0 255.255.255.0"
|
||||
|
||||
# ocsp and revocation
|
||||
script-security 2
|
||||
tls-verify /etc/openvpn/server/ocsp-verify.sh
|
||||
# auth
|
||||
cipher AES-256-GCM
|
||||
auth SHA256
|
||||
|
||||
plugin /usr/lib64/openvpn/plugins/openvpn-plugin-auth-pam.so totp
|
||||
tls-auth /etc/openvpn/server/ta.key 0
|
||||
\end{codeblock}
|
||||
|
||||
Foi criado o ficheiro \texttt{totp} com a configuração de autenticação a
|
||||
ser utilizada pelo plugin de PAM para o openvpn.
|
||||
|
||||
\begin{codeblock}{totp}
|
||||
auth required pam_google_authenticator.so forward_pass
|
||||
auth required pam_unix.so use_first_pass
|
||||
account required pam_unix.so
|
||||
\end{codeblock}
|
||||
|
||||
Este script simplesmente comunica com o servidor OpenSSl
|
||||
e verifica o resultado.
|
||||
|
||||
\begin{codeblock}{ocsp\_verify.sh}
|
||||
#!/bin/bash
|
||||
depth=$1
|
||||
if [ "$depth" -eq 0 ]; then
|
||||
if [ -n "$tls_serial_0" ]; then
|
||||
# e preciso converter o serial para hexadecimal porque o openssl espera em hex
|
||||
hex_serial=$(printf '%x' "$tls_serial_0")
|
||||
status=$(openssl ocsp -issuer /etc/openvpn/server/ca.crt -serial "0x$hex_serial" -url http://10.60.0.1:8888 -CAfile /etc/openvpn/server/ca.crt 2>/dev/null)
|
||||
if echo "$status" | grep -q "good"; then
|
||||
exit 0 # sucesso
|
||||
fi
|
||||
exit 1 # revogado ou nao encontrado
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
\end{codeblock}
|
||||
|
||||
\subsection{Erros}
|
||||
|
||||
Um dos erros que encontramos pelo caminho foi que o OpenSSL OCSP espera que o
|
||||
\textit{serial} esteja num formato diferente do que o esperado. Foi necessário
|
||||
converter para hexadecimal primeiro.
|
||||
|
||||
Adicionalmente, devido às restrições de segurança do \textit{systemd},
|
||||
tentamos desativar o \texttt{ProtectHome} no serviço do OpenVPN
|
||||
para que o plugin PAM consiga ler os ficheiros de segredo do Google Authenticator
|
||||
localizados nas diretorias \textit{home} dos utilizadores. Mas isto não
|
||||
foi suficiente, por isso acabamos por correr os serviços pela linha
|
||||
de comandoos.
|
||||
|
||||
\subsection{Configurar o utilizador com TOTP}
|
||||
|
||||
Primeiro, na gateway, entramos como o utilizador desejado e obtemos a chave
|
||||
do gerador de palavras passes temporárias. Ao inserir a chave no
|
||||
\texttt{google authenticator} podemos obter um código QR, a nossa primeira
|
||||
chave de 6 dígitos.
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=8em]{google-authenticator}
|
||||
\end{figure}
|
||||
|
||||
\begin{codeblock}[bash]{}
|
||||
su john
|
||||
google-authenticator
|
||||
\end{codeblock}
|
||||
|
||||
\section{VPN Client (Road Warrior)}
|
||||
|
||||
\subsection{Configuração da Máquina}
|
||||
Para a configuração da Máquina, configuramos o edereço, o default gateway e adicionamos apache aos Hosts:
|
||||
|
||||
\begin{codeblock}{VM\_ROAD\_WARRIOR.sh}
|
||||
#!/bin/bash
|
||||
|
||||
# --- configuracao --- #
|
||||
source VM_CONFIG.sh
|
||||
ifconfig enp0s8 193.136.212.10 netmask 255.255.255.0
|
||||
route add default gw 193.136.212.1
|
||||
|
||||
if ! grep -q "apache" /etc/hosts; then
|
||||
echo "10.60.0.1 apache" >> /etc/hosts
|
||||
fi
|
||||
|
||||
# --- vpn client --- #
|
||||
vpn_dir="/etc/openvpn/client/"
|
||||
cp ca/ta.key $vpn_dir
|
||||
cp ca/ca.crt $vpn_dir
|
||||
cp ca/user.key $vpn_dir
|
||||
cp ca/user.crt $vpn_dir
|
||||
cp conf/client.conf $vpn_dir
|
||||
|
||||
openvpn --config "${vpn_dir}/client.conf"
|
||||
\end{codeblock}
|
||||
|
||||
|
||||
% Esta configuração foi necessaria, porque sem edereço a VM não conseguia-se identificar na rede. Sem o default gateway
|
||||
% os edereços desconhecidos seriam enviados para a porta da internet, e adicionamos apache aos Hosts para que fosse igual
|
||||
% ao domain para não haver erros.
|
||||
%(I dunno about this Apache part??) Also sinto que ainda precisa de mais um bocado.
|
||||
Também foram movidos os certificados e chaves necessarias para as pastas do serviço openvpn, para que o Road Warrior
|
||||
consiga comunicar e ser validado pela gateway.
|
||||
|
||||
|
||||
\subsection{Configuração do Cliente OpenVPN}
|
||||
|
||||
O cliente encontra-se na rede externa (\texttt{193.136.212.10}) e liga-se à VPN
|
||||
gateway na porta 1194. Para garantir a segurança, utilizamos autenticação mútua (os certificados X.509)
|
||||
e um \textit{two factor authentication} (2FA) como palavras-passe temporárias, geradas através do
|
||||
\textit{Google Authenticator}.
|
||||
|
||||
\begin{codeblock}{client.conf}
|
||||
client
|
||||
dev tun
|
||||
proto udp
|
||||
remote 193.136.212.1 1194
|
||||
ca ca.crt
|
||||
cert user.crt
|
||||
key user.key
|
||||
auth-user-pass
|
||||
cipher AES-256-GCM
|
||||
auth SHA256
|
||||
\end{codeblock}
|
||||
|
||||
\subsection{Testes}
|
||||
Para verificar que a autenticação foi corretamente implementada, inserimos a password de um utilizador sem os digitos do TOTP, e identificamos que utilizar somente a password não é suficiente para autenticar. Igualmente ao utilizar ambos a autenticação é bem sucedida.
|
||||
|
||||
Para verificar que o tunel foi estabelecido, primeiro corremos na linha de comandos \texttt{ip a}. Observamos a existencia de uma nova interface tun0, ou seja o tunel foi corretamente establecido. Depois demos ping ao route e depois ao servidor interno, que resultou em pacotes devolvidos para ambos.
|
||||
|
||||
|
||||
|
||||
% TODO: screenshots? dizer que erros exatos nos obtemos a cada etapa
|
||||
% TODO: erros ortograficos lol
|
||||
|
||||
Para verificar que o OCSP funciona correctamente, o cliente conectou ao servidor OpenVPN:
|
||||
primeiro, sem o servidor OCSP a correr, uma segunda vez com ele a correr e com o certificado correcto
|
||||
e uma terceira vez com um certificado revogado. Fizemos estes testes sabendo que o
|
||||
cliente e o servidor já estavam correctamente configurados.
|
||||
|
||||
Verificamos que, como é suposto: sem OCSP não é possivel autenticar; com OCSP e com certificado válido,
|
||||
podemos autenticar; e com OCSP mas com certificado revogado, a autenticação falha.
|
||||
|
||||
\section{Servidor Apache e OCSP}
|
||||
Para a configuração da ultima maquina, temos o OpenSSL e Apache no mesmo servidor, por isso temos de configurar
|
||||
as pastas necessarias, os utilizadores do serviço, configurar os edereços e uma route:
|
||||
\begin{codeblock}{VM\_OPENSSL\_APACHE.sh}
|
||||
#!/bin/bash
|
||||
# configuracao
|
||||
source VM_CONFIG.sh
|
||||
|
||||
sudo yum install -y epel-release
|
||||
sudo yum install -y openssl httpd mod_ssl mod_authnz_pam google-authenticator
|
||||
sudo yum install -y mod_session
|
||||
|
||||
# utilizador
|
||||
id -u john &>/dev/null || useradd john
|
||||
echo "password" | passwd --stdin john
|
||||
|
||||
if_dentro="enp0s8"
|
||||
ip_dentro="10.60.0.1"
|
||||
ifconfig $if_dentro $ip_dentro netmask 255.255.255.0
|
||||
|
||||
# route de volta para comunicar com o warrior
|
||||
route add -net 10.8.0.0 netmask 255.255.255.0 gw 10.60.0.3
|
||||
|
||||
cp conf/openssl.cnf /etc/pki/tls/
|
||||
|
||||
# copiar ca para esta VM
|
||||
cp ca/index.txt $CA_DIR
|
||||
cp ca/ca.crt $CA_DIR
|
||||
cp ca/ca.key $CA_DIR
|
||||
cp ca/serial $CA_DIR
|
||||
cp ca/dh2048.pem $CA_DIR
|
||||
|
||||
# correr oscp
|
||||
killall openssl 2>/dev/null
|
||||
openssl ocsp -index $CA_DIR/index.txt -port 8888 -rsigner $CA_DIR/ca.crt -rkey $CA_DIR/ca.key -CA $CA_DIR/ca.crt -text &
|
||||
|
||||
# apache
|
||||
mkdir -p /etc/httpd/ssl
|
||||
cp ca/ca.crt /etc/httpd/ssl/
|
||||
cp ca/apache.crt /etc/httpd/ssl/
|
||||
cp ca/apache.key /etc/httpd/ssl/
|
||||
cp conf/ssl.conf /etc/httpd/conf.d/ssl.conf
|
||||
cp conf/httpd.conf /etc/httpd/conf/httpd.conf
|
||||
cp conf/httpd-totp /etc/pam.d/httpd-totp
|
||||
|
||||
echo "LoadModule session_module modules/mod_session.so" > /etc/httpd/conf.modules.d/01-session.conf
|
||||
echo "LoadModule session_cookie_module modules/mod_session_cookie.so" >> /etc/httpd/conf.modules.d/01-session.conf
|
||||
echo "LoadModule auth_form_module modules/mod_auth_form.so" > /etc/httpd/conf.modules.d/01-auth_form.conf
|
||||
|
||||
cp -r www/* /var/www/html/
|
||||
chown -R apache:apache /var/www/html/
|
||||
|
||||
httpd -X
|
||||
\end{codeblock}
|
||||
|
||||
\subsection{Configuração da Máquina}
|
||||
|
||||
Como já referimos a Máquina tem ambos o serviço OpenSSL e Apache, por isso vai precisar de dois .conf files para
|
||||
configurar-los. O httpd.conf tem as portas e modulos enquanto o ssl.conf tem a configuração da autenticação mútua, e o OCSP:
|
||||
\begin{codeblock}{httpd.conf}
|
||||
ServerRoot "/etc/httpd"
|
||||
|
||||
Include conf.modules.d/*.conf
|
||||
LoadModule authnz_pam_module modules/mod_authnz_pam.so
|
||||
LoadModule mpm_event_module modules/mod_mpm_event.so
|
||||
|
||||
User apache
|
||||
Group apache
|
||||
|
||||
Listen 80
|
||||
Listen 443
|
||||
|
||||
Include conf.d/*.conf
|
||||
|
||||
DocumentRoot "/var/www/html"
|
||||
<Directory "/var/www/html">
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
\end{codeblock}
|
||||
|
||||
\begin{codeblock}{ssl.conf}
|
||||
<VirtualHost *:443>
|
||||
ServerName 10.60.0.1
|
||||
DocumentRoot /var/www/html
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/httpd/ssl/apache.crt
|
||||
SSLCertificateKeyFile /etc/httpd/ssl/apache.key
|
||||
SSLCACertificateFile /etc/httpd/ssl/ca.crt
|
||||
|
||||
# mutual authentication
|
||||
SSLVerifyClient require
|
||||
SSLVerifyDepth 1
|
||||
|
||||
# ocsp validation
|
||||
SSLOCSPEnable on
|
||||
SSLOCSPDefaultResponder "http://10.60.0.1:8888"
|
||||
SSLOCSPOverrideResponder on
|
||||
SSLOCSPUseRequestNonce off
|
||||
|
||||
# session management
|
||||
Session On
|
||||
SessionCookieName session path=/;HttpOnly;Secure
|
||||
|
||||
# proteger
|
||||
<Location "/">
|
||||
AuthType Form
|
||||
AuthName "Coimbra VPN"
|
||||
AuthFormProvider PAM
|
||||
AuthPAMService httpd-totp
|
||||
AuthFormLoginRequiredLocation "/login.html"
|
||||
Require valid-user
|
||||
</Location>
|
||||
|
||||
# public login page
|
||||
<Location "/login.html">
|
||||
AuthType None
|
||||
Require all granted
|
||||
</Location>
|
||||
|
||||
# login handler
|
||||
<Location "/dologin">
|
||||
SetHandler form-login-handler
|
||||
AuthType Form
|
||||
AuthName "Coimbra VPN"
|
||||
AuthFormProvider PAM
|
||||
AuthPAMService httpd-totp
|
||||
Require all granted
|
||||
AuthFormLoginSuccessLocation "/index.html"
|
||||
AuthFormLoginRequiredLocation "/login.html?error=1"
|
||||
</Location>
|
||||
|
||||
# logout handler
|
||||
<Location "/logout">
|
||||
SetHandler form-logout-handler
|
||||
AuthFormLogoutLocation "/login.html?loggedout=1"
|
||||
</Location>
|
||||
|
||||
</VirtualHost>
|
||||
|
||||
# redirect para https
|
||||
<VirtualHost *:80>
|
||||
ServerName 10.60.0.1
|
||||
Redirect permanent / https://10.60.0.1/
|
||||
</VirtualHost>
|
||||
\end{codeblock}
|
||||
|
||||
\subsubsection{Testes}
|
||||
\begin{itemize}
|
||||
\item \textbf{Domínio:} Verificou-se que o acesso só é permitido utilizando o endereço correto, pois se for inserido outro dominio, não é direcionado para o site do Apache.
|
||||
\item \textbf{Redirecionamento HTTPS:} Ao testar quando colocamos http, e o dominio certo, era redirecionado para https.
|
||||
\item \textbf{Autenticação com o Certificado:} O acesso foi negado ao apresentar certificados inválidos ou ausentes no browser, devolvendo um erro com sobre não conseguir establecer connexão porque falta de certificado.
|
||||
\end{itemize}
|
||||
|
||||
Para testar o OCSP, fizemos os seguintes paços:
|
||||
|
||||
\begin{enumerate}
|
||||
\item Estabelecer a ligação VPN e verificar a conectividade à rede interna.
|
||||
\item No diretório da autoridade de certificação (máquina \textit{host}), revogar o certificado do utilizador:
|
||||
\begin{codeblock}[bash]{revoke.sh}
|
||||
openssl ca -revoke user.crt -config cheese.cfg -keyfile ca.key -cert ca.crt
|
||||
\end{codeblock}
|
||||
\item Atualizar o ficheiro \texttt{index.txt} no servidor OCSP e reiniciar o serviço para carregar o novo estado de revogação.
|
||||
\item Tentar estabelecer uma nova ligação VPN e verificar que a autenticação falha devido à resposta \texttt{revoked} do responder OCSP.
|
||||
\end{enumerate}
|
||||
|
||||
|
||||
\section{Teste Integrado}
|
||||
|
||||
Para validar, efetuámos um teste integrado englobando todos os requisitos:
|
||||
\begin{enumerate}
|
||||
\item Começamos por iniciar todas as máquinas com os devidos \textit{scripts}.
|
||||
\item Na máquina \textit{Road Warrior}, iniciámos a ligação OpenVPN com o utilizador, a sua password e o \textit{token} TOTP.
|
||||
\item O \textit{Gateway} OpenVPN verifica as credenciais e verifica o certificado cliente contra o servidor OCSP.
|
||||
\item Antes de acedermos ao firefox, temos que verificar que já adicionámos a nossa a nossa CA e o certificado \texttt{p12}.
|
||||
\item Através do túnel VPN, acedemos agora ao endereço \texttt{https://apache.coimbra} no browser.
|
||||
\item O servidor Apache solicitou o certificado X.509 do utilizador e validou a sua autenticidade e estado de revogação no OCSP.
|
||||
\item Finalmente, o Apache apresentou a página de login, onde inserimos as credenciais e o código TOTP.
|
||||
\end{enumerate}
|
||||
|
||||
|
||||
\section{Conclusão}
|
||||
|
||||
Atingimos o objetivo deste trabalho: conseguimos configurar o túnel VPN,
|
||||
o \textit{two-factor authentication} em múltiplos serviços, e conseguimos gerir o ciclo de vida dos
|
||||
certificados emitidos através de uma CA própria e OCSP. Utilizar mais máquinas para simular um cenário
|
||||
maior seria redundante e apenas exigiria a emissão de mais certificados, não acrescentando muito ao nível de aprendizagem.
|
||||
|
||||
Aplicando conhecimentos de trabalhos anteriores,
|
||||
poderíamos aplicar políticas mais restritas nas \textit{iptables} (ex: regras de DROP aos pacotes indesejados),
|
||||
e implementar ferramentas como o Suricata para identificar possíveis anomalias e ataques aos serviços.
|
||||
|
||||
\end{document}
|
||||
Reference in New Issue
Block a user