Freeradius + Google Authenticator + LDAP + Fortigate

Čo robiť, ak je dvojfaktorová autentifikácia potrebná, ale nemáme peniaze na hardvérové tokeny, a navyše odporúčajú, aby sme sa dobre cítili.

Toto riešenie nie je ničím superoriginálnym, skôr mix rôznych riešení nájdených na internete.

Takže, máme

Doména Active Directory.

Používatelia domény, ktorí používajú VPN, ako mnohí dnes.

VPN bránu zabezpečuje Fortigate.

Uloženie hesla pre VPN klienta je zakázané politikou zabezpečenia.

Politika Fortinet v počte vlastných tokenov nemôže byť považovaná za chamtivú — sú tu dokonca 10 bezplatných tokenov, ostatné sú za veľmi neprijateľnú cenu. RSASecureID, Duo a podobné som nezvažoval, pretože chcem open source.

Predpokladané požiadavky: host *nix s nainštalovaným freeradius, sssd — je pridaný do domény, doménoví používatelia sa na ňom môžu pokojne autentifikovať.

Doplňujúce balíčky: shellinabox, figlet, freeradius-ldap, font rebel.tlf z repozitára https://github.com/xero/figlet-fonts.

V mojom príklade — CentOS 7.8.

Logika fungovania sa predpokladá takto: Pri pripojení k VPN musí používateľ zadať domény login a OTP namiesto hesla.

Nastavenie služieb

V /etc/raddb/radiusd.conf sa mení len používateľ a skupina, pod ktorými sa spúšťa freeradius, pretože služba radiusd musí vedieť čítať súbory vo všetkých podpriečinkoch /home/.

user = root
group = root

Aby bolo možné používať skupiny v nastaveniach Fortigate, je potrebné posielať Vendor Specific Attribute. Na to v adresári raddb/policy.d vytvorím súbor s nasledujúcim obsahom:

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 := "Vitajte Admin"
                }
        }
    else {
        update reply {
        &Reply-Message := "Nie ste autorizovaní na vpn"
            }
        reject
        }
}

Po inštalácii freeradius-ldap v adresári raddb/mods-available sa vytvorí súbor ldap.

Je potrebné vytvoriť symbolický odkaz v adresári raddb/mods-enabled.

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

Upravím jeho obsah na tento formát:

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

V súboroch raddb/sites-enabled/default a raddb/sites-enabled/inner-tunnel v sekcii authorize pridávam názov politiky, ktorá sa bude používať — group_authorization. Podstatná poznámka — názov politiky sa určuje nie názvom súboru v adresári policy.d, ale príkazom vo vnútri súboru pred zloženými zátvorkami.
V sekcii authenticate v týchto istých súboroch je potrebné odkomentovať riadok pam.

V súbore clients.conf zapisujeme parametre, s ktorými sa pripojí Fortigate:

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

Konfigurácia modulu 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

Predvoľby pre zavedenie prepojenia freeradius s google authenticator predpokladajú, že používateľ zadáva svoje prihlasovacie údaje v formáte: username/password+OTP.

Predstavujúc si množstvo prekliatí, ktoré sa na mňa zosypú, ak použijem predvoľby freeradius s Google Authenticator, rozhodlo sa použiť konfiguráciu modulu pam tak, aby sa overoval len token Google Authenticator.

Pri pripojení používateľa sa deje nasledovné:

  • Freeradius overuje existenciu používateľa v doméne a v určitej skupine a v prípade úspechu sa overuje OTP token.

Všetko vyzeralo dosť dobre, kým som sa nezačal zamýšľať „Ako zaregistrovať OTP pre viac ako 300 používateľov?“

Používateľ sa musí prihlásiť na server s freeradius a zo svojej používateľskej účtu a spustiť aplikáciu Google authenticator, ktorá vygeneruje QR kód pre aplikáciu. A tu príde na pomoc shellinabox v kombinácii s .bash_profile.

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

Konfiguračný súbor démona sa nachádza v /etc/sysconfig/shellinabox.
Uvádzam tam port 443 a môžem si zadať svoj certifikát.

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

Používateľovi zostáva iba prihlásiť sa prostredníctvom odkazu, zadať doménové prihlasovacie údaje a získať QR kód pre aplikáciu.

Algoritmus je nasledovný:

  • Používateľ sa prihlasuje na stroj cez prehliadač.
  • Overuje sa, či je používateľ doménový. Ak nie, tak sa nič nezrealizuje.
  • Ak je používateľ doménový, kontroluje sa jeho príslušnosť k skupine administrátorov.
  • Ak nie je admin, kontroluje sa, či je nastavený Google Authenticator. Ak nie, generuje sa QR kód a používateľ sa odhlási.
  • Ak nie je admin a Google Authenticator je nastavený, jednoducho sa odhlási.
  • Ak je admin, tak opäť kontrola Google Authenticator. Ak nie je nastavený, generuje sa QR kód.

Celá logika sa vykonáva pomocou /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

Nastavenie Fortigate:

  • Vytvárame Radius-server

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Vytvárame potrebné skupiny v prípade, že je potrebné rozdeliť prístup podľa skupín. Názov skupiny na Fortigate musí zodpovedať skupine, ktorá sa prenáša do Vendor Specific Attribute Fortinet-Group-Name.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Upravujeme potrebné SSL-portály.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Pridávame skupiny do politík.

    Freeradius + Google Authenticator + LDAP + Fortigate

Výhody tohto riešenia:

  • Existuje možnosť autentifikácie pomocou OTP na Fortigate open-source riešení.
  • Vylučuje sa zadávanie doménového hesla používateľom pri pripojení cez VPN, čo trochu zjednodušuje proces pripojenia. 6-ciferné heslo je jednoduchšie zadať ako to, ktoré je stanovené bezpečnostnou politikou. V dôsledku toho sa znižuje počet tiketov s témou: „Nemôžem sa pripojiť k VPN“.

P.S. V pláne je dotiahnuť toto riešenie až na plnohodnotnú dvojfaktorovú autentifikáciu s challenge-response.

Aktualizácia:

Ako som sľúbil, dotiahli sme to na variantu s challenge-response.
Takže:
V súbore /etc/raddb/sites-enabled/default sekcia authorize vyzerá nasledovne:

authorize {
    filter_username
    preprocess
    auth_log
    chap
    mschap
    suffix
    eap {
        ok = return
    }
    files
    -sql
    #-ldap
    expiration
    logintime
    if (!State) {
        if (&User-Password) {
            # Ak !State a User-Password (PAP), potom núť LDAP:
            update control {
                Ldap-UserDN := "%{User-Name}"
                Auth-Type := LDAP
            }
        }
        else {
            zamietniť
        }
    }
    else {
        # Ak State, potom proxy požiadavka:
        group_authorization
    }
pap
}

Sekcia authenticate teraz má nasledujúci vzhľad:

authenticate {
        Auth-Type PAP {
                pap
        }
        Auth-Type CHAP {
                chap
        }
        Auth-Type MS-CHAP {
                mschap
        }
        mschap
        digest
        # Pokus o autentifikáciu priameho LDAP pripojenia:
        Auth-Type LDAP {
        ldap
        if (ok) {
            update reply {
                # Vytvorte náhodný atribút State:
                State := "%{randstr:aaaaaaaaaaaaaaaa}"
                Reply-Message := "Zadajte OTP"
                }
            # Vráťte Access-Challenge:
            challenge
            }
        }
        pam
        eap
}

Teraz sa kontrola používateľa vykonáva podľa nasledujúceho algoritmu:

  • Používateľ zadáva doménové údaje v VPN klientovi.
  • Freeradius kontroluje platnosť účtu a hesla.
  • Ak je heslo správne, odošle sa požiadavka na token.
  • Nastáva kontrola tokenu.
  • Zisk).

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster