summaryrefslogtreecommitdiffstats
path: root/raddb/sites-available/tls
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--raddb/sites-available/tls696
-rw-r--r--raddb/sites-available/tls-cache144
2 files changed, 840 insertions, 0 deletions
diff --git a/raddb/sites-available/tls b/raddb/sites-available/tls
new file mode 100644
index 0000000..137fcbc
--- /dev/null
+++ b/raddb/sites-available/tls
@@ -0,0 +1,696 @@
+######################################################################
+#
+# RADIUS over TLS (radsec)
+#
+# When a new client connects, the various TLS parameters for the
+# connection are available as dynamic expansions, e.g.
+#
+# %{listen:TLS-Client-Cert-Common-Name}
+#
+# Along with other TLS-Client-Cert-... attributes.
+# These expansions will only exist if the relevant fields
+# are in the client certificate. Read the debug output to see
+# which fields are available. Look for output like the following:
+#
+# (0) TLS - Creating attributes from certificate OIDs
+# (0) TLS-Client-Cert-Subject-Alt-Name-Dns := "one.example.org"
+# (0) TLS-Client-Cert-Subject-Alt-Name-Dns := "two.example.org"
+# ...
+#
+# It is also possible to distinguish between connections which have
+# TLS enables, and ones which do not. The expansion:
+#
+# %{listen:tls}
+#
+# Will return "yes" if the connection has TLS enabled. It will
+# return "no" if TLS is not enabled for a particular listen section.
+#
+# A number of TLS-Client-Cert-.. attributes holds X509v3 extensions
+# data, attributes named the way OpenSSL names them. It is possible
+# to extract data for an extension not known to OpenSSL by defining
+# a custom string attribute which contains extension OID in it's
+# name after 'TLS-Client-Cert-' prefix. E.g.:
+#
+# ATTRIBUTE TLS-Client-Cert-1.3.6.1.4.1.311.21.7 3002 string
+#
+# which will yield something simmilar to:
+#
+# (0) eap_tls: TLS - Creating attributes from certificate OIDs
+# (0) eap_tls: TLS-Client-Cert-1.3.6.1.4.1.311.21.7 += "0x302e06"
+# ...
+#
+######################################################################
+
+listen {
+ ipaddr = *
+ port = 2083
+
+ #
+ # TCP and TLS sockets can accept Access-Request and
+ # Accounting-Request on the same socket.
+ #
+ # auth = only Access-Request
+ # acct = only Accounting-Request
+ # auth+acct = both
+ # coa = only CoA / Disconnect requests
+ #
+ type = auth+acct
+
+ # For now, only TCP transport is allowed.
+ proto = tcp
+
+ # Send packets to the default virtual server
+ virtual_server = default
+
+ clients = radsec
+
+ #
+ # Use the haproxy "PROXY protocol".
+ #
+ # This configuration allows for many FreeRADIUS servers to be
+ # behind a haproxy server. The "PROXY protocol" allows
+ # haproxy to send the actual client IP to FreeRADIUS.
+ #
+ # This will work ONLY for RadSec (TLS). Both the haproxy AND
+ # the RadSec client MUST be listed as allowed RADIUS clients.
+ #
+ # haproxy needs to have "send-proxy" configured for this server.
+ # Health checks should be turned off, as haproxy does not
+ # support RADIUS health checks.
+ #
+ # The main use of this feature is for scalability. There is no
+ # longer any need to have a RADIUS proxy as a load balancer.
+ # haproxy is fast, stable, and supports dynamic reloads!
+ #
+ # The only problem is that many RADIUS clients do not support
+ # RadSec. That situation will hopefully change over time.
+ #
+# proxy_protocol = no
+
+ #
+ # When this is set to "yes", new TLS connections
+ # are processed through a section called
+ #
+ # Autz-Type New-TLS-Connection {
+ # ...
+ # }
+ #
+ # The request contains TLS client certificate attributes,
+ # and nothing else. The debug output will print which
+ # attributes are available on your system.
+ #
+ # If the section returns "ok" or "updated", then the
+ # connection is accepted. Otherwise the connection is
+ # terminated.
+ #
+# check_client_connections = yes
+
+ #
+ # Connection limiting for sockets with "proto = tcp".
+ #
+ limit {
+ #
+ # Limit the number of simultaneous TCP connections to the socket
+ #
+ # The default is 16.
+ # Setting this to 0 means "no limit"
+ max_connections = 16
+
+ # The per-socket "max_requests" option does not exist.
+
+ #
+ # The lifetime, in seconds, of a TCP connection. After
+ # this lifetime, the connection will be closed.
+ #
+ # Setting this to 0 means "forever".
+ lifetime = 0
+
+ #
+ # The idle timeout, in seconds, of a TCP connection.
+ # If no packets have been received over the connection for
+ # this time, the connection will be closed.
+ #
+ # Setting this to 0 means "no timeout".
+ #
+ # We STRONGLY RECOMMEND that you set an idle timeout.
+ #
+ idle_timeout = 30
+ }
+
+ # This is *exactly* the same configuration as used by the EAP-TLS
+ # module. It's OK for testing, but for production use it's a good
+ # idea to use different server certificates for EAP and for RADIUS
+ # transport.
+ #
+ # If you want only one TLS configuration for multiple sockets,
+ # then we suggest putting "tls { ...}" into radiusd.conf.
+ # The subsection below can then be changed into a reference:
+ #
+ # tls = ${tls}
+ #
+ # Which means "the tls sub-section is not here, but instead is in
+ # the top-level section called 'tls'".
+ #
+ # If you have multiple tls configurations, you can put them into
+ # sub-sections of a top-level "tls" section. There's no need to
+ # call them all "tls". You can then use:
+ #
+ # tls = ${tls.site1}
+ #
+ # to refer to the "site1" sub-section of the "tls" section.
+ #
+ tls {
+ private_key_password = whatever
+ private_key_file = ${certdir}/server.pem
+
+ # Accept an expired Certificate Revocation List
+ #
+ # allow_expired_crl = no
+
+ # If Private key & Certificate are located in
+ # the same file, then private_key_file &
+ # certificate_file must contain the same file
+ # name.
+ #
+ # If ca_file (below) is not used, then the
+ # certificate_file below MUST include not
+ # only the server certificate, but ALSO all
+ # of the CA certificates used to sign the
+ # server certificate.
+ certificate_file = ${certdir}/server.pem
+
+ # Trusted Root CA list
+ #
+ # ALL of the CA's in this list will be trusted
+ # to issue client certificates for authentication.
+ #
+ # In general, you should use self-signed
+ # certificates for 802.1x (EAP) authentication.
+ # In that case, this CA file should contain
+ # *one* CA certificate.
+ #
+ # This parameter is used only for EAP-TLS,
+ # when you issue client certificates. If you do
+ # not use client certificates, and you do not want
+ # to permit EAP-TLS authentication, then delete
+ # this configuration item.
+ ca_file = ${cadir}/ca.pem
+
+ # For DH cipher suites to work in OpenSSL < 1.1.0,
+ # you have to run OpenSSL to create the DH file
+ # first:
+ #
+ # openssl dhparam -out certs/dh 2048
+ #
+ # For OpenSSL >= 1.1.0, just leave this commented
+ # out, and OpenSSL will do the right thing.
+ #
+# dh_file = ${certdir}/dh
+
+ #
+ # If your system doesn't have /dev/urandom,
+ # you will need to create this file, and
+ # periodically change its contents.
+ #
+ # For security reasons, FreeRADIUS doesn't
+ # write to files in its configuration
+ # directory.
+ #
+# random_file = /dev/urandom
+
+ #
+ # The default fragment size is 1K.
+ # However, it's possible to send much more data than
+ # that over a TCP connection. The upper limit is 64K.
+ # Setting the fragment size to more than 1K means that
+ # there are fewer round trips when setting up a TLS
+ # connection. But only if the certificates are large.
+ #
+ fragment_size = 8192
+
+ # include_length is a flag which is
+ # by default set to yes If set to
+ # yes, Total Length of the message is
+ # included in EVERY packet we send.
+ # If set to no, Total Length of the
+ # message is included ONLY in the
+ # First packet of a fragment series.
+ #
+ # include_length = yes
+
+ # Check the Certificate Revocation List
+ #
+ # 1) Copy CA certificates and CRLs to same directory.
+ # 2) Execute 'c_rehash <CA certs&CRLs Directory>'.
+ # 'c_rehash' is OpenSSL's command.
+ # 3) uncomment the line below.
+ # 5) Restart radiusd
+ # check_crl = yes
+ ca_path = ${cadir}
+
+ # OpenSSL does not reload contents of ca_path dir over time.
+ # That means that if check_crl is enabled and CRLs are loaded
+ # from ca_path dir, at some point CRLs will expire and
+ # RADIUSd will stop authenticating NASes.
+ # If ca_path_reload_interval is non-zero, it will force OpenSSL
+ # to reload all data from ca_path periodically
+ #
+ # Flush ca_path each hour
+ ca_path_reload_interval = 3600
+
+ #
+ # If check_cert_issuer is set, the value will
+ # be checked against the DN of the issuer in
+ # the client certificate. If the values do not
+ # match, the certificate verification will fail,
+ # rejecting the user.
+ #
+ # This check can be done more generally by checking
+ # the value of the TLS-Client-Cert-Issuer attribute.
+ # This check can be done via any mechanism you choose.
+ #
+ # check_cert_issuer = "/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd"
+
+ #
+ # If check_cert_cn is set, the value will
+ # be xlat'ed and checked against the CN
+ # in the client certificate. If the values
+ # do not match, the certificate verification
+ # will fail rejecting the user.
+ #
+ # This check is done only if the previous
+ # "check_cert_issuer" is not set, or if
+ # the check succeeds.
+ #
+ # In 2.1.10 and later, this check can be done
+ # more generally by checking the value of the
+ # TLS-Client-Cert-Common-Name attribute. This check
+ # can be done via any mechanism you choose.
+ #
+ # check_cert_cn = %{User-Name}
+ #
+ # Set this option to specify the allowed
+ # TLS cipher suites. The format is listed
+ # in "man 1 ciphers".
+ cipher_list = "DEFAULT"
+
+ # If enabled, OpenSSL will use server cipher list
+ # (possibly defined by cipher_list option above)
+ # for choosing right cipher suite rather than
+ # using client-specified list which is OpenSSl default
+ # behavior. Having it set to yes is a current best practice
+ # for TLS
+ cipher_server_preference = no
+
+ #
+ # Older TLS versions are deprecated. But for RadSec,
+ # we CAN allow TLS 1.3.
+ #
+ tls_min_version = "1.2"
+ tls_max_version = "1.3"
+
+ #
+ # Session resumption / fast reauthentication
+ # cache.
+ #
+ # The cache contains the following information:
+ #
+ # session Id - unique identifier, managed by SSL
+ # User-Name - from the Access-Accept
+ # Stripped-User-Name - from the Access-Request
+ # Cached-Session-Policy - from the Access-Accept
+ #
+ # The "Cached-Session-Policy" is the name of a
+ # policy which should be applied to the cached
+ # session. This policy can be used to assign
+ # VLANs, IP addresses, etc. It serves as a useful
+ # way to re-apply the policy from the original
+ # Access-Accept to the subsequent Access-Accept
+ # for the cached session.
+ #
+ # On session resumption, these attributes are
+ # copied from the cache, and placed into the
+ # reply list.
+ #
+ # You probably also want "use_tunneled_reply = yes"
+ # when using fast session resumption.
+ #
+ cache {
+ #
+ # Enable it. The default is "no".
+ # Deleting the entire "cache" subsection
+ # Also disables caching.
+ #
+ #
+ # The session cache requires the use
+ # of the "name" and "persist_dir" configuration items, below.
+ #
+ # The internal OpenSSL session cache has been permanently
+ # disabled.
+ #
+ # You can disallow resumption for a
+ # particular user by adding the following
+ # attribute to the control item list:
+ #
+ # Allow-Session-Resumption = No
+ #
+ # If "enable = no" below, you CANNOT
+ # enable resumption for just one user
+ # by setting the above attribute to "yes".
+ #
+ enable = no
+
+ #
+ # Lifetime of the cached entries, in hours.
+ # The sessions will be deleted after this
+ # time.
+ #
+ lifetime = 24 # hours
+
+ #
+ # Internal "name" of the session cache.
+ # Used to distinguish which TLS context
+ # sessions belong to.
+ #
+ # The server will generate a random value
+ # if unset. This will change across server
+ # restart so you MUST set the "name" if you
+ # want to persist sessions (see below).
+ #
+ # If you use IPv6, change the "ipaddr" below
+ # to "ipv6addr"
+ #
+ #name = "TLS ${..ipaddr} ${..port} ${..proto}"
+
+ #
+ # Simple directory-based storage of sessions.
+ # Two files per session will be written, the SSL
+ # state and the cached VPs. This will persist session
+ # across server restarts.
+ #
+ # The server will need write perms, and the directory
+ # should be secured from anyone else. You might want
+ # a script to remove old files from here periodically:
+ #
+ # find ${logdir}/tlscache -mtime +2 -exec rm -f {} \;
+ #
+ # This feature REQUIRES "name" option be set above.
+ #
+ #persist_dir = "${logdir}/tlscache"
+ }
+
+ #
+ # Require a client certificate.
+ #
+ require_client_cert = yes
+
+ #
+ # As of version 2.1.10, client certificates can be
+ # validated via an external command. This allows
+ # dynamic CRLs or OCSP to be used.
+ #
+ # This configuration is commented out in the
+ # default configuration. Uncomment it, and configure
+ # the correct paths below to enable it.
+ #
+ verify {
+ # A temporary directory where the client
+ # certificates are stored. This directory
+ # MUST be owned by the UID of the server,
+ # and MUST not be accessible by any other
+ # users. When the server starts, it will do
+ # "chmod go-rwx" on the directory, for
+ # security reasons. The directory MUST
+ # exist when the server starts.
+ #
+ # You should also delete all of the files
+ # in the directory when the server starts.
+ # tmpdir = /tmp/radiusd
+
+ # The command used to verify the client cert.
+ # We recommend using the OpenSSL command-line
+ # tool.
+ #
+ # The ${..ca_path} text is a reference to
+ # the ca_path variable defined above.
+ #
+ # The %{TLS-Client-Cert-Filename} is the name
+ # of the temporary file containing the cert
+ # in PEM format. This file is automatically
+ # deleted by the server when the command
+ # returns.
+ # client = "/path/to/openssl verify -CApath ${..ca_path} %{TLS-Client-Cert-Filename}"
+ }
+
+ #
+ # When the RadSec clients use SNI, the server will
+ # automatically choose the correct certificate from
+ # "realm_dir". See raddb/certs/realms/README.md for
+ # more information.
+ #
+ # Note that the default is to use the same set of
+ # realm certificates for both EAP and RadSec! If
+ # this is not what you want, you should use different
+ # subdirectories or each, e.g. ${certdir}/realms/radsec/,
+ # and ${certdir}/realms/eap/
+ #
+ # realm_dir = ${certdir}/realms/
+ }
+}
+
+clients radsec {
+ client 127.0.0.1 {
+ ipaddr = 127.0.0.1
+
+ #
+ # Ensure that this client is TLS *only*.
+ #
+ proto = tls
+
+ #
+ # TCP clients can have any shared secret.
+ #
+ # TLS clients MUST have the shared secret
+ # set to "radsec". Or, for "proto = tls",
+ # you can omit the secret, and it will
+ # automatically be set to "radsec".
+ #
+ secret = radsec
+
+ #
+ # You can also use a "limit" section here.
+ # See raddb/clients.conf for examples.
+ #
+ # Note that BOTH limits are applied. You
+ # should therefore set the "listen" limits
+ # higher than the ones for each individual
+ # client.
+ #
+ }
+}
+
+#
+# When a request is proxied to a TLS-enabled home server,
+# the TLS parameters are available via the expansion:
+#
+# %{proxy_listen: ... }
+#
+# The contents of the expansion are the same as described
+# above with the %{listen: ... } expansion, and have similar
+# meanings. "client" in this case is the proxy (this system)
+# and "server" is the remote system (home server).
+#
+# Note that the %{proxy_listen: ... } parameters are available
+# only AFTER the connection has been made to the home server.
+#
+home_server tls {
+ ipaddr = 127.0.0.1
+ port = 2083
+
+ # type can be the same types as for the "listen" section/
+ # e.g. auth, acct, auth+acct, coa
+ type = auth
+ secret = radsec
+ proto = tcp
+ status_check = none
+
+ tls {
+ #
+ # Similarly to HTTP, the client can use Server Name
+ # Indication to inform the RadSec server as to which
+ # domain it is requesting. This selection allows
+ # multiple sites to exist at the same IP address.
+ #
+ # For example, an identity provider could host
+ # multiple sites, but present itself with one public
+ # IP address. If the RadSec clients do not use SNI,
+ # then they must be configured with the certificate
+ # of the identity provider.
+ #
+ # When SNI is used, the clients can be configured
+ # with the certificate of the hosted system that
+ # they're connecting to. This ability means that
+ # there is no need to change certificates when
+ # changing providers. In addition, there is no need
+ # to change the configuration of all RadSec clients
+ # when the hosting system changes its certifiates.
+ # Because the hosting system certificates are never used.
+ #
+ # Instead, each hosted company is responsible for its
+ # own certificates, and for its own clients.
+ #
+ # SNI also permits the use of a load balancer such as
+ # haproxy. That load balancer can terminate the TLS
+ # connection, and then use SNI to route the
+ # underlying RADIUS TCP traffic to a particular host.
+ #
+ # Note that "hostname" here is only for SNI, and is NOT
+ # the hostname or IP address we connect to. For that,
+ # see "ipaddr", above.
+ #
+ # hostname = "example.com"
+
+ private_key_password = whatever
+ private_key_file = ${certdir}/client.pem
+
+ # If Private key & Certificate are located in
+ # the same file, then private_key_file &
+ # certificate_file must contain the same file
+ # name.
+ #
+ # If ca_file (below) is not used, then the
+ # certificate_file below MUST include not
+ # only the server certificate, but ALSO all
+ # of the CA certificates used to sign the
+ # server certificate.
+ certificate_file = ${certdir}/client.pem
+
+ # Trusted Root CA list
+ #
+ # ALL of the CA's in this list will be trusted
+ # to issue client certificates for authentication.
+ #
+ # In general, you should use self-signed
+ # certificates for 802.1x (EAP) authentication.
+ # In that case, this CA file should contain
+ # *one* CA certificate.
+ #
+ # This parameter is used only for EAP-TLS,
+ # when you issue client certificates. If you do
+ # not use client certificates, and you do not want
+ # to permit EAP-TLS authentication, then delete
+ # this configuration item.
+ ca_file = ${cadir}/ca.pem
+
+ #
+ # Before version 3.2.1, outbound RadSec connections
+ # would put the home server certificate into the
+ # TLS-Client-Cert* attributes. Set this configuration
+ # item to "yes" in order to have the home server
+ # certificates placed into the "TLS-Cert-*" attributes.
+ #
+# fix_cert_order = yes
+
+ #
+ # For TLS-PSK, the key should be specified
+ # dynamically, instead of using a hard-coded
+ # psk_identity and psk_hexphrase.
+ #
+ # The input to the dynamic expansion will be the PSK
+ # identity supplied by the client, in the
+ # TLS-PSK-Identity attribute. The output of the
+ # expansion should be a hex string, of no more than
+ # 512 characters. The string should not be prefixed
+ # with "0x". e.g. "abcdef" is OK. "0xabcdef" is not.
+ #
+ # psk_query = "%{psksql:select hex(key) from psk_keys where keyid = '%{TLS-PSK-Identity}'}"
+
+ #
+ # For DH cipher suites to work, you have to
+ # run OpenSSL to create the DH file first:
+ #
+ # openssl dhparam -out certs/dh 1024
+ #
+# dh_file = ${certdir}/dh
+# random_file = /dev/urandom
+
+ #
+ # The default fragment size is 1K.
+ # However, TLS can send 64K of data at once.
+ # It can be useful to set it higher.
+ #
+ fragment_size = 8192
+
+ # include_length is a flag which is
+ # by default set to yes If set to
+ # yes, Total Length of the message is
+ # included in EVERY packet we send.
+ # If set to no, Total Length of the
+ # message is included ONLY in the
+ # First packet of a fragment series.
+ #
+ # include_length = yes
+
+ # Check the Certificate Revocation List
+ #
+ # 1) Copy CA certificates and CRLs to same directory.
+ # 2) Execute 'c_rehash <CA certs&CRLs Directory>'.
+ # 'c_rehash' is OpenSSL's command.
+ # 3) uncomment the line below.
+ # 5) Restart radiusd
+ # check_crl = yes
+ ca_path = ${cadir}
+
+ #
+ # If check_cert_issuer is set, the value will
+ # be checked against the DN of the issuer in
+ # the client certificate. If the values do not
+ # match, the certificate verification will fail,
+ # rejecting the user.
+ #
+ # In 2.1.10 and later, this check can be done
+ # more generally by checking the value of the
+ # TLS-Client-Cert-Issuer attribute. This check
+ # can be done via any mechanism you choose.
+ #
+ # check_cert_issuer = "/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd"
+
+ #
+ # If check_cert_cn is set, the value will
+ # be xlat'ed and checked against the CN
+ # in the client certificate. If the values
+ # do not match, the certificate verification
+ # will fail rejecting the user.
+ #
+ # This check is done only if the previous
+ # "check_cert_issuer" is not set, or if
+ # the check succeeds.
+ #
+ # In 2.1.10 and later, this check can be done
+ # more generally by checking the value of the
+ # TLS-Client-Cert-Common-Name attribute. This check
+ # can be done via any mechanism you choose.
+ #
+ # check_cert_cn = %{User-Name}
+ #
+ # Set this option to specify the allowed
+ # TLS cipher suites. The format is listed
+ # in "man 1 ciphers".
+ cipher_list = "DEFAULT"
+
+ #
+ # Connection timeout for outgoing TLS connections.
+ # Values are 1..30.
+ #
+ connect_timeout = 30
+ }
+}
+
+home_server_pool tls {
+ type = fail-over
+ home_server = tls
+}
+
+realm tls {
+ auth_pool = tls
+}
diff --git a/raddb/sites-available/tls-cache b/raddb/sites-available/tls-cache
new file mode 100644
index 0000000..e6451c5
--- /dev/null
+++ b/raddb/sites-available/tls-cache
@@ -0,0 +1,144 @@
+# -*- text -*-
+######################################################################
+#
+# This is a virtual server which handles TLS session caching.
+#
+# $Id$
+#
+######################################################################
+#
+# In mods-enabled/eap, "cache" subsection
+#
+# comment out
+#
+# persist_dir
+#
+# add
+#
+# virtual_server = tls-cache
+#
+# and set
+#
+# enable = yes
+#
+# In order to enable caching.
+#
+
+#
+# This virtual server SHOULD NOT have any "listen" sections.
+#
+#
+# All of the cache sections key off of &request:TLS-Session-Id
+#
+# The cache sections also run the "post-auth" section of any
+# module which they use.
+#
+# These sections do not need to return any specific codes (e.g. ok /
+# fail /etc.). The cache functionality depends only on which
+# attributes are saved / loaded.
+#
+# For example, if the "cache save" process fails, there is nothing
+# that the server can do about that. The users authentication
+# session will still succeed. The only difference from a successful
+# "cache save" is that the user will be unable to resume their
+# session. Instead, they will need to do a full re-authentication
+# process.
+#
+# Similarly for "cache load". If the session (and/or) the VPs are
+# not loaded from the cache, then the user will do a full
+# re-authentication.
+#
+# Whilst any store can be used for tls session caching, whatever is
+# chosen should be faster than performing a full re-authentication
+server tls-cache {
+
+cache clear {
+ # clear the cache entry by keying off of &request:TLS-Session-Id
+
+ # An example using redis
+# "%{redis:DEL %{request:TLS-Session-ID}}"
+
+ # An example using SQL
+# "%{sql:DELETE FROM tls_cache WHERE session_id = '%{request:TLS-Session-ID}'}"
+}
+
+cache save {
+ # use the key &request:TLS-Session-ID
+ # save &session-state:TLS-Session-Data
+ # save &reply:...
+
+ # The &reply: list is initialized to the attributes
+ # which should be saved. This includes attributes
+ # mentioned in the "store" subsection of the "cache"
+ # section configuration. This is the same set of
+ # attributes which is saved when the 'persist_dir'
+ # configuration is used.
+ #
+ # Note the "store" subsection will only copy matching
+ # attributes from the &reply: list at the time that
+ # eap authentication succeeds.
+ #
+ # Other attributes can be saved by referring to them
+ # e.g. &outer.request:...
+
+ # An example using redis
+# update {
+# &Tmp-String-0 := "%{session-state:TLS-Session-Data}|%{escape:%{reply:Tunnel-Private-Group-ID}}"
+# }
+# "%{redis: SET %{request:TLS-Session-ID} \"%{Tmp-String-0}\" EX 86400}"
+
+ # An example using SQL
+# "%{sql: INSERT INTO tls_cache (session_id, session_data, vlan, expiry) VALUES ('%{request:TLS-Session-ID}', '%{session-state:TLS-Session-Data}', '%{escape:%{reply:Tunnel-Private-Group-ID}}', DATE_ADD(NOW(), INTERVAL 24 HOUR))}"
+}
+
+cache load {
+ # use the key &request:TLS-Session-ID
+ # load &session-state:TLS-Session-Data
+ # load &reply:...
+
+ # Attributes returned in &reply: which are listed
+ # in the "store" subsection of the "cache" section
+ # configuration will be copied to &session-state:
+ #
+ # Certificate attributes returned in &reply: are added
+ # to &request: if they do not already exist and if
+ # EAP-Type is returned it is added to &control:
+ #
+ # Any other attributes returned are added to &reply:
+
+ # An example using redis
+# update {
+# &Tmp-String-0 := "%{redis:GET %{request:TLS-Session-ID}}"
+# }
+# if (!&Tmp-String-0 || &Tmp-String-0 !~ /^([^|]+)\|([^|]+)$/) {
+# return
+# }
+# update {
+# &session-state:TLS-Session-Data := "%{1}"
+# &reply:Tunnel-Private-Group-ID := "%{unescape:%{2}}"
+# }
+
+ # An example using SQL
+# update {
+# &Tmp-String-0 := "%{sql:SELECT CONCAT(session_data, '|', vlan) FROM session_cache WHERE session_id = '%{request:TLS-Session-ID}'}"
+# }
+# if (!&Tmp-String-0 || &Tmp-String-0 !~ /^([^|]+)\|([^|]+)$/) {
+# return
+# }
+# update {
+# &session-state:TLS-Session-Data := "%{1}"
+# &reply:Tunnel-Private-Group-ID := "%{unescape:%{2}}"
+# }
+}
+
+cache refresh {
+ # refresh the cache entry by keying off of &request:TLS-Session-ID
+
+ # An example using redis
+# "%{redis:EXPIRE %{request:TLS-Session-ID} 86400}"
+
+ # An example using SQL
+# "%{sql:UPDATE tls_cache SET expiry = DATE_ADD(NOW(), INTERVAL 24 HOUR) WHERE session_id = '%{request:TLS-Session-ID}'}"
+}
+
+}