diff --git a/README.md b/README.md index b173644..cc12d2a 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,11 @@ Python script for Home Assistant adding authentication via RADIUS\ The project is based on the library [pyrad](https://github.com/pyradius/pyrad.git) +## Overview +The script is designed to authenticate users in Home Assistant via a RADIUS server. This allows you to centrally manage user access.
+The script supports 2 launch modes: [auth_providers](#usage-in-auth_provider-mode) and [CLI](#usage-in-cli-mode). +For correct operation, you must add to the [dictionary](./dictionary) in the RADIUS server dictionary file. + ## Install [![](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=losenmann&repository=auth-radius&category=python_script) @@ -15,11 +20,12 @@ The project is based on the library [pyrad](https://github.com/pyradius/pyrad.gi - **Method 2.** Copy the manually `auth-radius.py` from [latest release](https://github.com/Losenmann/auth-radius/releases/latest) to path `/config/python_scripts` -## Setupe +## Usage in auth_provider mode +### Setupe - **Home Assistant** 1. Set connection parameters in the `secrets.yaml` file ```yaml - radius_host: "dns_or_ip_addreess_radius_server" + radius_server: "dns_or_ip_addreess_radius_server" radius_secret: "radius_server_secret" ``` 2. In the `configuration.yaml` file add the configuration, the authentication order matters @@ -28,11 +34,12 @@ The project is based on the library [pyrad](https://github.com/pyradius/pyrad.gi auth_providers: - type: command_line command: '/usr/local/bin/python' - args: ['/config/python_scripts/auth-radius.py', '--meta'] + args: ['/config/python_scripts/auth-radius.py', '-m'] meta: true - type: homeassistant ``` - You can remove the `meta:true` directive so that the script does not write some variables to standard output to populate the user account created in Home Assistant with additional data +> [!NOTE] +> You can remove the `meta: true` directive so that the script does not write some variables to standard output to populate the user account created in Home Assistant with additional data - **RADIUS** 1. Add data from the file [dictionary](./dictionary) to the RADIUS server's `dictionary` file @@ -43,3 +50,22 @@ The project is based on the library [pyrad](https://github.com/pyradius/pyrad.gi | `Hass-Group` | string | system-users
system-admin | User group | | `Hass-Local-Only` | byte | 0
1 | Local login only
(Defaults to 0) | | `Hass-Is-Active` | byte | 0
1 | Activate user account
(Defaults to 1) | + +## Usage in CLI mode +In CLI mode, you need to set execution permissions `chmod +x ./python_scripts/auth-ldap.py`
+Or run via Python `python ./python_scripts/auth-radius.py` +> [!NOTE] +> RADIUS connection parameters can be configured in `secrets.yaml`, see point 1 of the chapter [Usage in auth_provider mode](#usage-in-auth_provider-mode) +``` +./python_scripts/auth-radius.py -U 'username' -P 'password' -s 'radius.example.com' -S 'secret' +``` + +## Script arguments +| key | type | description | +| :--- | :--: | :---------- | +| `-h` | boolean | Get help information | +| `-m` | boolean | Enable meta to output credentials to stdout
(Defaults to False) | +| `-U` | string | Username | +| `-P` | string | Password | +| `-s` | string | RADIUS server
(Defaults from `secrets.yaml`) | +| `-S` | string | RADIUS secret
(Defaults from `secrets.yaml`) | diff --git a/info.md b/info.md index b173644..cc12d2a 100644 --- a/info.md +++ b/info.md @@ -8,6 +8,11 @@ Python script for Home Assistant adding authentication via RADIUS\ The project is based on the library [pyrad](https://github.com/pyradius/pyrad.git) +## Overview +The script is designed to authenticate users in Home Assistant via a RADIUS server. This allows you to centrally manage user access.
+The script supports 2 launch modes: [auth_providers](#usage-in-auth_provider-mode) and [CLI](#usage-in-cli-mode). +For correct operation, you must add to the [dictionary](./dictionary) in the RADIUS server dictionary file. + ## Install [![](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=losenmann&repository=auth-radius&category=python_script) @@ -15,11 +20,12 @@ The project is based on the library [pyrad](https://github.com/pyradius/pyrad.gi - **Method 2.** Copy the manually `auth-radius.py` from [latest release](https://github.com/Losenmann/auth-radius/releases/latest) to path `/config/python_scripts` -## Setupe +## Usage in auth_provider mode +### Setupe - **Home Assistant** 1. Set connection parameters in the `secrets.yaml` file ```yaml - radius_host: "dns_or_ip_addreess_radius_server" + radius_server: "dns_or_ip_addreess_radius_server" radius_secret: "radius_server_secret" ``` 2. In the `configuration.yaml` file add the configuration, the authentication order matters @@ -28,11 +34,12 @@ The project is based on the library [pyrad](https://github.com/pyradius/pyrad.gi auth_providers: - type: command_line command: '/usr/local/bin/python' - args: ['/config/python_scripts/auth-radius.py', '--meta'] + args: ['/config/python_scripts/auth-radius.py', '-m'] meta: true - type: homeassistant ``` - You can remove the `meta:true` directive so that the script does not write some variables to standard output to populate the user account created in Home Assistant with additional data +> [!NOTE] +> You can remove the `meta: true` directive so that the script does not write some variables to standard output to populate the user account created in Home Assistant with additional data - **RADIUS** 1. Add data from the file [dictionary](./dictionary) to the RADIUS server's `dictionary` file @@ -43,3 +50,22 @@ The project is based on the library [pyrad](https://github.com/pyradius/pyrad.gi | `Hass-Group` | string | system-users
system-admin | User group | | `Hass-Local-Only` | byte | 0
1 | Local login only
(Defaults to 0) | | `Hass-Is-Active` | byte | 0
1 | Activate user account
(Defaults to 1) | + +## Usage in CLI mode +In CLI mode, you need to set execution permissions `chmod +x ./python_scripts/auth-ldap.py`
+Or run via Python `python ./python_scripts/auth-radius.py` +> [!NOTE] +> RADIUS connection parameters can be configured in `secrets.yaml`, see point 1 of the chapter [Usage in auth_provider mode](#usage-in-auth_provider-mode) +``` +./python_scripts/auth-radius.py -U 'username' -P 'password' -s 'radius.example.com' -S 'secret' +``` + +## Script arguments +| key | type | description | +| :--- | :--: | :---------- | +| `-h` | boolean | Get help information | +| `-m` | boolean | Enable meta to output credentials to stdout
(Defaults to False) | +| `-U` | string | Username | +| `-P` | string | Password | +| `-s` | string | RADIUS server
(Defaults from `secrets.yaml`) | +| `-S` | string | RADIUS secret
(Defaults from `secrets.yaml`) | diff --git a/python_scripts/auth-radius.py b/python_scripts/auth-radius.py index f21e574..5a08ec7 100755 --- a/python_scripts/auth-radius.py +++ b/python_scripts/auth-radius.py @@ -38,29 +38,57 @@ def main(): vendor = 812300 - parser = argparse.ArgumentParser(description="Home Assistant RADIUS authentication via CLI") - parser.add_argument('-m', '--meta', action='store_true', help='Enable meta to output credentials to stdout') + parser = argparse.ArgumentParser( + prog='Auth RADIUS', + description='Home Assistant RADIUS authentication via CLI', + epilog='https://github.com/Losenmann/auth-radius' + ) + parser.add_argument('-m', '--meta', action='store_true', help='enable meta to output credentials to stdout') + parser.add_argument('-U', '--username', type=str, help='username') + parser.add_argument('-P', '--password', type=str, help='user password') + parser.add_argument('-s', '--server', type=str, help='RADIUS server') + parser.add_argument('-S', '--secret', type=str, help='RADIUS secret') args = parser.parse_args() - if not os.path.isfile("/config/python_scripts/dictionary"): + if not os.path.isfile("/config/.storage/dictionary.radius"): if not args.meta: print("Create dictionary file") - f = open("/config/python_scripts/dictionary", "w") + f = open("/config/.storage/dictionary.radius", "w") f.write(base64.b64decode(DictFileBase64()).decode("utf-8")) f.close() with open("/config/secrets.yaml") as fh: - secret = yaml.load(fh, Loader=yaml.FullLoader) + secret = yaml.load(fh, Loader=yaml.FullLoader) + try: + v_username = args.username if args.username else os.environ['username'] + except: + print("\033[33m{}\033[0m".format("Username not specified")) + sys.exit(1) + try: + v_password = args.password if args.password else os.environ['password'] + except: + print("\033[33m{}\033[0m".format("User password not specified")) + sys.exit(1) + try: + v_server = args.server if args.server else secret['radius_server'] + except: + print("\033[33m{}\033[0m".format("Server not specified")) + sys.exit(1) + try: + v_secret = args.secret if args.secret else secret['radius_secret'] + except: + print("\033[33m{}\033[0m".format("Server secret not specified")) + sys.exit(1) srv = Client( - server=bytes(secret["radius_host"], encoding="utf-8"), - secret=bytes(secret["radius_secret"], encoding="utf-8"), - dict=Dictionary("/config/python_scripts/dictionary") + server=bytes(v_server, encoding="utf-8"), + secret=bytes(v_secret, encoding="utf-8"), + dict=Dictionary("/config/.storage/dictionary.radius") ) req = srv.CreateAuthPacket(code=AccessRequest) - req["User-Name"] = os.environ['username'] - req["User-Password"] = req.PwCrypt(os.environ['password']) + req["User-Name"] = v_username + req["User-Password"] = req.PwCrypt(v_password) try: if not args.meta: @@ -76,20 +104,24 @@ def main(): sys.exit(1) if reply.code == AccessAccept: - v_local_only = "false" - if int(reply[(vendor, 2)][0].hex(), 16) > 0: - v_local_only = "true" - if args.meta: - print("name=" + req["User-Name"][0]) - print("group=" + reply[(vendor, 1)][0].decode("utf-8")) - print("local_only=" + v_local_only) - print("is_activ=" + "true") + if reply[(vendor, 1)][0].decode("utf-8") in ['system-admin', 'system-users']: + v_local_only = "false" + if int(reply[(vendor, 2)][0].hex(), 16) > 0: + v_local_only = "true" + if args.meta: + print("name=" + req["User-Name"][0]) + print("group=" + reply[(vendor, 1)][0].decode("utf-8")) + print("local_only=" + v_local_only) + print("is_activ=" + "true") + else: + print("\033[32m{}\033[0m".format("Access accepted")) + exit(0) else: - print("Access accepted") - exit(0) + if not args.meta: + print("\033[31m{}\033[0m".format("Insufficient access rights")) else: if not args.meta: - print("Access denied") + print("\033[31m{}\033[0m".format("Access denied")) exit(1) """bidict.py"""