
This virtual server provides an example of how to dynamically amend the
control flow within some virtual server's policy on the basis of the status
of some resource, such as an external database.

This resource-check virtual server receives periodic dummy server-status
requests that trigger an arbitrary set of checks. On the basis of those
checks the status of an instance of the rlm_always module, that we refer to
as the "control module", is updated to reflect the system status.

Elsewhere, some other virtual server (the "controlled virtual server") uses
the control module to make decisions during the processing of incoming
requests. By amending the status of the control module in response to the
system status this virtual server is able to manipulate the outcome of the
controlled virtual server.

Firstly, the authorize section of this virtual server will need to be
amended to check the status of the external resources and to set the status
of the control module appropriately, as described in the inline comments
below...

In addition to configuring and activating this virtual server, a control
module must be configured as an instance of rlm_always in mods-enabled, for
example:

  always db_online {
      # Default to online
      rcode = ok
  }

Now trigger the resource checks by sending a server-status request to this
virtual server, as follows:

  echo "Message-Authenticator = 0x00" | \
    radclient -r 1 -t 3 -q 127.0.0.1:18122 status testing123

The trigger could be invoked by a cron job or if more frequent checks than
once per minute are required a systemd timer might be used.

The current status of the control module can be examined at any time using
radmin:

  radmin -e 'show module status db_online'

For radmin to work requires that the control-socket virtual server is
configured and enabled.

The controlled virtual server will contain some control flow decision that
uses the control module, for example:

  server default {

  ...

  recv Access-Request {

      #  If the database is not healthy then remain silent to trigger
      #  NAS failover
      #
      db_online {
          fail = 1
      }
      if (fail) {
           do_not_respond
      }

      sql

      pap
  }
  ...
  }


The configuration for this virtual server follows and should be amended as
required.



Listen on a local port for Server-Status requests that trigger the resource
checks.

This uses the normal set of clients, with the same secret as for
authentication and accounting.



Within this virual server we provide only an Autz-Type Status-Server section
whose task is to perform the resource checks and sets the status of the
"control module"






In this example we check whether a PostgreSQL database is in
recovery (or inaccessible) and when this is the case we fail the
db_online control module.

Other modules could be used here.

You can even invoke synchronous checks using the %exec(...) xlat in
which case timeout should be set to less than the check trigger
interval to avoid buildup of checks when resources do not respond.
See rlm_exec for details.


Fail the db_online module, if it isn't already


Set the db_online module status to alive, if it isn't already




== Default Configuration

```
server resource-check {
namespace = radius
listen {
	transport = udp
	udp {
		ipaddr = 127.0.0.1
		port = 18122
	}
	type = Status-Server
}
recv Status-Server {
	if ("%sql('SELECT pg_is_in_recovery()')" != "f") {
		if (%db_online() != "fail") {
			%db_online(fail)
		}
	} else {
		if (%db_online() != "alive") {
			%db_online(alive)
		}
	}
}
}
```
