commit 2c2fce378b07913288422d59e3101a79c6e73131 Author: Roman Vaníček Date: Mon Jan 16 09:30:40 2023 +0100 Backuppc that breaks its config parenthesis (starts only once, no restart). diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..ab0393c --- /dev/null +++ b/.drone.yml @@ -0,0 +1,14 @@ +kind: pipeline +name: default + +steps: +- name: docker + image: plugins/docker + settings: + registry: https://git.ivasoft.cz + username: + from_secret: repo_user + password: + from_secret: repo_pass + repo: git.ivasoft.cz/sw/backuppc + tags: latest \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..cc5be2f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,63 @@ +#FROM alpine:3.15.0 +FROM alpine:edge + +LABEL maintainer="Adrien Ferrand " + +ARG BACKUPPC_VERSION="4.4.0" +ARG BACKUPPC_XS_VERSION="0.62" +ARG RSYNC_BPC_VERSION="3.1.3.0" + +ENV BACKUPPC_VERSION="${BACKUPPC_VERSION}" +ENV BACKUPPC_XS_VERSION="${BACKUPPC_XS_VERSION}" +ENV RSYNC_BPC_VERSION="${RSYNC_BPC_VERSION}" + +# Install backuppc runtime dependencies +RUN apk --no-cache --update add \ + rsync tar bash shadow ca-certificates \ + supervisor \ + perl perl-archive-zip perl-xml-rss perl-cgi perl-file-listing perl-json-xs \ + expat samba-client iputils openssh openssl rrdtool ttf-dejavu \ + msmtp lighttpd lighttpd-mod_auth apache2-utils tzdata libstdc++ libgomp \ + gzip pigz \ + && apk --no-cache --update -X http://dl-cdn.alpinelinux.org/alpine/edge/community add par2cmdline \ +# Install backuppc build dependencies + && apk --no-cache --update --virtual build-dependencies add \ + gcc g++ autoconf automake make git perl-dev acl-dev curl \ +# Compile and install BackupPC:XS + && git clone https://github.com/backuppc/backuppc-xs.git /root/backuppc-xs --branch $BACKUPPC_XS_VERSION \ + && cd /root/backuppc-xs \ + && perl Makefile.PL && make && make test && make install \ +# Compile and install Rsync (BPC version) + && git clone https://github.com/backuppc/rsync-bpc.git /root/rsync-bpc --branch $RSYNC_BPC_VERSION \ + && cd /root/rsync-bpc && ./configure && make reconfigure && make && make install \ +# Configure MSMTP for mail delivery (initially sendmail is a sym link to busybox) + && rm -f /usr/sbin/sendmail \ + && ln -s /usr/bin/msmtp /usr/sbin/sendmail \ +# Disable strict host key checking + && sed -i -e 's/^# Host \*/Host */g' /etc/ssh/ssh_config \ + && sed -i -e 's/^# StrictHostKeyChecking ask/ StrictHostKeyChecking no/g' /etc/ssh/ssh_config \ +# Get BackupPC, it will be installed at runtime to allow dynamic upgrade of existing config/pool + && curl -o /root/BackupPC-$BACKUPPC_VERSION.tar.gz -L https://github.com/backuppc/backuppc/releases/download/$BACKUPPC_VERSION/BackupPC-$BACKUPPC_VERSION.tar.gz \ +# Prepare backuppc home + && mkdir -p /home/backuppc && cd /home/backuppc \ +# Mark the docker as not run yet, to allow entrypoint to do its stuff + && touch /firstrun \ +# Clean + && rm -rf /root/backuppc-xs /root/rsync-bpc /root/par2cmdline \ + && apk del build-dependencies + +COPY files/lighttpd.conf /etc/lighttpd/lighttpd.conf +COPY files/auth.conf /etc/lighttpd/auth.conf +COPY files/auth-ldap.conf /etc/lighttpd/auth-ldap.conf +COPY files/entrypoint.sh /entrypoint.sh +COPY files/supervisord.conf /etc/supervisord.conf + +EXPOSE 8080 + +WORKDIR /home/backuppc + +VOLUME ["/etc/backuppc", "/home/backuppc", "/data/backuppc"] + +ENTRYPOINT ["/entrypoint.sh"] + +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"] diff --git a/files/auth-ldap.conf b/files/auth-ldap.conf new file mode 100644 index 0000000..3a20ef4 --- /dev/null +++ b/files/auth-ldap.conf @@ -0,0 +1,11 @@ +server.modules += ( "mod_authn_ldap" ) +auth.backend = "ldap" +auth.backend.ldap.hostname = "LDAP_HOSTNAME" +auth.backend.ldap.base-dn = "LDAP_BASE_DN" +auth.backend.ldap.filter = "LDAP_FILTER" +auth.backend.ldap.allow-empty-pw = "disable" + +auth.backend.ldap.bind-dn = "LDAP_BIND_DN" +auth.backend.ldap.bind-pw = "LDAP_BIND_PW" + +auth.require = ( "/BackupPC_Admin" => ( "method" => "basic", "realm" => "BackupPC", "require" => "valid-user" ) ) diff --git a/files/auth.conf b/files/auth.conf new file mode 100644 index 0000000..8e7e5d9 --- /dev/null +++ b/files/auth.conf @@ -0,0 +1,3 @@ +auth.backend = "htpasswd" +auth.backend.htpasswd.userfile = "/etc/backuppc/htpasswd" +auth.require = ( "/BackupPC_Admin" => ( "method" => "basic", "realm" => "BackupPC", "require" => "valid-user" ) ) diff --git a/files/entrypoint.sh b/files/entrypoint.sh new file mode 100644 index 0000000..e9f5939 --- /dev/null +++ b/files/entrypoint.sh @@ -0,0 +1,133 @@ +#!/bin/bash +set -e + +BACKUPPC_UUID="${BACKUPPC_UUID:-1000}" +BACKUPPC_GUID="${BACKUPPC_GUID:-1000}" +BACKUPPC_USERNAME=$(getent passwd "$BACKUPPC_UUID" | cut -d: -f1) +BACKUPPC_GROUPNAME=$(getent group "$BACKUPPC_GUID" | cut -d: -f1) + +if [ -f /firstrun ]; then + echo 'First run of the container. BackupPC will be installed.' + echo 'If exist, configuration and data will be reused and upgraded as needed.' + + # Executable bzip2 seems to have been moved into /usr/bin in latest Alpine version. Fix that. + if [ ! -f /bin/bzip2 ]; then + ln -s /usr/bin/bzip2 /bin/bzip2 + fi + + # Configure timezone if needed + if [ -n "$TZ" ]; then + cp /usr/share/zoneinfo/$TZ /etc/localtime + fi + + # Create backuppc user/group if needed + if [ -z "$BACKUPPC_GROUPNAME" ]; then + groupadd -r -g "$BACKUPPC_GUID" backuppc + BACKUPPC_GROUPNAME="backuppc" + fi + if [ -z "$BACKUPPC_USERNAME" ]; then + useradd -r -d /home/backuppc -g "$BACKUPPC_GUID" -u "$BACKUPPC_UUID" -M -N backuppc + BACKUPPC_USERNAME="backuppc" + else + usermod -d /home/backuppc "$BACKUPPC_USERNAME" + fi + chown "$BACKUPPC_USERNAME":"$BACKUPPC_GROUPNAME" /home/backuppc + + # Generate cryptographic key + if [ ! -f /home/backuppc/.ssh/id_rsa ]; then + su "$BACKUPPC_USERNAME" -s /bin/sh -c "ssh-keygen -t rsa -N '' -f /home/backuppc/.ssh/id_rsa" + fi + + # Extract BackupPC + cd /root + tar xf "BackupPC-$BACKUPPC_VERSION.tar.gz" + cd "/root/BackupPC-$BACKUPPC_VERSION" + + # Configure WEB UI access + configure_admin="" + if [ ! -f /etc/backuppc/htpasswd ]; then + htpasswd -b -c /etc/backuppc/htpasswd "${BACKUPPC_WEB_USER:-backuppc}" "${BACKUPPC_WEB_PASSWD:-password}" + configure_admin="--config-override CgiAdminUsers='${BACKUPPC_WEB_USER:-backuppc}'" + elif [[ -n "$BACKUPPC_WEB_USER" && -n "$BACKUPPC_WEB_PASSWD" ]]; then + touch /etc/backuppc/htpasswd + htpasswd -b /etc/backuppc/htpasswd "${BACKUPPC_WEB_USER}" "${BACKUPPC_WEB_PASSWD}" + configure_admin="--config-override CgiAdminUsers='$BACKUPPC_WEB_USER'" + fi + + # Install BackupPC (existing configuration will be reused and upgraded) + perl configure.pl \ + --batch \ + --config-dir /etc/backuppc \ + --cgi-dir /var/www/cgi-bin/BackupPC \ + --data-dir /data/backuppc \ + --log-dir /data/backuppc/log \ + --hostname "$HOSTNAME" \ + --html-dir /var/www/html/BackupPC \ + --html-dir-url /BackupPC \ + --install-dir /usr/local/BackupPC \ + --backuppc-user "$BACKUPPC_USERNAME" \ + $configure_admin + + # Prepare lighttpd + if [ "$USE_SSL" = true ]; then + # Do not generate a certificate if user already mapped the file with docker --volume + if [ ! -e /etc/lighttpd/server.pem ]; then + # Generate certificate file as needed + cd /etc/lighttpd + openssl genrsa -des3 -passout pass:1234 -out server.pass.key 2048 + openssl rsa -passin pass:1234 -in server.pass.key -out server.key + openssl req -new -key server.key -out server.csr \ + -subj "/C=UK/ST=Warwickshire/L=Leamington/O=OrgName/OU=IT Department/CN=example.com" + openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt + cat server.key server.crt > server.pem + chown "$BACKUPPC_USERNAME":"$BACKUPPC_GROUPNAME" server.pem + chmod 0600 server.pem + rm -f server.pass.key server.key server.csr server.crt + fi + # Reconfigure lighttpd to use ssl + echo "ssl.engine = \"enable\"" >> /etc/lighttpd/lighttpd.conf + echo "ssl.pemfile = \"/etc/lighttpd/server.pem\"" >> /etc/lighttpd/lighttpd.conf + sed -i -r '/^server\.modules/s# \)#, "mod_openssl" \)#' /etc/lighttpd/lighttpd.conf + fi + + if [ "$AUTH_METHOD" == "ldap" ]; then + + sed -i 's#LDAP_HOSTNAME#'"$LDAP_HOSTNAME"'#g' /etc/lighttpd/auth-ldap.conf + sed -i 's#LDAP_BASE_DN#'"$LDAP_BASE_DN"'#g' /etc/lighttpd/auth-ldap.conf + LDAP_FILTER=$(sed 's#&#\\&#g' <<< "$LDAP_FILTER") + sed -i 's#LDAP_FILTER#'"$LDAP_FILTER"'#g' /etc/lighttpd/auth-ldap.conf + sed -i 's#LDAP_BIND_DN#'"$LDAP_BIND_DN"'#g' /etc/lighttpd/auth-ldap.conf + sed -i 's#LDAP_BIND_PW#'"$LDAP_BIND_PW"'#g' /etc/lighttpd/auth-ldap.conf + sed -ie "s#^\$Conf{CgiAdminUsers}\s*=\s*'\w*'#\$Conf{CgiAdminUsers} = '$LDAP_BACKUPPC_ADMIN'#g" /etc/backuppc/config.pl + + echo "include \"auth-ldap.conf\"" >> /etc/lighttpd/lighttpd.conf + else + echo "include \"auth.conf\"" >> /etc/lighttpd/lighttpd.conf + fi + + touch /var/log/lighttpd/error.log && chown -R "$BACKUPPC_USERNAME":"$BACKUPPC_GROUPNAME" /var/log/lighttpd + + # Configure standard mail delivery parameters (may be overriden by backuppc user-wide config) + if [ ! -f /etc/msmtprc ]; then + echo "account default" > /etc/msmtprc + echo "logfile /var/log/msmtp.log" >> /etc/msmtprc + echo "host ${SMTP_HOST:-mail.example.org}" >> /etc/msmtprc + if [ "${SMTP_MAIL_DOMAIN:-}" != "" ]; then + echo "from %U@${SMTP_MAIL_DOMAIN}" >> /etc/msmtprc + fi + touch /var/log/msmtp.log + chown "${BACKUPPC_USERNAME}:${BACKUPPC_GROUPNAME}" /var/log/msmtp.log + fi + + # Clean + rm -rf "/root/BackupPC-$BACKUPPC_VERSION.tar.gz" "/root/BackupPC-$BACKUPPC_VERSION" /firstrun +fi + +export BACKUPPC_UUID +export BACKUPPC_GUID +export BACKUPPC_USERNAME +export BACKUPPC_GROUPNAME + +# Exec given CMD in Dockerfile +cd /home/backuppc +exec "$@" diff --git a/files/lighttpd.conf b/files/lighttpd.conf new file mode 100644 index 0000000..2415db5 --- /dev/null +++ b/files/lighttpd.conf @@ -0,0 +1,18 @@ +server.port = 8080 +server.username = env.BACKUPPC_USERNAME +server.groupname = env.BACKUPPC_GROUPNAME +server.document-root = "/srv/http" +server.errorlog = "/var/log/lighttpd/error.log" +dir-listing.activate = "enable" +index-file.names = ( "index.html", "index.php", "index.cgi" ) +mimetype.assign = ( ".html" => "text/html", ".txt" => "text/plain", ".jpg" => "image/jpeg", ".png" => "image/png", ".gif" => "image/gif", ".css" => "text/css", ".js" => "text/javascript", "" => "application/octet-stream" ) + +server.modules = ( "mod_alias", "mod_cgi", "mod_auth", "mod_access", "mod_rewrite", "mod_redirect" ) + +alias.url = ( "/BackupPC_Admin" => "/var/www/cgi-bin/BackupPC/BackupPC_Admin" ) +alias.url += ( "/BackupPC" => "/var/www/html/BackupPC" ) + +cgi.assign += ( ".cgi" => "/usr/bin/perl" ) +cgi.assign += ( "BackupPC_Admin" => "/usr/bin/perl" ) + +url.redirect = ("^/(\?.*)?$" => "/BackupPC_Admin$1") diff --git a/files/supervisord.conf b/files/supervisord.conf new file mode 100644 index 0000000..574c25e --- /dev/null +++ b/files/supervisord.conf @@ -0,0 +1,44 @@ +[unix_http_server] +file = /tmp/supervisor.sock +username = dummy +password = dummy + +[supervisord] +user = root +logfile = /var/log/supervisord.log +logfile_maxbytes = 50MB +logfile_backups = 10 +loglevel = info +pidfile = /tmp/supervisord.pid +nodaemon = true +minfds = 1024 +minprocs = 200 + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl = unix:///tmp/supervisor.sock +username = dummy +password = dummy + +[program:lighttpd] +command = /usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf -D +redirect_stderr = true +stdout_logfile = /dev/stdout +stdout_logfile_maxbytes = 0 +stopasgroup = true +killasgroup = true + +[program:backuppc] +command = /usr/local/BackupPC/bin/BackupPC +redirect_stderr = true +stdout_logfile = /dev/stdout +stdout_logfile_maxbytes = 0 +user = %(ENV_BACKUPPC_USERNAME)s + +[program:watchmails] +command = tail -f /var/log/msmtp.log +redirect_stderr = true +stdout_logfile = /dev/stdout +stdout_logfile_maxbytes = 0