FreeRadius 3 LDAP+ntlm_auth dynamiczne VLANy
Pojawił się ostatnio w pracy temat dynamicznych VLANów. Pierwszy pomysł był – zróbmy to po MAC adresie! Oczywiście, każdy zdaje sobie sprawę jaki jest to koszmar w zarządzaniu, podczas dopisywania MACów przy dużej liczbie pracowników. Jednak posiadając Active Directory, a w nim wszystkich użytkowników, czemu by nie spróbować użyć tych kont? W teorii pomysł brzmiał banalnie, jednak w praktyce okazało się, że tak różowo nie jest. Pierwszy napotkany problem, to praktycznie brak materiałów na ten temat. Większość tutoriali była napisana w okolicach 2008-2010 roku,do tego opisy na podstawie FreeRadiusa 2.x, gdzie różniły się praktycznie wszystkie pliki konfiguracyjne. Kolejny problem to logowanie użytkowników z AD, mimo że jesteśmy w stanie autoryzować użytkownika, to nie jesteśmy już w stanie przypisać VLANu dla grupy w której się znajduje dany użytkownik. Okazuje się, że sam ntlm_auth nie wystarczy, ponieważ nie jest w stanie wyciągnąć informacji o grupach, więc dochodzi nam jeszcze LDAP. Dzięki temu będziemy mogli sprawdzać, czy użytkownik który się loguje znajduje się w danej grupie, a co za tym idzie, dostanie odpowiedni VLAN przypisany dla tej grupy.
Po czterech dniach walki i konfigurowania wszystkiego metodą prób i błędów w końcu, udało się odnieść sukces. Zmobilizowało mnie to do zebrania wszystkiego razem i umieszczenia w jednym wpisie od początku do końca. Pełna konfiguracja od wpięcia Linuxa do domeny, po przez instalację i konfigurację FreeRadiusa 3, konfigurację switcha oraz konfigurację karty sieciowej na Windowsie.
W samym wpisie skupiam się nad konfiguracją dynamicznych VLANów z wykorzystaniem autoryzacji po AD dla sieci LAN. W internecie możemy znaleźć w 95% tutoriali (które są naprawdę szczątkowe) konfigurację pod WiFi.
Trochę danych technicznych:
– System na którym był stawiany Freeradius: CentOS 7.4
– Wszystkie paczki instalowane z domyślnych repozytoriów
– Switch 2960-X 48 portowy ver. iOS 15.2
– Konfiguracja karty sieciowej na Windows 7 (tak wiem, zabytek:)) jednak sama konfiguracja w nowszych systemach nie powinna się różnić.
Instalowanie potrzebnych paczek
sudo yum install samba samba-winbind-clients krb5-server krb5-workstation -y
Konfiguracja Samby /etc/samba/smb.conf
[global] workgroup = NASZA # z dużych liter nasza grupa password server = 192.168.0.100 # IP naszego serwera AD realm = NASZA-DOMENA.COM.PL # nasza domena z dużych liter security = ads winbind use default domain = false log file = /var/log/samba/log.%m max log size = 50 passdb backend = tdbsam load printers = no printcap name = /dev/null [homes] comment = Home Directories browseable = no writable = yes
Kebreros ustawienie /etc/krb5.conf
[logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = NASZA-DOMENA.COM.PL # Nasza domena dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true [realms] NASZA-DOMENA.COM.PL = { kdc = 192.168.0.100 # admin_server = 192.168.0.100 # IP naszego serwera AD } # [domain_realm] .nasza-domena.com.pl = NASZA-DOMENA.COM.PL nasza-domena.com.pl = NASZA-DOMENA.COM.PL
Konfiguracja /var/kerberos/krb5kdc/kdc.conf
[kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] NASZA-DOMENA.COM.PL = { #master_key_type = aes256-cts acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal }
Dodanie serwera AD jako serwer nazw /etc/resolv.conf
nameserver 192.168.0.100 options timeout:1
Tworzymy bilet Kerberosa
kinit Administrator@NASZA-DOMENA.COM.PL
Administrator <= konto admina domeny na AD, wymagane podanie hasła
Sprawdzenie biletów Kerberosa
klist
Tworzenie nowej bazy Kerberosa
kdb5_util create -s
Bedzie wymagane ustalenie hasła.
Przyłączenie serwera Linuxa do domeny Windowsa
net join -U Administrator
Administrator <= konto admina domeny na AD, wymagane podanie hasła
Uruchomienie i dodanie od autostartu samba, kerberos, winbind
systemctl enable smb.service systemctl start smb.service
systemctl enable winbind systemctl start winbind
systemctl enable krb5kdc systemctl start krb5kdc
Sprawdzamy czy działają poswiadczenia użytkownika z AD
ntlm_auth --request-nt-key --domain=NASZA-DOMENA.COM.PL --username=uzytkownik_AD
Po podaniu hasła powinniśmy zobaczyć informacje:
NT_STATUS_OK : Success (0x0)
Instalacja FreeRadius
sudo yum install freeradius freeradius-utils freeradius-ldap -y
Włączenie modułu LDAP
ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldap
Włączamy LDAP w configu radiusa /etc/raddb/radiusd.conf
W sekcji instantiate { robimy uncomment ldap
instantiate {
#
# We list the counter module here so that it registers
# the check_name attribute before any module which sets
# it
# daily
ldap
# subsections here can be thought of as "virtual" modules.
#
Dodajemy klienta /etc/raddb/clients.conf
Dodajemy Klienta, czyli nasz switch, który będzie się łączył do serwera radiusa. Na samym dole konfiga dodajemy wpis:
client Nasz_Switch { # nazwa naszego switcha ipaddr = 192.168.0.10 # adres ip switcha secret = test123 # hasło po którym switch uwierzytelni się do radiusa }
Edycja mods-available/mschap
W sekcji mschap { zaraz na początku dodajemy with_ntdomain_hack = yes
konieczne do poprawnego formatu w jakim przesyłane są informacje o użytkowniku.
mschap {
#
# If you are using /etc/smbpasswd, see the 'passwd'
# module for an example of how to use /etc/smbpasswd
with_ntdomain_hack = yes
# if use_mppe is not set to no mschap will
# add MS-CHAP-MPPE-Keys for MS-CHAPv1 and
# MS-MPPE-Recv-Key/MS-MPPE-Send-Key for MS-CHAPv2
#
Następnie robimy uncomment dla:
ntlm_auth = "/path/to/ntlm_auth --request-nt-key --username=%{%{Stripped-User-Name}:-%{%{User-Name}:-None}} --challenge=%{%{mschap:Challenge}:-00} --nt-response=%{%{mschap:NT-Response}:-00}"
i zmieniamy na :
ntlm_auth = "/usr/bin/ntlm_auth --request-nt-key --username=%{%{mschap:User-Name}:-00} --challenge=%{%{mschap:Challenge}:-00} --nt-response=%{%{mschap:NT-Response}:-00} --domain=%{mschap:NT-Domain}"
Naturalnie jeśli u nas ntlm_auth ma inną ścieżkę, to podmieniamy na swoją.
Edycja mods-available/eap
W sekcji ldap {:
server = 'ldap.nasza-domena.com.pl'
<= adres do naszego LDAP
identity = <uzytkownik z AD w formie LDAP>
czyli: 'CN=uzytkownik,OU=Accounts,DC=nasza-domena,DC=com,DC=pl’
password = password123
<= hasło dla tego użytkownika
base_dn = 'OU=Accounts,DC=nasza-domena,DC=com,DC=pl'
<= od którego miejsca LDAP ma wyszukiwać
W sekcji user {:
filter =
ustawiamy w następujący sposób:
filter = "(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}})"
Z racji tego że używamy AD musimy podstawic sAMAccountName=
gdyż po uid=
nie znajdziemy użytkownika.
W sekcji group {:
Robimy uncomment (jesli nie jest od komentowane) dla:
scope = 'sub'
name_attribute = cn
membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"membership_filter = "(&(objectClass=group)(member=%{Ldap-UserDn}))"
membership_attribute = 'memberOf'
Edycja mods-enabled/ntlm_auth
Tak naprawdę konfiguracja tego modułu, sprowadza sie tylko do ustawienia sciezki dla ntlm_auth i domeny:
exec ntlm_auth { wait = yes program = "/usr/bin/ntlm_auth --request-nt-key --domain=NASZA-DOMENA.COM.PL --username=%{mschap:User-Name} --password=%{User-Password}" }
Edycja sites-enabled/default
W sekcji authenticate { dodajemy autentykacje po ntlm_auth
authenticate { Auth-Type NTLMAuth { ntlm_auth } # # PAP authentication, when a back-end database listed # in the 'authorize' section supplies a password. The # password can be clear-text, or encrypted.
Dodanie REALMA w /etc/raddb/proxy.conf
Odszukujemy realm LOCAL i nad nim dodajemy:
realm NASZA { # to co nam sie pojawia przed kontem NASZA\użytkownik } realm LOCAL { # If we do not specify a server pool, the realm is LOCAL, and # requests are not proxied to it. }
Edycja sites-enabled/inner-tunnel
Konfigurujemy moduł expiration
w sekcji authorize { wyszukujemy expiration
i dodajemy:
expiration if (userlock) { update reply { &reply:Tunnel-Type := 13 # 13 według zapisu Cisco odpowiada VLAN &reply:Tunnel-Medium-Type := 6 # 6 według zapisu Cisco odpowiada IEEE-802 &reply:Tunnel-Private-Group-Id := "1" # albo ID VLANu np. 10 albo VLAN name } }
Dzięki temu, użytkownik będzie mógł dostać sieć, gdy wygaśnie mu hasło, a tym samym będzie miał możliwość zmiany hasła.
Dodajemy if, dla konkretnej grupy z AD w której znajduje się dany użytkownik, aby przypisać odpowiedniego VLANa.
W sekcji post-auth { wyszukujemy if (0) {
komentujemy cały blok i dodajemy własne:
if (LDAP-Group == freeradius_test) { # freeradiust_test to nasza grupa z AD update reply { &reply:Tunnel-Type := "VLAN" &reply:Tunnel-Medium-Type := "IEEE-802" &reply:Tunnel-Private-Group-Id := "NASZ_VLAN" # albo ID VLANu np. 10 albo VLAN name } } elsif (LDAP-Group == admin_test) { # admin_test to nasza grupa z AD update reply { &reply:Tunnel-Type := "VLAN" &reply:Tunnel-Medium-Type := "IEEE-802" &reply:Tunnel-Private-Group-Id := "UZYTKOWNICY" # albo ID VLANu np. 10 albo VLAN name } } else { update reply { Reply-Message := "Przykro mi, nie możesz dostać sieci" } reject }
Dokładnie w ten sposób dodajemy następne „elsif” jeden pod drugim z kolejnymi grupami.
Następnie w sekcji authorize { wyszukujemy ntdomain
i robimy uncomment:
# the authentication to another RADIUS server, and have the
# accounting logs *not* sent to the other server. This makes
# it difficult to bill people for their network activity.
#
suffix
ntdomain
#
# The "suffix" module takes care of stripping the domain
# (e.g. "@example.com") from the User-Name attribute, and the
KONFIGURACJA SWITCHA w dot1x
Konfiguracja dla switcha 2960-X iOS 15.x. Nie powinno być większych różnic w innych modelach.
S1# conf t S1 (config)# aaa new-model S1 (config)# aaa authentication dot1x default group radius S1 (config)# aaa authorization network default group radius S1 (config)# dot1x system-auth-control S1 (config)# radius server Freeradius S1 (config-radius-server)# address ipv4 192.168.0.50 auth-port 1812 acct-port 1813 # IP naszego radius serwera i porty S1 (config-radius-server)# key test123 # secret wpisany w pliku clients.conf na radiusie S1 (config-radius-server)# end
Konfiguracja portu
S1# conf t S1 (config)# interface GigabitEthernet1/0/24 S1 (config-if)# switchport mode access S1 (config-if)# authentication event fail action authorize vlan 1 S1 (config-if)# authentication event server dead action authorize vlan 1 S1 (config-if)# authentication event no-response action authorize vlan 1 S1 (config-if)# authentication port-control auto S1 (config-if)# authentication periodic S1 (config-if)# authentication port-control auto S1 (config-if)# dot1x pae authenticator
Jakby ktoś był zainteresowany co oznaczają poszczególne pozycje, to odsyłam tutaj.
Możemy wyświetlić ustawione interfejsy w dot1x poleceniem:
S1# sh dot1x all Sysauthcontrol Enabled Dot1x Protocol Version 3 Dot1x Info for GigabitEthernet1/0/24 ----------------------------------- PAE = AUTHENTICATOR QuietPeriod = 60 ServerTimeout = 0 SuppTimeout = 30 ReAuthMax = 2 MaxReq = 2 TxPeriod = 30
TEST RADIUSA
Mamy użytkownika testowy1 , który w AD należy do grupy freeradius_test. Sprawdzimy na radiusie, czy będzie się w stanie zalogować i otrzymać informacje zwrotną o VLANie. Uruchamiamy radiusa poleceniem:
radiusd -XXX
-XXX – tryb debugowania ze wszystkimi szczegółami
Test wykonujemy na serwerze radiusa za pomocą komendy radtest
z drugiego okna:
radtest -t mschap testowy1 password123 localhost:18120 0 testing123
kolejno mamy:
-t mschap – typ autentykacji
testowy1 – nasz użytkownik z AD
password123 – hasło z AD dla użytkownika testowy1
localhost:18120 0 – radius lokalnie
testing123 – secret ustalony dla połączenia po localhost
Po wykonaniu komendy, powinniśmy otrzymać taką informację:
Sent Access-Request Id 97 from 0.0.0.0:47357 to 127.0.0.1:18120 length 140 User-Name = "testowy1" MS-CHAP-Password = "password123" NAS-IP-Address = 192.168.0.50 NAS-Port = 0 Message-Authenticator = 0x00 Cleartext-Password = "password123" MS-CHAP-Challenge = 0xf6181a2119434823 MS-CHAP-Response = 0x00010000000000000000000000000000000000000000000000003ca9da216cf481f33c9d4c7dcc81bfd4d48973b6894c3a53 Received Access-Accept Id 97 from 127.0.0.1:18120 to 0.0.0.0:0 length 106 MS-CHAP-MPPE-Keys = 0x00000000000000003bffe2a886211ae0b0ae0f73e40abc31 MS-MPPE-Encryption-Policy = Encryption-Allowed MS-MPPE-Encryption-Types = RC4-40or128-bit-Allowed Tunnel-Type:0 = VLAN Tunnel-Medium-Type:0 = IEEE-802 Tunnel-Private-Group-Id:0 = "NASZ_VLAN"
KONFIGURACJA KARTY LAN W WINDOWS
Włączamy usługę Automatyczna konfiguracja sieci przewodowej.
W konfiguracji karty przechodzimy na zakładkę Uwierzytelnianie i konfigurujemy tak jak na screenie i klikamy w pole Ustawienia.
Odznaczamy weryfikacje certyfikatów, ustawiamy metodę uwierzytelnienia i klikamy w Konfiguruj…
Upewniamy się, że checkbox jest zaznaczony.
Wracamy na zakładkę Uwierzytelnianie i klikamy w Ustawienia dodatkowe…
Zaznaczamy określenie trybu uwierzytelnienia na Uwierzytelnienie użytkownika oraz włączamy Włącz rejestrację jednokrotną dla tej sieci i ustawiamy jak na screenie.
Jak to działa?
W momencie logowani użytkownika do Windowsa, zostaje wysłana informacja do switcha, że ktoś o takich danych próbuje dostać dostęp do sieci. Switch ustawiony w dot1x i ze wskazaniem na radius serwer, wysyła informację do radiusa. Ten z kolei sprawdza, czy zna takie konto dzięki ntlm_auth, oraz za pomocą modułu LDAP weryfikuje, czy dany użytkownik znajduje się w konkretnej grupie, dla której jest przypisany VLAN. Jeśli wszystko się zgadza, radius odsyła informacje do switcha, że autoryzacja przebiegła pomyślnie i port ma działać na danym VLANie, który jest przypisany do grupy z której pochodził użytkownik.
Słowem zakończenia
Fajnie, że ten temat się pojawił, było to coś nowego, gdzie do tej pory znane mi było tylko z teorii. Cieszy mnie fakt, ze po 4 dniach ostrej walki, udało się osiągnąć cel. Mam nadzieję, że wpis komuś się przyda, żeby nie musiał tak jak ja w 4 dni przekopać całej sieci i wyszukiwarki Google do 30-stej strony z wynikami w danym zapytaniu. Sprawdzając każdy najmniejszy trop, bo być może tam będzie odpowiedź 😉 Sama konfiguracja dynamicznych VLANów w oparciu o AD, zahacza tak naprawdę o trzy systemy, wiec daje bardzo ciekawe doświadczenie, a zebrany tutaj materiał myślę, że powinien odpowiedzieć na kilka pytań i znacznie ułatwić realizację tego przedsięwzięcia.