core: FIPS (#9683)
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
26
Dockerfile
26
Dockerfile
@ -38,7 +38,7 @@ COPY ./gen-ts-api /work/web/node_modules/@goauthentik/api
|
||||
RUN npm run build
|
||||
|
||||
# Stage 3: Build go proxy
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.22.3-bookworm AS go-builder
|
||||
FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/oss/go/microsoft/golang:1.22-fips-bookworm AS go-builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
@ -49,6 +49,11 @@ ARG GOARCH=$TARGETARCH
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt \
|
||||
dpkg --add-architecture arm64 && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends crossbuild-essential-arm64 gcc-aarch64-linux-gnu
|
||||
|
||||
RUN --mount=type=bind,target=/go/src/goauthentik.io/go.mod,src=./go.mod \
|
||||
--mount=type=bind,target=/go/src/goauthentik.io/go.sum,src=./go.sum \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
@ -63,11 +68,11 @@ COPY ./internal /go/src/goauthentik.io/internal
|
||||
COPY ./go.mod /go/src/goauthentik.io/go.mod
|
||||
COPY ./go.sum /go/src/goauthentik.io/go.sum
|
||||
|
||||
ENV CGO_ENABLED=0
|
||||
|
||||
RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
||||
--mount=type=cache,id=go-build-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/go-build \
|
||||
GOARM="${TARGETVARIANT#v}" go build -o /go/authentik ./cmd/server
|
||||
if [ "$TARGETARCH" = "arm64" ]; then export CC=aarch64-linux-gnu-gcc && export CC_FOR_TARGET=gcc-aarch64-linux-gnu; fi && \
|
||||
CGO_ENABLED=1 GOEXPERIMENT="systemcrypto" GOFLAGS="-tags=requirefips" GOARM="${TARGETVARIANT#v}" \
|
||||
go build -o /go/authentik ./cmd/server
|
||||
|
||||
# Stage 4: MaxMind GeoIP
|
||||
FROM --platform=${BUILDPLATFORM} ghcr.io/maxmind/geoipupdate:v7.0.1 as geoip
|
||||
@ -84,7 +89,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
|
||||
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
|
||||
|
||||
# Stage 5: Python dependencies
|
||||
FROM docker.io/python:3.12.3-slim-bookworm AS python-deps
|
||||
FROM ghcr.io/goauthentik/fips-python:3.12.3-slim-bookworm-fips-full AS python-deps
|
||||
|
||||
WORKDIR /ak-root/poetry
|
||||
|
||||
@ -97,7 +102,7 @@ RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloa
|
||||
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt \
|
||||
apt-get update && \
|
||||
# Required for installing pip packages
|
||||
apt-get install -y --no-install-recommends build-essential pkg-config libxmlsec1-dev zlib1g-dev libpq-dev
|
||||
apt-get install -y --no-install-recommends build-essential pkg-config libpq-dev
|
||||
|
||||
RUN --mount=type=bind,target=./pyproject.toml,src=./pyproject.toml \
|
||||
--mount=type=bind,target=./poetry.lock,src=./poetry.lock \
|
||||
@ -107,10 +112,11 @@ RUN --mount=type=bind,target=./pyproject.toml,src=./pyproject.toml \
|
||||
bash -c "source ${VENV_PATH}/bin/activate && \
|
||||
pip3 install --upgrade pip && \
|
||||
pip3 install poetry && \
|
||||
poetry install --only=main --no-ansi --no-interaction --no-root"
|
||||
poetry install --only=main --no-ansi --no-interaction --no-root && \
|
||||
pip install --force-reinstall /wheels/*"
|
||||
|
||||
# Stage 6: Run
|
||||
FROM docker.io/python:3.12.3-slim-bookworm AS final-image
|
||||
FROM ghcr.io/goauthentik/fips-python:3.12.3-slim-bookworm-fips-full AS final-image
|
||||
|
||||
ARG GIT_BUILD_HASH
|
||||
ARG VERSION
|
||||
@ -127,7 +133,7 @@ WORKDIR /
|
||||
# We cannot cache this layer otherwise we'll end up with a bigger image
|
||||
RUN apt-get update && \
|
||||
# Required for runtime
|
||||
apt-get install -y --no-install-recommends libpq5 openssl libxmlsec1-openssl libmaxminddb0 ca-certificates && \
|
||||
apt-get install -y --no-install-recommends libpq5 libmaxminddb0 ca-certificates && \
|
||||
# Required for bootstrap & healtcheck
|
||||
apt-get install -y --no-install-recommends runit && \
|
||||
apt-get clean && \
|
||||
@ -163,6 +169,8 @@ ENV TMPDIR=/dev/shm/ \
|
||||
VENV_PATH="/ak-root/venv" \
|
||||
POETRY_VIRTUALENVS_CREATE=false
|
||||
|
||||
ENV GOFIPS=1
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=30s --start-period=60s --retries=3 CMD [ "ak", "healthcheck" ]
|
||||
|
||||
ENTRYPOINT [ "dumb-init", "--", "ak" ]
|
||||
|
@ -2,17 +2,19 @@
|
||||
|
||||
import platform
|
||||
from datetime import datetime
|
||||
from ssl import OPENSSL_VERSION
|
||||
from sys import version as python_version
|
||||
from typing import TypedDict
|
||||
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
from django.utils.timezone import now
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from gunicorn import version_info as gunicorn_version
|
||||
from rest_framework.fields import SerializerMethodField
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from authentik import get_full_version
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.utils.reflection import get_env
|
||||
@ -25,11 +27,13 @@ class RuntimeDict(TypedDict):
|
||||
"""Runtime information"""
|
||||
|
||||
python_version: str
|
||||
gunicorn_version: str
|
||||
environment: str
|
||||
architecture: str
|
||||
platform: str
|
||||
uname: str
|
||||
openssl_version: str
|
||||
openssl_fips_mode: bool
|
||||
authentik_version: str
|
||||
|
||||
|
||||
class SystemInfoSerializer(PassiveSerializer):
|
||||
@ -64,11 +68,13 @@ class SystemInfoSerializer(PassiveSerializer):
|
||||
def get_runtime(self, request: Request) -> RuntimeDict:
|
||||
"""Get versions"""
|
||||
return {
|
||||
"python_version": python_version,
|
||||
"gunicorn_version": ".".join(str(x) for x in gunicorn_version),
|
||||
"environment": get_env(),
|
||||
"architecture": platform.machine(),
|
||||
"authentik_version": get_full_version(),
|
||||
"environment": get_env(),
|
||||
"openssl_fips_enabled": backend._fips_enabled,
|
||||
"openssl_version": OPENSSL_VERSION,
|
||||
"platform": platform.platform(),
|
||||
"python_version": python_version,
|
||||
"uname": " ".join(platform.uname()),
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,8 @@ class TestUsersAvatars(APITestCase):
|
||||
with Mocker() as mocker:
|
||||
mocker.head(
|
||||
(
|
||||
"https://secure.gravatar.com/avatar/84730f9c1851d1ea03f1a"
|
||||
"a9ed85bd1ea?size=158&rating=g&default=404"
|
||||
"https://www.gravatar.com/avatar/76eb3c74c8beb6faa037f1b6e2ecb3e252bdac"
|
||||
"6cf71fb567ae36025a9d4ea86b?size=158&rating=g&default=404"
|
||||
),
|
||||
text="foo",
|
||||
)
|
||||
|
@ -92,7 +92,11 @@ class CertificateKeyPair(SerializerModel, ManagedModel, CreatedUpdatedModel):
|
||||
@property
|
||||
def kid(self):
|
||||
"""Get Key ID used for JWKS"""
|
||||
return md5(self.key_data.encode("utf-8")).hexdigest() if self.key_data else "" # nosec
|
||||
return (
|
||||
md5(self.key_data.encode("utf-8"), usedforsecurity=False).hexdigest()
|
||||
if self.key_data
|
||||
else ""
|
||||
) # nosec
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Certificate-Key Pair {self.name}"
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from base64 import b64encode
|
||||
from functools import cache as funccache
|
||||
from hashlib import md5
|
||||
from hashlib import md5, sha256
|
||||
from typing import TYPE_CHECKING
|
||||
from urllib.parse import urlencode
|
||||
|
||||
@ -20,7 +20,7 @@ from authentik.tenants.utils import get_current_tenant
|
||||
if TYPE_CHECKING:
|
||||
from authentik.core.models import User
|
||||
|
||||
GRAVATAR_URL = "https://secure.gravatar.com"
|
||||
GRAVATAR_URL = "https://www.gravatar.com"
|
||||
DEFAULT_AVATAR = static("dist/assets/images/user_default.png")
|
||||
CACHE_KEY_GRAVATAR = "goauthentik.io/lib/avatars/"
|
||||
CACHE_KEY_GRAVATAR_AVAILABLE = "goauthentik.io/lib/avatars/gravatar_available"
|
||||
@ -55,10 +55,9 @@ def avatar_mode_gravatar(user: "User", mode: str) -> str | None:
|
||||
if not cache.get(CACHE_KEY_GRAVATAR_AVAILABLE, True):
|
||||
return None
|
||||
|
||||
# gravatar uses md5 for their URLs, so md5 can't be avoided
|
||||
mail_hash = md5(user.email.lower().encode("utf-8")).hexdigest() # nosec
|
||||
parameters = [("size", "158"), ("rating", "g"), ("default", "404")]
|
||||
gravatar_url = f"{GRAVATAR_URL}/avatar/{mail_hash}?{urlencode(parameters, doseq=True)}"
|
||||
mail_hash = sha256(user.email.lower().encode("utf-8")).hexdigest() # nosec
|
||||
parameters = {"size": "158", "rating": "g", "default": "404"}
|
||||
gravatar_url = f"{GRAVATAR_URL}/avatar/{mail_hash}?{urlencode(parameters)}"
|
||||
|
||||
full_key = CACHE_KEY_GRAVATAR + mail_hash
|
||||
if cache.has_key(full_key):
|
||||
@ -84,7 +83,9 @@ def avatar_mode_gravatar(user: "User", mode: str) -> str | None:
|
||||
|
||||
def generate_colors(text: str) -> tuple[str, str]:
|
||||
"""Generate colours based on `text`"""
|
||||
color = int(md5(text.lower().encode("utf-8")).hexdigest(), 16) % 0xFFFFFF # nosec
|
||||
color = (
|
||||
int(md5(text.lower().encode("utf-8"), usedforsecurity=False).hexdigest(), 16) % 0xFFFFFF
|
||||
) # nosec
|
||||
|
||||
# Get a (somewhat arbitrarily) reduced scope of colors
|
||||
# to avoid too dark or light backgrounds
|
||||
@ -179,7 +180,7 @@ def avatar_mode_generated(user: "User", mode: str) -> str | None:
|
||||
|
||||
def avatar_mode_url(user: "User", mode: str) -> str | None:
|
||||
"""Format url"""
|
||||
mail_hash = md5(user.email.lower().encode("utf-8")).hexdigest() # nosec
|
||||
mail_hash = md5(user.email.lower().encode("utf-8"), usedforsecurity=False).hexdigest() # nosec
|
||||
return mode % {
|
||||
"username": user.username,
|
||||
"mail_hash": mail_hash,
|
||||
|
@ -117,8 +117,12 @@ class OutpostHealthSerializer(PassiveSerializer):
|
||||
uid = CharField(read_only=True)
|
||||
last_seen = DateTimeField(read_only=True)
|
||||
version = CharField(read_only=True)
|
||||
version_should = CharField(read_only=True)
|
||||
golang_version = CharField(read_only=True)
|
||||
openssl_enabled = BooleanField(read_only=True)
|
||||
openssl_version = CharField(read_only=True)
|
||||
fips_enabled = BooleanField(read_only=True)
|
||||
|
||||
version_should = CharField(read_only=True)
|
||||
version_outdated = BooleanField(read_only=True)
|
||||
|
||||
build_hash = CharField(read_only=True, required=False)
|
||||
@ -173,6 +177,10 @@ class OutpostViewSet(UsedByMixin, ModelViewSet):
|
||||
"version_should": state.version_should,
|
||||
"version_outdated": state.version_outdated,
|
||||
"build_hash": state.build_hash,
|
||||
"golang_version": state.golang_version,
|
||||
"openssl_enabled": state.openssl_enabled,
|
||||
"openssl_version": state.openssl_version,
|
||||
"fips_enabled": state.fips_enabled,
|
||||
"hostname": state.hostname,
|
||||
"build_hash_should": get_build_hash(),
|
||||
}
|
||||
|
@ -121,6 +121,10 @@ class OutpostConsumer(JsonWebsocketConsumer):
|
||||
if msg.instruction == WebsocketMessageInstruction.HELLO:
|
||||
state.version = msg.args.pop("version", None)
|
||||
state.build_hash = msg.args.pop("buildHash", "")
|
||||
state.golang_version = msg.args.pop("golangVersion", "")
|
||||
state.openssl_enabled = msg.args.pop("opensslEnabled", False)
|
||||
state.openssl_version = msg.args.pop("opensslVersion", "")
|
||||
state.fips_enabled = msg.args.pop("fipsEnabled", False)
|
||||
state.args.update(msg.args)
|
||||
elif msg.instruction == WebsocketMessageInstruction.ACK:
|
||||
return
|
||||
|
@ -131,7 +131,7 @@ class OutpostServiceConnection(models.Model):
|
||||
verbose_name = _("Outpost Service-Connection")
|
||||
verbose_name_plural = _("Outpost Service-Connections")
|
||||
|
||||
def __str__(self) -> __version__:
|
||||
def __str__(self) -> str:
|
||||
return f"Outpost service connection {self.name}"
|
||||
|
||||
@property
|
||||
@ -434,6 +434,10 @@ class OutpostState:
|
||||
version: str | None = field(default=None)
|
||||
version_should: Version = field(default=OUR_VERSION)
|
||||
build_hash: str = field(default="")
|
||||
golang_version: str = field(default="")
|
||||
openssl_enabled: bool = field(default=False)
|
||||
openssl_version: str = field(default="")
|
||||
fips_enabled: bool = field(default=False)
|
||||
hostname: str = field(default="")
|
||||
args: dict = field(default_factory=dict)
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
from os import environ
|
||||
from ssl import OPENSSL_VERSION
|
||||
|
||||
import pytest
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
from authentik import get_full_version
|
||||
|
||||
@ -18,4 +20,7 @@ def pytest_sessionstart(*_, **__):
|
||||
@pytest.hookimpl(trylast=True)
|
||||
def pytest_report_header(*_, **__):
|
||||
"""Add authentik version to pytest output"""
|
||||
return [f"authentik version: {get_full_version()}"]
|
||||
return [
|
||||
f"authentik version: {get_full_version()}",
|
||||
f"OpenSSL version: {OPENSSL_VERSION}, FIPS: {backend._fips_enabled}",
|
||||
]
|
||||
|
5
internal/crypto/backend/fips_disabled.go
Normal file
5
internal/crypto/backend/fips_disabled.go
Normal file
@ -0,0 +1,5 @@
|
||||
//go:build requirefips
|
||||
|
||||
package backend
|
||||
|
||||
var FipsEnabled = true
|
5
internal/crypto/backend/fips_enabled.go
Normal file
5
internal/crypto/backend/fips_enabled.go
Normal file
@ -0,0 +1,5 @@
|
||||
//go:build !requirefips
|
||||
|
||||
package backend
|
||||
|
||||
var FipsEnabled = false
|
5
internal/crypto/backend/openssl_disabled.go
Normal file
5
internal/crypto/backend/openssl_disabled.go
Normal file
@ -0,0 +1,5 @@
|
||||
//go:build !goexperiment.systemcrypto
|
||||
|
||||
package backend
|
||||
|
||||
var OpensslEnabled = false
|
5
internal/crypto/backend/openssl_enabled.go
Normal file
5
internal/crypto/backend/openssl_enabled.go
Normal file
@ -0,0 +1,5 @@
|
||||
//go:build goexperiment.systemcrypto
|
||||
|
||||
package backend
|
||||
|
||||
var OpensslEnabled = true
|
17
internal/crypto/backend/openssl_version.go
Normal file
17
internal/crypto/backend/openssl_version.go
Normal file
@ -0,0 +1,17 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func OpensslVersion() string {
|
||||
cmd := exec.Command("openssl", "version")
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return out.String()
|
||||
}
|
@ -8,6 +8,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@ -15,11 +16,12 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"goauthentik.io/api/v3"
|
||||
"goauthentik.io/internal/constants"
|
||||
cryptobackend "goauthentik.io/internal/crypto/backend"
|
||||
"goauthentik.io/internal/utils/web"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type WSHandler func(ctx context.Context, args map[string]interface{})
|
||||
@ -187,6 +189,10 @@ func (a *APIController) getWebsocketPingArgs() map[string]interface{} {
|
||||
"version": constants.VERSION,
|
||||
"buildHash": constants.BUILD("tagged"),
|
||||
"uuid": a.instanceUUID.String(),
|
||||
"golangVersion": runtime.Version(),
|
||||
"opensslEnabled": cryptobackend.OpensslEnabled,
|
||||
"opensslVersion": cryptobackend.OpensslVersion(),
|
||||
"fipsEnabled": cryptobackend.FipsEnabled,
|
||||
}
|
||||
hostname, err := os.Hostname()
|
||||
if err == nil {
|
||||
|
@ -1,7 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Stage 1: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.22.3-bookworm AS builder
|
||||
FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/oss/go/microsoft/golang:1.22-fips-bookworm AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
@ -12,20 +12,26 @@ ARG GOARCH=$TARGETARCH
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt \
|
||||
dpkg --add-architecture arm64 && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends crossbuild-essential-arm64 gcc-aarch64-linux-gnu
|
||||
|
||||
RUN --mount=type=bind,target=/go/src/goauthentik.io/go.mod,src=./go.mod \
|
||||
--mount=type=bind,target=/go/src/goauthentik.io/go.sum,src=./go.sum \
|
||||
--mount=type=bind,target=/go/src/goauthentik.io/gen-go-api,src=./gen-go-api \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go mod download
|
||||
|
||||
ENV CGO_ENABLED=0
|
||||
COPY . .
|
||||
RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
||||
--mount=type=cache,id=go-build-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/go-build \
|
||||
GOARM="${TARGETVARIANT#v}" go build -o /go/ldap ./cmd/ldap
|
||||
if [ "$TARGETARCH" = "arm64" ]; then export CC=aarch64-linux-gnu-gcc && export CC_FOR_TARGET=gcc-aarch64-linux-gnu; fi && \
|
||||
CGO_ENABLED=1 GOEXPERIMENT="systemcrypto" GOFLAGS="-tags=requirefips" GOARM="${TARGETVARIANT#v}" \
|
||||
go build -o /go/ldap ./cmd/ldap
|
||||
|
||||
# Stage 2: Run
|
||||
FROM gcr.io/distroless/static-debian11:debug
|
||||
FROM ghcr.io/goauthentik/fips-debian:bookworm-slim-fips
|
||||
|
||||
ARG GIT_BUILD_HASH
|
||||
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
|
||||
@ -44,4 +50,6 @@ EXPOSE 3389 6636 9300
|
||||
|
||||
USER 1000
|
||||
|
||||
ENV GOFIPS=1
|
||||
|
||||
ENTRYPOINT ["/ldap"]
|
||||
|
@ -84,6 +84,7 @@ elif [[ "$1" == "bash" ]]; then
|
||||
elif [[ "$1" == "test-all" ]]; then
|
||||
prepare_debug
|
||||
chmod 777 /root
|
||||
pip install --force-reinstall /wheels/*
|
||||
check_if_root "python -m manage test authentik"
|
||||
elif [[ "$1" == "healthcheck" ]]; then
|
||||
run_authentik healthcheck $(cat $MODE_FILE)
|
||||
|
@ -7,6 +7,9 @@ from pathlib import Path
|
||||
from tempfile import gettempdir
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from cryptography.exceptions import InternalError
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
from defusedxml import defuse_stdlib
|
||||
from prometheus_client.values import MultiProcessValue
|
||||
|
||||
from authentik import get_full_version
|
||||
@ -25,6 +28,13 @@ if TYPE_CHECKING:
|
||||
|
||||
from authentik.root.asgi import AuthentikAsgi
|
||||
|
||||
defuse_stdlib()
|
||||
|
||||
try:
|
||||
backend._enable_fips()
|
||||
except InternalError:
|
||||
pass
|
||||
|
||||
wait_for_db()
|
||||
|
||||
_tmp = Path(gettempdir())
|
||||
|
@ -4,6 +4,8 @@ import os
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
from cryptography.exceptions import InternalError
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
from defusedxml import defuse_stdlib
|
||||
from django.utils.autoreload import DJANGO_AUTORELOAD_ENV
|
||||
|
||||
@ -22,6 +24,12 @@ warnings.filterwarnings(
|
||||
|
||||
defuse_stdlib()
|
||||
|
||||
try:
|
||||
backend._enable_fips()
|
||||
except InternalError:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
|
||||
wait_for_db()
|
||||
|
@ -17,7 +17,7 @@ COPY web .
|
||||
RUN npm run build-proxy
|
||||
|
||||
# Stage 2: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.22.3-bookworm AS builder
|
||||
FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/oss/go/microsoft/golang:1.22-fips-bookworm AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
@ -28,20 +28,26 @@ ARG GOARCH=$TARGETARCH
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt \
|
||||
dpkg --add-architecture arm64 && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends crossbuild-essential-arm64 gcc-aarch64-linux-gnu
|
||||
|
||||
RUN --mount=type=bind,target=/go/src/goauthentik.io/go.mod,src=./go.mod \
|
||||
--mount=type=bind,target=/go/src/goauthentik.io/go.sum,src=./go.sum \
|
||||
--mount=type=bind,target=/go/src/goauthentik.io/gen-go-api,src=./gen-go-api \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go mod download
|
||||
|
||||
ENV CGO_ENABLED=0
|
||||
COPY . .
|
||||
RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
||||
--mount=type=cache,id=go-build-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/go-build \
|
||||
GOARM="${TARGETVARIANT#v}" go build -o /go/proxy ./cmd/proxy
|
||||
if [ "$TARGETARCH" = "arm64" ]; then export CC=aarch64-linux-gnu-gcc && export CC_FOR_TARGET=gcc-aarch64-linux-gnu; fi && \
|
||||
CGO_ENABLED=1 GOEXPERIMENT="systemcrypto" GOFLAGS="-tags=requirefips" GOARM="${TARGETVARIANT#v}" \
|
||||
go build -o /go/proxy ./cmd/proxy
|
||||
|
||||
# Stage 3: Run
|
||||
FROM gcr.io/distroless/static-debian11:debug
|
||||
FROM ghcr.io/goauthentik/fips-debian:bookworm-slim-fips
|
||||
|
||||
ARG GIT_BUILD_HASH
|
||||
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
|
||||
@ -64,4 +70,6 @@ EXPOSE 9000 9300 9443
|
||||
|
||||
USER 1000
|
||||
|
||||
ENV GOFIPS=1
|
||||
|
||||
ENTRYPOINT ["/proxy"]
|
||||
|
@ -1,24 +1,37 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Stage 1: Build
|
||||
FROM docker.io/golang:1.22.3-bookworm AS builder
|
||||
FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/oss/go/microsoft/golang:1.22-fips-bookworm AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
ARG TARGETVARIANT
|
||||
|
||||
ARG GOOS=$TARGETOS
|
||||
ARG GOARCH=$TARGETARCH
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt \
|
||||
dpkg --add-architecture arm64 && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends crossbuild-essential-arm64 gcc-aarch64-linux-gnu
|
||||
|
||||
RUN --mount=type=bind,target=/go/src/goauthentik.io/go.mod,src=./go.mod \
|
||||
--mount=type=bind,target=/go/src/goauthentik.io/go.sum,src=./go.sum \
|
||||
--mount=type=bind,target=/go/src/goauthentik.io/gen-go-api,src=./gen-go-api \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go mod download
|
||||
|
||||
ENV CGO_ENABLED=0
|
||||
COPY . .
|
||||
RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
||||
--mount=type=cache,id=go-build-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/go-build \
|
||||
if [ "$TARGETARCH" = "arm64" ]; then export CC=aarch64-linux-gnu-gcc && export CC_FOR_TARGET=gcc-aarch64-linux-gnu; fi && \
|
||||
CGO_ENABLED=1 GOEXPERIMENT="systemcrypto" GOFLAGS="-tags=requirefips" GOARM="${TARGETVARIANT#v}" \
|
||||
go build -o /go/rac ./cmd/rac
|
||||
|
||||
# Stage 2: Run
|
||||
FROM ghcr.io/beryju/guacd:1.5.5
|
||||
FROM ghcr.io/beryju/guacd:1.5.5-fips
|
||||
|
||||
ARG GIT_BUILD_HASH
|
||||
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
|
||||
@ -35,4 +48,6 @@ HEALTHCHECK --interval=5s --retries=20 --start-period=3s CMD [ "/rac", "healthch
|
||||
|
||||
USER 1000
|
||||
|
||||
ENV GOFIPS=1
|
||||
|
||||
ENTRYPOINT ["/rac"]
|
||||
|
@ -1,7 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Stage 1: Build
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.22.3-bookworm AS builder
|
||||
FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/oss/go/microsoft/golang:1.22-fips-bookworm AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
@ -12,20 +12,26 @@ ARG GOARCH=$TARGETARCH
|
||||
|
||||
WORKDIR /go/src/goauthentik.io
|
||||
|
||||
RUN --mount=type=cache,id=apt-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/var/cache/apt \
|
||||
dpkg --add-architecture arm64 && \
|
||||
apt-get update && \
|
||||
apt-get install -y --no-install-recommends crossbuild-essential-arm64 gcc-aarch64-linux-gnu
|
||||
|
||||
RUN --mount=type=bind,target=/go/src/goauthentik.io/go.mod,src=./go.mod \
|
||||
--mount=type=bind,target=/go/src/goauthentik.io/go.sum,src=./go.sum \
|
||||
--mount=type=bind,target=/go/src/goauthentik.io/gen-go-api,src=./gen-go-api \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
go mod download
|
||||
|
||||
ENV CGO_ENABLED=0
|
||||
COPY . .
|
||||
RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
||||
--mount=type=cache,id=go-build-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/go-build \
|
||||
GOARM="${TARGETVARIANT#v}" go build -o /go/radius ./cmd/radius
|
||||
if [ "$TARGETARCH" = "arm64" ]; then export CC=aarch64-linux-gnu-gcc && export CC_FOR_TARGET=gcc-aarch64-linux-gnu; fi && \
|
||||
CGO_ENABLED=1 GOEXPERIMENT="systemcrypto" GOFLAGS="-tags=requirefips" GOARM="${TARGETVARIANT#v}" \
|
||||
go build -o /go/radius ./cmd/radius
|
||||
|
||||
# Stage 2: Run
|
||||
FROM gcr.io/distroless/static-debian11:debug
|
||||
FROM ghcr.io/goauthentik/fips-debian:bookworm-slim-fips
|
||||
|
||||
ARG GIT_BUILD_HASH
|
||||
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
|
||||
@ -44,4 +50,6 @@ EXPOSE 1812/udp 9300
|
||||
|
||||
USER 1000
|
||||
|
||||
ENV GOFIPS=1
|
||||
|
||||
ENTRYPOINT ["/radius"]
|
||||
|
28
schema.yml
28
schema.yml
@ -39368,6 +39368,18 @@ components:
|
||||
version:
|
||||
type: string
|
||||
readOnly: true
|
||||
golang_version:
|
||||
type: string
|
||||
readOnly: true
|
||||
openssl_enabled:
|
||||
type: boolean
|
||||
readOnly: true
|
||||
openssl_version:
|
||||
type: string
|
||||
readOnly: true
|
||||
fips_enabled:
|
||||
type: boolean
|
||||
readOnly: true
|
||||
version_should:
|
||||
type: string
|
||||
readOnly: true
|
||||
@ -39386,8 +39398,12 @@ components:
|
||||
required:
|
||||
- build_hash
|
||||
- build_hash_should
|
||||
- fips_enabled
|
||||
- golang_version
|
||||
- hostname
|
||||
- last_seen
|
||||
- openssl_enabled
|
||||
- openssl_version
|
||||
- uid
|
||||
- version
|
||||
- version_outdated
|
||||
@ -47106,8 +47122,6 @@ components:
|
||||
properties:
|
||||
python_version:
|
||||
type: string
|
||||
gunicorn_version:
|
||||
type: string
|
||||
environment:
|
||||
type: string
|
||||
architecture:
|
||||
@ -47116,10 +47130,18 @@ components:
|
||||
type: string
|
||||
uname:
|
||||
type: string
|
||||
openssl_version:
|
||||
type: string
|
||||
openssl_fips_mode:
|
||||
type: boolean
|
||||
authentik_version:
|
||||
type: string
|
||||
required:
|
||||
- architecture
|
||||
- authentik_version
|
||||
- environment
|
||||
- gunicorn_version
|
||||
- openssl_fips_mode
|
||||
- openssl_version
|
||||
- platform
|
||||
- python_version
|
||||
- uname
|
||||
|
@ -34,10 +34,12 @@ export class OutpostHealthElement extends AKElement {
|
||||
}
|
||||
let versionString = this.outpostHealth.version;
|
||||
if (this.outpostHealth.buildHash) {
|
||||
versionString = `${versionString} (build ${this.outpostHealth.buildHash.substring(
|
||||
0,
|
||||
8,
|
||||
)})`;
|
||||
versionString = msg(
|
||||
str`${versionString} (build ${this.outpostHealth.buildHash.substring(0, 8)})`,
|
||||
);
|
||||
}
|
||||
if (this.outpostHealth.fipsEnabled) {
|
||||
versionString = msg(str`${versionString} (FIPS)`);
|
||||
}
|
||||
return html`<dl class="pf-c-description-list pf-m-compact">
|
||||
<div class="pf-c-description-list__group">
|
||||
|
Reference in New Issue
Block a user