RadSecProxy: Difference between revisions

From Lolly's Wiki
Jump to navigationJump to search
 
(18 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Kategorie:Eduroam]]
[[Category:Eduroam]]
=RadSecProxy=
=RadSecProxy=
==Build==
==Build==
Line 5: Line 5:


In radsecproxy 1.6.9 and source from git on [[https://git.nordu.net/?p=radsecproxy.git;a=tree git.nordu.net]] this patch is not needed since [[https://git.nordu.net/?p=radsecproxy.git;a=commit;h=f3619bf65967255e1009fec42b28007b49e0f4e4 18.1.2017]].
In radsecproxy 1.6.9 and source from git on [[https://git.nordu.net/?p=radsecproxy.git;a=tree git.nordu.net]] this patch is not needed since [[https://git.nordu.net/?p=radsecproxy.git;a=commit;h=f3619bf65967255e1009fec42b28007b49e0f4e4 18.1.2017]].
<source lang=bash>
<syntaxhighlight lang=bash>
$ git clone https://git.nordu.net/radsecproxy.git
$ git clone https://git.nordu.net/radsecproxy.git
</source>
</syntaxhighlight>


[https://project.nordu.net/browse/RADSECPROXY-72 taken from here]  
[https://project.nordu.net/browse/RADSECPROXY-72 taken from here]  
<source lang=diff>
<syntaxhighlight lang=diff>
diff -rub radsecproxy-1.6.8/tcp.c radsecproxy-1.6.8_Ubuntu_16.04/tcp.c
diff -rub radsecproxy-1.6.8/tcp.c radsecproxy-1.6.8_Ubuntu_16.04/tcp.c
--- radsecproxy-1.6.8/tcp.c 2016-09-21 13:49:09.000000000 +0200
--- radsecproxy-1.6.8/tcp.c 2016-09-21 13:49:09.000000000 +0200
Line 35: Line 35:
     for (;;) {
     for (;;) {
  s = accept(*sp, (struct sockaddr *)&from, &fromlen);
  s = accept(*sp, (struct sockaddr *)&from, &fromlen);
</source>
</syntaxhighlight>


===Configure===
===Configure===
<source lang=bash>
<syntaxhighlight lang=bash>
$ ./configure --prefix=/opt/radsecproxy-1.6.8 --sysconfdir=/etc/radsec --with-ssl --enable-fticks  
$ ./configure --prefix=/opt/radsecproxy-1.6.8 --sysconfdir=/etc/radsec --with-ssl --enable-fticks  
$ make clean all && sudo make install
$ make clean all && sudo make install
</source>
</syntaxhighlight>


=== Another example: Version 1.7.2 from git ===
=== Another example: Version 1.7.2 from git ===
<source lang=bash>
<syntaxhighlight lang=bash>
$ mkdir radsecproxy && cd radsecproxy
$ mkdir radsecproxy && cd radsecproxy
$ git clone --single-branch --branch 1.7.2 https://github.com/radsecproxy/radsecproxy tags/1.7.2
$ git clone --single-branch --branch 1.7.2 https://github.com/radsecproxy/radsecproxy tags/1.7.2
Line 51: Line 51:
$ ./configure --prefix=/opt/radsecproxy-${PWD##*/} --sysconfdir=/etc/radsec --with-ssl
$ ./configure --prefix=/opt/radsecproxy-${PWD##*/} --sysconfdir=/etc/radsec --with-ssl
$ make clean all && sudo make install
$ make clean all && sudo make install
</source>
</syntaxhighlight>


==Config==
==Config==
===/etc/radsec/radsecproxy.conf===
===/etc/radsec/radsecproxy.conf===
<source lang=text>
<syntaxhighlight lang=text>
# Master config file for radsecproxy
# Master config file for radsecproxy


Line 66: Line 66:
#LogDestination file:///var/log/radsecproxy.log
#LogDestination file:///var/log/radsecproxy.log
LogDestination x-syslog:///LOG_DAEMON
LogDestination x-syslog:///LOG_DAEMON
LogThreadId on
LoopPrevention on
LoopPrevention on


Line 74: Line 76:
   CertificateKeyFile            /etc/radsec/cert/radsecproxy-key.pem
   CertificateKeyFile            /etc/radsec/cert/radsecproxy-key.pem
   CertificateKeyPassword        <PASSWORD>
   CertificateKeyPassword        <PASSWORD>
  TlsVersion TLS1_2
  CipherList TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:AES256-GCM-SHA384
}
}


Line 81: Line 86:
Include /etc/radsec/servers.conf
Include /etc/radsec/servers.conf
Include /etc/radsec/realms.conf  
Include /etc/radsec/realms.conf  
</source>
</syntaxhighlight>
 
===ca certificate in /etc/radsec/cert/ca===
For DFN users it is the TeleSec root certificate
 
====The destination file name is <hash of the certificate>.0====
<syntaxhighlight lang=text>
# openssl x509 -noout -hash -in /tmp/telesec.pem
1e09d511
# mv /tmp/telesec.pem /etc/radsec/cert/ca/1e09d511.0
</syntaxhighlight>
 
====/etc/radsec/cert/ca/1e09d511.0====
<syntaxhighlight lang=text>
subject= /C=DE/O=T-Systems Enterprise Services GmbH/OU=T-Systems Trust Center/CN=T-TeleSec GlobalRoot Class 2
-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
BSeOE6Fuwg==
-----END CERTIFICATE-----
</syntaxhighlight>


===/etc/radsec/rewrites.conf===
===/etc/radsec/rewrites.conf===
<source lang=text>
<syntaxhighlight lang=text>
## Empty for our setup
## Empty for our setup
</source>
</syntaxhighlight>
===/etc/radsec/clients.conf===
===/etc/radsec/clients.conf===
This matches our german top level radius (tlr) you have to customize it for other countries.
This matches our german top level radius (tlr) you have to customize it for other countries.
<source lang=text>
<syntaxhighlight lang=text>
client tlr1 {
#
## DFN
#
client tld1 {
host 193.174.75.134
host 193.174.75.134
type tls
type tls
Line 97: Line 143:
}
}


client tlr2 {
client tld2 {
host 193.174.75.138
host 193.174.75.138
type tls
type tls
certificatenamecheck off
certificatenamecheck off
matchCertificateAttribute CN:/^(radius2\.dfn|tld2\.eduroam)\.de$/
matchCertificateAttribute CN:/^(radius2\.dfn|tld2\.eduroam)\.de$/
}
client tld3 {
host 194.95.245.98
type tls
certificatenamecheck off
matchCertificateAttribute CN:/^tld3\.eduroam\.de$/
}
}


# Our WLAN Controller
# Our WLAN Controller
client wlc {
client wlc {
host 10.1.1.0/24
    host   10.1.1.0/24
type udp
    type   udp
        secret ****secret****
    secret ****secret****
}
}


Line 116: Line 169:
#  type TLS
#  type TLS
#}  
#}  
</source>
</syntaxhighlight>


===/etc/radsec/servers.conf===
===/etc/radsec/servers.conf===
<source lang=text>
<syntaxhighlight lang=text>
Server Our-EduroamRadiusAuth {
#
host <internal radius server>
## UDP Radius
        port 1812
#
#rewriteOut UserName
 
type udp
#Server Our-EduroamRadiusAuth {
secret ****secret****
# host <internal radius server>
# port 1812
# type udp
# secret ****secret****
#}
#Server Our-EduroamRadiusAcct {
# host <internal radius accounting server>
# port 1813
# type udp
# secret ****secret****
#}
 
#
## TLS Radius / RadSec
#
server freeradius-1 {
host <internal radius accounting server1>
type tls
certificatenamecheck off
matchCertificateAttribute CN:/^freeradius1\.domain\.tld$/
StatusServer on
secret ****secret****
}
}
Server Our-EduroamRadiusAcct {
 
host <internal radius accounting server>
server freeradius-2 {
        port 1813
host <internal radius accounting server2>
type udp
type tls
secret ****secret****
certificatenamecheck off
matchCertificateAttribute CN:/^freeradius2\.domain\.tld$/
StatusServer on
secret ****secret****
}
}
server tlr1 {
 
#
## DFN
#
server tld1 {
host 193.174.75.134
host 193.174.75.134
type tls
type tls
Line 140: Line 221:
StatusServer on
StatusServer on
}
}
server tlr2 {
server tld2 {
host 193.174.75.138
host 193.174.75.138
type tls
type tls
Line 147: Line 228:
StatusServer on
StatusServer on
}
}
</source>
server tld3 {
host 194.95.245.98
type tls
certificatenamecheck off
matchCertificateAttribute CN:/^tld3\.eduroam\.de$/
StatusServer on
}
</syntaxhighlight>
 
===/etc/radsec/realms.conf===
===/etc/radsec/realms.conf===
<source lang=text>
<syntaxhighlight lang=text>


# Our domain domain.tld
# Our domain domain.tld
realm /(eduroam|anonymous)@domain\.tld$/ {
realm /(eduroam|anonymous)@domain\.tld$/ {
   server freeradius-1
   server freeradius-1
   server freeradius-2
   server freeradius-2
   accountingServer freeradius-1
   accountingServer freeradius-1
   accountingServer freeradius-2
   accountingServer freeradius-2
Line 215: Line 304:
   accountingserver tlr2
   accountingserver tlr2
}
}
</source>
</syntaxhighlight>


===/etc/radsec/cert/radsecproxy.pem===
===/etc/radsec/cert/radsecproxy.pem===
<source lang=text>
<syntaxhighlight lang=text>
subject=/CN=radsecproxy.domain.tld/OU=bla/O=bli/L=Hamburg/ST=Hamburg/C=DE
subject=/CN=radsecproxy.domain.tld/OU=bla/O=bli/L=Hamburg/ST=Hamburg/C=DE
-----BEGIN CERTIFICATE-----
-----BEGIN CERTIFICATE-----
Line 224: Line 313:
-----END CERTIFICATE-----
-----END CERTIFICATE-----
And now the whole cerstificate chain...
And now the whole cerstificate chain...
</source>
</syntaxhighlight>


==Run the daemon==
==Run the daemon==
Line 234: Line 323:


====User====
====User====
<source lang=bash>
<syntaxhighlight lang=bash>
# addgroup -g 2083 radsecproxy
# addgroup -g 2083 radsecproxy
# useradd  -u 2083 -g nogroup -s /bin/false -h /nonexistent
# useradd  -u 2083 -g nogroup -s /bin/false -h /nonexistent
</source>
</syntaxhighlight>
====Permissions====
====Permissions====
<source lang=bash>
<syntaxhighlight lang=bash>
# chown -R root:radsecproxy /etc/radsec
# chown -R root:radsecproxy /etc/radsec
# find /etc/radsec -type d -exec chmod 0750 {} \;
# find /etc/radsec -type d -exec chmod 0750 {} \;
# find /etc/radsec -type f -exec chmod 0640 {} \;
# find /etc/radsec -type f -exec chmod 0640 {} \;
</source>
</syntaxhighlight>


====systemd unit file====
====systemd unit file====


<source lang=bash>
<syntaxhighlight lang=bash>
# systemctl cat radsecproxy.service  
# systemctl cat radsecproxy.service  
</source>
</syntaxhighlight>
<source lang=ini>
<syntaxhighlight lang=ini>
[Unit]
[Unit]
Description=radsecproxy
Description=radsecproxy
Line 273: Line 362:
[Install]
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target
</source>
</syntaxhighlight>


Put this to /lib/systemd/system/radsecproxy.service and do:
Put this to /lib/systemd/system/radsecproxy.service and do:
Line 281: Line 370:


===Testing===
===Testing===
  $ openssl s_client -connect <IP>:2083 -showcerts
 
Check on the server if the radsecproxy is listening:
<syntaxhighlight lang=bash>
# lsof -Pni TCP:2083 -s TCP:Listen
COMMAND    PID        USER  FD  TYPE DEVICE SIZE/OFF NODE NAME
radsecpro 1344 radsecproxy    9u  IPv4  22751      0t0 TCP <server ip>:2083 (LISTEN)
</syntaxhighlight>


===Certificate Enddate===
===Certificate Enddate===
<SyntaxHighlight lang=bash>
  $ openssl s_client -connect <IP>:2083 -tls1 -no_ssl2 -no_ssl3 -showcerts 2>/dev/null | openssl x509 -enddate -noout
  $ openssl s_client -connect <IP>:2083 -tls1 -no_ssl2 -no_ssl3 -showcerts 2>/dev/null | openssl x509 -enddate -noout
notAfter=Oct  9 12:13:17 2020 GMT
notAfter=Oct  9 12:13:17 2020 GMT
</SyntaxHighlight>
For this to work it is necessary, that you have configured a client that matches the host where you ask from:
<pre>
client openssl_check_radsec {
        host    a.b.c.d
        type    tls
        secret  dummy_for_openssl
}
</pre>
if not you will see something like this in the radsecproxy log:
<pre>
Jan 12 14:53:48 radsecproxy-1 radsecproxy[1359]: (305626) tlsservernew: ignoring request, no matching TLS client for a.b.c.d
</pre>
and your openssl just will show:
<SyntaxHighlight lang=bash>
$ openssl s_client -showcerts -connect a.b.c.d:2083
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 283 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
</SyntaxHighlight>
==Problems & Solutions==
===freeradius: systemd[1]: freeradius.service: Main process exited, code=killed, status=11/SEGV===
If you see something like this at you connected freeradius servers, check if you got the file from a windows user and see if it is in DOS format like this (use vi not less):
<pre>
-----BEGIN CERTIFICATE-----
MIIHszCCBZugAwIBAgIMKX2RveVddPE7s2KGMA0GCSqGSIb3DQEBCwUAMHYxCzAJ^M
BgNVBAYTAkRFMUUwQwYDVQQKDDxWZXJlaW4genVyIEZvZXJkZXJ1bmcgZWluZXMg^M
RGV1dHNjaGVuIEZvcnNjaHVuZ3NuZXR6ZXMgZS4gVi4xIDAeBgNVBAMMF2VkdXJv^M
...
</pre>
You can use unix2dos to convert it to unix format.
Yes... that the radsecproxy does not convert it is ugly... but that's life.

Latest revision as of 15:22, 12 January 2024

RadSecProxy

Build

Patch for radsecproxy-1.6.8 on Ubuntu 16.04

In radsecproxy 1.6.9 and source from git on [git.nordu.net] this patch is not needed since [18.1.2017].

$ git clone https://git.nordu.net/radsecproxy.git

taken from here

diff -rub radsecproxy-1.6.8/tcp.c radsecproxy-1.6.8_Ubuntu_16.04/tcp.c
--- radsecproxy-1.6.8/tcp.c	2016-09-21 13:49:09.000000000 +0200
+++ radsecproxy-1.6.8_Ubuntu_16.04/tcp.c	2017-07-13 16:35:52.414151832 +0200
@@ -353,7 +353,7 @@
     struct sockaddr_storage from;
     socklen_t fromlen = sizeof(from);
 
-    listen(*sp, 0);
+    listen(*sp, 16);
 
     for (;;) {
 	s = accept(*sp, (struct sockaddr *)&from, &fromlen);
diff -rub radsecproxy-1.6.8/tls.c radsecproxy-1.6.8_Ubuntu_16.04/tls.c
--- radsecproxy-1.6.8/tls.c	2016-09-21 13:49:09.000000000 +0200
+++ radsecproxy-1.6.8_Ubuntu_16.04/tls.c	2017-07-13 16:36:22.678166655 +0200
@@ -467,7 +467,7 @@
     struct sockaddr_storage from;
     socklen_t fromlen = sizeof(from);
 
-    listen(*sp, 0);
+    listen(*sp, 16);
 
     for (;;) {
 	s = accept(*sp, (struct sockaddr *)&from, &fromlen);

Configure

$ ./configure --prefix=/opt/radsecproxy-1.6.8 --sysconfdir=/etc/radsec --with-ssl --enable-fticks 
$ make clean all && sudo make install

Another example: Version 1.7.2 from git

$ mkdir radsecproxy && cd radsecproxy
$ git clone --single-branch --branch 1.7.2 https://github.com/radsecproxy/radsecproxy tags/1.7.2
$ cd tags/1.7.2
$ ./autogen.sh
$ ./configure --prefix=/opt/radsecproxy-${PWD##*/} --sysconfdir=/etc/radsec --with-ssl
$ make clean all && sudo make install

Config

/etc/radsec/radsecproxy.conf

# Master config file for radsecproxy

IPv4Only		on
listenUDP		<IP>:1812
listenUDP		<IP>:1813
listenTLS		<IP>:2083

LogLevel		5 # For testing later reduce to 3
#LogDestination		file:///var/log/radsecproxy.log
LogDestination		x-syslog:///LOG_DAEMON
LogThreadId		on

LoopPrevention		on

######## TLS section
tls default {
  CACertificatePath             /etc/radsec/cert/ca
  CertificateFile               /etc/radsec/cert/radsecproxy-cert.pem
  CertificateKeyFile            /etc/radsec/cert/radsecproxy-key.pem
  CertificateKeyPassword        <PASSWORD>

  TlsVersion			TLS1_2
  CipherList			TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:AES256-GCM-SHA384
}


Include /etc/radsec/rewrites.conf
Include /etc/radsec/clients.conf
Include /etc/radsec/servers.conf
Include /etc/radsec/realms.conf

ca certificate in /etc/radsec/cert/ca

For DFN users it is the TeleSec root certificate

The destination file name is <hash of the certificate>.0

# openssl x509 -noout -hash -in /tmp/telesec.pem 
1e09d511
# mv /tmp/telesec.pem /etc/radsec/cert/ca/1e09d511.0

/etc/radsec/cert/ca/1e09d511.0

subject= /C=DE/O=T-Systems Enterprise Services GmbH/OU=T-Systems Trust Center/CN=T-TeleSec GlobalRoot Class 2
-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
BSeOE6Fuwg==
-----END CERTIFICATE-----

/etc/radsec/rewrites.conf

## Empty for our setup

/etc/radsec/clients.conf

This matches our german top level radius (tlr) you have to customize it for other countries.

#
## DFN
#
client tld1 {
	host	193.174.75.134
	type	tls
        certificatenamecheck		off
        matchCertificateAttribute	CN:/^(radius1\.dfn|tld1\.eduroam)\.de$/
}

client tld2 {
	host	193.174.75.138
	type	tls
	certificatenamecheck		off
	matchCertificateAttribute	CN:/^(radius2\.dfn|tld2\.eduroam)\.de$/
}

client tld3 {
	host	194.95.245.98
	type	tls
	certificatenamecheck		off
	matchCertificateAttribute	CN:/^tld3\.eduroam\.de$/
}

# Our WLAN Controller
client wlc {
    host    10.1.1.0/24
    type    udp
    secret  ****secret****
}


#client anyIP4TLS {
#  host 0.0.0.0/0
#  type TLS
#}

/etc/radsec/servers.conf

#
## UDP Radius
#

#Server Our-EduroamRadiusAuth {
#	host		<internal radius server>
#	port		1812
#	type		udp
#	secret		****secret****
#}
#Server Our-EduroamRadiusAcct {
#	host		<internal radius accounting server>
#	port		1813
#	type		udp
#	secret		****secret****
#}

#
## TLS Radius / RadSec
#
server freeradius-1 {
	host				<internal radius accounting server1>
	type				tls
	certificatenamecheck		off
	matchCertificateAttribute	CN:/^freeradius1\.domain\.tld$/
	StatusServer			on
	secret				****secret****
}

server freeradius-2 {
	host				<internal radius accounting server2>
	type				tls
	certificatenamecheck		off
	matchCertificateAttribute	CN:/^freeradius2\.domain\.tld$/
	StatusServer			on
	secret				****secret****
}

#
## DFN
#
server tld1 {
	host				193.174.75.134
	type				tls
	certificatenamecheck		off
	matchCertificateAttribute	CN:/^(radius1\.dfn|tld1\.eduroam)\.de$/     
	StatusServer			on
}
server tld2 {
	host				193.174.75.138
	type				tls
	certificatenamecheck		off
	matchCertificateAttribute	CN:/^(radius2\.dfn|tld2\.eduroam)\.de$/
	StatusServer			on
}
server tld3 {
	host				194.95.245.98
	type				tls
	certificatenamecheck		off
	matchCertificateAttribute	CN:/^tld3\.eduroam\.de$/
	StatusServer			on
}

/etc/radsec/realms.conf

# Our domain domain.tld
realm /(eduroam|anonymous)@domain\.tld$/ {
  server			freeradius-1
  server			freeradius-2
  accountingServer	freeradius-1
  accountingServer	freeradius-2
}

# If the anonymous user has not been matched above, fail
# So users that use their real identity fail, too. Force anonymous!
realm /@domain\.tld$ {
  replymessage "Access rejected, wrong anonymous identity. Use eduroam@domain.tld as anonymous identity."
  accountingresponse on
}

# Other domain of our site not used for eduroam
realm /@wrong-domain\.tld$/ {
  replymessage "Misconfigured client: Use domain.tld as domain instead."
  accountingresponse on
}

# Default realm of some clients. Do not send to top level radius servers.
realm /@.*\.3gppnetwork\.org$/ {
  replymessage "Misconfigured client."
  accountingresponse on
}

# Default realm of some clients. Do not send to top level radius servers.
realm /myabc\.com$/ {
  replymessage "Misconfigured client: default realm of Intel PRO/Wireless supplicant! Rejected by us."
  accountingresponse on
}

# Empty realm. Do not send to top level radius servers.
realm /^$/ {
  replymessage "Misconfigured client: empty realm! Rejected by us."
  accountingresponse on
}

# Typo in realm. Realm without any dot in it. Do not send to top level radius servers.
realm /@[^\.]+$/ {
  replymessage "Misconfigured client: Typo in realm - No dot in realm ! Rejected by us."
  accountingresponse on
}

# Typo in realm. Realm without double dot in it. Do not send to top level radius servers.
realm /@.*\.\..*$/ {
  replymessage "Misconfigured client: Typo in realm - .. ! Rejected by us."
  accountingresponse on
}

# Typo in realm. Realm without space in it. Do not send to top level radius servers.
realm /@.*\s+.*$/ {
  replymessage "Misconfigured client: Typo in realm - Don't use spaces in your realm! Rejected by us."
  accountingresponse on
}

# All other realms -> Eduroam toplevel servers
realm * {
  server tlr1
  server tlr2
  accountingserver tlr1
  accountingserver tlr2
}

/etc/radsec/cert/radsecproxy.pem

subject=/CN=radsecproxy.domain.tld/OU=bla/O=bli/L=Hamburg/ST=Hamburg/C=DE
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
And now the whole cerstificate chain...

Run the daemon

Security

There is no need to run radsecproxy as root. But you need write access to the log or use syslog.

The config, certificate and key is not readable by the user (nogroup) but by the group radsecproxy where the porocess lives in (see systemd unit file radsecproxy.service).

User

# addgroup -g 2083 radsecproxy
# useradd  -u 2083 -g nogroup -s /bin/false -h /nonexistent

Permissions

# chown -R root:radsecproxy /etc/radsec
# find /etc/radsec -type d -exec chmod 0750 {} \;
# find /etc/radsec -type f -exec chmod 0640 {} \;

systemd unit file

# systemctl cat radsecproxy.service
[Unit]
Description=radsecproxy
ConditionPathExists=/etc/radsec/radsecproxy.conf
After=network.target
Documentation=man:radsecproxy(1)

[Service]
Type=forking
User=radsecproxy
Group=radsecproxy
RuntimeDirectory=radsecproxy
RuntimeDirectoryMode=0700
PrivateTmp=yes
InaccessibleDirectories=/var
ReadOnlyDirectories=/etc
ReadOnlyDirectories=/lib
ReadOnlyDirectories=/usr
ExecStart=/opt/radsecproxy/sbin/radsecproxy -i /run/radsecproxy/radsecproxy.pid
PIDFile=/run/radsecproxy/radsecproxy.pid

[Install]
WantedBy=multi-user.target

Put this to /lib/systemd/system/radsecproxy.service and do:

# systemctl daemon-reload
# systemctl enable radsecproxy.service
# systemctl start radsecproxy.service

Testing

Check on the server if the radsecproxy is listening:

# lsof -Pni TCP:2083 -s TCP:Listen
COMMAND    PID        USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
radsecpro 1344 radsecproxy    9u  IPv4  22751      0t0  TCP <server ip>:2083 (LISTEN)

Certificate Enddate

 $ openssl s_client -connect <IP>:2083 -tls1 -no_ssl2 -no_ssl3 -showcerts 2>/dev/null | openssl x509 -enddate -noout
notAfter=Oct  9 12:13:17 2020 GMT

For this to work it is necessary, that you have configured a client that matches the host where you ask from:

client openssl_check_radsec {
        host    a.b.c.d
        type    tls
        secret  dummy_for_openssl
}

if not you will see something like this in the radsecproxy log:

Jan 12 14:53:48 radsecproxy-1 radsecproxy[1359]: (305626) tlsservernew: ignoring request, no matching TLS client for a.b.c.d

and your openssl just will show:

$ openssl s_client -showcerts -connect a.b.c.d:2083
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 283 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

Problems & Solutions

freeradius: systemd[1]: freeradius.service: Main process exited, code=killed, status=11/SEGV

If you see something like this at you connected freeradius servers, check if you got the file from a windows user and see if it is in DOS format like this (use vi not less):

-----BEGIN CERTIFICATE-----
MIIHszCCBZugAwIBAgIMKX2RveVddPE7s2KGMA0GCSqGSIb3DQEBCwUAMHYxCzAJ^M
BgNVBAYTAkRFMUUwQwYDVQQKDDxWZXJlaW4genVyIEZvZXJkZXJ1bmcgZWluZXMg^M
RGV1dHNjaGVuIEZvcnNjaHVuZ3NuZXR6ZXMgZS4gVi4xIDAeBgNVBAMMF2VkdXJv^M
...

You can use unix2dos to convert it to unix format. Yes... that the radsecproxy does not convert it is ugly... but that's life.