From 839f6e614995faa9c948343f23bb23831af3117c Mon Sep 17 00:00:00 2001 From: clover caruso Date: Fri, 9 Jan 2026 00:28:36 -0800 Subject: [PATCH] feat: internal services on SSO --- compose.yaml | 108 +++++++++++----------- config/403.html | 5 ++ config/Caddyfile | 185 ++++++++++++++++++++------------------ config/jellyfin/Caddyfile | 5 +- config/keycloak/init.py | 2 +- 5 files changed, 162 insertions(+), 143 deletions(-) create mode 100644 config/403.html diff --git a/compose.yaml b/compose.yaml index ae48160196b83237e47a411b9e8c78afe2a6bd4f..cbf2de42df4967ce6b2e82b3b6bf0025d413eb98 100755 --- a/compose.yaml +++ b/compose.yaml @@ -17,6 +17,12 @@ services: watch: - path: ./config/Caddyfile action: restart + healthcheck: + test: ["CMD", "caddy", "healthcheck", "--address", ":2019"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 5s # SSO keycloak: # port 80, 443 container_name: keycloak @@ -255,6 +261,7 @@ services: ND_SCANNER_GROUPALBUMRELEASES: "1" ND_BASEURL: "https://music.${HOME_DOMAIN}/" ND_PID_ALBUM: "folder" + ND_EXTAUTH_USERHEADER: "Remote-User" ND_EXTAUTH_TRUSTEDSOURCES: "0.0.0.0/0" # troll ND_PORT: "80" labels: @@ -306,55 +313,55 @@ services: net.paperclover.list.domain: qbt net.paperclover.list.priority: 52 net.paperclover.list.access: media-manage - # jackett: # port 9117 - # container_name: jackett - # environment: - # - "PUID=$USER_ID" - # - "PGID=$GROUP_ID" - # - "TZ=America/Los_Angelas" - # image: lscr.io/linuxserver/jackett:latest - # restart: unless-stopped - # volumes: - # - "${APP_ROOT}/jackett:/config/Jackett" - # labels: - # net.paperclover.list.name: Jackett API Adapter - # net.paperclover.list.domain: jkt - # net.paperclover.list.priority: 40 - # net.paperclover.list.access: media-manage - # sonarr: # port 8989 - # container_name: sonarr - # environment: - # - "PUID=$USER_ID" - # - "PGID=$GROUP_ID" - # - "TZ=America/Los_Angelas" - # image: lscr.io/linuxserver/sonarr:latest - # volumes: - # - "${APP_ROOT}/sonarr:/config" - # - "${TORRENT_TEMP:-${APP_ROOT}/qbittorrent/tmp}:/data/tmp" - # - "${MEDIA_ROOT}:/data/media" - # restart: unless-stopped - # labels: - # net.paperclover.list.name: Sonarr TV PVR - # net.paperclover.list.domain: jkt - # net.paperclover.list.priority: 51 - # net.paperclover.list.access: media-manage - # radarr: # port 7878 - # container_name: radarr - # environment: - # - "PUID=$USER_ID" - # - "PGID=$GROUP_ID" - # - "TZ=America/Los_Angelas" - # image: lscr.io/linuxserver/radarr:latest - # volumes: - # - "${APP_ROOT}/radarr:/config" - # - "${TORRENT_TEMP:-${APP_ROOT}/qbittorrent/tmp}:/data/tmp" - # - "${MEDIA_ROOT}:/data/media" - # restart: unless-stopped - # labels: - # net.paperclover.list.name: Radarr Movie Organizer - # net.paperclover.list.domain: jkt - # net.paperclover.list.priority: 50 - # net.paperclover.list.access: media-manage + jackett: # port 9117 + container_name: jackett + environment: + - "PUID=$USER_ID" + - "PGID=$GROUP_ID" + - "TZ=America/Los_Angelas" + image: lscr.io/linuxserver/jackett:latest + restart: unless-stopped + volumes: + - "${APP_ROOT}/jackett:/config/Jackett" + labels: + net.paperclover.list.name: Jackett API Adapter + net.paperclover.list.domain: jkt + net.paperclover.list.priority: 40 + net.paperclover.list.access: media-manage + sonarr: # port 8989 + container_name: sonarr + environment: + - "PUID=$USER_ID" + - "PGID=$GROUP_ID" + - "TZ=America/Los_Angelas" + image: lscr.io/linuxserver/sonarr:latest + volumes: + - "${APP_ROOT}/sonarr:/config" + - "${TORRENT_TEMP:-${APP_ROOT}/qbittorrent/tmp}:/data/tmp" + - "${MEDIA_ROOT}:/data/media" + restart: unless-stopped + labels: + net.paperclover.list.name: Sonarr TV PVR + net.paperclover.list.domain: jkt + net.paperclover.list.priority: 51 + net.paperclover.list.access: media-manage + radarr: # port 7878 + container_name: radarr + environment: + - "PUID=$USER_ID" + - "PGID=$GROUP_ID" + - "TZ=America/Los_Angelas" + image: lscr.io/linuxserver/radarr:latest + volumes: + - "${APP_ROOT}/radarr:/config" + - "${TORRENT_TEMP:-${APP_ROOT}/qbittorrent/tmp}:/data/tmp" + - "${MEDIA_ROOT}:/data/media" + restart: unless-stopped + labels: + net.paperclover.list.name: Radarr Movie Organizer + net.paperclover.list.domain: rdr + net.paperclover.list.priority: 50 + net.paperclover.list.access: media-manage # language models opencode: # port 4096 container_name: opencode @@ -554,7 +561,7 @@ services: net.paperclover.list.name: Open Speed Test net.paperclover.list.domain: speedtest net.paperclover.list.priority: 10 - technitium-dns: + technitium-dns: # port 5380 image: technitium/dns-server container_name: technitium-dns user: "$USER_ID:$GROUP_ID" @@ -563,7 +570,6 @@ services: - 53:53/tcp - 67:67/udp - 68:68/udp - - 5380:5380/tcp # Web console - 8053:8053/tcp # dns over http volumes: - "${APP_ROOT}/technitium/config:/app/config" diff --git a/config/403.html b/config/403.html new file mode 100644 index 0000000000000000000000000000000000000000..0cd80c8175765a80d13a40358e47c5969ed708b6 --- /dev/null +++ b/config/403.html @@ -0,0 +1,5 @@ +no permission </3 ...
+retry +
+
+contact clover for assistance... diff --git a/config/Caddyfile b/config/Caddyfile index 6f414842dae07ef6584c18cd8c603edb64af0a38..89c3962d0758111dd635566c0333b20c1ffd94e3 100644 --- a/config/Caddyfile +++ b/config/Caddyfile @@ -1,62 +1,45 @@ -# (auth_require) { -# @not_websocket not header Connection Upgrade -# handle /snow.oauth2/* { -# reverse_proxy "http://forward-auth" { -# header_up X-Real-IP {remote_host} -# header_up X-Forwarded-Uri {uri} -# } -# } -# -# handle { -# forward_auth @not_websocket "http://forward-auth" { -# uri /snow.oauth2/auth -# header_up X-Real-IP {remote_host} -# copy_headers X-Forwarded-User X-Forwarded-Groups X-Forwarded-Email -# @error status 401 -# handle_response @error { -# redir * /snow.oauth2/sign_in?rd={scheme}://{host}{uri} -# } -# } -# -# reverse_proxy {args[:]} -# } -# } -(auth-optional) { - handle /snow.oauth2/* { +{ + admin +} + +(reverse_proxy_auth) { + handle /snow.oauth2/* { reverse_proxy "http://forward-auth" { header_up X-Real-IP {remote_host} header_up X-Forwarded-Uri {uri} } } - - @not_websocket not header Connection Upgrade - reverse_proxy @not_websocket "http://forward-auth" { - method GET - rewrite /snow.oauth2/auth - - header_up X-Forwarded-Method {method} - header_up X-Forwarded-Uri {uri} - - @good status 2xx - handle_response @good { - request_header User-Id {rp.header.X-Auth-Request-User} - request_header User-Groups {rp.header.X-Auth-Request-Groups} - request_header User-Email {rp.header.X-Auth-Request-Email} - request_header User-Name {rp.header.X-Auth-Request-Preferred-Username} - } - @bad status 4xx - handle_response @bad { - request_header User-Id "" - request_header User-Groups "" - request_header User-Email "" - request_header User-Name "" + handle { + reverse_proxy "http://forward-auth" { + method GET + header_up X-Forwarded-Method {method} + header_up X-Forwarded-Uri {uri} + rewrite /snow.oauth2/auth + header_up X-Real-IP {remote_host} + @error status 401 + handle_response @error { + redir * /snow.oauth2/sign_in?rd={scheme}://{host}{uri} + } + @valid_group header X-Auth-Request-Groups *role:{args[1]}* + handle_response @valid_group { + method {method} + rewrite {uri} + reverse_proxy {args[0]} { + header_up Cookie ([^;]*?)\s*_oauth2_proxy_\d=[^;]*(;?.*) "$1$2" + {block} + } + } + handle_response { + rewrite /403.html + file_server { + status 403 + root /etc/caddy + } + } } } - - reverse_proxy {args[:]} } - # services are sorted alphabetically auth.{$HOME_DOMAIN} { handle / { @@ -70,6 +53,9 @@ dawarich.{$HOME_DOMAIN} { db.{$HOME_DOMAIN} { reverse_proxy "http://clover-source-of-truth" } +dns.{$HOME_DOMAIN} { + import reverse_proxy_auth "http://technitium-dns:5380" admin +} file.{$HOME_DOMAIN} { handle "/.static/*" { uri strip_prefix /.static @@ -82,7 +68,36 @@ file.{$HOME_DOMAIN} { root /etc/caddy/static file_server } - import auth-optional "http://copyparty" + handle /snow.oauth2/* { + reverse_proxy "http://forward-auth" { + header_up X-Real-IP {remote_host} + header_up X-Forwarded-Uri {uri} + } + } + @should_auth not path /shr/* + reverse_proxy @should_auth "http://forward-auth" { + method GET + rewrite /snow.oauth2/auth + + header_up X-Forwarded-Method {method} + header_up X-Forwarded-Uri {uri} + + @good status 2xx + handle_response @good { + request_header User-Id {rp.header.X-Auth-Request-User} + request_header User-Groups {rp.header.X-Auth-Request-Groups} + request_header User-Email {rp.header.X-Auth-Request-Email} + request_header User-Name {rp.header.X-Auth-Request-Preferred-Username} + } + @bad status 4xx + handle_response @bad { + request_header User-Id "" + request_header User-Groups "" + request_header User-Email "" + request_header User-Name "" + } + } + reverse_proxy "http://copyparty" } git.{$HOME_DOMAIN} { handle /user/login { @@ -94,12 +109,11 @@ git.{$HOME_DOMAIN} { } } import ./jellyfin/Caddyfile -# jkt.{$HOME_DOMAIN} { -# import auth -# reverse_proxy "http://jackett:9117" { -# header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" -# } -# } +jkt.{$HOME_DOMAIN} { + import reverse_proxy_auth "http://jackett:9117" media-manage { + header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" + } +} music.{$HOME_DOMAIN} { handle_path /app/sw.js { header Content-Type "application/javascript" @@ -147,41 +161,34 @@ music.{$HOME_DOMAIN} { reverse_proxy "http://navidrome" } } -# opencode.{$HOME_DOMAIN} { -# import auth -# reverse_proxy "http://opencode" -# } -# pg.{$HOME_DOMAIN} { -# import auth -# reverse_proxy "http://pgadmin" -# } -# qbt.{$HOME_DOMAIN} { -# import auth -# reverse_proxy "qbittorrent:23938" -# } -# redis.{$HOME_DOMAIN} { -# import auth -# reverse_proxy "redis-insight:5540" -# } -# rdr.{$HOME_DOMAIN} { -# import auth -# reverse_proxy "radarr:7878" { -# header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" -# } -# } -# snr.{$HOME_DOMAIN} { -# import auth -# reverse_proxy "sonarr:8989" { -# header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" -# } -# } +opencode.{$HOME_DOMAIN} { + import reverse_proxy_auth "http://opencode" admin +} +pg.{$HOME_DOMAIN} { + import reverse_proxy_auth "http://pgadmin" admin +} +qbt.{$HOME_DOMAIN} { + import reverse_proxy_auth "http://qbittorrent:23938" media-manage +} +redis.{$HOME_DOMAIN} { + import reverse_proxy_auth "http://redis-insight:5540" admin +} +rdr.{$HOME_DOMAIN} { + import reverse_proxy_auth "http://radarr:7878" media-manage { + header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" + } +} +snr.{$HOME_DOMAIN} { + import reverse_proxy_auth "http://sonarr:8989" media-manage { + header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" + } +} speedtest.{$HOME_DOMAIN} { reverse_proxy "openspeedtest:3000" } -# sync.{$HOME_DOMAIN} { -# import auth -# reverse_proxy "syncthing:8384" -# } +sync.{$HOME_DOMAIN} { + import reverse_proxy_auth "http://syncthing:8384" admin +} # redirections paperclover.dev { diff --git a/config/jellyfin/Caddyfile b/config/jellyfin/Caddyfile index 258b7d35d0c8bcee1c1f1bf3c9ea059118c6481d..ecbdb0e4c5cf6af22ab12f7427490c35c582463f 100644 --- a/config/jellyfin/Caddyfile +++ b/config/jellyfin/Caddyfile @@ -49,8 +49,9 @@ jelly.{$HOME_DOMAIN} { } /* theme fixes */ - .playlistSectionButton, .noBackdropTransparency .detailPagePrimaryContainer { - background: rgb(from var(--main-background) r g b / 50%; + .material-icons.play_arrow { display: flex } + .detailPagePrimaryContainer { + background: rgb(from var(--main-background) r g b / 75%)!; } .selectLabel { display: flex; diff --git a/config/keycloak/init.py b/config/keycloak/init.py index d5fe1046c0a683f7f4b4fb9b11b9844d7768c26f..758f5eb1fcd5a973f4b2838273e55da024b1d068 100755 --- a/config/keycloak/init.py +++ b/config/keycloak/init.py @@ -19,7 +19,7 @@ def env(key: str): return val -groups_to_create = ["snow", "media", "media-manage", "git", "file"] +groups_to_create = ["snow", "media-manage"] realm_config = { "realm": "master", "displayName": "snow sign on", -- 2.54.0