diff options
-rwxr-xr-x | bin/ftpsync | 23 | ||||
-rwxr-xr-x | bin/rsync-ssl-tunnel | 98 | ||||
-rw-r--r-- | etc/ftpsync.conf.sample | 26 |
3 files changed, 143 insertions, 4 deletions
diff --git a/bin/ftpsync b/bin/ftpsync index 18e8e01..e3ba480 100755 --- a/bin/ftpsync +++ b/bin/ftpsync @@ -221,6 +221,7 @@ tracefile() { out="GUESSED:{${ARCHLIST}}" echo "Architectures: ${out}" echo "Upstream-mirror: ${RSYNC_HOST}" + echo "SSL: ${RSYNC_SSL}" total=0 if [[ -e ${LOGDIR}/rsync-${NAME}.log ]]; then for bytes in $(awk -F': ' '$1 == "Total bytes received" {print $2} ' "${LOGDIR}/rsync-${NAME}.log"); do @@ -527,6 +528,20 @@ if [[ ${SOURCE_EXCLUDE_EXPLICIT} ]] && [[ -z ${SOURCE_EXCLUDE} ]]; then SOURCE_EXCLUDE="$SOURCE_EXCLUDE --include=debian-cd_info.tar.gz --include=debian-faq.en.html.tar.gz --include=netboot.tar.gz --include=nfsroot.tar.gz --include=hd-media.tar.gz --include=dedication*.tar.gz" fi +RSYNC_SSL=${RSYNC_SSL:-"false"} +RSYNC_SSL_PORT=${RSYNC_SSL_PORT:-"1873"} +RSYNC_SSL_CAPATH=${RSYNC_SSL_CAPATH:-"/etc/ssl/certs"} +RSYNC_SSL_METHOD=${RSYNC_SSL_METHOD:-"stunnel4"} + +if [[ true != ${RSYNC_SSL} ]]; then + RSYNC_SSL_OPTIONS="" +else + export RSYNC_SSL_PORT + export RSYNC_SSL_CAPATH + export RSYNC_SSL_METHOD + RSYNC_SSL_OPTIONS="-e ${BASEDIR}/bin/rsync-ssl-tunnel" +fi + # Hooks HOOK1=${HOOK1:-""} HOOK2=${HOOK2:-""} @@ -640,12 +655,12 @@ while [[ -e ${UPDATEREQUIRED} ]]; do if [[ true = ${SYNCSTAGE1} ]] || [[ true = ${SYNCALL} ]]; then while [[ -e ${UPDATEREQUIRED} ]]; do rm -f "${UPDATEREQUIRED}" - log "Running stage1: ${RSYNC} ${RSYNC_OPTIONS} ${RSYNC_OPTIONS1} ${EXCLUDE} ${SOURCE_EXCLUDE} ${RSYNCPTH}::${RSYNC_PATH} ${TO}" + log "Running stage1: ${RSYNC} ${RSYNC_SSL_OPTIONS} ${RSYNC_OPTIONS} ${RSYNC_OPTIONS1} ${EXCLUDE} ${SOURCE_EXCLUDE} ${RSYNCPTH}::${RSYNC_PATH} ${TO}" set +e # Step one, sync everything except Packages/Releases rsync_started=$(date +%s) - ${RSYNC} ${RSYNC_OPTIONS} ${RSYNC_OPTIONS1} ${EXCLUDE} ${SOURCE_EXCLUDE} \ + ${RSYNC} ${RSYNC_SSL_OPTIONS} ${RSYNC_OPTIONS} ${RSYNC_OPTIONS1} ${EXCLUDE} ${SOURCE_EXCLUDE} \ ${RSYNCPTH}::${RSYNC_PATH} "${TO}" >>"${LOGDIR}/rsync-${NAME}.log" 2>>"${LOGDIR}/rsync-${NAME}.error" result=$? rsync_ended=$(date +%s) @@ -714,13 +729,13 @@ while [[ -e ${UPDATEREQUIRED} ]]; do result=1 fi else - log "Running stage2: ${RSYNC} ${RSYNC_OPTIONS} ${RSYNC_OPTIONS2} ${EXCLUDE} ${SOURCE_EXCLUDE} ${RSYNCPTH}::${RSYNC_PATH} ${TO}" + log "Running stage2: ${RSYNC} ${RSYNC_SSL_OPTIONS} ${RSYNC_OPTIONS} ${RSYNC_OPTIONS2} ${EXCLUDE} ${SOURCE_EXCLUDE} ${RSYNCPTH}::${RSYNC_PATH} ${TO}" set +e # We are lucky, it worked. Now do step 2 and sync again, this time including # the packages/releases files rsync_started=$(date +%s) - ${RSYNC} ${RSYNC_OPTIONS} ${RSYNC_OPTIONS2} ${EXCLUDE} ${SOURCE_EXCLUDE} \ + ${RSYNC} ${RSYNC_SSL_OPTIONS} ${RSYNC_OPTIONS} ${RSYNC_OPTIONS2} ${EXCLUDE} ${SOURCE_EXCLUDE} \ ${RSYNCPTH}::${RSYNC_PATH} "${TO}" >>"${LOGDIR}/rsync-${NAME}.log" 2>>"${LOGDIR}/rsync-${NAME}.error" result=$? rsync_ended=$(date +%s) diff --git a/bin/rsync-ssl-tunnel b/bin/rsync-ssl-tunnel new file mode 100755 index 0000000..d0daaf7 --- /dev/null +++ b/bin/rsync-ssl-tunnel @@ -0,0 +1,98 @@ +#! /bin/bash + +set -e +set -u + +usage() { + echo "Usage: [RSYNC_SSL_CAPATH=<capath>] [RSYNC_SSL_CAPATH=<port>] $0 <RSYNC_HOST>" +} + +while [[ "$#" -gt 0 ]]; do + case "$1" in + -h|--help) + usage + exit 0 + ;; + -l) + shift + shift + continue + ;; + --) + shift + continue + ;; + -*) + usage >&2 + exit 1 + ;; + *) + break + esac +done + +if [[ "$#" = 0 ]]; then + usage >&2 + echo >&2 "No arguments given." + exit 1 +fi +RSYNC_HOST="$1"; shift +RSYNC_SSL_PORT=${RSYNC_SSL_PORT:-"1873"} +RSYNC_SSL_CAPATH=${RSYNC_SSL_CAPATH:-"/etc/ssl/certs"} +RSYNC_SSL_METHOD=${RSYNC_SSL_METHOD:-"stunnel4"} + +method_stunnel() { + skip_host_check="$1"; shift + + tmp="`tempfile`" + trap "rm -f '$tmp'" EXIT + + ( + cat << EOF +# This file has been automatically created by ftpsync for syncing +# from ${RSYNC_HOST}. +# +# To test if things works, try the following: +# rsync -e 'stunnel4 <this config file>' \$RSYNC_USER@dummy:: +# +client = yes +verify = 2 +CApath = ${RSYNC_SSL_CAPATH} + +syslog = no +debug = 4 +output = /dev/stderr + +connect = ${RSYNC_HOST}:${RSYNC_SSL_PORT} +EOF + if ! [ "$skip_host_check" = 1 ]; then + echo "checkHost = ${RSYNC_HOST}" + fi + ) > "$tmp" + + exec stunnel4 "$tmp" + echo >&2 "Failed to exec stunnel4" + exit 1 +} + +method_socat() { + exec socat - "openssl-connect:${RSYNC_HOST}:${RSYNC_SSL_PORT},capath=${RSYNC_SSL_CAPATH}" + echo >&2 "Failed to exec socat." + exit 1 +} + +case ${RSYNC_SSL_METHOD:-} in + stunnel4) + method_stunnel 0 + ;; + stunnel4-old) + method_stunnel 1 + ;; + socat) + method_socat + ;; + *) + echo >&2 "Unknown method $RSYNC_SSL_METHOD." + exit 1 + ;; +esac diff --git a/etc/ftpsync.conf.sample b/etc/ftpsync.conf.sample index 1524e72..50b084b 100644 --- a/etc/ftpsync.conf.sample +++ b/etc/ftpsync.conf.sample @@ -31,6 +31,32 @@ ## If we need a user we also need a password #RSYNC_PASSWORD= +## Set to "true" to tunnel your rsync through stunnel. +## +## ftpsync will then use rsync's -e option to wrap the connection +## with bin/rsync-ssl-tunnel which sets up an stunnel to connect to +## RSYNC_SSL_PORT on the remote site. (This requires server +## support, obviously.) +## +## ftpsync can use either stunnel4, stunnel4-old, or socat to set up the +## encrypted tunnel. +## o stunnel4 requires at least stunnel4 version 5.15 built aginst openssl +## 1.0.2 or later such that the stunnel build supports the checkHost +## service-level option. This will cause stunnel to verify both the +## peer certificate's validity and that it's actually for the host we wish +## to connect to. +## o stunnel4-old will skip the checkHost check. As such it will connect +## to any peer that is able to present a valid certificate, regardless of +## which name it is made out to. +## o socat will verify the peer certificate name only starting with version +## 1.7.3 (Debian 9.0). +## To test if things work, you can run +## RSYNC_SSL_PORT=1873 RSYNC_SSL_CAPATH=/etc/ssl/certs RSYNC_SSL_METHOD=socat rsync -e 'bin/rsync-ssl-tunnel' <server>:: +#RSYNC_SSL=false +#RSYNC_SSL_PORT=1873 +#RSYNC_SSL_CAPATH=/etc/ssl/certs +#RSYNC_SSL_METHOD=stunnel4 + ## In which directory should logfiles end up ## Note that BASEDIR defaults to $HOME, but can be set before calling the ## ftpsync script to any value you want (for example using pam_env) |