diff --git a/radius-server/defaults/main.yml b/radius-server/defaults/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..1c7ce992972762a2654e93c029876833b1cda3e8 --- /dev/null +++ b/radius-server/defaults/main.yml @@ -0,0 +1,47 @@ +--- + +radius_ldap_server: + ad.example.com: 'ad.example.com' + ad2.example.com: 'ad2.example.com' +radius_ldap_bind_user: "cn=radius,cn=users,dc=example,dc=com" +radius_ldap_bind_pass: "" +radius_ldap_base_dn: "cn=users,dc=example,dc=com" + +radius_certs_dir: "{{ inventory_dir }}/files/radius-certs/" +radius_secret_localclient: testing123 +radius_secret_cert: testing123 + +radius_mschapv2_identity: ad.example.com +radius_ntlm_domain: EXAMPLE + +radius_clients: + - name: example + ip: 10.10.10.10 + secret: testing123 + +radius_realms: + - example.com + - ssl.example.com +radius_default_realm: example.com + +radius_vlan_assignments: + - key: User-Name + condition: =~ + value: '"^host\/.*\.example\.com$"' + vlan: 23 + - key: User-Name + condition: =~ + value: '"^lxc.*@ssl\.example\.com$"' + vlan: 23 + - key: Ldap-Group + condition: == + value: vlan42 + vlan: 42 + +radius_tunnel_checks: + - station: OtherStationSSID + condition: '(Ldap-Group == "CN=vlan42,CN=Users,DC=asta,DC=rwth-aachen,DC=de") || (&User-Name =~ /^host\/.*\.example\.com$/ )' + error: 'Not allowed to use this SSID' + - condition: '(&User-Name =~ /^host\/.*\.example\.com$/ ) || (Ldap-Group == "CN=foobar,CN=Users,DC=asta,DC=rwth-aachen,DC=de")' + error: 'User not allowed' + diff --git a/radius-server/handlers/main.yml b/radius-server/handlers/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..454c6c882b090cd2d6a1282132cedfba2e8bda3e --- /dev/null +++ b/radius-server/handlers/main.yml @@ -0,0 +1,4 @@ +--- + +- name: reload freeradius + service: name=freeradius state=restarted diff --git a/radius-server/tasks/main.yml b/radius-server/tasks/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..a8655b6f9289fe8ea1c07222eed2384f2d97bde6 --- /dev/null +++ b/radius-server/tasks/main.yml @@ -0,0 +1,105 @@ +--- + +- name: ensure freeradius server is installed + apt: + name: "{{ item }}" + state: present + with_items: + - freeradius + - freeradius-config + - freeradius-ldap + - freeradius-mysql + - freeradius-postgresql + - freeradius-utils + - winbind + tags: + - radius-server + - packages + +- name: ensure freeradius server SSL configuration + copy: + src: "{{ radius_certs_dir }}/{{ item }}" + dest: /etc/freeradius/3.0/certs/ + owner: root + group: freerad + mode: 0640 + with_items: + - dh + - cacert.pem + - "{{ ansible_fqdn }}.pem" + - "{{ ansible_fqdn }}.key" + notify: + - reload freeradius + tags: + - freeradius + - config + +- name: configure available modules + template: + src: "{{ item }}.j2" + dest: "/etc/freeradius/3.0/{{ item }}" + owner: root + group: root + mode: 0644 + with_items: + - mods-available/eap + - mods-available/ldap + notify: + - reload freeradius + tags: + - freeradius + - config + +- name: ensure freeradius server sites and policies are configured + template: + src: "{{ item }}.j2" + dest: "/etc/freeradius/3.0/{{ item }}" + owner: root + group: freerad + mode: 0640 + with_items: + - mods-available/mschap + - mods-available/realm + - mods-available/ntlm_auth + - clients.conf + - proxy.conf + - sites-available/default + - sites-available/inner-tunnel + - policy.d/rewrite_station_to_ssid + - policy.d/ntlm_auth + - mods-config/files/authorize + notify: + - reload freeradius + tags: + - freeradius + +- name: enable freeradius server modules + file: + src: "/etc/freeradius/3.0/mods-available/{{ item }}" + dest: "/etc/freeradius/3.0/mods-enabled/{{ item }}" + state: link + with_items: + - ldap + - eap + - mschap + - realm + - ntlm_auth + notify: + - reload freeradius + tags: + - freeradius + +- name: enable freeradius server sites + file: + src: "/etc/freeradius/3.0/sites-available/{{ item }}" + dest: "/etc/freeradius/3.0/sites-enabled/{{ item }}" + state: link + with_items: + - default + - inner-tunnel + notify: + - reload freeradius + tags: + - freeradius + +- meta: flush_handlers diff --git a/radius-server/templates/clients.conf.j2 b/radius-server/templates/clients.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..306a69fdb69cea04b233198bd15993662171a52b --- /dev/null +++ b/radius-server/templates/clients.conf.j2 @@ -0,0 +1,96 @@ +# -*- text -*- +## +## clients.conf -- client configuration directives +## +## $Id: 76b300d3c55f1c5c052289b76bf28ac3a370bbb2 $ + +####################################################################### +# +# Define RADIUS clients (usually a NAS, Access Point, etc.). + +# +# Defines a RADIUS client. +# +# '127.0.0.1' is another name for 'localhost'. It is enabled by default, +# to allow testing of the server after an initial installation. If you +# are not going to be permitting RADIUS queries from localhost, we suggest +# that you delete, or comment out, this entry. +# +# + +# +# Each client has a "short name" that is used to distinguish it from +# other clients. +# +# In version 1.x, the string after the word "client" was the IP +# address of the client. In 2.0, the IP address is configured via +# the "ipaddr" or "ipv6addr" fields. For compatibility, the 1.x +# format is still accepted. +# +client localhost { + # Only *one* of ipaddr, ipv4addr, ipv6addr may be specified for + # a client. + ipaddr = 127.0.0.1 + + proto = * + + # + # The shared secret use to "encrypt" and "sign" packets between + # the NAS and FreeRADIUS. You MUST change this secret from the + # default, otherwise it's not a secret any more! + secret = {{ radius_secret_localclient }} + + # + # Old-style clients do not send a Message-Authenticator + # in an Access-Request. RFC 5080 suggests that all clients + # SHOULD include it in an Access-Request. The configuration + # item below allows the server to require it. If a client + # is required to include a Message-Authenticator and it does + # not, then the packet will be silently discarded. + # + # allowed values: yes, no + require_message_authenticator = no + + shortname = localhost + + # + # As of 2.0, clients can also be tied to a virtual server. + # This is done by setting the "virtual_server" configuration + # item, as in the example below. + # +# virtual_server = home1 + + + # + # Connection limiting for clients using "proto = tcp". + # + # This section is ignored for clients sending UDP traffic + # + limit { + # Limit the number of simultaneous TCP connections from a client + max_connections = 16 + + # The per-socket "max_requests" option does not exist. + 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. + idle_timeout = 30 + } +} + +# IPv6 Client +client localhost_ipv6 { + ipv6addr = ::1 + secret = testing123 +} + +{%- for client in radius_clients %} +client {{ client.name }} { + ipaddr = {{ client.ip }} + secret = {{ client.secret }} +} +{% endfor -%} + diff --git a/radius-server/templates/mods-available/eap.j2 b/radius-server/templates/mods-available/eap.j2 new file mode 100644 index 0000000000000000000000000000000000000000..6160697d17191959f954f4069d85457b51b5b438 --- /dev/null +++ b/radius-server/templates/mods-available/eap.j2 @@ -0,0 +1,262 @@ +# -*- text -*- +## +## eap.conf -- Configuration for EAP types (PEAP, TTLS, etc.) +## +## $Id: 1b69550d28293a76de7c6aa7389ad318696b8509 $ + +####################################################################### +# +# Whatever you do, do NOT set 'Auth-Type := EAP'. The server +# is smart enough to figure this out on its own. The most +# common side effect of setting 'Auth-Type := EAP' is that the +# users then cannot use ANY other authentication method. +# +eap { + default_eap_type = peap + timer_expire = 60 + + ignore_unknown_eap_types = no + + cisco_accounting_username_bug = no + max_sessions = ${max_requests} + + # Supported EAP-types + + ## Common TLS configuration for TLS-based EAP types + tls-config tls-common { + private_key_password = {{ radius_secret_cert }} + private_key_file = ${certdir}/{{ ansible_fqdn }}.key + certificate_file = ${certdir}/{{ ansible_fqdn }}.pem + + ca_file = ${certdir}/cacert.pem + + dh_file = ${certdir}/dh + random_file = /dev/urandom + + # 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 lines below. + # 5) Restart radiusd + # check_crl = yes + # Check if intermediate CAs have been revoked. + # check_all_crl = yes + + ca_path = ${cadir} + + + # In 2.1.10 and later, this check can be done + # more generally by checking the value of the + # TLS-Client-Cert-CN 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" + + # Work-arounds for OpenSSL nonsense + # OpenSSL 1.0.1f and 1.0.1g do not calculate + # the EAP keys correctly. The fix is to upgrade + # OpenSSL, or disable TLS 1.2 here. +# disable_tlsv1_2 = no + + # + + # Elliptical cryptography configuration + ecdh_curve = "prime256v1" + + cache { + enable = no + lifetime = 24 # hours + max_entries = 255 + + # + # 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). + # + #name = "EAP module" + + # + # 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" + } + + # + # 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. + # + # If OCSP checking is enabled, and the OCSP checks fail, + # the verify section is skipped. + # + verify { + # If the OCSP checks succeed, the verify section + # is run to allow additional checks. + # + # If you want to skip verify on OCSP success, + # uncomment this configuration item, and set it + # to "yes". + # skip_if_ocsp_ok = no + + # 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}" + } + + # + # OCSP Configuration + # Certificates can be verified against an OCSP + # Responder. This makes it possible to immediately + # revoke certificates without the distribution of + # new Certificate Revocation Lists (CRLs). + # + ocsp { + # + # Enable it. The default is "no". + # Deleting the entire "ocsp" subsection + # also disables ocsp checking + # + enable = no + + # + # The OCSP Responder URL can be automatically + # extracted from the certificate in question. + # To override the OCSP Responder URL set + # "override_cert_url = yes". + # + override_cert_url = yes + + # + # If the OCSP Responder address is not extracted from + # the certificate, the URL can be defined here. + # + url = "http://127.0.0.1/ocsp/" + } + } + + ## EAP-TLS + tls { + tls = tls-common + + # + # As part of checking a client certificate, the EAP-TLS + # sets some attributes such as TLS-Client-Cert-CN. This + # virtual server has access to these attributes, and can + # be used to accept or reject the request. + # + # virtual_server = check-eap-tls + } + + + ## EAP-TTLS + ttls { + tls = tls-common + default_eap_type = mschapv2 + + # This seems to effectively destroy the user.name propagation for session logging --> Disabled + # However, if it is disabled the authentication does not work properly + copy_request_to_tunnel = yes + use_tunneled_reply = yes + + virtual_server = "inner-tunnel" + + + # + # Unlike EAP-TLS, EAP-TTLS does not require a client + # certificate. However, you can require one by setting the + # following option. You can also override this option by + # setting + # + # EAP-TLS-Require-Client-Cert = Yes + # + # in the control items for a request. + # + # require_client_cert = yes + } + + + ## EAP-PEAP + peap { + tls = tls-common + default_eap_type = tls #mschapv2 + + # This seems to effectively destroy the user.name propagation for session logging --> Disabled + # However, if it is disabled the authentication does not work properly + copy_request_to_tunnel = yes + use_tunneled_reply = yes + + virtual_server = "inner-tunnel" + + # This option enables support for MS-SoH + # see doc/SoH.txt for more info. + # It is disabled by default. + # + # soh = yes + # soh_virtual_server = "soh-server" + + # + # Unlike EAP-TLS, PEAP does not require a client certificate. + # However, you can require one by setting the following + # option. You can also override this option by setting + # + # EAP-TLS-Require-Client-Cert = Yes + # + # in the control items for a request. + # + # require_client_cert = yes + } + + mschapv2 { + identity = "{{ radius_mschapv2_identity }}" + } +} diff --git a/radius-server/templates/mods-available/ldap.j2 b/radius-server/templates/mods-available/ldap.j2 new file mode 100644 index 0000000000000000000000000000000000000000..135c21e6972bcabdb051f2217d7a8b8fcc91c7f2 --- /dev/null +++ b/radius-server/templates/mods-available/ldap.j2 @@ -0,0 +1,362 @@ +# -*- text -*- +# +# $Id: 0a1cf0221a9cbc95001d86d2ba3b16ac99330471 $ + +# +# Lightweight Directory Access Protocol (LDAP) +# +ldap { + # Note that this needs to match the name(s) in the LDAP server + # certificate, if you're using ldaps. See OpenLDAP documentation + # for the behavioral semantics of specifying more than one host. + # + # Depending on the libldap in use, server may be an LDAP URI. + # In the case of OpenLDAP this allows additional the following + # additional schemes: + # - ldaps:// (LDAP over SSL) + # - ldapi:// (LDAP over Unix socket) + # - ldapc:// (Connectionless LDAP) + server = '{{ radius_ldap_server[ansible_fqdn] }}' + + # Port to connect on, defaults to 389, will be ignored for LDAP URIs. +# port = 389 + + identity = '{{ radius_ldap_bind_user }}' + password = '{{ radius_ldap_bind_pass }}' + + base_dn = '{{ radius_ldap_base_dn }}' + + sasl { + } + + + # + # Mapping of LDAP directory attributes to RADIUS dictionary attributes. + # + + # WARNING: Although this format is almost identical to the unlang + # update section format, it does *NOT* mean that you can use other + # unlang constructs in module configuration files. + # + # Configuration items are in the format: + # <radius attr> <op> <ldap attr> + # + # Where: + # <radius attr>: Is the destination RADIUS attribute + # with any valid list and request qualifiers. + # <op>: Is any assignment attribute (=, :=, +=, -=). + # <ldap attr>: Is the attribute associated with user or + # profile objects in the LDAP directory. + # If the attribute name is wrapped in double + # quotes it will be xlat expanded. + # + # Request and list qualifiers may also be placed after the 'update' + # section name to set defaults destination requests/lists + # for unqualified RADIUS attributes. + # + # Note: LDAP attribute names should be single quoted unless you want + # the name value to be derived from an xlat expansion, or an + # attribute ref. + update { + control:Password-With-Header += 'userPassword' +# control:NT-Password := 'ntPassword' +# reply:Reply-Message := 'radiusReplyMessage' +# reply:Tunnel-Type := 'radiusTunnelType' +# reply:Tunnel-Medium-Type := 'radiusTunnelMediumType' +# reply:Tunnel-Private-Group-ID := 'radiusTunnelPrivategroupId' + + # Where only a list is specified as the RADIUS attribute, + # the value of the LDAP attribute is parsed as a valuepair + # in the same format as the 'valuepair_attribute' (above). + control: += 'radiusControlAttribute' + request: += 'radiusRequestAttribute' + reply: += 'radiusReplyAttribute' + } + + # Set to yes if you have eDirectory and want to use the universal + # password mechanism. +# edir = no + + # Set to yes if you want to bind as the user after retrieving the + # Cleartext-Password. This will consume the login grace, and + # verify user authorization. +# edir_autz = no + + # Note: set_auth_type was removed in v3.x.x + # Equivalent functionality can be achieved by adding the following + # stanza to the authorize {} section of your virtual server. + # + # ldap + # if ((ok || updated) && User-Password) { + # update { + # control:Auth-Type := ldap + # } + # } + + # + # User object identification. + # + user { + base_dn = "${..base_dn}" +{% raw %} + filter = "(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}})" +{% endraw %} + sasl { + # SASL mechanism +# mech = 'PLAIN' + + # SASL authorisation identity to proxy. +# proxy = &User-Name + + # SASL realm. Used for kerberos. +# realm = 'example.org' + } + +# scope = 'sub' + } + + # + # User membership checking. + # + group { + # Where to start searching in the tree for groups + base_dn = "${..base_dn}" + + # Filter for group objects, should match all available + # group objects a user might be a member of. + filter = '(objectClass=group)' + + # Search scope, may be 'base', 'one', sub' or 'children' +# scope = 'sub' + + name_attribute = cn + +{% raw %} +# membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))" + membership_filter = "(&(objectcategory=group)(member:1.2.840.113556.1.4.1941:=%{control:Ldap-UserDn}))" +{% endraw %} + membership_attribute = 'memberOf' + } + + # + # User profiles. RADIUS profile objects contain sets of attributes + # to insert into the request. These attributes are mapped using + # the same mapping scheme applied to user objects (the update section above). + # + profile { + } + + # + # Bulk load clients from the directory + # + client { + base_dn = "${..base_dn}" + filter = '(objectClass=radiusClient)' + +# scope = 'sub' + template { +# login = 'test' +# password = 'test' +# proto = tcp +# require_message_authenticator = yes + + # Uncomment to add a home_server with the same + # attributes as the client. +# coa_server { +# response_window = 2.0 +# } + } + + attribute { + ipaddr = 'radiusClientIdentifier' + secret = 'radiusClientSecret' +# shortname = 'radiusClientShortname' +# nas_type = 'radiusClientType' +# virtual_server = 'radiusClientVirtualServer' +# require_message_authenticator = 'radiusClientRequireMa' + } + } + + # Load clients on startup + read_clients = no + + # + # Modify user object on receiving Accounting-Request + # + + accounting { + } + + # + # Post-Auth can modify LDAP objects too + # +# post-auth { +# update { +# description := "Authenticated at %S" +# } +# } + + # + # LDAP connection-specific options. + # + # These options set timeouts, keep-alives, etc. for the connections. + # + options { + # Control under which situations aliases are followed. + # May be one of 'never', 'searching', 'finding' or 'always' + # default: libldap's default which is usually 'never'. + # + # LDAP_OPT_DEREF is set to this value. +# dereference = 'always' + + # + # The following two configuration items control whether the + # server follows references returned by LDAP directory. + # They are mostly for Active Directory compatibility. + # If you set these to 'no', then searches will likely return + # 'operations error', instead of a useful result. + # + chase_referrals = yes + rebind = yes + + # Seconds to wait for LDAP query to finish. default: 20 + res_timeout = 10 + + # Seconds LDAP server has to process the query (server-side + # time limit). default: 20 + # + # LDAP_OPT_TIMELIMIT is set to this value. + srv_timelimit = 3 + + # Seconds to wait for response of the server. (network + # failures) default: 10 + # + # LDAP_OPT_NETWORK_TIMEOUT is set to this value. + net_timeout = 1 + + # LDAP_OPT_X_KEEPALIVE_IDLE + idle = 60 + + # LDAP_OPT_X_KEEPALIVE_PROBES + probes = 3 + + # LDAP_OPT_X_KEEPALIVE_INTERVAL + interval = 3 + + # ldap_debug: debug flag for LDAP SDK + # (see OpenLDAP documentation). Set this to enable + # huge amounts of LDAP debugging on the screen. + # You should only use this if you are an LDAP expert. + # + # default: 0x0000 (no debugging messages) + # Example:(LDAP_DEBUG_FILTER+LDAP_DEBUG_CONNS) + ldap_debug = 0x0028 + } + + # + # This subsection configures the tls related items + # that control how FreeRADIUS connects to an LDAP + # server. It contains all of the 'tls_*' configuration + # entries used in older versions of FreeRADIUS. Those + # configuration entries can still be used, but we recommend + # using these. + # + tls { + # Set this to 'yes' to use TLS encrypted connections + # to the LDAP database by using the StartTLS extended + # operation. + # + # The StartTLS operation is supposed to be + # used with normal ldap connections instead of + # using ldaps (port 636) connections + start_tls = yes + + ca_file = ${certdir}/cacert.pem + +# ca_path = ${certdir} +# certificate_file = /path/to/radius.crt +# private_key_file = /path/to/radius.key +# random_file = /dev/urandom + + # Certificate Verification requirements. Can be: + # 'never' (do not even bother trying) + # 'allow' (try, but don't fail if the certificate + # cannot be verified) + # 'demand' (fail if the certificate does not verify) + # 'hard' (similar to 'demand' but fails if TLS + # cannot negotiate) + # + # The default is libldap's default, which varies based + # on the contents of ldap.conf. + + require_cert = 'demand' + } + + # As of version 3.0, the 'pool' section has replaced the + # following configuration items: + # + # ldap_connections_number + + # The connection pool is new for 3.0, and will be used in many + # modules, for all kinds of connection-related activity. + # + # When the server is not threaded, the connection pool + # limits are ignored, and only one connection is used. + pool { + # Connections to create during module instantiation. + # If the server cannot create specified number of + # connections during instantiation it will exit. + # Set to 0 to allow the server to start without the + # directory being available. + start = ${thread[pool].start_servers} + + # Minimum number of connections to keep open + min = ${thread[pool].min_spare_servers} + + # Maximum number of connections + # + # If these connections are all in use and a new one + # is requested, the request will NOT get a connection. + # + # Setting 'max' to LESS than the number of threads means + # that some threads may starve, and you will see errors + # like 'No connections available and at max connection limit' + # + # Setting 'max' to MORE than the number of threads means + # that there are more connections than necessary. + max = ${thread[pool].max_servers} + + # Spare connections to be left idle + # + # NOTE: Idle connections WILL be closed if "idle_timeout" + # is set. This should be less than or equal to "max" above. + spare = ${thread[pool].max_spare_servers} + + # Number of uses before the connection is closed + # + # 0 means "infinite" + uses = 0 + + # The number of seconds to wait after the server tries + # to open a connection, and fails. During this time, + # no new connections will be opened. + retry_delay = 30 + + # The lifetime (in seconds) of the connection + lifetime = 0 + + # Idle timeout (in seconds). A connection which is + # unused for this length of time will be closed. + idle_timeout = 60 + + # NOTE: All configuration settings are enforced. If a + # connection is closed because of 'idle_timeout', + # 'uses', or 'lifetime', then the total number of + # connections MAY fall below 'min'. When that + # happens, it will open a new connection. It will + # also log a WARNING message. + # + # The solution is to either lower the 'min' connections, + # or increase lifetime/idle_timeout. + } +} diff --git a/radius-server/templates/mods-available/mschap.j2 b/radius-server/templates/mods-available/mschap.j2 new file mode 100644 index 0000000000000000000000000000000000000000..609d3e81820b4e8108afbff4a7dd38c794b14888 --- /dev/null +++ b/radius-server/templates/mods-available/mschap.j2 @@ -0,0 +1,111 @@ +# -*- text -*- +# +# $Id: 4673fa7f9fd1d9931fcf1e4e1cdd9bb656b1d434 $ + +# Microsoft CHAP authentication +# +# This module supports MS-CHAP and MS-CHAPv2 authentication. +# It also enforces the SMB-Account-Ctrl attribute. +# +mschap { + with_ntdomain_hack=yes + + # The module can perform authentication itself, OR + # use a Windows Domain Controller. This configuration + # directive tells the module to call the ntlm_auth + # program, which will do the authentication, and return + # the NT-Key. Note that you MUST have "winbindd" and + # "nmbd" running on the local machine for ntlm_auth + # to work. See the ntlm_auth program documentation + # for details. + # + # If ntlm_auth is configured below, then the mschap + # module will call ntlm_auth for every MS-CHAP + # authentication request. If there is a cleartext + # or NT hashed password available, you can set + # "MS-CHAP-Use-NTLM-Auth := No" in the control items, + # and the mschap module will do the authentication itself, + # without calling ntlm_auth. + # + # Be VERY careful when editing the following line! + # + # You can also try setting the user name as: + # + # ... --username=%{mschap:User-Name} ... + # + # In that case, the mschap module will look at the User-Name + # attribute, and do prefix/suffix checks in order to obtain + # the "best" user name for the request. + # +{% raw %} + #ntlm_auth = "/usr/bin/ntlm_auth --request-nt-key --username=%{%{Stripped-User-Name}:-%{%{User-Name}:-None}} --challenge=%{%{mschap:Challenge}:-00} --nt-response=%{%{mschap:NT-Response}:-00}" + ntlm_auth = "/usr/bin/ntlm_auth --request-nt-key --username=%{mschap:User-Name} --challenge=%{%{mschap:Challenge}:-00} --nt-response=%{%{mschap:NT-Response}:-00}" +{% endraw %} + + # The default is to wait 10 seconds for ntlm_auth to + # complete. This is a long time, and if it's taking that + # long then you likely have other problems in your domain. + # The length of time can be decreased with the following + # option, which can save clients waiting if your ntlm_auth + # usually finishes quicker. Range 1 to 10 seconds. + # +# ntlm_auth_timeout = 10 + + # An alternative to using ntlm_auth is to connect to the + # winbind daemon directly for authentication. This option + # is likely to be faster and may be useful on busy systems, + # but is less well tested. + # + # Using this option requires libwbclient from Samba 4.2.1 + # or later to be installed. Make sure that ntlm_auth above is + # commented out. + # +# winbind_username = "%{mschap:User-Name}" +# winbind_domain = "%{mschap:NT-Domain}" + + # + # Information for the winbind connection pool. The configuration + # items below are the same for all modules which use the new + # connection pool. + # + pool { + start = ${thread[pool].start_servers} + min = ${thread[pool].min_spare_servers} + max = ${thread[pool].max_servers} + + spare = ${thread[pool].max_spare_servers} + + uses = 0 + retry_delay = 30 + lifetime = 86400 + cleanup_interval = 300 + idle_timeout = 600 + } + + passchange { + # This support MS-CHAPv2 (not v1) password change + # requests. See doc/mschap.rst for more IMPORTANT + # information. + # + # Samba/ntlm_auth - if you are using ntlm_auth to + # validate passwords, you will need to use ntlm_auth + # to change passwords. Uncomment the three lines + # below, and change the path to ntlm_auth. + # +# ntlm_auth = "/usr/bin/ntlm_auth --helper-protocol=ntlm-change-password-1" +# ntlm_auth_username = "username: %{mschap:User-Name}" +# ntlm_auth_domain = "nt-domain: %{mschap:NT-Domain}" + + # To implement a local password change, you need to + # supply a string which is then expanded, so that the + # password can be placed somewhere. e.g. passed to a + # script (exec), or written to SQL (UPDATE/INSERT). + # We give both examples here, but only one will be + # used. + # +# local_cpw = "%{exec:/path/to/script %{mschap:User-Name} %{MS-CHAP-New-Cleartext-Password}}" + # +# local_cpw = "%{sql:UPDATE radcheck set value='%{MS-CHAP-New-NT-Password}' where username='%{SQL-User-Name}' and attribute='NT-Password'}" + } + +} diff --git a/radius-server/templates/mods-available/ntlm_auth.j2 b/radius-server/templates/mods-available/ntlm_auth.j2 new file mode 100644 index 0000000000000000000000000000000000000000..5029a42ecbdc8989c953278d491e4171536b3ed4 --- /dev/null +++ b/radius-server/templates/mods-available/ntlm_auth.j2 @@ -0,0 +1,12 @@ +# +# For testing ntlm_auth authentication with PAP. +# +# If you have problems with authentication failing, even when the +# password is good, it may be a bug in Samba: +# +# https://bugzilla.samba.org/show_bug.cgi?id=6563 +# +exec ntlm_auth { + wait = yes + program = "/usr/bin/ntlm_auth --request-nt-key --domain={{ radius_ntlm_domain }} --username=%{mschap:User-Name} --password=%{User-Password}" +} diff --git a/radius-server/templates/mods-available/realm.j2 b/radius-server/templates/mods-available/realm.j2 new file mode 100644 index 0000000000000000000000000000000000000000..93c65ca3e832f2388e6577ff29733aa99aa5d9ea --- /dev/null +++ b/radius-server/templates/mods-available/realm.j2 @@ -0,0 +1,56 @@ +# -*- text -*- +# +# $Id: b4c8ee3d8534ece75f6129d4853e6bc081cf0aa5 $ + +# Realm module, for proxying. +# +# You can have multiple instances of the realm module to +# support multiple realm syntaxes at the same time. The +# search order is defined by the order that the modules are listed +# in the authorize and preacct sections. +# +# Four config options: +# format - must be "prefix" or "suffix" +# The special cases of "DEFAULT" +# and "NULL" are allowed, too. +# delimiter - must be a single character + +# 'realm/username' +# +# Using this entry, IPASS users have their realm set to "IPASS". +realm IPASS { + format = prefix + delimiter = "/" +} + +# 'username@realm' +# +realm suffix { + format = suffix + delimiter = "@" + + ignore_null = yes + # The next 3 configuration items are valid ONLY + # for a trust-router. For all other realms, + # they are ignored. +# trust_router = "localhost" +# rp_realm = "painless-security.com" +# default_community = "apc.moonshot.ja.net" +} + +# 'username%realm' +# +realm realmpercent { + format = suffix + delimiter = "%" +} + +# +# 'domain\user' +# +realm ntdomain { + format = prefix + delimiter = "\\" + + ignore_null = yes +} diff --git a/radius-server/templates/mods-config/files/authorize.j2 b/radius-server/templates/mods-config/files/authorize.j2 new file mode 100644 index 0000000000000000000000000000000000000000..1b93cecc1be3deb428fa31d356e3c59be311333b --- /dev/null +++ b/radius-server/templates/mods-config/files/authorize.j2 @@ -0,0 +1,49 @@ +# +# Deny access for a specific user. Note that this entry MUST +# be before any other 'Auth-Type' attribute which results in the user +# being authenticated. +# +# Note that there is NO 'Fall-Through' attribute, so the user will not +# be given any additional resources. +# +#lameuser Auth-Type := Reject +# Reply-Message = "Your account has been disabled." + +# old MAC auth user types + + +####################################################### +# DEFAULT +# +DEFAULT User-Name =~ "^[Aa][Nn][Oo][Nn][Yy][Mm][Oo][Uu][Ss]$" + Auth-Type := Reject + +DEFAULT User-Name =~ "^[Aa][Nn][Oo][Nn][Yy][Mm][Oo][Uu][Ss]@.*$" + Auth-Type := EAP + +DEFAULT Realm == NULL, Auth-Type := Reject + +DEFAULT Realm == {{ radius_default_realm }}, FreeRADIUS-Proxied-To == 127.0.0.1 + User-Name = '%{User-Name}', + Fall-Through = yes + +{%- for assign in radius_vlan_assignments %} +DEFAULT {{ assign.key }} {{ assign.condition }} {{ assign.value }} + Tunnel-Type = VLAN, + Tunnel-Medium-Type = IEEE-802, + Tunnel-Private-Group-Id = {{ assign.vlan }}, + Fall-Through = yes +{% endfor -%} + +# +# Deny access for a group of users. +# +# Note that there is NO 'Fall-Through' attribute, so the user will not +# be given any additional resources. +# +#DEFAULT Group == "disabled", Auth-Type := Reject +# Reply-Message = "Your account has been disabled." +# + +### Allow authentication with these certificates + diff --git a/radius-server/templates/policy.d/ntlm_auth.j2 b/radius-server/templates/policy.d/ntlm_auth.j2 new file mode 100644 index 0000000000000000000000000000000000000000..ac869e0395c984eb869190f102a887a46fc470cf --- /dev/null +++ b/radius-server/templates/policy.d/ntlm_auth.j2 @@ -0,0 +1,10 @@ +# Give the ntlm_auth exec module an "authorize" method that sets Auth-Type +# to itself but only if it's a valid PAP request, and Auth-Type is not +# already set to something +ntlm_auth.authorize { + if (!control:Auth-Type && User-Password) { + update control { + Auth-Type := ntlm_auth + } + } +} diff --git a/radius-server/templates/policy.d/rewrite_station_to_ssid.j2 b/radius-server/templates/policy.d/rewrite_station_to_ssid.j2 new file mode 100644 index 0000000000000000000000000000000000000000..2d6a47833490442da0820d74b35f3a7920f67537 --- /dev/null +++ b/radius-server/templates/policy.d/rewrite_station_to_ssid.j2 @@ -0,0 +1,13 @@ +# Source: http://wiki.freeradius.org/guide/Mac-Auth +# +rewrite_called_station_to_ssid { + if(Called-Station-Id =~ /^([0-9a-f]{2})[-:]?([0-9a-f]{2})[-:.]?([0-9a-f]{2})[-:]?([0-9a-f]{2})[-:.]?([0-9a-f]{2})[-:]?([0-9a-f]{2})[-:]?([-a-z0-9_. ]*)?/i){ + update request { + Called-Station-Id := "%{1}%{2}%{3}%{4}%{5}%{6}" + Called-Station-SSID := "%{7}" + } + } + else { + noop + } +} diff --git a/radius-server/templates/proxy.conf.j2 b/radius-server/templates/proxy.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..26857b4f5899155bb512723ab75c6147dd3d9ca5 --- /dev/null +++ b/radius-server/templates/proxy.conf.j2 @@ -0,0 +1,825 @@ +# -*- text -*- +## +## proxy.conf -- proxy radius and realm configuration directives +## +## $Id: a72beebf52d791616a09ebd69dd7ea9349597363 $ + +####################################################################### +# +# Proxy server configuration +# +# This entry controls the servers behaviour towards ALL other servers +# to which it sends proxy requests. +# +proxy server { + # + # Note that as of 2.0, the "synchronous", "retry_delay", + # "retry_count", and "dead_time" have all been deprecated. + # For backwards compatibility, they are are still accepted + # by the server, but they ONLY apply to the old-style realm + # configuration. i.e. realms with "authhost" and/or "accthost" + # entries. + # + # i.e. "retry_delay" and "retry_count" have been replaced + # with per-home-server configuration. See the "home_server" + # example below for details. + # + # i.e. "dead_time" has been replaced with a per-home-server + # "revive_interval". We strongly recommend that this not + # be used, however. The new method is much better. + + # + # In 2.0, the server is always "synchronous", and setting + # "synchronous = no" is impossible. This simplifies the + # server and increases the stability of the network. + # However, it means that the server (i.e. proxy) NEVER + # originates packets. It proxies packets ONLY when it receives + # a packet or a re-transmission from the NAS. If the NAS never + # re-transmits, the proxy never re-transmits, either. This can + # affect fail-over, where a packet does *not* fail over to a + # second home server.. because the NAS never retransmits the + # packet. + # + # If you need to set "synchronous = no", please send a + # message to the list <freeradius-users@lists.freeradius.org> + # explaining why this feature is vital for your network. + + # + # If a realm exists, but there are no live home servers for + # it, we can fall back to using the "DEFAULT" realm. This is + # most useful for accounting, where the server can proxy + # accounting requests to home servers, but if they're down, + # use a DEFAULT realm that is LOCAL (i.e. accthost = LOCAL), + # and then store the packets in the "detail" file. That data + # can be later proxied to the home servers by radrelay, when + # those home servers come back up again. + + # Setting this to "yes" may have issues for authentication. + # i.e. If you are proxying for two different ISP's, and then + # act as a general dial-up for Gric. If one of the first two + # ISP's has their RADIUS server go down, you do NOT want to + # proxy those requests to GRIC. Instead, you probably want + # to just drop the requests on the floor. In that case, set + # this value to 'no'. + # + # allowed values: {yes, no} + # + default_fallback = no + +} + +####################################################################### +# +# Configuration for the proxy realms. +# +# As of 2.0, the "realm" configuration has changed. Instead of +# specifying "authhost" and "accthost" in a realm section, the home +# servers are specified separately in a "home_server" section. For +# backwards compatibility, you can still use the "authhost" and +# "accthost" directives. If you only have one home server for a +# realm, it is easier to use the old-style configuration. +# +# However, if you have multiple servers for a realm, we STRONGLY +# suggest moving to the new-style configuration. +# +# +# Load-balancing and failover between home servers is handled via +# a "home_server_pool" section. +# +# Finally, The "realm" section defines the realm, some options, and +# indicates which server pool should be used for the realm. +# +# This change means that simple configurations now require multiple +# sections to define a realm. However, complex configurations +# are much simpler than before, as multiple realms can share the same +# server pool. +# +# That is, realms point to server pools, and server pools point to +# home servers. Multiple realms can point to one server pool. One +# server pool can point to multiple home servers. Each home server +# can appear in one or more pools. +# +# See sites-available/tls for an example of configuring home servers, +# pools, and realms with TLS. +# + +###################################################################### +# +# This section defines a "Home Server" which is another RADIUS +# server that gets sent proxied requests. In earlier versions +# of FreeRADIUS, home servers were defined in "realm" sections, +# which was awkward. In 2.0, they have been made independent +# from realms, which is better for a number of reasons. +# +home_server localhost { + # + # Home servers can be sent Access-Request packets + # or Accounting-Request packets. + # + # Allowed values are: + # auth - Handles Access-Request packets + # acct - Handles Accounting-Request packets + # auth+acct - Handles Access-Request packets at "port", + # and Accounting-Request packets at "port + 1" + # coa - Handles CoA-Request and Disconnect-Request packets. + # See also raddb/sites-available/originate-coa + type = auth + + # + # Configure ONE OF the following entries: + # + # IPv4 address + # + ipaddr = 127.0.0.1 + + # OR IPv6 address + # ipv6addr = ::1 + + # OR virtual server + # virtual_server = foo + + # Note that while both ipaddr and ipv6addr will accept + # both addresses and host names, we do NOT recommend + # using host names. When you specify a host name, the + # server has to do a DNS lookup to find the IP address + # of the home server. If the DNS server is slow or + # unresponsive, it means that FreeRADIUS will NOT be + # able to determine the address, and will therefore NOT + # start. + # + # Also, the mapping of host name to address is done ONCE + # when the server starts. If DNS is later updated to + # change the address, FreeRADIUS will NOT discover that + # until after a re-start, or a HUP. + # + # If you specify a virtual_server here, then requests + # will be proxied internally to that virtual server. + # These requests CANNOT be proxied again, however. The + # intent is to have the local server handle packets + # when all home servers are dead. + # + # Requests proxied to a virtual server will be passed + # through the pre-proxy and post-proxy sections, just + # like any other request. See also the sample "realm" + # configuration, below. + # + # None of the rest of the home_server configuration is used + # for the "virtual_server" configuration. + + # + # The port to which packets are sent. + # + # Usually 1812 for type "auth", and 1813 for type "acct". + # Older servers may use 1645 and 1646. + # Use 3799 for type "coa" + # + port = 1812 + + # + # The transport protocol. + # + # If unspecified, defaults to "udp", which is the traditional + # RADIUS transport. It may also be "tcp", in which case TCP + # will be used to talk to this home server. + # + # When home servers are put into pools, the pool can contain + # home servers with both UDP and TCP transports. + # + #proto = udp + + # + # The shared secret use to "encrypt" and "sign" packets between + # FreeRADIUS and the home server. + # + # The secret can be any string, up to 8k characters in length. + # + # Control codes can be entered vi octal encoding, + # e.g. "\101\102" == "AB" + # Quotation marks can be entered by escaping them, + # e.g. "foo\"bar" + # Spaces or other "special" characters can be entered + # by putting quotes around the string. + # e.g. "foo bar" + # "foo;bar" + # + secret = testing123 + + ############################################################ + # + # The rest of the configuration items listed here are optional, + # and do not have to appear in every home server definition. + # + ############################################################ + + # + # You can optionally specify the source IP address used when + # proxying requests to this home server. When the src_ipaddr + # it set, the server will automatically create a proxy + # listener for that IP address. + # + # If you specify this field for one home server, you will + # likely need to specify it for ALL home servers. + # + # If you don't care about the source IP address, leave this + # entry commented. + # +# src_ipaddr = 127.0.0.1 + + # + # If the home server does not respond to a request within + # this time, the server marks the request as timed out. + # After "response_timeouts", the home server is marked + # as being "zombie", and "zombie_period" starts. + # + # The response window can be a number between 0.001 and 60.000 + # Values on the low end are discouraged, as they will likely + # not work due to limitations of operating system timers. + # + # The default response window is large because responses may + # be slow, especially when proxying across the Internet. + # + # Useful range of values: 5 to 60 + response_window = 20 + + # + # Start "zombie_period" after this many responses have + # timed out. + # +# response_timeouts = 1 + + # + # If you want the old behaviour of the server rejecting + # proxied requests after "response_window" timeout, set + # the following configuration item to "yes". + # + # This configuration WILL be removed in a future release + # If you believe you need it, email the freeradius-users + # list, and explain why it should stay in the server. + # +# no_response_fail = no + + # + # If the home server does not respond to ANY packets during + # the "zombie period", it will be considered to be dead. + # + # A home server that is marked "zombie" will be used for + # proxying as a low priority. If there are live servers, + # they will always be preferred to a zombie. Requests will + # be proxied to a zombie server ONLY when there are no + # live servers. + # + # Any request that is proxied to a home server will continue + # to be sent to that home server until the home server is + # marked dead. At that point, it will fail over to another + # server, if a live server is available. If none is available, + # then the "post-proxy-type fail" handler will be called. + # + # If "status_check" below is something other than "none", then + # the server will start sending status checks at the start of + # the zombie period. It will continue sending status checks + # until the home server is marked "alive". + # + # Useful range of values: 20 to 120 + zombie_period = 40 + + ############################################################ + # + # As of 2.0, FreeRADIUS supports RADIUS layer "status + # checks". These are used by a proxy server to see if a home + # server is alive. + # + # These status packets are sent ONLY if the proxying server + # believes that the home server is dead. They are NOT sent + # if the proxying server believes that the home server is + # alive. They are NOT sent if the proxying server is not + # proxying packets. + # + # If the home server responds to the status check packet, + # then it is marked alive again, and is returned to use. + # + ############################################################ + + # + # Some home servers do not support status checks via the + # Status-Server packet. Others may not have a "test" user + # configured that can be used to query the server, to see if + # it is alive. For those servers, we have NO WAY of knowing + # when it becomes alive again. Therefore, after the server + # has been marked dead, we wait a period of time, and mark + # it alive again, in the hope that it has come back to + # life. + # + # If it has NOT come back to life, then FreeRADIUS will wait + # for "zombie_period" before marking it dead again. During + # the "zombie_period", ALL AUTHENTICATIONS WILL FAIL, because + # the home server is still dead. There is NOTHING that can + # be done about this, other than to enable the status checks, + # as documented below. + # + # e.g. if "zombie_period" is 40 seconds, and "revive_interval" + # is 300 seconds, the for 40 seconds out of every 340, or about + # 10% of the time, all authentications will fail. + # + # If the "zombie_period" and "revive_interval" configurations + # are set smaller, than it is possible for up to 50% of + # authentications to fail. + # + # As a result, we recommend enabling status checks, and + # we do NOT recommend using "revive_interval". + # + # The "revive_interval" is used ONLY if the "status_check" + # entry below is "none". Otherwise, it will not be used, + # and should be deleted. + # + # Useful range of values: 60 to 3600 + revive_interval = 120 + + # + # The proxying server (i.e. this one) can do periodic status + # checks to see if a dead home server has come back alive. + # + # If set to "none", then the other configuration items listed + # below are not used, and the "revive_interval" time is used + # instead. + # + # If set to "status-server", the Status-Server packets are + # sent. Many RADIUS servers support Status-Server. If a + # server does not support it, please contact the server + # vendor and request that they add it. With status-server if + # the home server is marked as a zombie and a status-server + # response is received, it will be immediately marked as live. + # + # This prevents spurious failovers in federations such as + # eduroam, where intermediary proxy servers may be functional + # but the servers of a home institution may not be, + # + # If set to "request", then Access-Request, or Accounting-Request + # packets are sent, depending on the "type" entry above (auth/acct). + # + # Allowed values: none, status-server, request + status_check = status-server + + # + # If the home server does not support Status-Server packets, + # then the server can still send Access-Request or + # Accounting-Request packets, with a pre-defined user name. + # + # This practice is NOT recommended, as it may potentially let + # users gain network access by using these "test" accounts! + # + # If it is used, we recommend that the home server ALWAYS + # respond to these Access-Request status checks with + # Access-Reject. The status check just needs an answer, it + # does not need an Access-Accept. + # + # For Accounting-Request status checks, only the username + # needs to be set. The rest of the accounting attribute are + # set to default values. The home server that receives these + # accounting packets SHOULD NOT treat them like normal user + # accounting packets. i.e It should probably NOT log them to + # a database. + # + # username = "test_user_please_reject_me" + # password = "this is really secret" + + # + # Configure the interval between sending status check packets. + # + # Setting it too low increases the probability of spurious + # fail-over and fallback attempts. + # + # Useful range of values: 6 to 120 + check_interval = 30 + + # + # Wait "check_timeout" seconds for a reply to a status check + # packet. + # + check_timeout = 4 + + # + # Configure the number of status checks in a row that the + # home server needs to respond to before it is marked alive. + # + # If you want to mark a home server as alive after a short + # time period of being responsive, it is best to use a small + # "check_interval", and a large value for + # "num_answers_to_alive". Using a long "check_interval" and + # a small number for "num_answers_to_alive" increases the + # probability of spurious fail-over and fallback attempts. + # + # Useful range of values: 3 to 10 + num_answers_to_alive = 3 + + # + # Limit the total number of outstanding packets to the home + # server. + # + # if ((#request sent) - (#requests received)) > max_outstanding + # then stop sending more packets to the home server + # + # This lets us gracefully fall over when the home server + # is overloaded. + max_outstanding = 65536 + + # + # The configuration items in the next sub-section are used ONLY + # when "type = coa". It is ignored for all other type of home + # servers. + # + # See RFC 5080 for the definitions of the following terms. + # RAND is a function (internal to FreeRADIUS) returning + # random numbers between -0.1 and +0.1 + # + # First Re-transmit occurs after: + # + # RT = IRT + RAND*IRT + # + # Subsequent Re-transmits occur after: + # + # RT = 2 * RTprev + RAND * RTprev + # + # Re-transmits are capped at: + # + # if (MRT && (RT > MRT)) RT = MRT + RAND * MRT + # + # For a maximum number of attempts: MRC + # + # For a maximum (total) period of time: MRD. + # + coa { + # Initial retransmit interval: 1..5 + irt = 2 + + # Maximum Retransmit Timeout: 1..30 (0 == no maximum) + mrt = 16 + + # Maximum Retransmit Count: 1..20 (0 == retransmit forever) + mrc = 5 + + # Maximum Retransmit Duration: 5..60 + mrd = 30 + } + + # + # Connection limiting for home servers with "proto = tcp". + # + # This section is ignored for other home servers. + # + limit { + # + # Limit the number of TCP connections to the home server. + # + # The default is 16. + # Setting this to 0 means "no limit" + max_connections = 16 + + # + # Limit the total number of requests sent over one + # TCP connection. After this number of requests, the + # connection will be closed. Any new packets that are + # proxied to the home server will result in a new TCP + # connection being made. + # + # Setting this to 0 means "no limit" + max_requests = 0 + + # + # 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 sent over the connection for + # this time, the connection will be closed. + # + # Setting this to 0 means "no timeout". + idle_timeout = 0 + } + +} + +# Sample virtual home server. +# +# +#home_server virtual.example.com { +# virtual_server = virtual.example.com +#} + +###################################################################### +# +# This section defines a pool of home servers that is used +# for fail-over and load-balancing. In earlier versions of +# FreeRADIUS, fail-over and load-balancing were defined per-realm. +# As a result, if a server had 5 home servers, each of which served +# the same 10 realms, you would need 50 "realm" entries. +# +# In version 2.0, you would need 5 "home_server" sections, +# 10 'realm" sections, and one "home_server_pool" section to tie the +# two together. +# +home_server_pool my_auth_failover { + # + # The type of this pool controls how home servers are chosen. + # + # fail-over - the request is sent to the first live + # home server in the list. i.e. If the first home server + # is marked "dead", the second one is chosen, etc. + # + # load-balance - the least busy home server is chosen, + # where "least busy" is counted by taking the number of + # requests sent to that home server, and subtracting the + # number of responses received from that home server. + # + # If there are two or more servers with the same low + # load, then one of those servers is chosen at random. + # This configuration is most similar to the old + # "round-robin" method, though it is not exactly the same. + # + # Note that load balancing does not work well with EAP, + # as EAP requires packets for an EAP conversation to be + # sent to the same home server. The load balancing method + # does not keep state in between packets, meaning that + # EAP packets for the same conversation may be sent to + # different home servers. This will prevent EAP from + # working. + # + # For non-EAP authentication methods, and for accounting + # packets, we recommend using "load-balance". It will + # ensure the highest availability for your network. + # + # client-balance - the home server is chosen by hashing the + # source IP address of the packet. If that home server + # is down, the next one in the list is used, just as + # with "fail-over". + # + # There is no way of predicting which source IP will map + # to which home server. + # + # This configuration is most useful to do simple load + # balancing for EAP sessions, as the EAP session will + # always be sent to the same home server. + # + # client-port-balance - the home server is chosen by hashing + # the source IP address and source port of the packet. + # If that home server is down, the next one in the list + # is used, just as with "fail-over". + # + # This method provides slightly better load balancing + # for EAP sessions than "client-balance". However, it + # also means that authentication and accounting packets + # for the same session MAY go to different home servers. + # + # keyed-balance - the home server is chosen by hashing (FNV) + # the contents of the Load-Balance-Key attribute from the + # control items. The request is then sent to home server + # chosen by taking: + # + # server = (hash % num_servers_in_pool). + # + # If there is no Load-Balance-Key in the control items, + # the load balancing method is identical to "load-balance". + # + # For most non-EAP authentication methods, The User-Name + # attribute provides a good key. An "unlang" policy can + # be used to copy the User-Name to the Load-Balance-Key + # attribute. This method may not work for EAP sessions, + # as the User-Name outside of the TLS tunnel is often + # static, e.g. "anonymous@realm". + # + # + # The default type is fail-over. + type = fail-over + + # + # A virtual_server may be specified here. If so, the + # "pre-proxy" and "post-proxy" sections are called when + # the request is proxied, and when a response is received. + # + # This lets you have one policy for all requests that are proxied + # to a home server. This policy is completely independent of + # any policies used to receive, or process the request. + # + #virtual_server = pre_post_proxy_for_pool + + # + # Next, a list of one or more home servers. The names + # of the home servers are NOT the hostnames, but the names + # of the sections. (e.g. home_server foo {...} has name "foo". + # + # Note that ALL home servers listed here have to be of the same + # type. i.e. they all have to be "auth", or they all have to + # be "acct", or the all have to be "auth+acct". + # + home_server = localhost + + # Additional home servers can be listed. + # There is NO LIMIT to the number of home servers that can + # be listed, though using more than 10 or so will become + # difficult to manage. + # + # home_server = foo.example.com + # home_server = bar.example.com + # home_server = baz.example.com + # home_server = ... + + + # + # If ALL home servers are dead, then this "fallback" home server + # is used. If set, it takes precedence over any realm-based + # fallback, such as the DEFAULT realm. + # + # For reasons of stability, this home server SHOULD be a virtual + # server. Otherwise, the fallback may itself be dead! + # + #fallback = virtual.example.com +} + +###################################################################### +# +# +# This section defines a new-style "realm". Note the in version 2.0, +# there are many fewer configuration items than in 1.x for a realm. +# +# Automatic proxying is done via the "realms" module (see "man +# rlm_realm"). To manually proxy the request put this entry in the +# "users" file: + +# +# +#DEFAULT Proxy-To-Realm := "realm_name" +# +# +realm example.com { + # + # Realms point to pools of home servers. +# + # For authentication, the "auth_pool" configuration item + # should point to a "home_server_pool" that was previously + # defined. All of the home servers in the "auth_pool" must + # be of type "auth". + # + # For accounting, the "acct_pool" configuration item + # should point to a "home_server_pool" that was previously + # defined. All of the home servers in the "acct_pool" must + # be of type "acct". + # + # If you have a "home_server_pool" where all of the home servers + # are of type "auth+acct", you can just use the "pool" + # configuration item, instead of specifying both "auth_pool" + # and "acct_pool". + + auth_pool = my_auth_failover +# acct_pool = acct + + # As of Version 3.0, the server can proxy CoA packets + # based on the Operator-Name attribute. This requires + # that the "suffix" module be listed in the "recv-coa" + # section. + # + # See raddb/sites-available/coa + # +# coa_pool = name_of_coa_pool + + # + # Normally, when an incoming User-Name is matched against the + # realm, the realm name is "stripped" off, and the "stripped" + # user name is used to perform matches. + # + # e.g. User-Name = "bob@example.com" will result in two new + # attributes being created by the "realms" module: + # + # Stripped-User-Name = "bob" + # Realm = "example.com" + # + # The Stripped-User-Name is then used as a key in the "users" + # file, for example. + # + # If you do not want this to happen, uncomment "nostrip" below. + # + # nostrip + + # There are no more configuration entries for a realm. +} + + +# +# This is a sample entry for iPass. +# Note that you have to define "ipass_auth_pool" and +# "ipass_acct_pool", along with home_servers for them, too. +# +#realm IPASS { +# nostrip +# +# auth_pool = ipass_auth_pool +# acct_pool = ipass_acct_pool +#} + +# +# This realm is used mainly to cancel proxying. You can have +# the "realm suffix" module configured to proxy all requests for +# a realm, and then later cancel the proxying, based on other +# configuration. +# +# For example, you want to terminate PEAP or EAP-TTLS locally, +# you can add the following to the "users" file: +# +# DEFAULT EAP-Type == PEAP, Proxy-To-Realm := LOCAL +# +realm LOCAL { + # If we do not specify a server pool, the realm is LOCAL, and + # requests are not proxied to it. +} + +{%- for realm in radius_realms %} +realm {{ realm }} { +} +{% endfor -%} + +# +# This realm is for requests which don't have an explicit realm +# prefix or suffix. User names like "bob" will match this one. +# +#realm NULL { +# authhost = radius.company.com:1600 +# accthost = radius.company.com:1601 +# secret = testing123 +#} + +# +# This realm is for ALL OTHER requests. +# +#realm DEFAULT { +# authhost = radius.company.com:1600 +# accthost = radius.company.com:1601 +# secret = testing123 +#} + + +# This realm "proxies" requests internally to a virtual server. +# The pre-proxy and post-proxy sections are run just as with any +# other kind of home server. The virtual server then receives +# the request, and replies, just as with any other packet. +# +# Once proxied internally like this, the request CANNOT be proxied +# internally or externally. +# +#realm virtual.example.com { +# virtual_server = virtual.example.com +#} +# + +# +# Regular expressions may also be used as realm names. If these are used, +# then the "find matching realm" process is as follows: +# +# 1) Look for a non-regex realm with an *exact* match for the name. +# If found, it is used in preference to any regex matching realm. +# +# 2) Look for a regex realm, in the order that they are listed +# in the configuration files. Any regex match is performed in +# a case-insensitive fashion. +# +# 3) If no realm is found, return the DEFAULT realm, if any. +# +# The order of the realms matters in step (2). For example, defining +# two realms ".*\.example.net$" and ".*\.test\.example\.net$" will result in +# the second realm NEVER matching. This is because all of the realms +# which match the second regex also match the first one. Since the +# first regex matches, it is returned. +# +# The solution is to list the realms in the opposite order,. e.g. +# ".*\.test\.example.net$", followed by ".*\.example\.net$". +# +# +# Some helpful rules: +# +# - always place a '~' character at the start of the realm name. +# This signifies that it is a regex match, and not an exact match +# for the realm. +# +# - place the regex in double quotes. This helps the configuration +# file parser ignore any "special" characters in the regex. +# Yes, this rule is different than the normal "unlang" rules for +# regular expressions. That may be fixed in a future release. +# +# - for version 3.0.4 and following, with "correct_escapes = true", +# use normal regex backslash rules. Just one. Not two. +# +# - If you are matching domain names, put a '$' at the end of the regex +# that matches the domain name. This tells the regex matching code +# that the realm ENDS with the domain name, so it does not match +# realms with the domain name in the middle. e.g. "~.*\.example\.net" +# will match "test.example.netFOO", which is likely not what you want. +# Using "~(.*\.)example\.net$" is better. +# +# The more regex realms that are defined, the more time it takes to +# process them. You should define as few regex realms as possible +# in order to maximize server performance. +# +#realm "~(.*\.)*example\.net$" { +# auth_pool = my_auth_failover +#} diff --git a/radius-server/templates/sites-available/default.j2 b/radius-server/templates/sites-available/default.j2 new file mode 100644 index 0000000000000000000000000000000000000000..7b5a2db81f299912ee59752db2a8cb5bbf320e89 --- /dev/null +++ b/radius-server/templates/sites-available/default.j2 @@ -0,0 +1,590 @@ +server default { +listen { + # Type of packets to listen for. + # Allowed values are: + # auth listen for authentication packets + # acct listen for accounting packets + # proxy IP to use for sending proxied packets + # detail Read from the detail file. For examples, see + # raddb/sites-available/copy-acct-to-home-server + # status listen for Status-Server packets. For examples, + # see raddb/sites-available/status + # coa listen for CoA-Request and Disconnect-Request + # packets. For examples, see the file + # raddb/sites-available/coa + # + type = auth + + + ipaddr = * + port = 0 + + # + # Connection limiting for sockets with "proto = tcp". + # + limit { + max_connections = 16 + lifetime = 0 + idle_timeout = 30 + } +} + +listen { + ipaddr = * + port = 0 + type = acct + + limit { + } +} + +# IPv6 versions of the above - read their full config to understand options +listen { + type = auth + ipv6addr = :: # any. ::1 == localhost + port = 0 + limit { + max_connections = 16 + lifetime = 0 + idle_timeout = 30 + } +} + +listen { + ipv6addr = :: + port = 0 + type = acct + + limit { + } +} + +# Authorization. First preprocess (hints and huntgroups files), +# then realms, and finally look in the "users" file. +# +# Any changes made here should also be made to the "inner-tunnel" +# virtual server. +# +# The order of the realm modules will determine the order that +# we try to find a matching realm. +# +# Make *sure* that 'preprocess' comes before any realm if you +# need to setup hints for the remote radius server +authorize { + # + # Take a User-Name, and perform some checks on it, for spaces and other + # invalid characters. If the User-Name appears invalid, reject the + # request. + # + # See policy.d/filter for the definition of the filter_username policy. + # + filter_username + + # + # Some broken equipment sends passwords with embedded zeros. + # i.e. the debug output will show + # + # User-Password = "password\000\000" + # + # This policy will fix it to just be "password". + # + filter_password + + # + # The preprocess module takes care of sanitizing some bizarre + # attributes in the request, and turning them into attributes + # which are more standard. + # + # It takes care of processing the 'raddb/hints' and the + # 'raddb/huntgroups' files. + preprocess + + # seperate AP MAC and SSID + rewrite_called_station_id + + # + # If you want to have a log of authentication requests, + # un-comment the following line. + auth_log + + # + # If the users are logging in with an MS-CHAP-Challenge + # attribute for authentication, the mschap module will find + # the MS-CHAP-Challenge attribute, and add 'Auth-Type := MS-CHAP' + # to the request, which will cause the server to then use + # the mschap module for authentication. + mschap + + pap + + # extract realm + suffix + ntdomain + + ntlm_auth + + # + # This module takes care of EAP-MD5, EAP-TLS, and EAP-LEAP + # authentication. + # + # It also sets the EAP-Type attribute in the request + # attribute list to the EAP type from the packet. + # + # The EAP module returns "ok" if it is not yet ready to + # authenticate the user. The configuration below checks for + # that code, and stops processing the "authorize" section if + # so. + # + # Any LDAP and/or SQL servers will not be queried for the + # initial set of packets that go back and forth to set up + # TTLS or PEAP. + # + eap { + ok = return + } + + # + # Read the 'users' file. In v3, this is located in + # raddb/mods-config/files/authorize + files + + # + # Look in an SQL database. The schema of the database + # is meant to mirror the "users" file. + # + # See "Authorization Queries" in mods-available/sql + -sql + + # + # The ldap module reads passwords from the LDAP database. + -ldap + + + # + expiration + logintime +} + + +# Authentication. +# +# +# This section lists which modules are available for authentication. +# Note that it does NOT mean 'try each module in order'. It means +# that a module from the 'authorize' section adds a configuration +# attribute 'Auth-Type := FOO'. That authentication type is then +# used to pick the appropriate module from the list below. +# + +# In general, you SHOULD NOT set the Auth-Type attribute. The server +# will figure it out on its own, and will do the right thing. The +# most common side effect of erroneously setting the Auth-Type +# attribute is that one authentication method will work, but the +# others will not. +# +# The common reasons to set the Auth-Type attribute by hand +# is to either forcibly reject the user (Auth-Type := Reject), +# or to or forcibly accept the user (Auth-Type := Accept). +# +# Note that Auth-Type := Accept will NOT work with EAP. +# +# Please do not put "unlang" configurations into the "authenticate" +# section. Put them in the "post-auth" section instead. That's what +# the post-auth section is for. +# +authenticate { + # + # MSCHAP authentication. + Auth-Type MS-CHAP { + mschap + } + + Auth-Type ntlm_auth { + ntlm_auth + } + + # + # Allow EAP authentication. + eap + + # + # The older configurations sent a number of attributes in + # Access-Challenge packets, which wasn't strictly correct. + # If you want to filter out these attributes, uncomment + # the following lines. + # +# Auth-Type eap { +# eap { +# handled = 1 +# } +# if (handled && (Response-Packet-Type == Access-Challenge)) { +# attr_filter.access_challenge.post-auth +# handled # override the "updated" code from attr_filter +# } +# } +} + + +# +# Pre-accounting. Decide which accounting type to use. +# +preacct { + preprocess + + # + # Merge Acct-[Input|Output]-Gigawords and Acct-[Input-Output]-Octets + # into a single 64bit counter Acct-[Input|Output]-Octets64. + # +# acct_counters64 + + # + # Session start times are *implied* in RADIUS. + # The NAS never sends a "start time". Instead, it sends + # a start packet, *possibly* with an Acct-Delay-Time. + # The server is supposed to conclude that the start time + # was "Acct-Delay-Time" seconds in the past. + # + # The code below creates an explicit start time, which can + # then be used in other modules. It will be *mostly* correct. + # Any errors are due to the 1-second resolution of RADIUS, + # and the possibility that the time on the NAS may be off. + # + # The start time is: NOW - delay - session_length + # + +# update request { +# FreeRADIUS-Acct-Session-Start-Time = "%{expr: %l - %{%{Acct-Session-Time}:-0} - %{%{Acct-Delay-Time}:-0}}" +# } + + + # + # Ensure that we have a semi-unique identifier for every + # request, and many NAS boxes are broken. + acct_unique + + # + # Look for IPASS-style 'realm/', and if not found, look for + # '@realm', and decide whether or not to proxy, based on + # that. + # + # Accounting requests are generally proxied to the same + # home server as authentication requests. +# IPASS + suffix + + # + # Read the 'acct_users' file + files +} + +# +# Accounting. Log the accounting data. +# +accounting { + # Update accounting packet by adding the CUI attribute + # recorded from the corresponding Access-Accept + # use it only if your NAS boxes do not support CUI themselves +# cui + # + # Create a 'detail'ed log of the packets. + # Note that accounting requests which are proxied + # are also logged in the detail file. + detail +# daily + + # Update the wtmp file + # + # If you don't use "radlast", you can delete this line. + unix + + # + # For Simultaneous-Use tracking. + # + # Due to packet losses in the network, the data here + # may be incorrect. There is little we can do about it. +# radutmp +# sradutmp + + # Return an address to the IP Pool when we see a stop record. +# main_pool + + # + # Log traffic to an SQL database. + # + # See "Accounting queries" in mods-available/sql + -sql + + # + # If you receive stop packets with zero session length, + # they will NOT be logged in the database. The SQL module + # will print a message (only in debugging mode), and will + # return "noop". + # + # You can ignore these packets by uncommenting the following + # three lines. Otherwise, the server will not respond to the + # accounting request, and the NAS will retransmit. + # +# if (noop) { +# ok +# } + + # + # Instead of sending the query to the SQL server, + # write it into a log file. + # +# sql_log + + # Cisco VoIP specific bulk accounting +# pgsql-voip + + # For Exec-Program and Exec-Program-Wait + exec + + # Filter attributes from the accounting response. + attr_filter.accounting_response + + # + # See "Autz-Type Status-Server" for how this works. + # +# Acct-Type Status-Server { +# +# } +} + + +# Session database, used for checking Simultaneous-Use. Either the radutmp +# or rlm_sql module can handle this. +# The rlm_sql module is *much* faster +session { +# radutmp + + # + # See "Simultaneous Use Checking Queries" in mods-available/sql +# sql +} + + +# Post-Authentication +# Once we KNOW that the user has been authenticated, there are +# additional steps we can take. +post-auth { + # + # If you need to have a State attribute, you can + # add it here. e.g. for later CoA-Request with + # State, and Service-Type = Authorize-Only. + # +# if (!&reply:State) { +# update reply { +# State := "0x%{randstr:16h}" +# } +# } + + # + # For EAP-TTLS and PEAP, add the cached attributes to the reply. + # The "session-state" attributes are automatically cached when + # an Access-Challenge is sent, and automatically retrieved + # when an Access-Request is received. + # + # The session-state attributes are automatically deleted after + # an Access-Reject or Access-Accept is sent. + # + update { + &reply: += &session-state: + } + + # Get an address from the IP Pool. +# main_pool + + + # Create the CUI value and add the attribute to Access-Accept. + # Uncomment the line below if *returning* the CUI. +# cui + + # + # If you want to have a log of authentication replies, + # un-comment the following line, and enable the + # 'detail reply_log' module. + reply_log + + # + # After authenticating the user, do another SQL query. + # + # See "Authentication Logging Queries" in mods-available/sql + -sql + + # + # Instead of sending the query to the SQL server, + # write it into a log file. + # +# sql_log + + # + # Un-comment the following if you want to modify the user's object + # in LDAP after a successful login. + # +# ldap + + # For Exec-Program and Exec-Program-Wait + exec + + # If there is a client certificate (EAP-TLS, sometimes PEAP + # and TTLS), then some attributes are filled out after the + # certificate verification has been performed. These fields + # MAY be available during the authentication, or they may be + # available only in the "post-auth" section. + # + # The first set of attributes contains information about the + # issuing certificate which is being used. The second + # contains information about the client certificate (if + # available). +# +# update reply { +# Reply-Message += "%{TLS-Cert-Serial}" +# Reply-Message += "%{TLS-Cert-Expiration}" +# Reply-Message += "%{TLS-Cert-Subject}" +# Reply-Message += "%{TLS-Cert-Issuer}" +# Reply-Message += "%{TLS-Cert-Common-Name}" +# Reply-Message += "%{TLS-Cert-Subject-Alt-Name-Email}" +# +# Reply-Message += "%{TLS-Client-Cert-Serial}" +# Reply-Message += "%{TLS-Client-Cert-Expiration}" +# Reply-Message += "%{TLS-Client-Cert-Subject}" +# Reply-Message += "%{TLS-Client-Cert-Issuer}" +# Reply-Message += "%{TLS-Client-Cert-Common-Name}" +# Reply-Message += "%{TLS-Client-Cert-Subject-Alt-Name-Email}" +# } + + # Insert class attribute (with unique value) into response, + # aids matching auth and acct records, and protects against duplicate + # Acct-Session-Id. Note: Only works if the NAS has implemented + # RFC 2865 behaviour for the class attribute, AND if the NAS + # supports long Class attributes. Many older or cheap NASes + # only support 16-octet Class attributes. +# insert_acct_class + + # MacSEC requires the use of EAP-Key-Name. However, we don't + # want to send it for all EAP sessions. Therefore, the EAP + # modules put required data into the EAP-Session-Id attribute. + # This attribute is never put into a request or reply packet. + # + # Uncomment the next few lines to copy the required data into + # the EAP-Key-Name attribute +# if (&reply:EAP-Session-Id) { +# update reply { +# EAP-Key-Name := &reply:EAP-Session-Id +# } +# } + + # Remove reply message if the response contains an EAP-Message + remove_reply_message_if_eap + + # + # Access-Reject packets are sent through the REJECT sub-section of the + # post-auth section. + # + # Add the ldap module name (or instance) if you have set + # 'edir_account_policy_check = yes' in the ldap module configuration + # + # The "session-state" attributes are not available here. + # + Post-Auth-Type REJECT { + # log failed authentications in SQL, too. + -sql + attr_filter.access_reject + + # Insert EAP-Failure message if the request was + # rejected by policy instead of because of an + # authentication failure + eap + + # Remove reply message if the response contains an EAP-Message + remove_reply_message_if_eap + } +} + +# +# When the server decides to proxy a request to a home server, +# the proxied request is first passed through the pre-proxy +# stage. This stage can re-write the request, or decide to +# cancel the proxy. +# +# Only a few modules currently have this method. +# +pre-proxy { + # Before proxing the request add an Operator-Name attribute identifying + # if the operator-name is found for this client. + # No need to uncomment this if you have already enabled this in + # the authorize section. +# operator-name + + # The client requests the CUI by sending a CUI attribute + # containing one zero byte. + # Uncomment the line below if *requesting* the CUI. +# cui + + # Uncomment the following line if you want to change attributes + # as defined in the preproxy_users file. +# files + + # Uncomment the following line if you want to filter requests + # sent to remote servers based on the rules defined in the + # 'attrs.pre-proxy' file. +# attr_filter.pre-proxy + + # If you want to have a log of packets proxied to a home + # server, un-comment the following line, and the + # 'detail pre_proxy_log' section, above. +# pre_proxy_log +} + +# +# When the server receives a reply to a request it proxied +# to a home server, the request may be massaged here, in the +# post-proxy stage. +# +post-proxy { + + # If you want to have a log of replies from a home server, + # un-comment the following line, and the 'detail post_proxy_log' + # section, above. +# post_proxy_log + + # Uncomment the following line if you want to filter replies from + # remote proxies based on the rules defined in the 'attrs' file. +# attr_filter.post-proxy + + # + # If you are proxying LEAP, you MUST configure the EAP + # module, and you MUST list it here, in the post-proxy + # stage. + # + # You MUST also use the 'nostrip' option in the 'realm' + # configuration. Otherwise, the User-Name attribute + # in the proxied request will not match the user name + # hidden inside of the EAP packet, and the end server will + # reject the EAP request. + # + eap + + # + # If the server tries to proxy a request and fails, then the + # request is processed through the modules in this section. + # + # The main use of this section is to permit robust proxying + # of accounting packets. The server can be configured to + # proxy accounting packets as part of normal processing. + # Then, if the home server goes down, accounting packets can + # be logged to a local "detail" file, for processing with + # radrelay. When the home server comes back up, radrelay + # will read the detail file, and send the packets to the + # home server. + # + # With this configuration, the server always responds to + # Accounting-Requests from the NAS, but only writes + # accounting packets to disk if the home server is down. + # +# Post-Proxy-Type Fail-Accounting { +# detail +# } +} +} diff --git a/radius-server/templates/sites-available/inner-tunnel.j2 b/radius-server/templates/sites-available/inner-tunnel.j2 new file mode 100644 index 0000000000000000000000000000000000000000..904009fc87f35d2cadf7e78e54f05f99e4e6a6ac --- /dev/null +++ b/radius-server/templates/sites-available/inner-tunnel.j2 @@ -0,0 +1,321 @@ +# -*- text -*- +###################################################################### +# +# This is a virtual server that handles *only* inner tunnel +# requests for EAP-TTLS and PEAP types. +# +# $Id: c250afa30a78fe9ff7a97b6c9b8a7c3a419a6946 $ +# +###################################################################### + +server inner-tunnel { + +# +# This next section is here to allow testing of the "inner-tunnel" +# authentication methods, independently from the "default" server. +# It is listening on "localhost", so that it can only be used from +# the same machine. +# +# $ radtest USER PASSWORD 127.0.0.1:18120 0 testing123 +# +# If it works, you have configured the inner tunnel correctly. To check +# if PEAP will work, use: +# +# $ radtest -t mschap USER PASSWORD 127.0.0.1:18120 0 testing123 +# +# If that works, PEAP should work. If that command doesn't work, then +# +# FIX THE INNER TUNNEL CONFIGURATION SO THAT IT WORKS. +# +# Do NOT do any PEAP tests. It won't help. Instead, concentrate +# on fixing the inner tunnel configuration. DO NOTHING ELSE. +# +listen { + ipaddr = 127.0.0.1 + port = 18120 + type = auth +} + + +# Authorization. First preprocess (hints and huntgroups files), +# then realms, and finally look in the "users" file. +authorize { + filter_username + + # + # Do checks on outer / inner User-Name, so that users + # can't spoof us by using incompatible identities + # + filter_inner_identity + + chap + mschap + + suffix + ntdomain + + # + # The "suffix" module takes care of stripping the domain + # (e.g. "@example.com") from the User-Name attribute, and the + # next few lines ensure that the request is not proxied. + # + # If you want the inner tunnel request to be proxied, delete + # the next few lines. + # +# update control { +# &Proxy-To-Realm := LOCAL +# } + + # + # This module takes care of EAP-MSCHAPv2 authentication. + # + # It also sets the EAP-Type attribute in the request + # attribute list to the EAP type from the packet. + # + # The example below uses module failover to avoid querying all + # of the following modules if the EAP module returns "ok". + # Therefore, your LDAP and/or SQL servers will not be queried + # for the many packets that go back and forth to set up TTLS + # or PEAP. The load on those servers will therefore be reduced. + # + eap { + ok = return + } + + # + # Read the 'users' file + files + + # + # Look in an SQL database. The schema of the database + # is meant to mirror the "users" file. + # + # See "Authorization Queries" in sql.conf + -sql + ldap + + {%- for check in radius_tunnel_checks %} + {%- if check.station %} + if ( &Called-Station-SSID == "{{ check.station }}" ) { + {% endif -%} + if {{ check.condition }} { + } + else { + update reply { + Reply-Message = "{{ check_error }}" + } + reject + } + {%- if check.station %} + } + {% endif -%} + {% endfor -%} + + expiration + logintime +} + + +# Authentication. +# +# +# This section lists which modules are available for authentication. +# Note that it does NOT mean 'try each module in order'. It means +# that a module from the 'authorize' section adds a configuration +# attribute 'Auth-Type := FOO'. That authentication type is then +# used to pick the appropriate module from the list below. +# + +# In general, you SHOULD NOT set the Auth-Type attribute. The server +# will figure it out on its own, and will do the right thing. The +# most common side effect of erroneously setting the Auth-Type +# attribute is that one authentication method will work, but the +# others will not. +# +# The common reasons to set the Auth-Type attribute by hand +# is to either forcibly reject the user, or forcibly accept him. +# +authenticate { + + # + # MSCHAP authentication. + Auth-Type MS-CHAP { + mschap + } + + # + # Allow EAP authentication. + eap +} + +###################################################################### +# +# There are no accounting requests inside of EAP-TTLS or PEAP +# tunnels. +# +###################################################################### + + +# Session database, used for checking Simultaneous-Use. Either the radutmp +# or rlm_sql module can handle this. +# The rlm_sql module is *much* faster +session { + radutmp + + # + # See "Simultaneous Use Checking Queries" in sql.conf +# sql +} + + +# Post-Authentication +# Once we KNOW that the user has been authenticated, there are +# additional steps we can take. +# +# Note that the last packet of the inner-tunnel authentication +# MAY NOT BE the last packet of the outer session. So updating +# the outer reply MIGHT work, and sometimes MIGHT NOT. The +# exact functionality depends on both the inner and outer +# authentication methods. +# +# If you need to send a reply attribute in the outer session, +# the ONLY safe way is to set "use_tunneled_reply = yes", and +# then update the inner-tunnel reply. +post-auth { + # If you want privacy to remain, see the + # Chargeable-User-Identity attribute from RFC 4372. + # If you want to use it just uncomment the line below. +# cui-inner + + # + # If you want to have a log of authentication replies, + # un-comment the following line, and enable the + # 'detail reply_log' module. + reply_log + + # + # After authenticating the user, do another SQL query. + # + # See "Authentication Logging Queries" in sql.conf + -sql + + # + # Instead of sending the query to the SQL server, + # write it into a log file. + # +# sql_log + + # + # Un-comment the following if you have set + # 'edir_account_policy_check = yes' in the ldap module sub-section of + # the 'modules' section. + # + ldap + + + # + # Instead of "use_tunneled_reply", uncomment the + # next two "update" blocks. + # +# update { +# &outer.session-state: += &reply: +# } + + # + # These attributes are for the inner session only. + # They MUST NOT be sent in the outer reply. + # + # If you uncomment the previous block and leave + # this one commented out, WiFi WILL NOT WORK, + # because the client will get two MS-MPPE-keys + # +# update outer.session-state { +# MS-MPPE-Encryption-Policy !* ANY +# MS-MPPE-Encryption-Types !* ANY +# MS-MPPE-Send-Key !* ANY +# MS-MPPE-Recv-Key !* ANY +# Message-Authenticator !* ANY +# EAP-Message !* ANY +# Proxy-State !* ANY +# } + + # + # Access-Reject packets are sent through the REJECT sub-section of the + # post-auth section. + # + # Add the ldap module name (or instance) if you have set + # 'edir_account_policy_check = yes' in the ldap module configuration + # + Post-Auth-Type REJECT { + # log failed authentications in SQL, too. + -sql + attr_filter.access_reject + + # + # Let the outer session know which module failed, and why. + # + update outer.session-state { + &Module-Failure-Message := &request:Module-Failure-Message + } + } + + update outer.reply { + User-Name = "%{request:User-Name}" + } +} + +# +# When the server decides to proxy a request to a home server, +# the proxied request is first passed through the pre-proxy +# stage. This stage can re-write the request, or decide to +# cancel the proxy. +# +# Only a few modules currently have this method. +# +pre-proxy { + # Uncomment the following line if you want to change attributes + # as defined in the preproxy_users file. +# files + + # Uncomment the following line if you want to filter requests + # sent to remote servers based on the rules defined in the + # 'attrs.pre-proxy' file. +# attr_filter.pre-proxy + + # If you want to have a log of packets proxied to a home + # server, un-comment the following line, and the + # 'detail pre_proxy_log' section, above. +# pre_proxy_log +} + +# +# When the server receives a reply to a request it proxied +# to a home server, the request may be massaged here, in the +# post-proxy stage. +# +post-proxy { + + # If you want to have a log of replies from a home server, + # un-comment the following line, and the 'detail post_proxy_log' + # section, above. +# post_proxy_log + + # Uncomment the following line if you want to filter replies from + # remote proxies based on the rules defined in the 'attrs' file. +# attr_filter.post-proxy + + # + # If you are proxying LEAP, you MUST configure the EAP + # module, and you MUST list it here, in the post-proxy + # stage. + # + # You MUST also use the 'nostrip' option in the 'realm' + # configuration. Otherwise, the User-Name attribute + # in the proxied request will not match the user name + # hidden inside of the EAP packet, and the end server will + # reject the EAP request. + # + eap +} + +} # inner-tunnel server block