diff --git a/.env.sample b/.env.sample index b919531..d9d38c6 100644 --- a/.env.sample +++ b/.env.sample @@ -19,6 +19,71 @@ SECRET_FORM_SECRET_VERSION=v1 SECRET_MACAROON_VERSION=v1 SECRET_REGISTRATION_VERSION=v1 +## Authentication + +# All login / SSO / MAS-related toggles in one place. + +### Local password & registration (Synapse native) + +# With MAS_ENABLED=1 you must set PASSWORD_LOGIN_ENABLED=false — Synapse forbids legacy password DB alongside matrix_authentication_service. +PASSWORD_LOGIN_ENABLED=true +ENABLE_REGISTRATION=false + +# Token based registration. Enable ADMIN_INTERFACE (below) to use the admin interface to generate tokens. +#REGISTRATION_REQUIRES_TOKEN=true + +### OIDC via Keycloak-shaped API (e.g. Authentik) + +#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak.yml" +#KEYCLOAK_ENABLED=1 +#KEYCLOAK_ID=keycloak +#KEYCLOAK_NAME= +#KEYCLOAK_URL= +#KEYCLOAK_CLIENT_ID= +#KEYCLOAK_CLIENT_DOMAIN= +#KEYCLOAK_ALLOW_EXISTING_USERS=false +#SECRET_KEYCLOAK_CLIENT_SECRET_VERSION=v1 + +### Second OIDC provider (compose.keycloak2.yml) + +#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak2.yml" +#KEYCLOAK2_ENABLED=1 +#KEYCLOAK2_ID=keycloak2 +#KEYCLOAK2_NAME= +#KEYCLOAK2_URL= +#KEYCLOAK2_CLIENT_ID= +#KEYCLOAK2_CLIENT_DOMAIN= +#KEYCLOAK2_ALLOW_EXISTING_USERS=false +#SECRET_KEYCLOAK2_CLIENT_SECRET_VERSION=v1 + +### Third OIDC provider (compose.keycloak3.yml) + +#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak3.yml" +#KEYCLOAK3_ENABLED=1 +#KEYCLOAK3_ID=keycloak3 +#KEYCLOAK3_NAME= +#KEYCLOAK3_URL= +#KEYCLOAK3_CLIENT_ID= +#KEYCLOAK3_CLIENT_DOMAIN= +#KEYCLOAK3_ALLOW_EXISTING_USERS=false +#SECRET_KEYCLOAK3_CLIENT_SECRET_VERSION=v1 + +### Matrix Authentication Service (MAS) — Element X / OIDC-native auth + +#COMPOSE_FILE="$COMPOSE_FILE:compose.mas.yml" +#MAS_ENABLED=1 +#PASSWORD_LOGIN_ENABLED=false +#SECRET_MAS_ENCRYPTION_VERSION=v1 # length=64 # charset=hex +#SECRET_MAS_SYNAPSE_SHARED_VERSION=v1 # length=64 # charset=hex +# PEM private key: abra cannot generate this format — insert only (e.g. openssl genrsa 2048 | abra app secret insert …) +#SECRET_MAS_SIGNING_RSA_VERSION=v1 # generate=false + +### Shared secret auth (bridges / automation) + +#COMPOSE_FILE="$COMPOSE_FILE:compose.shared_secret_auth.yml" +#SHARED_SECRET_AUTH_ENABLED=1 +#SECRET_SHARED_SECRET_AUTH_VERSION=v1 # length=128 + ## Federation #DISABLE_FEDERATION=1 @@ -28,14 +93,6 @@ SERVE_SERVER_WELLKNOWN=false ALLOW_PUBLIC_ROOMS_FEDERATION=false -## Registration - -ENABLE_REGISTRATION=false -PASSWORD_LOGIN_ENABLED=true - -# Token based registration. Enable ADMIN_INTERFACE (below) to use the admin interface to generate tokens. -#REGISTRATION_REQUIRES_TOKEN=true - ## Room auto-join #AUTO_JOIN_ROOM_ENABLED=1 @@ -98,30 +155,8 @@ RETENTION_MAX_LIFETIME=4w #LOGIN_LIMIT_ACCOUNT_PER_SECOND=1 #LOGIN_LIMIT_ACCOUNT_BURST=10 -## Keycloak SSO - -#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak.yml" -#KEYCLOAK_ENABLED=1 -#KEYCLOAK_ID=keycloak -#KEYCLOAK_NAME= -#KEYCLOAK_URL= -#KEYCLOAK_CLIENT_ID= -#KEYCLOAK_CLIENT_DOMAIN= -#KEYCLOAK_ALLOW_EXISTING_USERS=false -#SECRET_KEYCLOAK_CLIENT_SECRET_VERSION=v1 - ## TURN -#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak3.yml" -#KEYCLOAK3_ENABLED=1 -#KEYCLOAK3_ID=keycloak3 -#KEYCLOAK3_NAME= -#KEYCLOAK3_URL= -#KEYCLOAK3_CLIENT_ID= -#KEYCLOAK3_CLIENT_DOMAIN= -#KEYCLOAK3_ALLOW_EXISTING_USERS=false -#SECRET_KEYCLOAK3_CLIENT_SECRET_VERSION=v1 - #COMPOSE_FILE="$COMPOSE_FILE:compose.turn.yml" #TURN_ENABLED=1 #TURN_URIS="[\"turns:coturn.foo.zone?transport=udp\", \"turns:coturn.foo.zone?transport=tcp\"]" @@ -189,12 +224,6 @@ RETENTION_MAX_LIFETIME=4w #SECRET_SIGNAL_HS_TOKEN_VERSION=v1 #SECRET_SIGNAL_PICKLE_KEY_VERSION=v1 -## Shared auth - -#COMPOSE_FILE="$COMPOSE_FILE:compose.shared_secret_auth.yml" -#SHARED_SECRET_AUTH_ENABLED=1 -#SECRET_SHARED_SECRET_AUTH_VERSION=v1 # length=128 - ## Web Client (Redirect) #WEB_CLIENT_LOCATION=https://element-web.example.com diff --git a/abra.sh b/abra.sh index 5009278..8d1a1e0 100644 --- a/abra.sh +++ b/abra.sh @@ -1,13 +1,14 @@ export DISCORD_BRIDGE_YAML_VERSION=v2 export ENTRYPOINT_CONF_VERSION=v3 -export HOMESERVER_YAML_VERSION=v35 +export HOMESERVER_YAML_VERSION=v36 export LOG_CONFIG_VERSION=v2 export SHARED_SECRET_AUTH_VERSION=v2 export SIGNAL_BRIDGE_YAML_VERSION=v6 export TELEGRAM_BRIDGE_YAML_VERSION=v6 -export NGINX_CONFIG_VERSION=v12 +export NGINX_CONFIG_VERSION=v13 export WK_SERVER_VERSION=v1 -export WK_CLIENT_VERSION=v1 +export WK_CLIENT_VERSION=v2 +export MAS_CONFIG_VERSION=v1 export PG_BACKUP_VERSION=v2 export ADMIN_CONFIG_VERSION=v1 diff --git a/compose.mas.yml b/compose.mas.yml new file mode 100644 index 0000000..629eef1 --- /dev/null +++ b/compose.mas.yml @@ -0,0 +1,47 @@ +--- +version: "3.8" + +# Matrix Authentication Service (MAS) — optional overlay for Element X / OIDC-native auth. + +services: + mas: + image: ghcr.io/element-hq/matrix-authentication-service:1.14.0 + command: ["server", "--config=/etc/mas/config.yaml"] + environment: + - DOMAIN + - SERVER_NAME + - STACK_NAME + networks: + - internal + configs: + - source: mas_config + target: /etc/mas/config.yaml + secrets: + - db_password + - mas_encryption + - mas_synapse_shared + - mas_signing_rsa + deploy: + restart_policy: + condition: on-failure + + app: + secrets: + - mas_synapse_shared + +configs: + mas_config: + name: ${STACK_NAME}_mas_config_${MAS_CONFIG_VERSION} + file: mas.config.yaml.tmpl + template_driver: golang + +secrets: + mas_encryption: + external: true + name: ${STACK_NAME}_mas_encryption_${SECRET_MAS_ENCRYPTION_VERSION} + mas_synapse_shared: + external: true + name: ${STACK_NAME}_mas_synapse_shared_${SECRET_MAS_SYNAPSE_SHARED_VERSION} + mas_signing_rsa: + external: true + name: ${STACK_NAME}_mas_signing_rsa_${SECRET_MAS_SIGNING_RSA_VERSION} diff --git a/compose.yml b/compose.yml index a9209f6..b027d2a 100644 --- a/compose.yml +++ b/compose.yml @@ -10,6 +10,7 @@ services: environment: - DOMAIN - STACK_NAME + - MAS_ENABLED - NGINX_ACCESS_LOG_LOCATION - NGINX_ERROR_LOG_LOCATION - MAX_UPLOAD_SIZE @@ -46,6 +47,7 @@ services: - macaroon - form_secret environment: + - MAS_ENABLED - ALLOWED_LIFETIME_MAX - ALLOW_PUBLIC_ROOMS_FEDERATION - AUTO_JOIN_ROOM diff --git a/homeserver.yaml.tmpl b/homeserver.yaml.tmpl index 0fb7002..4e4cbe8 100644 --- a/homeserver.yaml.tmpl +++ b/homeserver.yaml.tmpl @@ -1,317 +1,326 @@ -# All configuration options are documented on the following link: -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html - -{{ if eq (env "SHARED_SECRET_AUTH_ENABLED") "1" }} -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#modules-1 -modules: - - module: shared_secret_authenticator.SharedSecretAuthProvider - config: - shared_secret: {{ secret "shared_secret_auth" }} - m_login_password_support_enabled: true -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#server_name -server_name: {{ or (env "SERVER_NAME") (env "DOMAIN") }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#public_baseurl -public_baseurl: https://{{ env "DOMAIN" }}/ - -# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#require_auth_for_profile_requests -require_auth_for_profile_requests: {{ env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS" }} - -# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_profile_requests_to_users_who_share_rooms -limit_profile_requests_to_users_who_share_rooms: {{ env "LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#serve_server_wellknown -serve_server_wellknown: {{ env "SERVE_SERVER_WELLKNOWN" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_without_auth -allow_public_rooms_without_auth: false - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_over_federation -allow_public_rooms_over_federation: {{ or (env "ALLOW_PUBLIC_ROOMS_FEDERATION") "true" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#listeners -listeners: - - port: 8008 - tls: false - type: http - x_forwarded: true - - {{ if eq (env "DISABLE_FEDERATION") "1" }} - resources: - {{ if eq (env "KEYCLOAK_ENABLED") "1" }} - - names: [client, openid] - compress: true - {{ else }} - - names: [client] - compress: true - {{ end }} - {{ else }} - resources: - {{ if eq (env "KEYCLOAK_ENABLED") "1" }} - - names: [client, openid, federation] - compress: true - {{ else }} - - names: [client, federation] - compress: true - {{ end }} - {{ end }} - -# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#delete_stale_devices_after -{{ if (env "DELETE_STALE_DEVICES_AFTER") }} -delete_stale_devices_after: {{ env "DELETE_STALE_DEVICES_AFTER" }} -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#admin_contact -admin_contact: 'mailto:{{ env "ADMIN_EMAIL" }}' - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_remote_rooms -limit_remote_rooms: - enabled: true - complexity: 200.0 - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_avatar_size -max_avatar_size: 10M - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forgotten_room_retention_period -forgotten_room_retention_period: 3d - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#request_token_inhibit_3pid_errors -request_token_inhibit_3pid_errors: true - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#redaction_retention_period -redaction_retention_period: {{ env "REDACTION_RETENTION_PERIOD" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_ips_max_age -user_ips_max_age: {{ env "USER_IPS_MAX_AGE" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#retention -retention: - enabled: true - default_policy: - min_lifetime: 1d - max_lifetime: {{ env "RETENTION_MAX_LIFETIME" }} - allowed_lifetime_min: 1d - allowed_lifetime_max: {{ env "ALLOWED_LIFETIME_MAX" }} - purge_jobs: - - longest_max_lifetime: 3d - interval: 12h - - shortest_max_lifetime: 3d - interval: 1d - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#federation_domain_whitelist -{{ if eq (env "DISABLE_FEDERATION") "1" }} -federation_domain_whitelist: [] -{{ else if eq (env "ENABLE_ALLOWLIST") "1" }} -federation_domain_whitelist: {{ env "FEDERATION_ALLOWLIST" }} -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#database-1 -database: - name: psycopg2 - txn_limit: 10000 - args: - user: synapse - password: "{{ secret "db_password" }}" - database: synapse - host: "{{ env "STACK_NAME" }}_db" - port: 5432 - cp_min: 5 - cp_max: 10 - keepalives_idle: 10 - keepalives_interval: 10 - keepalives_count: 3 - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#log_config -log_config: "/data/log.config" - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_store_path -media_store_path: "/data/media_store" - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_upload_size -max_upload_size: 50M - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#turn -{{ if eq (env "TURN_ENABLED") "1" }} -turn_uris: {{ env "TURN_URIS" }} -turn_shared_secret: "{{ secret "turn_shared_secret" }}" -turn_user_lifetime: 1h -turn_allow_guests: {{ env "TURN_ALLOW_GUESTS" }} -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_registration -enable_registration: {{ env "ENABLE_REGISTRATION" }} - -# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_requires_token -registration_requires_token: {{ env "REGISTRATION_REQUIRES_TOKEN" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_3pid_lookup -enable_3pid_lookup: {{ env "ENABLE_3PID_LOOKUP" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_guest_access -allow_guest_access: false - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_shared_secret -registration_shared_secret: {{ secret "registration" }} - -{{ if eq (env "AUTO_JOIN_ROOM_ENABLED") "1" }} -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#auto_join_rooms - -# AUTO_JOIN_ROOM only for backwards compatibility -{{ if (env "AUTO_JOIN_ROOM") }} -auto_join_rooms: - - "{{ env "AUTO_JOIN_ROOM" }}" -{{ else }} -auto_join_rooms: {{ env "AUTO_JOIN_ROOM_LIST" }} -{{ end }} - -{{ end }} - -# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#session_lifetime -{{ if (env "SESSION_LIFETIME") }} -session_lifetime: {{ env "SESSION_LIFETIME" }} -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#report_stats -report_stats: false - -# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#track_puppeted_user_ips -track_puppeted_user_ips: {{ env "TRACK_PUPPETED_USER_IPS" }} - -{{ if eq (env "APP_SERVICES_ENABLED") "1" }} -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#app_service_config_files -app_service_config_files: {{ env "APP_SERVICE_CONFIGS" }} -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#macaroon_secret_key -macaroon_secret_key: "{{ secret "macaroon" }}" - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#form_secret -form_secret: "{{ secret "form_secret" }}" - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#signing_key_path -signing_key_path: "/data/{{ env "DOMAIN" }}.signing.key" - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#old_signing_keys -{{ if (and (env "OLD_SIGNING_KEY_ID") (env "OLD_SIGNING_KEY") (env "OLD_SIGNING_KEY_EXPIRES")) }} -old_signing_keys: - "ed25519:{{ env "OLD_SIGNING_KEY_ID" }}": { key: "{{ env "OLD_SIGNING_KEY" }}", expired_ts: {{ env "OLD_SIGNING_KEY_EXPIRES" }} } -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#trusted_key_servers -{{ if eq (env "ENABLE_ALLOWLIST") "1" }} -trusted_key_servers: [] # NOTE(d1): defaults to requesting server directly, which matches FEDERATION_ALLOWLIST -{{ else }} -trusted_key_servers: - - server_name: "matrix.org" -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#oidc_providers -{{ if eq (env "KEYCLOAK_ENABLED") "1" }} -oidc_providers: - - idp_id: {{ env "KEYCLOAK_ID" }} - idp_name: {{ env "KEYCLOAK_NAME" }} - issuer: "{{ env "KEYCLOAK_URL" }}" - client_id: "{{ env "KEYCLOAK_CLIENT_ID" }}" - client_secret: "{{ secret "keycloak_client_secret" }}" - scopes: ["openid", "profile"] - allow_existing_users: {{ env "KEYCLOAK_ALLOW_EXISTING_USERS" }} - user_mapping_provider: - config: - localpart_template: "{{ "{{ user.preferred_username }}" }}" - display_name_template: "{{ "{{ user.name }}" }}" - - {{ if eq (env "KEYCLOAK2_ENABLED") "1" }} - - idp_id: {{ env "KEYCLOAK2_ID" }} - idp_name: {{ env "KEYCLOAK2_NAME" }} - issuer: "{{ env "KEYCLOAK2_URL" }}" - client_id: "{{ env "KEYCLOAK2_CLIENT_ID" }}" - client_secret: "{{ secret "keycloak2_client_secret" }}" - scopes: ["openid", "profile"] - allow_existing_users: {{ env "KEYCLOAK2_ALLOW_EXISTING_USERS" }} - user_mapping_provider: - config: - localpart_template: "{{ "{{ user.preferred_username }}" }}" - display_name_template: "{{ "{{ user.name }}" }}" - {{ end }} - - {{ if eq (env "KEYCLOAK3_ENABLED") "1" }} - - idp_id: {{ env "KEYCLOAK3_ID" }} - idp_name: {{ env "KEYCLOAK3_NAME" }} - issuer: "{{ env "KEYCLOAK3_URL" }}" - client_id: "{{ env "KEYCLOAK3_CLIENT_ID" }}" - client_secret: "{{ secret "keycloak3_client_secret" }}" - scopes: ["openid", "profile"] - allow_existing_users: {{ env "KEYCLOAK3_ALLOW_EXISTING_USERS" }} - user_mapping_provider: - config: - localpart_template: "{{ "{{ user.preferred_username }}" }}" - display_name_template: "{{ "{{ user.name }}" }}" - {{ end }} -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#sso -{{ if eq (env "KEYCLOAK_ENABLED") "1" }} -sso: - client_whitelist: - - https://{{ env "KEYCLOAK_CLIENT_DOMAIN" }} -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#password_config -password_config: - enabled: {{ env "PASSWORD_LOGIN_ENABLED" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email -{{ if eq (env "SMTP_ENABLED") "1" }} -email: - smtp_host: {{ env "SMTP_HOST" }} - smtp_port: {{ env "SMTP_PORT" }} - smtp_user: {{ env "SMTP_USER" }} - smtp_pass: "{{ secret "smtp_password" }}" - require_transport_security: true - notif_from: Your Friendly %(app)s homeserver <{{ env "SMTP_FROM" }}> - app_name: {{ env "SMTP_APP_NAME" }} - enable_notifs: true - client_base_url: https://{{ env "DOMAIN" }} -{{ end }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#encryption_enabled_by_default_for_room_type -encryption_enabled_by_default_for_room_type: {{ env "ENCRYPTED_BY_DEFAULT" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_directory -user_directory: - enabled: {{ env "USER_DIRECTORY_ENABLED" }} - search_all_users: {{ env "USER_DIRECTORY_SEARCH_ALL_USERS" }} - prefer_local_users: {{ env "USER_DIRECTORY_PREFER_LOCAL_USERS" }} - show_locked_users: {{ env "USER_DIRECTORY_SHOW_LOCKED_USERS" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_retention -media_retention: - local_media_lifetime: {{ env "MEDIA_RETENTION_LOCAL_LIFETIME" }} - remote_media_lifetime: {{ env "MEDIA_RETENTION_REMOTE_LIFETIME" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_metrics -enable_metrics: false - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#track_appservice_user_ips -track_appservice_user_ips: false - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forget_rooms_on_leave -forget_rooms_on_leave: true - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#opentracing-1 -opentracing: - enabled: false - -# https://matrix-org.github.io/synapse/develop/usage/configuration/config_documentation.html#ratelimiting -rc_login: - address: - per_second: {{ env "LOGIN_LIMIT_IP_PER_SECOND" }} - burst_count: {{ env "LOGIN_LIMIT_IP_BURST" }} - account: - per_second: {{ env "LOGIN_LIMIT_ACCOUNT_PER_SECOND" }} - burst_count: {{ env "LOGIN_LIMIT_ACCOUNT_BURST" }} - -# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#web_client_location -web_client_location: {{ env "WEB_CLIENT_LOCATION" }} +# All configuration options are documented on the following link: +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html + +{{ if eq (env "SHARED_SECRET_AUTH_ENABLED") "1" }} +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#modules-1 +modules: + - module: shared_secret_authenticator.SharedSecretAuthProvider + config: + shared_secret: {{ secret "shared_secret_auth" }} + m_login_password_support_enabled: true +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#server_name +server_name: {{ or (env "SERVER_NAME") (env "DOMAIN") }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#public_baseurl +public_baseurl: https://{{ env "DOMAIN" }}/ + +# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#require_auth_for_profile_requests +require_auth_for_profile_requests: {{ env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS" }} + +# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_profile_requests_to_users_who_share_rooms +limit_profile_requests_to_users_who_share_rooms: {{ env "LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#serve_server_wellknown +serve_server_wellknown: {{ env "SERVE_SERVER_WELLKNOWN" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_without_auth +allow_public_rooms_without_auth: false + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_over_federation +allow_public_rooms_over_federation: {{ or (env "ALLOW_PUBLIC_ROOMS_FEDERATION") "true" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#listeners +listeners: + - port: 8008 + tls: false + type: http + x_forwarded: true + + {{ if eq (env "DISABLE_FEDERATION") "1" }} + resources: + {{ if eq (env "KEYCLOAK_ENABLED") "1" }} + - names: [client, openid] + compress: true + {{ else }} + - names: [client] + compress: true + {{ end }} + {{ else }} + resources: + {{ if eq (env "KEYCLOAK_ENABLED") "1" }} + - names: [client, openid, federation] + compress: true + {{ else }} + - names: [client, federation] + compress: true + {{ end }} + {{ end }} + +# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#delete_stale_devices_after +{{ if (env "DELETE_STALE_DEVICES_AFTER") }} +delete_stale_devices_after: {{ env "DELETE_STALE_DEVICES_AFTER" }} +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#admin_contact +admin_contact: 'mailto:{{ env "ADMIN_EMAIL" }}' + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_remote_rooms +limit_remote_rooms: + enabled: true + complexity: 200.0 + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_avatar_size +max_avatar_size: 10M + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forgotten_room_retention_period +forgotten_room_retention_period: 3d + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#request_token_inhibit_3pid_errors +request_token_inhibit_3pid_errors: true + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#redaction_retention_period +redaction_retention_period: {{ env "REDACTION_RETENTION_PERIOD" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_ips_max_age +user_ips_max_age: {{ env "USER_IPS_MAX_AGE" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#retention +retention: + enabled: true + default_policy: + min_lifetime: 1d + max_lifetime: {{ env "RETENTION_MAX_LIFETIME" }} + allowed_lifetime_min: 1d + allowed_lifetime_max: {{ env "ALLOWED_LIFETIME_MAX" }} + purge_jobs: + - longest_max_lifetime: 3d + interval: 12h + - shortest_max_lifetime: 3d + interval: 1d + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#federation_domain_whitelist +{{ if eq (env "DISABLE_FEDERATION") "1" }} +federation_domain_whitelist: [] +{{ else if eq (env "ENABLE_ALLOWLIST") "1" }} +federation_domain_whitelist: {{ env "FEDERATION_ALLOWLIST" }} +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#database-1 +database: + name: psycopg2 + txn_limit: 10000 + args: + user: synapse + password: "{{ secret "db_password" }}" + database: synapse + host: "{{ env "STACK_NAME" }}_db" + port: 5432 + cp_min: 5 + cp_max: 10 + keepalives_idle: 10 + keepalives_interval: 10 + keepalives_count: 3 + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#log_config +log_config: "/data/log.config" + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_store_path +media_store_path: "/data/media_store" + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_upload_size +max_upload_size: 50M + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#turn +{{ if eq (env "TURN_ENABLED") "1" }} +turn_uris: {{ env "TURN_URIS" }} +turn_shared_secret: "{{ secret "turn_shared_secret" }}" +turn_user_lifetime: 1h +turn_allow_guests: {{ env "TURN_ALLOW_GUESTS" }} +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_registration +enable_registration: {{ env "ENABLE_REGISTRATION" }} + +# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_requires_token +registration_requires_token: {{ env "REGISTRATION_REQUIRES_TOKEN" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_3pid_lookup +enable_3pid_lookup: {{ env "ENABLE_3PID_LOOKUP" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_guest_access +allow_guest_access: false + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_shared_secret +registration_shared_secret: {{ secret "registration" }} + +{{ if eq (env "AUTO_JOIN_ROOM_ENABLED") "1" }} +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#auto_join_rooms + +# AUTO_JOIN_ROOM only for backwards compatibility +{{ if (env "AUTO_JOIN_ROOM") }} +auto_join_rooms: + - "{{ env "AUTO_JOIN_ROOM" }}" +{{ else }} +auto_join_rooms: {{ env "AUTO_JOIN_ROOM_LIST" }} +{{ end }} + +{{ end }} + +# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#session_lifetime +{{ if (env "SESSION_LIFETIME") }} +session_lifetime: {{ env "SESSION_LIFETIME" }} +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#report_stats +report_stats: false + +# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#track_puppeted_user_ips +track_puppeted_user_ips: {{ env "TRACK_PUPPETED_USER_IPS" }} + +{{ if eq (env "APP_SERVICES_ENABLED") "1" }} +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#app_service_config_files +app_service_config_files: {{ env "APP_SERVICE_CONFIGS" }} +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#macaroon_secret_key +macaroon_secret_key: "{{ secret "macaroon" }}" + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#form_secret +form_secret: "{{ secret "form_secret" }}" + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#signing_key_path +signing_key_path: "/data/{{ env "DOMAIN" }}.signing.key" + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#old_signing_keys +{{ if (and (env "OLD_SIGNING_KEY_ID") (env "OLD_SIGNING_KEY") (env "OLD_SIGNING_KEY_EXPIRES")) }} +old_signing_keys: + "ed25519:{{ env "OLD_SIGNING_KEY_ID" }}": { key: "{{ env "OLD_SIGNING_KEY" }}", expired_ts: {{ env "OLD_SIGNING_KEY_EXPIRES" }} } +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#trusted_key_servers +{{ if eq (env "ENABLE_ALLOWLIST") "1" }} +trusted_key_servers: [] # NOTE(d1): defaults to requesting server directly, which matches FEDERATION_ALLOWLIST +{{ else }} +trusted_key_servers: + - server_name: "matrix.org" +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#oidc_providers +{{ if eq (env "KEYCLOAK_ENABLED") "1" }} +oidc_providers: + - idp_id: {{ env "KEYCLOAK_ID" }} + idp_name: {{ env "KEYCLOAK_NAME" }} + issuer: "{{ env "KEYCLOAK_URL" }}" + client_id: "{{ env "KEYCLOAK_CLIENT_ID" }}" + client_secret: "{{ secret "keycloak_client_secret" }}" + scopes: ["openid", "profile"] + allow_existing_users: {{ env "KEYCLOAK_ALLOW_EXISTING_USERS" }} + user_mapping_provider: + config: + localpart_template: "{{ "{{ user.preferred_username }}" }}" + display_name_template: "{{ "{{ user.name }}" }}" + + {{ if eq (env "KEYCLOAK2_ENABLED") "1" }} + - idp_id: {{ env "KEYCLOAK2_ID" }} + idp_name: {{ env "KEYCLOAK2_NAME" }} + issuer: "{{ env "KEYCLOAK2_URL" }}" + client_id: "{{ env "KEYCLOAK2_CLIENT_ID" }}" + client_secret: "{{ secret "keycloak2_client_secret" }}" + scopes: ["openid", "profile"] + allow_existing_users: {{ env "KEYCLOAK2_ALLOW_EXISTING_USERS" }} + user_mapping_provider: + config: + localpart_template: "{{ "{{ user.preferred_username }}" }}" + display_name_template: "{{ "{{ user.name }}" }}" + {{ end }} + + {{ if eq (env "KEYCLOAK3_ENABLED") "1" }} + - idp_id: {{ env "KEYCLOAK3_ID" }} + idp_name: {{ env "KEYCLOAK3_NAME" }} + issuer: "{{ env "KEYCLOAK3_URL" }}" + client_id: "{{ env "KEYCLOAK3_CLIENT_ID" }}" + client_secret: "{{ secret "keycloak3_client_secret" }}" + scopes: ["openid", "profile"] + allow_existing_users: {{ env "KEYCLOAK3_ALLOW_EXISTING_USERS" }} + user_mapping_provider: + config: + localpart_template: "{{ "{{ user.preferred_username }}" }}" + display_name_template: "{{ "{{ user.name }}" }}" + {{ end }} +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#sso +{{ if eq (env "KEYCLOAK_ENABLED") "1" }} +sso: + client_whitelist: + - https://{{ env "KEYCLOAK_CLIENT_DOMAIN" }} +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#password_config +# With MAS (matrix_authentication_service), Synapse rejects password_config.enabled: true — set PASSWORD_LOGIN_ENABLED=false in app .env when MAS_ENABLED=1 (.env.sample). +password_config: + enabled: {{ env "PASSWORD_LOGIN_ENABLED" }} + +{{ if eq (env "MAS_ENABLED") "1" }} +# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#matrix_authentication_service +matrix_authentication_service: + enabled: true + endpoint: http://{{ env "STACK_NAME"}}_mas:8080/ + secret_path: /run/secrets/mas_synapse_shared +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email +{{ if eq (env "SMTP_ENABLED") "1" }} +email: + smtp_host: {{ env "SMTP_HOST" }} + smtp_port: {{ env "SMTP_PORT" }} + smtp_user: {{ env "SMTP_USER" }} + smtp_pass: "{{ secret "smtp_password" }}" + require_transport_security: true + notif_from: Your Friendly %(app)s homeserver <{{ env "SMTP_FROM" }}> + app_name: {{ env "SMTP_APP_NAME" }} + enable_notifs: true + client_base_url: https://{{ env "DOMAIN" }} +{{ end }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#encryption_enabled_by_default_for_room_type +encryption_enabled_by_default_for_room_type: {{ env "ENCRYPTED_BY_DEFAULT" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_directory +user_directory: + enabled: {{ env "USER_DIRECTORY_ENABLED" }} + search_all_users: {{ env "USER_DIRECTORY_SEARCH_ALL_USERS" }} + prefer_local_users: {{ env "USER_DIRECTORY_PREFER_LOCAL_USERS" }} + show_locked_users: {{ env "USER_DIRECTORY_SHOW_LOCKED_USERS" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_retention +media_retention: + local_media_lifetime: {{ env "MEDIA_RETENTION_LOCAL_LIFETIME" }} + remote_media_lifetime: {{ env "MEDIA_RETENTION_REMOTE_LIFETIME" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_metrics +enable_metrics: false + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#track_appservice_user_ips +track_appservice_user_ips: false + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forget_rooms_on_leave +forget_rooms_on_leave: true + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#opentracing-1 +opentracing: + enabled: false + +# https://matrix-org.github.io/synapse/develop/usage/configuration/config_documentation.html#ratelimiting +rc_login: + address: + per_second: {{ env "LOGIN_LIMIT_IP_PER_SECOND" }} + burst_count: {{ env "LOGIN_LIMIT_IP_BURST" }} + account: + per_second: {{ env "LOGIN_LIMIT_ACCOUNT_PER_SECOND" }} + burst_count: {{ env "LOGIN_LIMIT_ACCOUNT_BURST" }} + +# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#web_client_location +web_client_location: {{ env "WEB_CLIENT_LOCATION" }} diff --git a/mas.config.yaml.tmpl b/mas.config.yaml.tmpl new file mode 100644 index 0000000..3d958d6 --- /dev/null +++ b/mas.config.yaml.tmpl @@ -0,0 +1,41 @@ +# Docs: https://element-hq.github.io/matrix-authentication-service/ + +http: + public_base: https://{{ env "DOMAIN" }}/ + trusted_proxies: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + - 127.0.0.0/8 + - fd00::/8 + - ::1/128 + listeners: + - name: web + resources: + - name: discovery + - name: human + - name: oauth + - name: compat + - name: graphql + playground: false + - name: assets + binds: + - address: "[::]:8080" + +database: + uri: postgresql://synapse:{{ secret "db_password" }}@{{ env "STACK_NAME" }}_db:5432/mas?sslmode=disable + +matrix: + kind: synapse + homeserver: {{ or (env "SERVER_NAME") (env "DOMAIN") }} + endpoint: http://{{ env "STACK_NAME" }}_app:8008/ + secret_file: /run/secrets/mas_synapse_shared + +secrets: + # Plain hex in file (abra: length=64 charset=hex). See .env.sample modifiers. + encryption_file: /run/secrets/mas_encryption + keys: + - key_file: /run/secrets/mas_signing_rsa + +passwords: + enabled: true diff --git a/nginx.conf.tmpl b/nginx.conf.tmpl index 4169fc4..024e5fc 100644 --- a/nginx.conf.tmpl +++ b/nginx.conf.tmpl @@ -15,6 +15,14 @@ http { keepalive 16; } +{{ if eq (env "MAS_ENABLED") "1" }} + upstream mas_upstream { + zone mas_upstream 64k; + server {{ env "STACK_NAME"}}_mas:8080 resolve; + keepalive 8; + } +{{ end }} + server { listen 80; @@ -32,7 +40,30 @@ http { proxy_http_version 1.1; } - location ~* ^(\/_matrix|\/_synapse\/client) { +{{ if eq (env "MAS_ENABLED") "1" }} + # MAS on same Host as Synapse (public_base = https://$DOMAIN/): browser/OIDC paths live at repo root, not only under /_matrix/ + # Router reference: element-hq/matrix-authentication-service crates/router/src/endpoints.rs + # https://element-hq.github.io/matrix-authentication-service/setup/reverse-proxy.html + location ~ ^/(complete-compat-sso/|oauth2/|\.well-known/(openid-configuration|webfinger|change-password)|authorize|login|logout|register(/|$)|account/|upstream/|consent/|link(\?|/|$)|device/|recover(/|$)|assets/|graphql(/|$)|api/) { + proxy_pass http://mas_upstream; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + client_max_body_size 50M; + } + # Matrix CS API compat (login / logout / refresh and subpaths, e.g. …/login/sso/redirect) — before generic /_matrix + location ~ ^/_matrix/client/[^/]+/(login|logout|refresh)(/.*)?$ { + proxy_pass http://mas_upstream; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + client_max_body_size 50M; + } +{{ end }} + + location ~* ^(\/_matrix|\/_synapse\/client|\/_synapse\/mas) { proxy_pass http://matrix_upstream; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto https; diff --git a/well_known_client.conf.tmpl b/well_known_client.conf.tmpl index 8cacb96..a629317 100644 --- a/well_known_client.conf.tmpl +++ b/well_known_client.conf.tmpl @@ -1,5 +1,8 @@ { "m.homeserver": { "base_url": "https://{{ env "DOMAIN" }}" - } + }{{ if eq (env "MAS_ENABLED") "1" }}, + "org.matrix.msc2965.authentication": { + "issuer": "https://{{ env "DOMAIN" }}/" + }{{ end }} }