2020-05-26 00:15:56 +02:00
---
2022-02-21 08:16:54 +01:00
title: Custom authentication
sidebar_position: 40
2020-05-26 00:15:56 +02:00
---
2020-05-15 18:51:40 +02:00
2022-08-03 10:51:48 +02:00
:::warning
Since LibreTime v3.0.0-alpha.13, this documentation is out of date, as it relies on the Apache2 web server and the default web server installed by LibreTime is now NGINX.
:::
2022-02-21 08:16:54 +01:00
## Setup FreeIPA authentication
2017-03-18 19:15:20 +01:00
You can configure LibreTime to delegate all authentication to a FreeIPA server.
This allows you users to use their existing FreeIPA credentials. For this to
work you need to configure Apache to use `mod_authnz_pam` and `mod_intercept_form_submit` .
2022-02-21 08:16:54 +01:00
### Apache configuration
2017-03-18 19:15:20 +01:00
After installing the needed modules you can set up Apache to intercept form logins and
check them against pam.
2022-02-10 12:15:23 +01:00
```apacheconf
2017-03-18 19:15:20 +01:00
< Location / login >
InterceptFormPAMService http-libretime
InterceptFormLogin username
InterceptFormPassword password
InterceptFormLoginSkip admin
InterceptFormPasswordRedact on
InterceptFormLoginRealms INT.RABE.CH
Require pam-account http-libretime
< / Location >
< Location / >
< RequireAny >
< RequireAny >
Require pam-account http-libretime
Require all granted
< / RequireAny >
< RequireAll >
Require expr %{REQUEST_URI} =~ /(index.php|login|favicon.ico|js|css|locale)/
Require all granted
< / RequireAll >
< / RequireAny >
< / Location >
```
2022-02-21 08:16:54 +01:00
### PAM configuration
2017-03-18 19:15:20 +01:00
The above configuration expects a PAM configuration for the `http-libretime` service.
2024-06-05 17:54:12 +02:00
To configure this you need to create the file `/etc/pam.d/http-libretime` with the following contents.
2017-03-18 19:15:20 +01:00
```
auth required pam_sss.so
account required pam_sss.so
```
2022-02-21 08:16:54 +01:00
### LDAP configuration
2017-03-18 19:15:20 +01:00
LibreTime needs direct access to LDAP so it can fetch additional information. It does so with
a [system account ](https://www.freeipa.org/page/HowTo/LDAP#System_Accounts ) that you need to
set up beforehand.
2021-05-27 16:20:34 +02:00
You can configure everything pertaining to how LibreTime accesses LDAP in
2022-06-06 17:10:44 +02:00
`/etc/libretime/config.yml` . The default file has the following values you need to change.
2017-03-18 19:15:20 +01:00
2022-06-06 17:04:26 +02:00
```yml
2021-05-27 16:20:34 +02:00
#
2017-03-18 19:15:20 +01:00
# ----------------------------------------------------------------------
# L D A P
# ----------------------------------------------------------------------
#
# hostname: Hostname of LDAP server
#
# binddn: Complete DN of user used to bind to LDAP
#
# password: Password for binddn user
#
# account_domain: Domain part of username
#
# basedn: base search DN
#
# filter_field: Name of the uid field for searching
# Usually uid, may be cn
#
# groupmap_*: Map LibreTime user types to LDAP groups
# Lets LibreTime assign user types based on the
# group a given user is in.
#
2022-06-06 17:04:26 +02:00
ldap:
hostname: ldap.example.org
binddn: "uid=libretime,cn=sysaccounts,cn=etc,dc=int,dc=example,dc=org"
password: hackme
account_domain: INT.EXAMPLE.ORG
basedn: "cn=users,cn=accounts,dc=int,dc=example,dc=org"
filter_field: uid
groupmap_guest: "cn=guest,cn=groups,cn=accounts,dc=int,dc=example,dc=org"
groupmap_host: "cn=host,cn=groups,cn=accounts,dc=int,dc=example,dc=org"
groupmap_program_manager: "cn=program_manager,cn=groups,cn=accounts,dc=int,dc=example,dc=org"
groupmap_admin: "cn=admins,cn=groups,cn=accounts,dc=int,dc=example,dc=org"
groupmap_superadmin: "cn=superadmin,cn=groups,cn=accounts,dc=int,dc=example,dc=org"
2017-03-18 19:15:20 +01:00
```
2022-02-21 08:16:54 +01:00
### Enable FreeIPA authentication
2017-03-18 19:15:20 +01:00
2022-06-06 17:09:25 +02:00
After everything is set up properly you can enable FreeIPA auth in `config.yml` :
2017-03-18 19:15:20 +01:00
2022-06-06 17:04:26 +02:00
```yml
general:
auth: LibreTime_Auth_Adaptor_FreeIpa
2017-03-18 19:15:20 +01:00
```
You should now be able to use your FreeIPA credentials to log in to LibreTime.
feat(legacy): trused header sso auth (#3095)
### Description
Allows LibreTime to support Trusted Header SSO Authentication.
**This is a new feature**:
Yes
**I have updated the documentation to reflect these changes**:
Yes
### Testing Notes
**What I did:**
I spun up an Authelia/Traefik pair and configured them to protect
LibreTime according to Authelia's documentation, I then tested that you
could log in via the trusted headers, and tested that old methods of
authentication were not affected.
**How you can replicate my testing:**
Using the following `docker-compose.yml` file
```yml
services:
postgres:
image: postgres:15
networks:
- internal
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: ${POSTGRES_USER:-libretime}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-libretime} # Change me !
healthcheck:
test: pg_isready -U libretime
rabbitmq:
image: rabbitmq:3.13-alpine
networks:
- internal
environment:
RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_DEFAULT_VHOST:-/libretime}
RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-libretime}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-libretime} # Change me !
healthcheck:
test: nc -z 127.0.0.1 5672
playout:
image: ghcr.io/libretime/libretime-playout:${LIBRETIME_VERSION:-latest}
networks:
- internal
init: true
ulimits:
nofile: 1024
depends_on:
- rabbitmq
volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
- libretime_playout:/app
environment:
LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080
liquidsoap:
image: ghcr.io/libretime/libretime-playout:${LIBRETIME_VERSION:-latest}
networks:
- internal
command: /usr/local/bin/libretime-liquidsoap
init: true
ulimits:
nofile: 1024
ports:
- 8001:8001
- 8002:8002
depends_on:
- rabbitmq
volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
- libretime_playout:/app
environment:
LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080
analyzer:
image: ghcr.io/libretime/libretime-analyzer:${LIBRETIME_VERSION:-latest}
networks:
- internal
init: true
ulimits:
nofile: 1024
depends_on:
- rabbitmq
volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
- libretime_storage:/srv/libretime
environment:
LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080
worker:
image: ghcr.io/libretime/libretime-worker:${LIBRETIME_VERSION:-latest}
networks:
- internal
init: true
ulimits:
nofile: 1024
depends_on:
- rabbitmq
volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
environment:
LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080
api:
image: ghcr.io/libretime/libretime-api:${LIBRETIME_VERSION:-latest}
networks:
- internal
init: true
ulimits:
nofile: 1024
depends_on:
- postgres
- rabbitmq
volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
- libretime_storage:/srv/libretime
legacy:
image: ghcr.io/libretime/libretime-legacy:${LIBRETIME_VERSION:-latest}
networks:
- internal
init: true
ulimits:
nofile: 1024
depends_on:
- postgres
- rabbitmq
volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
- libretime_assets:/var/www/html
- libretime_storage:/srv/libretime
nginx:
image: nginx
networks:
- internal
- net
ports:
- 8080:8080
depends_on:
- legacy
volumes:
- libretime_assets:/var/www/html:ro
- libretime_storage:/srv/libretime:ro
- ${NGINX_CONFIG_FILEPATH:-./nginx.conf}:/etc/nginx/conf.d/default.conf:ro
labels:
- 'traefik.enable=true'
- 'traefik.docker.network=libretime_net'
- 'traefik.http.routers.libretime.rule=Host(`libretime.example.com`)'
- 'traefik.http.routers.libretime.entrypoints=https'
- 'traefik.http.routers.libretime.tls=true'
- 'traefik.http.routers.libretime.tls.options=default'
- 'traefik.http.routers.libretime.middlewares=authelia@docker'
- 'traefik.http.services.libretime.loadbalancer.server.port=8080'
icecast:
image: ghcr.io/libretime/icecast:2.4.4
networks:
- internal
ports:
- 8000:8000
environment:
ICECAST_SOURCE_PASSWORD: ${ICECAST_SOURCE_PASSWORD:-hackme} # Change me !
ICECAST_ADMIN_PASSWORD: ${ICECAST_ADMIN_PASSWORD:-hackme} # Change me !
ICECAST_RELAY_PASSWORD: ${ICECAST_RELAY_PASSWORD:-hackme} # Change me !
traefik:
image: traefik:v2.11.12
container_name: traefik
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- net
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.api.rule=Host(`traefik.example.com`)'
- 'traefik.http.routers.api.entrypoints=https'
- 'traefik.http.routers.api.service=api@internal'
- 'traefik.http.routers.api.tls=true'
- 'traefik.http.routers.api.tls.options=default'
- 'traefik.http.routers.api.middlewares=authelia@docker'
ports:
- '80:80'
- '443:443'
command:
- '--api'
- '--providers.docker=true'
- '--providers.docker.exposedByDefault=false'
- '--entrypoints.http=true'
- '--entrypoints.http.address=:80'
- '--entrypoints.http.http.redirections.entrypoint.to=https'
- '--entrypoints.http.http.redirections.entrypoint.scheme=https'
- '--entrypoints.https=true'
- '--entrypoints.https.address=:443'
- '--log=true'
- '--log.level=DEBUG'
authelia:
image: authelia/authelia
container_name: authelia
networks:
- net
volumes:
- ./authelia:/config
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.authelia.rule=Host(`auth.example.com`)'
- 'traefik.http.routers.authelia.entrypoints=https'
- 'traefik.http.routers.authelia.tls=true'
- 'traefik.http.routers.authelia.tls.options=default'
- 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/authz/forward-auth' # yamllint disable-line rule:line-length
- 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
- 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email' # yamllint disable-line rule:line-length
- 'traefik.http.services.authelia.loadbalancer.server.port=9091'
restart: unless-stopped
environment:
- TZ=America/Los_Angeles
volumes:
postgres_data: {}
libretime_storage: {}
libretime_assets: {}
libretime_playout: {}
networks:
internal:
net:
```
The following libretime dev config modification:
```yml
general:
public_url: https://libretime.example.com
auth: LibreTime_Auth_Adaptor_Header
header_auth:
group_map:
host: lt-host
program_manager: lt-pm
admin: lt-admin
superadmin: lt-superadmin
```
And the following authelia config file:
```yml
---
###############################################################
# Authelia configuration #
###############################################################
server:
address: 'tcp://:9091'
buffers:
read: 16384
write: 16384
log:
level: 'debug'
totp:
issuer: 'authelia.com'
identity_validation:
reset_password:
jwt_secret: 'a_very_important_secret'
authentication_backend:
file:
path: '/config/users_database.yml'
access_control:
default_policy: 'deny'
rules:
- domain: 'traefik.example.com'
policy: 'one_factor'
- domain: 'libretime.example.com'
policy: 'one_factor'
session:
secret: 'insecure_session_secret'
cookies:
- name: 'authelia_session'
domain: 'example.com' # Should match whatever your root protected domain is
authelia_url: 'https://auth.example.com'
expiration: '1 hour' # 1 hour
inactivity: '5 minutes' # 5 minutes
regulation:
max_retries: 3
find_time: '2 minutes'
ban_time: '5 minutes'
storage:
encryption_key: 'you_must_generate_a_random_string_of_more_than_twenty_chars_and_configure_this'
local:
path: '/config/db.sqlite3'
notifier:
filesystem:
filename: '/config/notification.txt'
...
```
And the following authelia users database:
```yml
---
###############################################################
# Users Database #
###############################################################
# This file can be used if you do not have an LDAP set up.
# List of users
users:
test:
disabled: false
displayname: "First Last"
password: "$argon2id$v=19$m=16,t=2,p=1$SWVVVzcySlRLUEFkWWh2eA$qPs1ZmzmDXR/9WckDzIN9Q"
email: test@example.com
groups:
- admins
- dev
- lt-admin
...
```
add the following entries to your `hosts` file:
```
127.0.0.1 traefik.example.com
127.0.0.1 auth.example.com
127.0.0.1 libretime.example.com
```
Then visit `libretime.example.com` in your browser, and login as the
user `test` with password of `password`. You should then be taken to the
LibreTime homepage, and when you click on login, you should be
automatically logged in.
### **Links**
https://www.authelia.com/integration/trusted-header-sso/introduction/
https://doc.traefik.io/traefik/middlewares/http/forwardauth/
---------
Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
2024-12-07 11:21:57 +01:00
## Setup Header Authentication
If you have an SSO system that supports trusted SSO header authentication such as [Authelia ](https://www.authelia.com/ ),
you can configure LibreTime to login users based on those trusted headers.
This allows users to only need to log in once on the SSO system and not need to log in again. It also allows LibreTime
to indirectly support other authentication mechanisms such as OAuth2.
This ONLY affects Legacy/Legacy API auth and does NOT affect API V2 auth.
### Configure Headers
LibreTime needs to know what headers are sent, and what information is available to it. You can also
setup a predefined group mapping so users are automatically granted the desired permissions.
This configuration is in `/etc/libretime/config.yml` . The following is an example configuration for an SSO service
that does the following:
- Sends the username in the `Remote-User` HTTP header.
- Sends the email in the `Remote-Email` HTTP header.
- Sends the name in the `Remote-Name` HTTP header. Example `John Doe`
- Sends the comma delimited groups in the `Remote-Groups` HTTP header. Example `group 1,lt-admin,group2`
- Has an IP of `10.0.0.34` (not required). When not provided it is not checked.
- Users with the `lt-host` group should get host privileges.
- Users with the `lt-admin` group should get admin privileges.
- Users with the `lt-pm` group should get program manager privileges.
- Users with the `lt-superadmin` group should get super admin privileges.
- All other users should get guest privileges.
```yml
header_auth:
user_header: Remote-User # This is the default and could be omitted
groups_header: Remote-Groups # This is the default and could be omitted
email_header: Remote-Email # This is the default and could be omitted
name_header: Remote-Name # This is the default and could be omitted
proxy_ip: 10.0.0.34
group_map:
host: lt-host
program_manager: lt-pm
admin: lt-admin
superadmin: lt-superadmin
```
If the `user_header` is not found in the request, users will be kicked to the login page
with a message that their username/password is invalid and will not be able to log in. When `proxy_ip` is provided
it will check that the request is coming from the correct proxy before doing the login. This prevents users who have
internal network access from being able to login as whoever they want in LibreTime.
::: warning
If `proxy_ip` is not provided any user on the internal network can log in as any user in LibreTime.
:::
### Enable Header authentication
After everything is set up properly you can enable header auth in `config.yml` :
```yml
general:
auth: LibreTime_Auth_Adaptor_Header
```
You should now be automatically logged into LibreTime when you click the `Login` button.