Freeradius + Google Authenticator + LDAP + Fortigate

Co jeśli uwierzytelnianie dwuskładnikowe jest zarówno pożądane, jak i kłujące, ale nie ma pieniędzy na tokeny sprzętowe i ogólnie oferują pozostanie w dobrym nastroju.

To rozwiązanie nie jest czymś super oryginalnym, a raczej mieszanką różnych rozwiązań znalezionych w Internecie.

Tak podane

Домен Active Directory.

Użytkownicy domeny pracujący przez VPN, jak wielu dzisiaj.

Działa jako brama VPN fortygować.

Zapisywanie hasła do klienta VPN jest zabronione przez politykę bezpieczeństwa.

Polityka Fortinet w odniesieniu do własnych tokenów nie można tego nazwać mniej niż zhlob - jest aż 10 darmowych tokenów, reszta - w bardzo niekoszernej cenie. Nie brałem pod uwagę RSASecureID, Duo i tym podobnych, ponieważ chcę open source.

Wymagania wstępne: host *nic z ustalonym freeradius, SSD - wpisany do domeny, użytkownicy domeny mogą łatwo się na nim uwierzytelniać.

Dodatkowe pakiety: Pudełko Shelliny, figleta, freeradius-ldap, czcionka bunt.tlf z repozytorium https://github.com/xero/figlet-fonts.

W moim przykładzie - CentOS 7.8.

Logika pracy ma być następująca: łącząc się z VPN, użytkownik zamiast hasła musi podać login domeny i OTP.

Konfiguracja usług

В /etc/raddb/radiusd.conf tylko użytkownik i grupa, w imieniu której się uruchamia freeradius, od usługi promień powinien mieć możliwość odczytu plików we wszystkich podkatalogach /Dom/.

user = root
group = root

Aby móc korzystać z grup w ustawieniach fortygować, należy przesłać Atrybut specyficzny dla dostawcy. Aby to zrobić, w katalogu raddb/policy.d Tworzę plik o następującej treści:

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

Po instalacji freeradius-ldap w katalogu raddb/mods-dostępne tworzony jest plik ldap.

Musisz utworzyć dowiązanie symboliczne do katalogu raddb/obsługa modów.

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

Doprowadzam jego zawartość do tej postaci:

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

w plikach raddb/witryny włączone/domyślne и raddb/obsługa witryn/tunel-wewnętrzny w sekcji autoryzować Dodaję nazwę polityki, która ma być używana - group_authorization. Ważna uwaga - nazwa polityki nie jest określana przez nazwę pliku w katalogu polityka.d, ale przez dyrektywę wewnątrz pliku przed nawiasami klamrowymi.
W dziale uwierzytelniać w tych samych plikach musisz odkomentować linię pam.

W pliku klienci.konf określić parametry, z którymi będzie się łączyć fortygować:

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

Konfiguracja modułu 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

Domyślne opcje implementacji pakietu freeradius с uwierzytelnianie google wymagać od użytkownika wprowadzenia poświadczeń w formacie: Nazwa użytkownika Hasło+OTP.

Wyobrażając sobie liczbę klątw, które spadną na głowę, w przypadku korzystania z domyślnego pakietu freeradius с Google Authenticator, zdecydowano się na wykorzystanie konfiguracji modułu pam aby można było sprawdzić tylko token Google Authenticator.

Gdy użytkownik się łączy, dzieje się co następuje:

  • Freeradius sprawdza, czy użytkownik jest w domenie i określonej grupie, a jeśli się powiedzie, sprawdza token OTP.

Wszystko wyglądało wystarczająco dobrze, aż do momentu, kiedy pomyślałem „Jak mogę zarejestrować OTP dla ponad 300 użytkowników?”

Użytkownik musi zalogować się na serwerze za pomocą freeradius i spod swojego konta i uruchom aplikację Wystawca uwierzytelnienia Google, który wygeneruje dla użytkownika kod QR dla aplikacji. Tu przychodzi pomoc. Pudełko Shelliny w połączeniu z .bash_profil.

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

Plik konfiguracyjny demona znajduje się pod adresem /etc/sysconfig/shellinabox.
Określam tam port 443 i możesz określić swój certyfikat.

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

Użytkownik musi tylko kliknąć link, wprowadzić kredyty domeny i otrzymać kod QR dla aplikacji.

Algorytm wygląda następująco:

  • Użytkownik loguje się do urządzenia przez przeglądarkę.
  • Czy użytkownik domeny jest zaznaczony. Jeśli nie, nie podejmuje się żadnych działań.
  • Jeśli użytkownik jest użytkownikiem domeny, sprawdzane jest członkostwo w grupie Administratorzy.
  • Jeśli nie jest administratorem, sprawdza, czy jest skonfigurowany Google Authenticator. Jeśli nie, generowany jest kod QR i wylogowanie użytkownika.
  • Jeśli nie jest to administrator, a Google Authenticator jest skonfigurowany, po prostu się wyloguj.
  • Jeśli jesteś administratorem, sprawdź ponownie Google Authenticator. Jeśli nie jest skonfigurowany, generowany jest kod QR.

Cała logika odbywa się za pomocą /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

Konfiguracja Fortigate:

  • Tworzymy Promień-serwer

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Tworzymy niezbędne grupy, jeśli to konieczne, kontrolę dostępu według grup. Nazwa grupy włączona fortygować musi pasować do przekazanej grupy Atrybut specyficzny dla dostawcy Nazwa-grupy-Fortinet.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Edycja niezbędnych SSL-portale.

    Freeradius + Google Authenticator + LDAP + Fortigate

  • Dodawanie grup do zasad.

    Freeradius + Google Authenticator + LDAP + Fortigate

Zalety tego rozwiązania:

  • Możliwe jest uwierzytelnienie przez OTP na fortygować rozwiązanie open source.
  • Użytkownik nie wprowadza hasła do domeny podczas łączenia przez VPN, co nieco upraszcza proces łączenia. 6-cyfrowe hasło jest łatwiejsze do wprowadzenia niż to, które zapewnia polityka bezpieczeństwa. W efekcie spada liczba zgłoszeń z tematem: „Nie mogę połączyć się z VPN”.

PS Planujemy uaktualnienie tego rozwiązania do pełnoprawnego uwierzytelniania dwuskładnikowego z funkcją challenge-response.

aktualizacja:

Zgodnie z obietnicą dostosowałem go do opcji wyzwanie-odpowiedź.
Tak więc:
W pliku /etc/raddb/sites-enabled/default Sekcja autoryzować wygląda tak:

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
}

sekcja uwierzytelniać teraz wygląda tak:

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
}

Teraz weryfikacja użytkownika odbywa się zgodnie z następującym algorytmem:

  • Użytkownik wprowadza kredyty domeny w kliencie VPN.
  • Freeradius sprawdza ważność konta i hasła
  • Jeśli hasło jest poprawne, wysyłana jest prośba o token.
  • Token jest weryfikowany.
  • zysk).

Źródło: www.habr.com

Dodaj komentarz