Freeradius + Google Autheticator + LDAP + Fortigate

Kva Ä gjere nÄr ein vil ha to-faktor autentisering, men ikkje har rÄd til hardware-tokens, og det blir berre sagt at ein mÄ halde ut og ha eit godt humÞr.

Denne lÞysinga er ikkje noko superoriginalt, heller ein miks av forskjellige lÞysingar funne pÄ internett.

SĂ„, her er situasjonen

Domene Active Directory.

Domenebrukarar som arbeider via VPN, slik mange gjer no om dagen.

VPN-gatewayen er Fortigate.

Lagring av passord for VPN-klienten er forbode av sikkerhetspolitikken.

Politikken Fortinet for sine eigne tokens kan ikkje kallast grĂ„dig — heile 10 gratis tokens, resten til ein svĂŠrt overprisa pris. RSASecureID, Duo og liknande blei ikkje vurdert, sidan eg ynskjer open kildekode.

FĂžrre krav: vert *nix med installert freeradius, sssd — blir innfĂžrt i domenet, domenebrukarar kan trygt autentisere seg pĂ„ det.

Tilleggs-pakkar: shellinabox, figlet, freeradius-ldap, skrifttype rebel.tlf frÄ depotet https://github.com/xero/figlet-fonts.

I mitt eksempel — CentOS 7.8.

Logikken i arbeidet vil vere som slik: ved tilkopling til VPN mÄ brukaren skrive inn domene brukarnamn og OTP i staden for passord.

Innstilling av tenestene

I /etc/raddb/radiusd.conf endrar berre brukaren og gruppa som tenesta startar under freeradius, sidan tenesta radiusd mÄ kunne lese filer i alle underkatalogane /home/.

user = root
group = root

For Ä kunne bruke grupper i innstillingane Fortigate, mÄ ein sende Vendor Specific Attribute. For dette i katalogen raddb/policy.d lagar eg ein fil med fÞlgjande innhald:

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 := "Velkomen Admin"
                }
        }
    else {
        update reply {
        &Reply-Message := "Ikke autorisert for vpn"
            }
        reject
        }
}

Etter installasjonen freeradius-ldap public/functions raddb/mods-available blir det oppretta ei fil ldap.

Ein mÄ lage ei symbolsk lenke i katogorien raddb/mods-enabled.

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

Eg tilpassar innhaldet slik:

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

I filene raddb/sites-enabled/default og raddb/sites-enabled/inner-tunnel i seksjonen authorisere legger til navnet pĂ„ policyen som skal brukes — group_authorization. En viktig detalj — navnet pĂ„ policyen defineres ikke av filnavnet i katalogen policy.d, men av direktivet inne i filen fĂžr klammeparentesene.
I seksjonen autentisere i disse filene mÄ du avkommentere linjen pam.

I filen clients.conf skriver inn parameterne som skal brukes for tilkobling Fortigate:

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

Konfigurasjon av modulen 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

Standardalternativene for implementeringen av freeradius med google authenticator forutsetter at brukeren angir legitimasjon i formatet: brukernavn/passord+OTP.

Med tanke pÄ antallet forbannelser som ville ramme hodet hvis standardkombinasjonen ble brukt freeradius med Google Authenticator, ble det besluttet Ä bruke modulkonfigurasjonen pam slik at bare tokenet sjekkes Google Authenticator.

Ved tilkobling av brukeren skjer fĂžlgende:

  • Freeradius sjekker om brukeren finnes i domenet og i en bestemt gruppe, og hvis det er vellykket, blir OTP-tokenet sjekket.

Alt sÄ ganske bra ut frem til jeg tenkte: «Hvordan registrerer jeg OTP for 300+ brukere?»

Brukeren mÄ logge inn pÄ serveren med freeradius og fra sin egen konto og starte applikasjonen Google authenticator, som vil generere QR-koden for brukeren. Her kommer shellinabox i kombinasjon med .bash_profile.

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

Konfigurasjonsfilen for daemonen finnes i /etc/sysconfig/shellinabox.
Angir port 443 der, og det er mulig Ă„ angi sitt eget sertifikat.

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

Brukeren mÄ bare gÄ til lenken, skrive inn domenelogin og fÄ QR-koden for applikasjonen.

Algoritmen er som fĂžlger:

  • Brukeren logger inn pĂ„ maskinen via nettleseren.
  • Det sjekkes om brukeren er fra domenet. Hvis ikke, tas det ingen tiltak.
  • Hvis brukeren er fra domenet, sjekkes det om han tilhĂžrer administratorgruppen.
  • Hvis ikke admin, sjekkes det om Google Authenticator er konfigurert. Hvis ikke, genereres QR-koden, og brukeren logges ut.
  • Hvis ikke admin og Google Authenticator er konfigurert, logges brukeren bare ut.
  • Hvis admin, sjekkes Google Authenticator igjen. Hvis ikke konfigurert, genereres QR-koden.

All logikken utfĂžres ved hjelp av /etc/skel/.bash_profile.

cat /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

Konfigurasjon av Fortigate:

  • Vi oppretter Radius-server

    Freeradius + Google Autheticator + LDAP + Fortigate

  • Vi oppretter nĂždvendige grupper, i tilfelle det er behov for Ă„ begrense tilgang etter grupper. Gruppenavnet mĂ„ Fortigate tilsvare gruppen som blir sendt til Vendor Specific Attribute Fortinet-Group-Name.

    Freeradius + Google Autheticator + LDAP + Fortigate

  • Vi redigerer nĂždvendige SSL-portaler.

    Freeradius + Google Autheticator + LDAP + Fortigate

  • Vi legger til grupper i retningslinjene.

    Freeradius + Google Autheticator + LDAP + Fortigate

Fordeler med denne lĂžsningen:

  • Det er mulig med autentisering via OTP pĂ„ Fortigate Ă„pen kildekode-lĂžsning.
  • Brukeren trenger ikke Ă„ skrive inn domenepassordet ved tilkobling via VPN, noe som forenkler tilkoblingsprosessen. Det er lettere Ă„ skrive inn et 6-sifret passord enn det som kreves av sikkerhetspolicyen. Som et resultat reduseres antall billetter med emnet: «Kan ikke koble til VPN».

P.S. Vi planlegger Ă„ utvikle denne lĂžsningen til en fullverdig to-faktor-autentisering med challenge-response.

Oppdatering:

Som lovet, har jeg nÄ faktisk fÄtt det til med challenge-response.
So:
I filen /etc/raddb/sites-enabled/default seksjon authorisere ser slik ut:

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
}

Seksjon autentisere har nÄ fÞlgende utseende:

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 {
                # Opprett en tilfeldig State-attribut:
                State := "%{randstr:aaaaaaaaaaaaaaaa}"
                Reply-Message := "Vennligst skriv inn OTP"
                }
            # Return Access-Challenge:
            challenge
            }
        }
        pam
        eap
}

NĂ„ skjer brukerverifiseringen etter fĂžlgende algoritme:

  • Brukeren skriver inn domenelogin i VPN-klienten.
  • Freeradius sjekker gyldigheten av brukerkontoen og passordet
  • Hvis passordet er korrekt, sendes en forespĂžrsel om token.
  • Det skjer en sjekk av tokenet.
  • Profit).

Kilde: habr.com

KjĂžp pĂ„litelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere đŸ”„ KjĂžp pĂ„litelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster