Showing posts with label configuration guide. Show all posts
Showing posts with label configuration guide. Show all posts

Monday, February 10, 2025

How to update the new WBA Root CA chain for the Radiator OpenRoaming deployments?


WBA OpenRoaming certificates now issued or renewed using the new WBA Root Certificate Authority chain


At 00:00 UTC (beginning of the day) on 3rd of Febuary 2025 Wireless Broadband Alliance (WBA) switched to issuing OpenRoaming certificates using new WBA Root Certificate Authority (CA) chain. This means that all OpenRoaming certificates, which are renewed or issued on 3rd of February 2025 or later, use the new WBA Root CA chain. 

Although WBA planned and informed OpenRoaming Identity Providers (IdP) and Access Network Providers (ANP) about the planned change, there are OpenRoaming ANPs and IdPs, which have not updated their RADIUS/RadSec server configurations to accept both the old and new WBA root CA certificate chain for RadSec connections.

This means for example that IdP customers of the IdP using the new root chain issued certificate are not able to roam in the ANP networks, which do not accept IdP's new RadSec server certificate if it is issued by the new WBA Root CA chain. If an IdP does not accept the new WBA Root CA verified RadSec client certificates for connections originating from the ANP's Wi-Fi network, that IdP's customers are not able to roam into that ANP's Wi-Fi network.

If ANPs and IdPs do not update their inbound and outbound RADIUS/RadSec connections to accept both the old and new WBA Root CA chain certificates, when new OpenRoaming certificates are issued or old ones are renewed, gradually the roaming connections with those ANPs and IdPs deteriorate.


How to update Radiator OpenRoaming deployment to use the new WBA Root CA chain?


If you have deployed Radiator utilising the Radiator OpenRoaming Configuration Guide, updating your configuration to support the newer WBA Root CA chain certificate (or any other CA certificates) can be done by simply adding new certificates to CA directories in the configuration.

Radiator OpenRoaming Configuration Repository contains a template Radiator configuration tree to use to set up OpenRoaming deployment. These configuration files are intended to be installed to /etc/radiator directory with the sub-directories. 

Both the old and the new WBA Root CAs available from the Wireless Broadband Alliance PKI repository in text (PEM) and binary (DER) format under WBA Root CAs paragraph. The old WBA Root CA is aliased wba-root0 and the new WBA Root CA is aliased wba-root1. Both of these should be installed to the following directories:
  • Directory for CA certificates used for verifying inbound OpenRoaming connections from other OpenRoaming ANPs to your server: /etc/radiator/certificates/radsec_inbound_openroaming/ca
  • Directory for CA certificates used for verifying the OpenRoaming IdP server certificates for RadSec connections used to authenticate those IdPs users roaming in your network: /etc/radiator/certificates/etc/radiator/certificates/radsec_outbound_openroaming/ca
The retrieval and installation of the new WBA Root CA chain can be done with the following commands on most Linux distributions as a root user or using sudo.

First install the new WBA Root CA to the CA directory for verifying inbound OpenRoaming RadSec connections:

cd /etc/radiator/certificates/radsec_inbound_openroaming/ca
wget https://wballiance.com/wp-content/uploads/2024/05/wba-root1.pem
chown root:radiator wba-root1.pem
chmod 644 wba-root1.pem
openssl rehash -v .

And then install the new WBA Root CA to the CA directory for verifying the IdP servers responding to outbound OpenRoaming RadSec connections:

cd /etc/radiator/certificates/radsec_outbound_openroaming/ca
wget https://wballiance.com/wp-content/uploads/2024/05/wba-root1.pem
chown root:radiator wba-root1.pem
chmod 644 wba-root1.pem
openssl rehash -v .

After installing the certificates, it is recommended to restart the Radiator instances responsible of handling the connections with:

systemctl restart radiator@radsec_inbound_openroaming
systemctl restart radiator@radsec_outbound_openroaming

or all Radiator instances with:

systemctl restart radiator-instances

If you are deploying Radiator OpenRoaming Configuration from scratch, you should also download and install wba-root0.pem from the WBA PKI repository by following the above instructions but replacing the wget command, which retrieves the certificate with:

wget https://wballiance.com/wp-content/uploads/2024/05/wba-root1.pem

All other commands should be executed as described above for both directories.

As a result you now have a Radiator OpenRoaming configuration, which supports both the old and the new WBA Root CA chain. You can read more about Radiator OpenRoaming configuration from the Radiator OpenRoaming Configuration Guide. There are also new useful updates to the Radiator OpenRoaming configuration template files done in January 2025


How can I do this with other RADIUS servers?


How and where certificates are set up, depends on the RADIUS server vendor and the configuration, but you should look for ca_dir or CA directory support and instructions if you want to set up similar kind of setup.


Where can I get more help with Radiator OpenRoaming deployment?


Radiator Software provides expert services for Radiator OpenRoaming deployments. Please contact us via email: sales (at) radiatorsoftware.com .

Wednesday, June 19, 2024

How to speed up RADIUS authentication processing during peak hours with Radiator

From time to time, our customers reach out to us and ask guidance on how to speed up RADIUS authentication processing during peak hours. Performance of this core functionality of Radiator is stable and predictable, and with increasing traffic load, most of the bottlenecks often emerge from the performance of the backend services that Radiator is utilising. In this blog, we give some helpful information to make improvements.

What causes bottlenecks?

In many cases,  authentication backends that Radiator is configured to use may be too slow to process the number of requests that are arriving. For example SQL databases may be slow to respond, LDAP lookups can take time, or HTTP requests be delayed. Writing accounting data or logging to a slow database can slow down Radiator.

When this happens, the host system's UDP traffic buffer on the listening port fills up to the point that it overflows and new RADIUS request packets arriving at the server get dropped. Because the requests are dropped by the host operating system, they cannot even be logged as failed requests by Radiator.

To get a better understanding of what is happening during peak hours, set `Trace 4` debug log level with `LogMicroseconds` in the configuration file (see [How to enable debug logging?]. The debug log will show how long each processing step is taking, and from there you can determine how many requests per second the configuration can handle.

How to tune Radiator to speed up authentication processing?

There are several ways to tune Radiator to speed up processing:

  • Split configuration into two separate files, one for authentication and one for accounting, and run Radiator as two separate running instances. This way there are two processes handling traffic with their own UDP buffers and backend dependencies that may even out the congestion. On Linux systems with systemd there are mechanisms readily available to help with that. More information: [How do I manage Radiator instances on a single host?].
  • Use a proxy instance to forward authentication and/or accounting requests to multiple worker instances (see first bullet). The requests can be spread out to worker instances so that request state is preserved (see [methods for load distribution and balancing] in documentation).
  • Within instances, use [FarmSize] to create a farm of server processes to add parallel processing of requests. Note: This is not compatible with many EAP protocols, such as EAP-TLS, EAP-TTLS, PEAP etc. This is because such protocols rely on authentication state being held within each server process, and it is necessary for all the requests for such protocols to go to the same Radiator process.
  • Incoming requests can be distributed from one or two proxying or load-balancing hosts to multiple hosts for processing.
  • Depending on use case, any combination of FarmSize, multiple instances per host and multiple hosts can be used together to enable more throughput. Separating processing on the Radiator side will create more separate connections to backends that may help even out backend load.
Additionally, the bottleneck might be the available resources
  • If the host is running other processes, make sure it has enough resources available for Radiator. The best would be to use dedicated hosts for each function.
  • If a virtualisation platform is used, make sure that it can provide the configured resources to Radiator virtual machines even during the peak hours when other vm's are running their peak loads.
  • Logging to external servers may cause some unneeded delays for Radiator. This can be mitigated by configuring Radiator to log locally, and then process and ship logs with a separate agent.
  • Outside of Radiator, performance of backends may be tuned depending on the backend itself. For example a database can be scaled up or replicated to multiple-server cluster. On the other hand, speeding up the database might be possible even without adding more hardware if queries can be optimised or suitable indexes created. For optimising backends, please refer to their respective documentation.
  • Running configuration or Radiator may contain some parts that can be optimised. At the end of this blog post, we tell a bit about our consultation services. 
How can we help?
 
In case you would like our assistance when tuning your Radiator and related infrastructure, please contact sales@radiatorsoftware.com. Our team of experts have a long experience on configuring Radiator, and also assisting with the best practices when integrating Radiator with existing or new infrastructure. 

Wednesday, March 25, 2020

Introducing new Radiator Repository

Recently, Radiator Software team has been putting their efforts into making life easier for system administrators. Following the introduction of the new Radiator Linux packages, we are now very proud to announce the new Radiator Repository. This is good news for the Linux users, since the new repository allows you to streamline maintenance and to easily distribute the updates to all Radiator servers in your organisation. What is even better, this new service is included with all active Radiator Support contracts. 

Supported platforms are RHEL 7/8, CentOS 7/8, Ubuntu 16.04/18.04/20.04/22.04, Debian 9/10/11. Here are the steps how to get it:

  1. Visit our repository page and log in using your existing Radiator user credentials: https://downloads.radiatorsoftware.com/repo/ 
  2. Scroll down to your Linux distribution version 
  3. Follow the instructions and use the commands in instructions to set up Radiator Repository
  4. Enjoy easy updates

For security, the repository URLs are customer specific and generated for your organization, and the packages provided from Radiator repositories are never marked as security upgrades. This means that using unattended-upgrades for system's security upgrades is safe as Radiator will not be automatically upgraded. You also get to pick whether you want the official releases only, or include the testing versions. 

For our customers using other platforms or with download access only contracts, Radiator Downloads site has been redesigned and is sporting a clean new look. You will continue to get the software updates the classic way by downloading the packages from our website, whether you are using Mac or Windows, older Linux distributions, or simply prefer to do so.  

Please contact our team at sales@radiatorsoftware.com if you want to check your subscription status, renew or upgrade your support contract, or reset your password. Let us know if you try the new repositories. We would like to hear your feedback!

Tuesday, June 25, 2019

Grouping and controlling multiple Radiator instances with systemd

Introduction


Radiator Linux packages provide by default two systemd service files — /lib/systemd/system/radiator.service for single instance and /lib/systemd/system/radiator@.service for multiple instances configuration. The single instance configuration expects to find its configuration from /etc/radiator/radiator.conf while the multiple instances configuration expects each instance configuration to be named as /etc/radiator/radiator-<instance>.conf e.g. /etc/radiator/radiator-proxy.conf. When naming instances, it's better to use underscores instead of hyphens, so filenames would be like radiator-auth_internal.conf or radiator-wifiaccounting.conf.

When configuration files are in place, the instances can be enabled/disabled with following commands.

Single instance enable/disable:

systemctl enable radiator
systemctl disable radiator


Multiple instance enable/disable (instance name proxy, configuration file name radiator-proxy.conf):

systemctl enable radiator@proxy
systemctl disable radiator@proxy

All the commands above and in these instructions require root privileges, so open a root shell or use sudo to make sure that commands work.

Please note that enabling or disabling an instance does not start or stop the instance. It only controls if an enabled instance is started when starting the server. For starting and stopping instances manually there are systemctl start <instance> and systemctl stop <instance> commands e.g systemctl start radiator@proxy.

Sometimes there exists a need to run multiple Radiator hosts on a single host — for example when one has separated RADIUS proxy and authentication functionality into multiple separate instances. The reasons to do so vary from clarifying configuration to optimising performance by running multiple Radiator processes instead of a single one.

When multiple instances are used, managing and restarting them separately may become burdensome. Together with Radiator's systemd service files, systemd provides the means to group and control multiple Radiator instances with one virtual systemd service. These instructions follow the systemd configuration guidelines as described by Linux distribution manuals.

Preparations before starting


Please check and do at least the following before starting to migrate to virtual systemd service model:
  1. Ensure that your Radiator instance configurations work as manually controlled services. This means that you have working configurations for them and are able to enable, disable, start and stop them without any problems. If you run into trouble getting instance configurations running, check the configuration file owner, group and file permissions so that they are readable by radiator user or group.
  2. Stop and disable all Radiator instances.
These will ensure that you can more easily detect problems with the virtual systemd service configuration, when you know for sure that the instances and their configurations are already tested to be working. Stopping and disabling them ensures that you will start from clean slate when adding new virtual systemd service files.

When editing systemd service files, please do not edit and change files in /lib/systemd/system as the next Linux Radiator package upgrade will overwrite those files. The proper place to do these adjustments is under /etc/systemd/system as the following instructions will also describe.

Setting up virtual systemd service to control multiple instances


The actual implementation varies with the version of systemd, but for clarity, we have divided the instructions according to tested and compatible Linux distribution versions.

RHEL 8 / 9, Ubuntu 18.04 / 20.04 / 22.04 / 24.04 LTS, Debian 10 / 11 / 12


Configuration files


Create the virtual systemd service file /etc/systemd/system/radiator-instances.service with the following content:

[Unit]
Description=Virtual service for managing all Radiator instances

[Service]
# The dummy program will exit
Type=oneshot
# Execute a dummy program
ExecStart=/bin/true
# This service shall be considered active after start
RemainAfterExit=yes

[Install]
# Components of this application should be started at boot time
WantedBy=multi-user.target


Adjust existing radiator@.service file by creating a directory /etc/systemd/system/radiator@.service.d and creating adjustment file /etc/systemd/system/radiator@.service.d/custom.conf with the following content:

[Unit]
PartOf=radiator-instances.service

[Install]
WantedBy=radiator-instances.service

Controlling the instances


When you have finished creating the files and directory, you can enable the virtual service and instance(s) for example with the following command (assuming you have instances proxy and auth):

systemctl enable radiator-instances radiator@proxy radiator@auth

You can then control all instances either separately or by directing the virtual service radiator-instances with commands like:

systemctl start radiator-instances
systemctl stop radiator-instances
systemctl restart radiator-instances

The virtual radiator-instances now controls all radiator@.instance based instances on host. If you need more granular control, of which services are controlled radiator-instances, you need check Grouping instances to control section in the end.

Centos 7, Debian 9, RHEL 7, Ubuntu 16.04 LTS, Oracle Linux


Configuration files


Centos 7, Red Hat 7 and Ubuntu 16.04 LTS have an older version of systemd, which is not able to understand instance configuration adjustment directories like /etc/systemd/system/radiator@.service.d. Because of this, on these platforms, the radiator@.service itself needs to be copied to /etc/systemd/system directory to be adjusted. The disadvantage of this is that if new Radiator packages update the radiator@.service, the updates need to be edited manually to the /etc/systemd/system/radiator@.service file.


Create the virtual systemd service file /etc/systemd/system/radiator-instances.service with the following content:

[Unit]
Description=Virtual service for managing all Radiator instances

[Service]
# The dummy program will exit
Type=oneshot
# Execute a dummy program
ExecStart=/bin/true
# This service shall be considered active after start
RemainAfterExit=yes

[Install]
# Components of this application should be started at boot time
WantedBy=multi-user.target


Copy the /lib/systemd/system/radiator@.service file to /etc/systemd/system/radiator@.service and add the following lines to it.

To [Unit] section add line:

PartOf=radiator-instances.service

To [Install] section add line:

WantedBy=radiator-instances.service

Controlling the instances


When you have finished creating the files, you can control the instances like already presented in the RHEL 8 / 9, Ubuntu 18.04 / 20.04 / 22.04 / 24.04 LTS, Debian 10 / 11 / 12 — Controlling the instances section.

Grouping instances to control


The above instructions assume that you want to control all Radiator instances on a host with the radiator-instances service, but if you want to select the instances the control, the recommended way is to create renamed radiator-instances and radiator@.service under /etc/systemd/system. This approach is common for all mentioned Linux distributions and Radiator packages

For example if you wanted to group certain organisation's instances on host under a virtual service, you could create radiator-organisation-instances.service and copy /lib/systemd/system/radiator@.service as radiator-organisation@.service under /etc/systemd/system. In this case it does not matter if you use newer or older systemd as it is better to separate radiator-organisation@.service from radiator@.service. What you need to do is to adjust radiator-organisation@.service file so that it has PartOf and WantedBy lines pointing to the new renamed radiator-organisation-instances.service file.

After setting up those renamed files, you will be able to command the group of instances the same way as above with system wide instances group. The only difference is that for example in this case you would use the same commands with differently named services and instances, for example:

systemctl enable radiator-organisation-instances radiator-organisation@auth radiator-organisation@proxy

systemctl start radiator-organisation-instances

systemctl stop radiator-organisation-instances


For more information


In case you have any questions, comments or feedback, please contact support@radiatorsoftware.com.

Monday, October 15, 2018

Improved support for Hotspots and subscription quotas!


New Radiator release version 4.22 will introduce an improved support for Hotspot functionality, including differentiated services and prepaid/postpaid quotas.

The release will include following new and updated modules which can be used to implement various service provider use cases:

A new module class called 'ServiceDatabase' which handles differentiated services and subscriptions:

  - <ServiceDatabase INTERNAL> stores service definitions and subscription data within in-memory.

  - <ServiceDatabase SQL> stores service definitions and subscription data within SQL database.

Existing <SessionDatabase INTERNAL> and <SessionDatabase SQL> modules have been updated to work seamlessly with new <ServiceDatabase> modules for RADIUS accounting based quota control.

A new generic <AuthBy HOTSPOT> module which combines <ServiceDatabase>, <SessionDatabase>, an authenticating <AuthBy>, and possible <AuthBy DYNAUTH> (RADIUS Dynamic Authorization) for sending CoA/DM e.g. after a successful authentication or when a quota has been depleted, into a working solution which can be used with captive portals (for example MikroTik) and network access controllers supporting RADIUS. Beside Hotspot use-case, the same solution can also be used to implement a quota control for fixed-line access or cellular APN.

A new <AuthBy HOTSPOTFIDELIO> module based on <AuthBy HOTSPOT> which uses Radiator Fidelio/Opera PMS integration for authenticating and billing guests. Note that <AuthBy HOTSPOTFIDELIO> obsoletes previous <AuthBy FIDELIOHOTSPOT> module.

Implementing a guest network access with Radiator using Fidelio/Opera PMS integration.

Examples

To demonstrate how new <AuthBy HOTSPOT> and <AuthBy HOTSPOTFIDELIO> combine these new features, see a following configuration examples of new Radiator Hotspot functionality:

Example 1. Using in-memory <ServiceDatabase INTERNAL> and <SessionDatabase INTERNAL> with <AuthBy HOTSPOT> and <AuthBy FILE>

# See goodies/hotspot.cfg for a full example config

...

### Service and Session databases ###

# ServiceDatabase INTERNAL for Services and Subscriptions
<ServiceDatabase INTERNAL>
  Identifier ServiceDatabase-INTERNAL

  # Service definitions
  # Service 1: free, 1 hour, 50M data, no policers  Service name:free price:0 prepaidTime:1h prepaidQuota:50M replyItems:"OSC-AVPAIR=Test1,OSC-AVPAIR=Test2" 
  # Service 2: price 1000 cents, 1 day, 100M data, 100M/10M policers
  Service name:premium price:1000 prepaidTime:24h prepaidQuota:100M prepaidUpRate:10M prepaidDownRate:100M

  # Service 3: price 2000 cents, 1 day, 1G data, 100M/100M policers
  Service name:gold price:2000 prepaidTime:24h prepaidQuota:1G prepaidUpRate:100M prepaidDownRate:100M
</ServiceDatabase>

# SessionDatabase INTERNAL for Sessions
<SessionDatabase INTERNAL>
  Identifier SessionDatabase-INTERNAL
</SessionDatabase>

...

### AuthBy Modules ###

# Authenticate Hotspot users with AuthBy FILE
<AuthBy FILE>
  Identifier AuthBy-FILE

  Filename %D/users
  NoDefault
</AuthBy>

<AuthBy HOTSPOT>
  Identifier AuthBy-HOTSPOT

  # Authenticate Hotspot users with AuthBy FILE
  AuthBy AuthBy-FILE

  # Use ServiceDatabase-INTERNAL for services and subscriptions
  ServiceDatabase ServiceDatabase-INTERNAL

  # Lookup a subscription based on username (%1) and Calling-Station-Id MAC address
  SubscriptionId %1-%{Calling-Station-Id}

  # Use SessionDatabase-INTERNAL for sessions
  SessionDatabase SessionDatabase-INTERNAL

  # Lookup a session based on username (%1) and Calling-Station-Id MAC address
  SessionId %1-%{Calling-Station-Id}
  # Empty SessionAttribute
  SessionAttribute

  # If RADIUS accounting will be used for quota monitoring,
  # create a new session upon a successful authentication
  #PreProvisionSession

  # Alternatively, reply with remaining time quota
  #UsageMonitoring
  # and remaining data quota
  #ReplyWithDataQuota
  #DataLimitAttribute Mikrotik-Total-Limit
  #DataLimitGigawordsAttribute Mikrotik-Total-Limit-Gigawords

  # Use service 'free' as a default service
  DefaultService free
  ServiceAttribute OSC-Service-Identifier
  #ServiceAttributePrefix Service=
</AuthBy>

# AuthBy DyNAUTH for creating DM/CoA requests for exceeded sessions
<AuthBy DYNAUTH>
  Identifier AuthBy-DYNAUTH

  SessionDatabase SessionDatabase-INTERNAL

  # Send Change-Filter-Request (CoA) to NAS UDP port 3799
  #RequestType Change-Filter-Request
  # Send Disconnect-Request (DM) to NAS UDP port 3799
  RequestType Disconnect-Request
  DynAuthPort 3799

  # Do not try to lookup a session again
  NoSessionMapping

  # Send CoA/DM to IP address within NAS-IP-Address RADIUS attribute
  NasAddrAttribute NAS-IP-Address

  # Identify user session by User-Name, Acct-Session-Id and NAS-Port
  DynAuthAttribute User-Name
  DynAuthAttribute Acct-Session-Id
  DynAuthAttribute NAS-Port
</AuthBy>

# AuthBy RADIUSBYATTR for sending out DM/CoA requests for exceeded sessions
<AuthBy RADIUSBYATTR>
  Identifier AuthBy-RADIUSBYATTR
</AuthBy>

### Request Handlers ###

# Accounting Handler
<Handler Request-Type=Accounting-Request>
  Identifier Accounting-Handler

  # Acknowledge Accounting-Request immediately
  AccountingAccepted

  AuthByPolicy ContinueUntilRejectOrChallenge

  # Handle RADIUS accounting
  AuthBy AuthBy-HOTSPOT
  # Send DM/CoA request for exceeded session
  AuthBy AuthBy-DYNAUTH
</Handler>

# Outgoing DM/CoA Handler
<Handler DynAuthRequest=1>
  Identifier Handler-DYNAUTH

  AuthBy AuthBy-RADIUSBYATTR
</Handler>

# Default Handler
<Handler>
  Identifier Default-Handler

  # Handle RADIUS authentication
  AuthBy AuthBy-HOTSPOT

  RejectHasReason
</Handler>
Example 2. Using <ServiceDatabase SQL> and <SessionDatabase SQL> with <AuthBy HOTSPOTFIDELIO>

# See goodies/hotspot-fidelio.cfg for a full example config
#
# Requires SQL definitions from goodies/hotspot.sql and goodies/hotspot-fidelio.sql
# See goodies/README.hotspot-fidelio for more information
#

...

### Service and Session databases ###

# ServiceDatabase SQL for Services and Subscriptions
<ServiceDatabase SQL>
  Identifier ServiceDatabase-SQL

  # Details of how to contact the service and subscription database
  DBSource   dbi:SQLite:dbname=hotspot.db
  #DBSource   dbi:mysql:hotspot
  DBUsername mikem
  DBAuth     fred
</ServiceDatabase>

# SessionDatabase SQL for Sessions
<SessionDatabase SQL>
  Identifier SessionDatabase-SQL

  # Details of how to contact the session database
  DBSource   dbi:SQLite:dbname=hotspot.db
  #DBSource   dbi:mysql:hotspot
  DBUsername mikem
  DBAuth     fred

  # Modified SQL queries/statements for a new session database schema (goodies/hotspot.sql)
  CountQuery SELECT nas_id, nas_port, id, ipv4 FROM SESSIONS WHERE user_name=%0
  ClearNasQuery DELETE FROM SESSIONS WHERE nas_id='%0'
  AddQuery
  DeleteQuery
  ClearNasSessionQuery
</SessionDatabase>

...

### AuthBy Modules ###

<AuthBy HOTSPOTFIDELIO>
  Identifier AuthBy-HOTSPOTFIDELIO

  # Use ServiceDatabase-SQL for services and subscriptions
  ServiceDatabase ServiceDatabase-SQL
  # Lookup a subscription based on username (%1), Fidelio PMS    Guest Number (%2) and Calling-Station-Id MAC address
  SubscriptionId %1-%2-%{Calling-Station-Id}

  # Use SessionDatabase-SQL for sessions
  SessionDatabase SessionDatabase-SQL
  # Lookup a session based on username (%1), Class (%3) and    Calling-Station-Id MAC address
  SessionId %1-%3-%{Calling-Station-Id}
  # Empty SessionAttribute
  SessionAttribute

  # If RADIUS accounting will be used for quota monitoring,
  # create a new session upon a successful authentication
  PreProvisionSession

  # Alternatively, reply with remaining time quota
  #UsageMonitoring
  # and remaining data quota
  #ReplyWithDataQuota
  #DataLimitAttribute Mikrotik-Total-Limit
  #DataLimitGigawordsAttribute Mikrotik-Total-Limit-Gigawords

  # Details of how to contact the Fidelio posting database
  # See AuthSQL for details
  DBSource   dbi:SQLite:dbname=hotspot.db
  #DBSource   dbi:mysql:hotspot
  DBUsername mikem
  DBAuth     fred

  # Fidelio PMS interface
  Protocol tcp
  Port 5010
  Host localhost

  # Validity time in seconds of plan purchased
  # Default 86400 seconds (1 day)
  BlockDuration 86400

  # Default price for plan
  # Price in database overrides this value
  BlockPrice 900

  # ServiceAttribute defines the RADIUS attribute that is
  # used select the desired prepaid service or plan. On
  # Mikrotik login page you can create a menu as shown
  # below to display the different purchase
  # options. Note: "name=radius0-9048" is OSC-AVPAIR.
  #  <tr><td>Service:</td><td>
  #  <select name="radius0-9048">
  #  <option value="Mikrotik-Service=free">best effort (free)  </option>
  #  <option value="Mikrotik-Service=premium">premium ($5)</option>
  #  </select></td></tr>
  ServiceAttribute OSC-AVPAIR

  # If it is possible that there are multiple instances
  # of the ServiceAttribute in the request, you can use
  # an optional prefix to choose the correct instance.
  ServiceAttributePrefix Mikrotik-Service=

  # By default upgrade or renewal of the current plan is
  # automatically processed and charged. With this option
  # you can ask the guest to confirm the charge first.
  # With Mikrotik you can show the message to the guest
  # by including
  #  $(if error)<br /><div style="color: #FF8080; font-size: 14px">$(error)</div><br>$(endif)
  # on the Mikrotik login page
  #ConfirmUpgradeOrRenew
  #ConfirmationMessage "You are going to upgrade or renew your plan, please login again to confirm the charge"

  # This one uses the last part of the guest name (case sensitive) as the
  # password. This is usually the guest surname
  UserPasswordHook sub {my @n = split(/\s/, $_[1]->{'GN'}); return $n[$#n];}

  # Need this to ensure the Guest Number is included in the postings
  # Required when there are multiple guests per room
  #PostingExtraFields G#,%4

  # You can add extra attributes in the reply here if you wish
  # to set limits or controls over access
  #AddToReply Mikrotik-Recv-Limit-Gigawords=1,Mikrotik-Xmit-Limit-Gigawords=1
</AuthBy>

# AuthBy DyNAUTH for creating DM/CoA requests for exceeded sessions
<AuthBy DYNAUTH>
  Identifier AuthBy-DYNAUTH

  SessionDatabase SessionDatabase-SQL

  # Send Change-Filter-Request (CoA) to NAS UDP port 1700
  #RequestType Change-Filter-Request
  # Send Disconnect-Request (DM) to NAS UDP port 1700
  RequestType Disconnect-Request
  DynAuthPort 1700

  # Do not try to lookup a session again
  NoSessionMapping

  # Send CoA/DM to IP address within NAS-IP-Address RADIUS attribute
  NasAddrAttribute NAS-IP-Address

  # Identify user session by User-Name, Acct-Session-Id and NAS-Port
  DynAuthAttribute User-Name
  DynAuthAttribute Acct-Session-Id
  DynAuthAttribute NAS-Port
</AuthBy>

# AuthBy RADIUSBYATTR for sending out DM/CoA requests for exceeded sessions
<AuthBy RADIUSBYATTR>
  Identifier AuthBy-RADIUSBYATTR
</AuthBy>

### Request Handlers ###

# Accounting Handler
<Handler Request-Type=Accounting-Request>
  Identifier Accounting-Handler

  # Acknowledge Accounting-Request immediately
  AccountingAccepted

  AuthByPolicy ContinueUntilRejectOrChallenge

  # Handle RADIUS accounting
  AuthBy AuthBy-HOTSPOTFIDELIO
  # Send DM/CoA request for exceeded session
  AuthBy AuthBy-DYNAUTH
</Handler>

# Outgoing DM/CoA Handler
<Handler DynAuthRequest=1>
  Identifier Handler-DYNAUTH

  AuthBy AuthBy-RADIUSBYATTR
</Handler>

# Default Handler
<Handler>
  Identifier Default-Handler

  # Use SessionDatabase-SQL
  SessionDatabase SessionDatabase-SQL
  # Don't try to delete a session before authentication
  SessionDatabaseOptions NoDeleteBeforeAuthentication

  # Handle RADIUS authentication
  AuthBy AuthBy-HOTSPOTFIDELIO

  RejectHasReason
</Handler>

Wednesday, February 7, 2018

New feature: OCSP and OCSP stapling support for TLS and EAP

New Radiator version 4.20 introduces support for OCSP and OCSP stapling for TLS based EAP methods (such as EAP-TLS, EAP-TTLS, and EAP-PEAP) and RadSec (TLS encryption for RADIUS over TCP).

OCSP (Online Certificate Status Protocol) is a method for checking certificates' revocation status online and is used as an alternative for CRL (Certificate Revocation List) files. Whereas CRL files needs to be updated every now and then, OCSP uses queries sent to CA (Certificate Authority) to obtain the latest revocation status.

Radiator uses OCSP to query and verify that EAP supplicant's or RadSec peer's certificate has not been revoked and can provide OCSP staple to EAP supplicants and RadSec peers to verify that Radiator's own certificate has not been revoked. More info about OCSP and OCSP staple can be found from the references at the end.

In order to use OCSP with Radiator, following conditions needs to be met:
  • Radiator version 4.20 or later
  • X.509 certificates and CA used support OCSP
  • OpenSSL library version 1.0.0 or later
  • Perl Net::SSLeay library version 1.83 or later
  • Perl LWP::UserAgent library
  • (Optional) Perl HTTP::Async library for asynchronous OCSP queries (supported only with EAP-TLS)

In this blog post, we show two configuration examples how to enable and test OCSP support.

We use demo certificates bundled with Radiator which do support OCSP.
You can check whether your X.509 certificate contains OCSP URL with the commands shown below.

Test client certificate:
% cd path/to/radiator-distribution
% openssl x509 -noout -issuer -subject -ocsp_uri -in certificates/cert-clt.pem
issuer= /C=AU/ST=Victoria/L=Melbourne/O=OSC Demo Certificates/OU=Test Certificate Section/CN=OSC Test CA (do not use in production)/emailAddress=mikem@open.com.au
subject= /C=AU/ST=Victoria/L=Melbourne/O=OSC Demo Certificates/OU=Test Certificate Section/CN=testUser
http://127.0.0.1:8008

Test server certificate:
% cd path/to/radiator-distribution
% openssl x509 -noout -issuer -subject -ocsp_uri -in certificates/cert-srv.pem
issuer= /C=AU/ST=Victoria/L=Melbourne/O=OSC Demo Certificates/OU=Test Certificate Section/CN=OSC Test CA (do not use in production)/emailAddress=mikem@open.com.au
subject= /C=AU/ST=Victoria/L=Melbourne/O=OSC Demo Certificates/OU=Test Certificate Section/CN=test.server.some.company.com
http://127.0.0.1:8008

For testing OCSP, we run OCSP responder provided by OpenSSL library.
Normally, CA who has signed the certificates runs OCSP responder on the Internet.

OCSP responder is run with a command shown below (pass phrase for all demo certificates is "whatever"):
% cd path/to/radiator-distribution/certificates
% openssl ocsp -rsigner root-CA-crt.pem -rkey root-CA-key.pem -index root-CA-idx.txt -port 8008 -CA root-CA-crt.pem -text
Enter pass phrase for root-CA-key.pem:
Waiting for OCSP client connections...

Leave OCSP responder running on http://127.0.0.1:8008/ and waiting for OCSP queries from Radiator.

EAP-TLS OCSP configuration example




Radiator configuration which enables OCSP queries and OCSP stapling for EAP-TLS (there is a similar example config in goodies/eap_tls.cfg):
Foreground
LogStdout
LogDir        .
DbDir         .
# User a lower trace level in production systems:
Trace         4
LogFile       %L/radiator.log

AuthPort 1812
AcctPort 1813

<Client DEFAULT>
      Secret radius
</Client>

<Handler>
      <AuthBy FILE>
            # Users must be in this file to get anywhere
            Filename %D/users
            
            EAPType                   TLS
            EAPTLS_CAFile             %D/certificates/demoCA/cacert.pem
            EAPTLS_CertificateFile    %D/certificates/cert-srv.pem
            EAPTLS_CertificateType    PEM
            EAPTLS_PrivateKeyFile     %D/certificates/cert-srv.pem
            EAPTLS_PrivateKeyPassword whatever
            EAPTLS_MaxFragmentSize    1200
            
            # Online Certificate Status Protocol (OCSP) related
            # configuration parameters

            # Provide OCSP staple for EAP-TLS clients asking for it.
            EAPTLS_OCSPStapling

            # Check OCSP status of EAP-TLS client certificates during TLS handshake
            EAPTLS_OCSPCheck

            # Check OCSP status of EAP-TLS client certificates asynchronous after TLS handshake
            # but before authenticating and authorizing the client.
            #EAPTLS_OCSPAsyncCheck

            # Reject EAP-TLS client certificate when OCSP responder is unavailable or OCSP status query fails.
            # By default, only a valid OCSP status response can reject EAP-TLS client certificate.
            EAPTLS_OCSPStrict

            # Use specified OCSP URI for OCSP queries instead of OCSP URI in EAP-TLS client certificate.
            #EAPTLS_OCSPURI

            # If OCSP query to OCSP URI fails, mark OCSP responder failed for 10 minutes.
            EAPTLS_OCSPFailureBackoffTime 600

            # Cache OCSP statuses for 1 hour (defaults to 20 minutes)
            EAPTLS_OCSPCacheTime 3600

            # Cache OCSP status for max 2000 different certificates (defaults to 1000 entries)
            EAPTLS_OCSPCacheSize 2000

            AutoMPPEKeys
      </AuthBy>
</Handler>

wpa_supplicant / eapol_test configuration for EAP-TLS which requires OCSP staple:
network={
      ssid="my8021xwpa"
      key_mgmt=WPA-EAP
      eap=TLS
      identity="testUser"
      ca_cert="./certificates/demoCA/cacert.pem"
      client_cert="./certificates/client-crt.pem"
      private_key="./certificates/client-key.pem"
      private_key_passwd="whatever"
      ocsp=2
}

RadSec OCSP configuration example


Besides TLS based EAP methods, OCSP can also be used with RadSec peerings, either with or without OCSP stapling.







Radiator configuration for RadSec client enables OCSP stapling (there is a similar example config in goodies/radsec-client.cfg):
Foreground
LogStdout
LogDir        .
DbDir         .
# User a lower trace level in production systems:
Trace         4

<Client DEFAULT>
      Secret mysecret
</Client>

<Handler>
      <AuthBy RADSEC>
            ReconnectTimeout        10
            NoreplyTimeout          5
            KeepaliveTimeout        30
            KeepaliveNoreplyTimeout 2
            UseStatusServerForFailureDetect

            UseTLS
            TLS_CAFile             %D/certificates/demoCA/cacert.pem
            TLS_CertificateFile    %D/certificates/cert-clt.pem
            TLS_CertificateType    PEM
            TLS_PrivateKeyFile     %D/certificates/cert-clt.pem
            TLS_PrivateKeyPassword whatever

            # Online Certificate Status Protocol (OCSP) related
            # configuration parameters

            # Request OCSP staple from RadSec server.
            TLS_OCSPStapling

            # Alternatively, check OCSP status of RadSec server certificates during TLS handshake.
            #TLS_OCSPCheck

            # Reject RadSec server certificate when OCSP staple or
            # OCSP responder is unavailable or OCSP status query
            # fails. By default, only a valid OCSP status
            # response can reject RadSec server certificate.
            TLS_OCSPStrict

            <Host localhost>
            </Host>
      </AuthBy>
</Handler>

Radiator configuration for RadSec server which enables OCSP queries and OCSP stapling (there is a similar example config in goodies/radsec-server.cfg):
Foreground
LogStdout
LogDir        .
DbDir         .
# User a lower trace level in production systems:
Trace         4

# Don't listen on any UDP ports
AuthPort
AcctPort

# Listen for AuthBy RADSEC connections from RadSec clients
<ServerRADSEC>
      UseTLS
      TLS_CAFile ./certificates/demoCA/cacert.pem
      TLS_CertificateFile ./certificates/cert-srv.pem
      TLS_CertificateType PEM
      TLS_PrivateKeyFile ./certificates/cert-srv.pem
      TLS_PrivateKeyPassword whatever

      TLS_RequireClientCert
      # Accept any peer with valid cert signed by demoCA for demo
      TLS_ExpectedPeerName .+

      # Online Certificate Status Protocol (OCSP) related
      # configuration parameters

      # Provide OCSP staple for RadSec client requesting it.
      TLS_OCSPStapling

      # Check OCSP status of RadSec client certificates during TLS handshake.
      TLS_OCSPCheck

      # Reject RadSec client certificate when OCSP staple or OCSP
      # responder is unavailable or OCSP status query fails. By
      # default, only a valid OCSP status response can reject RadSec
      # client certificate.
      TLS_OCSPStrict

      # Use specified OCSP URI for OCSP queries instead of OCSP URI in RadSec client certificate.
      #TLS_OCSPURI

      # If OCSP query to OCSP URI fails, mark OCSP responder failed for 10 minutes.
      TLS_OCSPFailureBackoffTime 600

      # Cache OCSP statuses for 1 hour (defaults to 20 minutes)
      TLS_OCSPCacheTime 3600

      # Cache OCSP status for max 2000 different certificates (defaults to 1000 entries)
      TLS_OCSPCacheSize 2000
</ServerRADSEC>

<Handler>
      <AuthBy FILE>
            Filename ./users
      </AuthBy>
</Handler>

Radiator acting as RadSec client (AuthBy RADSEC) will connect to Radiator acting as RadSec server (ServerRADSEC) and will request OCSP staple to be returned during TLS handshake. Server will get OCSP response for its own certificate and return it as OCSP staple to the client and when the client has sent its certificate, the server will query its revocation status with OCSP before accepting it.

References

Monday, June 6, 2016

Make your Radiator log data searchable

This is the first part of blog series that helps you to use log data that Radiator generates. Jump to second part.


Radiator exports AAA (authentication, authorisation, accounting) data to various formats. You can process the log data further by other log collection systems, such as Splunk and Elasticsearch. In this article, we briefly describe how to export data in JSON format. The common use case is to record the metrics that best describe your environment, for example, authentication, and authorisation messages.

The image below shows you an example of visualised Radiator worker statistics. The graphics were created with Grafana. Click the image for a larger view.





Adding a new field
With Radiator, it is possible to export log data in JSON format (for more information, see JSON.org). Basically, JSON is a set of name-value pairs. The values can also be ordered lists and it is possible to nest lists inside other lists. This makes it possible to express complex data structures in an universal manner with JSON.

Usually, the hardest part in modifying configuration is to figure out how to synchronise modifications everywhere, especially if the logs are centrally collected and parsed. For example, if Client-Identifier or some other RADIUS attribute is added to a log message when authentication fails, you have to ensure the log parser engine understands the new field.

This is an example of AuthLog FILE, which has date, username, and result.

Wed May 18 15:48:44 2016:mikem:FAIL

If you add a new field, the log entry looks like this:

Wed May 18 15:48:44 2016:mikem:client-1:FAIL

Here is the same information as a default JSON message without the new field:

{"timestamp":"2016-05-18T15:48:44Z","result":"reject","source_host":"osc-dev-3","username":"mikem","type":"authentication"}

Here is the JSON message with the new field: {"timestamp":"2016-05-18T15:48:44Z","result":"reject","source_host":"osc-dev-3","username":"mikem","type":"authentication", “client”:”client-1”}
With JSON, it is easy to add the new field to Radiator log message. Usually, there is no need to modify the parser configuration since the fields are just a group of name-value pairs and not fixed together in any way.

Configuring Radiator

The configuration process is straightforward: add Log <FILE, SYSLOG, ...> clause and use it in the same way as existing ones to your Radiator config and you are done. With Radiator, you can customise your own LogFormatHook and add, remove, or modify the fields. This is how Radiator extends the log usage possibilities even further.

Note: The following configuration example needs Radiator 4.16 with latest patches. You must have JSON module installed. JSON::XS module is recommended (see https://metacpan.org/pod/JSON and https://metacpan.org/pod/JSON::XS).


Configuration example: JSON output to radius.cfg (source goodies/logformat.cfg):



# This logger logs events in JSON format. It requires the Perl JSON
# module. Note the specific requirement for loading the logger module.
<Log FILE>
       Identifier mylogger-json
       Trace 4
       Filename %L/logfile.json
       LogFormatHook sub { Radius::LogFormat::format_log_json(@_); }
</Log>


# This auth logger logs both successes and failures to a JSON file.
<AuthLog FILE>
       Identifier myauthlogger-json
       Filename %L/authlog.json
       LogFormatHook sub { Radius::LogFormat::format_authlog_json(@_); }
       LogSuccess 1
       LogFailure 1
</AuthLog>


# This is the Handler-clause.
<Handler>
   <AuthBy FILE>
       Filename %D/users
   </AuthBy>
   AuthLog myauthlogger-json
   # Log accounting messages in JSON format.
   AcctLogFileName %L/acctlog.json
   AcctLogFileFormatHook sub { Radius::LogFormat::format_acctlog_json(@_); }
</Handler>



In this example configuration, all log data is saved into a single file. This may cause problems in the real configuration because of increasing log data file size. You can avoid this by using log rotation tools, for example, logrotate in Unix-based systems. Rotating log files can safely be done without restarting Radiator. Radiator also supports the special characters in the file names.

Do you want to know more?
Your JSON files are now ready, the next step is to use them efficiently. In the next part of the series, we will introduce the more detailed use cases, which will help you get the most out of Radiator logging.