Freeradius + Google Authenticator + LDAP + Fortigate

Vad ska man göra om man bÄde vill och behöver tvÄfaktorsautentisering, men inte har rÄd med hÄrdvarutoken, och överhuvudtaget uppmanas att hÄlla sig god humör.

Denna lösning Àr inte sÀrskilt originell, snarare en blandning av olika lösningar som hittats pÄ internet.

SĂ„, givet

DomÀn Active Directory.

DomÀnanvÀndare som arbetar via VPN, precis som mÄnga idag.

VPN-gatewayn Àr Fortigate.

Att spara lösenordet för VPN-klienten förbjuds av sÀkerhetspolicyn.

Policyn Fortinet angÄende egna tokens kan inte kallas annat Àn generös - 10 gratis tokens, resten till ett mycket osmakligt pris. RSASecureID, Duo och liknande övervÀgdes inte, dÄ man vill ha öppen kÀllkod.

PreliminÀra krav: vÀrd *nix installerat freeradius, sssd - Àr införlivad i domÀnen, domÀnanvÀndare kan enkelt autentisera sig dÀr.

Ytterligare paket: shellinabox, figlet, freeradius-ldap, teckensnitt rebel.tlf frÄn förrÄdet https://github.com/xero/figlet-fonts.

I mitt exempel - CentOS 7.8.

Arbetslogiken ska vara sÄ hÀr: nÀr anvÀndaren ansluter till VPN, mÄste de ange sitt domÀnlösen och OTP istÀllet för lösenord.

InstÀllning av tjÀnster

I /etc/raddb/radiusd.conf endast anvÀndare och grupp Àndras, som tjÀnsten startar under freeradius, eftersom tjÀnsten radiusd mÄste kunna lÀsa filer i alla underkataloger /home/.

user = root
group = root

För att kunna anvÀnda grupper i instÀllningarna Fortigate, mÄste man överföra Vendor Specific Attribute. För detta i katalogen raddb/policy.d skapar jag en fil med följande innehÄll:

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 := "VĂ€lkommen Admin"
                }
        }
    else {
        update reply {
        &Reply-Message := "Inte auktoriserad för vpn"
            }
        reject
        }
}

Efter installationen freeradius-ldap i katalogen raddb/mods-available skapas en fil ldap.

Det Àr nödvÀndigt att skapa en symbolisk lÀnk i katalogen raddb/mods-enabled.

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

Jag justerar dess innehÄll till följande:

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 filer raddb/sites-enabled/default och raddb/sites-enabled/inner-tunnel i sektionen authorize jag lÀgger till namnet pÄ policyn som kommer att anvÀndas - group_authorization. En viktig aspekt Àr att namnet pÄ policyn bestÀms av direktivet innanför klamrarna. policy.d, via direktivet inuti filen innan klamrarna.
I avsnittet authenticate i dessa filer behöver du avkommentera raden pam.

I filen clients.conf vi anger de parametrar som kommer att anvÀndas för anslutningen Fortigate:

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

Konfiguration 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

Standardalternativ för integration av freeradius med google authenticator krÀver att anvÀndaren anger sina referenser i formatet: anvÀndarnamn/lösenord+OTP.

Med tanke pÄ hur mÄnga svordomar som kommer att falla pÄ mitt huvud om standardintegrationen anvÀnds freeradius med Google Authenticator, beslutades det att anvÀnda modulkontrollen pam sÄ att endast tokenen verifieras Google Authenticator.

Vid anslutning av en anvÀndare hÀnder följande:

  • Freeradius kontrollerar om anvĂ€ndaren finns i domĂ€nen och i en viss grupp och, om det lyckas, görs en kontroll av OTP-token.

Allt verkade ganska bra tills jag började tÀnka "Hur ska jag registrera OTP för 300+ anvÀndare?"

AnvÀndaren mÄste logga in pÄ servern med freeradius och under sitt konto köra applikationen Google authenticator, som kommer att generera en QR-kod för anvÀndaren. HÀr kommer shellinabox i kombination med .bash_profile.

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

Konfigurationsfilen för demon finns i /etc/sysconfig/shellinabox.
Jag angav dÀr port 443 och kan ocksÄ ange mitt certifikat.

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

AnvÀndaren behöver bara gÄ till lÀnken, ange domÀnens uppgifter och fÄ QR-koden för applikationen.

Algoritmen Àr följande:

  • AnvĂ€ndaren loggar in pĂ„ maskinen via webblĂ€saren.
  • Det kontrolleras om anvĂ€ndaren tillhör domĂ€nen. Om inte, vidtas inga Ă„tgĂ€rder.
  • Om anvĂ€ndaren Ă€r en domĂ€nanvĂ€ndare kontrolleras medlemskapet i administratörsgruppen.
  • Om anvĂ€ndaren inte Ă€r administratör kontrolleras om Google Authenticator Ă€r instĂ€llt. Om det inte Ă€r det genereras en QR-kod och anvĂ€ndaren loggas ut.
  • Om anvĂ€ndaren inte Ă€r administratör och Google Authenticator Ă€r instĂ€llt, loggas anvĂ€ndaren bara ut.
  • Om anvĂ€ndaren Ă€r administratör görs en ny kontroll av Google Authenticator. Om det inte Ă€r instĂ€llt genereras en QR-kod.

All logik utförs med hjÀlp 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

Konfiguration av Fortigate:

  • Vi skapar Radius-server

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Skapa nödvĂ€ndiga grupper om det behövs för att avgrĂ€nsa Ă„tkomst per grupp. Gruppens namn ska Fortigate överensstĂ€mma med den grupp som skickas i Vendor Specific Attribute Fortinet-Group-Name.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Redigera nödvĂ€ndiga SSL-portaler.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • LĂ€gg till grupper i policyerna.

    Freeradius + Google Authenticator + LDAP + Fortigate

Fördelarna med denna lösning:

  • Det finns möjlighet till autentisering via OTP pĂ„ Fortigate lösningar med öppen kĂ€llkod.
  • Inmatning av domĂ€nens lösenord av anvĂ€ndaren vid anslutning via VPN utesluts, vilket förenklar anslutningsprocessen. Att ange ett 6-siffrigt lösenord Ă€r enklare Ă€n det som föreskrivs av sĂ€kerhetspolicyn. Som en följd minskas antalet Ă€renden med Ă€mnet: 'Kan inte ansluta till VPN'.

P.S. Planen Àr att utveckla denna lösning till en fullstÀndig tvÄfaktorsautentisering med challenge-response.

Update:

Som jag lovade har jag nu utvecklat till en variant med challenge-response.
SĂ„:
I filen /etc/raddb/sites-enabled/default sektion authorize ser ut som följer:

authorize {
    filter_username
    preprocess
    auth_log
    chap
    mschap
    suffix
    eap {
        ok = return
    }
    files
    -sql
    #-ldap
    expiration
    logintime
    if (!State) {
        if (&User-Password) {
            # Om !State och User-Password (PAP), tvinga LDAP:
            update control {
                Ldap-UserDN := "%{User-Name}"
                Auth-Type := LDAP
            }
        }
        else {
            reject
        }
    }
    else {
        # Om State, proxyförfrÄgan:
        group_authorization
    }
pap
}

Sektion authenticate har nu följande utseende:

authenticate {
        Auth-Type PAP {
                pap
        }
        Auth-Type CHAP {
                chap
        }
        Auth-Type MS-CHAP {
                mschap
        }
        mschap
        digest
        # Försök autentisering med direkt LDAP-bindning:
        Auth-Type LDAP {
        ldap
        if (ok) {
            update reply {
                # Skapa ett slumpmÀssigt State-attribut:
                State := "%{randstr:aaaaaaaaaaaaaaaa}"
                Reply-Message := "VĂ€nligen ange OTP"
                }
            # ÅtervĂ€nd Access-Challenge:
            challenge
            }
        }
        pam
        eap
}

Nu sker kontroll av anvÀndaren enligt följande algoritm:

  • AnvĂ€ndaren anger domĂ€nuppgifterna i VPN-klienten.
  • Freeradius kontrollerar giltigheten av kontot och lösenordet.
  • Om lösenordet Ă€r korrekt, skickas en förfrĂ„gan om token.
  • Kontroll av token sker.
  • Vinsten).

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster