mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
Mattermost 11.11.0 routes its OAuth token and userinfo requests through the
same outbound filter as webhooks and link previews. Upstream commit 232d968f435e
"Filter OAuth endpoint requests that hit reserved IPs" changed two lines in
server/channels/app/oauth.go:
1102 -> 1117 a.HTTPService().MakeClient(true) -> MakeClient(false)
1144 -> 1159 a.HTTPService().MakeClient(true) -> MakeClient(false)
MakeTransport(trustURLs=true) returns NewTransport(insecure, nil, nil), so
before the bump neither a host nor an IP filter applied to that path at all.
Keycloak resolves into a reserved range in this topology, so every sign-in now
ends at /error?message=Token+request+failed:
AuthorizeOAuthUser: Token request failed., Post
"https://auth.<domain>/realms/<realm>/protocol/openid-connect/token":
address forbidden ... IP 172.30.0.10 is in a reserved range and not in
AllowedUntrustedInternalConnections
Name the issuer host, which is the smallest grant Mattermost offers. A verbatim
hostname short-circuits the dial before DNS and before the IP check
(shared/httpservice/client.go:136), so no CIDR is needed; a CIDR would open the
whole stack to webhook and link-preview SSRF instead. Both guarded legs are
listed because an inventory may override USER_INFO_URL to a different host, and
they are comma-joined because splitFields splits on whitespace and commas while
a space would need quoting in a dotenv value.
Not CI-only: IsOwnIP treats any address bound on a local interface as reserved,
so a single-host production deployment hits the same block. The cost is that
every MakeClient(false) consumer may now dial that one hostname on any port,
since Mattermost offers no port or path granularity.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
61 lines
2.8 KiB
Django/Jinja
61 lines
2.8 KiB
Django/Jinja
{% include 'roles/sys-svc-container/templates/env.j2' %}
|
|
|
|
MM_SERVICESETTINGS_SITEURL={{ lookup('tls', application_id, 'url.base') }}
|
|
MM_SERVICESETTINGS_LISTENADDRESS=:{{ container_port }}
|
|
MM_SERVICESETTINGS_ALLOWCORSFROM={{ lookup('tls', application_id, 'url.base') }}
|
|
MM_SERVICESETTINGS_ENABLELOCALMODE=true
|
|
MM_SERVICESETTINGS_ENABLEUSERACCESSTOKENS={{ (lookup('config', application_id, 'services.mattermost.user_access_token_enabled') | bool) or (MATTERMOST_MCP_ENABLED | bool) }}
|
|
MM_EXPERIMENTALSETTINGS_DISABLELANDINGPAGE=true
|
|
|
|
MM_LOGSETTINGS_CONSOLELEVEL={% if MODE_DEBUG | bool %}DEBUG{% else %}INFO{% endif %}
|
|
|
|
MM_LOGSETTINGS_ENABLEFILE=false
|
|
|
|
MM_SQLSETTINGS_DRIVERNAME=postgres
|
|
MM_SQLSETTINGS_DATASOURCE={{ MATTERMOST_DATABASE_DSN }}
|
|
MM_SQLSETTINGS_MAXOPENCONNS=20
|
|
MM_SQLSETTINGS_MAXIDLECONNS=10
|
|
|
|
MM_CONFIG={{ MATTERMOST_DATABASE_DSN }}
|
|
|
|
{% if lookup('objstore', application_id, 'enabled') | bool %}
|
|
MM_FILESETTINGS_DRIVERNAME=amazons3
|
|
MM_FILESETTINGS_AMAZONS3BUCKET={{ lookup('objstore', application_id, 'bucket') }}
|
|
MM_FILESETTINGS_AMAZONS3ENDPOINT={{ lookup('objstore', application_id, 'endpoint') }}
|
|
MM_FILESETTINGS_AMAZONS3ACCESSKEYID={{ lookup('objstore', application_id, 'access_key') }}
|
|
MM_FILESETTINGS_AMAZONS3SECRETACCESSKEY={{ lookup('objstore', application_id, 'secret_key') }}
|
|
MM_FILESETTINGS_AMAZONS3SSL=false
|
|
MM_FILESETTINGS_AMAZONS3REGION={{ lookup('objstore', application_id, 'region') }}
|
|
{% else %}
|
|
MM_FILESETTINGS_DRIVERNAME=local
|
|
MM_FILESETTINGS_DIRECTORY=/mattermost/data/
|
|
{% endif %}
|
|
|
|
{% set email = lookup('email', application_id) %}
|
|
{% if email.enabled | bool %}
|
|
MM_EMAILSETTINGS_ENABLESMTPAUTH=true
|
|
MM_EMAILSETTINGS_SMTPSERVER={{ email.host }}
|
|
MM_EMAILSETTINGS_SMTPPORT={{ email.port }}
|
|
MM_EMAILSETTINGS_SMTPUSERNAME={{ email.username }}
|
|
MM_EMAILSETTINGS_SMTPPASSWORD={{ email.password | dotenv_quote }}
|
|
MM_EMAILSETTINGS_CONNECTIONSECURITY=TLS
|
|
MM_EMAILSETTINGS_FEEDBACKEMAIL={{ email['from'] }}
|
|
MM_EMAILSETTINGS_REPLYTOADDRESS={{ email['from'] }}
|
|
MM_EMAILSETTINGS_SENDEMAILNOTIFICATIONS=true
|
|
{% endif %}
|
|
|
|
{% if MATTERMOST_OIDC_ENABLED | bool %}
|
|
MM_GITLABSETTINGS_ENABLE=true
|
|
MM_GITLABSETTINGS_ID={{ OIDC.CLIENT.ID }}
|
|
MM_GITLABSETTINGS_SECRET={{ OIDC.CLIENT.SECRET }}
|
|
MM_GITLABSETTINGS_AUTHENDPOINT={{ OIDC.CLIENT.AUTHORIZE_URL }}
|
|
MM_GITLABSETTINGS_TOKENENDPOINT={{ OIDC.CLIENT.TOKEN_URL }}
|
|
MM_GITLABSETTINGS_USERAPIENDPOINT={{ OIDC.CLIENT.USER_INFO_URL }}
|
|
MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS={{ [OIDC.CLIENT.TOKEN_URL | urlsplit('hostname'), OIDC.CLIENT.USER_INFO_URL | urlsplit('hostname')] | unique | join(',') }}
|
|
{% endif %}
|
|
|
|
{% if lookup('config', application_id, 'services.prometheus.native_metrics.enabled', False) | bool %}
|
|
MM_METRICSSETTINGS_ENABLE=true
|
|
MM_METRICSSETTINGS_LISTENADDRESS=:{{ lookup('config', application_id, 'services.prometheus.native_metrics.port') }}
|
|
{% endif %}
|