Use LL::NG REST API for config and sessions

This commit is contained in:
Daniel Berteaud 2024-01-02 21:23:18 +01:00
parent ab87cfd7ea
commit d24ddc605d
4 changed files with 42 additions and 72 deletions

View File

@ -32,19 +32,24 @@ Note that while creating new or updating existing basicauth entry will be reload
# Lemonldap::NG Handler # Lemonldap::NG Handler
The job support running a Lemonldap::NG handler, but in a very specific configuration only for now. You have to use a MySQL or MariaDB for the config and the sessions, and this DB must be reachable through the Consul service mesh. The job support running a Lemonldap::NG handler, using the REST API to reach config and session databases
Then you need to enable support for the handler, in your variables.yml file
``` ```
lemonldap: lemonldap:
enabled: True enabled: True
db: config:
service_name: mariadb url: https://auth.example.org/index.psgi/config
user: lemonldap user: lemonldap
db: lemonldap password: '{{ with secret "kv/service/traefik" }}{{ .Data.data.llng_api_pwd }}{{ end }}'
realm: Lemonldap::NG API
sessions:
url: https://auth.example.org/index.psgi/sessions/global
user: lemonldap
password: '{{ with secret "kv/service/traefik" }}{{ .Data.data.llng_api_pwd }}{{ end }}'
realm: Lemonldap::NG API
``` ```
And the password for the DB is stored in vault And the password for the API is stored in vault
``` ```
vault kv put kv/service/traefik llng_handler_db_pwd='ThisIsNotAVeryStrongPassword' vault kv put kv/service/traefik llng_api_pwd='ThisIsNotAVeryStrongPassword'
``` ```

View File

@ -1,5 +1,5 @@
[all] [all]
logLevel = debug logLevel = info
logger = Lemonldap::NG::Common::Logger::Std logger = Lemonldap::NG::Common::Logger::Std
userLogger = Lemonldap::NG::Common::Logger::Std userLogger = Lemonldap::NG::Common::Logger::Std
localSessionStorage = Cache::FileCache localSessionStorage = Cache::FileCache
@ -7,71 +7,33 @@ localSessionStorageOptions = { \
'namespace' => 'sessions', \ 'namespace' => 'sessions', \
'default_expires_in' => '10', \ 'default_expires_in' => '10', \
'directory_umask' => '007', \ 'directory_umask' => '007', \
'cache_root' => '/secrets/cache/', \ 'cache_root' => '/tmp', \
'cache_depth' => 3 \ 'cache_depth' => 3 \
} }
globalStorage = Apache::Session::Browseable::MySQL globalStorage = Lemonldap::NG::Common::Apache::Session::REST
globalStorageOptions = { \ globalStorageOptions = { \
'DataSource' => 'DBI:mysql:database=[[ .lemonldap.db.name ]];host=[[ .lemonldap.db.host ]];port=[[ .lemonldap.db.port ]];mysql_enable_utf8=1', \ baseUrl => "[[ .lemonldap.sessions.url ]]", \
'UserName' => '[[ .lemonldap.db.user ]]', \ [[- if and (has .lemonldap.sessions "user") (has .lemonldap.sessions "password") (has .lemonldap.sessions "realm") ]]
'Password' => '{{ with secret "[[ .vault.prefix ]]kv/service/traefik" }}{{ .Data.data.llng_handler_db_pwd }}{{ end }}', \ user => "[[ .lemonldap.sessions.user ]]", \
'TableName' => 'sessions', \ password => "[[ .lemonldap.sessions.password ]]", \
'Index' => 'ipAddr _whatToTrace user _session_kind _utime _httpSessionType', \ realm => "[[ .lemonldap.sessions.realm ]]", \
'generateModule' => 'Lemonldap::NG::Common::Apache::Session::Generate::SHA256' \ [[- end ]]
}
persistentStorage = Apache::Session::Browseable::MySQL
persistentStorageOptions = { \
'DataSource' => 'DBI:mysql:database=[[ .lemonldap.db.name ]];host=[[ .lemonldap.db.host ]];port=[[ .lemonldap.db.port ]];mysql_enable_utf8=1', \
'UserName' => '[[ .lemonldap.db.user ]]', \
'Password' => '{{ with secret "[[ .vault.prefix ]]kv/service/traefik" }}{{ .Data.data.llng_handler_db_pwd }}{{ end }}', \
'TableName' => 'psessions', \
'Index' => 'ipAddr _whatToTrace _session_kind _httpSessionType _session_uid', \
'generateModule' => 'Lemonldap::NG::Common::Apache::Session::Generate::SHA256' \
}
samlStorage = Apache::Session::Browseable::MySQL
samlStorageOptions = { \
'DataSource' => 'DBI:mysql:database=[[ .lemonldap.db.name ]];host=[[ .lemonldap.db.host ]];port=[[ .lemonldap.db.port ]];mysql_enable_utf8=1', \
'UserName' => '[[ .lemonldap.db.user ]]', \
'Password' => '{{ with secret "[[ .vault.prefix ]]kv/service/traefik" }}{{ .Data.data.llng_handler_db_pwd }}{{ end }}', \
'TableName' => 'samlsessions', \
'Index' => '_session_kind _utime _saml_id', \
'generateModule' => 'Lemonldap::NG::Common::Apache::Session::Generate::SHA256' \
}
oidcStorage = Apache::Session::Browseable::MySQL
oidcStorageOptions = { \
'DataSource' => 'DBI:mysql:database=[[ .lemonldap.db.name ]];host=[[ .lemonldap.db.host ]];port=[[ .lemonldap.db.port ]];mysql_enable_utf8=1', \
'UserName' => '[[ .lemonldap.db.user ]]', \
'Password' => '{{ with secret "[[ .vault.prefix ]]kv/service/traefik" }}{{ .Data.data.llng_handler_db_pwd }}{{ end }}', \
'TableName' => 'oidcsessions', \
'Index' => '_session_kind _utime', \
'generateModule' => 'Lemonldap::NG::Common::Apache::Session::Generate::SHA256' \
}
casStorage = Apache::Session::Browseable::MySQL
casStorageOptions = { \
'DataSource' => 'DBI:mysql:database=[[ .lemonldap.db.name ]];host=[[ .lemonldap.db.host ]];port=[[ .lemonldap.db.port ]];mysql_enable_utf8=1', \
'UserName' => '[[ .lemonldap.db.user ]]', \
'Password' => '{{ with secret "[[ .vault.prefix ]]kv/service/traefik" }}{{ .Data.data.llng_handler_db_pwd }}{{ end }}', \
'TableName' => 'cassessions', \
'Index' => '_session_kind _utime _cas_id', \
'generateModule' => 'Lemonldap::NG::Common::Apache::Session::Generate::SHA256' \
} }
[configuration] [configuration]
type = CDBI type = REST
dbiChain = DBI:mysql:database=[[ .lemonldap.db.name ]];host=[[ .lemonldap.db.host ]];port=[[ .lemonldap.db.port ]];mysql_enable_utf8=1 baseUrl = [[ .lemonldap.config.url ]]
dbiUser = [[ .lemonldap.db.user ]] [[- if and (has .lemonldap.config "user") (has .lemonldap.config "password") (has .lemonldap.config "realm") ]]
dbiPassword = {{ with secret "[[ .vault.prefix ]]kv/service/traefik" }}{{ .Data.data.llng_handler_db_pwd }}{{ end }} user = [[ .lemonldap.config.user ]]
password = [[ .lemonldap.config.password ]]
realm = [[ .lemonldap.config.realm ]]
[[- end ]]
localStorage = Cache::FileCache localStorage = Cache::FileCache
localStorageOptions = { \ localStorageOptions = { \
'namespace' => 'config', \ 'namespace' => 'config', \
'default_expires_in' => '5', \ 'default_expires_in' => '5', \
'directory_umask' => '007', \ 'directory_umask' => '007', \
'cache_root' => '/secrets/cache/', \ 'cache_root' => '/tmp', \
'cache_depth' => 0 \ 'cache_depth' => 0 \
} }
[handler]
https = 1
status = 0
hideSignature = 1

View File

@ -136,6 +136,8 @@ _EOF
"secrets/lemonldap-ng.ini:/etc/lemonldap-ng/lemonldap-ng.ini:ro", "secrets/lemonldap-ng.ini:/etc/lemonldap-ng/lemonldap-ng.ini:ro",
"local/Traefik.pm:/usr/share/perl5/vendor_perl/Lemonldap/NG/Handler/Server/Traefik.pm:ro" "local/Traefik.pm:/usr/share/perl5/vendor_perl/Lemonldap/NG/Handler/Server/Traefik.pm:ro"
] ]
# Add a tmpfs to store config and session cache
[[ template "common/tmpfs" dict "size" "10000000" "target" "/tmp" ]]
} }
lifecycle { lifecycle {
@ -151,7 +153,7 @@ _EOF
template { template {
data =<<_EOT data =<<_EOT
[[ template "traefik/lemonldap-ng.ini.tpl" . ]] [[ template "traefik/lemonldap-ng.ini.tpl" . ]]
_EOT _EOT
destination = "secrets/lemonldap-ng.ini" destination = "secrets/lemonldap-ng.ini"
perms = "0400" perms = "0400"

View File

@ -93,13 +93,14 @@ lemonldap:
cpu: 200 cpu: 200
memory: 128 memory: 128
# DB the handler will use for config and session config:
# Only MySQL/MariaDB is supported for now url: https://auth.example.org/index.psgi/config
db: # user: lemonldap
host: 127.0.0.1 # password: secret
port: 3306 realm: Lemonldap::NG API
# DB user
user: lemonldapnghandler
# DB name
name: lemonldapng
sessions:
url: https://auth.example.org/index.psgi/sessions/global
# user: lemonldap
# password: secret
realm: Lemonldap::NG API