FreeRadius 3 LDAP+ntlm_auth dynamiczne VLANy

   Sieci 0 Comments

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 radtestz 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.