diff --git a/synology/Dockerfile.spksrc b/synology/Dockerfile.spksrc new file mode 100644 index 000000000..0ea42afb3 --- /dev/null +++ b/synology/Dockerfile.spksrc @@ -0,0 +1,73 @@ +FROM debian:buster + +ENV LANG C.UTF-8 + +# Manage i386 arch +RUN dpkg --add-architecture i386 + +# Install required packages (in sync with README.rst instructions) +RUN apt-get update && apt-get install --no-install-recommends -y \ + autoconf-archive \ + autogen \ + automake \ + bc \ + bison \ + build-essential \ + check \ + cmake \ + curl \ + cython \ + debootstrap \ + ed \ + expect \ + fakeroot \ + flex \ + g++-multilib \ + gawk \ + gettext \ + git \ + gperf \ + imagemagick \ + intltool \ + jq \ + libbz2-dev \ + libc6-i386 \ + libcppunit-dev \ + libffi-dev \ + libgc-dev \ + libgmp3-dev \ + libltdl-dev \ + libmount-dev \ + libncurses-dev \ + libpcre3-dev \ + libssl-dev \ + libtool \ + libunistring-dev \ + lzip \ + moreutils \ + pkg-config \ + python3 \ + python3-distutils \ + rename \ + rsync \ + scons \ + subversion \ + sudo \ + swig \ + texinfo \ + unzip \ + xmlto \ + zlib1g-dev && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ + adduser --disabled-password --gecos '' user && \ + adduser user sudo && \ + echo "%users ALL=(ALL:ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/users + +# Volume pointing to spksrc sources +VOLUME /spksrc + +WORKDIR /spksrc + +COPY syn-pkg-entrypoint.sh /syn-pkg-entrypoint.sh +ENTRYPOINT ["/syn-pkg-entrypoint.sh"] diff --git a/synology/README.md b/synology/README.md new file mode 100644 index 000000000..cdef46c6c --- /dev/null +++ b/synology/README.md @@ -0,0 +1,7 @@ +## Synology + +### DSM 6 Packaging procedure + +``` +./build.sh build +``` diff --git a/synology/build.sh b/synology/build.sh new file mode 100755 index 000000000..47e9285a9 --- /dev/null +++ b/synology/build.sh @@ -0,0 +1,142 @@ +#!/bin/bash + +ZTO_VER=$(jq -r '.version' config.json) +PKG_REV=$(jq -r '.rev' config.json) +echo $ZTO_VER-$PKG_REV +ZTO_DESC=$(jq -r '.desc' config.json) +echo $ZTO_DESC +ZTO_EMAIL=$(jq -r '.email' config.json) +echo $ZTO_EMAIL +read -p "Confirm details [y/n] ? " -n 1 -r; echo; if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Exiting."; exit; fi + +build_environment() +{ + git clone https://github.com/SynoCommunity/spksrc.git + sudo docker build --load -t zt-spksrc -f Dockerfile.spksrc . +} + +generate_package_sources() +{ + # Clean up any intermediate files + make -C spksrc clean + rm -rf spksrc/distrib/* + rm -rf spksrc/packages/* + rm -rf spksrc/distrib/*source.tar.gz* + + # Generate the SPK + + # Copy package scripts to spksrc so they're accessible to container + rm -rf spksrc/ztpkg-dsm6 + cp -rf ztpkg-dsm6 spksrc/ztpkg-dsm6 + + TAB="$(printf '\t')" + + cd .. + + # Generate ZTO source tarball used by spksrc + git ls-files -z | xargs -0 tar -czvf source.tar.gz + mkdir -p synology/spksrc/distrib + cp source.tar.gz synology/spksrc/distrib/source.tar.gz + + # + # Set up (cross) directory contents + # + rm -rf spksrc/cross/* + mkdir -p spksrc/cross/zerotier + +cat > synology/spksrc/cross/zerotier/digests <<- EOM +source.tar.gz SHA1 $(sha1sum source.tar.gz | awk '{print $1}') +source.tar.gz SHA256 $(sha256sum source.tar.gz | awk '{print $1}') +source.tar.gz MD5 $(md5sum source.tar.gz | awk '{print $1}') +EOM + + cd - + + + STAGING_DIR='$(STAGING_DIR)' + RUN='$(RUN)' + +cat > spksrc/cross/zerotier/Makefile <<- EOM +PKG_NAME = ZeroTierOne +PKG_VERS = $ZTO_VER +PKG_EXT = tar.gz +PKG_DIST_NAME = source.tar.gz +PKG_DIR = +PKG_DIST_SITE = http://localhost:8000 +DEPENDS = +GNU_CONFIGURE = 1 +CONFIGURE_ARGS = HAVE_CXX=yes + +INSTALL_TARGET = zerotier_custom_install +CONFIGURE_TARGET = zerotier_custom_configure + +ENV += ZT_SYNOLOGY=1 + +include ../../mk/spksrc.cross-cc.mk + +.PHONY: zerotier_custom_install +zerotier_custom_install: +${TAB}$RUN mkdir -p $STAGING_DIR/bin +${TAB}$RUN cp zerotier-one $STAGING_DIR/bin/zerotier-one +EOM + +cat > spksrc/cross/zerotier/PLIST <<- EOM +bin:bin/zerotier-one +EOM + + # + # Set up (spk) directory contents + # + rm -rf spksrc/spk/* + mkdir -p spksrc/spk/zerotier + + STAGING_DIR='$(STAGING_DIR)' + WORK_DIR='$(WORK_DIR)' + PRODUCT_DIR='$(PRODUCT_DIR)' + +cat > spksrc/spk/zerotier/Makefile <<- EOM +SPK_NAME = zerotier +SPK_VERS = $ZTO_VER +SPK_REV = $PKG_REV +SPK_ICON = /spksrc/ztpkg-dsm6/PACKAGE_ICON_256.png +DEPENDS = cross/zerotier +MAINTAINER = ZeroTier, Inc. +DESCRIPTION = $ZTO_DESC +LICENSE = BUSL-1.1 +CHANGELOG = +HOMEPAGE = https://my.zerotier.com +REPORT_URL = https://github.com/zerotier/ZeroTierOne/issues +DISPLAY_NAME = ZeroTier +PRODUCT_DIR = $WORK_DIR + +STARTABLE = yes +REQUIRED_DSM = 6.2.4 + +ENV += ZT_SYNOLOGY=1 + +SERVICE_SETUP = ../../ztpkg-dsm6/service-setup.sh +SSS_SCRIPT = ../../ztpkg-dsm6/start-stop-status.sh + +PRE_STRIP_TARGET = zerotier_install + +include ../../mk/spksrc.spk.mk + +.PHONY: zerotier_install +zerotier_install: +${TAB}install -m 755 -d $STAGING_DIR/bin +${TAB}install -m 755 $PRODUCT_DIR/zerotier-one $STAGING_DIR/bin/zerotier-one +EOM + +cat > spksrc/spk/zerotier/PLIST <<- EOM +bin:bin/zerotier-one +EOM +} + +build() +{ + build_environment + generate_package_sources + sudo docker run -it -v $(pwd)/spksrc:/spksrc zt-spksrc /bin/bash +} + +"$@" diff --git a/synology/config.json b/synology/config.json new file mode 100644 index 000000000..0b99541bc --- /dev/null +++ b/synology/config.json @@ -0,0 +1,6 @@ +{ + "version": "1.8.7", + "rev": "0", + "desc": "Securely connect any device, anywhere.", + "email": "support@zerotier.com" +} diff --git a/synology/syn-pkg-entrypoint.sh b/synology/syn-pkg-entrypoint.sh new file mode 100755 index 000000000..1764e8e6c --- /dev/null +++ b/synology/syn-pkg-entrypoint.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +pushd spk/zerotier + +make arch-x64-6.2.4 +make arch-braswell-6.2.4 +# make arch-88f6281-6.2.4 #(std11) +# make arch-monaco-6.2.4 #(ZT_AES_NO_ACCEL=1) +# make arch-hi3535-6.2.4 #(take out -mfloat-abi=hard) +# make arch-comcerto2k-6.2.4 #(ZT_AES_NO_ACCEL=1, remove all flags from arm hf section) +# make arch-alpine4k-6.2.4 #(problem?) +# make arch-alpine-6.2.4 #(problem?) +make arch-aarch64-6.2.4 +make arch-apollolake-6.2.4 +make arch-armada370-6.2.4 +make arch-armada375-6.2.4 +make arch-armada37xx-6.2.4 +make arch-armada38x-6.2.4 +make arch-armadaxp-6.2.4 +make arch-armv7-6.2.4 +make arch-avoton-6.2.4 +make arch-broadwell-6.2.4 +make arch-broadwellnk-6.2.4 +make arch-bromolow-6.2.4 +make arch-cedarview-6.2.4 +make arch-denverton-6.2.4 +make arch-evansport-6.2.4 +make arch-geminilake-6.2.4 +make arch-grantley-6.2.4 +make arch-kvmx64-6.2.4 +make arch-dockerx64-6.2.3 +make arch-purley-6.2.4 +make arch-qoriq-6.2.4 +make arch-rtd1296-6.2.4 +make arch-v1000-6.2.4 +make arch-x86-6.2.4 + +popd diff --git a/synology/ztpkg-dsm6/PACKAGE_ICON.png b/synology/ztpkg-dsm6/PACKAGE_ICON.png new file mode 100644 index 000000000..ff7785f08 Binary files /dev/null and b/synology/ztpkg-dsm6/PACKAGE_ICON.png differ diff --git a/synology/ztpkg-dsm6/PACKAGE_ICON_256.png b/synology/ztpkg-dsm6/PACKAGE_ICON_256.png new file mode 100644 index 000000000..bf89cb127 Binary files /dev/null and b/synology/ztpkg-dsm6/PACKAGE_ICON_256.png differ diff --git a/synology/ztpkg-dsm6/scripts/postinst b/synology/ztpkg-dsm6/scripts/postinst new file mode 100644 index 000000000..c52d3c26b --- /dev/null +++ b/synology/ztpkg-dsm6/scripts/postinst @@ -0,0 +1,3 @@ +#!/bin/sh + +exit 0 diff --git a/synology/ztpkg-dsm6/scripts/postuninst b/synology/ztpkg-dsm6/scripts/postuninst new file mode 100644 index 000000000..c52d3c26b --- /dev/null +++ b/synology/ztpkg-dsm6/scripts/postuninst @@ -0,0 +1,3 @@ +#!/bin/sh + +exit 0 diff --git a/synology/ztpkg-dsm6/scripts/postupgrade b/synology/ztpkg-dsm6/scripts/postupgrade new file mode 100644 index 000000000..039e4d006 --- /dev/null +++ b/synology/ztpkg-dsm6/scripts/postupgrade @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 diff --git a/synology/ztpkg-dsm6/scripts/preinst b/synology/ztpkg-dsm6/scripts/preinst new file mode 100644 index 000000000..039e4d006 --- /dev/null +++ b/synology/ztpkg-dsm6/scripts/preinst @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 diff --git a/synology/ztpkg-dsm6/scripts/preuninst b/synology/ztpkg-dsm6/scripts/preuninst new file mode 100644 index 000000000..c52d3c26b --- /dev/null +++ b/synology/ztpkg-dsm6/scripts/preuninst @@ -0,0 +1,3 @@ +#!/bin/sh + +exit 0 diff --git a/synology/ztpkg-dsm6/scripts/preupgrade b/synology/ztpkg-dsm6/scripts/preupgrade new file mode 100644 index 000000000..039e4d006 --- /dev/null +++ b/synology/ztpkg-dsm6/scripts/preupgrade @@ -0,0 +1,2 @@ +#!/bin/sh +exit 0 diff --git a/synology/ztpkg-dsm6/service-setup.sh b/synology/ztpkg-dsm6/service-setup.sh new file mode 100644 index 000000000..10988beb2 --- /dev/null +++ b/synology/ztpkg-dsm6/service-setup.sh @@ -0,0 +1,32 @@ + +service_postinst() +{ + exit 0 +} + +service_postuninst() +{ + # remove all files except for identity files and network config files (for future convenience) + find /var/lib/zerotier-one/* -type f -o -type d ! -name 'identity.*' -delete + exit 0 +} + +service_postupgrade() +{ + exit 0 +} + +service_preinst() +{ + exit 0 +} + +service_preuninst() +{ + exit 0 +} + +service_preupgrade() +{ + exit 0 +} diff --git a/synology/ztpkg-dsm6/start-stop-status.sh b/synology/ztpkg-dsm6/start-stop-status.sh new file mode 100755 index 000000000..8cd7c4ff6 --- /dev/null +++ b/synology/ztpkg-dsm6/start-stop-status.sh @@ -0,0 +1,164 @@ +#!/bin/sh + +if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -eq "6" ]; then + PKGDIR="/var/packages/zerotier/var" +else + PKGDIR="${SYNOPKG_PKGVAR}" +fi + +ZTO_PID_FILE="${PKGDIR}/zerotier-one.pid" +WAT_PID_FILE="${PKGDIR}/zerotier-watchdog.pid" +ZTO_LOG_FILE="${PKGDIR}/zerotier-one.log" + +log() +{ + local timestamp=$(date --iso-8601=second) + echo "${timestamp} $1" >> ${ZTO_LOG_FILE} +} + +configure_tun() +{ + log "Checking for TUN device" + # Create /dev/net/tun if needed + if ( [ ! -c /dev/net/tun ] ); then + if ( [ ! -d /dev/net ] ); then + mkdir -m 755 /dev/net + fi + log "Adding TUN device" + mknod /dev/net/tun c 10 200 + chmod 0755 /dev/net/tun + fi + + # Load TUN kernel module + if ( !( lsmod | grep -q "^tun\s" ) ); then + log "Loading TUN kernel module" + insmod /lib/modules/tun.ko + fi +} + +configure_cli() +{ + # Create ZT CLI symlinks if needed + mkdir -p /usr/local/bin/ + ln -s ${SYNOPKG_PKGDEST}/bin/zerotier-one /usr/local/bin/zerotier-cli + ln -s ${SYNOPKG_PKGDEST}/bin/zerotier-one /usr/local/bin/zerotier-idtool +} + +apply_routes() +{ + echo $BASHPID >> ${WAT_PID_FILE} + log "Started Watchdog ($(cat $WAT_PID_FILE))" + + # Wait for ZT service to come online before attempting queries + sleep 15 + + # Loop until killed, every two minutes check for required routes and add if needed + while true + do + NETWORK_COUNT=$(zerotier-cli -j listnetworks | jq -r '. | length') + if [ "$NETWORK_COUNT" -gt 0 ]; then + for ((j=0; j<=$((NETWORK_COUNT-1)); j++)) + do + ROUTE_COUNT=$(zerotier-cli -j listnetworks | jq -r '.['$j'].routes | length') + for ((k=0; k<=$((ROUTE_COUNT-1)); k++)) + do + ROUTE=$(zerotier-cli -j listnetworks | jq -r '.['$j'].routes['$k'].target') + EXIST=$(ip route show $ROUTE | wc -l) + if [ $EXIST -eq 0 ]; + then + IFNAME=$(zerotier-cli -j listnetworks | jq -r '.['$j'] | .portDeviceName') + ip route add $ROUTE dev $IFNAME + log "Added route $ROUTE to dev $IFNAME" + # Routes will be deleted when ZT brings the interface down + fi + done + done + sleep 15 + fi + done +} + +configure_routes() +{ + if [ -r "${WAT_PID_FILE}" ]; then + exit 0 + else + apply_routes & + fi +} + +start_daemon() +{ + ${SYNOPKG_PKGDEST}/bin/zerotier-one -d + echo $(pidof zerotier-one) > ${ZTO_PID_FILE} + log "Started ZeroTier ($(cat $ZTO_PID_FILE))" +} + +stop_daemon() { + if [ -r "${ZTO_PID_FILE}" ]; then + local ZTO_PID=$(cat "${ZTO_PID_FILE}") + log "Stopped ZeroTier ($(cat $ZTO_PID_FILE))" + kill -TERM $ZTO_PID + wait_for_status 1 || kill -KILL $PID >> ${LOG_FILE} 2>&1 + rm -f $ZTO_PID_FILE > /dev/null + fi + if [ -r "${WAT_PID_FILE}" ]; then + local WAT_PID=$(cat "${WAT_PID_FILE}") + log "Stopped Watchdog ($(cat $WAT_PID_FILE))" + kill -TERM $WAT_PID + rm -f $WAT_PID_FILE > /dev/null + fi +} + +daemon_status() +{ + if [ -f ${ZTO_PID_FILE} ] && kill -0 `cat ${ZTO_PID_FILE}` > /dev/null 2>&1; then + return + fi + rm -f ${ZTO_PID_FILE} + return 1 +} + +wait_for_status() +{ + counter=$2 + while [ ${counter} -gt 0 ]; do + daemon_status + [ $? -eq $1 ] && return + let counter=counter-1 + sleep 1 + done + return 1 +} + +case "$1" in + start) + if ( pidof zerotier-one ); then + exit 0 + else + configure_tun + configure_cli + start_daemon + configure_routes + fi + ;; + stop) + if ( pidof zerotier-one ); then + stop_daemon + else + exit 0 + fi + ;; + status) + if ( pidof zerotier-one ); then + exit 0 + else + exit 1 + fi + ;; + *) + exit 1 + ;; +esac + +exit 0