vzakharchenko / keycloak-radius-plugin

Make the radius server as part of keycloak SSO
Apache License 2.0
188 stars 46 forks source link
authport chillispot cisco docker docker-compose fido2 hotspot keycloak keycloak-plugin mikrotik radius radius-accounting radius-attributes radius-plugin radius-protocol radius-proxy radius-server radsec-server webauthn yubikey

Embedded Radius Server in Keycloak SSO

CircleCI Java CI with Maven Node.js Examples Coverage Status [Maven Central] BCH compliance

Run radius server inside keycloak. features:

Examples

Donate

Donate

Release Setup

  1. Download keycloak-radius.zip asset from github releases
  2. unzip release
    unzip keycloak-radius.zip -d keycloak-radius
  3. run keycloak
    sh keycloak-radius/bin/standalone.sh  -c standalone.xml -b 0.0.0.0 -Djboss.bind.address.management=0.0.0.0 --debug 8190 -Djboss.http.port=8090
  4. open http://localhost:8090
  5. initialize keycloak master realm

    Docker Container

    Run inside Docker Container

    Manual Setup

    build project

    requirements: java jdk 11 and above, maven 3.5 and above

    • cd keycloak-plugins
    • mvn clean install

      Configure Keycloak (based on Quarkus)

      requirements: keycloak 21.0.0

      cp ${SOURCE}/keycloak-plugins/radius-plugin/target/radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/radius-plugin-1.5.0-SNAPSHOT.jar
      cp ${SOURCE}/keycloak-plugins/rad-sec-plugin/target/rad-sec-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/rad-sec-plugin-1.5.0-SNAPSHOT.jar
      cp ${SOURCE}/keycloak-plugins/mikrotik-radius-plugin/target/mikrotik-radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/mikrotik-radius-plugin-1.5.0-SNAPSHOT.jar
      cp ${SOURCE}/keycloak-plugins/cisco-radius-plugin/target/cisco-radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/cisco-radius-plugin-1.5.0-SNAPSHOT.jar
      cp ${SOURCE}/keycloak-plugins/chillispot-radius-plugin/target/chillispot-radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/chillispot-radius-plugin-1.5.0-SNAPSHOT.jar
      cp ${SOURCE}/keycloak-plugins/radius-disconnect-plugin/target/radius-disconnect-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/radius-disconnect-plugin-1.5.0-SNAPSHOT.jar
      cp ${SOURCE}/keycloak-plugins/proxy-radius-plugin/target/proxy-radius-plugin-1.5.0-SNAPSHOT.jar ${KEYCLOAK_PATH}/providers/proxy-radius-plugin-1.5.0-SNAPSHOT.jar
      cp ${SOURCE}/keycloak-radius-plugin/keycloak-plugins/radius-theme/target/radius-theme-1.5.0-SNAPSHOT.zip ${KEYCLOAK_PATH}/providers/radius-theme-1.5.0-SNAPSHOT.jar

      where

    • KEYCLOAK_PATH - Path where you are unpacked keycloak-21.0.0.zip (you can use RADIUS_CONFIG_PATH instead of KEYCLOAK_PATH)
    • SOURCE - Path where you checked out the code and built the project

Environment Variables

Variable Name Variable Value Config file Location
KEYCLOAK_PATH Path where you are unpacked keycloak ${KEYCLOAK_PATH}/config/radius.config
RADIUS_CONFIG_PATH Path where you store radius.config ${RADIUS_CONFIG_PATH}/radius.config

Examples:

export RADIUS_CONFIG_PATH= /opt/keycloak/radius/config

or

export KEYCLOAK_PATH= /opt/keycloak/

Configuration

Radius server config file

Keycloak Client with Radius Protocol

radiusProtocol

Mapping Radius Password to Keycloak Credentials

Radius Protocol Keycloak credentials Keycloak credentials with OTP Kerberos credentials Ldap credentials Keycloak Radius credentials Keycloak Radius credentials with OTP Keycloak OTP(if config file contains "otp":true)
PAP Yes Yes Yes Yes Yes Yes NO
CHAP No No No No Yes Yes Yes
MSCHAPV2 No No No No Yes Yes Yes

Assign Radius Attributes to Role

NOTE: Composite roles supported

RoleAttributes

Role Conditional Attributes

if conditional Attribute is present and has valid value then all other attributes will be applied. (Example: apply role attributes only if NAS-IP-Address= 192.168.88.1)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example:

COND_NAS-IP-Address = "192.168.88.1, 192.168.88.2"

ConditionalRole The role will only be applied if the NAS server address is 192.168.88.1 or 192.168.88.2.

Role REJECT Attributes (Example)

if reject Attribute is present and has valid value then access request will be rejected. (Example: reject user request if access request contains attribute NAS-IP-Address= 192.168.88.1)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example:

REJECT_NAS-IP-Address = "192.168.88.2"

reject_conditional The role will only be applied if the NAS server address is not 192.168.88.2, otherwise request will be rejected

Role REJECT WITHOUT CONDITION

If Reject Attribute is present then access request will be rejected. Structure of Attribute: REJECT_RADIUS=<ANY VALUE> Example:

REJECT_RADIUS = "true"

Role ACCEPT Attributes (Example)

if accept Attribute is present and has valid value then access request will be accepted, otherwise rejected. (Example: accept user request if access request contains attribute NAS-IP-Address= 192.168.88.1,192.168.88.2)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example:

ACCEPT_NAS-IP-Address = "192.168.88.1"

acceptConditional The role will only be applied if the NAS server address is not 192.168.88.2, otherwise request will be rejected

Assign Radius Attributes to Group

NOTE: SubGroups supported groupAttributes

Group Conditional Attributes

if conditional Attribute is present and has valid value then all other attributes will be applied. (Example: apply group attributes only if NAS-IP-Address= 192.168.88.1)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example: Role Conditional Attributes/README.md:1

Group REJECT Attributes

if reject Attribute is present and has valid value then access request will be rejected. (Example: reject user request if access request contains attribute NAS-IP-Address= 192.168.88.1)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example: Role REJECT Attributes

Group REJECT WITHOUT CONDITION

If Reject Attribute is present then access request will be rejected. Structure of Attribute: REJECT_RADIUS=<ANY VALUE> Example:

REJECT_RADIUS = "true"

Group ACCEPT Attributes

if accept Attribute is present and has valid value then access request will be accepted, otherwise rejected. (Example: accept user request if access request contains attribute NAS-IP-Address= 192.168.88.1,192.168.88.2)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example: Role ACCEPT Attributes

Assign Radius Attributes to User

userAttributes

User Conditional Attributes

if conditional Attribute is present and has valid value then all other attributes will be applied. (Example: apply user attributes only if NAS-IP-Address= 192.168.88.1)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example: Role Conditional Attributes/README.md:1

User REJECT Attributes

if reject Attribute is present and has valid value then access request will be rejected. (Example: reject user request if access request contains attribute NAS-IP-Address= 192.168.88.1)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example: Role REJECT Attributes

User ACCEPT Attributes

if accept Attribute is present and has valid value then access request will be accepted, otherwise rejected. (Example: accept user request if access request contains attribute NAS-IP-Address= 192.168.88.1,192.168.88.2)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example: Role ACCEPT Attributes

Assign Radius Attributes to Authorization Resource

Change admin theme to "Radius"

radiusTheme

Enable Authorization on Radius Client

Authorization

Create Resource

Authorization

Assign Attributes to Resource

assignAttributesToResource

Create policy and permissions

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example: Role Conditional Attributes/README.md:1

Resource REJECT Attributes

if reject Attribute is present and has valid value then access request will be rejected. (Example: reject user request if access request contains attribute NAS-IP-Address= 192.168.88.1)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example: Role REJECT Attributes

Resource REJECT without condition

If Reject Attribute is present then access request will be rejected. Structure of Attribute: REJECT_RADIUS=<ANY VALUE> Example:

REJECT_RADIUS = "true"

Resource ACCEPT Attributes

if accept Attribute is present and has valid value then access request will be accepted, otherwise rejected. (Example: accept user request if access request contains attribute NAS-IP-Address= 192.168.88.1,192.168.88.2)

Structure of Attribute:

\<PREFIX>\<ATTRIBUTE_NAME>=\<values>

Example: Role ACCEPT Attributes

Hotspot Example (with Facebook login)

Hotspot Example (with Facebook login)

Example CoA Configuration

Radius Disconnect Message

Radius Proxy

Radius Proxy Module

Keycloak Radius credentials

Otp Password

  1. enable Otp Password on Keycloak side. https://www.keycloak.org/docs/latest/server_admin/ impersonateUserExample3 impersonateUserExample4
  2. password in request must contain the password and otp.
  3. Structure Password in request:
    • PAP password: <Keycloak Password/RADIUS Password><OTP> example: testPassword123456, where testPassword is password, 123456 is otp
    • MSCHAP/CHAP: <RADIUS Password><OTP> example: testPassword123456, where testPassword is password, 123456 is otp
    • PAP password with Otp (if config file contains "otp":true) : <OTP> example: 123456, where 123456 is otp

OTP Password example

WebAuthn Authentication

wiki page

Add custom Radius Dictionary(example for Fortinet)

VENDORATTR 12356 Fortinet-Group-Name 1 string VENDORATTR 12356 Fortinet-Client-IP-Address 2 ipaddr VENDORATTR 12356 Fortinet-Vdom-Name 3 string VENDORATTR 12356 Fortinet-Client-IPv6-Address 4 octets VENDORATTR 12356 Fortinet-Interface-Name 5 string VENDORATTR 12356 Fortinet-Access-Profile 6 string

 - run as docker container

docker run -p 8090:8080 -e -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true" -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e RADIUS_DICTIONARY=/opt/dictionary -v pwd/Fortinet.dictionary:/opt/dictionary vassio/keycloak-radius-plugin



### Development
[wiki page](https://github.com/vzakharchenko/keycloak-radius-plugin/wiki/Development)