Skip to content

Commit

Permalink
[proxy] Configure Caddy
Browse files Browse the repository at this point in the history
  • Loading branch information
aledbf committed May 19, 2021
1 parent 4b952bd commit dd0826c
Show file tree
Hide file tree
Showing 9 changed files with 560 additions and 53 deletions.
4 changes: 0 additions & 4 deletions .werft/values.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ hostname: staging.gitpod-dev.com
imagePrefix: eu.gcr.io/gitpod-core-dev/build/
certificatesSecret:
secretName: proxy-config-certificates
fullChainName: tls.crt
chainName: tls.crt
keyName: tls.key
version: not-set
forceHTTPS: false
imagePullPolicy: Always
affinity:
nodeAffinity:
Expand Down
50 changes: 50 additions & 0 deletions chart/templates/proxy-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright (c) 2021 Gitpod GmbH. All rights reserved.
# Licensed under the MIT License. See License-MIT.txt in the project root for license information.

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.components.proxy.name }}-config
labels:
app: {{ template "gitpod.fullname" $ }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
data:
vhost.empty: |
# Placeholder to avoid errors loading files using a glob pattern
{{- if index .Values "minio" "enabled" }}
vhost.minio: |
https://minio.{$GITPOD_DOMAIN} {
import enable_log
import remove_server_header
import ssl_configuration
reverse_proxy {{ index .Values "minio" "fullnameOverride" }}.{{ .Release.Namespace }}.{$KUBE_DOMAIN}:9000 {
flush_interval -1
}
}
{{- end }}
{{- if index .Values "docker-registry" "enabled" }}
{{- if index .Values "docker-registry" "authentication" -}}
{{ $t := set . "username" (index .Values "docker-registry" "authentication" "username") }}
{{ $t := set . "password" (index .Values "docker-registry" "authentication" "password") }}
{{- else }}
{{ $t := set . "username" (randAlphaNum 20) }}
{{ $t := set . "password" (randAlphaNum 20) }}
{{- end }}
vhost.docker-registry: |
https://minio.{$GITPOD_DOMAIN} {
import enable_log
import remove_server_header
import ssl_configuration
basicauth bcrypt "Docker Registry" {
{{ .username }} {{ bcrypt .password | b64enc }}
}
reverse_proxy https://{{ index .Values "docker-registry" "fullnameOverride" }}.{{ .Release.Namespace }}.{$KUBE_DOMAIN} {
flush_interval -1
}
}
{{- end }}
3 changes: 1 addition & 2 deletions components/proxy/BUILD.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ packages:
type: docker
srcs:
- "conf/**"
- "startup/**"
- "nodomain-certs/**"
- "plugins/**"
argdeps:
- imageRepoBase
config:
Expand Down
50 changes: 3 additions & 47 deletions components/proxy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,11 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License-AGPL.txt in the project root for license information.

FROM openresty/openresty:1.19.3.1-3-alpine

ENV TRIGGER_REBUILD 1
FROM aledbf/caddy-http2:0.5

# Debug convenience
ENV TERM=xterm
ENV SHELL=/bin/bash

RUN apk add --no-cache \
vim \
less \
bind-tools \
curl \
apache2-utils \
gettext \
bash

# Include certbot into the proxy for HTTPS termination
RUN curl -o /usr/bin/lama -sSL https://github.com/csweichel/lama/releases/download/v0.3.0/lama_0.3.0_Linux_x86_64 \
&& chmod +x /usr/bin/lama \
&& mkdir -p /var/www/lama/nginx \
&& touch /var/www/lama/nginx/status

RUN apk add --no-cache \
procps \
certbot \
certbot-nginx

RUN set -e \
&& apk add --no-cache git \
&& cd /tmp \
&& git clone https://github.com/cloudflare/lua-resty-cookie/ \
&& cp lua-resty-cookie/lib/resty/*.lua /usr/local/openresty/site/lualib/ \
&& apk del git \
&& rm -rf /tmp/*

# Update alpine packages
RUN apk upgrade --no-cache

# nginx config templates...
#COPY conf/ /etc/nginx/
# .. and startup script
COPY startup/nginx.sh /nginx.sh

COPY conf/lua-prometheus /etc/nginx/lua-prometheus

# ip.mygitpod.com HTTPS support
COPY nodomain-certs/* /nodomain-certs/

# Run!
EXPOSE 8080
CMD ["/nginx.sh"]
COPY conf/Caddyfile /etc/caddy/Caddyfile
COPY conf/vhost.empty /etc/caddy/vhosts/vhost.empty
244 changes: 244 additions & 0 deletions components/proxy/conf/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
{
# disable automatic SSL certificate generation
auto_https off
# disable admin API server
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
}

(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
}
}

(enable_log) {
log {
output stdout
format filter {
wrap json
fields {
logger delete
msg delete
size delete
status delete
resp_headers delete
request delete
}
}
}
}

(remove_server_header) {
header {
-server
-x-powered-by
}
}

(ssl_configuration) {
tls /etc/caddy/certificates/tls.crt /etc/caddy/certificates/tls.key {
#ca_root <pem_file>
}
}

(upstream_headers) {
header_up X-Real-IP {http.request.remote.host}
}

(upstream_connection) {
lb_try_duration 1s
}

(debug_headers) {
header X-Gitpod-Region {$GITPOD_INSTALLATION_LONGNAME}
}

# Kubernetes health-check
:8003 {
respond /live 200
respond /ready 200
}

# 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

@workspace_download path /workspace-download*
handle @workspace_download {
header {
# The browser needs to see the correct archive content type to trigger the download.
content-type "application/tar+gzip"
-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
}

gitpod.workspace_download {
service http://server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000
}

redir {http.gitpod.workspace_download_url} 303
}

@backend_wss path /api/gitpod
handle @backend_wss {
uri strip_prefix /api
reverse_proxy server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_headers
}
}

@backend path /api/* /admin/*
handle @backend {
gitpod.cors_origin {
base_domain {$GITPOD_DOMAIN}
}

import compression

uri strip_prefix /api
reverse_proxy server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_headers
import upstream_connection
}
}

@codesync path /code-sync*
handle @codesync {
gitpod.cors_origin {
base_domain {$GITPOD_DOMAIN}
}

import compression

reverse_proxy server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_headers
import upstream_connection

flush_interval -1
}
}

@to_server path /auth/github/callback /auth /auth/* /apps /apps/*
handle @to_server {
import compression

reverse_proxy server.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3000 {
import upstream_headers
import upstream_connection
}
}

handle {
reverse_proxy dashboard.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:3001 {
import upstream_headers
import upstream_connection
}
}

handle_errors {
redir https://{$GITPOD_DOMAIN}/sorry/#Error%20{http.reverse_proxy.status_text} 302
}
}

# workspaces
https://*.*.{$GITPOD_DOMAIN} {
import enable_log
import security_headers
import remove_server_header
import ssl_configuration
import debug_headers

@workspace_blobserve header_regexp host Host ^blobserve.ws(?P<location>-[a-z0-9]+)?.{$GITPOD_DOMAIN}
handle @workspace_blobserve {
gitpod.cors_origin {
base_domain {$GITPOD_DOMAIN}
}

reverse_proxy https://ws-proxy.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:9090 {
transport http {
tls_insecure_skip_verify
}

import upstream_headers

header_up X-WSProxy-Host {http.request.host}

header_down -access-control-allow-origin
}
}

@workspace_port header_regexp host Host ^(webview-|browser-|extensions-)?(?P<workspacePort>[0-9]{2,5})-(?P<workspaceID>[a-z0-9][0-9a-z\-]+).ws(?P<location>-[a-z0-9]+)?.{$GITPOD_DOMAIN}
handle @workspace_port {
reverse_proxy ws-{re.host.workspaceID}-ports.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:{re.host.workspacePort} {
import upstream_headers

header_up X-Gitpod-WorkspaceId {re.host.workspaceID}
header_up X-Gitpod-Port {re.host.workspacePort}
header_up X-WSProxy-Host {http.request.host}
}
}

@workspace header_regexp host Host ^(webview-|browser-|extensions-)?(?P<workspaceID>[a-z0-9][0-9a-z\-]+).ws(?P<location>-[a-z0-9]+)?.{$GITPOD_DOMAIN}
handle @workspace {
reverse_proxy https://ws-proxy.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:9090 {
transport http {
tls_insecure_skip_verify
}

import upstream_headers

header_up X-Gitpod-WorkspaceId {re.host.workspaceID}
header_up X-WSProxy-Host {http.request.host}
}
}

respond "Not found" 404
}

import /etc/caddy/vhosts/vhost.*
1 change: 1 addition & 0 deletions components/proxy/conf/vhost.empty
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Placeholder to avoid errors loading files using a glob pattern
Loading

0 comments on commit dd0826c

Please sign in to comment.