diff --git a/.drone.yml b/.drone.yml
index 22779d1..bed6b91 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -6,7 +6,7 @@ steps:
- name: build image only
image: plugins/docker
settings:
- repo: eumau/openvpn
+ repo: eumau/webdav
auto_tag: true
dry_run: true
when:
@@ -16,7 +16,7 @@ steps:
- name: build and publish image
image: plugins/docker
settings:
- repo: eumau/openvpn
+ repo: eumau/webdav
auto_tag: true
username:
from_secret: dockerhub_username
diff --git a/Dockerfile b/Dockerfile
index 6c01a20..4f80864 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,17 +1,13 @@
-FROM debian:buster-slim
-ARG REMCO_VER=0.11.1
-RUN apt-get update \
- && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
- openvpn unzip wget ca-certificates \
- && wget https://github.com/HeavyHorst/remco/releases/download/v${REMCO_VER}/remco_${REMCO_VER}_linux_amd64.zip \
- && unzip remco_${REMCO_VER}_linux_amd64.zip \
- && rm remco_${REMCO_VER}_linux_amd64.zip \
- && mv remco_linux /bin/remco \
- && apt-get purge -y unzip wget ca-certificates \
- && apt-get autoremove --purge -y \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+FROM golang AS remco
+RUN go install github.com/HeavyHorst/remco/cmd/remco@latest
+
+FROM httpd
+COPY --from=remco /go/bin/remco /usr/local/bin/remco
COPY config /etc/remco/config
-COPY openvpn_setup.tmpl /etc/remco/templates/openvpn_setup.tmpl
+COPY *.tmpl /etc/remco/templates/
+
+EXPOSE 80
+CMD ["httpd-foreground"]
+
ENTRYPOINT ["remco"]
diff --git a/README.md b/README.md
index 5519fab..517fe71 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,3 @@
-# OpenVPN Docker image
+# WebDAV Server with LDAP Authentication
-This Docker image runs OpenVPN inside Docker. Configuration is done
-via environment variables.
+This Docker image runs an Apache server with WebDAV capabilities and LDAP authentication. Configuration is done via environment variables.
diff --git a/config b/config
index 1e83b08..10bfa0d 100644
--- a/config
+++ b/config
@@ -2,19 +2,24 @@ log_level = "info"
log_format = "text"
[[resource]]
-name = "opendkim"
-start_cmd = "/usr/local/sbin/openvpn_setup"
+name = "httpd"
+start_cmd = "/usr/local/sbin/setup.sh"
[resource.exec]
-command = "/usr/sbin/openvpn --config /etc/openvpn.conf"
+command = "/usr/local/bin/httpd-foreground"
[[resource.template]]
-src = "/etc/remco/templates/openvpn_setup.tmpl"
-dst = "/usr/local/sbin/openvpn_setup"
-mode = "0700"
+src = "/etc/remco/templates/httpd.conf.tmpl"
+dst = "/usr/local/apache2/conf/httpd.conf"
+mode = "0644"
+
+[[resource.template]]
+src = "/etc/remco/templates/setup.sh.tmpl"
+dst = "/usr/local/sbin/setup.sh"
+mode = "0755"
[resource.backend]
[resource.backend.env]
-keys = ["/openvpn"]
+keys = ["/webdav","/ldap"]
watch = false
onetime = true
diff --git a/docker-compose.sample.yml b/docker-compose.sample.yml
index ef98ce0..f23c44d 100644
--- a/docker-compose.sample.yml
+++ b/docker-compose.sample.yml
@@ -1,25 +1,18 @@
---
version: "3.5"
services:
- openvpn:
+ webdav:
build: .
- cap_add:
- - NET_ADMIN
- labels:
- - traefik.enable=false
environment:
- OPENVPN_MODE: client
- OPENVPN_DEV: tun
- OPENVPN_REMOTE: ${OPENVPN_REMOTE}
- OPENVPN_NOBIND: "yes"
- OPENVPN_COMP_LZO: "yes"
- OPENVPN_NS_CERT_TYPE: server
- OPENVPN_TLS_CLIENT: "yes"
- # OPENVPN_TA: ${OPENVPN_TA}
- # OPENVPN_TA_DIR: "1"
- OPENVPN_CA: ${OPENVPN_CA}
- OPENVPN_KEY: ${OPENVPN_KEY}
- OPENVPN_CERT: ${OPENVPN_CERT}
- OPENVPN_VERB: 3
+ WEBDAV_LOCK: ${WEBDAV_LOCK_DIR}/DavLock
+ WEBDAV_PATH: ${WEBDAV_PATH}
+ WEBDAV_DIR: ${WEBDAV_DIR}
+ WEBDAV_LDAP_URL: ${WEBDAV_LDAP_URL}
volumes:
- - /dev/net/tun:/dev/net/tun
+ - dav:${WEBDAV_DIR}
+ - lock:${WEBDAV_LOCK_DIR}
+ labels:
+ - traefik.http.routers.dav.rule=Host(`dav.example.com`)
+ - traefik.http.routers.dav.middlewares=dav
+ - traefik.http.middlewares.dav.redirectregex.regex=^https?://dav.example.com/.well-known/(card|cal)dav.*$$
+ - traefik.http.middlewares.dav.redirectregex.replacement=https://dav.example.com/
diff --git a/httpd.conf.tmpl b/httpd.conf.tmpl
new file mode 100644
index 0000000..3caf98c
--- /dev/null
+++ b/httpd.conf.tmpl
@@ -0,0 +1,298 @@
+ServerRoot "/usr/local/apache2"
+Listen 80
+
+LoadModule mpm_event_module modules/mod_mpm_event.so
+LoadModule authn_file_module modules/mod_authn_file.so
+LoadModule authn_core_module modules/mod_authn_core.so
+LoadModule authz_host_module modules/mod_authz_host.so
+LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
+LoadModule authz_user_module modules/mod_authz_user.so
+LoadModule authz_core_module modules/mod_authz_core.so
+LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
+LoadModule access_compat_module modules/mod_access_compat.so
+LoadModule auth_basic_module modules/mod_auth_basic.so
+LoadModule reqtimeout_module modules/mod_reqtimeout.so
+LoadModule filter_module modules/mod_filter.so
+LoadModule mime_module modules/mod_mime.so
+LoadModule ldap_module modules/mod_ldap.so
+LoadModule log_config_module modules/mod_log_config.so
+LoadModule env_module modules/mod_env.so
+LoadModule headers_module modules/mod_headers.so
+LoadModule setenvif_module modules/mod_setenvif.so
+LoadModule version_module modules/mod_version.so
+LoadModule unixd_module modules/mod_unixd.so
+LoadModule dav_module modules/mod_dav.so
+LoadModule status_module modules/mod_status.so
+LoadModule autoindex_module modules/mod_autoindex.so
+
+ #LoadModule cgid_module modules/mod_cgid.so
+
+
+ #LoadModule cgi_module modules/mod_cgi.so
+
+LoadModule dav_fs_module modules/mod_dav_fs.so
+LoadModule dav_lock_module modules/mod_dav_lock.so
+LoadModule dir_module modules/mod_dir.so
+LoadModule alias_module modules/mod_alias.so
+LoadModule rewrite_module modules/mod_rewrite.so
+
+
+User www-data
+Group www-data
+
+
+#
+# ServerAdmin: Your address, where problems with the server should be
+# e-mailed. This address appears on some server-generated pages, such
+# as error documents. e.g. admin@your-domain.com
+#
+ServerAdmin {{ getv("/webdav/server/admin", "admin@example.com") }}
+
+#
+# ServerName gives the name and port that the server uses to identify itself.
+# This can often be determined automatically, but we recommend you specify
+# it explicitly to prevent problems during startup.
+#
+# If your host doesn't have a registered DNS name, enter its IP address here.
+#
+#ServerName www.example.com:80
+
+
+ AllowOverride none
+ Require all denied
+
+
+DocumentRoot "/usr/local/apache2/htdocs"
+
+ #
+ # Possible values for the Options directive are "None", "All",
+ # or any combination of:
+ # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
+ #
+ # Note that "MultiViews" must be named *explicitly* --- "Options All"
+ # doesn't give it to you.
+ #
+ # The Options directive is both complicated and important. Please see
+ # http://httpd.apache.org/docs/2.4/mod/core.html#options
+ # for more information.
+ #
+ Options Indexes FollowSymLinks
+
+ #
+ # AllowOverride controls what directives may be placed in .htaccess files.
+ # It can be "All", "None", or any combination of the keywords:
+ # AllowOverride FileInfo AuthConfig Limit
+ #
+ AllowOverride None
+
+ #
+ # Controls who can get stuff from this server.
+ #
+ Require all granted
+
+
+#
+# DirectoryIndex: sets the file that Apache will serve if a directory
+# is requested.
+#
+
+ DirectoryIndex index.html
+
+
+#
+# The following lines prevent .htaccess and .htpasswd files from being
+# viewed by Web clients.
+#
+
+ Require all denied
+
+
+#
+# ErrorLog: The location of the error log file.
+# If you do not specify an ErrorLog directive within a
+# container, error messages relating to that virtual host will be
+# logged here. If you *do* define an error logfile for a
+# container, that host's errors will be logged there and not here.
+#
+ErrorLog /proc/self/fd/2
+
+#
+# LogLevel: Control the number of messages logged to the error_log.
+# Possible values include: debug, info, notice, warn, error, crit,
+# alert, emerg.
+#
+LogLevel warn
+
+
+ #
+ # The following directives define some format nicknames for use with
+ # a CustomLog directive (see below).
+ #
+ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+ LogFormat "%h %l %u %t \"%r\" %>s %b" common
+
+
+ # You need to enable mod_logio.c to use %I and %O
+ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
+
+
+ #
+ # The location and format of the access logfile (Common Logfile Format).
+ # If you do not define any access logfiles within a
+ # container, they will be logged here. Contrariwise, if you *do*
+ # define per- access logfiles, transactions will be
+ # logged therein and *not* in this file.
+ #
+ CustomLog /proc/self/fd/1 common
+
+ #
+ # If you prefer a logfile with access, agent, and referer information
+ # (Combined Logfile Format) you can use the following directive.
+ #
+ #CustomLog "logs/access_log" combined
+
+
+
+ #
+ # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied
+ # backend servers which have lingering "httpoxy" defects.
+ # 'Proxy' request header is undefined by the IETF, not listed by IANA
+ #
+ RequestHeader unset Proxy early
+
+
+
+ #
+ # TypesConfig points to the file containing the list of mappings from
+ # filename extension to MIME-type.
+ #
+ TypesConfig conf/mime.types
+
+ #
+ # AddType allows you to add to or override the MIME configuration
+ # file specified in TypesConfig for specific file types.
+ #
+ #AddType application/x-gzip .tgz
+ #
+ # AddEncoding allows you to have certain browsers uncompress
+ # information on the fly. Note: Not all browsers support this.
+ #
+ #AddEncoding x-compress .Z
+ #AddEncoding x-gzip .gz .tgz
+ #
+ # If the AddEncoding directives above are commented-out, then you
+ # probably should define those extensions to indicate media types:
+ #
+ AddType application/x-compress .Z
+ AddType application/x-gzip .gz .tgz
+
+ #
+ # AddHandler allows you to map certain file extensions to "handlers":
+ # actions unrelated to filetype. These can be either built into the server
+ # or added with the Action directive (see below)
+ #
+ # To use CGI scripts outside of ScriptAliased directories:
+ # (You will also need to add "ExecCGI" to the "Options" directive.)
+ #
+ #AddHandler cgi-script .cgi
+
+ # For type maps (negotiated resources):
+ #AddHandler type-map var
+
+ #
+ # Filters allow you to process content before it is sent to the client.
+ #
+ # To parse .shtml files for server-side includes (SSI):
+ # (You will also need to add "Includes" to the "Options" directive.)
+ #
+ #AddType text/html .shtml
+ #AddOutputFilter INCLUDES .shtml
+
+
+
+# Required modules: mod_alias, mod_auth_digest, mod_authn_core, mod_authn_file,
+# mod_authz_core, mod_authz_user, mod_dav, mod_dav_fs,
+# mod_setenvif
+
+# Enable the LDAP connection pool and shared
+# memory cache. Enable the LDAP cache status
+# handler. Requires that mod_ldap and mod_authnz_ldap
+# be loaded. Change the "yourdomain.example.com" to
+# match your domain.
+
+LDAPSharedCacheSize 500000
+LDAPCacheEntries 1024
+LDAPCacheTTL 600
+LDAPOpCacheEntries 1024
+LDAPOpCacheTTL 600
+
+# The following example gives DAV write access to a directory called
+# "uploads" under the ServerRoot directory.
+#
+# The User/Group specified in httpd.conf needs to have write permissions
+# on the directory where the DavLockDB is placed and on any directory where
+# "Dav On" is specified.
+
+DavLockDB "{{ getv("/webdav/lock", "/usr/local/apache2/var/DavLock") }}"
+
+Alias {{ getv("/webdav/path", "/") }} "{{ getv("/webdav/dir", "/usr/local/apache2/uploads/") }}"
+
+
+ Dav On
+
+ AuthType {{ getv("/webdav/auth/type", "Basic") }}
+ AuthName {{ getv("/webdav/auth/name", "WebDAV") }}
+
+ AuthBasicProvider ldap
+ AuthLDAPURL "{{ getv("/webdav/ldap/url", "ldap://ldap/dc=example,dc=com?uid?one") }}"
+
+ # Allow universal read-access, but writes are restricted
+ # to the admin user.
+
+ {% if eq (getv("/webdav/public/read", "false"), "true") %}
+
+ Require method GET POST OPTIONS
+ Require valid-user
+
+ {% else %}
+ Require valid-user
+ {% endif %}
+
+
+
+ SetHandler ldap-status
+ # Require host yourdomain.example.com
+
+ Satisfy any
+ AuthType Basic
+ AuthName "LDAP Status"
+ AuthBasicProvider ldap
+ AuthLDAPURL "{{ getv("/webdav/ldap/url", "ldap://ldap/dc=example,dc=com?uid?one") }}"
+ Require valid-user
+
+
+#
+# The following directives disable redirects on non-GET requests for
+# a directory that does not include the trailing slash. This fixes a
+# problem with several clients that do not appropriately handle
+# redirects for folders with DAV methods.
+#
+BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
+BrowserMatch "MS FrontPage" redirect-carefully
+BrowserMatch "^WebDrive" redirect-carefully
+BrowserMatch "^WebDAVFS/1.[01234]" redirect-carefully
+BrowserMatch "^gnome-vfs/1.0" redirect-carefully
+BrowserMatch "^XML Spy" redirect-carefully
+BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully
+BrowserMatch " Konqueror/4" redirect-carefully
+
+# Configure mod_proxy_html to understand HTML4/XHTML1
+
+Include conf/extra/proxy-html.conf
+
+
+# Secure (SSL/TLS) connections
+
+SSLRandomSeed startup builtin
+SSLRandomSeed connect builtin
+
diff --git a/openvpn_setup.tmpl b/openvpn_setup.tmpl
deleted file mode 100644
index 7431894..0000000
--- a/openvpn_setup.tmpl
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/bin/bash
-
-# setup openvpn configuration and secrets
-mkdir -p /etc/openvpn
-
-cat - < /etc/openvpn.conf
-
-# client
-{% if exists("/openvpn/mode") %}
-{{ getv("/openvpn/mode") }}
-{% endif %}
-
-# dev tun
-{% if exists("/openvpn/dev") %}
-dev {{ getv("/openvpn/dev") }}
-{% endif %}
-
-# remote
-{% if exists("/openvpn/remote") %}
-remote {{ getv("/openvpn/remote") }}
-{% endif %}
-
-# proto udp
-{% if exists("/openvpn/proto") %}
-proto {{ getv("/openvpn/proto") }}
-{% endif %}
-
-# nobind
-{% if exists("/openvpn/nobind") %}
-nobind
-{% endif %}
-
-# ns-cert-type server
-{% if exists("/openvpn/ns/cert/type") %}
-ns-cert-type {{ getv("/openvpn/ns/cert/type") }}
-{% endif %}
-
-# up /etc/openvpn/update-resolv-conf
-{% if exists("/openvpn/up") %}
-up {{ getv("/openvpn/up") }}
-{% endif %}
-
-# down /etc/openvpn/update-resolv-conf
-{% if exists("/openvpn/down") %}
-down {{ getv("/openvpn/down") }}
-{% endif %}
-
-# tls-client
-{% if exists("/openvpn/tls/client") %}
-tls-client
-{% endif %}
-
-# tls-auth file 1
-{% if exists("/openvpn/ta") %}
-tls-auth /etc/openvpn/ta {{ getv("/openvpn/ta/dir")|default:"1" }}
-{% endif %}
-
-# ca
-ca /etc/openvpn/ca
-
-# cert
-cert /etc/openvpn/cert
-
-# key
-key /etc/openvpn/key
-
-# port 1194
-{% if exists("/openvpn/port") %}
-port {{ getv("/openvpn/port") }}
-{% endif %}
-
-{% if exists("/openvpn/user") %}
-user {{ getv("/openvpn/user") }}
-{% else %}
-user nobody
-{% endif %}
-
-{% if exists("/openvpn/group") %}
-group {{ getv("/openvpn/group") }}
-{% else %}
-group nogroup
-{% endif %}
-
-# comp-lzo
-{% if exists("/openvpn/comp/lzo") %}
-comp-lzo
-{% endif %}
-
-# ping 15
-{% if exists("/openvpn/ping") %}
-ping {{ getv("/openvpn/ping") }}
-{% endif %}
-
-# ping-restart 45
-{% if exists("/openvpn/ping/restart") %}
-ping-restart {{ getv("/openvpn/ping/restart") }}
-{% endif %}
-
-# ping-timer-rem
-{% if exists("/openvpn/ping/timer/rem") %}
-ping-timer-rem
-{% endif %}
-
-# persist-tun
-{% if exists("/openvpn/persist/tun") %}
-persist-tun
-{% endif %}
-
-# persist-remote-ip
-{% if exists("/openvpn/persist/remote/ip") %}
-persist-remote-ip
-{% endif %}
-
-# persist-key
-{% if exists("/openvpn/persist/key") %}
-persist-key
-{% endif %}
-
-# verb 4
-{% if exists("/openvpn/verb") %}
-verb {{ getv("/openvpn/verb") }}
-{% endif %}
-
-# redirect-gateway def1
-{% if exists("/openvpn/redirect/gateway") %}
-redirect-gateway {{ getv("/openvpn/redirect/gateway") }}
-{% endif %}
-EOF
-
-{% if exists("/openvpn/ta") %}
-cat - < /etc/openvpn/ta
-{% for keyline in (replace(getv("/openvpn/ta"),"\\n","!",-1)|split:"!") %}
-{{ keyline }}
-{% endfor %}
-EOKEY
-chmod 600 /etc/openvpn/ta
-{% endif %}
-
-cat - < /etc/openvpn/ca
-{% for keyline in (replace(getv("/openvpn/ca"),"\\n","!",-1)|split:"!") %}
-{{ keyline }}
-{% endfor %}
-EOKEY
-
-cat - < /etc/openvpn/cert
-{% for keyline in (replace(getv("/openvpn/cert"),"\\n","!",-1)|split:"!") %}
-{{ keyline }}
-{% endfor %}
-EOKEY
-
-cat - < /etc/openvpn/key
-{% for keyline in (replace(getv("/openvpn/key"),"\\n","!",-1)|split:"!") %}
-{{ keyline }}
-{% endfor %}
-EOKEY
-chmod 600 /etc/openvpn/key
diff --git a/setup.sh.tmpl b/setup.sh.tmpl
new file mode 100644
index 0000000..d477c12
--- /dev/null
+++ b/setup.sh.tmpl
@@ -0,0 +1,5 @@
+#!/bin/bash
+mkdir -p "{{ getv("/webdav/root/dir", "/usr/local/apache2/uploads") }}"
+chown -R www-data:www-data "{{ getv("/webdav/root/dir", "/usr/local/apache2/uploads") }}"
+mkdir -p "$(dirname "{{ getv("/webdav/lock/path", "/usr/local/apache2/var/DavLock") }}")"
+chown -R www-data:www-data "$(dirname "{{ getv("/webdav/lock/path", "/usr/local/apache2/var/DavLock") }}")"