Co dělat, pokud je dvoufaktorová autentizace nutná, ale nemáme peníze na hardwarové tokeny, a vůbec, snažíme se mít dobrou náladu.
Toto řešení není nijak originální, spíše je to mix různých řešení nalezených na internetu.
Takže, dáno
Doména Active Directory.
Uživatelé domény, kteří pracují přes VPN, jak je nyní běžné.
VPN bránu zastává Fortigate.
Uložení hesla pro VPN klienta je zakázáno bezpečnostní politikou.
Politiku Fortinet ohledně vlastních tokenů nelze nazvat jinak než velkorysou — zdarma je 10 tokenů, ostatní za opravdu vysokou cenu. RSASecureID, Duo a podobné jsem nezvažoval, protože chci open-source.
Požadavky: host *nix s nainstalovaným freeradius, sssd — přidán do domény, doménoví uživatelé se na něm mohou bez problémů autentizovat.
Další balíčky: shellinabox, figlet, freeeradius-ldap, font rebel.tlf z repozitáře .
V mém příkladu — CentOS 7.8.
Logika fungování je následující: při připojení k VPN musí uživatel zadat doménové přihlašovací údaje a OTP místo hesla.
Nastavení služeb
V /etc/raddb/radiusd.conf se mění pouze uživatel a skupina, pod kterými služba startuje freeradius, protože služba radiusd musí mít možnost číst soubory ve všech podadresářích /home/.
user = root
group = root
Aby bylo možné používat skupiny v nastavení Fortigate, je třeba předat Vendor Specific Attribute. K tomu v adresáři raddb/policy.d vytvořím soubor se následujícím obsahem:
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 := "Vítejte Admin"
}
}
else {
update reply {
&Reply-Message := "Není autorizováno pro vpn"
}
reject
}
}
Po instalaci freeradius-ldap v adresáři raddb/mods-available se vytvoří soubor ldap.
Je třeba vytvořit symbolický odkaz v adresáři raddb/mods-enabled.
ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldapUpravuji jeho obsah na následující:
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 souborech raddb/sites-enabled/default a raddb/sites-enabled/inner-tunnel v sekci authorize přidávám název politiky, která se bude používat — group_authorization. Důležitý bod — název politiky se určuje nikoli podle názvu souboru ve složce policy.d, ale podle direktivy uvnitř souboru před složenými závorkami.
V sekci authenticate v těchto souborech je nutné odkomentovat řádek pam.
V souboru clients.conf zapisujeme parametry, s kterými se bude připojovat Fortigate:
client fortigate {
ipaddr = 192.168.1.200
secret = testing123
require_message_authenticator = no
nas_type = other
}
Konfigurace 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
Výchozí možnosti implementace kombinace freeradius s google authenticator předpokládají, že uživatel zadá přihlašovací údaje ve formátu: uživatelské jméno/heslo+OTP.
S ohledem na množství nadávek, které by na mě dopadly v případě použití výchozí kombinace freeradius s Google Authenticator, bylo rozhodnuto použít konfiguraci modulu pam tak, aby se kontroloval pouze token Google Authenticator.
Při připojení uživatele dochází k následujícímu:
- Freeradius kontroluje přítomnost uživatele v doméně a v určité skupině a v případě úspěchu probíhá kontrola OTP tokenu.
Všechno vypadalo dost dobře, dokud jsem se nezamyslel: „Jak provést registraci OTP pro více než 300 uživatelů?“
Uživatel se musí přihlásit na server s freeradius a pod svým uživatelským účtem spustit aplikaci Google authenticator, která vygeneruje pro uživatele QR kód pro aplikaci. A zde přichází na pomoc shellinabox v kombinaci s .bash_profile.
[root@freeradius ~]# yum install -y shellinabox
Konfigurační soubor démona se nachází v /etc/sysconfig/shellinabox.
Uvádím tam port 443 a mohu uvést svůj certifikát.
[root@freeradius ~]#systemctl enable --now shellinaboxdUživatel by se měl pouze přihlásit na odkazu, zadat doménové údaje a získat QR kód pro aplikaci.
Algoritmus je následující:
- Uživatel se přihlásí na stroj přes prohlížeč.
- Ověřuje se, zda je uživatel doménový. Pokud ne, není podniknuto žádné opatření.
- Pokud je uživatel doménový, kontroluje se příslušnost ke skupině administrátorů.
- Pokud není admin, zkontroluje se, zda je nastaven Google Authenticator. Pokud ne, generuje se QR kód a uživatel se odhlašuje.
- Pokud není admin a Google Authenticator je nastaven, odhlásí se jednoduše.
- Pokud je admin, opět se kontroluje Google Authenticator. Pokud není nastaven, generuje se QR kód.
Veškerá logika se provádí 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
Nastavení Fortigate:
- Vytváříme Radius-server

- Vytváříme potřebné skupiny, v případě potřeby rozdělení přístupu podle skupin. Název skupiny na Fortigate musí odpovídat skupině, která je předávána v Vendor Specific Attribute Fortinet-Group-Name.

- Upravujeme potřebné SSL-portály.

- Přidáváme skupiny do politik.

Výhody tohoto řešení:
- Je možná autentizace pomocí OTP na Fortigate open-source řešení.
- Uživatelský doménový heslo není nutné zadávat při připojení přes VPN, což poněkud usnadňuje proces připojení. Šestimístné heslo je snadnější zadat než to, které je dáno politikou zabezpečení. V důsledku toho se snižuje počet tiketů na téma: 'Nemohu se připojit k VPN'.
P.S. Plánuji toto řešení přetvořit na plnohodnotnou dvoufaktorovou autorizaci s challenge-response.
Update:
Jak jsem slíbil, přetvořil jsem na variantu s challenge-response.
Takže:
V souboru /etc/raddb/sites-enabled/default sekce authorize vypadat následovně:
authorize {
filter_username
preprocess
auth_log
chap
mschap
suffix
eap {
ok = return
}
files
-sql
#-ldap
expiration
logintime
if (!State) {
if (&User-Password) {
# Pokud !State a User-Password (PAP), pak nucení LDAP:
update control {
Ldap-UserDN := "%{User-Name}"
Auth-Type := LDAP
}
}
else {
reject
}
}
else {
# Pokud State, pak proxy dotaz:
group_authorization
}
pap
}
Sekce authenticate nyní má následující podobu:
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
mschap
digest
# Pokus o autentizaci s přímým LDAP bind:
Auth-Type LDAP {
ldap
if (ok) {
update reply {
# Vytvořit náhodný atribut State:
State := "%{randstr:aaaaaaaaaaaaaaaa}"
Reply-Message := "Zadejte OTP"
}
# Vrátit Access-Challenge:
challenge
}
}
pam
eap
}
Nyní se kontrola uživatele provádí podle následujícího algoritmu:
- Uživatel zadává doménové kredity v VPN klientovi.
- Freeradius kontroluje platnost účtu a hesla.
- Pokud je heslo správné, odešle se požadavek na token.
- Probíhá kontrola tokenu.
- Profit).
Zdroj: habr.com




