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