From 988cf15b71d26c493f0ad09e5bcccbcd1ba519f4 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Mon, 3 May 2021 00:49:16 +0200 Subject: [PATCH] root: initial go proxy, update compose and helm Signed-off-by: Jens Langhammer --- Dockerfile | 30 +++++ authentik/root/urls.py | 10 -- cmd/server/main.go | 33 +++++ docker-compose.yml | 36 +---- go.mod | 10 ++ go.sum | 184 ++++++++++++++++++++++++++ helm/templates/ingress.yaml | 20 --- helm/templates/static-deployment.yaml | 57 -------- helm/templates/static-service.yaml | 21 --- helm/templates/static-sm.yaml | 17 --- helm/templates/web-deployment.yaml | 5 +- helm/templates/web-service.yaml | 2 +- internal/config/config.go | 53 ++++++++ internal/config/struct.go | 22 +++ internal/crypto/generate.go | 90 +++++++++++++ internal/gounicorn/gounicorn.go | 36 +++++ internal/web/middleware_log.go | 25 ++++ internal/web/middleware_sentry.go | 38 ++++++ internal/web/web.go | 60 +++++++++ internal/web/web_proxy.go | 13 ++ internal/web/web_static.go | 43 ++++++ lifecycle/bootstrap.sh | 2 +- web/Dockerfile | 15 --- web/azure-pipelines.yml | 30 ----- web/static.go | 21 +++ 25 files changed, 667 insertions(+), 206 deletions(-) create mode 100644 cmd/server/main.go create mode 100644 go.mod create mode 100644 go.sum delete mode 100644 helm/templates/static-deployment.yaml delete mode 100644 helm/templates/static-service.yaml delete mode 100644 helm/templates/static-sm.yaml create mode 100644 internal/config/config.go create mode 100644 internal/config/struct.go create mode 100644 internal/crypto/generate.go create mode 100644 internal/gounicorn/gounicorn.go create mode 100644 internal/web/middleware_log.go create mode 100644 internal/web/middleware_sentry.go create mode 100644 internal/web/web.go create mode 100644 internal/web/web_proxy.go create mode 100644 internal/web/web_static.go delete mode 100644 web/Dockerfile create mode 100644 web/static.go diff --git a/Dockerfile b/Dockerfile index eb4d70f7c..e439357c7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,4 @@ +# Stage 1: Lock python dependencies FROM python:3.9-slim-buster as locker COPY ./Pipfile /app/ @@ -9,6 +10,34 @@ RUN pip install pipenv && \ pipenv lock -r > requirements.txt && \ pipenv lock -rd > requirements-dev.txt +# Stage 2: Build webui +FROM node as npm-builder + +COPY ./web /static/ + +ENV NODE_ENV=production +RUN cd /static && npm i --production=false && npm run build + +# Stage 3: Build go proxy +FROM golang:1.16.3 AS builder + +WORKDIR /work + +COPY --from=npm-builder /static/robots.txt /work/web/robots.txt +COPY --from=npm-builder /static/security.txt /work/web/security.txt +COPY --from=npm-builder /static/dist/ /work/web/dist/ +COPY --from=npm-builder /static/authentik/ /work/web/authentik/ + +# RUN ls /work/web/static/authentik/ && exit 1 +COPY ./cmd /work/cmd +COPY ./web/static.go /work/web/static.go +COPY ./internal /work/internal +COPY ./go.mod /work/go.mod +COPY ./go.sum /work/go.sum + +RUN go build -o /work/authentik ./cmd/server/main.go + +# Stage 4: Run FROM python:3.9-slim-buster WORKDIR / @@ -44,6 +73,7 @@ COPY ./pyproject.toml / COPY ./xml /xml COPY ./manage.py / COPY ./lifecycle/ /lifecycle +COPY --from=builder /work/authentik /authentik-proxy USER authentik STOPSIGNAL SIGINT diff --git a/authentik/root/urls.py b/authentik/root/urls.py index 1dd9a9a3a..2c5baf3b4 100644 --- a/authentik/root/urls.py +++ b/authentik/root/urls.py @@ -1,6 +1,4 @@ """authentik URL Configuration""" -from django.conf import settings -from django.conf.urls.static import static from django.urls import include, path from structlog.stdlib import get_logger @@ -49,11 +47,3 @@ urlpatterns += [ path("-/health/live/", LiveView.as_view(), name="health-live"), path("-/health/ready/", ReadyView.as_view(), name="health-ready"), ] - -if settings.DEBUG: # pragma: no cover - - urlpatterns = ( - static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) - + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) - + urlpatterns - ) diff --git a/cmd/server/main.go b/cmd/server/main.go new file mode 100644 index 000000000..aa99020be --- /dev/null +++ b/cmd/server/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "sync" + + log "github.com/sirupsen/logrus" + "goauthentik.io/internal/config" + "goauthentik.io/internal/gounicorn" + "goauthentik.io/internal/web" +) + +func main() { + config.DefaultConfig() + config.ConfigureLogger() + + rl := log.WithField("logger", "authentik.g") + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + defer wg.Done() + g := gounicorn.NewGoUnicorn() + for { + err := g.Start() + rl.WithError(err).Warning("gunicorn process died, restarting") + } + }() + go func() { + defer wg.Done() + ws := web.NewWebServer() + ws.Run() + }() + wg.Wait() +} diff --git a/docker-compose.yml b/docker-compose.yml index 98e9bb9d4..5d8d4dc4f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -47,6 +47,9 @@ services: traefik.http.services.app-service.loadbalancer.server.port: '8000' env_file: - .env + ports: + - "0.0.0.0:9000:9000" + - "0.0.0.0:9443:9443" worker: image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.4.5} restart: unless-stopped @@ -67,39 +70,6 @@ services: - geoip:/geoip env_file: - .env - static: - image: ${AUTHENTIK_IMAGE_STATIC:-beryju/authentik-static}:${AUTHENTIK_TAG:-2021.4.5} - restart: unless-stopped - networks: - - internal - labels: - traefik.enable: 'true' - traefik.docker.network: internal - traefik.http.routers.static-router.rule: PathPrefix(`/static`, `/if`, `/media`, `/robots.txt`, `/favicon.ico`) - traefik.http.routers.static-router.tls: 'true' - traefik.http.routers.static-router.service: static-service - traefik.http.services.static-service.loadbalancer.healthcheck.path: / - traefik.http.services.static-service.loadbalancer.healthcheck.interval: 30s - traefik.http.services.static-service.loadbalancer.server.port: '80' - volumes: - - ./media:/usr/share/nginx/html/media - traefik: - image: traefik:2.3 - restart: unless-stopped - command: - - "--log.format=json" - - "--api.insecure=true" - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--entrypoints.http.address=:80" - - "--entrypoints.https.address=:443" - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - ports: - - "0.0.0.0:443:443" - - "127.0.0.1:8080:8080" - networks: - - internal geoipupdate: image: "maxmindinc/geoipupdate:latest" volumes: diff --git a/go.mod b/go.mod new file mode 100644 index 000000000..89962b90a --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module goauthentik.io + +go 1.16 + +require ( + github.com/getsentry/sentry-go v0.10.0 // indirect + github.com/gorilla/handlers v1.5.1 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/sirupsen/logrus v1.8.1 +) diff --git a/go.sum b/go.sum new file mode 100644 index 000000000..878ca4f61 --- /dev/null +++ b/go.sum @@ -0,0 +1,184 @@ +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/getsentry/sentry-go v0.10.0 h1:6gwY+66NHKqyZrdi6O2jGdo7wGdo9b3B69E01NFgT5g= +github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/helm/templates/ingress.yaml b/helm/templates/ingress.yaml index 262deb08c..69ad25ec2 100644 --- a/helm/templates/ingress.yaml +++ b/helm/templates/ingress.yaml @@ -32,24 +32,4 @@ spec: backend: serviceName: {{ $fullName }}-web servicePort: http - - path: /static/ - backend: - serviceName: {{ $fullName }}-static - servicePort: http - - path: /if/ - backend: - serviceName: {{ $fullName }}-static - servicePort: http - - path: /media/ - backend: - serviceName: {{ $fullName }}-static - servicePort: http - - path: /robots.txt - backend: - serviceName: {{ $fullName }}-static - servicePort: http - - path: /favicon.ico - backend: - serviceName: {{ $fullName }}-static - servicePort: http {{- end }} diff --git a/helm/templates/static-deployment.yaml b/helm/templates/static-deployment.yaml deleted file mode 100644 index 7feee3089..000000000 --- a/helm/templates/static-deployment.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "authentik.fullname" . }}-static - labels: - app.kubernetes.io/name: {{ include "authentik.name" . }} - helm.sh/chart: {{ include "authentik.chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - k8s.goauthentik.io/component: static -spec: - selector: - matchLabels: - app.kubernetes.io/name: {{ include "authentik.name" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - k8s.goauthentik.io/component: static - template: - metadata: - labels: - app.kubernetes.io/name: {{ include "authentik.name" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - k8s.goauthentik.io/component: static - spec: - containers: - - name: {{ .Chart.Name }}-static - image: "{{ .Values.image.name_static }}:{{ .Values.image.tag }}" - imagePullPolicy: "{{ .Values.image.pullPolicy }}" - ports: - - name: http - containerPort: 80 - protocol: TCP - livenessProbe: - initialDelaySeconds: 10 - timeoutSeconds: 5 - httpGet: - path: / - port: http - readinessProbe: - initialDelaySeconds: 10 - timeoutSeconds: 5 - httpGet: - path: / - port: http - resources: - requests: - cpu: 10m - memory: 10M - limits: - cpu: 20m - memory: 20M - volumeMounts: - - name: authentik-uploads - mountPath: /usr/share/nginx/html/media - volumes: - - name: authentik-uploads - persistentVolumeClaim: - claimName: {{ include "authentik.fullname" . }}-uploads diff --git a/helm/templates/static-service.yaml b/helm/templates/static-service.yaml deleted file mode 100644 index 7e9482619..000000000 --- a/helm/templates/static-service.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "authentik.fullname" . }}-static - labels: - app.kubernetes.io/name: {{ include "authentik.name" . }} - helm.sh/chart: {{ include "authentik.chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - k8s.goauthentik.io/component: static -spec: - type: ClusterIP - ports: - - port: 80 - targetPort: http - protocol: TCP - name: http - selector: - app.kubernetes.io/name: {{ include "authentik.name" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - k8s.goauthentik.io/component: static diff --git a/helm/templates/static-sm.yaml b/helm/templates/static-sm.yaml deleted file mode 100644 index 542e7ba41..000000000 --- a/helm/templates/static-sm.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.monitoring.enabled -}} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - app.kubernetes.io/name: {{ include "authentik.name" . }} - helm.sh/chart: {{ include "authentik.chart" . }} - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/managed-by: {{ .Release.Service }} - name: {{ include "authentik.fullname" . }}-static-monitoring -spec: - endpoints: - - port: http - selector: - matchLabels: - k8s.goauthentik.io/component: static -{{- end }} diff --git a/helm/templates/web-deployment.yaml b/helm/templates/web-deployment.yaml index 109f5d3d5..e33e59081 100644 --- a/helm/templates/web-deployment.yaml +++ b/helm/templates/web-deployment.yaml @@ -79,7 +79,10 @@ spec: {{- end }} ports: - name: http - containerPort: 8000 + containerPort: 9000 + protocol: TCP + - name: https + containerPot: 9443 protocol: TCP livenessProbe: httpGet: diff --git a/helm/templates/web-service.yaml b/helm/templates/web-service.yaml index 0fcbbf9b6..f09c3661e 100644 --- a/helm/templates/web-service.yaml +++ b/helm/templates/web-service.yaml @@ -11,7 +11,7 @@ metadata: spec: type: ClusterIP ports: - - port: 80 + - port: 9000 targetPort: http protocol: TCP name: http diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 000000000..e182e658d --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,53 @@ +package config + +import ( + log "github.com/sirupsen/logrus" +) + +var G Config + +func DefaultConfig() { + G = Config{ + Debug: true, + Web: WebConfig{ + Listen: "localhost:9000", + ListenTLS: "localhost:9443", + }, + Paths: PathsConfig{ + Media: "./media", + }, + Log: LogConfig{ + Level: "trace", + Format: "json", + }, + } +} + +func ConfigureLogger() { + switch G.Log.Level { + case "trace": + log.SetLevel(log.TraceLevel) + case "debug": + log.SetLevel(log.DebugLevel) + case "info": + log.SetLevel(log.InfoLevel) + case "warning": + log.SetLevel(log.WarnLevel) + case "error": + log.SetLevel(log.ErrorLevel) + default: + log.SetLevel(log.DebugLevel) + } + + switch G.Log.Format { + case "json": + log.SetFormatter(&log.JSONFormatter{ + FieldMap: log.FieldMap{ + log.FieldKeyMsg: "event", + log.FieldKeyTime: "timestamp", + }, + }) + default: + log.SetFormatter(&log.TextFormatter{}) + } +} diff --git a/internal/config/struct.go b/internal/config/struct.go new file mode 100644 index 000000000..d9540067f --- /dev/null +++ b/internal/config/struct.go @@ -0,0 +1,22 @@ +package config + +type Config struct { + Debug bool + Web WebConfig + Paths PathsConfig + Log LogConfig +} + +type WebConfig struct { + Listen string + ListenTLS string +} + +type PathsConfig struct { + Media string +} + +type LogConfig struct { + Level string + Format string +} diff --git a/internal/crypto/generate.go b/internal/crypto/generate.go new file mode 100644 index 000000000..7503ed0d4 --- /dev/null +++ b/internal/crypto/generate.go @@ -0,0 +1,90 @@ +package crypto + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "math/big" + "net" + "os" + "time" + + log "github.com/sirupsen/logrus" +) + +func GenerateKeypair(hosts []string) { + priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + log.Fatalf("Failed to generate private key: %v", err) + } + + keyUsage := x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment + + notBefore := time.Now() + notAfter := notBefore.Add(365 * 24 * time.Hour) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + log.Fatalf("Failed to generate serial number: %v", err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"BeryJu.org"}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: keyUsage, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + for _, h := range hosts { + if ip := net.ParseIP(h); ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } else { + template.DNSNames = append(template.DNSNames, h) + } + } + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv, priv) + if err != nil { + log.Fatalf("Failed to create certificate: %v", err) + } + + certOut, err := os.Create("cert.pem") + if err != nil { + log.Fatalf("Failed to open cert.pem for writing: %v", err) + } + if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { + log.Fatalf("Failed to write data to cert.pem: %v", err) + } + if err := certOut.Close(); err != nil { + log.Fatalf("Error closing cert.pem: %v", err) + } + log.Print("wrote cert.pem\n") + + keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + log.Fatalf("Failed to open key.pem for writing: %v", err) + return + } + privBytes, err := x509.MarshalPKCS8PrivateKey(priv) + if err != nil { + log.Fatalf("Unable to marshal private key: %v", err) + } + if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil { + log.Fatalf("Failed to write data to key.pem: %v", err) + } + if err := keyOut.Close(); err != nil { + log.Fatalf("Error closing key.pem: %v", err) + } + log.Print("wrote key.pem\n") + return +} diff --git a/internal/gounicorn/gounicorn.go b/internal/gounicorn/gounicorn.go new file mode 100644 index 000000000..9345974b5 --- /dev/null +++ b/internal/gounicorn/gounicorn.go @@ -0,0 +1,36 @@ +package gounicorn + +import ( + "os" + "os/exec" + + log "github.com/sirupsen/logrus" + "goauthentik.io/internal/config" +) + +type GoUnicorn struct { + log *log.Entry +} + +func NewGoUnicorn() *GoUnicorn { + return &GoUnicorn{ + log: log.WithField("logger", "authentik.g.unicorn"), + } +} + +func (g *GoUnicorn) Start() error { + command := "gunicorn" + args := []string{"-c", "./lifecycle/gunicorn.conf.py", "authentik.root.asgi:application"} + if config.G.Debug { + command = "python" + args = []string{"manage.py", "runserver", "localhost:8000"} + } + g.log.WithField("args", args).WithField("cmd", command).Debug("Starting gunicorn") + p := exec.Command(command, args...) + p.Env = append(os.Environ(), + "WORKERS=2", + ) + p.Stdout = os.Stdout + p.Stderr = os.Stderr + return p.Run() +} diff --git a/internal/web/middleware_log.go b/internal/web/middleware_log.go new file mode 100644 index 000000000..79bddc597 --- /dev/null +++ b/internal/web/middleware_log.go @@ -0,0 +1,25 @@ +package web + +import ( + "net/http" + "time" + + "github.com/getsentry/sentry-go" + log "github.com/sirupsen/logrus" +) + +func loggingMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + span := sentry.StartSpan(r.Context(), "request.logging") + before := time.Now() + // Call the next handler, which can be another middleware in the chain, or the final handler. + next.ServeHTTP(w, r) + after := time.Now() + log.WithFields(log.Fields{ + "remote": r.RemoteAddr, + "method": r.Method, + "took": after.Sub(before), + }).Info(r.RequestURI) + span.Finish() + }) +} diff --git a/internal/web/middleware_sentry.go b/internal/web/middleware_sentry.go new file mode 100644 index 000000000..a74609e0e --- /dev/null +++ b/internal/web/middleware_sentry.go @@ -0,0 +1,38 @@ +package web + +import ( + "encoding/json" + "net/http" + + sentryhttp "github.com/getsentry/sentry-go/http" +) + +func recoveryMiddleware() func(next http.Handler) http.Handler { + sentryHandler := sentryhttp.New(sentryhttp.Options{}) + return func(next http.Handler) http.Handler { + sentryHandler.Handle(next) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + next.ServeHTTP(w, r) + defer func() { + re := recover() + if re == nil { + return + } + err := re.(error) + if err != nil { + jsonBody, _ := json.Marshal(struct { + Successful bool + Error string + }{ + Successful: false, + Error: err.Error(), + }) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusInternalServerError) + w.Write(jsonBody) + } + }() + }) + } +} diff --git a/internal/web/web.go b/internal/web/web.go new file mode 100644 index 000000000..e924ecb06 --- /dev/null +++ b/internal/web/web.go @@ -0,0 +1,60 @@ +package web + +import ( + "net/http" + "sync" + + "github.com/gorilla/handlers" + "github.com/gorilla/mux" + log "github.com/sirupsen/logrus" + "goauthentik.io/internal/config" +) + +type WebServer struct { + Bind string + BindTLS bool + + LegacyProxy bool + + m *mux.Router + lh *mux.Router + log *log.Entry +} + +func NewWebServer() *WebServer { + mainHandler := mux.NewRouter() + mainHandler.Use(recoveryMiddleware()) + mainHandler.Use(handlers.ProxyHeaders) + mainHandler.Use(handlers.CompressHandler) + logginRouter := mainHandler.NewRoute().Subrouter() + logginRouter.Use(loggingMiddleware) + ws := &WebServer{ + LegacyProxy: true, + + m: mainHandler, + lh: logginRouter, + log: log.WithField("logger", "authentik.g.web"), + } + ws.configureStatic() + ws.configureProxy() + return ws +} + +func (ws *WebServer) Run() { + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + defer wg.Done() + ws.listenPlain() + }() + go func() { + defer wg.Done() + // ws.listenTLS() + }() + wg.Done() +} + +func (ws *WebServer) listenPlain() { + ws.log.WithField("addr", config.G.Web.Listen).Info("Running") + http.ListenAndServe(config.G.Web.Listen, ws.m) +} diff --git a/internal/web/web_proxy.go b/internal/web/web_proxy.go new file mode 100644 index 000000000..03f5232da --- /dev/null +++ b/internal/web/web_proxy.go @@ -0,0 +1,13 @@ +package web + +import ( + "net/http/httputil" + "net/url" +) + +func (ws *WebServer) configureProxy() { + // Reverse proxy to the application server + u, _ := url.Parse("http://localhost:8000") + rp := httputil.NewSingleHostReverseProxy(u) + ws.m.PathPrefix("/").Handler(rp) +} diff --git a/internal/web/web_static.go b/internal/web/web_static.go new file mode 100644 index 000000000..a0a0e13c1 --- /dev/null +++ b/internal/web/web_static.go @@ -0,0 +1,43 @@ +package web + +import ( + "net/http" + + "goauthentik.io/internal/config" + staticWeb "goauthentik.io/web" +) + +func (ws *WebServer) configureStatic() { + if config.G.Debug { + ws.log.Debug("Using local static files") + ws.lh.PathPrefix("/static/dist").Handler(http.StripPrefix("/static/dist", http.FileServer(http.Dir("./web/dist")))) + ws.lh.PathPrefix("/static/authentik").Handler(http.StripPrefix("/static/authentik", http.FileServer(http.Dir("./web/authentik")))) + } else { + ws.log.Debug("Using packaged static files") + ws.lh.PathPrefix("/static/dist").Handler(http.StripPrefix("/static", http.FileServer(http.FS(staticWeb.StaticDist)))) + ws.lh.PathPrefix("/static/authentik").Handler(http.StripPrefix("/static", http.FileServer(http.FS(staticWeb.StaticAuthentik)))) + } + ws.lh.Path("/robots.txt").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.Header()["Content-Type"] = []string{"text/plain"} + rw.WriteHeader(200) + rw.Write(staticWeb.RobotsTxt) + }) + ws.lh.Path("/.well-known/security.txt").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.Header()["Content-Type"] = []string{"text/plain"} + rw.WriteHeader(200) + rw.Write(staticWeb.SecurityTxt) + }) + // Interfaces + ws.lh.Path("/if/admin/").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.Header()["Content-Type"] = []string{"text/html"} + rw.WriteHeader(200) + rw.Write(staticWeb.InterfaceAdmin) + }) + ws.lh.Path("/if/flow/{slug}/").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.Header()["Content-Type"] = []string{"text/html"} + rw.WriteHeader(200) + rw.Write(staticWeb.InterfaceFlow) + }) + // Media files, always local + ws.lh.PathPrefix("/media").Handler(http.StripPrefix("/media", http.FileServer(http.Dir(config.G.Paths.Media)))) +} diff --git a/lifecycle/bootstrap.sh b/lifecycle/bootstrap.sh index d4e318c1f..98256e1d5 100755 --- a/lifecycle/bootstrap.sh +++ b/lifecycle/bootstrap.sh @@ -3,7 +3,7 @@ python -m lifecycle.wait_for_db printf '{"event": "Bootstrap completed", "level": "info", "logger": "bootstrap", "command": "%s"}\n' "$@" > /dev/stderr if [[ "$1" == "server" ]]; then python -m lifecycle.migrate - gunicorn -c /lifecycle/gunicorn.conf.py authentik.root.asgi:application + /authentik-proxy elif [[ "$1" == "worker" ]]; then celery -A authentik.root.celery worker --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events elif [[ "$1" == "migrate" ]]; then diff --git a/web/Dockerfile b/web/Dockerfile deleted file mode 100644 index 34ab8eb89..000000000 --- a/web/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM node as npm-builder - -COPY . /static/ - -ENV NODE_ENV=production -RUN cd /static && npm i --production=false && npm run build - -FROM nginx - -RUN mkdir /usr/share/nginx/html/.well-known -COPY --from=npm-builder /static/robots.txt /usr/share/nginx/html/robots.txt -COPY --from=npm-builder /static/security.txt /usr/share/nginx/html/.well-known/security.txt -COPY --from=npm-builder /static/dist/ /usr/share/nginx/html/static/dist/ -COPY --from=npm-builder /static/authentik/ /usr/share/nginx/html/static/authentik/ -COPY ./nginx.conf /etc/nginx/nginx.conf diff --git a/web/azure-pipelines.yml b/web/azure-pipelines.yml index 4352991cf..72d9888a5 100644 --- a/web/azure-pipelines.yml +++ b/web/azure-pipelines.yml @@ -3,12 +3,6 @@ trigger: - next - version-* -variables: - ${{ if startsWith(variables['Build.SourceBranch'], 'refs/pull/') }}: - branchName: ${{ replace(variables['System.PullRequest.SourceBranch'], '/', '-') }} - ${{ if startsWith(variables['Build.SourceBranch'], 'refs/heads/') }}: - branchName: ${{ replace(variables['Build.SourceBranchName'], 'refs/heads/', '') }} - stages: - stage: generate jobs: @@ -99,27 +93,3 @@ stages: command: 'custom' workingDir: 'web/' customCommand: 'run build' - - stage: build_docker - jobs: - - job: build_static - pool: - vmImage: 'ubuntu-latest' - steps: - - task: DownloadPipelineArtifact@2 - inputs: - buildType: 'current' - artifactName: 'ts_swagger_client' - path: "web/api/" - - task: Bash@3 - inputs: - targetType: 'inline' - script: | - python ./scripts/az_do_set_branch.py - - task: Docker@2 - inputs: - containerRegistry: 'beryjuorg-harbor' - repository: 'authentik/static' - command: 'buildAndPush' - Dockerfile: 'web/Dockerfile' - tags: "gh-$(branchName)" - buildContext: 'web/' diff --git a/web/static.go b/web/static.go new file mode 100644 index 000000000..f039f838b --- /dev/null +++ b/web/static.go @@ -0,0 +1,21 @@ +package web + +import "embed" + +//go:embed dist/* +var StaticDist embed.FS + +//go:embed authentik +var StaticAuthentik embed.FS + +//go:embed dist/if/flow/index.html +var InterfaceFlow []byte + +//go:embed dist/if/admin/index.html +var InterfaceAdmin []byte + +//go:embed robots.txt +var RobotsTxt []byte + +//go:embed security.txt +var SecurityTxt []byte