Hvad skal man gøre, hvis man både vil have to-faktor-autentifikation og også gerne vil have det, men ikke har penge til hardware tokens, og man overhovedet får at vide, at man skal holde sig oppe med godt humør.
Denne løsning er ikke noget superoriginalt, snarere en blanding af forskellige løsninger, fundet på internettet.
Så, vi har:
Domæne Active Directory.
Brugere af domænet, der arbejder via VPN, som mange gør i dag.
VPN-gatewayen fungerer som: Fortigate.
At gemme adgangskoden til VPN-klienten er forbudt af sikkerhedspolitikken.
Politikken Fortinet med hensyn til egne tokens kan knap nok betegnes som grådig — der er hele 10 gratis tokens, de øvrige koster en meget høj pris. RSASecureID, Duo og lignende blev ikke overvejet, da der ønskes open source.
Forudsætninger: host *nix installeret med freeradius, sssd — er blevet tilføjet til domænet, domænebrugere kan autentificere sig problemfrit.
Supplerende pakker: shellinabox, figlet, freeradius-ldap, skrifttype rebel.tlf fra lageret. .
I mit eksempel — CentOS 7.8.
Logikken er sådan: ved tilslutning til VPN skal brugeren indtaste domænebrugernavn og OTP i stedet for adgangskoden.
Konfiguration af tjenester
I /etc/raddb/radiusd.conf ændres kun bruger og gruppe, under hvilke freeradiuskører, da tjenesten radiusd skal kunne læse filer i alle undermapper. /home/.
user = root
group = root
For at kunne bruge grupper i indstillingerne Fortigate, skal man videregive Vendor Specific Attribute. For dette i mappen raddb/policy.d opretter jeg en fil med følgende indhold:
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
}
}
Efter installationen af freeradius-ldap public/functions raddb/mods-available oprettes der en fil. ldap.
Der skal oprettes et symbolsk link i mappen raddb/mods-enabled..
ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldapJeg tilpasser dens indhold til følgende:
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 og raddb/sites-enabled/inner-tunnel i sektionen authorize jeg tilføjer navnet på politikken, der skal bruges — group_authorization. Et vigtigt punkt — politiknavnet bestemmes ikke af filnavnet i mappen policy.d, men af direktivet inde i filen før de krøllede parenteser.
I sektionen authenticate i disse filer skal linjen afkommenteres pam.
I filen clients.conf vi angiver de parametre, som vil blive brugt til at forbinde Fortigate:
client fortigate {
ipaddr = 192.168.1.200
secret = testing123
require_message_authenticator = no
nas_type = other
}
Modulkonfiguration 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
Standardimplementeringen af forbindelsen freeradius med google authenticator kræver, at brugeren indtaster legitimationsoplysninger i formatet: brugernavn/adgangskode+OTP.
Tænker på det antal forbandelser, der vil regne ned over hovedet, hvis standardkonfigurationen bruges freeradius med Google Authenticator, blev det besluttet at bruge modulkonfigurationen pam så kun token skal verificeres Google Authenticator.
Ved tilslutning af brugeren sker følgende:
- Freeradius tjekker brugeren i domænet og i en bestemt gruppe, og hvis det lykkes, kontrolleres OTP token.
Alt så ganske lovende ud, indtil jeg kom til at tænke: «Hvordan registrerer jeg OTP for 300+ brugere?»
Brugeren skal logge ind på serveren med freeradius og fra sin konto og starte appen Google authenticator, som vil generere en QR-kode til brugeren. Her kommer shellinabox ind i billedet sammen med .bash_profile.
[root@freeradius ~]# yum install -y shellinabox
Konfigurationsfilen for dæmonen findes i /etc/sysconfig/shellinabox.
Jeg angiver port 443, og man kan angive sit eget certifikat.
[root@freeradius ~]#systemctl enable --now shellinaboxdBrugeren skal blot gå til linket, indtaste domænelegitimationsoplysninger og få QR-koden til appen.
Algoritmen er som følger:
- Brugeren logger ind på maskinen via browseren.
- Det kontrolleres, om brugeren er domænebruger. Hvis ikke, gøres der ikke noget.
- Hvis brugeren er domænebruger, kontrolleres det, om vedkommende tilhører administratorgruppen.
- Hvis ikke admin, kontrolleres det, om Google Authenticator er konfigureret. Hvis ikke, genereres der en QR-kode, og brugeren logges ud.
- Hvis ikke admin og Google Authenticator er konfigureret, logges brugeren bare ud.
- Hvis admin, kontrolleres Google Authenticator igen. Hvis ikke konfigureret, genereres der en QR-kode.
Hele logikken udføres med brug af /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 konfiguration:
- Vi opretter Radius-server

- Opretter de nødvendige grupper for at opdele adgang, hvis det er nødvendigt. Gruppens navn skal Fortigate svare til den gruppe, der sendes i Vendor Specific Attribute Fortinet-Group-Name.

- Rediger de nødvendige SSL-portaler.

- Tilføj grupper til politikkerne.

Fordele ved denne løsning:
- Der er mulighed for OTP-autentifikation med Fortigate en open source-løsning.
- Brugen af det domænebaserede kodeord ved VPN-forbindelse er elimineret, hvilket forenkler tilslutningsprocessen. Det er lettere at indtaste en 6-cifret kode end den, der kræves af sikkerhedspolitikken. Som følge heraf reduceres antallet af supportanmodninger med emnet: 'Kan ikke oprette forbindelse til VPN'.
P.S. Planen er at forbedre denne løsning til en fuldgyldig to-faktor-autentifikation med challenge-response.
Opdatering:
Som lovet har jeg tilføjet en løsning med challenge-response.
Så:
I filen /etc/raddb/sites-enabled/default sektion authorize sådan ud:
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
}
Sektion authenticate har nu følgende form:
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
digest
# Forsøg autentificering med en direkte LDAP bind:
Auth-Type LDAP {
ldap
if (ok) {
update reply {
# Opret en tilfældig State-attribut:
State := "%{randstr:aaaaaaaaaaaaaaaa}"
Reply-Message := "Indtast venligst OTP"
}
# Returner Access-Challenge:
challenge
}
}
pam
eap
}
Nu sker brugerens kontrol efter følgende algoritme:
- Brugeren indtaster domænelegitimationerne i VPN-klienten.
- Freeradius kontrollerer gyldigheden af brugerkontoen og adgangskoden.
- Hvis adgangskoden er korrekt, sendes der en forespørgsel om token.
- Der sker en kontrol af token.
- Profit).
Kilde: habr.com




