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
This commit is contained in:
schreibubi
2020-10-14 13:41:02 +02:00
committed by GitHub
parent ba2cb35235
commit df263e5fa1
9 changed files with 163 additions and 4 deletions
+1 -1
View File
@@ -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
+6
View File
@@ -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
@@ -9,7 +9,7 @@
<id>user.username</id>
<label>Username</label>
<type>text</type>
<help>Set the unique username for the user. Allowed characters are 0-9, a-z, A-Z, and ._-</help>
<help>Set the unique username for the user. Allowed characters are 0-9, a-z, A-Z, and ._-@/</help>
</field>
<field>
<id>user.password</id>
@@ -29,4 +29,10 @@
<type>dropdown</type>
<help>This enables CRL checking, please restart this service with every change to the CRL.</help>
</field>
<field>
<id>eap.check_tls_names</id>
<label>Check TLS Common-Name</label>
<type>checkbox</type>
<help>Checks that the username given by the user matches the Common-Name of the certificate.</help>
</field>
</form>
@@ -11,6 +11,7 @@
<md5>MD5</md5>
<mschapv2>MSCHAPv2</mschapv2>
<peap>PEAP</peap>
<tls>TLS</tls>
<ttls>TTLS</ttls>
</OptionValues>
</default_eap_type>
@@ -30,5 +31,9 @@
<Type>crl</Type>
<Required>N</Required>
</crl>
<check_tls_names type="BooleanField">
<default>0</default>
<Required>Y</Required>
</check_tls_names>
</items>
</model>
@@ -11,7 +11,7 @@
</enabled>
<username type="TextField">
<Required>Y</Required>
<mask>/^([0-9a-zA-Z._\-]){1,128}$/u</mask>
<mask>/^([0-9a-zA-Z@._\-\/]){1,128}$/u</mask>
</username>
<password type="TextField">
<Required>Y</Required>
@@ -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
@@ -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 %}
}
@@ -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
}
}