Run radius server inside keycloak. features:
unzip keycloak-radius.zip -d keycloak-radius
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
requirements: java jdk 11 and above, maven 3.5 and above
cd keycloak-plugins
mvn clean install
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
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/
example
{
"sharedSecret": "radsec",
"authPort": 1812,
"accountPort": 1813,
"numberThreads": 8,
"useUdpRadius": true,
"externalDictionary": "/opt/dictionary",
"otp": false,
"radsec": {
"privateKey": "config/private.key",
"certificate": "config/public.crt",
"numberThreads": 8,
"useRadSec": true
},
"coa":{
"port":3799,
"useCoA":true
}
}
where
Run Keycloak Locally
#!/usr/bin/env bash
set -e
cd keycloak-21.0.0
sh bin/kc.sh --debug 8190 start-dev --http-port=8090
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 |
NOTE: Composite roles supported
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>
COND_
Example:
COND_NAS-IP-Address = "192.168.88.1, 192.168.88.2"
The role will only be applied if the NAS server address is 192.168.88.1 or 192.168.88.2.
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>
REJECT_
Example:
REJECT_NAS-IP-Address = "192.168.88.2"
The role will only be applied if the NAS server address is not 192.168.88.2, otherwise request will be rejected
If Reject Attribute is present then access request will be rejected.
Structure of Attribute: REJECT_RADIUS=<ANY VALUE>
Example:
REJECT_RADIUS = "true"
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>
ACCEPT_
Example:
ACCEPT_NAS-IP-Address = "192.168.88.1"
The role will only be applied if the NAS server address is not 192.168.88.2, otherwise request will be rejected
NOTE: SubGroups supported
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>
COND_
Example: Role Conditional Attributes/README.md:1
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>
REJECT_
Example: Role REJECT Attributes
If Reject Attribute is present then access request will be rejected.
Structure of Attribute: REJECT_RADIUS=<ANY VALUE>
Example:
REJECT_RADIUS = "true"
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>
ACCEPT_
Example: Role ACCEPT 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>
COND_
Example: Role Conditional Attributes/README.md:1
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>
REJECT_
Example: Role REJECT 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>
ACCEPT_
Example: Role ACCEPT 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>
COND_
Example: Role Conditional Attributes/README.md:1
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>
REJECT_
Example: Role REJECT Attributes
If Reject Attribute is present then access request will be rejected.
Structure of Attribute: REJECT_RADIUS=<ANY VALUE>
Example:
REJECT_RADIUS = "true"
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>
ACCEPT_
Example: Role ACCEPT Attributes
Hotspot Example (with Facebook login)
<Keycloak Password/RADIUS Password><OTP>
example: testPassword123456, where testPassword is password, 123456 is otp<RADIUS Password><OTP>
example: testPassword123456, where testPassword is password, 123456 is otp<OTP>
example: 123456, where 123456 is otp
VENDOR 12356 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)