кадди авторизация наконец-то заработала

This commit is contained in:
2025-08-27 18:33:52 +03:00
parent d3b6b3fba6
commit da0babf5ab
3 changed files with 99 additions and 70 deletions
+27 -43
View File
@@ -1,79 +1,73 @@
{ {
email dead@cxap.space email dead@cxap.space
dns cloudflare {$CF_API_TOKEN} acme_dns cloudflare {$CF_API_TOKEN}
order authenticate before respond order authenticate before respond
order authorize before respond order authorize before reverse_proxy
servers { servers {
trusted_proxies static private_ranges trusted_proxies static private_ranges
} }
certificates { security {
automate auth.realy.nothing.help
automate *.realy.nothing.help
}
}
security {
# Локальное хранилище пользователей
local identity store localdb { local identity store localdb {
realm local realm local
path /data/users.json path /data/users.json
} }
# Портал аутентификации (используем в site-блоке ниже)
authentication portal authportal { authentication portal authportal {
# криптополитика и тайминги crypto default token lifetime {$AUTH_TOKEN_LIFETIME:43200}
crypto default token lifetime {$AUTH_TOKEN_LIFETIME:-12h}
enable identity store localdb enable identity store localdb
# единый cookie для всех поддоменов realy.nothing.help
cookie domain realy.nothing.help cookie domain realy.nothing.help
cookie lifetime {$AUTH_COOKIE_LIFETIME:-12h} cookie lifetime {$AUTH_COOKIE_LIFETIME:43200}
cookie idle_timeout {$AUTH_IDLE_TIMEOUT:-30m}
cookie samesite lax cookie samesite lax
ui { ui {
title "Account"
# можно добавить ярлыки на часто используемые сервисы
links { links {
"Portainer" "https://port.realy.nothing.help" "Portainer" "https://port.realy.nothing.help" icon "las la-tachometer-alt"
"WhoAmI" "/whoami" "WhoAmI" "/whoami" icon "las la-user"
} }
} }
# Всем локальным пользователям — роль admin + требование MFA
transform user { transform user {
match origin local match origin local
action add role admin action add role admin
# require mfa # require mfa
} }
# И базовая роль "user" всем аутентифицированным
transform user {
action add role user
}
} }
# Политика для API: либо admin-роль, либо API-ключи портала
authorization policy apikey_or_admin { authorization policy apikey_or_admin {
set auth url https://auth.realy.nothing.help set auth url https://auth.realy.nothing.help
allow roles admin allow roles admin
with api key auth portal authportal realm local with api key auth portal authportal realm local
# Явные ACL с логами acl rule {
acl rule { comment "Accept" match role admin allow stop log info } comment "Accept"
acl rule { comment "Deny" match any deny log warn } match role admin
allow stop log info
}
acl rule {
comment "Deny"
match any
deny log warn
}
}
}
}
(auth_forward) {
authorize with apikey_or_admin {
set auth url https://auth.realy.nothing.help
inject headers with claims
} }
} }
auth.realy.nothing.help { auth.realy.nothing.help {
# сам портал на отдельном хосте
route { route {
authenticate with authportal authenticate with authportal
} }
# Базовые security-заголовки
header { header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff" X-Content-Type-Options "nosniff"
@@ -82,16 +76,6 @@ auth.realy.nothing.help {
} }
} }
# Обычная «пользовательская» защита: просто требует валидную сессию, *.realy.nothing.help {
# редиректит на портал, прокидывает клеймы в заголовки. respond / "ok"
(auth_forward) {
authorize {
set auth url https://auth.realy.nothing.help
inject headers with claims
}
}
# Защита API: только admin или по API-ключу (policy объявлена выше)
(authorize_apikey_or_admin) {
authorize with apikey_or_admin
} }
+4 -6
View File
@@ -8,7 +8,7 @@ services:
ports: ports:
- "80:80" - "80:80"
- "443:443" - "443:443"
- "443:443/udp" # HTTP/3 - "443:443/udp"
environment: environment:
- CADDY_INGRESS_NETWORKS=proxy - CADDY_INGRESS_NETWORKS=proxy
- CF_API_TOKEN=${CF_API_TOKEN} - CF_API_TOKEN=${CF_API_TOKEN}
@@ -16,7 +16,7 @@ services:
- /var/run/docker.sock:/var/run/docker.sock:ro - /var/run/docker.sock:/var/run/docker.sock:ro
- caddy_data:/data - caddy_data:/data
- ./Caddyfile:/etc/caddy/Caddyfile:ro - ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./users.json:/data/users.json:ro - ./users.json:/data/users.json
networks: [proxy] networks: [proxy]
command: ["caddy","docker-proxy","--caddyfile-path=/etc/caddy/Caddyfile","--docker-sockets","unix:///var/run/docker.sock"] command: ["caddy","docker-proxy","--caddyfile-path=/etc/caddy/Caddyfile","--docker-sockets","unix:///var/run/docker.sock"]
@@ -25,16 +25,14 @@ services:
container_name: portainer container_name: portainer
restart: always restart: always
expose: expose:
- "9000" # HTTP UI внутрь докера - "9000"
- "8000" # Edge (если нужен: лучше через NetBird; иначе публикуйте отдельно с FW) - "8000"
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data - portainer_data:/data
networks: [proxy] networks: [proxy]
labels: labels:
caddy: port.realy.nothing.help caddy: port.realy.nothing.help
caddy.handle_path: /api/*
caddy.handle_path.0_reverse_proxy: "{{upstreams 9000}}"
caddy.encode: zstd gzip caddy.encode: zstd gzip
caddy.import: auth_forward caddy.import: auth_forward
caddy.reverse_proxy: "{{upstreams 9000}}" caddy.reverse_proxy: "{{upstreams 9000}}"
+50 -3
View File
@@ -1,11 +1,58 @@
{ {
"version": "1.1.2",
"policy": {
"password": {
"keep_versions": 10,
"min_length": 8,
"max_length": 128,
"require_uppercase": false,
"require_lowercase": false,
"require_number": false,
"require_non_alpha_numeric": false,
"block_reuse": false,
"block_password_change": false
},
"user": {
"min_length": 3,
"max_length": 50,
"allow_non_alpha_numeric": false,
"allow_uppercase": false
}
},
"revision": 2,
"last_modified": "2021-10-25T13:04:58.482997492-04:00",
"users": [ "users": [
{ {
"id": "39555452-454e-4c85-829b-8195a8dd8c81",
"username": "deadcxap", "username": "deadcxap",
"email": "dead@cxap.space", "email_address": {
"password": "$2b$12$s5SZcTu0THrdIHmdqTIuS.Hb89nokYfwF5xSDPSJPZsKoYnFkv61i", "address": "dead@cxap.space",
"domain": "cxap.space"
},
"email_addresses": [
{
"address": "dead@cxap.space",
"domain": "cxap.space"
}
],
"passwords": [
{
"purpose": "generic",
"algorithm": "bcrypt",
"hash": "$2b$12$s5SZcTu0THrdIHmdqTIuS.Hb89nokYfwF5xSDPSJPZsKoYnFkv61i",
"cost": 10,
"expired_at": "0001-01-01T00:00:00Z",
"created_at": "2021-10-25T17:04:58.4251263Z",
"disabled_at": "0001-01-01T00:00:00Z"
}
],
"created": "2021-10-25T17:04:58.42512588Z",
"last_modified": "2021-10-25T17:04:58.42512594Z",
"roles": [ "roles": [
"admin" {
"name": "admin",
"organization": "authp"
}
] ]
} }
] ]