Certificate validation in rest module fails
Murali Krishnamoorthy
hibkmurali at gmail.com
Fri Sep 5 15:28:53 UTC 2025
Interestingly, I found that using the ca_info_file instead of the ca_file
attribute makes it work fine.
On Thu, Sep 4, 2025 at 10:20 PM Murali Krishnamoorthy <hibkmurali at gmail.com>
wrote:
>
>
> On Thu, Sep 4, 2025 at 11:55 AM Alan DeKok <alan.dekok at inkbridge.io>
> wrote:
>
>> On Sep 4, 2025, at 2:42 PM, Murali Krishnamoorthy <hibkmurali at gmail.com>
>> wrote:
>> > > *(0) rest_auth_failure_log: ERROR: Request failed: 60 - SSL peer
>> > > certificate or SSH remote key was not OK*
>> >
>> > Hmm... unfortunately, that error is coming from curl. The REST
>> module just uses the curl APIs to do the bulk of the work.
>>
>> i.e. error 60 is the Curl error for when it cannot verify the
>> certificate of the REST server.
>>
>> > Is there any external command I could use to verify what freeradius
>> rest module is doing to get better debug?
>>
>> I don't think there's any additional debugging you could see on the
>> FreeRADIUS side. It just gets passes the data to Curl, and Curl returns
>> "error 60". In order to enable more Curl debugging, you would have to edit
>> rlm_rest, to add more Curl API calls.
>>
>> Another possibility is that FreeRADIUS and the local "curl" command are
>> using different versions of OpenSSL.
>>
>> But in the end, FreeRADIUS passes data to Curl, and Curl returns error
>> 60. The only solution here is to pass the right data into Curl.
>>
>> We've used rlm_rest in many places, and have never run into this
>> issue. So it looks like a local configuration problem.
>>
>
> I rechecked by using the same curl/openssl versions as the rlm_rest. It
> worked fine.
>
> I edited rest.c to log info on the ssl cert file options we are setting
> in libcurl and enabled debug on libcurl. I see that, although we set
> ca_file to "/etc/certs/craas-ca.pem" and is also parsed correctly, libcurl
> is somehow using "/etc/ssl/certs.pem" instead and so cannot find the ca
> file. This feels like a bug. Full logs below.
>
> FreeRADIUS Version 3.2.9
> Copyright (C) 1999-2025 The FreeRADIUS server project and contributors
> There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
> PARTICULAR PURPOSE
> You may redistribute copies of FreeRADIUS under the terms of the
> GNU General Public License
> For more information about these matters, see the file named COPYRIGHT
>
> FreeRADIUS is developed, maintained, and supported by InkBridge Networks.
> For commercial support, please email sales at inkbridgenetworks.com
> https://inkbridgenetworks.com/
> Starting - reading configuration files ...
> including dictionary file /opt/share/freeradius/dictionary
> including dictionary file /opt/share/freeradius/dictionary.dhcp
> including dictionary file /opt/share/freeradius/dictionary.vqp
> including configuration file /opt/etc/raddb/radiusd.conf
> including configuration file /opt/etc/raddb/clients.conf
> including files in directory /opt/etc/raddb/mods-enabled/
> including configuration file /opt/etc/raddb/mods-enabled/preprocess
> including configuration file /opt/etc/raddb/mods-enabled/pap
> including configuration file /opt/etc/raddb/mods-enabled/files
> including configuration file /opt/etc/raddb/mods-enabled/rest
> including configuration file /opt/etc/raddb/mods-enabled/realm
> including files in directory /opt/etc/raddb/sites-enabled/
> including configuration file /opt/etc/raddb/sites-enabled/default
> main {
> security {
> allow_core_dumps = no
> }
> name = "radiusd"
> prefix = "/usr/local"
> localstatedir = "/usr/local/var"
> logdir = "/usr/local/var/log"
> run_dir = "/usr/local/var/run/radiusd"
> }
> main {
> name = "radiusd"
> prefix = "/usr/local"
> localstatedir = "/usr/local/var"
> sbindir = "/usr/local/sbin"
> logdir = "/usr/local/var/log"
> run_dir = "/usr/local/var/run/radiusd"
> libdir = "/usr/local/lib"
> radacctdir = "/usr/local/var/log/radacct"
> hostname_lookups = no
> max_request_time = 30
> proxy_dedup_window = 1
> cleanup_delay = 5
> max_requests = 256
> max_fds = 512
> postauth_client_lost = no
> pidfile = "/usr/local/var/run/radiusd/radiusd.pid"
> checkrad = "/usr/local/sbin/checkrad"
> debug_level = 0
> proxy_requests = yes
> log {
> stripped_names = no
> auth = no
> auth_badpass = no
> auth_goodpass = no
> msg_denied = "You are already logged in - access denied"
> }
> resources {
> }
> security {
> max_attributes = 0
> reject_delay = 0.000000
> delay_proxy_rejects = no
> status_server = no
> require_message_authenticator = "auto"
> limit_proxy_state = "auto"
> allow_vulnerable_openssl = "no"
> }
> unlang {
> group_stop_return = no
> policy_stop_return = no
> }
> }
> radiusd: #### Loading Realms and Home Servers ####
> radiusd: #### Loading Clients ####
> client radtest {
> ipaddr = 0.0.0.0/0
> secret = <<< secret >>>
> proto = "*"
> limit {
> max_connections = 16
> lifetime = 0
> idle_timeout = 30
> }
> }
> Shared secret for client radtest is short, and likely can be broken by an
> attacker.
> Found debugger attached
> Configuration version: e39d-75aa-fdaa-463e
> # Creating Auth-Type = PAP
> radiusd: #### Instantiating modules ####
> modules {
> # Loaded module rlm_preprocess
> # Loading module "preprocess" from file
> /opt/etc/raddb/mods-enabled/preprocess
> preprocess {
> with_ascend_hack = no
> ascend_channels_per_line = 23
> with_ntdomain_hack = no
> with_specialix_jetstream_hack = no
> with_cisco_vsa_hack = no
> with_alvarion_vsa_hack = no
> }
> # Loaded module rlm_pap
> # Loading module "pap" from file /opt/etc/raddb/mods-enabled/pap
> pap {
> normalise = yes
> }
> # Loaded module rlm_files
> # Loading module "files" from file /opt/etc/raddb/mods-enabled/files
> files {
> usersfile = "/opt/etc/raddb/users"
> }
> # Loaded module rlm_rest
> # Loading module "rest" from file /opt/etc/raddb/mods-enabled/rest
> rest {
> connect_timeout = 4.000000
> http_negotiation = "default"
> }
> # Loaded module rlm_realm
> # Loading module "IPASS" from file /opt/etc/raddb/mods-enabled/realm
> realm IPASS {
> format = "prefix"
> delimiter = "/"
> ignore_default = no
> ignore_null = no
> }
> # Loading module "suffix" from file /opt/etc/raddb/mods-enabled/realm
> realm suffix {
> format = "suffix"
> delimiter = "@"
> ignore_default = no
> ignore_null = no
> }
> # Loading module "bangpath" from file /opt/etc/raddb/mods-enabled/realm
> realm bangpath {
> format = "prefix"
> delimiter = "!"
> ignore_default = no
> ignore_null = no
> }
> # Loading module "realmpercent" from file
> /opt/etc/raddb/mods-enabled/realm
> realm realmpercent {
> format = "suffix"
> delimiter = "%"
> ignore_default = no
> ignore_null = no
> }
> # Loading module "ntdomain" from file /opt/etc/raddb/mods-enabled/realm
> realm ntdomain {
> format = "prefix"
> delimiter = "\"
> ignore_default = no
> ignore_null = no
> }
> # Instantiating module "preprocess" from file
> /opt/etc/raddb/mods-enabled/preprocess
> # Instantiating module "pap" from file /opt/etc/raddb/mods-enabled/pap
> # Instantiating module "files" from file
> /opt/etc/raddb/mods-enabled/files
> reading pairlist file /opt/etc/raddb/users
> # Instantiating module "rest" from file /opt/etc/raddb/mods-enabled/rest
> post-auth {
> uri = "https://auth.feature-devops.qa.xcloudiq.com:8443/auth/log-event
> "
> method = "post"
> body = "json"
> attr_num = no
> raw_value = no
> data = "{"Auth-Result": "FAILURE", "Message":"%{Reply-Message}",
> "User-Name": "%{User-Name}", "NAS-Identifier": "%{NAS-Identifier}",
> "NAS-Port-Type": "%{NAS-Port-Type}", "NAS-IP-Address": "%{NAS-IP-Address}",
> "NAS-Port": "%{NAS-Port}", "NAS-Port-Id": "%{NAS-Port-Id}",
> "Called-Station-Id": "%{Called-Station-Id}", "Calling-Station-Id":
> "%{Calling-Station-Id}", "EAP-Message": "%{EAP-Message}"}"
> auth = "none"
> require_auth = no
> timeout = 4.000000
> chunk = 0
> tls {
>
>
> * ca_file = "/etc/certs/craas-ca.pem" certificate_file =
> "/etc/certs/client.pem" private_key_file = "/etc/certs/client.key"*
> check_cert = yes
> check_cert_cn = yes
> }
> body_uri_encode = yes
> }
> rlm_rest: libcurl version: libcurl/8.12.1 OpenSSL/3.3.4 zlib/1.3.1
> brotli/1.1.0 zstd/1.5.6 c-ares/1.34.5 libidn2/2.3.7 libpsl/0.21.5
> nghttp2/1.64.0
> rlm_rest (rest): Initialising connection pool
> pool {
> start = 5
> min = 5
> max = 10
> spare = 3
> uses = 0
> lifetime = 0
> cleanup_interval = 30
> idle_timeout = 60
> retry_delay = 1
> max_retries = 5
> spread = no
> }
> rlm_rest (rest): Opening additional connection (0), 1 of 10 pending slots
> used
> rlm_rest (rest): Skipping pre-connect, connect_uri not specified
> rlm_rest (rest): Opening additional connection (1), 1 of 9 pending slots
> used
> rlm_rest (rest): Skipping pre-connect, connect_uri not specified
> rlm_rest (rest): Opening additional connection (2), 1 of 8 pending slots
> used
> rlm_rest (rest): Skipping pre-connect, connect_uri not specified
> rlm_rest (rest): Opening additional connection (3), 1 of 7 pending slots
> used
> rlm_rest (rest): Skipping pre-connect, connect_uri not specified
> rlm_rest (rest): Opening additional connection (4), 1 of 6 pending slots
> used
> rlm_rest (rest): Skipping pre-connect, connect_uri not specified
> # Instantiating module "IPASS" from file
> /opt/etc/raddb/mods-enabled/realm
> # Instantiating module "suffix" from file
> /opt/etc/raddb/mods-enabled/realm
> # Instantiating module "bangpath" from file
> /opt/etc/raddb/mods-enabled/realm
> # Instantiating module "realmpercent" from file
> /opt/etc/raddb/mods-enabled/realm
> # Instantiating module "ntdomain" from file
> /opt/etc/raddb/mods-enabled/realm
> } # modules
> radiusd: #### Loading Virtual Servers ####
> server { # from file /opt/etc/raddb/radiusd.conf
> } # server
> server default { # from file /opt/etc/raddb/sites-enabled/default
> # Loading authenticate {...}
> Compiling Auth-Type PAP for attr Auth-Type
> # Loading authorize {...}
> # Loading preacct {...}
> # Loading post-auth {...}
> Compiling Post-Auth-Type REJECT for attr Post-Auth-Type
> } # server default
> radiusd: #### Opening IP addresses and Ports ####
> listen {
> type = "auth"
> ipaddr = *
> port = 1812
> }
> listen {
> type = "acct"
> ipaddr = *
> port = 1813
> }
> Listening on auth address * port 1812 bound to server default
> Listening on acct address * port 1813 bound to server default
> Ready to process requests
>
> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
> BlastRADIUS check: Received packet with Message-Authenticator.
> Setting "require_message_authenticator = true" for client radtest
>
> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
> It looks like the client has been updated to protect from the BlastRADIUS
> attack.
> Please set "require_message_authenticator = true" for client radtest
>
> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
> (0) Received Access-Request Id 145 from 172.25.0.2:52483 to
> 172.25.0.20:1812 length 78
> (0) Message-Authenticator = 0x9aed201100840d25636141144c32327d
> (0) User-Name = "testuser"
> (0) User-Password = "password123"
> (0) NAS-IP-Address = 172.25.0.2
> (0) NAS-Port = 0
> (0) # Executing section authorize from file
> /opt/etc/raddb/sites-enabled/default
> (0) authorize {
> (0) [preprocess] = ok
> (0) suffix: Checking for suffix after "@"
> (0) suffix: No '@' in User-Name = "testuser", looking up realm NULL
> (0) suffix: No such realm "NULL"
> (0) [suffix] = noop
> (0) pap: WARNING: No "known good" password found for the user. Not
> setting Auth-Type
> (0) pap: WARNING: Authentication will fail unless a "known good" password
> is available
> (0) [pap] = noop
> (0) } # authorize = ok
> (0) ERROR: No Auth-Type found: rejecting the user via Post-Auth-Type =
> Reject
> (0) Failed to authenticate the user
> (0) Using Post-Auth-Type Reject
> (0) # Executing group from file /opt/etc/raddb/sites-enabled/default
> (0) Post-Auth-Type REJECT {
> rlm_rest (rest): Reserved connection (0)
> (0) rest: Expanding URI components
> (0) rest: EXPAND https://auth.feature-devops.qa.xcloudiq.com:8443
> (0) rest: --> https://auth.feature-devops.qa.xcloudiq.com:8443
> (0) rest: EXPAND /auth/log-event
> (0) rest: --> /auth/log-event
> (0) rest: Sending HTTP POST to "
> https://auth.feature-devops.qa.xcloudiq.com:8443/auth/log-event"
>
>
> *(0) rest: Setting CURLOPT_SSLCERT to '/etc/certs/client.pem'(0) rest:
> Setting CURLOPT_SSLKEY to '/etc/certs/client.key'(0) rest: Setting
> CURLOPT_ISSUERCERT to '/etc/certs/craas-ca.pem'*
> (0) rest: EXPAND {"Auth-Result": "FAILURE", "Message":"%{Reply-Message}",
> "User-Name": "%{User-Name}", "NAS-Identifier": "%{NAS-Identifier}",
> "NAS-Port-Type": "%{NAS-Port-Type}", "NAS-IP-Address": "%{NAS-IP-Address}",
> "NAS-Port": "%{NAS-Port}", "NAS-Port-Id": "%{NAS-Port-Id}",
> "Called-Station-Id": "%{Called-Station-Id}", "Calling-Station-Id":
> "%{Calling-Station-Id}", "EAP-Message": "%{EAP-Message}"}
> (0) rest: --> {"Auth-Result": "FAILURE", "Message":"", "User-Name":
> "testuser", "NAS-Identifier": "", "NAS-Port-Type": "", "NAS-IP-Address":
> "172.25.0.2", "NAS-Port": "0", "NAS-Port-Id": "", "Called-Station-Id": "",
> "Calling-Station-Id": "", "EAP-Message": ""}
> (0) rest: From rest_request_perform():
> (0) rest: CURLOPT_SSLCERT(tls_certificate_file): /etc/certs/client.pem
> (0) rest: CURLOPT_SSLKEY(tls_private_key_file): /etc/certs/client.key
> (0) rest: CURLOPT_ISSUERCERT(tls_ca_file): /etc/certs/craas-ca.pem
> rlm_rest: libcurl: Host auth.feature-devops.qa.xcloudiq.com:8443 was
> resolved.
> rlm_rest: libcurl: IPv6: (none)
> rlm_rest: libcurl: IPv4: 3.150.3.32, 3.19.113.11
> rlm_rest: libcurl: Trying 3.150.3.32:8443...
> rlm_rest: libcurl: ALPN: curl offers h2,http/1.1
> rlm_rest: libcurl: TLSv1.3 (OUT), TLS handshake, Client hello (1):
> *rlm_rest: libcurl: CAfile: /etc/ssl/cert.pem *
> rlm_rest: libcurl: CApath: /etc/ssl/certs
> rlm_rest: libcurl: TLSv1.3 (IN), TLS handshake, Server hello (2):
> rlm_rest: libcurl: TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
> rlm_rest: libcurl: TLSv1.3 (IN), TLS handshake, Request CERT (13):
> rlm_rest: libcurl: TLSv1.3 (IN), TLS handshake, Certificate (11):
> rlm_rest: libcurl: TLSv1.3 (OUT), TLS alert, unknown CA (560):
> *rlm_rest: libcurl: SSL certificate problem: unable to get local issuer
> certificate *
> rlm_rest: libcurl: closing connection #0
> (0) rest: ERROR: Request failed: 60 - SSL peer certificate or SSH remote
> key was not OK
> (0) rest: ERROR: Server returned no data
> rlm_rest (rest): Released connection (0)
> (0) [rest] = fail
> (0) } # Post-Auth-Type REJECT = fail
> (0) Sent Access-Reject Id 145 from 172.25.0.20:1812 to 172.25.0.2:52483
> length 38
> (0) Finished request
> Waking up in 4.9 seconds.
> (0) Cleaning up request packet ID 145 with timestamp +10 due to
> cleanup_delay was reached
> Ready to process requests
>
>
>
>
>
More information about the Freeradius-Users
mailing list