radsecproxy.conf(5)
π radsecproxy.conf β the manual page, but make it make sense π
okay bestie, so this is radsecproxy.conf(5) β the whole entire tea on how to write the config file for radsecproxy. it's long, it comes in parts, and we're doing part one right now. no sign-off, we're just getting started. grab a snack. π
β¨ NAME β¨
radsecproxy.conf β the configuration file for the radsec proxy, like, the whole vibe document π
πΈ DESCRIPTION πΈ
so when the proxy server starts up, here's the order of operations: first it peeks at the command line arguments, and then it reads the configuration file. normally radsecproxy just reads /etc/radsecproxy.conf, like, that's the default, no cap. but if you wanna be different, the command line -c option lets you point it at an alternate file instead (go check radsecproxy(8) for the deets on that one).
if the config file can't be found? the proxy exits with an error message. periodt, it's not playing. also important: there's an include facility, so any config file can include other config files. and if there are configuration errors? yeah, the proxy exits on those too. π
π CONFIGURATION SYNTAX π
okay so when the configuration file gets processed, whitespace (spaces and tabs) is generally ignored. for every line, leading and trailing whitespace gets ignored. a line is fully ignored if it's:
- empty
- only whitespace
- or if the first non-whitespace character is a
#
the configuration is generally case insensitive, BUT in some cases the option values (more on those below) are not case insensitive. so like, read the fine print. π
two types of config structures, pick your fighter β¨
1. the simple line π«Ά
the first and simplest type is just lines in the format option value. so: an option name (full list of valid options is below), then whitespace (at least one space or tab character), then a value.
heads up bestie: if the value contains whitespace, you gotta quote it using""or''. any whitespace in front of the option or after the value just gets ignored.
2. the block π
the other type of structure is a block. a block spans at least two lines and looks like this:
blocktype name {
option value
option value
...
}
so: some blocktype (list of the different block types is below), and then inside the braces you've got zero or more lines that each follow that option value format we just talked about. different block types have different rules for which options can go in them, and those are all listed below. the rules about whitespace, comments and quotes are the same as above. so you can absolutely do stuff like:
blocktype name {
# option value
option "value with space"
...
}
hex escapes, because of course π§
option value characters can also be written in hex for options that need a string type value. here's the deal:
- a
%character followed by two hexadecimal digits gets replaced by its byte value. - longer hex strings can be escaped with
%%. in that case, all the following hexadecimal digit pairs get replaced by byte values until the first non-hex character shows up. - if a
%is used without two following hexadecimal digits, then the%and the following characters are used as written. - if you wanna write a
%and not trigger this decoding, you can of course just write%in hex, i.e.%25.
watch out: since %00 would terminate a string, this value is not converted in most cases β except when used with rewrite statements or secrets.
regex, iykyk π₯
some options allow or require the use of regular expressions, denoted as regex. the POSIX extended RE system is used, so go look at re_format(7) if you need it.
the special one π
there's one special option that can be used both as a basic option and inside all blocks. that's the option Include, where the value specifies files to be included. the value can be a single file, or it can use normal shell globbing to specify multiple files, like:
include /etc/radsecproxy.conf.d/*.conf
the files get sorted alphabetically. included files are read in the order they're specified, and when you reach the end of a file, the next file is read. when you reach the end of the last included file, the proxy returns to read the next line following the Include option. and yes β included files may again include other files. it's includes all the way down. π¦
β¨ BASIC OPTIONS β¨
okay bestie, here's where the actual knobs live π these are the top-level options you can drop straight into the config file. blocktypes and the options that live inside blocks? those come later, don't worry.
quick vibe check before we start:
- none of these are required. like, at all. in lots of real setups you won't need most of them.
- specify each one at most once. what happens if you don't? undefined behaviour π that's the manpage's words, not mine, but fr fr don't test it.
PidFilefile β tells the proxy where to write its process id (PID). heads up though: the-icommand line option overrides this. and there's no default value forPidFile, so if you want one, you gotta say so yourself.LogLevel1-5 β sets the debug level, and it has to be1,2,3,4or5.1logs only the serious errors,5logs everything. the default is2, which gives you errors, warnings and a few informational messages. also! the command line option-doverrides this whole thing, so watch out for that.LogDestination(file|syslog) β where do the log messages go? by default they go to syslog with facilityLOG_DAEMON. this option lets you pick a different syslog facility, or say "actually, write to this file instead of syslog." the value has to be either a file URL likefile:///path/to/your/logfile.log, or a syslog URL with this syntax:x-syslog:///FACILITY, where FACILITY has to be one ofLOG_DAEMON,LOG_MAIL,LOG_USER,LOG_LOCAL0,LOG_LOCAL1,LOG_LOCAL2,LOG_LOCAL3,LOG_LOCAL4,LOG_LOCAL5,LOG_LOCAL6orLOG_LOCAL7. you can leave the facility out of the URL to mean "use the default facility", but ngl that's not very useful since the default facility is literally the default log destination already π also note: this option is ignored if-fis specified on the command line.LogThreadId(on|off) β set this toonand the thread-id shows up in your log messages. super useful for debugging π§LogFullUsername(on|off) β set this tooffand only the realm gets logged in Access-Accept/Reject log messages. that's the privacy-friendly setting, bestie π«ΆLogMACopt β controls if and how Calling-Station-Id (aka the user's Ethernet MAC address) gets logged. it can be one ofStatic,Original,VendorHashed,VendorKeyHashed,FullyHashedorFullyKeyHashed. the default value forLogMACisOriginal.
see radsecproxy.conf-example for the details.
LogKeykey β the key used when producing HMAC's, which happens as an effect of settingVendorKeyHashedorFullyKeyHashedfor theLogMACoption. πFTicksReportingfticks β turns F-Ticks logging on. can be set toNone,BasicorFull, and its default value isNone. ifFTicksReportingis set to anything other thanNone, note that the default value forFTicksMACneedsFTicksKeyto be set. and for F-Ticks records to actually be generated, at least theFticksVISCOUNTRYoption has to be set on the originating client.
see radsecproxy.conf-example for the details.
FTicksMACopt β does the same job asLogMAC, but for FTicks. the default forFTicksMACisVendorKeyHashed, which needsFTicksKeyto be set.
before you pick any ofOriginal,FullyHashedorVendorHashed, please sit with the implications for user privacy when MAC addresses are collected. how are those logs gonna be stored, transferred and accessed? π think about it.
FTicksKeykey β same job asLogKey, but for Fticks.FTicksSyslogFacilitysyslog β lets you point F-Ticks messages at a dedicated syslog facility, which makes filtering them way easier β¨ if you don't give aFTicksSyslogFacilityoption, F-Ticks messages get written wherever theLogDestinationoption says.
F-Ticks messages are always logged using the log level LOG_DEBUG. and heads up: specifying a file in FTicksSyslogFacility (using the file:/// prefix) is not supported.
FTicksPrefixprefix β sets the prefix printed in F-Ticks messages, which is what lets you use F-Ticks messages in non-eduroam environments π if you don't give aFTicksPrefixoption, it defaults to the prefix used for eduroam,F-TICKS/eduroam/1.0.ListenUDP,ListenTCP,ListenTLS,ListenDTLS(address|*)[:port] β listen for the address and port for the respective protocol. normally the proxy listens to the standard ports if it's configured to handle clients with the respective protocol. the default ports are 1812 for UDP and TCP and 2083 for TLS and DTLS. on most systems it does this for all of the system's IP addresses (both IPv4 and IPv6) β though on some systems it may respond to only IPv4 or only IPv6, which is giving "it depends on your system" energy π to specify an alternate port, use a value on the form*:portwhere port is any valid port number. want a specific address too? you can do e.g.192.168.1.1:1812or[2001:db8::1]:1812. you can omit the port if you want the default one. note that you must use brackets around the IPv6 address β no brackets, no vibes. these options may be specified multiple times to listen to multiple addresses and/or ports for each protocol πSourceUDP,SourceTCP,SourceTLS,SourceDTLS(address|*)[:port] β specify the source address and/or source port the proxy will use when connecting to clients to send messages (e.g. Access Request). same syntax as forListen..., so everything above still applies πTTLAttribute(attr|vendor:attr) β changes the default TTL attribute. only change this if you know what you are doing, bestie, i'm serious π the syntax is either a numerical value denoting the TTL attribute, or two numerical values separated by column, specifying a vendor attribute.AddTTL1-255 β if a TTL attribute is present, the proxy decrements the value and discards the message if it hits zero. normally, if no TTL attribute is present, the proxy does nothing at all. but if you use theAddTTLoption with a value1-255, then when forwarding a message with no TTL attribute, the proxy will add one with the specified value β¨ note that this option can also be specified for a client/server, which will override this setting when forwarding a message to that client/server.LoopPrevention(on|off) β when this is enabled (on), a request will never be sent to a server named the same as the client it was received from. i.e., the names of the client block and the server block are compared. note that this only gives limited protection against loops. it can be used as a basic option and inside server blocks, where it overrides the basic setting.IPv4Only,IPv6Only(on|off) β enablingIPv4OnlyorIPv6Only(on) makes radsecproxy resolve DNS names to the corresponding address family only, and not the other. this is done for both clients and servers. at most one ofIPv4OnlyandIPv6Onlycan be enabled β pick a lane π note that this can be overridden in client and server blocks, see below.SNI(on|off) β Server Name Indication (SNI) is an extension to the TLS protocol. it lets a client indicate which hostname it's trying to connect to at the start of the TLS handshake π¦ enabling this will use the extension for all TLS and DTLS servers which specify a hostname (not an IP address). this can be overridden in server blocks, see below.VerifyEAP(on|off) β a radius proxy is mostly agnostic to the contents of the attributes within a radius message, and forwards them as-is. but wrong EAP attributes can lead to a bad user experience π so radsecproxy checks the content length of the contained EAP message and denies the access-request if it doesn't match the attribute length. in case malformatted EAP attributes are intentional, this behaviour can be disabled (defaulton).Includefile β okay this one is not a normal configuration option; it can be specified multiple times. it can be used both as a basic option and inside blocks. for the full description, see the configuration syntax section above. π
π§± BLOCKS π§±
there are five types of blocks, bestie: client, server, realm, tls and rewrite.
- at least one instance of each of
clientandrealmis required for the proxy to do anything useful, and it will exit if none are configured. like, it just leaves π - the
tlsblock is required if at least one TLS/DTLS client or server is configured. - note that there can be multiple blocks for each type.
- for each type, the block names should be unique. the behaviour with multiple occurrences of the same name for the same block type is undefined.
also, some block option values may reference a block by name β in which case the block name must be previously defined. hence the order of the blocks may be significant π so yeah, arrange them thoughtfully, not chaotically.
β¨ CLIENT BLOCK β¨
okay bestie, so this block is literally the whole vibe for one client. it tells the proxy who a client is and what rules apply to them. the name of the block (with one tiny exception, we'll get to it) has to be either the client's IP address (v4 or v6), an IP prefix like IpAddress/PrefixLength (v4 or v6), or a domain name (FQDN). the way an FQDN gets resolved into an IP can be influenced by the IPv4Only and IPv6Only options. and heads up: literal IPv6 addresses need to be wrapped in brackets. π
client (name|fqdn|(address[/length])) {
...
}
if you give a domain name, it gets resolved immediately to all the addresses linked to that name, and the proxy will not care about any later DNS changes. so no DNS dependency after startup. but if the name can't be resolved, startup just fails. periodt. π
when a client later sends a request, the proxy looks at the source IP and goes through all the addresses of each configured client (in the order they're defined) to figure out which one this is. when you use the IpAddress/PrefixLength form, you might mask clients defined later, and those will never ever be matched. π«Ά
for TLS/DTLS, the client name must match the FQDN or IP address in the client certificate (CN or SubectAltName:DNS or SubjectAltName:IP respectively) and any MatchCertificateAttribute to be positively identified. note that no FQDN/IP is checked when using an IP prefix. if you have overlapping clients (see the section above), they'll be searched for positive identification, but only among clients referencing the same tls block (selected by the first matching IP address or prefix).
the allowed options in a client block are:
Host (fqdn|(address[/length]))β instead of specifying the FQDN or address in the block name, you can use thishostoption. then the value ofhostis used as described above, while the block name is just a cute descriptive name for the admin. you can usehostmultiple times, and it can mix addresses, FQDNs and prefixes. β¨IPv4Only (on|off)β enabling this (on) makes radsecproxy resolve DNS names to IPv4 only, not IPv6. at most one ofIPv4OnlyandIPv6Onlycan be enabled. this overrides the global option for this client.IPv6Only (on|off)β enabling this (on) makes radsecproxy resolve DNS names to IPv6 only, not IPv4. at most one ofIPv4OnlyandIPv6Onlycan be enabled. this overrides the global option for this client.Type typeβ specify the type (protocol) of the client. available options areUDP,TCP,TLSandDTLS. while TLS and DTLS are secure, encrypted transports, UDP and TCP are not. Radius uses the shared secret only to encrypt certain critical attributes, but most of the Radius data is sent in clear. protection against manipulation is only provided if the client uses theMessage-Authenticatorattribute. so UDP and TCP should only be used in secured networks or when an underlying secure transport like IPSEC or MACSEC is used. UDP and TCP SHOULD NOT be used across the internet. π¨Secret secretβ usesecretas the shared RADIUS key with this client. if the secret contains whitespace, the value must be quoted. this option is optional for TLS/DTLS and if omitted will default to"radsec". (note that using a secret other than"radsec"for TLS is a violation of the standard (RFC 6614) and that the proposed standard for DTLS stipulates that the secret must be"radius/dtls".) πTLS tlsβ for a TLS/DTLS client you may also specify thetlsoption. the value must be the name of a previously defined TLS block. if this option is not specified, the TLS block with the namedefaultClientordefaultwill be used if defined (in that order). if the specified TLS block name does not exist, or the option is not specified and none of the defaults exist, the proxy will exit with an error. πServerName servernameβ useservernamefor the certificate name check instead of host or the client block name (e.g. if host uses static IP address).CertificateNameCheck (on|off)β for a TLS/DTLS client, disable the default behaviour of matching CN or SubjectAltName against the specified hostname or IP address.MatchCertificateAttributeβ perform additional validation of certificate attributes. currently matching of CN and SubjectAltName types URI, DNS, IP, rID, and otherName is supported. if specified multiple times, all terms must match for the certificate to be considered valid. the supported forms are:
MatchCertificateAttribute CN:/regexp/
MatchCertificateAttribute SubjectAltName:DNS:/regexp/
MatchCertificateAttribute SubjectAltName:URI:/regexp/
MatchCertificateAttribute SubjectAltName:IP:address
MatchCertificateAttribute SubjectAltName:rID:oid
MatchCertificateAttribute SubjectAltName:otherName:oid:/regexp/
PSKkey keyβ for TLS, use TLS-PSK (pre shared key) instead of certificate based authentication. if specified,PSKidentitymust also be provided. the key must be at least 16 bytes long. to provide the key in hex, use the%%escaping (see CONFIGURATION SYNTAX). in addition to the psk, peers must also agree on the key derivation hash function. for this, the server simply uses the hash funciton of the negotiated cipher as this negotiation must yield a compatible cipher anyway. to ensure unambiguous cipher and hash selection, only use ciphers with the same hash function in the CipherSuites of the tls block. if no tls block is specified, a default config withSHA256is used. note: only TLS1.3 PSK is supported and only for TLS, not DTLS (pending OpenSSL DTLS1.3 support). π₯PSKidentity identityβ the TLS-PSK identity to identify the client. when omitted, the client name is used as the identity. when using TLS-PSK, all clients are identified by thier PSK identity, however it is highly recommended to limit the allowed source address(es) using theHostaddress option. πDuplicateInterval secondsβ specify for how many seconds duplicate checking should be done. if a proxy receives a new request within a few seconds of a previous one, it may be treated the same if from the same client, with the same authenticator etc. the proxy will then ignore the new request (if it is still processing the previous one), or return a copy of the previous reply.AddTTL 1-255β theAddTTLoption has the same meaning as the option used in the basic config. see the BASIC OPTIONS section for details. any value configured here overrides the basic one when sending messages to this client.TCPKeepalive (on|off)β enable TCP keepalive (default is off). if keepalives are not answered within30sthe connection is considered lost. π¦FticksVISCOUNTRY ccβ sets this client to be eligible to F-Ticks logging as defined by theFTicksReportingbasic option, and specifies the country to be reported. the country should be specified by the two-letter country code. πFticksVISINST institutionβ set the institution to report in F-Ticks logging. if this option is omitted, the name of the client block is used.Rewrite rewriteβ this option is deprecated. userewriteIninstead. πRewriteIn rewriteβ apply the operations in the specified rewrite block on incoming (request) messages from this client. rewriting incoming messages is done before other processing. ifRewriteInis not configured, the rewrite blocksdefaultClientordefaultwill be applied if defined.RewriteOut rewriteβ apply the operations in the specified rewrite block on outgoing (response) messages from this client. rewriting outgoing messages is done after other processing. no default blocks are applied forRewriteOut.RewriteAttribute User-Name:/regex/replace/β rewrite theUser-Nameattribute in a client request for the request forwarded by the proxy. theUser-Nameattribute is written back to the original value if a matching response is later sent back to the client. example usage:
RewriteAttribute User-Name:/^(.*)@local$/\1@example.com/
RequireMessageAuthenticator (on|off)β require all Access-Requests be signed with a Message-Authenticator. this should be enabled if the client is a proxy, or a NAS known to use Message-Authenticator (e.g. all EAP based NAS like Wifi). this setting is ignored when using TLS/DTLS transport.RequireMessageAuthenticatorProxy (on|off)β require all Access-Requests containing aProxy-Stateattribute to be signed with a Message-Authenticaor. this should always be enabled if the client is a NAS. this setting is ignored when using TLS/DLTS transport or whenRequireMessageAuthenticatoris enabled.
π¦ SERVER BLOCK π¦
server (name|((fqdn|address)[:port])) {
...
}
okay bestie, this is the glow-up block π it's how you tell the proxy about a server β like, hey girl, here's a server, and here's exactly how we should talk to her when we slide into her DMs.
The name of the server block has to be either the IP address (IPv4 or IPv6) of the server, or a domain name (FQDN) β with one exception, which we get to below. If you give a domain name, it gets resolved immediately to all the addresses hanging off that name, and after that the proxy literally does not care about any DNS changes that happen later. So no DNS dependency after startup, periodt. β¨
If that domain name resolves to multiple addresses:
- For UDP/DTLS, the first address is the one used.
- For TCP/TLS, the proxy loops through the addresses until it can connect to one of them. π₯
The way an FQDN gets resolved into an IP address can be nudged by the IPv4Only and IPv6Only options.
For TLS/DTLS, the name of the server must match the FQDN or IP address in the server certificate. No cap, that's a hard requirement. π
Also! The fqdn or address may include a port number (separated with a column). That port number then overrides the default port or a port option in the server block. And literal IPv6 addresses must be wrapped in brackets. π
πΈ The allowed options in a server block are: πΈ
Host(fqdn|address)[:port]β instead of putting the FQDN or address in the block name, you can use the host option. In that case the value of the host option gets used exactly as described above, while the block name is only there as a descriptive name for the administrator (so like, a nickname, cute but not load-bearing π). Note that multiple host options may be used β that gets treated as multiple names/addresses for the same server. When initiating a TCP/TLS connection, all addresses of all names may be attempted, but there is no failover between the different host values. For failover, use separate server blocks. π«ΆPortportβ specify the port (UDP/TCP) to connect to. If you omit it, UDP and TCP default to1812while TLS and DTLS default to2083. βSource(address|*)[:port]β specify the source address and/or port to use for this server. See theSource...options above. π§DynamicLookupCommandcommandβ execute the command to dynamically configure a server for a realm given by the username field in an Access-Request. The command can take two special forms,naptr:serviceorsrv:prefix, or point to a script or executable.
The naptr: and srv: forms execute the corresponding DNS queries β either searching for service in NAPTR records (followed by an SRV query), or querying for prefix.realm SRV records. Finally a server block will be constructed for the dynamic realm, taking this server block as a template and overriding the host entries with the content of the SRV records. π
Otherwise, the command should be an executable file or script, given with full path, that gets invoked with the name of the realm as its first and only argument. It should either print a valid server {...} block containing at least one host statement on stdout and exit with a code of 0, or print nothing and exit with a non-zero exit code. If the command exited with 0 and provided a valid server config, it will be combined with the statements in this server block, with the values returned by the command taking preference. π
An example of a shell script resolving the DNS NAPTR records for the realm and then the SRV records for each NAPTR matching x-eduroam:radius.tls is provided in tools/naptr-eduroam.sh. This is equivalent to configuring naptr:x-eduroam:radius.tls directly. π
ServerNameservernameβ use servername for the certificate name check instead of host or the server block name (e.g. if host uses a static IP address). Additionally, this name is used for SNI (if enabled), unlessSNIservernameis set. πΈSNI(on|off)β override the global SNI setting (see above). This is implicitly enabled ifSNIservernameis set. β¨SNIservernamesniβ explicitly set the sni to request from the server, in case the server is specified by IP address or to override the hostname. Implicitly enables SNI for this server. πPSKkeykeyPSKidentityidentity
The meaning of these options is very similar to the client block, with minor differences:
- The identity must always be provided and cannot be derived from the server name.
- For the key derivation hash function, the hash function of the first cipher in the
CipherSuitesof the referenced tls block is used. π
StatusServer(on|off|minimal|auto)β enable the use of status-server messages for this server (defaultoff). If statusserver is enabled (on), the proxy will send regular status-server messages to the server to verify that it is alive. Status tracking of the server will solely depend on status-server messages and ignore lost requests. This should only be enabled if the server supports it. With the optionminimal, status-server messages are only sent when regular requests have been lost and no other replies have been received.
The option auto tries to detect whether the other server supports status-server. If so, status-server messages are enabled in minimal mode. π
RetryCountcountβ set how many times the proxy should retry sending a request to the server. Default is2retries for UDP and DTLS. For TCP and TLS it is always0.
Retries from radius clients are ignored and radsecproxy performs its own retry handling since the requirements differ when switching transport protocols. π
RetryIntervalintervalβ set the interval between each retry. Default is5s. β±οΈRewriterewriteβ this option is deprecated. UserewriteIninstead. π¨RewriteOutrewriteRewriteInrewrite
Apply the operations in the specified rewrite block on outgoing (request) or incoming (response) messages to/from this server. Rewriting outgoing messages is done after, incoming before other processing. If RewriteIn is not configured, the rewrite blocks defaultServer or default will be applied if defined. No default blocks are applied for RewriteOut. π
LoopPrevention(on|off)β this overrides the globalLoopPreventionoption for this server. See section BASIC OPTIONS for details on this option. πBlockingStartup(on|off)β start the dynamic server in blocking mode (defaultoff), treating it as if it was already connected and enqueue requests to this server. Queued requests will be sent out when the connection is established. If however the dynamic lookup or the connection fails, the queued requests will be lost. π
This is only considered for dynamic lookup servers, i.e. when DynamicLookupCommand is specified. Warning: when the dynamic lookup and connection process is slow, this will block the respective realm for that time. β οΈ
DTLSForceMTUmtuβ some non-Linux platforms are unable to query the MTU of a connection, causing DTLS to limit itself to256bytes and thus failing to connect. Manually set mtu to a large enough value so the initial DTLS client-hello fits without fragmentation. π οΈRequireMessageAuthenticator(on|off)β require all responses to Access-Requests be signed with a Message-Authenticator.
This should always be enabled unless the server is known to only support legacy RADIUS/UDP behavior.
This setting is ignored when using TLS/DTLS transport. π₯
The meaning and syntax of the following options are exactly the same as for the client block. The details are not repeated here β please refer to the definitions in the CLIENT BLOCK section, bestie, they're right there. π
IPv4Only(on|off)IPv6Only(on|off)TypetypeSecretsecretTLStlsCertificateNameCheck(on|off)MatchCertificateAttribute...AddTTL1-255TCPKeepalive(on|off)
π REALM BLOCK π
okay bestie, this is where the proxy figures out where to send stuff, and it's giving matchmaking service but for RADIUS. π
realm (*|realm|/regex/) {
...
}
When the proxy receives an Access-Request it needs to figure out to which server it should be forwarded. This is done by looking at the Username attribute in the request, and matching that against the names of the defined realm blocks. The proxy will match against the blocks in the order they are specified, using the first match if any. If no realm matches, the proxy will simply ignore the request. Each realm block specifies what the server should do when a match is found.
The allowed options in a realm block are:
Serverserver β Specify the server to which requests for this realm should be forwarded. server references a previously defined server block (see the SERVER BLOCK section). EachserverandaccountingServercan be specified multiple times, or omitted completely. If noserveris configured, the proxy will deny all Access-Requests for this realm. If noaccountingServeris configured, the proxy will silently ignore all Accounting-Requests for this realm. See the SERVER SELECTION section below for details. π«ΆAccountingResponse(on|off)β Enable sendingAccounting-Responseinstead of ignoring Accounting-Requests when noaccoutingServerare configured. (yes bestie, the manpage saysaccoutingServerβ we don't make the rules, we just report them π)AccountingLog(on|off)β When responding to Accounting-Requests (AccountingResponse on), log the accounting data. πReplyMessagemessage β Specify a message to be sent back to the client if aAccess-Requestis denied because no server are configured. π
β¨ REALM BLOCK NAMES AND MATCHING β¨
In the general case the proxy will look for a @ in the username attribute, and try to do an exact, case insensitive match between what comes after the @ and the name of the realm block. So if you get a request with the attribute value anonymous@example.com, the proxy will go through the realm names in the order they are specified, looking for a realm block named example.com.
There are two exceptions to this, one is the realm name * which means match everything. Hence if you have a realm block named *, then it will always match. This should then be the last realm block defined, since any blocks after this would never be checked. This is useful for having a default. π
The other exception is regular expression matching. If the realm name starts with a /, the name is treated as an regular expression. A case insensitive regexp match will then be done using this regexp on the value of the entire Username attribute. Optionally you may also have a trailing / after the regexp. So as an example, if you want to use regexp matching the domain example.com you could have a realm block named /@example\.com$/. If you want to match all domains under the .com top domain, you could do /@.*\.com$/. Note that since the matching is done on the entire attribute value, you can also use rules like /^[a-k].*@example\.com$/ to get some of the users in this domain to use one server, while other users could be matched by another realm block and use another server. π§ β¨
π₯ SERVER SELECTION π₯
Normally requests will be forwarded to the first server option defined. If there are multiple server options, the proxy will do fail-over and use the second server if the first is down. If the two first are down, it will try the third etc. If the first server comes back up, it will go back to using that one. Detection of servers being up or down is based on the use of StatusServer (if enabled), and that TCP/TLS/DTLS connections are up. Otherwise unanswered requests are used to detect unresponsive servers. AccountingServers are treated the same, but independently of the other servers. π
If there is no Server option (or all dynamic lookups have failed), the proxy will if ReplyMessage is specified, reply back to the client with an Access Reject message. The message contains a replyMessage attribute with the value as specified by the ReplyMessage option. Note that this is different from having no match since then the request is simply ignored. This can be used to catch all undefined sub-domains or even all undefined realms by configuring either a regex match like /@.*\.example\.com/ or the realm * with no server option. Another use-case is to block a specific pattern in the username or realm part using a regex. π«
If there is no AccountingServer option, the proxy will normally do nothing, ignoring accounting requests. If instead AccountingResponse is set to on, the proxy will log some of the accounting information and send an Accounting-Response back. This stops clients from retransmitting Accounting-Request messages when a realm has no accountingServer configured. πΈ
π¦ TLS BLOCK π¦
tls name {
...
}
The TLS block specifies TLS configuration options and you need at least one of these if you have clients or servers using TLS/DTLS. As discussed in the client and server block descriptions, a client or server block may reference a particular TLS block by name. There are also however the special TLS block names default, defaultClient and defaultServer which are used as defaults if the client or server block does not reference a TLS block. Also note that a TLS block must be defined before the client or server block that would use it. If you want the same TLS configuration for all TLS/DTLS clients and servers, you need just a single tls block named default, and the client and servers need not refer to it. If you want all TLS/DTLS clients to use one config, and all TLS/DTLS servers to use another, then you would be fine only defining two TLS blocks named defaultClient and defaultServer. If you want different clients (or different servers) to have different TLS parameters, then you may need to create other TLS blocks with other names, and reference those from the client or server definitions. π
As both clients and servers need to present and verify a certificate, both a certificate as well as a CA to verify the peers certificate must be configured. π
The allowed options in a tls block are:
CACertificateFilefile β The CA certificate file used to verify the peers certificate. The file can include multiple certificates as well as CRLs. πCACertificatePathpath β The path to search for CA or intermediate certificates and CRLs. All files must have hashed symbolic links to be found. Seeopenssl-rehash(1). πCertificateFilefile β The server certificate this proxy will use. The file may also contain a certificate chain. Any missing certificates to complete the chain will be searched for in theCACertificateFileandCACertificatePath. πCertificateKeyFilefile β The private-key file for the server certificate specified inCACertificateFile. ποΈCertificateKeyPasswordpassword β The password to decrypt the private-key. π€«PolicyOIDoid β Require the peers certificate to adhere to the policy specified by oid. When specified multiple times at least one policy must be valid in the peer certificate. πCRLCheck(on|off)β Enable checking peer certificate against the CRL (defaultoff). Note if enabled, all CAs in this context MUST provide a CRL, otherwise they are considered untrusted. Note that radsecproxy does not fetch the CRLs itself. This has to be done separately, e.g. withfetch-crl(8). β οΈCacheExpiryseconds β Specify how many seconds the CA and CRL information should be cached. By default, the CA and CRL are loaded at startup and cached indefinetely. After the configured time, the CA and CRL are re-read. Alternatively, reloading the CA and CRL can be triggered by sending aSIGHUPto the radsecproxy process. This option may be set to zero to disable caching, but be warned: this might have a huge performance impact. Any negative value will disable the cache expiry. β³CipherListciphers β Specify the list of accepted ciphers. Seeopenssl-ciphers(1). πCipherSuitesciphersuites β Specify the ciphersuites to be used for TLS1.3. Seeopenssl-ciphers(1). Note this requires OpenSSL 1.1.1. β¨TlsVersion( version | minversion:maxversion )β Specify the TLS protocol version to be used. Specify the range of allowed protocol versions between minversion and maxversion (inclusive). If either is left out, any version up to, or starting from this version is allowed. E.g."TLS1_2:"will allow TLSv1.2 or later. If omitted, use the system defaults set inopenssl.conf. Currently supported values areSSL3,TLS1,TLS1_1,TLS1_2,TLS1_3for TLS andDTLS1,DTLS1_2for DTLS. πΆDtlsVersion( version | minversion:maxversion )β Specify the DTLS protocol version to be used. Same rules asTlsVersionabove, bestie. π«DhFilefile β DH parameter file to use. Seeopenssl-dhparam(1). Note: starting with OpenSSL 3.0, use of custom DH parameters is discouraged. π
π REWRITE BLOCK π
okay bestie, this is the block that gets to edit stuff. Like, actually reach into your RADIUS messages and change them. Iconic behaviour tbh.
rewrite name {
...
}
The rewrite block specifies rules that may rewrite RADIUS messages. It can be used to add, remove and modify specific attributes from messages received from and sent to clients and servers. As discussed in the client and server block descriptions, a client or server block may reference a particular rewrite block by name. There are however also the special rewrite block names default, defaultClient and defaultServer which are used as defaults if the client or server block does not reference a block. Also note that a rewrite block must be defined before the client or server block that would use it. So like, order matters, no cap. π
If you want the same rewrite rules for input from all clients and servers, you need just a single rewrite block named default, and the clients and servers need not refer to it. If you want all clients to use one config, and all servers to use another, then you would be fine only defining two rewrite blocks named defaultClient and defaultServer. π«Ά
β οΈ Note that these defaults are only used for rewrite on input. No rewriting is done on output unless explicitly specified using the RewriteOut option. So don't come crying to me when your output is untouched, bestie, that's literally documented.
β¨ the order of operations (yes it's giving math class) β¨
The rewrite actions are performed in this sequence:
RemoveAttribute(orWhitelistAttribute)ModifyAttributeSupplementAttributeAddAttribute
All options can be specified multiple times. The allowed options in a rewrite block are:
AddAttribute attribute:valueβ Add an attribute to the radius message and set it tovalue. The attribute must be specified using the numerical attribute id. Thevaluecan either be numerical, a string, or a hex value. If the value starts with a number, it is interpreted as a 32bit unsigned integer. Use the'character at the start of the value to force string interpretation. When using hex value, it is recommended to also lead with'to avoid unintended numeric interpretation. See theCONFIGURATION SYNTAXsection for further details. πAddVendorAttribute vendor:subattribute:valueβ Add a vendor attribute to the radius message, specified byvendorandsubattribute. Bothvendorandsubattributemust be specified as numerical values. The format ofvalueis the same as forAddAttributeabove.SupplementAttribute attribute:valueβ Add an attribute to the radius message and set it tovalue, only if the attribute is not yet present on the message. The format ofvalueis the same as forAddAttributeabove. It's giving "only if you're not already here" energy. πSupplementVendorAttribute vendor:subattribute:valueβ Add a vendor attribute to the radius message only if the subattribute of this vendor is not yet present on the message. The format is the same as forAddVendorAttributeabove.ModifyAttribute attribute:/regex/replace/β Modify the given attribute using the regex replace pattern. As above,attributemust be specified by a numerical value. Example usage:
modifyAttribute 1:/^(.*)@local$/\1@example.com/
ModifyVendorAttribute vendor:subattribute:/regex/replace/β Modify the given subattribute of given vendor using the regex replace pattern. Other than the added vendor, the same syntax as forModifyAttributeapplies.RemoveAttribute attributeβ Remove all attributes with the given id. bye bye πRemoveVendorAttribute vendor[:subattribute]β Remove all vendor attributes that match the given vendor and subattribute. If thesubattributeis omitted, all attributes with the given vendor id are removed.WhitelistMode (on|off)β Enable whitelist mode. All attributes except those configured withWhitelistAttributeorWhitelistVendorAttributewill be removed. While whitelist mode is active,RemoveAttributeandRemoveVendorAttributestatements are ignored. π«WhitelistAttribute attributeβ Do not remove attributes with the given id whenWhitelistModeison. Ignored otherwise.WhitelistVendorAttribute vendor[:subattribute]β Do not remove vendor attributes that match the given vendor and subattribute whenWhitelistModeison. Ignored otherwise.
If the subattribute is omitted, the complete vendor attribute is whitelisted. Otherwise only the specified subattribute is kept but all other subattributes are removed.
π SEE ALSO π
and that's a wrap on the whole page, bestie!! π₯³ you made it to the end, I'm so proud. this page is from radsecproxy 1.11.4, dated 2026-08-10, and it's radsecproxy.conf(5) β go forth and configure, you absolute icon πβ¨π
π¦ where this page comes from
- epel 10: radsecproxy 1.11.4-1.el10_3 Β· BSD-3-Clause
- epel 9: radsecproxy 1.11.4-1.el9 Β· BSD-3-Clause
- fedora 43: radsecproxy 1.11.4-1.fc43 Β· BSD-3-Clause
- fedora 44: radsecproxy 1.11.4-1.fc44 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms