Freeradius + Google Autheticator + LDAP + Fortigate

¿Qué pasa si la autenticación de dos factores es deseable y espinosa, pero no hay dinero para tokens de hardware y, en general, ofrecen mantenerse de buen humor?



Esta solución no es algo súper original, sino más bien una combinación de diferentes soluciones que se encuentran en Internet.



Entonces, dado



Dominio de Active Directory .



Usuarios de dominio que usan una VPN, como muchos hoy en día. Fortigate



actúa como una puerta de enlace VPN . La política de seguridad prohíbe guardar la contraseña para el cliente VPN. La política de Fortinet con respecto a sus propios tokens no se puede llamar menos que redneck: hay hasta 10 tokens gratuitos, el resto tiene un precio muy poco kosher. RSASecureID, Duo y similares no se han considerado, porque quiero código abierto. Requisitos previos: * host nix con freeradius instalado , sssd : ingresado en el dominio, los usuarios del dominio pueden autenticarse fácilmente en él. Paquetes adicionales:















shellinabox , figlet , freeeradius-ldap , rebel.tlf fuente del repositorio https://github.com/xero/figlet-fonts .



En mi ejemplo, CentOS 7.8.



La lógica del trabajo es la siguiente: cuando se conecta a una VPN, el usuario debe ingresar un nombre de usuario de dominio y una OTP en lugar de una contraseña.



Configurar servicios



En /etc/raddb/radiusd.conf, sólo se cambia el usuario y el grupo bajo el cual comienza freeradius , ya que el servicio radiusd debe poder leer archivos en todos los subdirectorios de / home / .



user = root
group = root


Para poder usar grupos en la configuración de Fortigate , debe pasar el Atributo específico del proveedor . Para hacer esto, en el directorio raddb / policy.d, cree un archivo con el siguiente contenido:



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
        }
}


Después de instalar freeradius-ldap en el directorio raddb / mods-available , se crea el archivo ldap .



Necesita crear un enlace simbólico al directorio raddb / mods-enabled .



ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldap


Traigo su contenido a este formulario:



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'
        }
}


En los archivos raddb / sites-enabled / default y raddb / sites-enabled / inner-tunnel en la sección de autorización agrego el nombre de la política que se utilizará: group_authorization. Un punto importante: el nombre de la política no está determinado por el nombre del archivo en el directorio policy.d , sino por la directiva dentro del archivo antes de las llaves.

En la sección de autenticación de los mismos archivos, elimine el comentario de pam .



En el archivo clients.conf, escriba los parámetros con los que se conectará Fortigate :



client fortigate {
    ipaddr = 192.168.1.200
    secret = testing123
    require_message_authenticator = no
    nas_type = other
}


Configuración del 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


Las opciones predeterminadas para implementar el paquete freeradius con el autenticador de Google implican que el usuario ingrese credenciales en el formato: nombre de usuario / contraseña + OTP .



Habiendo presentado la cantidad de maldiciones que caerán sobre su cabeza, en el caso de usar el paquete freeradius predeterminado con Google Authenticator , se decidió usar la configuración del módulo pam para verificar solo el token de Google Authenticator .



Cuando un usuario se conecta, sucede lo siguiente:



  • Freeradius verifica la presencia del usuario en el dominio y en un grupo específico y, si tiene éxito, verifica el token OTP.


Todo parecía suficientemente bueno hasta que pensé: "¿Cómo puedo registrar OTP para más de 300 usuarios?"



El usuario debe iniciar sesión en el servidor con freeradius y bajo su cuenta y ejecutar la aplicación de autenticación de Google , que generará un código QR para la aplicación para el usuario. Aquí es donde shellinabox resulta útil en combinación con .bash_profile .



[root@freeradius ~]# yum install -y shellinabox


El archivo de configuración del demonio se encuentra en / etc / sysconfig / shellinabox .

Indico el puerto 443 allí y puede especificar su certificado.



[root@freeradius ~]#systemctl enable --now shellinaboxd


El usuario solo necesita seguir el enlace, ingresar créditos de dominio y recibir un código QR para la aplicación.



El algoritmo es como sigue:



  • El usuario inicia sesión en la máquina a través de un navegador.
  • El usuario del dominio está marcado. De lo contrario, no se realiza ninguna acción.
  • Si el usuario es un usuario de dominio, se verifica la pertenencia al grupo Administradores.
  • Si no es administrador, comprueba si Google Autheticator está configurado. De lo contrario, se genera un código QR y el cierre de sesión del usuario.
  • Si no hay un administrador y Google Authenticator está configurado, simplemente cierre la sesión.
  • Si es el administrador, vuelva a comprobar Google Authenticator. Si no está configurado, se genera un código QR.


Toda la lógica se realiza mediante /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




Configuración de Fortigate:



  • Crear un servidor Radius



  • Creamos los grupos necesarios, si es necesario, diferenciamos el acceso por grupos. El nombre del grupo en Fortigate debe coincidir con el grupo que se pasa en el atributo específico del proveedor Fortinet-Group-Name .



  • Editando los portales SSL requeridos .



  • Agregue grupos a las políticas.







Las ventajas de esta solución:

  • Existe la posibilidad de autenticación OTP en la solución de código abierto Fortigate .
  • Excluye al usuario que ingresa la contraseña del dominio cuando se conecta a través de VPN, lo que simplifica algo el proceso de conexión. La contraseña de 6 dígitos es más fácil de ingresar que la política de seguridad. Como resultado, la cantidad de tickets con el asunto: "No se puede conectar a la VPN" disminuye.


PD: Hay planes para ajustar esta solución a una autenticación completa de dos factores con desafío-respuesta.



Actualizar:



Como prometí, lo terminé hasta la opción desafío-respuesta.

Entonces:

en el archivo / etc / raddb / sites-enabled / default , la sección de autorización se ve así:



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
}


La sección de autenticación ahora se ve así:



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
}


Ahora se verifica al usuario según el siguiente algoritmo:

  • El usuario ingresa créditos de dominio en el cliente VPN.
  • Freeradius verifica la validez de la cuenta y la contraseña
  • Si la contraseña es correcta, se envía una solicitud de token.
  • El token está verificado.
  • Lucro).



All Articles