Wat te doen als je twee-factor authenticatie wilt, maar er geen geld is voor hardware tokens en je in het algemeen wordt aangeraden om goed gezind te blijven.
Deze oplossing is niet echt origineel, eerder een mix van verschillende oplossingen die op het internet zijn gevonden.
Dus, gegeven
Domein Active Directory.
Domeingebruikers die via VPN werken, zoals velen tegenwoordig.
De VPN-gateway is Fortigate.
Het opslaan van het wachtwoord voor de VPN-client is verboden door het beveiligingsbeleid.
Het beleid Fortinet met betrekking tot eigen tokens is minder dan gul te noemen — er zijn maar liefst 10 gratis tokens, de andere zijn voor een zeer onvriendelijke prijs. RSASecureID, Duo en soortgelijke heb ik niet overwogen, omdat ik open-source wil.
Vereisten: host *nix met geïnstalleerde freeradius, sssd - toegevoegd aan het domein, domeingebruikers kunnen zich er probleemloos authentiseren.
Aanvullende pakketten: shellinabox, figlet, freeeradius-ldap, lettertype rebel.tlf van de repository .
In mijn voorbeeld — CentOS 7.8.
De logica werkt als volgt: wanneer je verbinding maakt met de VPN moet de gebruiker inloggen met de domeinlogin en OTP in plaats van een wachtwoord.
Instelling van de services
In /etc/raddb/radiusd.conf verandert alleen de gebruiker en groep waaronder freeradiusde service radiusd moet in staat zijn om bestanden in alle submappen te lezen. /home/.
user = root
group = root
Om groepen in de instellingen te kunnen gebruiken Fortigate, moet er worden doorgegeven Vendor Specific Attribute. Hiervoor maak ik in de directory raddb/policy.d een bestand aan met de volgende inhoud:
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 := "Welkom Admin"
}
}
else {
update reply {
&Reply-Message := "Niet gemachtigd voor vpn"
}
reject
}
}
Na de installatie freeradius-ldap in de directory raddb/mods-available wordt een bestand aangemaakt. ldap.
Er moet een symbolische link worden gemaakt in de map raddb/mods-enabled.
ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldapIk pas de inhoud aan naar dit formaat:
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'
}
} In bestanden raddb/sites-enabled/default en raddb/sites-enabled/inner-tunnel in de sectie authorize voeg ik de naam van het beleid toe dat zal worden gebruikt — group_authorization. Een belangrijk punt — de naam van het beleid wordt niet bepaald door de naam van het bestand in de directory policy.d, maar door de richtlijn binnen het bestand vóór de accolades.
In de sectie authenticate in deze bestanden moet de regel worden uitgecommentarieerd pam.
In het bestand clients.conf we geven de parameters op waarmee zal worden verbonden Fortigate:
client fortigate {
ipaddr = 192.168.1.200
secret = testing123
require_message_authenticator = no
nas_type = other
}
Configuratie van de module 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
Standaardopties voor de implementatie van de koppeling freeradius met google authenticator houden in dat de gebruiker inloggegevens moet invoeren in het formaat: gebruikersnaam/wachtwoord+OTP.
Gezien het aantal vloeken dat over me heen zou komen in het geval van het gebruik van de standaardkoppeling freeradius met Google Authenticator, werd besloten om de configuratie van de module te gebruiken pam om alleen de token te controleren Google Authenticator.
Bij het verbinden van de gebruiker gebeurt het volgende:
- Freeradius controleert of de gebruiker in het domein en in een bepaalde groep staat en, bij succes, wordt de OTP-token gecontroleerd.
Het leek vrij goed te gaan tot het moment dat ik dacht: 'Hoe registreer ik OTP voor 300+ gebruikers?'
De gebruiker moet inloggen op de server met freeradius en vanuit zijn account de applicatie opstarten Google authenticator, die een QR-code voor de gebruiker zal genereren. Hier komt shellinabox in combinatie met .bash_profile.
[root@freeradius ~]# yum install -y shellinabox
Het configuratiebestand van de daemon bevindt zich in /etc/sysconfig/shellinabox.
Ik geef daar poort 443 op en ik kan mijn certificaat opgeven.
[root@freeradius ~]#systemctl enable --now shellinaboxdDe gebruiker hoeft alleen maar de link te volgen, de domeinreferenties in te voeren en de QR-code voor de applicatie te ontvangen.
Het algoritme is als volgt:
- De gebruiker logt in op de machine via de browser.
- Er wordt gecontroleerd of de gebruiker domeingerelateerd is. Als dat niet het geval is, worden er geen acties ondernomen.
- Als de gebruiker domein is, wordt de lidmaatschap van de beheerdersgroep gecontroleerd.
- Als het geen admin is, wordt gecontroleerd of Google Authenticator is ingesteld. Als dat niet het geval is, wordt er een QR-code gegenereerd en wordt de gebruiker uitgelogd.
- Als het geen admin is en Google Authenticator is ingesteld, volgt er gewoon een uitlogging.
- Als het admin is, wordt Google Authenticator opnieuw gecontroleerd. Als het niet is ingesteld, wordt er een QR-code gegenereerd.
Alle logica wordt uitgevoerd met behulp van /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
Configuratie van Fortigate:
- We create Radius-server

- We create the necessary groups in case access needs to be restricted by groups. The group name should Fortigate correspond to the group passed in Vendor Specific Attribute Fortinet-Group-Name.

- We edit the necessary SSL-portals.

- We add groups to the policies.

The advantages of this solution:
- There is an option for OTP authentication on Fortigate an open-source solution.
- The user does not need to enter a domain password when connecting via VPN, which simplifies the connection process. It is easier to enter a 6-digit password than the one required by the security policy. Consequently, the number of tickets with the subject: ‘I cannot connect to VPN’ decreases.
P.S. Plans are underway to enhance this solution into a full two-factor authentication with challenge-response.
Update:
As promised, I have indeed enhanced it to the challenge-response option.
Dus:
In het bestand /etc/raddb/sites-enabled/default section authorize er als volgt uit:
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
}
Sectie authenticate now has the following form:
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
}
Now the user verification follows this algorithm:
- The user enters domain credentials in the VPN client.
- Freeradius checks the validity of the account and password.
- If the password is correct, a token request is sent.
- Token verification takes place.
- Profit).
Bron: habr.com




