######################################################################
#
#  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

	#
	#  We have clients specifically for TLS.
	#
	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

	#
	#  This configuration item should be enabled for all listen
	#  sections which do TLS.
	#
	#  It is only disabled because we are careful about changing
	#  existing behavior in a stable release.
	#
	#  Setting this configuration item to "yes" means that the
	#  server will be able to gracefully recover if a TLS
	#  connection is blocking at the network layer.
	#
	#  Note that setting "nonblock = yes" is NOT possible for bare
	#  TCP connections.  RADIUS/TCP should generally be avoided.
	#
#	nonblock = yes

	#
	#  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"

		#
		#  See mods-available/eap for documentation
		#
		ecdh_curve = ""

		#
		#  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.
		#
		#  If you set this to "no", then any client can
		#  connect anonymously.  This is bad, and is likely
		#  not what you want.
		#
		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.
			#
			#  Note that, on Linux systems with systemd, the
			#  /tmp directory may be restricted. In this case
			#  it may be best to use `${run_dir}/tmp` here
			#  and create the temporary directory with the
			#  systemd `RuntimeDirectory` unit option.
			#
	#		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

	#
	#  This configuration item should be enabled for all
	#  home_server sections which do TLS.
	#
	#  It is only disabled because we are careful about changing
	#  existing behavior in a stable release.
	#
	#  Setting this configuration item to "yes" means that the
	#  server will be able to gracefully recover if a TLS
	#  connection is blocking at the network layer.
	#
	#  Note that setting "nonblock = yes" is NOT possible for bare
	#  TCP connections.  RADIUS/TCP should generally be avoided.
	#
#	nonblock = yes

	#
	#  The TLS settings used by the proxy (i.e. RADIUS client)
	#  when it connects to a home server.
	#
	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 TLS-PSK, you can hard-code a fixed PSK identity
		#  and (hex) password here.
		#
	#	psk_identity = "test"
	#	psk_hexphrase = "036363823"

		#
		#  For TLS-PSK, uncomment the following line to use
		#  standard ciphers for TLS 1.3.
		#
		#  TLS-PSK may work without this line, but it is
		#  likely to not work when the "next hop" home_server
		#  accepts both certificates and PSK.  OpenSSL will
		#  negotiate cipher suites which are incompatible with
		#  PSK, and then fail.
		#
		#  Setting the cipher_suites here forces PSK to be negotiated.
		#
	#	cipher_suites = "TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"

		#
		#  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
}
