Freeradius + Google Authenticator + LDAP + Fortigate

Kā rīkoties, ja divfaktoru autentifikācija ir vēlama, bet nav finanšu līdzekļu aparatūras tokeniem, un vispār tiek ieteikts turēties pie labas noskaņas.

Šis risinājums nav nekas pārāk oriģināls, drīzāk tas ir dažādu risinājumu mikss, atrasts interneta plašumos.

Tātad, ir dots

Domēns Active Directory.

Lietotāji domēnā, kas strādā caur VPN, kā daudzi mūsdienās.

VPN vārtejas lomā ir Fortigate.

Paroles saglabāšana VPN klientam ir aizliegta drošības politikā.

Politika Fortinet attiecībā uz savām tokenām ir mazāk nekā izsalkusi — bezmaksas tokeni ir pieejami 10 eksemplāros, pārējie — par ļoti dārgu cenu. RSASecureID, Duo un tamlīdzīgi netika apskatīti, jo nepieciešams opensource risinājums.

Iepriekšējās prasības: hosts *nix ar instalētu freeradius, sssd — iekļauts domēnā, domēna lietotāji var droši autentificēties uz tā.

Papildu pakotnes: shellinabox, figlet, freeeradius-ldap, fonts rebel.tlf no repozitorija https://github.com/xero/figlet-fonts.

Manā piemērā — CentOS 7.8.

Darba loģika ir tāda: pieslēdzoties VPN, lietotājam jāievada domēna pieteikšanās un OTP vietā parolē.

Servisu konfigurācija

No /etc/raddb/radiusd.conf mainās tikai lietotājs un grupa, ar kuru tie uzsāk freeradius, jo serviss radiusd jāspēj lasīt failus visās apakšdirektorijās /home/.

user = root
group = root

Lai varētu izmantot grupas iestatījumos Fortigate, jānodod Vendor Specific Attribute. Tam nepieciešams direktorijā raddb/policy.d izveidot failu ar sekojošu saturu:

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 := "Laipni lūdzam, Administrātora"}
            }
        }
    else {
        update reply {
        &Reply-Message := "Nav pilnvarots VPN" 
            }
        reject
        }
}

Pēc freeradius-ldap instalēšanas direktorijā raddb/mods-available tiek izveidots fails Jāizveido simboliskā saite katalogā ldap.

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

Es tā satura formātu šādā veidā:

Pārvēršu tā saturu šādā veidā:

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

Failos raddb/sites-enabled/default un raddb/sites-enabled/inner-tunnel sadaļā authorize pievienoju politikas nosaukumu, kas tiks izmantota — group_authorization. Svarīgs moments — politikas nosaukums tiek noteikts nevis pēc faila nosaukuma katalogā policy.d, bet gan ar direktīvu iekš faila pirms izliekuma iekavām.
Sadaļā authenticate šajos pašos failos ir jāizkomentē rinda pam.

Failā clients.conf norakstām parametrus, ar kuriem tiks izveidota savienojums Fortigate:

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

Moduļa konfigurācija 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

Pamatā iesaistoties varianti freeradius ar google authenticator paredz lietotāja datu ievadi formātā: lietotājvārds/parole+OTP.

Iedomājoties visu lāstu daudzumu, kas uzkūlos uz galvas, ja tiks izmantots noklusējuma saistījums freeradius ar Google Authenticator, tika nolemts izmantot moduļa konfigurāciju pam tādā veidā, lai pārbaudītu tikai tokenu Google Authenticator.

Lietotāja pieslēgšanās laikā notiek sekojošais:

  • Freeradius pārbauda lietotāja esamību domēnā un noteiktā grupā, un, ja viss ir kārtībā, notiek OTP tokena pārbaude.

Viss izskatījās diezgan labi, līdz es nepamanīju "Kā reģistrēt OTP vairāk nekā 300 lietotājiem?"

Lietotājam jāielogojas serverī no freeradius un no savas lietotāja konta un jāpalaiž Google authenticator, kas ģenerēs QR kodu lietotājam. Šeit noder shellinabox kombinācijā ar .bash_profile.

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

Demonā konfigurācijas fails atrodas /etc/sysconfig/shellinabox.
Es tur norādu portu 443 un varu norādīt savu sertifikātu.

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

Lietotājam paliek tikai jāapmeklē saite, jāievada domēna akreditīvi un jāsaņem QR kods lietotājam.

Algoritms ir šāds:

  • Lietotājs pieslēdzas mašīnai caur pārlūku.
  • Tiek pārbaudīts, vai lietotājs ir domēna lietotājs. Ja nē, tad nekādi pasākumi netiek veikti.
  • Ja, ja lietotājs ir domēna, tiek pārbaudīta piederība administratoru grupai.
  • Ja nav administrators, tiek pārbaudīts, vai ir iestatīts Google Authenticator. Ja nav, tad tiek ģenerēts QR kods un lietotājs tiek izrakstīts.
  • Ja nav administrators un Google Authenticator ir iestatīts, tad vienkārši tiek izrakstīts.
  • Ja ir administrators, tad atkal tiek pārbaudīts Google Authenticator. Ja nav iestatīts, tad tiek ģenerēts QR kods.

Visa loģika tiek veikta, izmantojot /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

Fortigate konfigurācija:

  • Izveidojam Radius-serveris

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Izveidojam nepieciešamās grupas, ja ir nepieciešama piekļuves ierobežošana grupām. Grupas nosaukumam Fortigate jāatbilst grupai, kas tiek nodota Vendor Specific Attribute Fortinet-Group-Name.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Rediģējam nepieciešamos SSL-portālus.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Pievienojam grupas politikām.

    Freeradius + Google Authenticator + LDAP + Fortigate

Šī risinājuma priekšrocības:

  • Ir iespēja autentificēties, izmantojot OTP uz Fortigate atvērto avotu risinājumu.
  • Izslēdzam domēna parolē ievadi lietotājam, pieslēdzoties VPN, kas nedaudz vienkāršo pieslēgšanās procesu. Sešciparu paroli ir vieglāk ievadīt nekā to, kas paredzēta drošības politikā. Tā rezultātā samazinās biļešu skaits ar tēmu: "Nevaru pieslēgties VPN".

P.S. Plānos ir uzlabot šo risinājumu līdz pilnvērtīgai divu faktoru autentifikācijai ar challenge-response.

Atjauninājums:

Kā solīts, es to uzlabojusi līdz variantam ar challenge-response.
Tātad:
Failā /etc/raddb/sites-enabled/default sekcija authorize izskatās šādi:

authorize {
    filter_username
    preprocess
    auth_log
    chap
    mschap
    suffix
    eap {
        ok = return
    }
    files
    -sql
    #-ldap
    expiration
    logintime
    if (!State) {
        if (&User-Password) {
            # Ja !State un lietotāja parole (PAP), tad piespiežam LDAP:
            update control {
                Ldap-UserDN := "%{User-Name}"
                Auth-Type := LDAP
            }
        }
        else {
            reject
        }
    }
    else {
        # Ja State, tad proksē pieprasījums:
        group_authorization
    }
pap
}

Sekcija authenticate tagad izskatās šādi:

authenticate {
        Auth-Type PAP {
                pap
        }
        Auth-Type CHAP {
                chap
        }
        Auth-Type MS-CHAP {
                mschap
        }
        mschap
        digest
        # Cenšamies autentificēties, izmantojot tiešo LDAP piesaisti:
        Auth-Type LDAP {
        ldap
        if (ok) {
            update reply {
                # Izveidojam nejaušu State atribūtu:
                State := "%{randstr:aaaaaaaaaaaaaaaa}"
                Reply-Message := "Lūdzu, ievadiet OTP"
                }
            # Atgriežam Access-Challenge:
            challenge
            }
        }
        pam
        eap
}

Tagad lietotāja pārbaude notiek pēc šāda algoritma:

  • Lietotājs ievada domēna akreditācijas datus VPN klientā.
  • Freeradius pārbauda konta un paroles derīgumu.
  • Ja parole ir pareiza, tad tiek nosūtīta pieprasījums par tokenu.
  • Notiek tokena pārbaude.
  • Profits).

Avots: habr.com

Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem 🔥 Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem | ProHoster