summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/ftpsync23
-rwxr-xr-xbin/rsync-ssl-tunnel98
-rw-r--r--etc/ftpsync.conf.sample26
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)