From df263e5fa1c4f1ef0200a95c080f39b2eb6c9aa6 Mon Sep 17 00:00:00 2001 From: schreibubi Date: Wed, 14 Oct 2020 13:41:02 +0200 Subject: [PATCH] Freeradius TLS (#1900) * net/freeradius: Allow '@' as part of the username Freeradius allows to have e-mail addresses as usernames. * net/freeradius: Add option to enforce that user-name and certificate common-name are identical * net/freeradius: Allow '/' as part of the username Windows authenticates machines with host/ prefixed to the username, thus need to allow specifying usernames containing '/'. * net/freeradius: Allow selection of TLS for default EAP type * net/freeradius: Bump version number to 1.9.8 and update pkg-descr --- net/freeradius/Makefile | 2 +- net/freeradius/pkg-descr | 6 + .../forms/dialogEditFreeRADIUSUser.xml | 2 +- .../OPNsense/Freeradius/forms/eap.xml | 6 + .../app/models/OPNsense/Freeradius/Eap.xml | 5 + .../app/models/OPNsense/Freeradius/User.xml | 2 +- .../templates/OPNsense/Freeradius/+TARGETS | 1 + .../OPNsense/Freeradius/mods-enabled-eap | 6 +- .../Freeradius/sites-enabled-check-eap-tls | 137 ++++++++++++++++++ 9 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-check-eap-tls diff --git a/net/freeradius/Makefile b/net/freeradius/Makefile index 2178cd874..ca1e699b5 100644 --- a/net/freeradius/Makefile +++ b/net/freeradius/Makefile @@ -1,5 +1,5 @@ PLUGIN_NAME= freeradius -PLUGIN_VERSION= 1.9.7 +PLUGIN_VERSION= 1.9.8 PLUGIN_COMMENT= RADIUS Authentication, Authorization and Accounting Server PLUGIN_DEPENDS= freeradius3 PLUGIN_MAINTAINER= m.muenz@gmail.com diff --git a/net/freeradius/pkg-descr b/net/freeradius/pkg-descr index bedbd33da..3c64880be 100644 --- a/net/freeradius/pkg-descr +++ b/net/freeradius/pkg-descr @@ -15,6 +15,12 @@ The server is fast, feature-rich, modular, and scalable. Plugin Changelog ================ +1.9.8 + +* Add support for checking TLS certificate names +* Allow / and @ as part of the user-names +* Allow TLS as the default EAP type + 1.9.7 * Fix Login-Time validation diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSUser.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSUser.xml index 1f1cc7ec8..a859a6396 100644 --- a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSUser.xml +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSUser.xml @@ -9,7 +9,7 @@ user.username text - Set the unique username for the user. Allowed characters are 0-9, a-z, A-Z, and ._- + Set the unique username for the user. Allowed characters are 0-9, a-z, A-Z, and ._-@/ user.password diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/eap.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/eap.xml index c13503bed..531cc4fde 100644 --- a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/eap.xml +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/eap.xml @@ -29,4 +29,10 @@ dropdown This enables CRL checking, please restart this service with every change to the CRL. + + eap.check_tls_names + + checkbox + Checks that the username given by the user matches the Common-Name of the certificate. + diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Eap.xml b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Eap.xml index 005d63707..f2b451bea 100644 --- a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Eap.xml +++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Eap.xml @@ -11,6 +11,7 @@ MD5 MSCHAPv2 PEAP + TLS TTLS @@ -30,5 +31,9 @@ crl N + + 0 + Y + diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/User.xml b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/User.xml index c2432ab0b..f56b97050 100644 --- a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/User.xml +++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/User.xml @@ -11,7 +11,7 @@ Y - /^([0-9a-zA-Z._\-]){1,128}$/u + /^([0-9a-zA-Z@._\-\/]){1,128}$/u Y diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS index 083726a5d..4de8793c1 100644 --- a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS @@ -14,4 +14,5 @@ radiusd.conf:/usr/local/etc/raddb/radiusd.conf sites-enabled-default:/usr/local/etc/raddb/sites-enabled/default sites-enabled-dhcp:/usr/local/etc/raddb/sites-enabled/dhcp sites-enabled-inner-tunnel:/usr/local/etc/raddb/sites-enabled/inner-tunnel +sites-enabled-check-eap-tls:/usr/local/etc/raddb/sites-enabled/check-eap-tls users:/usr/local/etc/raddb/mods-config/files/authorize diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/mods-enabled-eap b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/mods-enabled-eap index f5fa439da..d1ec223d2 100644 --- a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/mods-enabled-eap +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/mods-enabled-eap @@ -593,7 +593,11 @@ eap { # virtual server has access to these attributes, and can # be used to accept or reject the request. # - # virtual_server = check-eap-tls +{% if helpers.exists('OPNsense.freeradius.eap.enable_client_cert') and OPNsense.freeradius.eap.enable_client_cert == '1' %} +{% if helpers.exists('OPNsense.freeradius.eap.check_tls_names') and OPNsense.freeradius.eap.check_tls_names == '1' %} + virtual_server = check-eap-tls +{% endif %} +{% endif %} } diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-check-eap-tls b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-check-eap-tls new file mode 100644 index 000000000..bc74ab5b6 --- /dev/null +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-check-eap-tls @@ -0,0 +1,137 @@ +# This virtual server allows EAP-TLS to reject access requests +# based on some attributes of the certificates involved. +# +# To use this virtual server, you must enable it in the tls +# section of mods-enabled/eap as well as adding a link to this +# file in sites-enabled/. +# +# +# Value-pairs that are available for checking include: +# +# TLS-Client-Cert-Subject +# TLS-Client-Cert-Issuer +# TLS-Client-Cert-Common-Name +# TLS-Client-Cert-Subject-Alt-Name-Email +# +# To see a full list of attributes, run the server in debug mode +# with this virtual server configured, and look at the attributes +# passed in to this virtual server. +# +# +# This virtual server is also useful when using EAP-TLS as it is +# only called once, just before the final Accept is about to be +# returned from eap, whereas the outer authorize section is called +# multiple times for each challenge / response. For this reason, +# here may be a good location to put authentication logging, and +# modules that check for further authorization, especially if they +# hit external services such as sql or ldap. + + +server check-eap-tls { + + +# Authorize - this is the only section required. +# +# To accept the access request, set Auth-Type = Accept, otherwise +# set it to Reject. + +authorize { + + # + # By default, we just accept the request: + # + update config { + &Auth-Type := Accept + } + + + # + # Check the client certificate matches a string, and reject otherwise + # + +# if ("%{TLS-Client-Cert-Common-Name}" == 'client.example.com') { +# update config { +# &Auth-Type := Accept +# } +# } +# else { +# update config { +# &Auth-Type := Reject +# } +# update reply { +# &Reply-Message := "Your certificate is not valid." +# } +# } + + + # + # Check the client certificate common name against the supplied User-Name + # + if (&User-Name == &TLS-Client-Cert-Common-Name || &User-Name == "host/%{TLS-Client-Cert-Common-Name}") { + update config { + &Auth-Type := Accept + } + } + else { + update config { + &Auth-Type := Reject + } + } + + + # + # This is a convenient place to call LDAP, for example, when using + # EAP-TLS, as it will only be called once, after all certificates as + # part of the EAP-TLS challenge process have been verified. + # + # An example could be to use LDAP to check that the connecting host, as + # well as presenting a valid certificate, is also in a group based on + # the User-Name (assuming this contains the service principal name). + # Settings such as the following could be used in the ldap module + # configuration: + # + # basedn = "dc=example, dc=com" + # filter = "(servicePrincipalName=%{User-Name})" + # base_filter = "(objectClass=computer)" + # groupname_attribute = cn + # groupmembership_filter = "(&(objectClass=group)(member=%{control:Ldap-UserDn}))" + +# ldap + + # Now let's test membership of an LDAP group (the ldap bind user will + # need permission to read this group membership): + +# if (!(Ldap-Group == "Permitted-Laptops")) { +# update config { +# &Auth-Type := Reject +# } +# } + + # or, to be more specific, you could use the group's full DN: + # if (!(Ldap-Group == "CN=Permitted-Laptops,OU=Groups,DC=example,DC=org")) { + + + # + # This may be a better place to call the files modules when using + # EAP-TLS, as it will only be called once, after the challenge-response + # iteration has completed. + # + + files + + expiration + logintime + + # + # Log all request attributes, plus TLS certificate details, to the + # auth_log file. Again, this is just once per connection request, so + # may be preferable than in the outer authorize section. It is + # suggested that 'auth_log' also be in the outer post-auth and + # Post-Auth REJECT sections to log reply packet details, too. + # + + #auth_log + +} +} +