From 2d8efa1787ffa56dfc78edb62f4dbc94c1c9450e Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Wed, 21 Aug 2019 03:19:29 +0200 Subject: Change to system-wide Apache installation --- 2.4/Dockerfile | 85 ++++++++++++++++--------------- 2.4/conf/conf-available/dav.conf | 6 +-- 2.4/docker-entrypoint.sh | 90 +++++--------------------------- LICENSE | 21 -------- README.md | 107 --------------------------------------- 5 files changed, 60 insertions(+), 249 deletions(-) delete mode 100644 LICENSE delete mode 100644 README.md diff --git a/2.4/Dockerfile b/2.4/Dockerfile index 4645a3f..26757fc 100644 --- a/2.4/Dockerfile +++ b/2.4/Dockerfile @@ -1,4 +1,4 @@ -FROM httpd:alpine +FROM alpine:latest ARG ENABLE_PROXY=0 ARG ENABLE_PHP=0 @@ -7,30 +7,18 @@ ARG ENABLE_DAV=0 ARG EXTRA_PACKAGES="" ARG EXTRA_MODULES="" -# These variables are inherited from the httpd:alpine image: -# ENV HTTPD_PREFIX /usr/local/apache2 -# WORKDIR "$HTTPD_PREFIX" - -COPY conf/ conf/ -COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh +COPY conf/ /tmp/conf +COPY docker-entrypoint.sh /docker-entrypoint.sh RUN set -ex; \ - # Install openssl if we need to generate a self-signed certificate. - packages="${EXTRA_PACKAGES} openssl apr-util-dbm_db"; \ + # Install packages + packages="${EXTRA_PACKAGES} apache2 libxml2-dev apache2-utils apr-util-dbm_db"; \ if [ ${ENABLE_PHP} -ne 0 ]; then \ packages="$packages php7-apache2"; \ fi; \ - apk add --no-cache $packages; \ - # Create empty default DocumentRoot. - mkdir -p "/var/www/html"; \ - # Create directories for Dav data and lock database. - mkdir -p "/var/lib/dav/data"; \ + apk update && apk upgrade && apk add --no-cache $packages; \ \ - # Configure port - sed -i -e "s|Listen .*|Listen 8080|" "conf/httpd.conf"; \ - # Configure file paths - sed -i -e "s|PidFile .*|PidFile /tmp/apache.pid|" "conf/extra/httpd-mpm.conf"; \ - # Make sure authentication modules are enabled. + # Enable optional modules modules="${EXTRA_MODULES} authn_core authn_file authz_core authz_user auth_basic auth_digest alias headers mime setenvif"; \ if [ ${ENABLE_PROXY} -ne 0 ]; then \ modules="$modules rewrite proxy proxy_http"; \ @@ -38,36 +26,49 @@ RUN set -ex; \ if [ ${ENABLE_DAV} -ne 0 ]; then \ modules="$modules dav dav_fs"; \ fi; \ - if [ ${ENABLE_PHP} -ne 0 ]; then \ - modules="$modules php7"; \ - fi; \ for i in $modules; do \ - sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "conf/httpd.conf"; \ + sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "/etc/apache2/httpd.conf"; \ done; \ \ + # Create empty default DocumentRoot. + mkdir -p "/var/www/html"; \ + # Create directories for Dav data and lock database. + mkdir -p "/var/dav/data"; \ + \ + # Configure port + sed -i -e "s|Listen .*|Listen 8080|" "/etc/apache2/httpd.conf"; \ + sed -i -e "s|PidFile .*|PidFile /tmp/apache.pid|" "/etc/apache2/conf.d/mpm.conf"; \ + \ # Include enabled configs and sites. - printf '%s\n' "PidFile /tmp/httpd.pid" \ - >> "conf/httpd.conf"; \ - printf '%s\n' "Include conf/sites-enabled/*.conf" \ - >> "conf/httpd.conf"; \ - printf '%s\n' "Include conf/conf-enabled/*.conf" \ - >> "conf/httpd.conf"; \ - # Enable module configuration and default site. + printf '%s\n' "IncludeOptional /tmp/conf/sites-enabled/*.conf" \ + >> "/etc/apache2/httpd.conf"; \ + printf '%s\n' "IncludeOptional /tmp/conf/conf-enabled/*.conf" \ + >> "/etc/apache2/httpd.conf"; \ \ - have_conf=0; \ - mkdir -p "conf/conf-enabled"; \ - mkdir -p "conf/sites-enabled"; \ + # Enable module configuration and default site. + mkdir -p "/tmp/conf/conf-enabled"; \ + mkdir -p "/tmp/conf/sites-enabled"; \ + ln -s ../sites-available/default.conf "/tmp/conf/sites-enabled"; \ for i in $modules; do \ - if [ -f conf/conf-available/${i}.conf ]; then \ - have_conf=1; \ - ln -s ../conf-available/${i}.conf "conf/conf-enabled"; \ + if [ -f /etc/apache2/conf-available/${i}.conf ]; then \ + ln -s ../conf-available/${i}.conf "/tmp/conf/conf-enabled"; \ fi; \ done; \ - ln -s ../sites-available/default.conf "conf/sites-enabled"; \ - if [ $have_conf -eq 0 ]; then \ - touch conf/conf-enabled/dummy.conf ;\ - fi + \ + # Remove extra configs + #rm /etc/apache2/conf.d/default.conf; \ + rm /etc/apache2/conf.d/info.conf; \ + rm /etc/apache2/conf.d/languages.conf; \ + #rm /etc/apache2/conf.d/mpm.conf; \ + rm /etc/apache2/conf.d/userdir.conf; \ + \ + # Allow scripts to alter configuration + chmod -R g=u /tmp/conf; \ + chmod g=u /etc/passwd + +VOLUME /var/dav/data +VOLUME /var/www/html EXPOSE 8080/tcp 8043/tcp -ENTRYPOINT [ "docker-entrypoint.sh" ] -CMD [ "httpd-foreground" ] +ENTRYPOINT [ "/docker-entrypoint.sh" ] +CMD [ "httpd", "-DFOREGROUND" ] diff --git a/2.4/conf/conf-available/dav.conf b/2.4/conf/conf-available/dav.conf index bb0924c..4f4f0d4 100644 --- a/2.4/conf/conf-available/dav.conf +++ b/2.4/conf/conf-available/dav.conf @@ -1,12 +1,12 @@ DavLockDB "/tmp/DavLock" -Alias / "/var/lib/dav/data/" - +Alias / "/var/dav/data/" + Dav On Options Indexes FollowSymLinks AuthType Basic AuthName "WebDAV" - AuthUserFile "/tmp/user.passwd" + AuthUserFile "/tmp/conf/user.passwd" Require valid-user diff --git a/2.4/docker-entrypoint.sh b/2.4/docker-entrypoint.sh index cab689a..d565765 100755 --- a/2.4/docker-entrypoint.sh +++ b/2.4/docker-entrypoint.sh @@ -1,56 +1,10 @@ #!/bin/sh set -e -# Environment variables that are used if not empty: -# SERVER_NAMES -# LOCATION -# AUTH_TYPE -# REALM -# USERNAME -# PASSWORD -# ANONYMOUS_METHODS -# SSL_CERT - -# Just in case this environment variable has gone missing. -HTTPD_PREFIX="${HTTPD_PREFIX:-/usr/local/apache2}" - -# Configure vhosts. -if [ "x$SERVER_NAMES" != "x" ]; then - # Use first domain as Apache ServerName. - SERVER_NAME="${SERVER_NAMES%%,*}" - sed -e "s|ServerName .*|ServerName $SERVER_NAME|" \ - -i "$HTTPD_PREFIX"/conf/sites-available/default*.conf - - # Replace commas with spaces and set as Apache ServerAlias. - SERVER_ALIAS="`printf '%s\n' "$SERVER_NAMES" | tr ',' ' '`" - sed -e "/ServerName/a\ \ ServerAlias $SERVER_ALIAS" \ - -i "$HTTPD_PREFIX"/conf/sites-available/default*.conf -fi - -# Configure dav.conf -if [ "x$LOCATION" != "x" ]; then - sed -e "s|Alias .*|Alias $LOCATION /var/lib/dav/data/|" \ - -i "$HTTPD_PREFIX/conf/conf-available/dav.conf" -fi -if [ "x$REALM" != "x" ]; then - sed -e "s|AuthName .*|AuthName \"$REALM\"|" \ - -i "$HTTPD_PREFIX/conf/conf-available/dav.conf" -else - REALM="WebDAV" -fi -if [ "x$AUTH_TYPE" != "x" ]; then - # Only support "Basic" and "Digest". - if [ "$AUTH_TYPE" != "Basic" ] && [ "$AUTH_TYPE" != "Digest" ]; then - printf '%s\n' "$AUTH_TYPE: Unknown AuthType" 1>&2 - exit 1 - fi - sed -e "s|AuthType .*|AuthType $AUTH_TYPE|" \ - -i "$HTTPD_PREFIX/conf/conf-available/dav.conf" -fi - # Add password hash, unless "user.passwd" already exists (ie, bind mounted). -if [ ! -e "/tmp/user.passwd" ]; then - touch "/tmp/user.passwd" +REALM="WebDAV" +if [ ! -e "/tmp/conf/user.passwd" ]; then + touch "/tmp/conf/user.passwd" # Only generate a password hash if both username and password given. if [ "x$USERNAME" != "x" ] && [ "x$PASSWORD" != "x" ]; then if [ "$AUTH_TYPE" = "Digest" ]; then @@ -58,7 +12,7 @@ if [ ! -e "/tmp/user.passwd" ]; then HASH="`printf '%s' "$USERNAME:$REALM:$PASSWORD" | md5sum | awk '{print $1}'`" printf '%s\n' "$USERNAME:$REALM:$HASH" > /tmp/user.passwd else - htpasswd -B -b -c "/tmp/user.passwd" $USERNAME $PASSWORD + htpasswd -B -b -c "/tmp/conf/user.passwd" $USERNAME $PASSWORD fi fi fi @@ -67,39 +21,23 @@ fi if [ "x$ANONYMOUS_METHODS" != "x" ]; then if [ "$ANONYMOUS_METHODS" = "ALL" ]; then sed -e "s/Require valid-user/Require all granted/" \ - -i "$HTTPD_PREFIX/conf/conf-available/dav.conf" + -i "/tmp/conf/conf-available/dav.conf" else ANONYMOUS_METHODS="`printf '%s\n' "$ANONYMOUS_METHODS" | tr ',' ' '`" sed -e "/Require valid-user/a\ \ \ \ Require method $ANONYMOUS_METHODS" \ - -i "$HTTPD_PREFIX/conf/conf-available/dav.conf" + -i "/tmp/conf/conf-available/dav.conf" fi fi -# If specified, generate a selfsigned certificate. -if [ "${SSL_CERT:-none}" = "selfsigned" ]; then - # Generate self-signed SSL certificate. - # If SERVER_NAMES is given, use the first domain as the Common Name. - if [ ! -e /privkey.pem ] || [ ! -e /cert.pem ]; then - openssl req -x509 -newkey rsa:2048 -days 1000 -nodes \ - -keyout /privkey.pem -out /cert.pem -subj "/CN=${SERVER_NAME:-selfsigned}" - fi -fi - -# This will either be the self-signed certificate generated above or one that -# has been bind mounted in by the user. -if [ -e /privkey.pem ] && [ -e /cert.pem ]; then - # Enable SSL Apache modules. - for i in http2 ssl; do - sed -e "/^#LoadModule ${i}_module.*/s/^#//" \ - -i "$HTTPD_PREFIX/conf/httpd.conf" - done - # Enable SSL vhost. - ln -sf ../sites-available/default-ssl.conf \ - "$HTTPD_PREFIX/conf/sites-enabled" -fi - # Create directories for Dav data and lock database. -[ ! -d "/var/lib/dav/data" ] && mkdir -p "/var/lib/dav/data" +[ ! -d "/var/dav/data" ] && mkdir -p "/var/dav/data" [ ! -e "/tmp/DavLock" ] && touch "/tmp/DavLock" + +if ! whoami &> /dev/null; then + if [ -w /etc/passwd ]; then + echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd + fi +fi + exec "$@" diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 13b6351..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Bytemark Hosting - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index f9b9e8e..0000000 --- a/README.md +++ /dev/null @@ -1,107 +0,0 @@ -## Supported tags - -* [`2.4`, `latest` (*2.4/Dockerfile*)](https://github.com/BytemarkHosting/docker-webdav/blob/master/2.4/Dockerfile) - -## Quick reference - -This image runs an easily configurable WebDAV server with Apache. - -You can configure the authentication type, the authentication of multiple users, or to run with a self-signed SSL certificate. If you want a Let's Encrypt certificate, see an example of how to do that [here](https://github.com/BytemarkHosting/configs-webdav-docker). - -* **Code repository:** - https://github.com/BytemarkHosting/docker-webdav -* **Where to file issues:** - https://github.com/BytemarkHosting/docker-webdav/issues -* **Maintained by:** - [Bytemark Hosting](https://www.bytemark.co.uk) -* **Supported architectures:** - [Any architecture that the `httpd` image supports](https://hub.docker.com/_/httpd/) - -## Usage - -### Basic WebDAV server - -This example starts a WebDAV server on port 80. It can only be accessed with a single username and password. - -When using unencrypted HTTP, use `Digest` authentication (instead of `Basic`) to avoid sending plaintext passwords in the clear. - -To make sure your data doesn't get deleted, you'll probably want to create a persistent storage volume (`-v vol-webdav:/var/lib/dav`) or bind mount a directory (`-v /path/to/directory:/var/lib/dav`): - -``` -docker run --restart always -v /srv/dav:/var/lib/dav \ - -e AUTH_TYPE=Digest -e USERNAME=alice -e PASSWORD=secret1234 \ - --publish 80:80 -d bytemark/webdav - -``` - -#### Via Docker Compose: - -``` -version: '3' -services: - webdav: - image: bytemark/webdav - restart: always - ports: - - "80:80" - environment: - AUTH_TYPE: Digest - USERNAME: alice - PASSWORD: secret1234 - volumes: - - /srv/dav:/var/lib/dav - -``` -### Secure WebDAV with SSL - -We recommend you use a reverse proxy (eg, Traefik) to handle SSL certificates. You can see an example of how to do that [here](https://github.com/BytemarkHosting/configs-webdav-docker). - -If you're happy with a self-signed SSL certificate, specify `-e SSL_CERT=selfsigned` and the container will generate one for you. - -``` -docker run --restart always -v /srv/dav:/var/lib/dav \ - -e AUTH_TYPE=Basic -e USERNAME=test -e PASSWORD=test \ - -e SSL_CERT=selfsigned --publish 443:443 -d bytemark/webdav - -``` - -If you bind mount a certificate chain to `/cert.pem` and a private key to `/privkey.pem`, the container will use that instead! - -### Authenticate multiple clients - -Specifying `USERNAME` and `PASSWORD` only supports a single user. If you want to have lots of different logins for various users, bind mount your own file to `/user.passwd` and the container will use that instead. - -If using `Basic` authentication, run the following commands: - -``` -touch user.passwd -htpasswd -B user.passwd alice -htpasswd -B user.passwd bob - -``` - -If using `Digest` authentication, run the following commands. (NB: The default `REALM` is `WebDAV`. If you specify your own `REALM`, you'll need to run `htdigest` again with the new name.) - - -``` -touch user.passwd -htdigest user.passwd WebDAV alice -htdigest user.passwd WebDAV bob - -``` - -Once you've created your own `user.passwd`, bind mount it into your container with `-v /path/to/user.passwd:/user.passwd`. - -### Environment variables - -All environment variables are optional. You probably want to at least specify `USERNAME` and `PASSWORD` (or bind mount your own authentication file to `/user.passwd`) otherwise nobody will be able to access your WebDAV server! - -* **`SERVER_NAMES`**: Comma-separated list of domains (eg, `example.com,www.example.com`). The first is set as the [ServerName](https://httpd.apache.org/docs/current/mod/core.html#servername), and the rest (if any) are set as [ServerAlias](https://httpd.apache.org/docs/current/mod/core.html#serveralias). The default is `localhost`. -* **`LOCATION`**: The URL path for WebDAV (eg, if set to `/webdav` then clients should connect to `example.com/webdav`). The default is `/`. -* **`AUTH_TYPE`**: Apache authentication type to use. This can be `Basic` (best choice for HTTPS) or `Digest` (best choice for HTTP). The default is `Basic`. -* **`REALM`**: Sets [AuthName](https://httpd.apache.org/docs/current/mod/mod_authn_core.html#authname), an identifier that is displayed to clients when they connect. The default is `WebDAV`. -* **`USERNAME`**: Authenticate with this username (and the password below). This is ignored if you bind mount your own authentication file to `/user.passwd`. -* **`PASSWORD`**: Authenticate with this password (and the username above). This is ignored if you bind mount your own authentication file to `/user.passwd`. -* **`ANONYMOUS_METHODS`**: Comma-separated list of HTTP request methods (eg, `GET,POST,OPTIONS,PROPFIND`). Clients can use any method you specify here without authentication. Set to `ALL` to disable authentication. The default is to disallow any anonymous access. -* **`SSL_CERT`**: Set to `selfsigned` to generate a self-signed certificate and enable Apache's SSL module. If you specify `SERVER_NAMES`, the first domain is set as the Common Name. - -- cgit v1.2.1