Freeradius + Google Authenticator + LDAP + Fortigate

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 https://github.com/xero/figlet-fonts.

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

    Freeradius + Google Authenticator + LDAP + Fortigate

  • 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.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Editando o necessário SSL-portais.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Adicionando grupos a políticas.

    Freeradius + Google Authenticator + LDAP + Fortigate

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

Adicionar um comentário