aboutsummaryrefslogtreecommitdiffstats
path: root/roles/freeradius
diff options
context:
space:
mode:
authorStonewall Jackson <stonewall@sacredheartsc.com>2023-02-04 01:23:43 -0500
committerStonewall Jackson <stonewall@sacredheartsc.com>2023-02-04 01:52:13 -0500
commit0261e875679f1bf63c8d689da7fc7e014597885d (patch)
tree3f19cd74a0c1070944f75437f30b098d6ef2ffcb /roles/freeradius
downloadselfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.tar.gz
selfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.zip
initial commit
Diffstat (limited to 'roles/freeradius')
-rw-r--r--roles/freeradius/defaults/main.yml3
-rw-r--r--roles/freeradius/files/etc/systemd/system/radiusd.service.d/override.conf6
-rw-r--r--roles/freeradius/handlers/main.yml4
-rw-r--r--roles/freeradius/tasks/freeipa.yml50
-rw-r--r--roles/freeradius/tasks/main.yml74
-rw-r--r--roles/freeradius/templates/etc/raddb/clients.conf.j26
-rw-r--r--roles/freeradius/templates/etc/raddb/mods-available/eap.j254
-rw-r--r--roles/freeradius/templates/etc/raddb/mods-available/ldap.j2113
-rw-r--r--roles/freeradius/templates/etc/raddb/radiusd.conf.j273
-rw-r--r--roles/freeradius/templates/etc/raddb/sites-available/inner-tunnel.j290
-rw-r--r--roles/freeradius/vars/main.yml12
11 files changed, 485 insertions, 0 deletions
diff --git a/roles/freeradius/defaults/main.yml b/roles/freeradius/defaults/main.yml
new file mode 100644
index 0000000..416d15f
--- /dev/null
+++ b/roles/freeradius/defaults/main.yml
@@ -0,0 +1,3 @@
+freeradius_clients: []
+freeradius_ldap_servers: '{{ freeipa_hosts }}'
+freeradius_access_group: role-wifi-access
diff --git a/roles/freeradius/files/etc/systemd/system/radiusd.service.d/override.conf b/roles/freeradius/files/etc/systemd/system/radiusd.service.d/override.conf
new file mode 100644
index 0000000..d1edca8
--- /dev/null
+++ b/roles/freeradius/files/etc/systemd/system/radiusd.service.d/override.conf
@@ -0,0 +1,6 @@
+[Unit]
+After=syslog.target network-online.target ipa.service dirsrv.target krb5kdc.service mysql.service mariadb.service postgresql.service gssproxy.service
+Wants=gssproxy.service
+
+[Service]
+Environment=GSS_USE_PROXY=yes
diff --git a/roles/freeradius/handlers/main.yml b/roles/freeradius/handlers/main.yml
new file mode 100644
index 0000000..9c89432
--- /dev/null
+++ b/roles/freeradius/handlers/main.yml
@@ -0,0 +1,4 @@
+- name: restart radiusd
+ systemd:
+ name: radiusd
+ state: restarted
diff --git a/roles/freeradius/tasks/freeipa.yml b/roles/freeradius/tasks/freeipa.yml
new file mode 100644
index 0000000..945e2a8
--- /dev/null
+++ b/roles/freeradius/tasks/freeipa.yml
@@ -0,0 +1,50 @@
+- name: create access group
+ ipagroup:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ name: '{{ freeradius_access_group }}'
+ description: wifi access
+ nonposix: yes
+ state: present
+ run_once: True
+
+- name: create service principal
+ ipaservice:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ name: 'radius/{{ ansible_fqdn }}'
+ state: present
+
+- name: retrieve service keytab
+ include_role:
+ name: freeipa_keytab
+ vars:
+ keytab_principal: 'radius/{{ ansible_fqdn }}'
+ keytab_path: '{{ freeradius_keytab }}'
+
+- name: configure gssproxy for kerberized LDAP
+ include_role:
+ name: gssproxy_client
+ vars:
+ gssproxy_name: freeradius
+ gssproxy_section: service/freeradius
+ gssproxy_client_keytab: '{{ freeradius_keytab }}'
+ gssproxy_cred_usage: initiate
+ gssproxy_euid: radiusd
+
+- name: create systemd override directory
+ file:
+ path: /etc/systemd/system/radiusd.service.d
+ state: directory
+
+- name: create systemd override file
+ copy:
+ src: etc/systemd/system/radiusd.service.d/override.conf
+ dest: /etc/systemd/system/radiusd.service.d/override.conf
+ register: freeradius_systemd_unit
+ notify: restart radiusd
+
+- name: reload systemd units
+ systemd:
+ daemon_reload: yes
+ when: freeradius_systemd_unit.changed
diff --git a/roles/freeradius/tasks/main.yml b/roles/freeradius/tasks/main.yml
new file mode 100644
index 0000000..a2c926d
--- /dev/null
+++ b/roles/freeradius/tasks/main.yml
@@ -0,0 +1,74 @@
+- name: install freeradius
+ dnf:
+ name: '{{ freeradius_packages }}'
+ state: present
+
+- import_tasks: freeipa.yml
+
+- name: request TLS certificate
+ include_role:
+ name: getcert_request
+ vars:
+ certificate_service: radius
+ certificate_path: '{{ freeradius_certificate_path }}'
+ certificate_key_path: '{{ freeradius_certificate_key_path }}'
+ certificate_ca_path: '{{ freeradius_certificate_ca_path }}'
+ certificate_owner: radiusd
+ certificate_hook: systemctl restart radiusd
+
+- name: generate dhparams
+ openssl_dhparam:
+ path: '{{ freeradius_dhparams_path }}'
+ size: 2048
+
+- name: enable ldap module
+ file:
+ src: /etc/raddb/mods-available/ldap
+ dest: /etc/raddb/mods-enabled/ldap
+ state: link
+
+- name: generate freeradius configuration
+ template:
+ src: etc/raddb/{{ item }}.j2
+ dest: /etc/raddb/{{ item }}
+ owner: root
+ group: radiusd
+ mode: 0640
+ loop:
+ - radiusd.conf
+ - clients.conf
+ - mods-available/eap
+ - mods-available/ldap
+ - sites-available/inner-tunnel
+ notify: restart radiusd
+
+- name: create tlscache directory
+ file:
+ path: '{{ freeradius_tlscache_dir }}'
+ state: directory
+ owner: radiusd
+ group: radiusd
+ mode: 0700
+
+- name: set up clean-freeradius-tlscache timer
+ include_role:
+ name: systemd_timer
+ vars:
+ timer_name: clean-freeradius-tlscache
+ timer_description: Delete old freeradius tlscache files
+ timer_on_calendar: daily
+ timer_exec: find {{ freeradius_tlscache_dir }} -mtime +2 -exec rm -vf {} ;
+
+- name: start freeradius
+ systemd:
+ name: radiusd
+ enabled: yes
+ state: started
+
+- name: open firewall ports
+ firewalld:
+ service: radius
+ permanent: yes
+ immediate: yes
+ state: enabled
+ tags: firewalld
diff --git a/roles/freeradius/templates/etc/raddb/clients.conf.j2 b/roles/freeradius/templates/etc/raddb/clients.conf.j2
new file mode 100644
index 0000000..f6396e0
--- /dev/null
+++ b/roles/freeradius/templates/etc/raddb/clients.conf.j2
@@ -0,0 +1,6 @@
+{% for client in freeradius_clients %}
+client {{ client.name }} {
+ ipaddr = {{ client.address }}
+ secret = {{ client.secret }}
+}
+{% endfor %}
diff --git a/roles/freeradius/templates/etc/raddb/mods-available/eap.j2 b/roles/freeradius/templates/etc/raddb/mods-available/eap.j2
new file mode 100644
index 0000000..5db0d1f
--- /dev/null
+++ b/roles/freeradius/templates/etc/raddb/mods-available/eap.j2
@@ -0,0 +1,54 @@
+eap {
+ default_eap_type = ttls
+ timer_expire = 60
+ ignore_unknown_eap_types = yes
+ cisco_accounting_username_bug = no
+ max_sessions = ${max_requests}
+
+ tls-config tls-common {
+ private_key_password =
+ private_key_file = {{ freeradius_certificate_key_path }}
+ certificate_file = {{ freeradius_certificate_path }}
+ ca_file = {{ freeradius_certificate_ca_path }}
+ auto_chain = no
+ ca_path = ${cadir}
+ cipher_list = "PROFILE=SYSTEM"
+ cipher_server_preference = no
+ tls_min_version = "1.2"
+ tls_max_version = "1.2"
+ ecdh_curve = "prime256v1"
+
+ cache {
+ enable = yes
+ lifetime = 24 # hours
+ name = "EAP module"
+ persist_dir = "${db_dir}/tlscache"
+ store {
+ Tunnel-Private-Group-Id
+ }
+ }
+
+ verify {
+ skip_if_ocsp_ok = yes
+ tmpdir = /var/run/radiusd/tmp
+ client = "/usr/bin/openssl verify -CApath ${..ca_path} %{TLS-Client-Cert-Filename}"
+ }
+
+ ocsp {
+ enable = yes
+ override_cert_url = no
+ }
+ }
+
+ tls {
+ tls = tls-common
+ }
+
+ ttls {
+ tls = tls-common
+ default_eap_type = md5
+ copy_request_to_tunnel = no
+ use_tunneled_reply = no
+ virtual_server = "inner-tunnel"
+ }
+}
diff --git a/roles/freeradius/templates/etc/raddb/mods-available/ldap.j2 b/roles/freeradius/templates/etc/raddb/mods-available/ldap.j2
new file mode 100644
index 0000000..85aede1
--- /dev/null
+++ b/roles/freeradius/templates/etc/raddb/mods-available/ldap.j2
@@ -0,0 +1,113 @@
+ldap {
+{% for server in freeradius_ldap_servers %}
+ server = '{{ server }}'
+{% endfor %}
+
+ base_dn = '{{ freeipa_user_basedn }}'
+
+ sasl {
+ mech = 'GSSAPI'
+ realm = '{{ freeipa_realm }}'
+ }
+
+ update {
+ control:Password-With-Header += 'userPassword'
+ control: += 'radiusControlAttribute'
+ request: += 'radiusRequestAttribute'
+ reply: += 'radiusReplyAttribute'
+ }
+
+ user_dn = "LDAP-UserDn"
+
+ user {
+ base_dn = "${..base_dn}"
+{% raw %}
+ filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
+{% endraw %}
+ }
+
+ group {
+ base_dn = '{{ freeipa_group_basedn }}'
+ filter = '(objectClass=ipagroup)'
+ name_attribute = cn
+{% raw %}
+ membership_filter = "(member=%{control:${..user_dn}})"
+{% endraw %}
+ membership_attribute = 'memberOf'
+ cacheable_name = 'yes'
+ cacheable_dn = 'yes'
+ allow_dangling_group_ref = 'yes'
+ }
+
+ profile { }
+
+ client {
+ base_dn = "${..base_dn}"
+ filter = '(objectClass=radiusClient)'
+
+ template { }
+
+ attribute {
+ ipaddr = 'radiusClientIdentifier'
+ secret = 'radiusClientSecret'
+ }
+ }
+
+ read_clients = no
+
+ accounting {
+ reference = "%{tolower:type.%{Acct-Status-Type}}"
+
+ type {
+ start {
+ update {
+ description := "Online at %S"
+ }
+ }
+
+ interim-update {
+ update {
+ description := "Last seen at %S"
+ }
+ }
+
+ stop {
+ update {
+ description := "Offline at %S"
+ }
+ }
+ }
+ }
+
+ post-auth {
+ update {
+ description := "Authenticated at %S"
+ }
+ }
+
+ options {
+ chase_referrals = yes
+ rebind = yes
+ res_timeout = 10
+ srv_timelimit = 3
+ net_timeout = 1
+ idle = 60
+ probes = 3
+ interval = 3
+ ldap_debug = 0x0000
+ }
+
+ tls { }
+
+ 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
+ }
+}
diff --git a/roles/freeradius/templates/etc/raddb/radiusd.conf.j2 b/roles/freeradius/templates/etc/raddb/radiusd.conf.j2
new file mode 100644
index 0000000..ad9b58f
--- /dev/null
+++ b/roles/freeradius/templates/etc/raddb/radiusd.conf.j2
@@ -0,0 +1,73 @@
+prefix = /usr
+exec_prefix = /usr
+sysconfdir = /etc
+localstatedir = /var
+sbindir = /usr/sbin
+logdir = ${localstatedir}/log/radius
+raddbdir = ${sysconfdir}/raddb
+radacctdir = ${logdir}/radacct
+
+name = radiusd
+
+confdir = ${raddbdir}
+modconfdir = ${confdir}/mods-config
+certdir = ${confdir}/certs
+cadir = ${confdir}/certs
+run_dir = ${localstatedir}/run/${name}
+
+db_dir = ${localstatedir}/lib/radiusd
+libdir = /usr/lib64/freeradius
+pidfile = ${run_dir}/${name}.pid
+correct_escapes = true
+max_request_time = 30
+cleanup_delay = 5
+max_requests = 16384
+hostname_lookups = no
+log {
+ destination = stdout
+ colourise = no
+ stripped_names = no
+ auth = yes
+ auth_badpass = no
+ auth_goodpass = no
+ msg_denied = "You are already logged in - access denied"
+}
+
+checkrad = ${sbindir}/checkrad
+
+ENV { }
+
+security {
+ user = radiusd
+ group = radiusd
+ allow_core_dumps = no
+ max_attributes = 200
+ reject_delay = 1
+ status_server = yes
+}
+
+proxy_requests = yes
+$INCLUDE proxy.conf
+
+$INCLUDE clients.conf
+
+thread pool {
+ start_servers = 5
+ max_servers = 32
+ min_spare_servers = 3
+ max_spare_servers = 10
+ max_requests_per_server = 0
+ auto_limit_acct = no
+}
+
+modules {
+ $INCLUDE mods-enabled/
+}
+
+instantiate { }
+
+policy {
+ $INCLUDE policy.d/
+}
+
+$INCLUDE sites-enabled/
diff --git a/roles/freeradius/templates/etc/raddb/sites-available/inner-tunnel.j2 b/roles/freeradius/templates/etc/raddb/sites-available/inner-tunnel.j2
new file mode 100644
index 0000000..043349a
--- /dev/null
+++ b/roles/freeradius/templates/etc/raddb/sites-available/inner-tunnel.j2
@@ -0,0 +1,90 @@
+server inner-tunnel {
+ listen {
+ ipaddr = 127.0.0.1
+ port = 18120
+ type = auth
+ }
+
+ authorize {
+ filter_username
+ chap
+ suffix
+
+ update control {
+ &Proxy-To-Realm := LOCAL
+ }
+
+ eap {
+ ok = return
+ }
+
+ ldap
+ if (ok || updated) {
+ update {
+ control:Auth-Type := ldap
+ }
+ }
+
+ expiration
+ logintime
+ pap
+ }
+
+ authenticate {
+ Auth-Type PAP {
+ pap
+ }
+
+ Auth-Type CHAP {
+ chap
+ }
+
+ Auth-Type LDAP {
+ ldap
+ }
+
+ eap
+ }
+
+ session {
+ radutmp
+ }
+
+
+ post-auth {
+ -sql
+ 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 {
+ -sql
+ attr_filter.access_reject
+
+ update outer.session-state {
+ &Module-Failure-Message := &request:Module-Failure-Message
+ }
+ }
+
+ if (LDAP-Group != "{{ freeradius_access_group }}") {
+ reject
+ }
+ }
+
+ pre-proxy { }
+
+ post-proxy {
+ eap
+ }
+}
diff --git a/roles/freeradius/vars/main.yml b/roles/freeradius/vars/main.yml
new file mode 100644
index 0000000..a99a6aa
--- /dev/null
+++ b/roles/freeradius/vars/main.yml
@@ -0,0 +1,12 @@
+freeradius_packages:
+ - freeradius
+ - freeradius-ldap
+ - freeradius-utils
+
+freeradius_certificate_path: /etc/pki/tls/certs/radiusd.pem
+freeradius_certificate_key_path: /etc/pki/tls/private/radiusd.key
+freeradius_certificate_ca_path: /etc/ipa/ca.crt
+freeradius_dhparams_path: /etc/raddb/certs/dh
+freeradius_tlscache_dir: /var/lib/radiusd/tlscache
+
+freeradius_keytab: /var/lib/gssproxy/clients/freeradius.keytab