[FEATURE] Container privilege de-escalation (#1370)
* support for running as non-root * forgot to save file * removed write perms for user on entrypoint script * preserve existing user behavior * fix entrypoint permissions to account for non-root user * typo in chmod on line 63 * better entrypoint script; moved to root * execute bit * support for running as non-root * forgot to save file * removed write perms for user on entrypoint script * preserve existing user behavior * fix entrypoint permissions to account for non-root user * typo in chmod on line 63 * better entrypoint script; moved to root * execute bit * very rough draft documentation * added missing header * typo changes -> changed * Update entrypoint.sh Co-authored-by: Amir Zarrinkafsh <nightah@me.com> * Apply suggestions from code review looks good Co-authored-by: Amir Zarrinkafsh <nightah@me.com>pull/1392/head
parent
0ba634ffee
commit
af2ae328e7
12
Dockerfile
12
Dockerfile
|
@ -51,16 +51,20 @@ GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -tags netgo -ldflags '-s -w -link
|
||||||
# ===================================
|
# ===================================
|
||||||
FROM alpine:3.12.0
|
FROM alpine:3.12.0
|
||||||
|
|
||||||
RUN apk --no-cache add ca-certificates tzdata
|
COPY --from=builder-backend /go/src/app/cmd/authelia/authelia ./
|
||||||
|
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
|
RUN apk --no-cache add ca-certificates su-exec tzdata
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=builder-backend /go/src/app/cmd/authelia/authelia ./
|
|
||||||
|
|
||||||
EXPOSE 9091
|
EXPOSE 9091
|
||||||
|
|
||||||
VOLUME /config
|
VOLUME /config
|
||||||
|
|
||||||
ENV PATH="/app:${PATH}"
|
ENV PATH="/app:${PATH}"
|
||||||
|
ENV PUID=0
|
||||||
|
ENV PGID=0
|
||||||
|
|
||||||
CMD ["authelia", "--config", "/config/configuration.yml"]
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
|
CMD ["--config", "/config/configuration.yml"]
|
||||||
|
|
|
@ -55,18 +55,21 @@ GOOS=linux GOARCH=arm CGO_ENABLED=1 CC=arm-linux-musleabihf-gcc go build -tags n
|
||||||
FROM arm32v7/alpine:3.12.0
|
FROM arm32v7/alpine:3.12.0
|
||||||
|
|
||||||
COPY ./qemu-arm-static /usr/bin/qemu-arm-static
|
COPY ./qemu-arm-static /usr/bin/qemu-arm-static
|
||||||
|
COPY --from=builder-backend /go/src/app/cmd/authelia/authelia ./
|
||||||
|
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
RUN apk --no-cache add ca-certificates tzdata && \
|
RUN apk --no-cache add ca-certificates su-exec tzdata && \
|
||||||
rm /usr/bin/qemu-arm-static
|
rm /usr/bin/qemu-arm-static
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=builder-backend /go/src/app/cmd/authelia/authelia ./
|
|
||||||
|
|
||||||
EXPOSE 9091
|
EXPOSE 9091
|
||||||
|
|
||||||
VOLUME /config
|
VOLUME /config
|
||||||
|
|
||||||
ENV PATH="/app:${PATH}"
|
ENV PATH="/app:${PATH}"
|
||||||
|
ENV PUID=0
|
||||||
|
ENV PGID=0
|
||||||
|
|
||||||
CMD ["authelia", "--config", "/config/configuration.yml"]
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
|
CMD ["--config", "/config/configuration.yml"]
|
||||||
|
|
|
@ -55,18 +55,21 @@ GOOS=linux GOARCH=arm64 CGO_ENABLED=1 CC=aarch64-linux-musl-gcc go build -tags n
|
||||||
FROM arm64v8/alpine:3.12.0
|
FROM arm64v8/alpine:3.12.0
|
||||||
|
|
||||||
COPY ./qemu-aarch64-static /usr/bin/qemu-aarch64-static
|
COPY ./qemu-aarch64-static /usr/bin/qemu-aarch64-static
|
||||||
|
COPY --from=builder-backend /go/src/app/cmd/authelia/authelia ./
|
||||||
|
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
RUN apk --no-cache add ca-certificates tzdata && \
|
RUN apk --no-cache add ca-certificates su-exec tzdata && \
|
||||||
rm /usr/bin/qemu-aarch64-static
|
rm /usr/bin/qemu-aarch64-static
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=builder-backend /go/src/app/cmd/authelia/authelia ./
|
|
||||||
|
|
||||||
EXPOSE 9091
|
EXPOSE 9091
|
||||||
|
|
||||||
VOLUME /config
|
VOLUME /config
|
||||||
|
|
||||||
ENV PATH="/app:${PATH}"
|
ENV PATH="/app:${PATH}"
|
||||||
|
ENV PUID=0
|
||||||
|
ENV PGID=0
|
||||||
|
|
||||||
CMD ["authelia", "--config", "/config/configuration.yml"]
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
|
CMD ["--config", "/config/configuration.yml"]
|
||||||
|
|
|
@ -30,17 +30,17 @@ post nginx has written on [HSTS].
|
||||||
|
|
||||||
## Protection against username enumeration
|
## Protection against username enumeration
|
||||||
|
|
||||||
Authelia adaptively delays authentication attempts based on the mean (average) of the
|
Authelia adaptively delays authentication attempts based on the mean (average) of the
|
||||||
previous 10 successful attempts, and a small random interval to make it even harder to
|
previous 10 successful attempts, and a small random interval to make it even harder to
|
||||||
determine if the attempt was successful. On start it is assumed that the last 10 attempts
|
determine if the attempt was successful. On start it is assumed that the last 10 attempts
|
||||||
took 1000ms, this quickly grows or shrinks to the correct value over time regardless of the
|
took 1000ms, this quickly grows or shrinks to the correct value over time regardless of the
|
||||||
authentication backend.
|
authentication backend.
|
||||||
|
|
||||||
The cost of this is low since in the instance of a user not existing it just sleeps to delay
|
The cost of this is low since in the instance of a user not existing it just sleeps to delay
|
||||||
the login. Lastly the absolute minimum time authentication can take is 250ms. Both of these measures
|
the login. Lastly the absolute minimum time authentication can take is 250ms. Both of these measures
|
||||||
also have the added effect of creating an additional delay for all authentication attempts reducing
|
also have the added effect of creating an additional delay for all authentication attempts reducing
|
||||||
the likelihood a password can be brute-forced even if regulation settings are too permissive.
|
the likelihood a password can be brute-forced even if regulation settings are too permissive.
|
||||||
|
|
||||||
## Protections against password cracking (File authentication provider)
|
## Protections against password cracking (File authentication provider)
|
||||||
|
|
||||||
Authelia implements a variety of measures to prevent an attacker cracking passwords if they
|
Authelia implements a variety of measures to prevent an attacker cracking passwords if they
|
||||||
|
@ -50,8 +50,8 @@ First and foremost Authelia only uses very secure hashing algorithms with sane a
|
||||||
The first and default hashing algorithm we use is Argon2id which is currently considered
|
The first and default hashing algorithm we use is Argon2id which is currently considered
|
||||||
the most secure hashing algorithm. We also support SHA512, which previously was the default.
|
the most secure hashing algorithm. We also support SHA512, which previously was the default.
|
||||||
|
|
||||||
Secondly Authelia uses salting with all hashing algorithms. These salts are generated with a random
|
Secondly Authelia uses salting with all hashing algorithms. These salts are generated with a random
|
||||||
string generator, which is seeded every time it's used by a cryptographically secure 1024bit prime number.
|
string generator, which is seeded every time it's used by a cryptographically secure 1024bit prime number.
|
||||||
This ensures that even if an attacker obtains the file, each password has to be brute forced individually.
|
This ensures that even if an attacker obtains the file, each password has to be brute forced individually.
|
||||||
|
|
||||||
Lastly Authelia's implementation of Argon2id is highly tunable. You can tune the key length, salt
|
Lastly Authelia's implementation of Argon2id is highly tunable. You can tune the key length, salt
|
||||||
|
@ -60,12 +60,12 @@ used, iterations (time), parallelism, and memory usage. To read more about this
|
||||||
|
|
||||||
## User profile and group membership always kept up-to-date (LDAP authentication provider)
|
## User profile and group membership always kept up-to-date (LDAP authentication provider)
|
||||||
|
|
||||||
Authelia by default refreshes the user's profile and membership every 5 minutes. Additionally, it
|
Authelia by default refreshes the user's profile and membership every 5 minutes. Additionally, it
|
||||||
will invalidate any session where the user could not be retrieved from LDAP based on the user filter, for
|
will invalidate any session where the user could not be retrieved from LDAP based on the user filter, for
|
||||||
example if they were deleted or disabled provided the user filter is set correctly. These updates occur when
|
example if they were deleted or disabled provided the user filter is set correctly. These updates occur when
|
||||||
a user accesses a resource protected by Authelia.
|
a user accesses a resource protected by Authelia.
|
||||||
|
|
||||||
These protections can be [tuned](../configuration/authentication/ldap.md) according to your security policy
|
These protections can be [tuned](../configuration/authentication/ldap.md) according to your security policy
|
||||||
by changing refresh_interval, however we believe that 5 minutes is a fairly safe interval.
|
by changing refresh_interval, however we believe that 5 minutes is a fairly safe interval.
|
||||||
|
|
||||||
## Notifier security measures (SMTP)
|
## Notifier security measures (SMTP)
|
||||||
|
@ -73,12 +73,12 @@ by changing refresh_interval, however we believe that 5 minutes is a fairly safe
|
||||||
By default the SMTP Notifier implementation does not allow connections that are not secure.
|
By default the SMTP Notifier implementation does not allow connections that are not secure.
|
||||||
As such all connections require the following:
|
As such all connections require the following:
|
||||||
|
|
||||||
1. TLS Connection (STARTTLS or SMTPS) has been negotiated before authentication or sending emails (unauthenticated
|
1. TLS Connection (STARTTLS or SMTPS) has been negotiated before authentication or sending emails (unauthenticated
|
||||||
connections require it as well)
|
connections require it as well)
|
||||||
2. Valid X509 Certificate presented to the client during the TLS handshake
|
2. Valid X509 Certificate presented to the client during the TLS handshake
|
||||||
|
|
||||||
There is an option to disable both of these security measures however they are
|
There is an option to disable both of these security measures however they are
|
||||||
not recommended. You should only do this in a situation where you control all
|
not recommended. You should only do this in a situation where you control all
|
||||||
networks between Authelia and the SMTP server. The following configuration options
|
networks between Authelia and the SMTP server. The following configuration options
|
||||||
exist to configure the security level:
|
exist to configure the security level:
|
||||||
|
|
||||||
|
@ -91,12 +91,12 @@ automatically when a SMTP notifier is configured with the SMTPS port of 465.
|
||||||
### Configuration Option: disable_verify_cert
|
### Configuration Option: disable_verify_cert
|
||||||
|
|
||||||
This is a YAML boolean type (true/false, y/n, 1/0, etc). This disables the X509 PKI
|
This is a YAML boolean type (true/false, y/n, 1/0, etc). This disables the X509 PKI
|
||||||
verification mechanism. We recommend using the trusted_cert option over this, as
|
verification mechanism. We recommend using the trusted_cert option over this, as
|
||||||
disabling this security feature makes you vulnerable to MITM attacks.
|
disabling this security feature makes you vulnerable to MITM attacks.
|
||||||
|
|
||||||
### Configuration Option: disable_require_tls
|
### Configuration Option: disable_require_tls
|
||||||
|
|
||||||
This is a YAML boolean type (true/false, y/n, 1/0, etc). This disables the
|
This is a YAML boolean type (true/false, y/n, 1/0, etc). This disables the
|
||||||
requirement that all connections must be over TLS. This is only usable currently
|
requirement that all connections must be over TLS. This is only usable currently
|
||||||
with authentication disabled (comment the password) and as such is only an
|
with authentication disabled (comment the password) and as such is only an
|
||||||
option for SMTP servers that allow unauthenticated relay (bad practice).
|
option for SMTP servers that allow unauthenticated relay (bad practice).
|
||||||
|
@ -107,8 +107,8 @@ This is a YAML string type. This specifies the file location of a pub certificat
|
||||||
that can be used to validate the authenticity of a server with a self signed
|
that can be used to validate the authenticity of a server with a self signed
|
||||||
certificate. This can either be the public cert of the certificate authority
|
certificate. This can either be the public cert of the certificate authority
|
||||||
used to sign the certificate or the public key itself. They must be in the PEM
|
used to sign the certificate or the public key itself. They must be in the PEM
|
||||||
format. The certificate is added in addition to the certificates trusted by the
|
format. The certificate is added in addition to the certificates trusted by the
|
||||||
host machine. If the certificate is invalid, inaccessible, or is otherwise not
|
host machine. If the certificate is invalid, inaccessible, or is otherwise not
|
||||||
configured; Authelia just uses the hosts certificates.
|
configured; Authelia just uses the hosts certificates.
|
||||||
|
|
||||||
### Explanation
|
### Explanation
|
||||||
|
@ -129,14 +129,14 @@ for information.
|
||||||
### Session security
|
### Session security
|
||||||
|
|
||||||
We have a few options to configure the security of a session. The main and most important
|
We have a few options to configure the security of a session. The main and most important
|
||||||
one is the session secret. This is used to encrypt the session data when when stored in the
|
one is the session secret. This is used to encrypt the session data when when stored in the
|
||||||
Redis key value database. This should be as random as possible.
|
Redis key value database. This should be as random as possible.
|
||||||
|
|
||||||
Additionally you can configure the validity period of sessions. For example in a highly
|
Additionally you can configure the validity period of sessions. For example in a highly
|
||||||
security conscious domain you would probably want to set the session remember_me_duration
|
security conscious domain you would probably want to set the session remember_me_duration
|
||||||
to 0 to disable this feature, and set an expiration of something like 2 hours and inactivity
|
to 0 to disable this feature, and set an expiration of something like 2 hours and inactivity
|
||||||
of 10 minutes. This means the hard limit or the time the session will be destroyed no matter
|
of 10 minutes. This means the hard limit or the time the session will be destroyed no matter
|
||||||
what is 2 hours, and the soft limit or the time a user can be inactive for is 10 minutes.
|
what is 2 hours, and the soft limit or the time a user can be inactive for is 10 minutes.
|
||||||
|
|
||||||
### More protections measures with Nginx
|
### More protections measures with Nginx
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ add_header Pragma "no-cache";
|
||||||
|
|
||||||
# Clickjacking / XSS protection
|
# Clickjacking / XSS protection
|
||||||
|
|
||||||
# We don't want Authelia's login page to be rendered within a <frame>,
|
# We don't want Authelia's login page to be rendered within a <frame>,
|
||||||
# <iframe> or <object> from an external website.
|
# <iframe> or <object> from an external website.
|
||||||
add_header X-Frame-Options "SAMEORIGIN";
|
add_header X-Frame-Options "SAMEORIGIN";
|
||||||
|
|
||||||
|
@ -206,3 +206,61 @@ chain = DOCKER-USER
|
||||||
If you are not using Docker remove the the line "chain = DOCKER-USER"
|
If you are not using Docker remove the the line "chain = DOCKER-USER"
|
||||||
|
|
||||||
Finally, restart the fail2ban service.
|
Finally, restart the fail2ban service.
|
||||||
|
|
||||||
|
## Container privilege de-escalation
|
||||||
|
|
||||||
|
Authelia will run as root by default, there are two options to run as a non-root user. The first option is to use the
|
||||||
|
Docker `--user` option on the command line or in docker-compose. The second option is to use the `PUID` and `PGID`
|
||||||
|
environment variables. An added benefit of using the environment variables is the mounted volumes ownership will automatically
|
||||||
|
be changed for you.
|
||||||
|
|
||||||
|
### Docker user option
|
||||||
|
|
||||||
|
With the Docker `--user` option, Docker will ensure Authelia is running as the user id and group id you specify.
|
||||||
|
In order to use this option, you will need to mount the `/config` volume to a directory on the host and set
|
||||||
|
the owner and group of that directory to the same user you supplied to docker. Running Authelia with `--user`
|
||||||
|
without mounting a volume to `/config` or incorrectly setting the host systems directory owner will cause Authelia
|
||||||
|
to exit immediately. The docker `--user` option will take precedence over the environment variables.
|
||||||
|
|
||||||
|
On the command line, you would create your Authelia data directory, change ownership to your non-root user
|
||||||
|
and run Authelia with `--user` set:
|
||||||
|
```
|
||||||
|
mkdir /authelia
|
||||||
|
chown user:group /authelia
|
||||||
|
docker run --user user:group -v /authelia:/config authelia/authelia:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
As a docker-compose.yml file:
|
||||||
|
```
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
authelia:
|
||||||
|
image: authelia/authelia
|
||||||
|
container_name: authelia
|
||||||
|
user: 1000:1000
|
||||||
|
volumes:
|
||||||
|
- ./authelia:/config
|
||||||
|
```
|
||||||
|
|
||||||
|
### PUID/PGID environment variables
|
||||||
|
|
||||||
|
If you choose to use the environment variables, the correct ownership will be applied automatically on startup of
|
||||||
|
the container, so there's no need to `chown` before running, to use this on the command line use the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -e PUID=1000 -e PGID=1000 -v /authelia:/config authelia:authelia:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
As a docker-compose.yml file:
|
||||||
|
```
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
authelia:
|
||||||
|
image: authelia/authelia
|
||||||
|
container_name: authelia
|
||||||
|
environment:
|
||||||
|
PUID: 1000
|
||||||
|
PGID: 1000
|
||||||
|
volumes:
|
||||||
|
- ./authelia:/config
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [[ ! -z ${1} ]] && [[ ${1} != "--config" ]]; then
|
||||||
|
exec "$@"
|
||||||
|
elif [[ $(id -u) != 0 ]] || [[ $(id -g) != 0 ]]; then
|
||||||
|
exec authelia "$@"
|
||||||
|
else
|
||||||
|
chown -R ${PUID}:${PGID} /config
|
||||||
|
exec su-exec ${PUID}:${PGID} authelia "$@"
|
||||||
|
fi
|
Loading…
Reference in New Issue