mirror of
https://github.com/hoellen/docker-nextcloud.git
synced 2025-04-22 21:49:27 +00:00
Compare commits
22 Commits
125ea0a2f6
...
f194e4b319
Author | SHA1 | Date | |
---|---|---|---|
f194e4b319 | |||
3c945d7ee7 | |||
7a377af96a | |||
7905e3a7c4 | |||
425b04ad03 | |||
|
79d99eb02f | ||
|
0b3b86dfff | ||
|
a906f113b5 | ||
|
1ffd446214 | ||
|
8c11184ba1 | ||
|
2c662e7862 | ||
|
f7aded2aeb | ||
|
9a30d0ff02 | ||
|
33dc46def2 | ||
|
7974e54491 | ||
|
6e8e9619ed | ||
|
eceef9c4ac | ||
|
bce0750e6e | ||
|
d451bcf1ef | ||
|
2ac3ec67f2 | ||
|
df476c0dc4 | ||
|
7611471834 |
78
.github/workflows/build.yml
vendored
78
.github/workflows/build.yml
vendored
@ -8,44 +8,66 @@ on:
|
||||
# Build the image regularly (each Friday)
|
||||
- cron: '23 04 * * 5'
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository_owner }}/nextcloud
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build, scan & push
|
||||
runs-on: "ubuntu-20.04"
|
||||
name: Build, push & sign
|
||||
runs-on: "ubuntu-latest"
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build an image from Dockerfile
|
||||
- name: Extract version for tags
|
||||
run: |
|
||||
docker build \
|
||||
-t ghcr.io/${{ github.actor }}/nextcloud \
|
||||
-t ghcr.io/${{ github.actor }}/nextcloud:$(grep -oP '(?<=NEXTCLOUD_VERSION=).*' Dockerfile | head -c6) \
|
||||
-t ghcr.io/${{ github.actor }}/nextcloud:$(grep -oP '(?<=NEXTCLOUD_VERSION=).*' Dockerfile | head -c2) \
|
||||
.
|
||||
echo "FULL_VERSION=$(grep -oP '(?<=NEXTCLOUD_VERSION=).*' Dockerfile | head -c6)" >> $GITHUB_ENV
|
||||
echo "MAJOR_VERSION=$(grep -oP '(?<=NEXTCLOUD_VERSION=).*' Dockerfile | head -c2)" >> $GITHUB_ENV
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@master
|
||||
- name: Install cosign
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: sigstore/cosign-installer@main
|
||||
with:
|
||||
image-ref: 'ghcr.io/${{ github.actor }}/nextcloud'
|
||||
format: 'template'
|
||||
template: '@/contrib/sarif.tpl'
|
||||
output: 'trivy-results.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
vuln-type: "os"
|
||||
cosign-release: 'v1.6.0'
|
||||
|
||||
- name: Upload Trivy scan results to GitHub Security tab
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to registry
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
sarif_file: 'trivy-results.sarif'
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Login to the registry
|
||||
run: >-
|
||||
echo "${{ secrets.GITHUB_TOKEN }}"
|
||||
| docker login -u "${{ github.actor }}" --password-stdin ghcr.io
|
||||
- name: Set Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
latest
|
||||
${{ env.FULL_VERSION }}
|
||||
${{ env.MAJOR_VERSION }}
|
||||
|
||||
- name: Push image to GitHub
|
||||
run: |
|
||||
docker push ghcr.io/${{ github.actor }}/nextcloud
|
||||
docker push ghcr.io/${{ github.actor }}/nextcloud:$(grep -oP '(?<=NEXTCLOUD_VERSION=).*' Dockerfile | head -c6)
|
||||
docker push ghcr.io/${{ github.actor }}/nextcloud:$(grep -oP '(?<=NEXTCLOUD_VERSION=).*' Dockerfile | head -c2)
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
- name: Sign the published Docker image
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: "true"
|
||||
run: cosign sign ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build-and-push.outputs.digest }}
|
||||
|
38
Dockerfile
38
Dockerfile
@ -1,25 +1,32 @@
|
||||
# -------------- Build-time variables --------------
|
||||
ARG NEXTCLOUD_VERSION=23.0.4
|
||||
ARG NEXTCLOUD_VERSION=24.0.0
|
||||
ARG PHP_VERSION=8.0
|
||||
ARG NGINX_VERSION=1.20
|
||||
|
||||
ARG ALPINE_VERSION=3.15
|
||||
ARG HARDENED_MALLOC_VERSION=11
|
||||
ARG SNUFFLEUPAGUS_VERSION=0.7.1
|
||||
|
||||
ARG UID=1000
|
||||
ARG GID=1000
|
||||
|
||||
# nextcloud-24.0.0.tar.bz2
|
||||
ARG SHA256_SUM="176cb5620f20465fb4759bdf3caaebeb7acff39d6c8630351af9f8738c173780"
|
||||
|
||||
# Nextcloud Security <security@nextcloud.com> (D75899B9A724937A)
|
||||
ARG GPG_FINGERPRINT="2880 6A87 8AE4 23A2 8372 792E D758 99B9 A724 937A"
|
||||
# ---------------------------------------------------
|
||||
|
||||
### Build PHP base
|
||||
FROM php:${PHP_VERSION}-fpm-alpine${ALPINE_VERSION} as base
|
||||
|
||||
ARG APCU_VERSION
|
||||
ARG REDIS_VERSION
|
||||
ARG SNUFFLEUPAGUS_VERSION
|
||||
|
||||
RUN apk -U upgrade \
|
||||
&& apk add -t build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
freetype-dev \
|
||||
git \
|
||||
gmp-dev \
|
||||
icu-dev \
|
||||
libjpeg-turbo-dev \
|
||||
@ -67,8 +74,10 @@ RUN apk -U upgrade \
|
||||
smbclient \
|
||||
redis \
|
||||
imagick \
|
||||
&& cd /tmp && git clone --depth 1 --branch v${SNUFFLEUPAGUS_VERSION} https://github.com/jvoisin/snuffleupagus \
|
||||
&& cd snuffleupagus/src && phpize && ./configure --enable-snuffleupagus && make && make install \
|
||||
&& apk del build-deps \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
&& rm -rf /var/cache/apk/* /tmp/*
|
||||
|
||||
|
||||
### Build Hardened Malloc
|
||||
@ -98,7 +107,8 @@ COPY --from=nginx /etc/nginx /etc/nginx
|
||||
COPY --from=build-malloc /tmp/hardened_malloc/out-light/libhardened_malloc-light.so /usr/local/lib/
|
||||
|
||||
ARG NEXTCLOUD_VERSION
|
||||
ARG GPG_nextcloud="2880 6A87 8AE4 23A2 8372 792E D758 99B9 A724 937A"
|
||||
ARG SHA256_SUM
|
||||
ARG GPG_FINGERPRINT
|
||||
|
||||
ARG UID
|
||||
ARG GID
|
||||
@ -111,31 +121,30 @@ ENV UPLOAD_MAX_SIZE=10G \
|
||||
CRON_MEMORY_LIMIT=1g \
|
||||
DB_TYPE=sqlite3 \
|
||||
DOMAIN=localhost \
|
||||
LD_PRELOAD="/usr/local/lib/libhardened_malloc-light.so /usr/lib/preloadable_libiconv.so"
|
||||
PHP_HARDENING=true \
|
||||
LD_PRELOAD="/usr/local/lib/libhardened_malloc-light.so"
|
||||
|
||||
RUN apk --no-cache add \
|
||||
gnupg \
|
||||
gnu-libiconv \
|
||||
pcre \
|
||||
s6 \
|
||||
&& NEXTCLOUD_TARBALL="nextcloud-${NEXTCLOUD_VERSION}.tar.bz2" && cd /tmp \
|
||||
&& wget -q https://download.nextcloud.com/server/releases/${NEXTCLOUD_TARBALL} \
|
||||
&& wget -q https://download.nextcloud.com/server/releases/${NEXTCLOUD_TARBALL}.sha512 \
|
||||
&& wget -q https://download.nextcloud.com/server/releases/${NEXTCLOUD_TARBALL}.asc \
|
||||
&& wget -q https://nextcloud.com/nextcloud.asc \
|
||||
&& echo "Verifying both integrity and authenticity of ${NEXTCLOUD_TARBALL}..." \
|
||||
&& CHECKSUM_STATE=$(echo -n $(sha512sum -c ${NEXTCLOUD_TARBALL}.sha512) | tail -c 2) \
|
||||
&& CHECKSUM_STATE=$(echo -n $(echo "${SHA256_SUM} ${NEXTCLOUD_TARBALL}" | sha256sum -c) | tail -c 2) \
|
||||
&& if [ "${CHECKSUM_STATE}" != "OK" ]; then echo "Error: checksum does not match" && exit 1; fi \
|
||||
&& gpg --import nextcloud.asc \
|
||||
&& FINGERPRINT="$(LANG=C gpg --verify ${NEXTCLOUD_TARBALL}.asc ${NEXTCLOUD_TARBALL} 2>&1 \
|
||||
| sed -n "s#Primary key fingerprint: \(.*\)#\1#p")" \
|
||||
&& if [ -z "${FINGERPRINT}" ]; then echo "Error: invalid GPG signature!" && exit 1; fi \
|
||||
&& if [ "${FINGERPRINT}" != "${GPG_nextcloud}" ]; then echo "Error: wrong GPG fingerprint" && exit 1; fi \
|
||||
&& if [ "${FINGERPRINT}" != "${GPG_FINGERPRINT}" ]; then echo "Error: wrong GPG fingerprint" && exit 1; fi \
|
||||
&& echo "All seems good, now unpacking ${NEXTCLOUD_TARBALL}..." \
|
||||
&& mkdir /nextcloud && tar xjf ${NEXTCLOUD_TARBALL} --strip 1 -C /nextcloud \
|
||||
&& apk del gnupg && rm -rf /tmp/* /root/.gnupg \
|
||||
&& adduser -g ${GID} -u ${UID} --disabled-password --gecos "" nextcloud \
|
||||
&& chown -R nextcloud:nextcloud /nextcloud
|
||||
&& chown -R nextcloud:nextcloud /nextcloud/config
|
||||
|
||||
COPY --chown=nextcloud:nextcloud rootfs /
|
||||
|
||||
@ -149,8 +158,9 @@ VOLUME /data /nextcloud/config /nextcloud/apps2 /nextcloud/themes
|
||||
|
||||
EXPOSE 8888
|
||||
|
||||
LABEL description="A server software for creating file hosting services" \
|
||||
nextcloud="Nextcloud v${NEXTCLOUD_VERSION}" \
|
||||
maintainer="Hoellen <dev@hoellen.eu>"
|
||||
LABEL org.opencontainers.image.description="All-in-one Nextcloud image, based on Alpine Linux" \
|
||||
org.opencontainers.image.version="${NEXTCLOUD_VERSION}" \
|
||||
org.opencontainers.image.authors="Hoellen <dev@hoellen.eu>" \
|
||||
org.opencontainers.image.source="https://github.com/hoellen/docker-nextcloud"
|
||||
|
||||
CMD ["run.sh"]
|
||||
|
108
README.md
108
README.md
@ -3,71 +3,115 @@
|
||||
|
||||
Nextcloud [official website](https://nextcloud.com/) and [source code](https://github.com/nextcloud).
|
||||
|
||||
## Why this image?
|
||||
This non-official image is intended as an **all-in-one** (as in monolithic) Nextcloud **production** image. It is based on the [Wondefall/docker-nextcloud](https://github.com/Wonderfall/docker-nextcloud) image. If you're not sure you want this image, you should probably use [the official image](https://hub.docker.com/r/nextcloud).
|
||||
## About
|
||||
This non-official image is intended as an **all-in-one** (as in monolithic) Nextcloud **production** image. If you're not sure you want this image, you should probably use [the official image](https://hub.docker.com/r/nextcloud). The main goal is to provide an easy-to-use image with decent security standards. This repository is mainly based on [Wondefall/docker-nextcloud](https://github.com/Wonderfall/docker-nextcloud).
|
||||
|
||||
## Security
|
||||
Don't run random images from random dudes on the Internet. Ideally, you want to maintain and build it yourself.
|
||||
Check out Nextcloud [official website](https://nextcloud.com/) and [source code](https://github.com/nextcloud).
|
||||
|
||||
Images are scanned every day by [Trivy](https://github.com/aquasecurity/trivy) for OS vulnerabilities. Latest tag/version is automatically built weekly, so you should often update your images regardless if you're already using the latest Nextcloud version.
|
||||
___
|
||||
|
||||
If you're building manually, you should always build production images without cache (use `docker build --no-cache` for instance). Latest dependencies will hence be used instead of outdated ones due to a cached layer.
|
||||
* [Features](#features)
|
||||
* [Security](#security)
|
||||
* [Tags](#tags)
|
||||
* [Build-time variables](#build-time-variables)
|
||||
* [Environment variables](#environment-variables)
|
||||
* [Runtime](#runtime)
|
||||
* [Startup](#startup)
|
||||
* [Volumes](#volumes)
|
||||
* [Ports](#ports)
|
||||
* [Migration](#migration)
|
||||
* [Usage](#usage)
|
||||
|
||||
## Features
|
||||
|
||||
- Based on [Alpine Linux](https://alpinelinux.org/).
|
||||
- Fetching PHP/nginx from their official images.
|
||||
- **Rootless**: no privilege at any time, even at startup.
|
||||
- Includes **hardened_malloc**, a hardened memory allocator.
|
||||
- Uses [s6](https://skarnet.org/software/s6/) as a lightweight process supervisor.
|
||||
- Supports MySQL/MariaDB, PostgresQL and SQLite3 database backends.
|
||||
- Includes OPcache and APCu for improved caching & performance, also supports redis.
|
||||
- Tarball integrity & authenticity checked during build process.
|
||||
- Includes **hardened_malloc**, [a hardened memory allocator](https://github.com/GrapheneOS/hardened_malloc).
|
||||
- Includes **Snuffleupagus**, [a PHP security module](https://github.com/jvoisin/snuffleupagus).
|
||||
- Includes a simple **built-in cron** system.
|
||||
- Much easier to maintain thanks to multi-stages build.
|
||||
- Does not include imagick, samba, etc. by default.
|
||||
|
||||
You're free to make your own image based on this one if you want a specific feature. Uncommon features won't be included as they can increase attack surface: this image intends to stay **minimal**, but **functional enough** to cover basic needs.
|
||||
|
||||
## Security
|
||||
|
||||
Don't run random images from random dudes on the Internet. Ideally, you want to maintain and build it yourself.
|
||||
|
||||
- **Images are scanned every day** by [Trivy](https://github.com/aquasecurity/trivy) for OS vulnerabilities. Known vulnerabilities will be automatically uploaded to [GitHub Security Lab](https://github.com/Wonderfall/docker-nextcloud/security/code-scanning) for full transparency. This also warns me if I have to take action to fix a vulnerability.
|
||||
- **Latest tag/version is automatically built weekly**, so you should often update your images regardless if you're already using the latest Nextcloud version.
|
||||
- **Build production images without cache** (use `docker build --no-cache` for instance) if you want to build your images manually. Latest dependencies will hence be used instead of outdated ones due to a cached layer.
|
||||
- **A security module for PHP called [Snuffleupagus](https://github.com/jvoisin/snuffleupagus) is used by default**. This module aims at killing entire bug and security exploit classes (including XXE, weak PRNG, file-upload based code execution), thus raising the cost of attacks. For now we're using a configuration file derived from [the default one](https://github.com/jvoisin/snuffleupagus/blob/master/config/default_php8.rules), with some explicit exceptions related to Nextcloud. This configuration file is tested and shouldn't break basic functionality, but it can cause issues in specific and untested use cases: if that happens to you, get logs from either `syslog` or `/nginx/logs/error.log` inside the container, and [open an issue](https://github.com/hoellen/docker-nextcloud/issues). You can also disable the security module altogether by changing the `PHP_HARDENING` environment variable to `false` before recreating the container.
|
||||
- **Images are signed with the GitHub-provided OIDC token in Actions** using the experimental "keyless" signing feature provided by [cosign](https://github.com/sigstore/cosign). You can verify the image signature using `cosign` as well:
|
||||
|
||||
```
|
||||
COSIGN_EXPERIMENTAL=true cosign verify ghcr.io/hoellen/nextcloud
|
||||
```
|
||||
|
||||
Verifying the signature isn't a requirement, and might not be as seamless as using *Docker Content Trust* (which is not supported by GitHub's OCI registry). However, it's strongly recommended to do so in a sensitive environment to ensure the authenticity of the images and further limit the risk of supply chain attacks.
|
||||
|
||||
## Tags
|
||||
|
||||
- `latest` : latest Nextcloud version
|
||||
- `x` : latest Nextcloud x.x (e.g. `21`)
|
||||
- `x.x.x` : Nextcloud x.x.x (e.g. `21.0.2`)
|
||||
- `x` : latest Nextcloud x.x (e.g. `24`)
|
||||
- `x.x.x` : Nextcloud x.x.x (e.g. `24.0.0`)
|
||||
|
||||
You can always have a glance [here](https://github.com/users/hoellen/packages/container/package/nextcloud).
|
||||
Only the **latest stable version** will be maintained by myself.
|
||||
|
||||
*Note: automated builds only target `linux/amd64` (x86_64). There is no technical reason preventing the image to be built for `arm64` (in fact you can build it yourself), but GitHub Actions runners are limited in memory, and this limit makes it currently impossible to target both platforms.*
|
||||
|
||||
## Build-time variables
|
||||
| Variable | Description |
|
||||
| --------------------------- | -------------------------- |
|
||||
| **NEXTCLOUD_VERSION** | version of Nextcloud |
|
||||
| **ALPINE_VERSION** | version of Alpine Linux |
|
||||
| **PHP_VERSION** | version of PHP |
|
||||
| **NGINX_VERSION** | version of nginx |
|
||||
| **APCU_VERSION** | version of APCu (php ext) |
|
||||
| **REDIS_VERSION** | version of redis (php ext) |
|
||||
| **HARDENED_MALLOC_VERSION** | version of hardened_malloc |
|
||||
| **CONFIG_NATIVE** | native code for hmalloc |
|
||||
| **UID** | user id (default: 1000) |
|
||||
| **GID** | group id (default: 1000) |
|
||||
|
||||
For convenience they were put at [the very top of the Dockerfile](https://github.com/hoellen/docker-nextcloud/blob/master/Dockerfile#L1-L13) and their usage should be quite explicit if you intend to build this image yourself.
|
||||
| Variable | Description | Default |
|
||||
| --------------------------- | -------------------------------------- | ------------------ |
|
||||
| **NEXTCLOUD_VERSION** | version of Nextcloud | * |
|
||||
| **ALPINE_VERSION** | version of Alpine Linux | * |
|
||||
| **PHP_VERSION** | version of PHP | * |
|
||||
| **NGINX_VERSION** | version of nginx | * |
|
||||
| **HARDENED_MALLOC_VERSION** | version of hardened_malloc | * |
|
||||
| **SNUFFLEUPAGUS_VERSION** | version of Snuffleupagus (php ext) | * |
|
||||
| **SHA256_SUM** | checksum of Nextcloud tarball (sha256) | * |
|
||||
| **GPG_FINGERPRINT** | fingerprint of Nextcloud GPG key | * |
|
||||
| **UID** | user id | 1000 |
|
||||
| **GID** | group id | 1000 |
|
||||
| **CONFIG_NATIVE** | native code for hardened_malloc | false |
|
||||
| **VARIANT** | variant of hardened_malloc (see repo) | light |
|
||||
|
||||
## Environment variables (Dockerfile)
|
||||
*\* latest known available, likely to change regularly*
|
||||
|
||||
For convenience they were put at [the very top of the Dockerfile](https://github.com/Wonderfall/docker-nextcloud/blob/main/Dockerfile#L1-L13) and their usage should be quite explicit if you intend to build this image yourself. If you intend to change `NEXTCLOUD_VERSION`, change `SHA256_SUM` accordingly.
|
||||
|
||||
## Environment variables
|
||||
|
||||
### Runtime
|
||||
|
||||
| Variable | Description | Default |
|
||||
| ------------------------- | --------------------------- | ------------------ |
|
||||
| **UPLOAD_MAX_SIZE** | file upload maximum size | 10G |
|
||||
| **APC_SHM_SIZE** | apc shared memory size | 128M |
|
||||
| **OPCACHE_MEM_SIZE** | opcache available memory | 128M |
|
||||
| **MEMORY_LIMIT** | max php command mem usage | 512M |
|
||||
| **CRON_PERIOD** | cron time interval (min.) | 5m |
|
||||
| **CRON_MEMORY_LIMIT** | cron max memory usage | 1G |
|
||||
| **DB_TYPE** | sqlite3, mysql, pgsql | sqlite3 |
|
||||
| **DOMAIN** | host domain | localhost |
|
||||
| **DOMAIN** | host domain | localhost |
|
||||
| **PHP_HARDENING** | enables snuffleupagus | true |
|
||||
|
||||
Leave them at default if you're not sure what you're doing.
|
||||
|
||||
## Environment variables (used by setup.sh)
|
||||
### Startup
|
||||
|
||||
| Variable | Description |
|
||||
| ------------------------- | --------------------------- |
|
||||
| **ADMIN_USER** | admin username |
|
||||
| **ADMIN_PASSWORD** | admin password |
|
||||
| **DB_TYPE** | sqlit3, mysql, pgsql |
|
||||
| **DB_TYPE** | sqlite3, mysql, pgsql |
|
||||
| **DB_NAME** | name of the database |
|
||||
| **DB_USER** | name of the database user |
|
||||
| **DB_PASSWORD** | password of the db user |
|
||||
@ -78,24 +122,29 @@ Leave them at default if you're not sure what you're doing.
|
||||
The usage of [Docker secrets](https://docs.docker.com/engine/swarm/secrets/) will be considered in the future, but `config.php` already covers quite a lot.
|
||||
|
||||
## Volumes
|
||||
|
||||
| Variable | Description |
|
||||
| ------------------------- | -------------------------- |
|
||||
| **/data** | data files |
|
||||
| **/nextcloud/config** | config files |
|
||||
| **/nextcloud/apps2** | 3rd-party apps |
|
||||
| **/nextcloud/themes** | custom themes |
|
||||
| **/php/session** | PHP session files |
|
||||
|
||||
*Note: mounting `/php/session` isn't required but could be desirable in some circumstances.*
|
||||
|
||||
## Ports
|
||||
|
||||
| Port | Use |
|
||||
| ------------------------- | -------------------------- |
|
||||
| **8888** (tcp) | Nextcloud web |
|
||||
|
||||
|
||||
A reverse proxy like [Traefik](https://doc.traefik.io/traefik/) or [Caddy](https://caddyserver.com/) can be used, and you should consider:
|
||||
- Redirecting all HTTP traffic to HTTPS
|
||||
- Setting the [HSTS header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) correctly
|
||||
|
||||
## Migration from the legacy image
|
||||
## Migration
|
||||
|
||||
From now on you'll need to make sure all volumes have proper permissions. The default UID/GID is now 1000, so you'll need to build the image yourself if you want to change that, or you can just change the actual permissions of the volumes using `chown -R 1000:1000`. The flexibility provided by the legacy image came at some cost (performance & security), therefore this feature won't be provided anymore.
|
||||
|
||||
Other changes that should be reflected in your configuration files:
|
||||
@ -105,5 +154,6 @@ Other changes that should be reflected in your configuration files:
|
||||
|
||||
You should edit your `docker-compose.yml` and `config.php` accordingly.
|
||||
|
||||
## Get started
|
||||
## Usage
|
||||
|
||||
*To do.*
|
||||
|
19
SECURITY.md
19
SECURITY.md
@ -1,14 +1,23 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
## Supported versions
|
||||
|
||||
As of now, only the latest stable version will be supported.
|
||||
All versions of the Nextcloud community version which still receive updates will be supported
|
||||
and will receive the minor version updates and security patches.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 21. x | :white_check_mark: |
|
||||
| 24. x | :white_check_mark: |
|
||||
| 23. x | :white_check_mark: |
|
||||
| 22. x | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
Please update to the latest version available. Major migrations are always tested before being pushed.
|
||||
|
||||
## Automated vulnerability scanning
|
||||
|
||||
Uploaded images are regularly scanned for [OS vulnerabilities](https://github.com/Wonderfall/docker-nextcloud/security/code-scanning).
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
*Upstream* vulnerabilities should be reported to *upstream* projects according to their own security policies.
|
||||
|
||||
@ -17,4 +26,4 @@ Regarding vulnerabilities specific to this project:
|
||||
- Unsafe defaults
|
||||
- Dependencies security updates
|
||||
|
||||
Those can be disclosed in private to `wonderfall@pm.me` or `wonderfall:targaryen.house` on Matrix (preferred).
|
||||
Those can be disclosed in private to `dev@hoellen.eu`.
|
||||
|
@ -22,7 +22,7 @@ server {
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
||||
add_header X-Robots-Tag "none" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header X-XSS-Protection "0" always;
|
||||
|
||||
location = /robots.txt {
|
||||
allow all;
|
||||
|
@ -9,6 +9,12 @@ sed -i -e "s/<APC_SHM_SIZE>/$APC_SHM_SIZE/g" /usr/local/etc/php/conf.d/apcu.ini
|
||||
-e "s/<UPLOAD_MAX_SIZE>/$UPLOAD_MAX_SIZE/g" /etc/nginx/nginx.conf /usr/local/etc/php-fpm.conf \
|
||||
-e "s/<MEMORY_LIMIT>/$MEMORY_LIMIT/g" /usr/local/etc/php-fpm.conf
|
||||
|
||||
# Enable Snuffleupagus
|
||||
if [ "$PHP_HARDENING" == "true" ] && [ ! -f /usr/local/etc/php/conf.d/snuffleupagus.ini ]; then
|
||||
echo "Enabling Snuffleupagus..."
|
||||
cp /usr/local/etc/php/snuffleupagus/* /usr/local/etc/php/conf.d
|
||||
fi
|
||||
|
||||
# If new install, run setup
|
||||
if [ ! -f /nextcloud/config/config.php ]; then
|
||||
touch /nextcloud/config/CAN_INSTALL
|
||||
|
@ -55,11 +55,13 @@ cat >> /nextcloud/config/autoconfig.php <<EOF;
|
||||
?>
|
||||
EOF
|
||||
|
||||
until nc -z "${DB_HOST:-nextcloud-db}" "${DB_PORT:-3306}"
|
||||
do
|
||||
if [ ${DB_TYPE} != "sqlite3" ]; then
|
||||
until nc -z "${DB_HOST:-nextcloud-db}" "${DB_PORT:-3306}"
|
||||
do
|
||||
echo "waiting for the database container..."
|
||||
sleep 1
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
echo "Starting automatic configuration..."
|
||||
# Execute setup
|
||||
|
@ -6,3 +6,5 @@ opcache.memory_consumption=<OPCACHE_MEM_SIZE>
|
||||
opcache.interned_strings_buffer=16
|
||||
opcache.max_accelerated_files=10000
|
||||
opcache.revalidate_freq=60
|
||||
opcache.jit=disable
|
||||
opcache.jit_buffer_size=0
|
||||
|
131
rootfs/usr/local/etc/php/snuffleupagus/nextcloud-php8.rules
Normal file
131
rootfs/usr/local/etc/php/snuffleupagus/nextcloud-php8.rules
Normal file
@ -0,0 +1,131 @@
|
||||
# This is the default configuration file for Snuffleupagus (https://snuffleupagus.rtfd.io),
|
||||
# for php8.
|
||||
# It contains "reasonable" defaults that won't break your websites,
|
||||
# and a lot of commented directives that you can enable if you want to
|
||||
# have a better protection.
|
||||
|
||||
# Harden the PRNG
|
||||
sp.harden_random.enable();
|
||||
|
||||
# Disabled XXE
|
||||
sp.disable_xxe.enable();
|
||||
|
||||
# Global configuration variables
|
||||
# sp.global.secret_key("YOU _DO_ NEED TO CHANGE THIS WITH SOME RANDOM CHARACTERS.");
|
||||
|
||||
# Globally activate strict mode
|
||||
# https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.strict
|
||||
sp.global_strict.enable();
|
||||
|
||||
# Prevent unserialize-related exploits
|
||||
# sp.unserialize_hmac.enable();
|
||||
|
||||
# Only allow execution of read-only files. This is a low-hanging fruit that you should enable.
|
||||
# sp.readonly_exec.enable();
|
||||
|
||||
# PHP has a lot of wrappers, most of them aren't usually useful, you should
|
||||
# only enable the ones you're using.
|
||||
# sp.wrappers_whitelist.list("file,php,phar");
|
||||
|
||||
# Prevent sloppy comparisons.
|
||||
sp.sloppy_comparison.enable();
|
||||
|
||||
# Use SameSite on session cookie
|
||||
# https://snuffleupagus.readthedocs.io/features.html#protection-against-cross-site-request-forgery
|
||||
sp.cookie.name("PHPSESSID").samesite("lax");
|
||||
|
||||
# Nextcloud whitelist (tested with Nextcloud 24.0.0)
|
||||
sp.disable_function.function("function_exists").param("function").value("proc_open").filename("/nextcloud/3rdparty/symfony/console/Terminal.php").allow();
|
||||
sp.disable_function.function("proc_open").filename("/nextcloud/3rdparty/symfony/console/Terminal.php").allow();
|
||||
sp.disable_function.function("ini_set").param("option").value_r("display_errors").filename("/nextcloud/lib/base.php").allow();
|
||||
sp.disable_function.function("ini_get").param("option").value("open_basedir").filename("/nextcloud/3rdparty/bantu/ini-get-wrapper/src/IniGetWrapper.php").allow();
|
||||
sp.disable_function.function("function_exists").param("function").value("exec").filename("/nextcloud/lib/private/legacy/OC_Helper.php").allow();
|
||||
sp.disable_function.function("ini_get").param("option").value_r("suhosin").filename("/nextcloud/3rdparty/bantu/ini-get-wrapper/src/IniGetWrapper.php").allow();
|
||||
sp.disable_function.function("ini_get").param("option").value("open_basedir").filename("/nextcloud/apps2/twofactor_webauthn/vendor/symfony/process/ExecutableFinder.php").allow();
|
||||
sp.disable_function.function("ini_get").param("option").value("open_basedir").filename("/nextcloud/3rdparty/symfony/process/ExecutableFinder.php").allow();
|
||||
sp.disable_function.function("ini_get").param("option").value("allow_url_fopen").filename("/nextcloud/3rdparty/guzzlehttp/guzzle/src/Utils.php").allow();
|
||||
|
||||
# Harden the `chmod` function (0777 (oct = 511, 0666 = 438)
|
||||
sp.disable_function.function("chmod").param("permissions").value("438").drop();
|
||||
sp.disable_function.function("chmod").param("permissions").value("511").drop();
|
||||
|
||||
# Prevent various `mail`-related vulnerabilities
|
||||
sp.disable_function.function("mail").param("additional_parameters").value_r("\\-").drop();
|
||||
|
||||
# Since it's now burned, me might as well mitigate it publicly
|
||||
sp.disable_function.function("putenv").param("assignment").value_r("LD_").drop()
|
||||
|
||||
# This one was burned in Nov 2019 - https://gist.github.com/LoadLow/90b60bd5535d6c3927bb24d5f9955b80
|
||||
sp.disable_function.function("putenv").param("assignment").value_r("GCONV_").drop()
|
||||
|
||||
# Since people are stupid enough to use `extract` on things like $_GET or $_POST, we might as well mitigate this vector
|
||||
sp.disable_function.function("extract").param("array").value_r("^_").drop()
|
||||
sp.disable_function.function("extract").param("flags").value("0").drop()
|
||||
|
||||
# This is also burned:
|
||||
# ini_set('open_basedir','..');chdir('..');…;chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/etc/passwd'));
|
||||
# Since we have no way of matching on two parameters at the same time, we're
|
||||
# blocking calls to open_basedir altogether: nobody is using it via ini_set anyway.
|
||||
# Moreover, there are non-public bypasses that are also using this vector ;)
|
||||
sp.disable_function.function("ini_set").param("option").value_r("open_basedir").drop()
|
||||
|
||||
# Prevent various `include`-related vulnerabilities
|
||||
sp.disable_function.function("require_once").value_r("\.(inc|phtml|php)$").allow();
|
||||
sp.disable_function.function("include_once").value_r("\.(inc|phtml|php)$").allow();
|
||||
sp.disable_function.function("require").value_r("\.(inc|phtml|php)$").allow();
|
||||
sp.disable_function.function("include").value_r("\.(inc|phtml|php)$").allow();
|
||||
sp.disable_function.function("require_once").drop()
|
||||
sp.disable_function.function("include_once").drop()
|
||||
sp.disable_function.function("require").drop()
|
||||
sp.disable_function.function("include").drop()
|
||||
|
||||
# Prevent `system`-related injections
|
||||
sp.disable_function.function("system").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
|
||||
sp.disable_function.function("shell_exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
|
||||
sp.disable_function.function("exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
|
||||
sp.disable_function.function("proc_open").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
|
||||
|
||||
# Prevent runtime modification of interesting things
|
||||
sp.disable_function.function("ini_set").param("option").value("assert.active").drop();
|
||||
sp.disable_function.function("ini_set").param("option").value("zend.assertions").drop();
|
||||
sp.disable_function.function("ini_set").param("option").value("memory_limit").drop();
|
||||
sp.disable_function.function("ini_set").param("option").value("include_path").drop();
|
||||
sp.disable_function.function("ini_set").param("option").value("open_basedir").drop();
|
||||
|
||||
# Detect some backdoors via environment recon
|
||||
sp.disable_function.function("ini_get").param("option").value("allow_url_fopen").drop();
|
||||
sp.disable_function.function("ini_get").param("option").value("open_basedir").drop();
|
||||
sp.disable_function.function("ini_get").param("option").value_r("suhosin").drop();
|
||||
sp.disable_function.function("function_exists").param("function").value("eval").drop();
|
||||
sp.disable_function.function("function_exists").param("function").value("exec").drop();
|
||||
sp.disable_function.function("function_exists").param("function").value("system").drop();
|
||||
sp.disable_function.function("function_exists").param("function").value("shell_exec").drop();
|
||||
sp.disable_function.function("function_exists").param("function").value("proc_open").drop();
|
||||
sp.disable_function.function("function_exists").param("function").value("passthru").drop();
|
||||
sp.disable_function.function("is_callable").param("value").value("eval").drop();
|
||||
sp.disable_function.function("is_callable").param("value").value("exec").drop();
|
||||
sp.disable_function.function("is_callable").param("value").value("system").drop();
|
||||
sp.disable_function.function("is_callable").param("value").value("shell_exec").drop();
|
||||
sp.disable_function.function("is_callable").param("value").value("proc_open").drop();
|
||||
sp.disable_function.function("is_callable").param("value").value("passthru").drop();
|
||||
|
||||
# Ghetto error-based sqli detection
|
||||
# sp.disable_function.function("mysql_query").ret("FALSE").drop();
|
||||
# sp.disable_function.function("mysqli_query").ret("FALSE").drop();
|
||||
# sp.disable_function.function("PDO::query").ret("FALSE").drop();
|
||||
|
||||
# Ensure that certificates are properly verified
|
||||
sp.disable_function.function("curl_setopt").param("value").value("1").allow();
|
||||
sp.disable_function.function("curl_setopt").param("value").value("2").allow();
|
||||
# `81` is SSL_VERIFYHOST and `64` SSL_VERIFYPEER
|
||||
sp.disable_function.function("curl_setopt").param("option").value("64").drop().alias("Please don't turn CURLOPT_SSL_VERIFYCLIENT off.");
|
||||
sp.disable_function.function("curl_setopt").param("option").value("81").drop().alias("Please don't turn CURLOPT_SSL_VERIFYHOST off.");
|
||||
|
||||
# File upload
|
||||
sp.disable_function.function("move_uploaded_file").param("to").value_r("\\.ph").drop();
|
||||
sp.disable_function.function("move_uploaded_file").param("to").value_r("\\.ht").drop();
|
||||
|
||||
# Logging lockdown
|
||||
sp.disable_function.function("ini_set").param("option").value_r("error_log").drop()
|
||||
sp.disable_function.function("ini_set").param("option").value_r("error_reporting").drop()
|
||||
sp.disable_function.function("ini_set").param("option").value_r("display_errors").drop()
|
2
rootfs/usr/local/etc/php/snuffleupagus/snuffleupagus.ini
Normal file
2
rootfs/usr/local/etc/php/snuffleupagus/snuffleupagus.ini
Normal file
@ -0,0 +1,2 @@
|
||||
extension=snuffleupagus.so
|
||||
sp.configuration_file=/usr/local/etc/php/conf.d/nextcloud-php8.rules
|
Loading…
x
Reference in New Issue
Block a user