• Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Search
  • Register
  • Login
Netgate Discussion Forum
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Search
  • Register
  • Login

FreeRADIUS EAP-TLS, works but and "Check Client Certificate CN" doesn't

Scheduled Pinned Locked Moved pfSense Packages
4 Posts 3 Posters 2.6k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L
    Lobanz
    last edited by Aug 15, 2023, 8:36 PM

    So I have WPA2/Enterprise with EAP-TLS working on Windows and Android with Unifi APs against FreeRADIUS on pfsense+.

    BUT, there is an EAP-TLS sessing in Services -> FreeRADIUS -> EAP -> EAP-TLS called "Check Client Certificate CN". The description says "When enabled, the Common Name of the client certificate must match the username set in 'FreeRADIUS > Users'."

    Can't get this setting to work. I can make a user with username "foo" and a cert with common name "foo" and everything works great. Problem is that I can change the "foo" user's FreeRADIUS username to "bob" and it still works. On Windows and Android WiFi clients, you have to specify an "identity" (username) but it seems to be ignored by FreeRADIUS.

    SO, it looks like that when EAP-TLS is in use that the FreeRADIUS users don't really matter. I CAN revoke the certificate (and then bounce FreeRADIUS) and the user can't login.

    In addition, there doesn't seem to be a way to turn off other EAP auth methods like EAP-TTLS, so IF there is a user defined in FreeRADIUS and I revoke their cert so they can't use EAP-TLS, they can switch to EAP-TTLS (no client cert) as long as they know the password for the user.

    Am I not getting something?

    BTW, here's some things I had to do to get it working.

    • Use a publicly trusted SSL server cert for FreeRADIUS. I used a Let's Encrypt cert via the pfsense acme package (which was awesome)
    • Issue all your certs off your root CA. Don't use an intermediate CA. Everything works with the intermediate except CRL checking.
    • On Windows, define your WiFi connection in Control Panel -> Network & Sharing Center -> Setup New Connection. You dont have the options you need in the half-baked modern GUI.
    • On Android, you have to type in a "domain". This is the FQDN of the publicly trusted FreeRADIUS SSL server cert.
    • EAP-TLS and EAP-TTLS/MS-CHAP-V2 both work. EAP-TTLS uses the FreeRADIUS username/password. EAP-TLS just uses the client cert (but you have to specify an "identity" (username) in both Windows and Android, but, as I mention above, it seems to be ignored by FreeRADIUS.
    P J 2 Replies Last reply Jan 9, 2024, 10:11 AM Reply Quote 0
    • P
      pavannani @Lobanz
      last edited by Jan 9, 2024, 10:11 AM

      @Lobanz can you share full documentation on how to configure EAP-TLS and what changes need to be done in Windows to connect wifi

      1 Reply Last reply Reply Quote 0
      • J
        johnpoz LAYER 8 Global Moderator @Lobanz
        last edited by Jan 9, 2024, 3:06 PM

        @Lobanz said in FreeRADIUS EAP-TLS, works but and "Check Client Certificate CN" doesn't:

        "When enabled, the Common Name of the client certificate must match the username set in 'FreeRADIUS > Users'."

        Hmmm, I do believe this use to work.. But yeah seems I am able to duplicate the issue. I have that checked.

        check.jpg

        I even completely deleted the freerad user, and still auths just fine..

        An intelligent man is sometimes forced to be drunk to spend time with his fools
        If you get confused: Listen to the Music Play
        Please don't Chat/PM me for help, unless mod related
        SG-4860 24.11 | Lab VMs 2.8, 24.11

        P 1 Reply Last reply Jan 10, 2024, 4:43 AM Reply Quote 0
        • P
          pavannani @johnpoz
          last edited by Jan 10, 2024, 4:43 AM

          @johnpoz
          @johnpoz

          Below is my configuration for EAP-tls but I am unable to connect to wifi for windows
          radiusd.conf

          prefix = /usr/local
          exec_prefix = ${prefix}
          sysconfdir = ${prefix}/etc
          localstatedir = /var
          sbindir = ${exec_prefix}/sbin
          logdir = ${localstatedir}/log
          raddbdir = ${sysconfdir}/raddb
          radacctdir = ${logdir}/radacct
          name = radiusd
          confdir = ${raddbdir}
          modconfdir = ${confdir}/mods-config
          certdir = ${confdir}/certs
          cadir = ${confdir}/certs
          run_dir = ${localstatedir}/run
          db_dir = ${raddbdir}
          libdir = /usr/local/lib/freeradius-3.2.3
          pidfile = ${run_dir}/${name}.pid
          max_request_time = 30
          cleanup_delay = 5
          max_requests = 1024
          hostname_lookups = no
          regular_expressions = yes
          extended_expressions = yes

          log {
          destination = files
          colourise = yes
          file = ${logdir}/radius.log
          syslog_facility = daemon
          stripped_names = yes
          auth = yes
          auth_badpass = yes
          auth_goodpass = yes
          msg_goodpass = ""
          msg_badpass = ""
          msg_denied = "You are already logged in - access denied"
          }

          checkrad = ${sbindir}/checkrad
          security {
          allow_core_dumps = no
          max_attributes = 200
          reject_delay = 1
          status_server = no
          # Disable this check since it may not be accurate due to how FreeBSD patches OpenSSL
          allow_vulnerable_openssl = yes
          }

          $INCLUDE clients.conf
          thread pool {
          start_servers = 5
          max_servers = 32
          min_spare_servers = 3
          max_spare_servers = 10
          max_queue_size = 65536
          max_requests_per_server = 0
          auto_limit_acct = no
          }

          modules {
          $INCLUDE ${confdir}/mods-enabled/
          }

          instantiate {
          exec
          expr
          expiration
          logintime
          ### Dis-/Enable sql instatiate
          #sql
          daily
          weekly
          monthly
          forever
          }
          policy {
          $INCLUDE policy.d/
          }
          $INCLUDE sites-enabled/


          EAP

          EAP

          eap {
          default_eap_type = tls
          timer_expire = 60
          ignore_unknown_eap_types = no
          cisco_accounting_username_bug = no
          max_sessions = 4096

          DISABLED WEAK EAP TYPES MD5, GTC

          pwd {

          group = 19

          server_id = theserver@example.com

          fragment_size = 1020

          virtual_server = "inner-tunnel"

          }

          tls-config tls-common {
          	# private_key_password = whatever
          	private_key_file = ${certdir}/server_key.pem
          	certificate_file = ${certdir}/server_cert.pem
          	ca_path = ${confdir}/certs
          	ca_file = ${ca_path}/ca_cert.pem
          #	auto_chain = yes
          #	psk_identity = "test"
          #	psk_hexphrase = "036363823"
          	dh_file = ${certdir}/dh
          	random_file = /dev/urandom
          	fragment_size = 1024
          	include_length = yes
          	check_crl = no
          	### check_cert_issuer = "/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd/emailAddress=test@mycomp.com/CN=myca" ###
          	### check_cert_cn = %{User-Name} ###
          	cipher_list = "DEFAULT"
          	cipher_server_preference = no
          

          disable_tlsv1_2 = no

          	ecdh_curve = "prime256v1"
          	tls_min_version = "1.2"
          	cache {
          		enable = no
          		lifetime = 24
          		max_entries = 255
          		#name = "EAP module"
          		#persist_dir = "/tlscache"
          	}
          	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 = no
          		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
          	include_length = yes
          #	require_client_cert = yes
          	virtual_server = "inner-tunnel-ttls"
          	#use_tunneled_reply is deprecated, new method happens in virtual-server
          }	### end ttls
          peap {
          	tls = tls-common
          	default_eap_type = mschapv2
          	copy_request_to_tunnel = no
          #	proxy_tunneled_request_as_eap = yes
          #	require_client_cert = yes
          

          MS SoH Server is disabled

          	virtual_server = "inner-tunnel-peap"
          	#use_tunneled_reply is deprecated, new method happens in virtual-server
          }
          mschapv2 {
          

          send_error = no

          identity = "FreeRADIUS"

          }
          

          fast {

          tls = tls-common

          pac_lifetime = 604800

          authority_identity = "1234"

          pac_opaque_key = "0123456789abcdef0123456789ABCDEF"

          virtual_server = inner-tunnel

          }

          }

          /usr/local/etc/raddb/clients.conf

          client "wifi" {
          ipaddr = 192.168.0.1
          proto = udp
          secret = '123456789'
          require_message_authenticator = no
          nas_type = other
          ### login = !root ###
          ### password = someadminpass ###
          limit {
          max_connections = 16
          lifetime = 0
          idle_timeout = 30
          }
          }


          default

          server default {
          listen {
          type = auth
          ipaddr = *
          port = 1812
          }

          authorize {

          filter_username

          filter_password

          preprocess
          

          operator-name

          cui

          AUTHORIZE FOR PLAIN MAC-AUTH IS DISABLED

          auth_log

          chap
          mschap
          digest
          

          wimax

          IPASS

          suffix
          ntdomain
          eap {
          	ok = return
          

          updated = return

          }
          

          unix

          files
          if ((notfound || noop) && ("%{%{Control:Auth-Type}:-No-Accept}" != "Accept")) {
          		### sql DISABLED ###
          if (true) {
          
          		### ldap ###
          		if (notfound || noop) {
          			reject
          		}
          	}
          }
          
          -daily
          -weekly
          -monthly
          -forever
          # Formerly checkval
          if (&request:Calling-Station-Id == &control:Calling-Station-Id) {
          	ok
          }
          expiration
          logintime
          pap
          Autz-Type Status-Server {
          
          }
          

          }

          authenticate {
          Auth-Type PAP {
          pap
          }
          Auth-Type CHAP {
          chap
          }
          Auth-Type MS-CHAP {
          mschap
          }
          mschap
          Auth-Type MOTP {
          motp
          }
          Auth-Type GOOGLEAUTH {
          googleauth
          }
          digest

          pam

          unix

          #Auth-Type LDAP {
          	#ldap
          	#### ldap2 disabled ###
          #}
          
          eap
          

          Auth-Type eap {

          eap {

          handled = 1

          }

          if (handled && (Response-Packet-Type == Access-Challenge)) {

          attr_filter.access_challenge.post-auth

          handled # override the "updated" code from attr_filter

          }

          }

          }

          preacct {
          preprocess

          ACCOUNTING FOR PLAIN MAC-AUTH DISABLED

          acct_counters64

          update request {
          	&FreeRADIUS-Acct-Session-Start-Time = "%{expr: %l - %{%{Acct-Session-Time}:-0} - %{%{Acct-Delay-Time}:-0}}"
          }
          

          acct_unique

          IPASS

          suffix
          ntdomain
          files
          

          }

          accounting {

          cui

          detail
          ### This makes it possible to run the datacounter_acct module only on accounting-stop and interim-updates
          if ((request:Acct-Status-Type == Stop) || (request:Acct-Status-Type == Interim-Update)) {
          	datacounterdaily
          	datacounterweekly
          	datacountermonthly
          	datacounterforever
          }
          

          unix

          radutmp
          

          sradutmp

          main_pool

          ### sql DISABLED ###
          daily
          weekly
          monthly
          forever
          

          if (noop) {

          ok

          }

          pgsql-voip

          exec
          attr_filter.accounting_response
          Acct-Type Status-Server {
          
          }
          

          }

          session {

          radutmp

          radutmp
          

          }

          post-auth {

          if (!&reply:State) {

          update reply {

          State := "0x%{randstr:16h}"

          }

          }

          update {
          	&reply: += &session-state:
          }
          

          main_pool

          cui

          reply_log

          sql DISABLED

          ldap

          exec
          

          wimax

          update reply {

          Reply-Message += "%{TLS-Cert-Serial}"

          Reply-Message += "%{TLS-Cert-Expiration}"

          Reply-Message += "%{TLS-Cert-Subject}"

          Reply-Message += "%{TLS-Cert-Issuer}"

          Reply-Message += "%{TLS-Cert-Common-Name}"

          Reply-Message += "%{TLS-Cert-Subject-Alt-Name-Email}"

          Reply-Message += "%{TLS-Client-Cert-Serial}"

          Reply-Message += "%{TLS-Client-Cert-Expiration}"

          Reply-Message += "%{TLS-Client-Cert-Subject}"

          Reply-Message += "%{TLS-Client-Cert-Issuer}"

          Reply-Message += "%{TLS-Client-Cert-Common-Name}"

          Reply-Message += "%{TLS-Client-Cert-Subject-Alt-Name-Email}"

          }

          insert_acct_class

          if (&reply:EAP-Session-Id) {

          update reply {

          EAP-Key-Name := &reply:EAP-Session-Id

          }

          }

          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 {
          
          }
          

          }

          pre-proxy {

          operator-name

          cui

          files

          attr_filter.pre-proxy
          

          pre_proxy_log

          }

          post-proxy {

          post_proxy_log

          attr_filter.post-proxy
          eap
          

          Post-Proxy-Type Fail-Accounting {

          detail

          }

          }
          }


          1 Reply Last reply Reply Quote 0
          • First post
            Last post
          Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.
            [[user:consent.lead]]
            [[user:consent.not_received]]