mirror of
https://git.lapiole.org/dani/ansible-roles.git
synced 2025-07-27 00:05:44 +02:00
Update to 2021-12-01 19:13
This commit is contained in:
48
roles/radius_server/defaults/main.yml
Normal file
48
roles/radius_server/defaults/main.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
|
||||
rad_clients: []
|
||||
# rad_clients:
|
||||
# - name: ap-wifi
|
||||
# ip: 192.168.7.0/24
|
||||
# secret: p@ssw0rd
|
||||
# nas_type: other
|
||||
|
||||
rad_auth_port: 1812
|
||||
rad_acc_port: 1813
|
||||
rad_ports: [ "{{ rad_auth_port }}", "{{ rad_acc_port }}" ]
|
||||
rad_src_ip: []
|
||||
|
||||
# An optional password if the private key is protected
|
||||
# rad_tls_key_pass:
|
||||
|
||||
# The CA (full chain) to verify client's certificates
|
||||
# rad_tls_ca: |
|
||||
# ---- BEGIN CERTIFICATE ----
|
||||
# ---- END CERTIFICATE ----
|
||||
|
||||
# The certificate of the radius server
|
||||
# rad_tls_cert: |
|
||||
# ---- BEGIN CERTIFICATE ----
|
||||
# ---- END CERTIFICATE ----
|
||||
|
||||
# The private key of the radius server
|
||||
# rad_tls_key: |
|
||||
# -----BEGIN RSA PRIVATE KEY-----
|
||||
# -----END RSA PRIVATE KEY-----
|
||||
|
||||
# An optional CRL to check client's certificate against
|
||||
# Can either be a raw CRL in PEM format, or an http or https URL
|
||||
# where to fetch it
|
||||
# If undefined, no check will be performed, and revoked certificates will be accepted
|
||||
# rad_tls_crl:
|
||||
|
||||
# An email address to notify in case of CRL issue.
|
||||
# In case the CRL couldn't be fetched or is outdated, and rad_notify_crl is defined
|
||||
# the validation script will allow the authentication and notify the adress instead of failing
|
||||
# rad_notify_crl: admin@example.org
|
||||
|
||||
# The issuer of the clients certificate
|
||||
# This can be usefull if you have several intermediate CA
|
||||
# all signed by the same root CA, but only want to trust clients from
|
||||
# one of them
|
||||
# rad_tls_issuer: /C=FR/ST=Aquitaine/L=Bordeaux/O=Firewall Services/OU=Security/CN=wifi
|
97
roles/radius_server/files/rad_check_client_cert
Normal file
97
roles/radius_server/files/rad_check_client_cert
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use LWP::Simple qw($ua getstore);
|
||||
use Net::Domain qw(hostname hostfqdn hostdomain domainname);
|
||||
use Mail::Sendmail;
|
||||
|
||||
my $cert;
|
||||
my $ca = '/etc/radius/certs/ca.pem';
|
||||
my $crl;
|
||||
my $issuer;
|
||||
my $notify_crl;
|
||||
|
||||
GetOptions(
|
||||
'certificate=s' => \$cert,
|
||||
'cacert=s' => \$ca,
|
||||
'crl=s' => \$crl,
|
||||
'notify-crl=s' => \$notify_crl,
|
||||
'issuer=s' => \$issuer
|
||||
);
|
||||
|
||||
# Set a 5 sec timeout to fetch the CRL
|
||||
$ua->timeout(5);
|
||||
|
||||
my $crl_file;
|
||||
my $crl_age;
|
||||
if ($crl){
|
||||
if ($crl =~ m{^/} && -e $crl){
|
||||
$crl_file = $crl;
|
||||
$crl_age = time - ( stat($crl) )[9];
|
||||
} elsif ($crl =~ m{^https?://}) {
|
||||
$crl_age = 9999999;
|
||||
|
||||
if (-e '/run/radiusd/tls/crl.pem'){
|
||||
$crl_age = time - ( stat('/run/radiusd/tls/crl.pem') )[9];
|
||||
$crl_file = '/run/radiusd/tls/crl.pem';
|
||||
}
|
||||
|
||||
if (!-e '/run/radiusd/tls/crl.pem' or $crl_age > 900){
|
||||
my $code = getstore($crl, '/run/radiusd/tls/crl.pem');
|
||||
if ($code == 200){
|
||||
$crl_age = 0;
|
||||
$crl_file = '/run/radiusd/tls/crl.pem';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $crl and (not defined $crl_file or ($crl =~ m{https?://} and $crl_age > 7200))){
|
||||
if (defined $notify_crl){
|
||||
my %mail = (
|
||||
To => $notify_crl,
|
||||
From => 'radius@' . hostdomain(),
|
||||
Subject => 'CRL issue',
|
||||
Message => 'Authentication done with an outdated CRL'
|
||||
);
|
||||
sendmail(%mail);
|
||||
} else {
|
||||
die "CRL is too old or missing\n";
|
||||
}
|
||||
}
|
||||
|
||||
my $cmd = "openssl verify -trusted $ca -purpose sslclient";
|
||||
$cmd .= " -crl_check -CRLfile $crl_file" if (defined $crl_file);
|
||||
$cmd .= " $cert";
|
||||
my $ca_check = qx($cmd);
|
||||
if ($? != 0){
|
||||
print "openssl verify command returned non zero\n";
|
||||
print $ca_check;
|
||||
exit 1;
|
||||
}
|
||||
chomp($ca_check);
|
||||
if ($ca_check !~ m/^$cert:\s+OK$/){
|
||||
print "openssl failed to verify $cert against $ca\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $expire_check = qx(openssl x509 -in $cert -checkend 0);
|
||||
if ($? != 0 || $expire_check !~ m/^Certificate will not expire/){
|
||||
print "certificate is expired\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if ($issuer){
|
||||
my $issuer_check = qx(openssl x509 -in $cert -noout -issuer);
|
||||
chomp($issuer_check);
|
||||
$issuer_check =~ s/^issuer=\s*//;
|
||||
unless ($issuer_check eq $issuer){
|
||||
print "Certificate is signed by $issuer_check instead of $issuer\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
exit 0;
|
4
roles/radius_server/handlers/main.yml
Normal file
4
roles/radius_server/handlers/main.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
|
||||
- name: restart radiusd
|
||||
service: name=radiusd state=restarted
|
116
roles/radius_server/tasks/main.yml
Normal file
116
roles/radius_server/tasks/main.yml
Normal file
@@ -0,0 +1,116 @@
|
||||
---
|
||||
|
||||
- name: Install packages
|
||||
yum:
|
||||
name:
|
||||
- freeradius
|
||||
- freeradius-utils
|
||||
- perl-LWP-Protocol-https # For the check script to be able to fetch CRL on https URL
|
||||
- perl-Mail-Sendmail
|
||||
tags: radius
|
||||
|
||||
- name: Create configuration directories
|
||||
file: path=/etc/radius/{{ item }} state=directory group=radiusd mode=750
|
||||
with_items:
|
||||
- certs
|
||||
- modules
|
||||
tags: radius
|
||||
|
||||
- name: Create radiusd unit snippet dir
|
||||
file: path=/etc/systemd/system/radiusd.service.d/ state=directory
|
||||
tags: radius
|
||||
|
||||
- name: Remove obsolete systemd unit override
|
||||
file: path=/etc/systemd/system/radiusd.service state=absent
|
||||
register: rad_old_unit
|
||||
tags: radius
|
||||
|
||||
- name: Overwrite radiusd unit file
|
||||
copy:
|
||||
content: |
|
||||
[Service]
|
||||
ExecStartPre=
|
||||
ExecStartPre=-/bin/chown -R radiusd.radiusd /var/run/radiusd
|
||||
ExecStartPre=/usr/sbin/radiusd -C -d /etc/radius
|
||||
ExecStart=
|
||||
ExecStart=/usr/sbin/radiusd -d /etc/radius
|
||||
dest: /etc/systemd/system/radiusd.service.d/99-ansible.conf
|
||||
register: rad_unit
|
||||
notify: restart radiusd
|
||||
tags: radius
|
||||
|
||||
- name: Reload systemd
|
||||
systemd: daemon_reload=True
|
||||
when: rad_unit.changed or rad_old_unit.changed
|
||||
tags: radius
|
||||
|
||||
- name: Install client certificate checker script
|
||||
copy: src=rad_check_client_cert dest=/usr/local/bin/rad_check_client_cert mode=755
|
||||
tags: radius
|
||||
|
||||
- name: Deploy configuration
|
||||
template: src={{ item }}.j2 dest=/etc/radius/{{ item }} group=radiusd mode=640
|
||||
with_items:
|
||||
- radiusd.conf
|
||||
- clients.conf
|
||||
- modules/eap.conf
|
||||
- sites.conf
|
||||
notify: restart radiusd
|
||||
tags: radius
|
||||
|
||||
- name: Create DH param
|
||||
shell: /usr/bin/openssl dhparam -out /etc/radius/certs/dh.pem 2048
|
||||
args:
|
||||
creates: /etc/radius/certs/dh.pem
|
||||
notify: restart radiusd
|
||||
tags: radius
|
||||
|
||||
- name: Deploy certificates
|
||||
copy: content={{ item.content }} dest=/etc/radius/certs/{{ item.dest }} group=radiusd mode={{ item.mode | default(omit) }}
|
||||
with_items:
|
||||
- content: "{{ rad_tls_ca }}"
|
||||
dest: ca.pem
|
||||
- content: "{{ rad_tls_cert }}"
|
||||
dest: cert.pem
|
||||
- content: "{{ rad_tls_key }}"
|
||||
dest: key.pem
|
||||
mode: 640
|
||||
notify: restart radiusd
|
||||
no_log: True
|
||||
tags: radius
|
||||
|
||||
- name: Deploy CRL
|
||||
copy: content={{ rad_tls_crl }} dest=/etc/radiusd/certs/crl.pem
|
||||
when:
|
||||
- rad_tls_crl is defined
|
||||
- rad_tls_crl is not search('^https?://')
|
||||
tags: radius
|
||||
|
||||
- name: Deploy tmpfile fragment
|
||||
template: src=tmpfiles.conf dest=/etc/tmpfiles.d/radiusd.conf
|
||||
register: rad_tmpfiles
|
||||
tags: radius
|
||||
|
||||
- name: Create tmpfiles
|
||||
command: systemd-tmpfiles --create
|
||||
when: rad_tmpfiles.changed
|
||||
tags: radius
|
||||
|
||||
- name: Handle radius ports
|
||||
iptables_raw:
|
||||
name: radius_ports
|
||||
state: "{{ (rad_src_ip | length > 0) | ternary('present','absent') }}"
|
||||
rules: "-A INPUT -m state --state new -p udp -m multiport --dports {{ rad_ports | join(',') }} -s {{ rad_src_ip | join(',') }} -j ACCEPT"
|
||||
when: iptables_manage | default(True)
|
||||
tags: [firewall,radius]
|
||||
|
||||
# This is needed to allow the verification script to send email notification
|
||||
# when the CRL is too old
|
||||
- name: Configure SELinux
|
||||
seboolean: name=nis_enabled state=True persistent=True
|
||||
when: ansible_selinux.status == 'enabled'
|
||||
tags: radius
|
||||
|
||||
- name: Start and enable the service
|
||||
service: name=radiusd state=started enabled=True
|
||||
tags: radius
|
7
roles/radius_server/templates/clients.conf.j2
Normal file
7
roles/radius_server/templates/clients.conf.j2
Normal file
@@ -0,0 +1,7 @@
|
||||
{% for client in rad_clients %}
|
||||
client {{ client.name }} {
|
||||
ipaddr = {{ client.ip }}
|
||||
secret = {{ client.secret }}
|
||||
nas_type = {{ client.nas_type | default('other') }}
|
||||
}
|
||||
{% endfor %}
|
27
roles/radius_server/templates/modules/eap.conf.j2
Normal file
27
roles/radius_server/templates/modules/eap.conf.j2
Normal file
@@ -0,0 +1,27 @@
|
||||
eap {
|
||||
default_eap_type = tls
|
||||
tls-config tls-common {
|
||||
{% if rad_tls_key_pass is defined %}
|
||||
private_key_password = {{ rad_tls_key_pass }}
|
||||
{% endif %}
|
||||
private_key_file = /etc/radius/certs/key.pem
|
||||
certificate_file = /etc/radius/certs/cert.pem
|
||||
{% if rad_tls_ca is defined %}
|
||||
ca_file = /etc/radius/certs/ca.pem
|
||||
{% endif %}
|
||||
dh_file = /etc/radius/certs/dh.pem
|
||||
ca_path = /etc/radius/certs/
|
||||
ecdh_curve = "prime256v1"
|
||||
{% if rad_tls_issuert is defined %}
|
||||
check_cert_issuer = "{{ rad_tls_issuer }}"
|
||||
{% endif %}
|
||||
verify {
|
||||
tmpdir = /run/radiusd/tls
|
||||
client = "/usr/local/bin/rad_check_client_cert --cert %{TLS-Client-Cert-Filename}{% if rad_tls_crl is defined %} --crl {{ (rad_tls_crl is search ('https?://')) | ternary(rad_tls_crl,'/etc/radius/certs/crl.pem') }}{% endif %}{% if rad_tls_issuer is defined %} --issuer '{{ rad_tls_issuer }}'{% endif %}{% if rad_crl_notify is defined %} --notify-crl='{{ rad_crl_notify }}'{% endif %}"
|
||||
}
|
||||
}
|
||||
|
||||
tls {
|
||||
tls = tls-common
|
||||
}
|
||||
}
|
46
roles/radius_server/templates/radiusd.conf.j2
Normal file
46
roles/radius_server/templates/radiusd.conf.j2
Normal file
@@ -0,0 +1,46 @@
|
||||
prefix = /usr
|
||||
localstatedir = /var/lib/radiusd
|
||||
logdir = /var/log/radius
|
||||
run_dir = /run/radiusd
|
||||
correct_escapes = true
|
||||
max_request_time = 30
|
||||
cleanup_delay = 5
|
||||
max_requests = 16384
|
||||
hostname_lookups = no
|
||||
log {
|
||||
destination = syslog
|
||||
syslog_facility = daemon
|
||||
colourise = yes
|
||||
stripped_names = no
|
||||
auth = yes
|
||||
auth_badpass = no
|
||||
auth_goodpass = no
|
||||
}
|
||||
security {
|
||||
user = radiusd
|
||||
group = radiusd
|
||||
allow_core_dumps = no
|
||||
max_attributes = 200
|
||||
reject_delay = 1
|
||||
status_server = yes
|
||||
}
|
||||
proxy_requests = no
|
||||
|
||||
$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 modules/eap.conf
|
||||
}
|
||||
instantiate {
|
||||
}
|
||||
policy {
|
||||
}
|
||||
$INCLUDE sites.conf
|
21
roles/radius_server/templates/radiusd.service.j2
Normal file
21
roles/radius_server/templates/radiusd.service.j2
Normal file
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
Description=FreeRADIUS high performance RADIUS server.
|
||||
After=syslog.target network.target ipa.service dirsrv.target krb5kdc.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
PIDFile=/var/run/radiusd/radiusd.pid
|
||||
ExecStartPre=/usr/sbin/radiusd -C
|
||||
ExecStart=/usr/sbin/radiusd -f -d /etc/radius
|
||||
ExecReload=/usr/sbin/radiusd -C
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=on-failure
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
ProtectSystem=full
|
||||
ProtectHome=yes
|
||||
NoNewPrivileges=yes
|
||||
MemoryLimit=256M
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
31
roles/radius_server/templates/sites.conf.j2
Normal file
31
roles/radius_server/templates/sites.conf.j2
Normal file
@@ -0,0 +1,31 @@
|
||||
server site {
|
||||
listen {
|
||||
type = auth
|
||||
ipaddr = *
|
||||
port = {{ rad_auth_port }}
|
||||
limit {
|
||||
max_connections = 16
|
||||
lifetime = 0
|
||||
idle_timeout = 30
|
||||
}
|
||||
}
|
||||
|
||||
authorize {
|
||||
eap {
|
||||
ok = return
|
||||
}
|
||||
}
|
||||
|
||||
authenticate {
|
||||
eap
|
||||
}
|
||||
|
||||
session {
|
||||
}
|
||||
|
||||
post-auth {
|
||||
update {
|
||||
&reply: += &session-state:
|
||||
}
|
||||
}
|
||||
}
|
2
roles/radius_server/templates/tmpfiles.conf
Normal file
2
roles/radius_server/templates/tmpfiles.conf
Normal file
@@ -0,0 +1,2 @@
|
||||
d /run/radiusd 710 radiusd radiusd
|
||||
d /run/radiusd/tls 700 radiusd radiusd
|
Reference in New Issue
Block a user