RADIUS

From PostgreSQL wiki
Jump to navigationJump to search

Deprecation of built-in RADIUS authentication method

Don't use the built-in RADIUS authentication for PostgreSQL: it is known to be insecure, and there are many other options. If you must use RADIUS, consider doing so via PAM. The built-in support will be removed in PostgreSQL 19.

PAM-based RADIUS

Pluggable Authentication Modules are supported by all OSes PostgreSQL targets except OpenBSD and Windows, and PostgreSQL supports them. (For OpenBSD, BSD Authentication is approximately equivalent and login_radius may correspond to what is described below, but that has not been investigated.)

Suppose your pg_hba.conf file has:

   host all all 192.168.1.0/24 radius radiusserver=10.0.0.50 radiussecret=my_shared_secret radiusport=1812

First, change this to a PAM entry. Here, "postgresql" is chosen as the PAM service name, but it can be any name you prefer:

   host all all 192.168.1.0/24 pam pamservice=postgresql

Next, configure the PAM service. The details depend on which of several PAM RADIUS implementations you are using.

FreeRADIUS pam_radius_auth.so

This is the most popular one, found at pam_radius_auth.so module and Linux package managers (Debian | ...).

The service configuration file should be created under /etc/pam.d with suitable permissions, in this example /etc/pam.d/postgresql:

   #%PAM-1.0
   auth required pam_radius_auth.so conf=/etc/radius.conf require_message_authenticator
   account required pam_permit.so

The "auth" line says that passwords should be checked using RADIUS. The conf option is shown here for completeness, but /etc/radius.conf is the default RADIUS configuration file name and it isn't necessary to include the conf option unless you want to use a different path. Note that require_message_authenticator provides mitigation against the Blast-RADIUS attack (something that the built-in RADIUS method lacks), and without that some RADIUS servers might reject requests or report warnings. The "account" line says that all account (role/user) names are acceptable, which is appropriate here because PostgreSQL itself will check that that the role name is valid, and the authentication method is only responsible for checking the password.

Then a /etc/radius.conf file (or whatever was provided with conf=) should be created:

   # server[:port] shared_secret timeout
   10.0.0.50:1812 my_shared_secret 3

More than one server can be listed on separate lines, to support fail-over in round-robin order. A timeout of 3 seconds corresponds to the built-in RADIUS method's hard-coded timeout.

The configuration above will use RADIUS/UDP, just like the built-in RADIUS method, except with the mitigation against Blast-RADIUS enabled. Even with the mitigation enabled, RADIUS/UDP is not considered to be very secure, and it would be much better to use RADIUS/TLS (sometimes known as RADSEC). Unfortunately, pam_radius doesn't support that yet. A pull request exists that would allow RADIUS/TLS to be configured, and that should become the recommendation on this page once it ships.

FreeBSD and NetBSD pam_radius.so

pam_radius.so is part of the base system of these operating systems. Unfortunately it does not yet appear to support require_message_authenticator or RADIUS/TLS, so it might be necessary to get the FreeRADIUS version if you really need that. The configuration is nearly identical.

/etc/pam.d/postgresql:

   #%PAM-1.0
   auth required pam_radius.so conf=/etc/radius.conf
   account required pam_permit.so

/etc/radius.conf file (or whatever was provided with conf=):

   # server[:port] shared_secret timeout
   10.0.0.50:1812 my_shared_secret 3

Solaris pam_radius_auth.so

Not tested or investigated, but pam_radius_auth.so looks very similar to the above, and apparently already supports RADIUS/TLS.

History

PostgreSQL has supported RADIUS authentication since 2010, but only the RADIUS/UDP variant, and without the Message-Authenticator. It relies on MD5, which has been considered dead for security purposes since the mid to late 2000s when researchers began to publish practical collision techniques and generate forged certificates, leading to its widespread deprecation wherever cryptograpic hashes are required. For example, it is deprecated in favour of scram-sha-256 in PostgreSQL's password authentication. RADIUS/UDP was well known to be insecure, but in 2024 some of the same researchers showed a practical attack that could be used to forge a successful response datagram in 30-60 seconds given access to the network and 47 Xeon CPUs to find the collision, forcing the standards community to do something to discourage the use of the obsolete versions of the protocol. Fortunately PostgreSQL only waits 3 seconds for a RADIUS server to respond, hopefully making the attack impractical for anyone without vastly more computing power than that.

Initially PostgreSQL developers considered implementing Message-Authenticator, but noted that the timeout already made the attack impractical, and the total absence of problem reports from the field indicating that RADIUS is not really used with PostgreSQL. The plan agreed on was to remove support in v19, declare it deprecated and insecure in the documentation of the release branches, and show how to use the PAM module instead, just in case there really are some users out there who need a pathway to the modern, supported variants of the protocol.