Skip to content

Commit

Permalink
[feature] Allow to use custom certificates with FreeRADIUS EAP
Browse files Browse the repository at this point in the history
  • Loading branch information
pandafy committed May 16, 2024
1 parent 054faea commit c626fe1
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 4 deletions.
88 changes: 86 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -606,16 +606,24 @@ 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
radius_secret: demo-radius-token
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
Expand All @@ -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: "<privileged-users-to-renew-certs>"
certbot_certs:
- email: "<paste-your-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: "<paste-your-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
------------------------

Expand Down
4 changes: 2 additions & 2 deletions templates/freeradius/eap/eap.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down

0 comments on commit c626fe1

Please sign in to comment.