freeradius: support for EAP-TTLS/PAP and EAP-PEAP/GTC

This commit is contained in:
jeltz 2022-09-01 17:35:22 +02:00
parent 231c3aac09
commit 2d6ee91f93
Signed by: jeltz
GPG key ID: 800882B66C0C3326
10 changed files with 186 additions and 11 deletions

View file

@ -4,6 +4,9 @@
- radius-1.isp.infra.auro.re - radius-1.isp.infra.auro.re
vars: vars:
radiusd__clients: radiusd__clients:
localhost:
addr: 127.0.0.1
secret: abcdef
wifi-ap-v4: wifi-ap-v4:
addr: 10.102.0.0/16 addr: 10.102.0.0/16
secret: abcdef secret: abcdef

View file

@ -18,6 +18,8 @@ radiusd__enabled_modules_minimal:
- realm # TODO - realm # TODO
- unpack # TODO - unpack # TODO
- eap_inner - eap_inner
- ldap
- pap
- utf8 - utf8
radiusd__enabled_modules: [] radiusd__enabled_modules: []
radiusd__tls_cipher_list: DEFAULT radiusd__tls_cipher_list: DEFAULT

View file

@ -54,6 +54,8 @@
- mods-available/eap_inner - mods-available/eap_inner
- mods-config/attr_filter/access_challenge - mods-config/attr_filter/access_challenge
- mods-config/attr_filter/access_reject - mods-config/attr_filter/access_reject
- sites-available/inner-tunnel
- sites-available/default
notify: notify:
- Restart freeradius - Restart freeradius

View file

@ -2,12 +2,8 @@
{% for name, client in radiusd__clients.items() %} {% for name, client in radiusd__clients.items() %}
client {{ name }} { client {{ name }} {
{% if client.addr | ansible.utils.ipv4 %} ipaddr = {{ client.addr }}
ipv4addr = {{ client.addr | ansible.utils.ipv4("network") }} shortname = {{ name }}
{% else %}
ipv6addr = {{ client.addr | ansible.utils.ipaddr("network") }}
{% endif %}
netmask = {{ client.addr | ansible.utils.ipaddr("prefix") }}
proto = * proto = *
require_message_authenticator = yes require_message_authenticator = yes
nastype = other nastype = other

View file

@ -5,6 +5,7 @@ eap {
default_eap_type = peap default_eap_type = peap
type = peap type = peap
type = ttls
ignore_unknown_eap_types = no ignore_unknown_eap_types = no
@ -40,6 +41,16 @@ eap {
peap { peap {
tls = tls-common tls = tls-common
default_eap_type = gtc default_eap_type = gtc
require_client_cert = no
copy_request_to_tunnel = no
use_tunneled_reply = no
virtual_server = inner-tunnel
}
ttls {
tls = tls-common
default_eap_type = pap
require_client_cert = no
copy_request_to_tunnel = no copy_request_to_tunnel = no
use_tunneled_reply = no use_tunneled_reply = no
virtual_server = inner-tunnel virtual_server = inner-tunnel

View file

@ -5,13 +5,10 @@ eap inner-eap {
default_eap_type = gtc default_eap_type = gtc
type = gtc type = gtc
type = mschapv2 type = pap
gtc { gtc {
auth_type = local auth_type = LDAP
}
mschapv2 {
} }
} }

View file

@ -0,0 +1,50 @@
{{ ansible_managed | comment }}
ldap {
server = "ldap://ldap-1.int.infra.auro.re"
# TODO: quand on passera en prod, créer un utilisation dédié
identity = "cn=Directory manager"
password = "MotDePasseSuperComplique"
base_dn = "ou=users,dc=auro,dc=re"
user_dn = "LDAP-UserDn"
user {
base_dn = "${..base_dn}"
filter = "{{ '(uid=%{%{Stripped-User-Name}:-%{User-Name}})' }}"
}
group {
base_dn = "${..base_dn}"
filter = "(objectClass=posixGroup)"
membership_attribute = "memberOf"
}
# TODO
options {
chase_referrals = yes
rebind = yes
res_timeout = 10
srv_timelimit = 3
net_timeout = 1
idle = 60
probes = 3
interval = 3
ldap_debug = 0x0028
}
pool {
start = ${thread[pool].start_servers}
min = ${thread[pool].min_spare_servers}
max = ${thread[pool].max_servers}
spare = ${thread[pool].max_spare_servers}
uses = 0
retry_delay = 30
lifetime = 0
idle_timeout = 60
}
}

View file

@ -0,0 +1,5 @@
{{ ansible_managed | comment }}
pap {
normalise = no
}

View file

@ -0,0 +1,70 @@
{{ ansible_managed | comment }}
server default {
listen {
type = auth
ipaddr = *
port = 0
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
listen {
type = auth
ipv6addr = *
port = 0
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
authorize {
filter_username # TODO
preprocess # TODO
suffix
eap
}
authenticate {
eap
}
preacct {
}
accounting {
}
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:
}
Post-Auth-Type REJECT {
attr_filter.access_reject
eap
remove_reply_message_if_eap
}
remove_reply_message_if_eap
}
pre-proxy {
}
post-proxy {
eap
}
}

View file

@ -0,0 +1,39 @@
{{ ansible_managed | comment }}
server inner-tunnel {
authorize {
# Look for realm using the 'suffix' format (user@realm)
suffix
# Don't proxy requests from inner tunnel
update control {
&Proxy-To-Realm := LOCAL
}
# TODO: vérifier que le realm est soit vide, soit 'auro.re'
# Must be before 'ldap', so that we don't query the LDAP server
# for "internal" packets (cf. documentation for
# sites-available/inner-tunnel)
inner-eap {
ok = return
}
ldap
# See https://github.com/FreeRADIUS/freeradius-server/blob/master/doc/antora/modules/howto/pages/modules/ldap/authentication.adoc
if ((ok || updated) && User-Password) {
update control {
Auth-Type := ldap
}
}
pap
}
authenticate {
inner-eap
# Authenticate using 'Auth-Type = LDAP'
# This is not recommended by FreeRADIUS (cf. documentation for
# sites-available/default), but the password hashing scheme used
# by 389DS is not yet supported by FreeRADIUS 3
# (cf. https://github.com/FreeRADIUS/freeradius-server/issues/2649)
ldap
}
}