summaryrefslogtreecommitdiffstats
path: root/raddb/sites-available/resource-check
blob: 486c3b8a6ac521cf2dab5455488030c26defe030 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# -*- text -*-
######################################################################
#
#  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 {
#
#    ...
#
#    authorize {
#
#        #  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.
#
listen {
	type = status
	ipaddr = 127.0.0.1
	port = 18122
	virtual_server = resource_check
}


#
#  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"
#
server resource-check {

authorize {

Autz-Type Status-Server {

	#
	#  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.
	#
	if ("%{sql:SELECT pg_is_in_recovery()}" != "f") {

		# Fail the db_online module, if it isn't already
		if ("%{db_online:}" != "fail") {
			%{db_online:fail}
		}

	} else {

		# Set the db_online module status to alive, if it isn't already
		if ("%{db_online:}" != "alive") {
			%{db_online:alive}
		}

	}

}

}

}