2023-01-31 13:47:38 +01:00

391 lines
8.8 KiB
Caddyfile

{
# disable automatic SSL certificate generation
auto_https off
# disable admin API server
# admin localhost:2019
admin off
# set default SNI for old clients
default_sni {$GITPOD_DOMAIN}
# debug
# configure plugin order
# https://caddyserver.com/docs/caddyfile/directives#directive-order
order gitpod.cors_origin before header
order gitpod.workspace_download before redir
order gitpod.headless_log_download before rewrite
order gitpod.configcat before rewrite
order gitpod.sec_websocket_key before header
order gitpod.frontend_dev after forward_auth
servers {
protocols h1 h2 h2c
}
}
(compression) {
encode zstd gzip
}
# configure headers to force HTTPS and enable more strict rules for the browser
(security_headers) {
header {
# enable HSTS
Strict-Transport-Security max-age=31536000
# disable clients from sniffing the media type
X-Content-Type-Options nosniff
# Define valid parents that may embed a page
Content-Security-Policy "frame-ancestors 'self' https://*.{$GITPOD_DOMAIN} https://{$GITPOD_DOMAIN}"
# keep referrer data off of HTTP connections
Referrer-Policy no-referrer-when-downgrade
# Enable cross-site filter (XSS) and tell browser to block detected attacks
X-XSS-Protection "1; mode=block"
defer # delay changes
}
}
# workspace security headers
(workspace_security_headers) {
header {
# Disallow sharing the same browsing context when opened in a popup
Cross-Origin-Opener-Policy same-origin-allow-popups
}
import security_headers
}
(enable_log) {
log {
output stdout
format if "status > 399" jsonselect "{severity:level} {timestamp:ts} {logName:logger} {httpRequest>requestMethod:request>method} {httpRequest>protocol:request>proto} {httpRequest>status:status} {httpRequest>responseSize:size} {httpRequest>userAgent:request>headers>User-Agent>[0]} {httpRequest>requestUrl:request>uri} {httpRequest>requestHost:request>host} {cacheStatus:resp_headers>X-Cache-Status>[0]}" {
level_format "upper"
time_format "rfc3339_nano"
}
}
}
(enable_log_debug) {
log {
output stdout
format jsonselect "{severity:level} {timestamp:ts} {logName:logger} {httpRequest>requestMethod:request>method} {httpRequest>protocol:request>proto} {httpRequest>status:status} {httpRequest>responseSize:size} {httpRequest>userAgent:request>headers>User-Agent>[0]} {httpRequest>requestUrl:request>uri} {httpRequest>requestHost:request>host} {cacheStatus:resp_headers>X-Cache-Status>[0]}" {
level_format "upper"
time_format "rfc3339_nano"
}
}
}
(remove_server_header) {
header {
-server
-x-powered-by
}
}
(ssl_configuration) {
tls /etc/caddy/certificates/tls.crt /etc/caddy/certificates/tls.key {
protocols tls1.2
#ca_root <pem_file>
}
}
(upstream_connection) {
lb_try_duration 1s
}
(debug_headers) {
header X-Gitpod-Region {$GITPOD_REGION}.{$GITPOD_INSTALLATION_SHORTNAME}
}
(workspace_transport) {
transport http {
tls_insecure_skip_verify
keepalive 60s
keepalive_idle_conns 100
}
}
(google_storage_headers) {
header {
-x-guploader-uploadid
-etag
-x-goog-generation
-x-goog-metageneration
-x-goog-hash
-x-goog-stored-content-length
-x-gitpod-region
-x-goog-stored-content-encoding
-x-goog-storage-class
-x-goog-generation
-x-goog-metageneration
-cache-control
-expires
defer # delay changes
}
}
(slow_fast_matchers) {
@slow {
header X-Gitpod-Slow-Database "true"
}
@fast {
not header X-Gitpod-Slow-Database "true"
}
}
# Kubernetes health-check
:8003 {
respond /live 200
respond /ready 200
}
# TODO: refactor once we can listen only in localhost
:9545 {
metrics /metrics {
disable_openmetrics
}
}
# public-api
api.{$GITPOD_DOMAIN} {
log {
level DEBUG
output stdout
}
gitpod.cors_origin {
allowed_origins https://{$GITPOD_DOMAIN}
}
reverse_proxy public-api-server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:9002
}
# always redirect to HTTPS
http:// {
redir https://{host}{uri} permanent
}
https://{$GITPOD_DOMAIN} {
import enable_log
import remove_server_header
import ssl_configuration
import security_headers
@proxy_public_api path /public-api*
handle @proxy_public_api {
uri strip_prefix /public-api
reverse_proxy public-api-server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:9002
}
@workspace_download path /workspace-download*
handle @workspace_download {
import google_storage_headers
header {
# The browser needs to see the correct archive content type to trigger the download.
content-type "application/tar+gzip"
}
gitpod.workspace_download {
service http://server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000
}
# redirect works here because we "navigate" to this URL, which makes the browser handle this as primary request, and not fuff around with CORS at all
redir {http.gitpod.workspace_download_url} 303
}
@headless_log_download path /headless-log-download*
handle @headless_log_download {
header {
# Alltough logs are plain text "text/html" works for reliably for streaming
content-type "text/html; charset=utf-8"
}
# Perform lookup to server and actual reverse_proxy in one go because caddy's `reverse_proxy` is not powerful enough
gitpod.headless_log_download {
service http://server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000
}
}
@configcat path /configcat*
handle @configcat {
gitpod.cors_origin {
any_domain true
}
gitpod.configcat
}
@backend_wss {
path /api/gitpod /api/v1
}
handle @backend_wss {
gitpod.cors_origin {
base_domain {$GITPOD_DOMAIN}
}
gitpod.sec_websocket_key
forward_auth server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
uri /feature-flags/slow-database
header_up -Connection
header_up -Upgrade
copy_headers X-Gitpod-Slow-Database
}
import slow_fast_matchers
uri strip_prefix /api
reverse_proxy @fast server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_connection
}
reverse_proxy @slow slow-server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_connection
}
}
@backend path /api/* /headless-logs/*
handle @backend {
gitpod.cors_origin {
base_domain {$GITPOD_DOMAIN}
}
forward_auth server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
uri /feature-flags/slow-database
copy_headers X-Gitpod-Slow-Database
}
import slow_fast_matchers
uri strip_prefix /api
reverse_proxy @fast server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_connection
# required for smooth streaming of terminal logs
flush_interval -1
}
reverse_proxy @slow slow-server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_connection
# required for smooth streaming of terminal logs
flush_interval -1
}
}
@iam path /iam/*
handle @iam {
gitpod.cors_origin {
any_domain true
}
uri strip_prefix /iam
reverse_proxy public-api-server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:9002 {
import upstream_connection
}
}
@codesync path /code-sync*
handle @codesync {
gitpod.cors_origin {
any_domain true
}
import compression
reverse_proxy server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_connection
flush_interval -1
}
}
@local_app {
path /static/bin/gitpod-local-companion-*
}
handle @local_app {
import compression
reverse_proxy ide-proxy.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:80 {
import upstream_connection
}
}
@to_server path /auth/github/callback /auth /auth/* /apps /apps/*
handle @to_server {
import compression
forward_auth server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
uri /feature-flags/slow-database
copy_headers X-Gitpod-Slow-Database
}
import slow_fast_matchers
reverse_proxy @fast server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_connection
}
reverse_proxy @slow slow-server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_connection
}
}
# Default: route to dashboard
handle {
# Dev URL header present?
@frontend_dev {
header X-Frontend-Dev-URL *
}
handle @frontend_dev {
# ...and allowed to use it?
forward_auth server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
uri /auth/frontend-dev
header_up -Connection
header_up -Upgrade
}
# Then handle it with our plugin!
gitpod.frontend_dev
}
reverse_proxy dashboard.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3001 {
import upstream_connection
}
}
@legacy_urls path /github.com/* /gitlab.com/* /bitbucket.org/*
handle @legacy_urls {
redir https://{$GITPOD_DOMAIN}/#{uri} permanent
}
handle_errors {
redir https://{$GITPOD_DOMAIN}/sorry/#Error%20{http.reverse_proxy.status_text} 302
}
}
# workspaces
https://*.*.{$GITPOD_DOMAIN} {
import enable_log
import workspace_security_headers
import remove_server_header
import ssl_configuration
import debug_headers
# Dear future reader: If you wonder about the asterisk in the line below: So do I!
# But as of now (caddy 2.6.2) it's the only way to make caddy import a file.
import /etc/caddy/workspace-handler/*.{$WORKSPACE_HANDLER_FILE}
}
import /etc/caddy/vhosts/vhost.*