E se a autenticação de dois fatores for desejável e espinhosa, mas não há dinheiro para tokens de hardware e, em geral, eles oferecem para ficar de bom humor.
Esta solução não é algo super original, mas sim uma mistura de diferentes soluções encontradas na Internet.
Tão dado
Nome de domínio Active Directory.
Usuários de domínio que trabalham por meio de uma VPN, como muitos hoje.
Atua como um gateway VPN FortiGate.
Salvar a senha do cliente VPN é proibido pela política de segurança.
Política Fortinet no que diz respeito aos seus próprios tokens, você não pode chamá-lo de menos de um zhlob - existem até 10 tokens gratuitos, o restante - a um preço muito não kosher. Não considerei RSASecureID, Duo e similares, porque quero código aberto.
Pré-requisitos: anfitrião * nix com estabelecido freeradius, ssd - inserido no domínio, os usuários do domínio podem se autenticar facilmente nele.
Pacotes adicionais: caixa shellina, figo, freeradius-ldap, Fonte rebelde.tlf do repositório
No meu exemplo - CentOS 7.8.
A lógica do trabalho deve ser a seguinte: ao se conectar a uma VPN, o usuário deve inserir um login de domínio e OTP em vez de uma senha.
Configuração de serviços
В /etc/raddb/radiusd.conf apenas o usuário e o grupo em nome do qual inicia freeradius, já que o serviço raio deve ser capaz de ler arquivos em todos os subdiretórios /casa/.
user = root
group = root
Para poder usar grupos nas configurações FortiGate, deve ser transmitido Atributo específico do fornecedor. Para fazer isso, no diretório raddb/policy.d Criei um arquivo com o seguinte conteúdo:
group_authorization {
if (&LDAP-Group[*] == "CN=vpn_admins,OU=vpn-groups,DC=domain,DC=local") {
update reply {
&Fortinet-Group-Name = "vpn_admins" }
update control {
&Auth-Type := PAM
&Reply-Message := "Welcome Admin"
}
}
else {
update reply {
&Reply-Message := "Not authorized for vpn"
}
reject
}
}
Após a instalação freeradius-ldap no diretório raddb/mods disponíveis arquivo é criado ldap.
Precisa criar um link simbólico para o diretório raddb/mods ativado.
ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldap
Trago seu conteúdo para este formulário:
ldap {
server = 'domain.local'
identity = 'CN=freerad_user,OU=users,DC=domain,DC=local'
password = "SupeSecretP@ssword"
base_dn = 'dc=domain,dc=local'
sasl {
}
user {
base_dn = "${..base_dn}"
filter = "(sAMAccountname=%{%{Stripped-User-Name}:-%{User-Name}})"
sasl {
}
scope = 'sub'
}
group {
base_dn = "${..base_dn}"
filter = '(objectClass=Group)'
scope = 'sub'
name_attribute = cn
membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"
membership_attribute = 'memberOf'
}
}
Em arquivos raddb/sites habilitados/padrão и raddb/sites habilitados/inner-tunnel na seção autorizar Eu adiciono o nome da política a ser usada - group_authorization. Um ponto importante - o nome da política não é determinado pelo nome do arquivo no diretório política.d, mas por uma diretiva dentro do arquivo antes das chaves.
Na seção autenticar nos mesmos arquivos você precisa descomentar a linha pam.
No arquivo clientes.conf prescrever os parâmetros com os quais se conectará FortiGate:
client fortigate {
ipaddr = 192.168.1.200
secret = testing123
require_message_authenticator = no
nas_type = other
}
Configuração do módulo pam.d/radiusd:
#%PAM-1.0
auth sufficient pam_google_authenticator.so
auth include password-auth
account required pam_nologin.so
account include password-auth
password include password-auth
session include password-auth
Opções de implementação de pacote padrão freeradius с autenticador google exigir que o usuário insira credenciais no formato: usuário senha+OTP.
Imaginando a quantidade de maldições que cairão na cabeça, no caso de usar o pacote padrão freeradius с Google Authenticator, foi decidido usar a configuração do módulo pam para que apenas o token possa ser verificado Google Authenticator.
Quando um usuário se conecta, acontece o seguinte:
- O Freeradius verifica se o usuário existe no domínio e em um determinado grupo e, se for bem-sucedido, o token OTP é verificado.
Tudo parecia bom o suficiente até o momento em que pensei “Como posso registrar OTP para mais de 300 usuários?”
O usuário deve acessar o servidor com freeradius e de sua conta e execute o aplicativo Autenticador do Google, que irá gerar um código QR do aplicativo para o usuário. É aqui que entra a ajuda. caixa shellina em combinação com .bash_profile.
[root@freeradius ~]# yum install -y shellinabox
O arquivo de configuração do daemon está localizado em /etc/sysconfig/shellinabox.
Eu especifico a porta 443 lá e você pode especificar seu certificado.
[root@freeradius ~]#systemctl enable --now shellinaboxd
O usuário só precisa seguir o link, inserir os créditos do domínio e receber um código QR para o aplicativo.
O algoritmo é o seguinte:
- O usuário faz login na máquina por meio de um navegador.
- Se o usuário do domínio está marcado. Se não, então nenhuma ação é tomada.
- Se o usuário for um usuário de domínio, a associação ao grupo Administradores será verificada.
- Se não for um administrador, ele verifica se o Google Authenticator está configurado. Caso contrário, um código QR e logout do usuário serão gerados.
- Se não for um administrador e o Google Authenticator estiver configurado, basta sair.
- Se for administrador, verifique novamente o Google Authenticator. Se não configurado, um código QR é gerado.
Toda a lógica é feita usando /etc/skel/.bash_profile.
gato /etc/skel/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
# Make several commands available from user shell
if [[ -z $(id $USER | grep "admins") || -z $(cat /etc/passwd | grep $USER) ]]
then
[[ ! -d $HOME/bin ]] && mkdir $HOME/bin
[[ ! -f $HOME/bin/id ]] && ln -s /usr/bin/id $HOME/bin/id
[[ ! -f $HOME/bin/google-auth ]] && ln -s /usr/bin/google-authenticator $HOME/bin/google-auth
[[ ! -f $HOME/bin/grep ]] && ln -s /usr/bin/grep $HOME/bin/grep
[[ ! -f $HOME/bin/figlet ]] && ln -s /usr/bin/figlet $HOME/bin/figlet
[[ ! -f $HOME/bin/rebel.tlf ]] && ln -s /usr/share/figlet/rebel.tlf $HOME/bin/rebel.tlf
[[ ! -f $HOME/bin/sleep ]] && ln -s /usr/bin/sleep $HOME/bin/sleep
# Set PATH env to <home user directory>/bin
PATH=$HOME/bin
export PATH
else
PATH=PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH
fi
if [[ -n $(id $USER | grep "domain users") ]]
then
if [[ ! -e $HOME/.google_authenticator ]]
then
if [[ -n $(id $USER | grep "admins") ]]
then
figlet -t -f $HOME/bin/rebel.tlf "Welcome to Company GAuth setup portal"
sleep 1.5
echo "Please, run any of these software on your device, where you would like to setup OTP:
Google Autheticator:
AppStore - https://apps.apple.com/us/app/google-authenticator/id388497605
Play Market - https://play.google.com/stor/apps/details?id=com.google.android.apps.authenticator2&hl=en
FreeOTP:
AppStore - https://apps.apple.com/us/app/freeotp-authenticator/id872559395
Play Market - https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp&hl=en
And prepare to scan QR code.
"
sleep 5
google-auth -f -t -w 3 -r 3 -R 30 -d -e 1
echo "Congratulations, now you can use an OTP token from application as a password connecting to VPN."
else
figlet -t -f $HOME/bin/rebel.tlf "Welcome to Company GAuth setup portal"
sleep 1.5
echo "Please, run any of these software on your device, where you would like to setup OTP:
Google Autheticator:
AppStore - https://apps.apple.com/us/app/google-authenticator/id388497605
Play Market - https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en
FreeOTP:
AppStore - https://apps.apple.com/us/app/freeotp-authenticator/id872559395
Play Market - https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp&hl=en
And prepare to scan QR code.
"
sleep 5
google-auth -f -t -w 3 -r 3 -R 30 -d -e 1
echo "Congratulations, now you can use an OTP token from application as a password to VPN."
logout
fi
else
echo "You have already setup a Google Authenticator"
if [[ -z $(id $USER | grep "admins") ]]
then
logout
fi
fi
else
echo "You don't need to set up a Google Authenticator"
fi
Fortigar configuração:
- Criar Raio-servidor
- Criamos os grupos necessários, se necessário, controle de acesso por grupos. Nome do grupo ativado FortiGate deve corresponder ao grupo que é passado em Atributo específico do fornecedor Nome do Grupo Fortinet.
- Editando o necessário SSL-portais.
- Adicionando grupos a políticas.
As vantagens desta solução:
- É possível autenticar por OTP em FortiGate solução de código aberto.
- O usuário não insere uma senha de domínio ao se conectar via VPN, o que simplifica um pouco o processo de conexão. A senha de 6 dígitos é mais fácil de inserir do que a fornecida pela política de segurança. Como resultado, o número de tickets com o assunto: “Não consigo me conectar à VPN” diminui.
PS Planejamos atualizar esta solução para uma autenticação de dois fatores completa com resposta de desafio.
Update:
Como prometido, mudei para a opção de resposta ao desafio.
Assim:
No arquivo /etc/raddb/sites-enabled/default seção autorizar é o seguinte:
authorize {
filter_username
preprocess
auth_log
chap
mschap
suffix
eap {
ok = return
}
files
-sql
#-ldap
expiration
logintime
if (!State) {
if (&User-Password) {
# If !State and User-Password (PAP), then force LDAP:
update control {
Ldap-UserDN := "%{User-Name}"
Auth-Type := LDAP
}
}
else {
reject
}
}
else {
# If State, then proxy request:
group_authorization
}
pap
}
Секция autenticar agora está assim:
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
digest
# Attempt authentication with a direct LDAP bind:
Auth-Type LDAP {
ldap
if (ok) {
update reply {
# Create a random State attribute:
State := "%{randstr:aaaaaaaaaaaaaaaa}"
Reply-Message := "Please enter OTP"
}
# Return Access-Challenge:
challenge
}
}
pam
eap
}
Agora a verificação do usuário ocorre de acordo com o seguinte algoritmo:
- O usuário insere créditos de domínio no cliente VPN.
- Freeradius verifica a validade da conta e senha
- Se a senha estiver correta, uma solicitação de token será enviada.
- O token está sendo verificado.
- lucro).
Fonte: habr.com