Hello and welcome, Dear community, I am asking for help. I've been struggling with configuring Freeradius in my home lab for several days. And I've reached a wall that I can't overcome. What does the architecture look like: AD Controller dc1.lab.lan Freeradius 3.0.21 (Debian 11 bullseye) Unifi Controller (on Debian) AP Unifi CA (using xCA - issuing certificates manually) Everything is on one local network 192.168.80.x/24, Gateway 192.168.80.1 DNS 192.168.80.21 (dc1). And so the goal is to authorize users using AD credentials or certificates issued from xCA. Certificates in pem12 (for android). I tested on Android 9 and 13. What works - user authorization using login and password from AD. EAP-PEAP MSCHAPv2 Certificate – Imported p12 User+rootCA Variant 2 EAP-PEAP MSCHAPv2 Certificate – don't check Certificates user authorization through issued certificates works (signed directly by rootCA for now, without an intermediate authority). EAP-TLS Device certificate - Imported p12 User+rootCA User certificate - Imported p12 User+rootCA Username: cannot be empty, I have to enter something to make it work, e.g. AAA (in radius, if the check CN option is selected, it is required to enter the correct username). Case two EAP-TLS Device cert: labrootca (imported separately – rootCA) User certificate – user1 Username: whatever Password: blank (user1 does not exist in AD or local configuration files and yet freeradius authorizes it) My main problem is the CRL not working. I made a combined rootCA+CRL certificate in pem. I deleted the .cnf files in /etc/freeradius/3.0/certs because I don't want to use an external CA (xCA). I only left bootstrap and dh. I did this before turning on freeradius C_rehash /etc/freeradius/3.0/certs New files (links) have appeared. sudo freeradius -XC => Configuration appears to be OK Then start freeradius -X => shows no errors Here is my second question - is it possible to set double authorization, i.e. the user must have an installed certificate and then provide the login and password from AD to connect to WiFi? First of all, please tell me what I can do wrong with this CRL list. Below are the configuration files (most # comments removed, I left a few for example) Labrootca.crt -----BEGIN CERTIFICATE----- MIIDljCCAn6gAwIBAgIIWSbrdC7xrG0wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE BhMCUEwxFjAUBgNVBAoTDWxhYi5wYy1pdC5sYW4xFjAUBgNVBAsTDWxhYi5wYy1p (rest of cert) sUTnIqKeufo9rhrL3V/1UPAJK0+2gj+RaXuJcwjrs5pDIiN0NWitepTPZdsl5TaM NviIhB0RA14UhQ== -----END CERTIFICATE----- Labrootcacrl_and_CA.pem -----BEGIN CERTIFICATE----- MIIDljCCAn6gAwIBAgIIWSbrdC7xrG0wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE BhMCUEwxFjAUBgNVBAoTDWxhYi5wYy1pdC5sYW4xFjAUBgNVBAsTDWxhYi5wYy1p (rest of cert) sUTnIqKeufo9rhrL3V/1UPAJK0+2gj+RaXuJcwjrs5pDIiN0NWitepTPZdsl5TaM NviIhB0RA14UhQ== -----END CERTIFICATE----- -----BEGIN X509 CRL----- MIIB4zCBzAIBATANBgkqhkiG9w0BAQsFADBRMQswCQYDVQQGEwJQTDEWMBQGA1UE ChMNbGFiLnBjLWl0LmxhbjEWMBQGA1UECxMNbGFiLnBjLWl0LmxhbjESMBAGA1UE (rest of CRL) 9xWxqQIS5Q== -----END X509 CRL----- ---------EAP FILE--------- eap { default_eap_type = peap timer_expire = 60 ignore_unknown_eap_types = no cisco_accounting_username_bug = no max_sessions = ${max_requests} #md5 { #} #leap { #} #gtc { #challenge = "Password: " #auth_type = PAP #} tls-config tls-common { #freerad and key are in the same file so duplicated private_key_file = /etc/certyfikaty/freerad.pem certificate_file = /etc/certyfikaty/freerad.pem ca_file = /etc/freeradius/3.0/certs/labrootcacrl_and_CA.pem #auto_chain = yes dh_file = ${certdir}/dh #random_file = /dev/urandom #fragment_size = 1024 #include_length = yes #Check the Certificate Revocation List # #1) Copy CA certificates and CRLs to same directory. #2) Execute 'c_rehash <CA certs&CRLs Directory>'. #'c_rehash' is OpenSSL's command. #3) uncomment the lines below. #5) Restart radiusd check_crl = yes # Check if intermediate CAs have been revoked. check_all_crl = yes ca_path = /etc/freeradius/3.0/certs/labrootcacrl_and_CA.pem allow_expired_crl = yes #check_cert_issuer = "/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd" #check_cert_cn = %{User-Name} cipher_list = "DEFAULT" cipher_server_preference = no #disable_tlsv1_2 = no #disable_tlsv1_1 = yes #disable_tlsv1 = yes tls_min_version = "1.2" tls_max_version = "1.2" ecdh_curve = "prime256v1" cache { enable = no lifetime = 24 # hours #name = "EAP module" #persist_dir = "${logdir}/tlscache" store { Tunnel-Private-Group-Id } } verify { #skip_if_ocsp_ok = no #tmpdir = /tmp/radiusd #client = "/path/to/openssl verify -CApath ${..ca_path} %{TLS-Client-Cert-Filename}" } ocsp { enable = no override_cert_url = yes url = "http://127.0.0.1/ocsp/" #use_nonce = yes #timeout = 0 #softfail = no } } tls { tls = tls-common #virtual_server = check-eap-tls } ttls { tls = tls-common default_eap_type = md5 copy_request_to_tunnel = no use_tunneled_reply = no virtual_server = "inner-tunnel" #include_length = yes require_client_cert = yes } peap { tls = tls-common default_eap_type = mschapv2 copy_request_to_tunnel = no use_tunneled_reply = no #proxy_tunneled_request_as_eap = yes virtual_server = "inner-tunnel" #soh = yes #soh_virtual_server = "soh-server" #require_client_cert = yes } mschapv2 { #send_error = no #identity = "FreeRADIUS" } } ----- SITES DEFAULT --- server default { listen { type = auth ipaddr = * port = 0 limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } listen { ipaddr = * #ipv6addr = :: port = 0 type = acct limit { } } listen { type = auth ipv6addr = ::# any.::1 == localhost port = 0 limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } listen { ipv6addr = :: port = 0 type = acct limit { } } authorize { filter_username preprocess chap mschap digest suffix ntdomain eap { ok = return #updated = return } files -sql -ldap expiration logintime pap } authenticate { ntlm_auth Auth-Type PAP { pap } Auth-Type CHAP { chap } Auth-Type MS-CHAP { mschap } mschap digest #Auth-Type LDAP { #ldap #} eap } preacct { preprocess acct_unique suffix #ntdomain files } accounting { detail unix -sql exec attr_filter.accounting_response } session { } post-auth { if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) { update reply { &User-Name !* ANY } } update { &reply: += &session-state: } -sql exec remove_reply_message_if_eap Post-Auth-Type REJECT { # log failed authentications in SQL, too. -sql attr_filter.access_reject eap remove_reply_message_if_eap } Post-Auth-Type Challenge { #remove_reply_message_if_eap #attr_filter.access_challenge.post-auth } } pre-proxy { } post-proxy { eap } } ---INNER TUNNEL server inner-tunnel { listen { ipaddr = 127.0.0.1 port = 18120 type = auth } authorize { filter_username chap mschap suffix #ntdomain update control { &Proxy-To-Realm := LOCAL } eap { ok = return } files -sql -ldap expiration logintime pap } authenticate { ntlm_auth Auth-Type PAP { pap } Auth-Type CHAP { chap } Auth-Type MS-CHAP { mschap } mschap #Auth-Type LDAP { #ldap #} eap } session { radutmp } post-auth { -sql #ldap if (0) { update reply { User-Name !* ANY Message-Authenticator !* ANY EAP-Message !* ANY Proxy-State !* ANY MS-MPPE-Encryption-Types !* ANY MS-MPPE-Encryption-Policy !* ANY MS-MPPE-Send-Key !* ANY MS-MPPE-Recv-Key !* ANY } update { &outer.session-state: += &reply: } } Post-Auth-Type REJECT { # log failed authentications in SQL, too. -sql attr_filter.access_reject update outer.session-state { &Module-Failure-Message := &request:Module-Failure-Message } } } pre-proxy { } post-proxy { eap } } # inner-tunnel server block