diff --git a/README.md b/README.md index 3ef170f2..67c13ae8 100644 --- a/README.md +++ b/README.md @@ -606,6 +606,11 @@ installs FreeRADIUS, and configures it for WPA Enterprise (EAP-TTLS-PAP): acct_port: 1823 # Port used by the authentication service of inner tunnel for this FreeRADIUS site inner_tunnel_auth_port: 18230 + # If you want to use a custom certificate for FreeRADIUS EAP module, + # you can specify the path to the certificate and private key as follows. + # Ensure that the certificate and private key can be read by the "freerad" user. + cert: /etc/freeradius/certs/cert.pem + private_key: /etc/freeradius/certs/key.pem # You can add as many organizations as you want - name: demo uuid: 00000000-0000-0000-0000-000000000001 @@ -613,9 +618,12 @@ installs FreeRADIUS, and configures it for WPA Enterprise (EAP-TTLS-PAP): auth_port: 1832 acct_port: 1833 inner_tunnel_auth_port: 18330 - ``` + # If you omit the "cert" and "private_key" keys, + # the FreeRADIUS site will use the default certificates + # located in /etc/freeradius/certs. +``` -**Note**: In the example playbook above, custom ports 1822, 1823, and 18230 +**Note**: In the example above, custom ports 1822, 1823, and 18230 are utilized for FreeRADIUS authentication, accounting, and inner tunnel authentication, respectively. These custom ports are specified because the Ansible role creates a common FreeRADIUS site for all organizations, which @@ -624,6 +632,82 @@ to listen on the default FreeRADIUS ports 1812, 1813, and 18120. Therefore, when configuring WPA Enterprise authentication for each organization, unique ports must be provided to ensure proper isolation and functionality. +#### Using Let's Encrypt Certificate for WPA Enterprise (EAP-TTLS-PAP) + +In this section, we demonstrate how to utilize Let's Encrypt certificates for WPA Enterprise (EAP-TTLS-PAP) authentication. Similar to the [Automatic SSL certificate](#automatic-ssl-certificate), we use [geerlingguy.certbot](https://galaxy.ansible.com/geerlingguy/certbot/) role to automatically install and renew a valid SSL certificate. + +The following example playbook achieves the following goals: + +- Provision a separate Let's Encrypt certificate for the `freeradius.yourdomain.com` hostname. This certificate will be utilized by the FreeRADIUS site for WPA Enterprise authentication. +- Create a renewal hook to set permissions on the generated certificate so the FreeRADIUS server can read it. + +**Note**: You can also use the same SSL certificate for both Nginx and FreeRADIUS, but it's crucial to understand the security implications. Please exercise caution and refer to the example playbook comments for guidance. + +```yaml + - hosts: openwisp2 + become: "{{ become | default('yes') }}" + roles: + - geerlingguy.certbot + - openwisp.openwisp2 + vars: + # certbot configuration + certbot_auto_renew_minute: "20" + certbot_auto_renew_hour: "5" + certbot_create_if_missing: true + certbot_auto_renew_user: "" + certbot_certs: + - email: "" + domains: + - "{{ inventory_hostname }}" + # If you choose to re-use the same certificate for both services, + # you can omit the following item in your playbook. + - email: "" + domains: + - "freeradius.yourdomain.com" + # Configuration to use Let's Encrypt certificate for OpenWISP server (Nnginx) + openwisp2_ssl_cert: "/etc/letsencrypt/live/{{ inventory_hostname }}/fullchain.pem" + openwisp2_ssl_key: "/etc/letsencrypt/live/{{ inventory_hostname }}/privkey.pem" + # Configuration for openwisp-radius + openwisp2_radius: true + openwisp2_freeradius_install: true + freeradius_eap_orgs: + - name: demo + uuid: 00000000-0000-0000-0000-000000000001 + radius_secret: demo-radius-token + auth_port: 1832 + acct_port: 1833 + inner_tunnel_auth_port: 18330 + # Update the cert_file and private_key paths to point to the + # Let's Encrypt certificate. + cert: /etc/letsencrypt/live/freeradius.yourdomain.com/fullchain.pem + private_key: /etc/letsencrypt/live/freeradius.yourdomain.com/privkey.pem + # If you choose to re-use the same certificate for both services, + # your configuration would look like this + # cert: /etc/letsencrypt/live/{{ inventory_hostname }}/fullchain.pem + # private_key: /etc/letsencrypt/live/{{ inventory_hostname }}/privkey.pem + tasks: + # Tasks to ensure the Let's Encrypt certificate can be read by the FreeRADIUS server. + # If you are using the same certificate for both services, you need to + # replace "freeradius.yourdomain.com" with "{{ inventory_hostname }}" + # in the following task. + - name: "Create a renewal hook for setting permissions on /etc/letsencrypt/live/freeradius.yourdomain.com" + copy: + content: | + #!/bin/bash + chown -R root:freerad /etc/letsencrypt/live/ /etc/letsencrypt/archive/ + chmod 0750 /etc/letsencrypt/live/ /etc/letsencrypt/archive/ + chmod -R 0640 /etc/letsencrypt/archive/freeradius.yourdomain.com/ + chmod 0750 /etc/letsencrypt/archive/freeradius.yourdomain.com/ + dest: /etc/letsencrypt/renewal-hooks/post/chown_freerad + owner: root + group: root + mode: '0700' + register: chown_freerad_result + - name: Change the ownership of the certificate files + when: chown_freerad_result.changed + command: /etc/letsencrypt/renewal-hooks/post/chown_freerad +``` + Configuring CORS Headers ------------------------ diff --git a/templates/freeradius/eap/eap.j2 b/templates/freeradius/eap/eap.j2 index ccd92506..38c6c83d 100644 --- a/templates/freeradius/eap/eap.j2 +++ b/templates/freeradius/eap/eap.j2 @@ -8,8 +8,8 @@ eap eap-org_{{ org.name }} { tls-config tls-common { # make sure to have a valid SSL certificate for production usage private_key_password = whatever - private_key_file = ${certdir}/server.pem - certificate_file = ${certdir}/server.pem + private_key_file = {{ org.private_key | default('${certdir}/server.pem') }} + certificate_file = {{ org.cert | default('${certdir}/server.pem') }} ca_file = ${cadir}/ca.pem dh_file = ${certdir}/dh ca_path = ${cadir}