From 0693f74ba2e2b091c6ee01b4868db2ffbae93fbf Mon Sep 17 00:00:00 2001 From: casjay Date: Sat, 20 Sep 2025 03:06:55 -0400 Subject: [PATCH] =?UTF-8?q?=20=F0=9F=A6=88=F0=9F=8F=A0=F0=9F=90=9C?= =?UTF-8?q?=E2=9D=97=20Initial=20Commit=20=E2=9D=97=F0=9F=90=9C?= =?UTF-8?q?=F0=9F=A6=88=F0=9F=8F=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 9 + .env.scripts | 60 + .gitattributes | 0 .gitea/workflows/docker.yaml | 52 + .gitignore | 96 + .gitkeep | 0 Dockerfile | 257 +++ Jenkinsfile | 71 + LICENSE.md | 13 + README.md | 36 + rootfs/root/docker/setup/00-init.sh | 40 + rootfs/root/docker/setup/01-system.sh | 38 + rootfs/root/docker/setup/02-packages.sh | 38 + rootfs/root/docker/setup/03-files.sh | 89 + rootfs/root/docker/setup/04-users.sh | 38 + rootfs/root/docker/setup/05-custom.sh | 47 + rootfs/root/docker/setup/06-post.sh | 38 + rootfs/root/docker/setup/07-cleanup.sh | 39 + rootfs/tmp/etc/nginx/mime.types | 79 + rootfs/tmp/etc/nginx/nginx.conf | 126 ++ rootfs/tmp/etc/nginx/vhosts.d/template | 71 + rootfs/tmp/etc/privoxy/config | 5 + rootfs/tmp/etc/tor/torrc | 0 rootfs/tmp/etc/unbound/unbound.conf | 22 + rootfs/usr/local/bin/entrypoint.sh | 572 ++++++ rootfs/usr/local/bin/pkmgr | 142 ++ .../local/etc/docker/init.d/01-tor-bridge.sh | 751 ++++++++ .../local/etc/docker/init.d/02-tor-relay.sh | 753 ++++++++ .../local/etc/docker/init.d/03-tor-server.sh | 806 ++++++++ .../usr/local/etc/docker/init.d/09-unbound.sh | 690 +++++++ .../usr/local/etc/docker/init.d/98-privoxy.sh | 690 +++++++ .../usr/local/etc/docker/init.d/zz-nginx.sh | 745 ++++++++ .../share/httpd/default/hidden_service.html | 22 + rootfs/usr/share/httpd/default/index.css | 116 ++ rootfs/usr/share/httpd/default/index.html | 30 + rootfs/usr/share/httpd/default/list.html | 1654 +++++++++++++++++ rootfs/usr/share/tor/html/exit.html | 337 ++++ 37 files changed, 8572 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.scripts create mode 100644 .gitattributes create mode 100644 .gitea/workflows/docker.yaml create mode 100644 .gitignore create mode 100644 .gitkeep create mode 100644 Dockerfile create mode 100644 Jenkinsfile create mode 100644 LICENSE.md create mode 100644 README.md create mode 100755 rootfs/root/docker/setup/00-init.sh create mode 100755 rootfs/root/docker/setup/01-system.sh create mode 100755 rootfs/root/docker/setup/02-packages.sh create mode 100755 rootfs/root/docker/setup/03-files.sh create mode 100755 rootfs/root/docker/setup/04-users.sh create mode 100755 rootfs/root/docker/setup/05-custom.sh create mode 100755 rootfs/root/docker/setup/06-post.sh create mode 100755 rootfs/root/docker/setup/07-cleanup.sh create mode 100644 rootfs/tmp/etc/nginx/mime.types create mode 100644 rootfs/tmp/etc/nginx/nginx.conf create mode 100644 rootfs/tmp/etc/nginx/vhosts.d/template create mode 100644 rootfs/tmp/etc/privoxy/config create mode 100644 rootfs/tmp/etc/tor/torrc create mode 100644 rootfs/tmp/etc/unbound/unbound.conf create mode 100755 rootfs/usr/local/bin/entrypoint.sh create mode 100755 rootfs/usr/local/bin/pkmgr create mode 100755 rootfs/usr/local/etc/docker/init.d/01-tor-bridge.sh create mode 100755 rootfs/usr/local/etc/docker/init.d/02-tor-relay.sh create mode 100755 rootfs/usr/local/etc/docker/init.d/03-tor-server.sh create mode 100755 rootfs/usr/local/etc/docker/init.d/09-unbound.sh create mode 100755 rootfs/usr/local/etc/docker/init.d/98-privoxy.sh create mode 100755 rootfs/usr/local/etc/docker/init.d/zz-nginx.sh create mode 100644 rootfs/usr/share/httpd/default/hidden_service.html create mode 100644 rootfs/usr/share/httpd/default/index.css create mode 100644 rootfs/usr/share/httpd/default/index.html create mode 100644 rootfs/usr/share/httpd/default/list.html create mode 100644 rootfs/usr/share/tor/html/exit.html diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..62efb77 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +# Files to ignore +.gitkeep +.gitignore +node_modules/** +.node_modules/** +**/.gitkeep +**/.gitignore +**/node_modules/** +**/.node_modules/** diff --git a/.env.scripts b/.env.scripts new file mode 100644 index 0000000..6dc7ca1 --- /dev/null +++ b/.env.scripts @@ -0,0 +1,60 @@ +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501060857-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@Copyright : Copyright 2025 CasjaysDev +# @@Created : Mon Jan 6 08:57:09 AM EST 2025 +# @@File : .env.scripts +# @@Description : Variables for gen-dockerfile and buildx scripts +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# entrypoint Settings +DOCKER_ENTYPOINT_PORTS_WEB="${DOCKER_ENTYPOINT_PORTS_WEB}" +DOCKER_ENTYPOINT_PORTS_SRV="${DOCKER_ENTYPOINT_PORTS_SRV}" +DOCKER_ENTYPOINT_HEALTH_APPS="$DOCKER_ENTYPOINT_HEALTH_APPS" +DOCKER_ENTYPOINT_HEALTH_ENDPOINTS="$DOCKER_ENTYPOINT_HEALTH_ENDPOINTS" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Dockerfile info +ENV_DOCKERFILE="Dockerfile" +ENV_IMAGE_NAME="tor" +ENV_USE_TEMPLATE="alpine" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Maintainer info +ENV_ORG_NAME="casjaysdevdocker" +ENV_VENDOR="CasjaysDev" +ENV_AUTHOR="CasjaysDev" +ENV_MAINTAINER="CasjaysDev " +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# REPO info +ENV_GIT_REPO_URL="https://github.com/casjaysdevdocker/tor" +ENV_REGISTRY_URL="https://hub.docker.com/r/casjaysdevdocker/tor" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Push image info +ENV_IMAGE_PUSH="casjaysdevdocker/tor" +ENV_IMAGE_TAG="latest" +ENV_ADD_TAGS="USE_DATE" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ENV_ADD_IMAGE_PUSH="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Pull image info +ENV_PULL_URL="casjaysdev/alpine" +ENV_DISTRO_TAG="${IMAGE_VERSION}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Env +SERVICE_PORT="80" +EXPOSE_PORTS="80 8118 9040 9050 9053 9080 57000-57010" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Versions +PHP_VERSION="84" +NODE_VERSION="system" +NODE_MANAGER="system" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Default directories +WWW_ROOT_DIR="/usr/local/share/httpd/default" +DEFAULT_FILE_DIR="/usr/local/share/template-files" +DEFAULT_DATA_DIR="/usr/local/share/template-files/data" +DEFAULT_CONF_DIR="/usr/local/share/template-files/config" +DEFAULT_TEMPLATE_DIR="/usr/local/share/template-files/defaults" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ENV_PACKAGES="tor torsocks nginx php\$PHP_VERSION" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e69de29 diff --git a/.gitea/workflows/docker.yaml b/.gitea/workflows/docker.yaml new file mode 100644 index 0000000..9102595 --- /dev/null +++ b/.gitea/workflows/docker.yaml @@ -0,0 +1,52 @@ +name: release-tag + +on: push + +jobs: + release-image: + runs-on: act_runner + container: + image: catthehacker/ubuntu:act-latest + env: + RUNNER_TOOL_CACHE: /toolcache + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Get Meta + id: meta + run: | + echo DATE_TAG=$(date +'%y%m') >> $GITHUB_OUTPUT + echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT + echo DOCKER_ORG=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $1}') >> $GITHUB_OUTPUT + echo DOCKER_TAG=$([ -n "$DOCKER_TAG" ] && echo ${DOCKER_TAG} || echo "latest") >> $GITHUB_OUTPUT + echo DOCKER_HUB=$([ -n "$DOCKER_HUB" ] && echo ${DOCKER_HUB} || echo "docker.io") >> $GITHUB_OUTPUT + echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}' | sed 's|^docker-||g') >> $GITHUB_OUTPUT + echo "$DOCKER_HUB/$DOCKER_ORG/$REPO_NAME:$DOCKER_TAG" + + - name: Set up Docker BuildX + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKER_USERNAME }} + registry: ${{ steps.meta.outputs.DOCKER_HUB }} + + - name: Build and push + uses: docker/build-push-action@v4 + with: + context: . + file: ./Dockerfile + platforms: | + linux/amd64 + linux/arm64 + push: true + tags: | # replace it with your local IP and tags + ${{ steps.meta.outputs.DOCKER_HUB }}/${{ steps.meta.outputs.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.DATE_TAG }} + ${{ steps.meta.outputs.DOCKER_HUB }}/${{ steps.meta.outputs.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.DOCKER_TAG }} + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e745d4a --- /dev/null +++ b/.gitignore @@ -0,0 +1,96 @@ +# gitignore created on 02/25/23 at 15:50 +# Disable reminder in prompt +ignoredirmessage + +# Disable reminder in prompt +ignoredirmessage + +# OS generated files +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Other +**/.installed + +# ignore commit message +**/.gitcommit + +#ignore .failed +**/.build_failed + +# ignore .bak files +**/*.bak + +# ignore .no_push files +**/.no_push + +# ignore .no_git files +**/.no_git + diff --git a/.gitkeep b/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..081080d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,257 @@ +# Docker image for tor using the alpine template +ARG IMAGE_NAME="tor" +ARG PHP_SERVER="tor" +ARG BUILD_DATE="202501060852" +ARG LANGUAGE="en_US.UTF-8" +ARG TIMEZONE="America/New_York" +ARG WWW_ROOT_DIR="/usr/local/share/httpd/default" +ARG DEFAULT_FILE_DIR="/usr/local/share/template-files" +ARG DEFAULT_DATA_DIR="/usr/local/share/template-files/data" +ARG DEFAULT_CONF_DIR="/usr/local/share/template-files/config" +ARG DEFAULT_TEMPLATE_DIR="/usr/local/share/template-files/defaults" +ARG PATH="/usr/local/etc/docker/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + +ARG USER="root" +ARG SHELL_OPTS="set -e -o pipefail" + +ARG SERVICE_PORT="80" +ARG EXPOSE_PORTS="80 8118 9040 9050 9053 9080 57000-57010" +ARG PHP_VERSION="84" +ARG NODE_VERSION="system" +ARG NODE_MANAGER="system" + +ARG IMAGE_REPO="casjaysdevdocker/tor" +ARG IMAGE_VERSION="latest" +ARG CONTAINER_VERSION="USE_DATE" + +ARG PULL_URL="casjaysdev/alpine" +ARG DISTRO_VERSION="${IMAGE_VERSION}" +ARG BUILD_VERSION="${BUILD_DATE}" + +FROM tianon/gosu:latest AS gosu +FROM ${PULL_URL}:${DISTRO_VERSION} AS build +ARG TZ +ARG USER +ARG LICENSE +ARG TIMEZONE +ARG LANGUAGE +ARG IMAGE_NAME +ARG BUILD_DATE +ARG SERVICE_PORT +ARG EXPOSE_PORTS +ARG BUILD_VERSION +ARG IMAGE_VERSION +ARG WWW_ROOT_DIR +ARG DEFAULT_FILE_DIR +ARG DEFAULT_DATA_DIR +ARG DEFAULT_CONF_DIR +ARG DEFAULT_TEMPLATE_DIR +ARG DISTRO_VERSION +ARG NODE_VERSION +ARG NODE_MANAGER +ARG PHP_VERSION +ARG PHP_SERVER +ARG SHELL_OPTS +ARG PATH + +ARG PACK_LIST="tor torsocks lyrebird privoxy nginx socat unbound bind-tools php$PHP_VERSION" + +ENV ENV=~/.profile +ENV SHELL="/bin/sh" +ENV PATH="${PATH}" +ENV TZ="${TIMEZONE}" +ENV TIMEZONE="${TZ}" +ENV LANG="${LANGUAGE}" +ENV TERM="xterm-256color" +ENV HOSTNAME="casjaysdevdocker-tor" + +USER ${USER} +WORKDIR /root + +COPY ./rootfs/usr/local/bin/. /usr/local/bin/ + +RUN echo "Updating the system and ensuring bash is installed"; \ + pkmgr update;pkmgr install bash + +RUN set -e; \ + echo "Setting up prerequisites"; \ + true + +ENV SHELL="/bin/bash" +SHELL [ "/bin/bash", "-c" ] + +COPY --from=gosu /usr/local/bin/gosu /usr/local/bin/gosu +COPY --from=thetorproject/snowflake-proxy:latest /bin/proxy /usr/local/bin/snowflake + +RUN echo "Initializing the system"; \ + $SHELL_OPTS; \ + mkdir -p "${DEFAULT_DATA_DIR}" "${DEFAULT_CONF_DIR}" "${DEFAULT_TEMPLATE_DIR}" "/root/docker/setup" "/etc/profile.d"; \ + if [ -f "/root/docker/setup/00-init.sh" ];then echo "Running the init script";/root/docker/setup/00-init.sh||{ echo "Failed to execute /root/docker/setup/00-init.sh" >&2 && exit 10; };echo "Done running the init script";fi; \ + echo "" + +RUN echo "Creating and editing system files "; \ + $SHELL_OPTS; \ + [ -f "/root/.profile" ] || touch "/root/.profile"; \ + if [ -f "/root/docker/setup/01-system.sh" ];then echo "Running the system script";/root/docker/setup/01-system.sh||{ echo "Failed to execute /root/docker/setup/01-system.sh" >&2 && exit 10; };echo "Done running the system script";fi; \ + echo "" + +RUN echo "Running pre-package commands"; \ + $SHELL_OPTS; \ + echo "" + +RUN echo "Setting up and installing packages"; \ + $SHELL_OPTS; \ + if [ -n "${PACK_LIST}" ];then echo "Installing packages: $PACK_LIST";echo "${PACK_LIST}" >/root/docker/setup/packages.txt;pkmgr install ${PACK_LIST};fi; \ + echo "" + +RUN echo "Initializing packages before copying files to image"; \ + $SHELL_OPTS; \ + if [ -f "/root/docker/setup/02-packages.sh" ];then echo "Running the packages script";/root/docker/setup/02-packages.sh||{ echo "Failed to execute /root/docker/setup/02-packages.sh" >&2 && exit 10; };echo "Done running the packages script";fi; \ + echo "" + +COPY ./rootfs/. / +COPY ./Dockerfile /root/docker/Dockerfile + +RUN echo "Updating system files "; \ + $SHELL_OPTS; \ + echo "$TIMEZONE" >"/etc/timezone"; \ + touch "/etc/profile" "/root/.profile"; \ + echo 'hosts: files dns' >"/etc/nsswitch.conf"; \ + [ "$PHP_VERSION" = "system" ] && PHP_VERSION="php" || true; \ + PHP_BIN="$(command -v ${PHP_VERSION} 2>/dev/null || true)"; \ + PHP_FPM="$(ls /usr/*bin/php*fpm* 2>/dev/null || true)"; \ + pip_bin="$(command -v python3 2>/dev/null || command -v python2 2>/dev/null || command -v python 2>/dev/null || true)"; \ + py_version="$(command $pip_bin --version | sed 's|[pP]ython ||g' | awk -F '.' '{print $1$2}' | grep '[0-9]' || true)"; \ + [ "$py_version" -gt "310" ] && pip_opts="--break-system-packages " || pip_opts=""; \ + [ -f "/usr/share/zoneinfo/${TZ}" ] && ln -sf "/usr/share/zoneinfo/${TZ}" "/etc/localtime" || true; \ + [ -n "$PHP_BIN" ] && [ -z "$(command -v php 2>/dev/null)" ] && ln -sf "$PHP_BIN" "/usr/bin/php" 2>/dev/null || true; \ + [ -n "$PHP_FPM" ] && [ -z "$(command -v php-fpm 2>/dev/null)" ] && ln -sf "$PHP_FPM" "/usr/bin/php-fpm" 2>/dev/null || true; \ + if [ -f "/etc/profile.d/color_prompt.sh.disabled" ]; then mv -f "/etc/profile.d/color_prompt.sh.disabled" "/etc/profile.d/color_prompt.sh";fi ; \ + { [ -f "/etc/bash/bashrc" ] && cp -Rf "/etc/bash/bashrc" "/root/.bashrc"; } || { [ -f "/etc/bashrc" ] && cp -Rf "/etc/bashrc" "/root/.bashrc"; } || { [ -f "/etc/bash.bashrc" ] && cp -Rf "/etc/bash.bashrc" "/root/.bashrc"; } || true; \ + if [ -z "$(command -v "apt-get" 2>/dev/null)" ];then grep -sh -q 'alias quit' "/root/.bashrc" || printf '# Profile\n\n%s\n%s\n%s\n' '. /etc/profile' '. /root/.profile' "alias quit='exit 0 2>/dev/null'" >>"/root/.bashrc"; fi; \ + if [ "$PHP_VERSION" != "system" ] && [ -e "/etc/php" ] && [ -d "/etc/php${PHP_VERSION}" ];then rm -Rf "/etc/php";fi; \ + if [ "$PHP_VERSION" != "system" ] && [ -n "${PHP_VERSION}" ] && [ -d "/etc/php${PHP_VERSION}" ];then ln -sf "/etc/php${PHP_VERSION}" "/etc/php";fi; \ + if [ -f "/root/docker/setup/03-files.sh" ];then echo "Running the files script";/root/docker/setup/03-files.sh||{ echo "Failed to execute /root/docker/setup/03-files.sh" >&2 && exit 10; };echo "Done running the files script";fi; \ + echo "" + +RUN echo "Custom Settings"; \ + $SHELL_OPTS; \ + echo "" + +RUN echo "Setting up users and scripts "; \ + $SHELL_OPTS; \ + if [ -f "/root/docker/setup/04-users.sh" ];then echo "Running the users script";/root/docker/setup/04-users.sh||{ echo "Failed to execute /root/docker/setup/04-users.sh" >&2 && exit 10; };echo "Done running the users script";fi; \ + echo "" + +RUN echo "Running the user init commands"; \ + $SHELL_OPTS; \ + echo "" + +RUN echo "Setting OS Settings "; \ + $SHELL_OPTS; \ + echo "" + +RUN echo "Custom Applications"; \ + $SHELL_OPTS; \ + echo "" + +RUN echo "Running custom commands"; \ + if [ -f "/root/docker/setup/05-custom.sh" ];then echo "Running the custom script";/root/docker/setup/05-custom.sh||{ echo "Failed to execute /root/docker/setup/05-custom.sh" && exit 10; };echo "Done running the custom script";fi; \ + echo "" + +RUN echo "Running final commands before cleanup"; \ + $SHELL_OPTS; \ + if [ -f "/root/docker/setup/06-post.sh" ];then echo "Running the post script";/root/docker/setup/06-post.sh||{ echo "Failed to execute /root/docker/setup/06-post.sh" >&2 && exit 10; };echo "Done running the post script";fi; \ + echo "" + +RUN echo "Deleting unneeded files"; \ + $SHELL_OPTS; \ + pkmgr clean; \ + rm -Rf /etc/tor/*.sample || true; \ + rm -Rf "/config" "/data" || true; \ + rm -rf /etc/systemd/system/*.wants/* || true; \ + rm -rf /lib/systemd/system/systemd-update-utmp* || true; \ + rm -rf /lib/systemd/system/anaconda.target.wants/* || true; \ + rm -rf /lib/systemd/system/local-fs.target.wants/* || true; \ + rm -rf /lib/systemd/system/multi-user.target.wants/* || true; \ + rm -rf /lib/systemd/system/sockets.target.wants/*udev* || true; \ + rm -rf /lib/systemd/system/sockets.target.wants/*initctl* || true; \ + rm -Rf /usr/share/doc/* /var/tmp/* /var/cache/*/* /root/.cache/* /usr/share/info/* /tmp/* || true; \ + if [ -d "/lib/systemd/system/sysinit.target.wants" ];then cd "/lib/systemd/system/sysinit.target.wants" && rm -f $(ls | grep -v systemd-tmpfiles-setup);fi; \ + if [ -f "/root/docker/setup/07-cleanup.sh" ];then echo "Running the cleanup script";/root/docker/setup/07-cleanup.sh||{ echo "Failed to execute /root/docker/setup/07-cleanup.sh" >&2 && exit 10; };echo "Done running the cleanup script";fi; \ + echo "" + +RUN echo "Init done" +FROM scratch +ARG TZ +ARG PATH +ARG USER +ARG TIMEZONE +ARG LANGUAGE +ARG IMAGE_NAME +ARG BUILD_DATE +ARG SERVICE_PORT +ARG EXPOSE_PORTS +ARG BUILD_VERSION +ARG IMAGE_VERSION +ARG WWW_ROOT_DIR +ARG DEFAULT_FILE_DIR +ARG DEFAULT_DATA_DIR +ARG DEFAULT_CONF_DIR +ARG DEFAULT_TEMPLATE_DIR +ARG DISTRO_VERSION +ARG NODE_VERSION +ARG NODE_MANAGER +ARG PHP_VERSION +ARG PHP_SERVER +ARG LICENSE="WTFPL" +ARG ENV_PORTS="${EXPOSE_PORTS}" + +USER ${USER} +WORKDIR /root + +LABEL maintainer="CasjaysDev " +LABEL org.opencontainers.image.vendor="CasjaysDev" +LABEL org.opencontainers.image.authors="CasjaysDev" +LABEL org.opencontainers.image.description="Containerized version of ${IMAGE_NAME}" +LABEL org.opencontainers.image.title="${IMAGE_NAME}" +LABEL org.opencontainers.image.base.name="${IMAGE_NAME}" +LABEL org.opencontainers.image.authors="${LICENSE}" +LABEL org.opencontainers.image.created="${BUILD_DATE}" +LABEL org.opencontainers.image.version="${BUILD_VERSION}" +LABEL org.opencontainers.image.schema-version="${BUILD_VERSION}" +LABEL org.opencontainers.image.url="https://hub.docker.com/r/casjaysdevdocker/tor" +LABEL org.opencontainers.image.source="https://hub.docker.com/r/casjaysdevdocker/tor" +LABEL org.opencontainers.image.vcs-type="Git" +LABEL org.opencontainers.image.revision="${BUILD_VERSION}" +LABEL org.opencontainers.image.source="https://github.com/casjaysdevdocker/tor" +LABEL org.opencontainers.image.documentation="https://github.com/casjaysdevdocker/tor" +LABEL com.github.containers.toolbox="false" + +ENV ENV=~/.bashrc +ENV USER="${USER}" +ENV PATH="${PATH}" +ENV TZ="${TIMEZONE}" +ENV SHELL="/bin/bash" +ENV TIMEZONE="${TZ}" +ENV LANG="${LANGUAGE}" +ENV TERM="xterm-256color" +ENV PORT="${SERVICE_PORT}" +ENV ENV_PORTS="${ENV_PORTS}" +ENV CONTAINER_NAME="${IMAGE_NAME}" +ENV HOSTNAME="casjaysdev-${IMAGE_NAME}" +ENV PHP_SERVER="${PHP_SERVER}" +ENV NODE_VERSION="${NODE_VERSION}" +ENV NODE_MANAGER="${NODE_MANAGER}" +ENV PHP_VERSION="${PHP_VERSION}" +ENV DISTRO_VERSION="${IMAGE_VERSION}" +ENV WWW_ROOT_DIR="${WWW_ROOT_DIR}" + +COPY --from=build /. / + +VOLUME [ "/config","/data" ] + +EXPOSE ${SERVICE_PORT} ${ENV_PORTS} + +ENTRYPOINT [ "tini","--","/usr/local/bin/entrypoint.sh" ] +HEALTHCHECK --start-period=10m --interval=5m --timeout=15s CMD [ "/usr/local/bin/entrypoint.sh", "healthcheck" ] diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..c474dca --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,71 @@ +pipeline { + agent { + label 'arm64 || amd64' + } + + options { + buildDiscarder(logRotator(numToKeepStr: '10')) + timeout(time: 60, unit: 'MINUTES') + timestamps() + } + + environment { + DOCKER_REGISTRY = 'docker.io' + IMAGE_NAME = 'casjaysdevdocker/tor' + DOCKER_BUILDKIT = '1' + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build Multi-Arch Image') { + steps { + script { + def buildArgs = "" + if (fileExists('.env.scripts')) { + buildArgs = "--build-arg-file .env.scripts" + } + + sh """ + docker buildx create --use --name mybuilder || true + docker buildx build \\ + --platform linux/amd64,linux/arm64 \\ + --tag ${DOCKER_REGISTRY}/${IMAGE_NAME}:latest \\ + --tag ${DOCKER_REGISTRY}/${IMAGE_NAME}:\${BUILD_NUMBER} \\ + ${buildArgs} \\ + --push . + """ + } + } + } + + stage('Test') { + steps { + script { + sh """ + docker run --rm --platform linux/\$(uname -m) \\ + ${DOCKER_REGISTRY}/${IMAGE_NAME}:latest \\ + /bin/sh -c 'echo "Container test passed"' + """ + } + } + } + } + + post { + always { + sh 'docker buildx rm mybuilder || true' + cleanWs() + } + success { + echo 'Build completed successfully!' + } + failure { + echo 'Build failed!' + } + } +} \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..e744b9c --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,13 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2023 casjay + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 1. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/README.md b/README.md new file mode 100644 index 0000000..589d994 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +## 👋 Welcome to tor 🚀 + +tor README + + +## Install my system scripts + +```shell + sudo bash -c "$(curl -q -LSsf "https://github.com/systemmgr/installer/raw/main/install.sh")" + sudo systemmgr --config && sudo systemmgr install scripts +``` + +## Get source files + +```shell +dockermgr download src tor +``` + +OR + +```shell +git clone "https://github.com/casjaysdevdocker/tor" "$HOME/Projects/github/casjaysdevdocker/tor" +``` + +## Build container + +```shell +cd "$HOME/Projects/github/casjaysdevdocker/tor" +buildx +``` + +## Authors + +📽 dockermgr: [Github](https://github.com/dockermgr) 📽 +🤖 casjay: [Github](https://github.com/casjay) [Docker](https://hub.docker.com/r/casjay) 🤖 +⛵ CasjaysDevDocker: [Github](https://github.com/casjaysdevdocker) [Docker](https://hub.docker.com/r/casjaysdevdocker) ⛵ diff --git a/rootfs/root/docker/setup/00-init.sh b/rootfs/root/docker/setup/00-init.sh new file mode 100755 index 0000000..25db03e --- /dev/null +++ b/rootfs/root/docker/setup/00-init.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501061127-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@ReadME : +# @@Copyright : Copyright 2023 CasjaysDev +# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 +# @@File : 00-init.sh +# @@Description : script to run init +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck shell=bash +# shellcheck disable=SC2016 +# shellcheck disable=SC2031 +# shellcheck disable=SC2120 +# shellcheck disable=SC2155 +# shellcheck disable=SC2199 +# shellcheck disable=SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set bash options +set -o pipefail +[ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set env variables +exitCode=0 + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Predefined actions +if [ -d "/usr/local/share/template-files/data" ]; then rm -Rf "/usr/local/share/template-files/data"/*; fi +if [ -d "/usr/local/share/template-files/config" ]; then rm -Rf "/usr/local/share/template-files/config"/*; fi +if [ -d "/usr/local/share/template-files/defaults" ]; then rm -Rf "/usr/local/share/template-files/defaults"/*; fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Main script + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the exit code +#exitCode=$? +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $exitCode diff --git a/rootfs/root/docker/setup/01-system.sh b/rootfs/root/docker/setup/01-system.sh new file mode 100755 index 0000000..4b40e92 --- /dev/null +++ b/rootfs/root/docker/setup/01-system.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501061127-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@ReadME : +# @@Copyright : Copyright 2023 CasjaysDev +# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 +# @@File : 01-system.sh +# @@Description : script to run system +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck shell=bash +# shellcheck disable=SC2016 +# shellcheck disable=SC2031 +# shellcheck disable=SC2120 +# shellcheck disable=SC2155 +# shellcheck disable=SC2199 +# shellcheck disable=SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set bash options +set -o pipefail +[ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set env variables +exitCode=0 + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Predefined actions + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Main script + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the exit code +#exitCode=$? +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $exitCode diff --git a/rootfs/root/docker/setup/02-packages.sh b/rootfs/root/docker/setup/02-packages.sh new file mode 100755 index 0000000..84126f7 --- /dev/null +++ b/rootfs/root/docker/setup/02-packages.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501061127-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@ReadME : +# @@Copyright : Copyright 2023 CasjaysDev +# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 +# @@File : 02-packages.sh +# @@Description : script to run packages +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck shell=bash +# shellcheck disable=SC2016 +# shellcheck disable=SC2031 +# shellcheck disable=SC2120 +# shellcheck disable=SC2155 +# shellcheck disable=SC2199 +# shellcheck disable=SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set bash options +set -o pipefail +[ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set env variables +exitCode=0 + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Predefined actions + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Main script + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the exit code +#exitCode=$? +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $exitCode diff --git a/rootfs/root/docker/setup/03-files.sh b/rootfs/root/docker/setup/03-files.sh new file mode 100755 index 0000000..5b2667c --- /dev/null +++ b/rootfs/root/docker/setup/03-files.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202408270903-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@ReadME : +# @@Copyright : Copyright 2023 CasjaysDev +# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 +# @@File : 03-files.sh +# @@Description : script to run files +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck shell=bash +# shellcheck disable=SC2016 +# shellcheck disable=SC2031 +# shellcheck disable=SC2120 +# shellcheck disable=SC2155 +# shellcheck disable=SC2199 +# shellcheck disable=SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set bash options +set -o pipefail +[ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set env variables +exitCode=0 +rm -Rf /etc/unbound/* +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Predefined actions +if [ -d "/tmp/bin" ]; then + mkdir -p "/usr/local/bin" + for bin in "/tmp/bin"/*; do + name="$(basename -- "$bin")" + echo "Installing $name to /usr/local/bin/$name" + copy "$bin" "/usr/local/bin/$name" + chmod -f +x "/usr/local/bin/$name" + done +fi +unset bin +if [ -d "/tmp/var" ]; then + for var in "/tmp/var"/*; do + name="$(basename -- "$var")" + echo "Installing $var to /var/$name" + if [ -d "$var" ]; then + mkdir -p "/var/$name" + copy "$var/." "/var/$name/" + else + copy "$var" "/var/$name" + fi + done +fi +unset var +if [ -d "/tmp/etc" ]; then + for config in "/tmp/etc"/*; do + name="$(basename -- "$config")" + echo "Installing $config to /etc/$name" + if [ -d "$config" ]; then + mkdir -p "/etc/$name" + copy "$config/." "/etc/$name/" + mkdir -p "/usr/local/share/template-files/config/$name" + copy "$config/." "/usr/local/share/template-files/config/$name/" + else + copy "$config" "/etc/$name" + copy "$config" "/usr/local/share/template-files/config/$name" + fi + done +fi +unset config +if [ -d "/tmp/data" ]; then + for data in "/tmp/data"/*; do + name="$(basename -- "$data")" + echo "Installing $data to /usr/local/share/template-files/data" + if [ -d "$data" ]; then + mkdir -p "/usr/local/share/template-files/data/$name" + copy "$data/." "/usr/local/share/template-files/data/$name/" + else + copy "$data" "/usr/local/share/template-files/data/$name" + fi + done +fi +unset data +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Main script + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the exit code +#exitCode=$? +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $exitCode diff --git a/rootfs/root/docker/setup/04-users.sh b/rootfs/root/docker/setup/04-users.sh new file mode 100755 index 0000000..6e19426 --- /dev/null +++ b/rootfs/root/docker/setup/04-users.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501061127-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@ReadME : +# @@Copyright : Copyright 2023 CasjaysDev +# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 +# @@File : 04-users.sh +# @@Description : script to run users +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck shell=bash +# shellcheck disable=SC2016 +# shellcheck disable=SC2031 +# shellcheck disable=SC2120 +# shellcheck disable=SC2155 +# shellcheck disable=SC2199 +# shellcheck disable=SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set bash options +set -o pipefail +[ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set env variables +exitCode=0 + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Predefined actions + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Main script + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the exit code +#exitCode=$? +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $exitCode diff --git a/rootfs/root/docker/setup/05-custom.sh b/rootfs/root/docker/setup/05-custom.sh new file mode 100755 index 0000000..e0dd38e --- /dev/null +++ b/rootfs/root/docker/setup/05-custom.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501061127-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@ReadME : +# @@Copyright : Copyright 2023 CasjaysDev +# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 +# @@File : 05-custom.sh +# @@Description : script to run custom +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck shell=bash +# shellcheck disable=SC2016 +# shellcheck disable=SC2031 +# shellcheck disable=SC2120 +# shellcheck disable=SC2155 +# shellcheck disable=SC2199 +# shellcheck disable=SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set bash options +set -o pipefail +[ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set env variables +exitCode=0 +tor_bin="$(type -P tor)" +tor_dir=$(dirname "$tor_bin") +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Predefined actions +for tor_service in bridge relay server; do cp -Rf "$tor_bin" "$tor_dir/tor-$tor_service"; done +[ -f "/etc/privoxy/trust.new" ] && mv -f /etc/privoxy/trust.new /etc/privoxy/trust +[ -f "/etc/privoxy/user.action.new" ] && mv -f /etc/privoxy/user.action.new /etc/privoxy/user.action +[ -f "/etc/privoxy/user.filter.new" ] && mv -f /etc/privoxy/user.filter.new /etc/privoxy/user.filter +[ -f "/etc/privoxy/default.action.new" ] && mv -f /etc/privoxy/default.action.new /etc/privoxy/default.action +[ -f "/etc/privoxy/default.filter.new" ] && mv -f /etc/privoxy/default.filter.new /etc/privoxy/default.filter +[ -f "/etc/privoxy/match-all.action.new" ] && mv -f /etc/privoxy/match-all.action.new /etc/privoxy/match-all.action +[ -f "/etc/privoxy/regression-tests.action.new" ] && mv -f /etc/privoxy/regression-tests.action.new /etc/privoxy/regression-tests.action +rm -Rf /etc/privoxy/*.new /etc/tor/*.sample +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Main script + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the exit code +#exitCode=$? +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $exitCode diff --git a/rootfs/root/docker/setup/06-post.sh b/rootfs/root/docker/setup/06-post.sh new file mode 100755 index 0000000..d7bd215 --- /dev/null +++ b/rootfs/root/docker/setup/06-post.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501061127-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@ReadME : +# @@Copyright : Copyright 2023 CasjaysDev +# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 +# @@File : 06-post.sh +# @@Description : script to run post +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck shell=bash +# shellcheck disable=SC2016 +# shellcheck disable=SC2031 +# shellcheck disable=SC2120 +# shellcheck disable=SC2155 +# shellcheck disable=SC2199 +# shellcheck disable=SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set bash options +set -o pipefail +[ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set env variables +exitCode=0 + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Predefined actions + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Main script + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the exit code +#exitCode=$? +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $exitCode diff --git a/rootfs/root/docker/setup/07-cleanup.sh b/rootfs/root/docker/setup/07-cleanup.sh new file mode 100755 index 0000000..c67dd85 --- /dev/null +++ b/rootfs/root/docker/setup/07-cleanup.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501061127-git +# @@Author : CasjaysDev +# @@Contact : CasjaysDev +# @@License : MIT +# @@ReadME : +# @@Copyright : Copyright 2023 CasjaysDev +# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 +# @@File : 07-cleanup.sh +# @@Description : script to run cleanup +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck shell=bash +# shellcheck disable=SC2016 +# shellcheck disable=SC2031 +# shellcheck disable=SC2120 +# shellcheck disable=SC2155 +# shellcheck disable=SC2199 +# shellcheck disable=SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set bash options +set -o pipefail +[ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set env variables +exitCode=0 + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Predefined actions +if [ -d "/tmp" ]; then rm -Rf "/tmp"/*; fi +if [ -d "$HOME/.cache" ]; then rm -Rf "$HOME/.cache"; fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Main script + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the exit code +#exitCode=$? +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $exitCode diff --git a/rootfs/tmp/etc/nginx/mime.types b/rootfs/tmp/etc/nginx/mime.types new file mode 100644 index 0000000..5d132eb --- /dev/null +++ b/rootfs/tmp/etc/nginx/mime.types @@ -0,0 +1,79 @@ +types { + text/html html htm shtml; + text/css css; + text/xml xml; + image/gif gif; + image/jpeg jpeg jpg; + application/x-javascript js; + application/atom+xml atom; + application/rss+xml rss; + + text/mathml mml; + text/plain txt; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/x-component htc; + + image/png png; + image/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/x-icon ico; + image/x-jng jng; + image/x-ms-bmp bmp; + image/svg+xml svg svgz; + image/webp webp; + + application/java-archive jar war ear; + application/mac-binhex40 hqx; + application/msword doc; + application/pdf pdf; + application/postscript ps eps ai; + application/rtf rtf; + application/vnd.ms-excel xls; + application/vnd.ms-powerpoint ppt; + application/vnd.wap.wmlc wmlc; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + application/x-7z-compressed 7z; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/xhtml+xml xhtml; + application/zip zip; + + application/octet-stream bin exe dll; + application/octet-stream deb; + application/octet-stream dmg; + application/octet-stream eot; + application/octet-stream iso img; + application/octet-stream msi msp msm; + + audio/midi mid midi kar; + audio/mpeg mp3; + audio/ogg ogg; + audio/x-m4a m4a; + audio/x-realaudio ra; + + video/3gpp 3gpp 3gp; + video/mp4 mp4; + video/mpeg mpeg mpg; + video/quicktime mov; + video/webm webm; + video/x-flv flv; + video/x-m4v m4v; + video/x-mng mng; + video/x-ms-asf asx asf; + video/x-ms-wmv wmv; + video/x-msvideo avi; +} diff --git a/rootfs/tmp/etc/nginx/nginx.conf b/rootfs/tmp/etc/nginx/nginx.conf new file mode 100644 index 0000000..4df2e00 --- /dev/null +++ b/rootfs/tmp/etc/nginx/nginx.conf @@ -0,0 +1,126 @@ +# Default nginx configuration +user REPLACE_SERVICE_USER; +worker_processes auto; +daemon off; +pid /run/nginx.pid; +error_log /data/logs/nginx/nginx.log warn; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type "text/html"; + sendfile on; + keepalive_timeout 65; + gzip on; + disable_symlinks off; + server_names_hash_bucket_size 128; + access_log /data/logs/nginx/access.REPLACE_SERVER_NAME.log; + map $http_upgrade $connection_upgrade { default upgrade; '' close; } + root REPLACE_SERVER_WWW_DIR; + + server { + listen REPLACE_SERVER_PORT default_server; + server_name REPLACE_SERVER_NAME; + root REPLACE_SERVER_WWW_DIR; + index index.php index.html index.cgi index.pl index.aspx index.txt index.json index.unknown.php index.default.php; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' *; frame-src 'self' *; object-src 'self'" always; + proxy_intercept_errors off; + client_max_body_size 0; + send_timeout 3600; + + location ^~ /favicon.ico { + alias REPLACE_SERVER_WWW_DIR/favicon.ico; + allow all; + log_not_found off; + access_log off; + } + + location ^~ /robots.txt { + default_type "text/plain"; + alias REPLACE_SERVER_WWW_DIR/robots.txt; + allow all; + log_not_found off; + access_log off; + } + + location ^~ /.well-known { + default_type "text/plain"; + alias REPLACE_SERVER_WWW_DIR/.well-known; + allow all; + log_not_found on; + access_log off; + } + + location ^~ /.well-known/security.txt { + default_type "text/plain"; + alias REPLACE_SERVER_WWW_DIR/security.txt; + allow all; + log_not_found off; + access_log off; + } + + location ^~ /health { + default_type "text/plain"; + allow all; + access_log off; + return 200 'ok'; + } + + location ^~ /health/txt { + default_type "text/plain"; + allow all; + access_log off; + return 200 'ok'; + } + + location ^~ /health/json { + default_type "application/json"; + allow all; + access_log off; + return 200 '{"status":"OK"}'; + } + + location ^~ /health/status { + stub_status; + } + + location ~ [^/]\.php(/|$) { + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + if (!-f $document_root$fastcgi_script_name) { + return 404; + } + fastcgi_param HTTP_PROXY ""; + fastcgi_pass 127.0.0.1:9000; + fastcgi_index index.php; + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param CONTENT_LENGTH $content_length; + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param DOCUMENT_URI $document_uri; + fastcgi_param DOCUMENT_ROOT $document_root; + fastcgi_param SERVER_PROTOCOL $server_protocol; + fastcgi_param REQUEST_SCHEME $scheme; + fastcgi_param HTTPS $https if_not_empty; + fastcgi_param GATEWAY_INTERFACE CGI/1.1; + fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; + fastcgi_param REMOTE_ADDR $remote_addr; + fastcgi_param REMOTE_PORT $remote_port; + fastcgi_param SERVER_ADDR $server_addr; + fastcgi_param SERVER_PORT $server_port; + fastcgi_param SERVER_NAME $server_name; + fastcgi_param REDIRECT_STATUS 200; + } + } + include /etc/nginx/vhosts.d/*.conf; +} diff --git a/rootfs/tmp/etc/nginx/vhosts.d/template b/rootfs/tmp/etc/nginx/vhosts.d/template new file mode 100644 index 0000000..3ed4411 --- /dev/null +++ b/rootfs/tmp/etc/nginx/vhosts.d/template @@ -0,0 +1,71 @@ +#DO NOT CHANGE THIS FILE +#Use as template and copy to /etc/nginx/vhosts.d/servername.conf + +#Reverse Proxy +#See /etc/nginx/conf.d/default.conf for proxy servers +server { + server_name REPLACE_ONION_SITE; + listen REPLACE_ONION_PORT; + keepalive_timeout 75 75; + access_log /data/logs/nginx/access.REPLACE_ONION_SITE.log; + error_log /data/logs/nginx/error.REPLACE_ONION_SITE.log info; + client_max_body_size 0; + send_timeout 3600; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' *; frame-src 'self' *; object-src 'self'" always; + root REPLACE_ONION_WWW_DIR; + index index.php index.html index.cgi index.pl index.aspx index.txt index.json index.unknown.php index.default.php; + + location / { + root REPLACE_ONION_WWW_DIR; + } + location ^~ /favicon.ico { + alias REPLACE_SERVER_WWW_DIR/favicon.ico; + allow all; + access_log off; + log_not_found off; + } + location ^~ /robots.txt { + default_type "text/plain"; + alias REPLACE_SERVER_WWW_DIR/robots.txt; + allow all; + access_log off; + log_not_found off; + } + location ^~ /.well-known { + default_type "text/plain"; + alias REPLACE_SERVER_WWW_DIR/.well-known; + allow all; + access_log off; + log_not_found on; + } + location ^~ /.well-known/security.txt { + default_type "text/plain"; + alias REPLACE_SERVER_WWW_DIR/security.txt; + allow all; + access_log off; + log_not_found off; + } + location ^~ /health { + default_type "text/plain"; + allow all; + access_log off; + return 200 'ok'; + } + location ^~ /health/txt { + default_type "text/plain"; + allow all; + access_log off; + return 200 'ok'; + } + location ^~ /health/json { + default_type "application/json"; + allow all; + access_log off; + return 200 '{"status":"OK"}'; + } +} diff --git a/rootfs/tmp/etc/privoxy/config b/rootfs/tmp/etc/privoxy/config new file mode 100644 index 0000000..fa80309 --- /dev/null +++ b/rootfs/tmp/etc/privoxy/config @@ -0,0 +1,5 @@ +forward-socks5t / 127.0.0.1:9050 . +listen-address 0.0.0.0:8118 +max-client-connections 9999999 +listen-backlog 8192 +trust-x-forwarded-for 1 diff --git a/rootfs/tmp/etc/tor/torrc b/rootfs/tmp/etc/tor/torrc new file mode 100644 index 0000000..e69de29 diff --git a/rootfs/tmp/etc/unbound/unbound.conf b/rootfs/tmp/etc/unbound/unbound.conf new file mode 100644 index 0000000..a3da9f8 --- /dev/null +++ b/rootfs/tmp/etc/unbound/unbound.conf @@ -0,0 +1,22 @@ +server: + directory: "/etc/unbound" + do-udp: yes + do-tcp: yes + interface: 0.0.0.0 + interface: ::0 + interface-automatic: yes + interface-automatic-ports: "53 9053" + access-control: 0.0.0.0/0 allow + access-control: ::/0 allow + domain-insecure: "onion" + private-domain: "onion" + do-not-query-localhost: no + local-zone: "onion." nodefault + +forward-zone: + name: "onion" + forward-addr: 127.0.0.1@8053 +forward-zone: + name: "." + forward-addr: 148.135.52.175 + forward-addr: 1.1.1.1 diff --git a/rootfs/usr/local/bin/entrypoint.sh b/rootfs/usr/local/bin/entrypoint.sh new file mode 100755 index 0000000..2371ee9 --- /dev/null +++ b/rootfs/usr/local/bin/entrypoint.sh @@ -0,0 +1,572 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501061041-git +# @@Author : Jason Hempstead +# @@Contact : jason@casjaysdev.pro +# @@License : LICENSE.md +# @@ReadME : entrypoint.sh --help +# @@Copyright : Copyright: (c) 2025 Jason Hempstead, Casjays Developments +# @@Created : Monday, Jan 06, 2025 10:41 EST +# @@File : entrypoint.sh +# @@Description : Entrypoint file for tor +# @@Changelog : New script +# @@TODO : Better documentation +# @@Other : +# @@Resource : +# @@Terminal App : no +# @@sudo/root : no +# @@Template : other/docker-entrypoint +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1003,SC2016,SC2031,SC2120,SC2155,SC2199,SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# setup debugging - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}" +{ [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; } && echo "Enabling debugging" && set -o pipefail -x$DEBUGGER_OPTIONS && export DEBUGGER="on" || set -o pipefail +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set bash options +SCRIPT_FILE="$0" +CONTAINER_NAME="tor" +SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +CONTAINER_NAME="${ENV_CONTAINER_NAME:-$CONTAINER_NAME}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# remove whitespaces from beginning argument +while :; do [ "$1" = " " ] && shift 1 || break; done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ "$1" = "$SCRIPT_FILE" ] && shift 1 +[ "$1" = "$SCRIPT_NAME" ] && shift 1 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import the functions file +if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then + . "/usr/local/etc/docker/functions/entrypoint.sh" +else + echo "Can not load functions from /usr/local/etc/docker/functions/entrypoint.sh" + exit 1 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +case "$1" in +# Help message +-h | --help) + shift 1 + echo 'Docker container for '$CONTAINER_NAME'' + echo "Usage: $CONTAINER_NAME [cron exec start init shell certbot ssl procs ports healthcheck backup command]" + echo "" + exit 0 + ;; +-*) + shift + ;; +esac +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Create the default env files +__create_env_file "/config/env/default.sh" "/root/env.sh" &>/dev/null +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import variables from files +for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do + [ -f "$set_env" ] && . "$set_env" +done +unset set_env +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User to use to launch service - IE: postgres +RUNAS_USER="root" # normally root +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User and group in which the service switches to - IE: nginx,apache,mysql,postgres +SERVICE_USER="root" # execute command as another user +SERVICE_GROUP="root" # Set the service group +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set user and group ID +SERVICE_UID="0" # set the user id +SERVICE_GID="0" # set the group id +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Primary server port- will be added to server ports +WEB_SERVER_PORT="$PORT" # port : 80,443 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Secondary ports +SERVER_PORTS="" # specifiy other ports +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Healthcheck variables +HEALTH_ENABLED="yes" # enable healthcheck [yes/no] +SERVICES_LIST="tini,tor-bridge,tor-relay,tor-server,unbound,privoxy,zz-nginx" +HEALTH_ENDPOINTS="" # url endpoints: [http://localhost/health,http://localhost/test] +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Update path var +export PATH RUNAS_USER SERVICE_USER SERVICE_GROUP SERVICE_UID SERVICE_GID WWW_ROOT_DIR DATABASE_DIR +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# show message +__run_message() { + + return +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +################## END OF CONFIGURATION ##################### +# Lets get containers ip address +IP4_ADDRESS="$(__get_ip4)" +IP6_ADDRESS="$(__get_ip6)" +CONTAINER_IP4_ADDRESS="${CONTAINER_IP4_ADDRESS:-$IP4_ADDRESS}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Startup variables +export INIT_DATE="${INIT_DATE:-$(date)}" +export CONTAINER_INIT="${CONTAINER_INIT:-no}" +export START_SERVICES="${START_SERVICES:-no}" +export ENTRYPOINT_MESSAGE="${ENTRYPOINT_MESSAGE:-yes}" +export ENTRYPOINT_FIRST_RUN="${ENTRYPOINT_FIRST_RUN:-yes}" +export DATA_DIR_INITIALIZED="${DATA_DIR_INITIALIZED:-no}" +export CONFIG_DIR_INITIALIZED="${CONFIG_DIR_INITIALIZED:-no}" +export CONTAINER_NAME="${ENV_CONTAINER_NAME:-$CONTAINER_NAME}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# System +export LANG="${LANG:-C.UTF-8}" +export LC_ALL="${LANG:-C.UTF-8}" +export TZ="${TZ:-${TIMEZONE:-America/New_York}}" +export HOSTNAME="$(hostname -s)" +export DOMAINNAME="$(hostname -d)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Default directories +export SSL_DIR="${SSL_DIR:-/config/ssl}" +export SSL_CA="${SSL_CERT:-/config/ssl/ca.crt}" +export SSL_KEY="${SSL_KEY:-/config/ssl/localhost.pem}" +export SSL_CERT="${SSL_CERT:-/config/ssl/localhost.crt}" +export LOCAL_BIN_DIR="${LOCAL_BIN_DIR:-/usr/local/bin}" +export DEFAULT_DATA_DIR="${DEFAULT_DATA_DIR:-/usr/local/share/template-files/data}" +export DEFAULT_CONF_DIR="${DEFAULT_CONF_DIR:-/usr/local/share/template-files/config}" +export DEFAULT_TEMPLATE_DIR="${DEFAULT_TEMPLATE_DIR:-/usr/local/share/template-files/defaults}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Backup settings +export BACKUP_MAX_DAYS="${BACKUP_MAX_DAYS:-}" +export BACKUP_RUN_CRON="${BACKUP_RUN_CRON:-}" +export BACKUP_DIR="${BACKUP_DIR:-/data/backups}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional +export PHP_INI_DIR="${PHP_INI_DIR:-$(__find_php_ini)}" +export PHP_BIN_DIR="${PHP_BIN_DIR:-$(__find_php_bin)}" +export HTTPD_CONFIG_FILE="${HTTPD_CONFIG_FILE:-$(__find_httpd_conf)}" +export NGINX_CONFIG_FILE="${NGINX_CONFIG_FILE:-$(__find_nginx_conf)}" +export MYSQL_CONFIG_FILE="${MYSQL_CONFIG_FILE:-$(__find_mysql_conf)}" +export PGSQL_CONFIG_FILE="${PGSQL_CONFIG_FILE:-$(__find_pgsql_conf)}" +export MONGODB_CONFIG_FILE="${MONGODB_CONFIG_FILE:-$(__find_mongodb_conf)}" +export ENTRYPOINT_PID_FILE="${ENTRYPOINT_PID_FILE:-$ENTRYPOINT_PID_FILE}" +export ENTRYPOINT_INIT_FILE="${ENTRYPOINT_INIT_FILE:-/config/.entrypoint.done}" +export ENTRYPOINT_DATA_INIT_FILE="${ENTRYPOINT_DATA_INIT_FILE:-/data/.docker_has_run}" +export ENTRYPOINT_CONFIG_INIT_FILE="${ENTRYPOINT_CONFIG_INIT_FILE:-/config/.docker_has_run}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if [ -n "$CONTAINER_WEB_SERVER_WWW_REPO" ]; then + www_temp_dir="/tmp/git/$(basename -- "$CONTAINER_WEB_SERVER_WWW_REPO")" + rm -Rf "${WWW_ROOT_DIR:?}"/* "${www_temp_dir:?}"/* + mkdir -p "$WWW_ROOT_DIR" "$www_temp_dir" + git clone -q "$CONTAINER_WEB_SERVER_WWW_REPO" "$www_temp_dir" 2>/dev/null + rm -Rf "$www_temp_dir/.git" "$www_temp_dir"/.git* + rsync -ra "$www_temp_dir/" "$WWW_ROOT_DIR" --delete >/dev/null 2>&1 + rm -Rf "$www_temp_dir" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# variables based on env/files +[ -f "/config/enable/ssl" ] && SSL_ENABLED="yes" +[ -f "/config/enable/ssh" ] && SSH_ENABLED="yes" +[ "$WEB_SERVER_PORT" = "443" ] && SSL_ENABLED="yes" +[ "$CONTAINER_WEB_SERVER_PROTOCOL" = "https" ] && SSL_ENABLED="yes" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# export variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# is already Initialized +[ -f "$ENTRYPOINT_DATA_INIT_FILE" ] && DATA_DIR_INITIALIZED="yes" || DATA_DIR_INITIALIZED="no" +[ -f "$ENTRYPOINT_CONFIG_INIT_FILE" ] && CONFIG_DIR_INITIALIZED="yes" || CONFIG_DIR_INITIALIZED="no" +{ [ -f "$ENTRYPOINT_PID_FILE" ] || [ -f "$ENTRYPOINT_INIT_FILE" ]; } && ENTRYPOINT_FIRST_RUN="no" || ENTRYPOINT_FIRST_RUN="yes" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# clean ENV_PORTS variables +ENV_PORTS="${ENV_PORTS//,/ }" # +ENV_PORTS="${ENV_PORTS//\/*/}" # +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# clean SERVER_PORTS variables +SERVER_PORTS="${SERVER_PORTS//,/ }" # +SERVER_PORTS="${SERVER_PORTS//\/*/}" # +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# clean WEB_SERVER_PORTS variables +WEB_SERVER_PORTS="${WEB_SERVER_PORT//\/*/}" # +WEB_SERVER_PORTS="${WEB_SERVER_PORTS//\/*/}" # +WEB_SERVER_PORTS="${WEB_SERVER_PORT//,/ } ${ENV_WEB_SERVER_PORTS//,/ }" # +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# rewrite and merge variables +ENV_PORTS="$(__format_variables "$ENV_PORTS" || false)" +WEB_SERVER_PORTS="$(__format_variables "$WEB_SERVER_PORTS" || false)" +ENV_PORTS="$(__format_variables "$SERVER_PORTS" "$WEB_SERVER_PORTS" "$ENV_PORTS" "$SERVER_PORTS" || false)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Remove the commas from env +HEALTH_ENDPOINTS="${HEALTH_ENDPOINTS//,/ }" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create required directories +mkdir -p "/run" +mkdir -p "/tmp" +mkdir -p "/root" +mkdir -p "/var/run" +mkdir -p "/var/tmp" +mkdir -p "/run/cron" +mkdir -p "/data/logs" +mkdir -p "/run/init.d" +mkdir -p "/config/enable" +mkdir -p "/config/secure" +mkdir -p "/usr/local/etc/docker/exec" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create required files +touch "/data/logs/start.log" +touch "/data/logs/entrypoint.log" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# fix permissions +chmod -f 777 "/run" +chmod -f 777 "/tmp" +chmod -f 700 "/root" +chmod -f 777 "/var/run" +chmod -f 777 "/var/tmp" +chmod -f 777 "/run/cron" +chmod -f 777 "/data/logs" +chmod -f 777 "/run/init.d" +chmod -f 777 "/config/enable" +chmod -f 777 "/config/secure" +chmod -f 777 "/data/logs/entrypoint.log" +chmod -f 777 "/usr/local/etc/docker/exec" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# lets ensure everyone can write to std* +[ -f "/dev/stdin" ] && chmod -f 777 "/dev/stdin" +[ -f "/dev/stderr" ] && chmod -f 777 "/dev/stderr" +[ -f "/dev/stdout" ] && chmod -f 777 "/dev/stdout" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +cat </dev/null +export LANG="\${LANG:-C.UTF-8}" +export LC_ALL="\${LANG:-C.UTF-8}" +export TZ="\${TZ:-\${TIMEZONE:-America/New_York}}" +EOF +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Create the backup dir +[ -n "$BACKUP_DIR" ] && { [ -d "$BACKUP_DIR" ] || mkdir -p "$BACKUP_DIR"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if [ -f "$ENTRYPOINT_PID_FILE" ]; then + START_SERVICES="no" + touch "$ENTRYPOINT_PID_FILE" +else + echo "$$" >"$ENTRYPOINT_PID_FILE" +fi +if [ -f "$ENTRYPOINT_INIT_FILE" ]; then + ENTRYPOINT_MESSAGE="no" ENTRYPOINT_FIRST_RUN="no" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if [ "$ENTRYPOINT_FIRST_RUN" != "no" ]; then + # Show start message + if [ "$CONFIG_DIR_INITIALIZED" = "no" ] || [ "$DATA_DIR_INITIALIZED" = "no" ]; then + [ "$ENTRYPOINT_MESSAGE" = "yes" ] && echo "Executing entrypoint script for tor" + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Set reusable variables + { { [ -w "/etc" ] && [ ! -f "/etc/hosts" ]; } || [ -w "/etc/hosts" ]; } && UPDATE_FILE_HOSTS="yes" && touch "/etc/hosts" + { { [ -w "/etc" ] && [ ! -f "/etc/timezone" ]; } || [ -w "/etc/timezone" ]; } && UPDATE_FILE_TZ="yes" && touch "/etc/timezone" + { { [ -w "/etc" ] && [ ! -f "/etc/resolv.conf" ]; } || [ -w "/etc/resolv.conf" ]; } && UPDATE_FILE_RESOLV="yes" && touch "/etc/resolv.conf" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Set timezone + [ -n "$TZ" ] && [ "$UPDATE_FILE_TZ" = "yes" ] && echo "$TZ" >"/etc/timezone" + [ -f "/usr/share/zoneinfo/$TZ" ] && [ "$UPDATE_FILE_TZ" = "yes" ] && ln -sf "/usr/share/zoneinfo/$TZ" "/etc/localtime" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # if ipv6 add it to /etc/hosts + if [ "$UPDATE_FILE_HOSTS" = "yes" ]; then + echo "# known hostname mappings" >"/etc/hosts" + if [ -n "$(ip a 2>/dev/null | grep 'inet6.*::' || ifconfig 2>/dev/null | grep 'inet6.*::')" ]; then + __printf_space "40" "::1" "localhost" >>"/etc/hosts" + __printf_space "40" "127.0.0.1" "localhost" >>"/etc/hosts" + else + __printf_space "40" "127.0.0.1" "localhost" >>"/etc/hosts" + fi + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # add .home domain + if [ "$UPDATE_FILE_HOSTS" = "yes" ] && [ -n "$HOSTNAME" ]; then + __grep_test " $HOSTNAME" "/etc/hosts" || __printf_space "40" "${CONTAINER_IP4_ADDRESS:-127.0.0.1}" "$HOSTNAME" >>"/etc/hosts" + __grep_test " ${HOSTNAME%%.*}.home" "/etc/hosts" || __printf_space "40" "${CONTAINER_IP4_ADDRESS:-127.0.0.1}" "${HOSTNAME%%.*}.home" >>"/etc/hosts" + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # add domainname + if [ "$UPDATE_FILE_HOSTS" = "yes" ] && [ "$DOMAINNAME" != "home" ] && [ -n "$DOMAINNAME" ] && [ "$HOSTNAME.$DOMAINNAME" != "$DOMAINNAME" ]; then + __grep_test " ${HOSTNAME%%.*}.$DOMAINNAME" "/etc/hosts" || __printf_space "40" "${CONTAINER_IP4_ADDRESS:-127.0.0.1}" "${HOSTNAME%%.*}.$DOMAINNAME" >>"/etc/hosts" + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Set containers hostname + [ -n "$HOSTNAME" ] && [ "$UPDATE_FILE_HOSTS" = "yes" ] && echo "$HOSTNAME" >"/etc/hostname" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Set containers hostname with domain + # [ -n "$DOMAINNAME" ] && [ "$UPDATE_FILE_HOSTS" = "yes" ] && echo "$HOSTNAME.$DOMAINNAME" >"/etc/hostname" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + if [ -f "/etc/hostname" ]; then + [ -n "$(type -P hostname)" ] && hostname -F "/etc/hostname" &>/dev/null || HOSTNAME="$(<"/etc/hostname")" + export HOSTNAME + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # import hosts file into container + [ -f "/usr/local/etc/hosts" ] && [ "$UPDATE_FILE_HOSTS" = "yes" ] && cat "/usr/local/etc/hosts" | grep -vF "$HOSTNAME" >>"/etc/hosts" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # import resolv.conf file into container + [ "$CUSTOM_DNS" != "yes" ] && [ -f "/usr/local/etc/resolv.conf" ] && [ "$UPDATE_FILE_RESOLV" = "yes" ] && cat "/usr/local/etc/resolv.conf" >"/etc/resolv.conf" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + if [ -n "$HOME" ] && [ -d "/usr/local/etc/skel" ]; then + [ -d "$HOME" ] && cp -Rf "/usr/local/etc/skel/." "$HOME/" + fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Delete any .gitkeep files +[ -d "/data" ] && rm -Rf "/data/.gitkeep" "/data"/*/*.gitkeep +[ -d "/config" ] && rm -Rf "/config/.gitkeep" "/config"/*/*.gitkeep +[ -f "/usr/local/bin/.gitkeep" ] && rm -Rf "/usr/local/bin/.gitkeep" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Setup bin directory - /config/bin > /usr/local/bin +__initialize_custom_bin_dir +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Copy default system configs - /usr/local/share/template-files/defaults > /config/ +__initialize_default_templates +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Copy custom config files - /usr/local/share/template-files/config > /config/ +__initialize_config_dir +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Copy custom data files - /usr/local/share/template-files/data > /data/ +__initialize_data_dir +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__initialize_ssl_certs +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if [ -f "$ENTRYPOINT_INIT_FILE" ]; then + ENTRYPOINT_FIRST_RUN="no" +fi +if [ -d "/config" ]; then + echo "Initialized on: $INIT_DATE" >"$ENTRYPOINT_INIT_FILE" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Check if this is a new container +if [ -f "$ENTRYPOINT_DATA_INIT_FILE" ]; then + DATA_DIR_INITIALIZED="yes" +fi +if [ -d "/data" ]; then + echo "Initialized on: $INIT_DATE" >"$ENTRYPOINT_DATA_INIT_FILE" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if [ -f "$ENTRYPOINT_CONFIG_INIT_FILE" ]; then + CONFIG_DIR_INITIALIZED="yes" +fi +if [ -d "/config" ]; then + echo "Initialized on: $INIT_DATE" >"$ENTRYPOINT_CONFIG_INIT_FILE" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if [ "$ENTRYPOINT_FIRST_RUN" != "no" ]; then + # setup the smtp server + __setup_mta +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# if no pid assume container restart - clean stale files on restart +if [ ! -f "$ENTRYPOINT_PID_FILE" ]; then + START_SERVICES="yes" + # Clean stale pid files from previous container runs + rm -f /run/__start_init_scripts.pid /run/init.d/*.pid /run/*.pid +elif [ ! -f "/run/__start_init_scripts.pid" ]; then + START_SERVICES="yes" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ "$ENTRYPOINT_MESSAGE" = "yes" ] && __printf_space "40" "Container ip address is:" "$CONTAINER_IP4_ADDRESS" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Show configured listing processes +if [ "$ENTRYPOINT_MESSAGE" = "yes" ] && [ -n "$ENV_PORTS" ]; then + show_port="" + for port in $ENV_PORTS; do [ -n "$port" ] && show_port+="$(printf '%s ' "${port// /}") "; done + __printf_space "40" "The following ports are open:" "$show_port" + unset port show_port +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# execute init script +if [ -f "/tmp/init" ]; then sh "/tmp/init"; fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create user if needed +__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Modify user if needed +__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Show message +__run_message +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Just start services +START_SERVICES="${START_SERVICES:-SYSTEM_INIT}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Start all services if no pidfile +if [ "$START_SERVICES" = "yes" ] && [ "$1" != "backup" ] && [ "$1" != "healthcheck" ] && [ "$1" != "cron" ] && [ "$1" != "logs" ] && [ "$1" != "cron" ]; then + [ "$1" = "start" ] && shift 1 + [ "$1" = "all" ] && shift 1 + [ "$1" = "init" ] && export CONTAINER_INIT="yes" + echo "$$" >"$ENTRYPOINT_PID_FILE" + rm -Rf "/run"/*/*pid + __start_init_scripts "/usr/local/etc/docker/init.d" + START_SERVICES="no" + CONTAINER_INIT="${CONTAINER_INIT:-no}" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Begin options +case "$1" in +init) + shift 1 + echo "Container has been Initialized" + exit 0 + ;; +logs) + shift 1 + case "$1" in + follow) + tail -Fq /data/logs/*/* + ;; + clean) + log_files="$(find "/data/logs" -type f)" + for log in "${log_files[@]}"; do + echo "clearing $log" + printf '' >$log + done + ;; + *) + echo "Usage: logs [follow,clean]" + exit 0 + ;; + esac + ;; +cron) + shift 1 + __cron "$@" & + echo "cron script is running with pid: $!" + exit + ;; +# backup data and config dirs +backup) + shift 1 + __backup $BACKUP_MAX_DAYS $1 + exit $? + ;; +# Docker healthcheck +healthcheck) + healthStatus=0 + services="${SERVICES_LIST:-$@}" + healthEnabled="${HEALTH_ENABLED:-}" + healthPorts="${WEB_SERVER_PORTS:-}" + healthEndPoints="${HEALTH_ENDPOINTS:-}" + healthMessage="Everything seems to be running" + services="${services//,/ }" + [ "$healthEnabled" = "yes" ] || exit 0 + { [ "$1" = "init" ] || [ "$1" = "test" ]; } && exit 0 + for proc in $services; do + if [ -n "$proc" ]; then + if ! __pgrep "$proc"; then + echo "$proc is not running" >&2 + healthStatus=$((healthStatus + 1)) + fi + fi + done + for port in $ports; do + if [ -n "$(type -P netstat)" ] && [ -n "$port" ]; then + if ! netstat -taupln | grep -q ":$port "; then + echo "$port isn't open" >&2 + healthStatus=$((healthStatus + 1)) + fi + fi + done + for endpoint in $healthEndPoints; do + if [ -n "$endpoint" ]; then + if ! __curl "$endpoint"; then + echo "Can not connect to $endpoint" >&2 + healthStatus=$((healthStatus + 1)) + fi + fi + done + [ "$healthStatus" -eq 0 ] || healthMessage="Errors reported see: docker logs --follow $CONTAINER_NAME" + [ -n "$healthMessage" ] && echo "$healthMessage" + exit $healthStatus + ;; + # show open ports +ports) + shift 1 + ports="$(__netstat -taupln | awk -F ' ' '{print $4}' | awk -F ':' '{print $2}' | sort --unique --version-sort | grep -v '^$' | grep '^' || echo '')" + [ -n "$ports" ] && printf '%s\n%s\n' "The following are servers:" "$ports" | tr '\n' ' ' + exit $? + ;; + # show running processes +procs) + shift 1 + ps="$(__ps axco command | grep -vE 'COMMAND|grep|ps' | sort -u || grep '^' || echo '')" + [ -n "$ps" ] && printf '%s\n%s\n' "Found the following processes" "$ps" | tr '\n' ' ' + exit $? + ;; + # setup ssl +ssl) + shift 1 + __create_ssl_cert + exit $? + ;; +# manage ssl certificate +certbot) + shift 1 + CERT_BOT_ENABLED="yes" + if [ "$1" = "create" ]; then + shift 1 + __certbot "create" + elif [ "$1" = "renew" ]; then + shift 1 + __certbot "renew certonly --force-renew" + else + __exec_command "certbot" "$@" + fi + exit $? + ;; +# Launch shell +*/bin/sh | */bin/bash | bash | sh | shell) + shift 1 + __exec_command "${@:-/bin/bash -l}" + exit $? + ;; +# execute commands +exec) + shift 1 + __exec_command "${@:-echo "No commands given"}" + exit $? + ;; +# show/start init scripts +start) + shift 1 + export PATH="/usr/local/etc/docker/init.d:$PATH" + if [ $# -eq 0 ]; then + scripts="$(ls -A "/usr/local/etc/docker/init.d")" + [ -n "$scripts" ] && echo "$scripts" || echo "No scripts found in: /usr/local/etc/docker/init.d" + exit + elif [ "$1" = "all" ]; then + shift $# + if [ "$START_SERVICES" = "yes" ]; then + echo "$$" >"$ENTRYPOINT_PID_FILE" + __start_init_scripts "/usr/local/etc/docker/init.d" + __no_exit + elif [ -f "/usr/local/etc/docker/init.d/$1" ]; then + eval "/usr/local/etc/docker/init.d/$1" & + __no_exit + + fi + fi + ;; +# Execute primary command +*) + if [ $# -eq 0 ]; then + if [ ! -f "$ENTRYPOINT_PID_FILE" ]; then + echo "$$" >"$ENTRYPOINT_PID_FILE" + [ "$START_SERVICES" = "no" ] && [ "$CONTAINER_INIT" = "yes" ] || __start_init_scripts "/usr/local/etc/docker/init.d" + fi + __no_exit + else + __exec_command "$@" + fi + exit $? + ;; +esac +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# end of entrypoint +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +# ex: ts=2 sw=2 et filetype=sh diff --git a/rootfs/usr/local/bin/pkmgr b/rootfs/usr/local/bin/pkmgr new file mode 100755 index 0000000..205c2b0 --- /dev/null +++ b/rootfs/usr/local/bin/pkmgr @@ -0,0 +1,142 @@ +#!/usr/bin/env sh +# shellcheck shell=sh +# shellcheck disable=SC2016 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +USER_UID="$(id -u)" +USER_GID="$(id -g)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if [ -x "$(command -v apt 2>/dev/null)" ]; then + export DEBIAN_FRONTEND=noninteractive + pkmgr_cmd="apt" + pkmgr_clean_cmd="$pkmgr_cmd clean" + pkmgr_mkcache_cmd="$pkmgr_cmd update" + pkmgr_update_cmd="$pkmgr_cmd upgrade -yy" + pkmgr_install_cmd="$pkmgr_cmd install -yy $PKMGR_OPTS" + pkmgr_install_post="$pkmgr_cmd --fix-broken install" +elif [ -x "$(command -v apt-get 2>/dev/null)" ]; then + export DEBIAN_FRONTEND=noninteractive + pkmgr_cmd="apt-get" + pkmgr_clean_cmd="$pkmgr_cmd clean" + pkmgr_mkcache_cmd="$pkmgr_cmd update" + pkmgr_update_cmd="$pkmgr_cmd upgrade -yy" + pkmgr_install_cmd="$pkmgr_cmd install -yy $PKMGR_OPTS" + pkmgr_install_post="$pkmgr_cmd --fix-broken install" +elif [ -x "$(command -v dnf 2>/dev/null)" ]; then + pkmgr_cmd="dnf" + pkmgr_clean_cmd="$pkmgr_cmd clean all" + pkmgr_mkcache_cmd="$pkmgr_cmd makecache" + pkmgr_update_cmd="$pkmgr_cmd update -y --skip-broken $PKMGR_OPTS" + pkmgr_install_cmd="$pkmgr_cmd install -y --skip-broken $PKMGR_OPTS" +elif [ -x "$(command -v yum 2>/dev/null)" ]; then + pkmgr_cmd="yum" + pkmgr_clean_cmd="$pkmgr_cmd clean all" + pkmgr_mkcache_cmd="$pkmgr_cmd makecache" + pkmgr_update_cmd="$pkmgr_cmd update -y --skip-broken $PKMGR_OPTS" + pkmgr_install_cmd="$pkmgr_cmd install -y --skip-broken $PKMGR_OPTS" +elif [ -n "$(command -v pacman 2>/dev/null)" ]; then + pkmgr_cmd="pacman" + pkmgr_mkcache_cmd="true" + pkmgr_clean_cmd="$pkmgr_cmd -Scc --noconfirm" + pkmgr_update_cmd="$pkmgr_cmd -Syyu --noconfirm $PKMGR_OPTS" + pkmgr_install_cmd="$pkmgr_cmd -Syy --noconfirm $PKMGR_OPTS" +elif [ -x "$(command -v apk 2>/dev/null)" ]; then + pkmgr_cmd="apk" + pkmgr_mkcache_cmd="true" + pkmgr_clean_cmd="$pkmgr_cmd cache clean" + pkmgr_update_cmd="$pkmgr_cmd -U upgrade --no-cache $PKMGR_OPTS" + pkmgr_install_cmd="$pkmgr_cmd add --no-cache $PKMGR_OPTS" +elif [ -x "$(command -v zypper 2>/dev/null)" ]; then + pkmgr_cmd="zypper" + pkmgr_mkcache_cmd="true" + pkmgr_clean_cmd="$pkmgr_cmd clean --all" + pkmgr_update_cmd="$pkmgr_cmd update -y $PKMGR_OPTS" + pkmgr_install_cmd="$pkmgr_cmd install -y $PKMGR_OPTS" +else + pkmgr_cmd="true" + pkmgr_mkcache_cmd="$pkmgr_cmd" + pkmgr_clean_cmd="$pkmgr_cmd" + pkmgr_update_cmd="$pkmgr_cmd" + pkmgr_install_cmd="$pkmgr_cmd" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if [ -f "/config/pkmgr/settings.conf" ]; then + . "/config/pkmgr/settings.conf" +elif [ -f "/etc/pkmgr/settings.conf" ]; then + . "/etc/pkmgr/settings.conf" +else + mkdir -p "/config/pkmgr" + cat <"/config/pkmgr/settings.conf" +pkmgr_cmd="$pkmgr_cmd" +pkmgr_clean_cmd="$pkmgr_clean_cmd" +pkmgr_update_cmd="$pkmgr_update_cmd" +pkmgr_install_cmd="$pkmgr_install_cmd" +pkmgr_mkcache_cmd="$pkmgr_mkcache_cmd" +EEOF +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ -n "$pkmgr_cmd" ] || { echo "Can not determine the package manager" && exit 1; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +case "$1" in +pip) + shift 1 + pip_bin="$(command -v python3 2>/dev/null || command -v python2 2>/dev/null || command -v python 2>/dev/null || echo "")" + py_version="$($pip_bin --version | sed 's|[pP]ython ||g' | awk -F '.' '{print $1$2}' | grep '[0-9]' || echo "0")" + [ "$py_version" -gt "310" ] && pip_opts="--break-system-packages " || pip_opts="" + case "$1" in + install) + shift 1 + pkg_list="$*" + for pkg in $pkg_list; do + $pip_bin -m pip $pip_opts "$pkg" + done + ;; + *) + for pkg in "$@"; do + $pip_bin -m pip "$pkg" + done + ;; + esac + exit + ;; +install) + shift 1 + [ -n "$1" ] || exit 0 + [ "$USER_UID" -eq 0 ] || [ "$USER" = "root" ] || pkmgr_install_cmd="sudo $pkmgr_install_cmd" + if [ -f "$1" ]; then + install_list="$(cat "$1")" + else + install_list="$*" + fi + for pkg in $install_list;do + echo "installing packages command: $pkmgr_install_cmd $pkg" + $pkmgr_install_cmd $pkg + if [ -n "$pkmgr_install_post" ]; then eval $pkmgr_install_post; fi + done + exit + ;; +update | upgrade) + shift $# + [ "$USER_UID" -eq 0 ] || [ "$USER" = "root" ] || pkmgr_update_cmd="sudo $pkmgr_install_cmd" + echo "Updating packages command: $pkmgr_update_cmd" + $pkmgr_mkcache_cmd + $pkmgr_update_cmd + exit $? + ;; +clean) + shift $# + [ -n "$1" ] || exit 0 + [ "$USER_UID" -eq 0 ] || [ "$USER" = "root" ] || pkmgr_clean_cmd="sudo $pkmgr_clean_cmd" + echo "Cleaning package cache: $pkmgr_clean_cmd" + $pkmgr_clean_cmd + exit $? + ;; +*) + [ -n "$1" ] || exit 0 + [ "$USER_UID" -eq 0 ] || [ "$USER" = "root" ] || pkmgr_cmd="sudo $pkmgr_cmd" + echo "executing packages command: $pkmgr_cmd $*" + $pkmgr_cmd "$@" + exit $? + ;; +esac +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# end diff --git a/rootfs/usr/local/etc/docker/init.d/01-tor-bridge.sh b/rootfs/usr/local/etc/docker/init.d/01-tor-bridge.sh new file mode 100755 index 0000000..4bffe0d --- /dev/null +++ b/rootfs/usr/local/etc/docker/init.d/01-tor-bridge.sh @@ -0,0 +1,751 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501060902-git +# @@Author : Jason Hempstead +# @@Contact : jason@casjaysdev.pro +# @@License : LICENSE.md +# @@ReadME : tor.sh --help +# @@Copyright : Copyright: (c) 2025 Jason Hempstead, Casjays Developments +# @@Created : Monday, Jan 06, 2025 09:02 EST +# @@File : tor.sh +# @@Description : +# @@Changelog : New script +# @@TODO : Better documentation +# @@Other : +# @@Resource : +# @@Terminal App : no +# @@sudo/root : no +# @@Template : other/start-service +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1003,SC2016,SC2031,SC2120,SC2155,SC2199,SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Exit if service is disabled +if [ "$TOR_BRIDGE_ENABLED" != "yes" ]; then exit 0; fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run trap command on exit +trap 'retVal=$?;[ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE";exit $retVal' SIGINT SIGTERM +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# setup debugging - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}" +{ [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; } && echo "Enabling debugging" && set -xo pipefail -x$DEBUGGER_OPTIONS && export DEBUGGER="on" || set -o pipefail +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +export PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SCRIPT_FILE="$0" +SERVICE_NAME="tor-bridge" +SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# exit if __start_init_scripts function hasn't been Initialized +if [ ! -f "/run/__start_init_scripts.pid" ]; then + echo "__start_init_scripts function hasn't been Initialized" >&2 + SERVICE_IS_RUNNING="no" + exit 1 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import the functions file +if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then + . "/usr/local/etc/docker/functions/entrypoint.sh" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import variables +for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do + [ -f "$set_env" ] && . "$set_env" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +printf '%s\n' "# - - - Initializing $SERVICE_NAME - - - #" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom functions + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Script to execute +START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Reset environment before executing service +RESET_ENV="yes" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set webroot +WWW_ROOT_DIR="/usr/local/share/httpd/default" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Default predefined variables +DATA_DIR="/data/tor/bridge" # set data directory +CONF_DIR="/config/tor/bridge" # set config directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the containers etc directory +ETC_DIR="/etc/tor/bridge" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the var dir +VAR_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TMP_DIR="/tmp/tor/bridge" # set the temp dir +RUN_DIR="/run/tor/bridge" # set scripts pid dir +LOG_DIR="/data/logs/tor" # set log directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the working dir +WORK_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# port which service is listening on +SERVICE_PORT="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User to use to launch service - IE: postgres +RUNAS_USER="root" # normally root +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User and group in which the service switches to - IE: nginx,apache,mysql,postgres +#SERVICE_USER="tor" # execute command as another user +#SERVICE_GROUP="tor" # Set the service group +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set password length +RANDOM_PASS_USER="" +RANDOM_PASS_ROOT="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set user and group ID +SERVICE_UID="0" # set the user id +SERVICE_GID="0" # set the group id +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# execute command variables - keep single quotes variables will be expanded later +EXEC_CMD_BIN='tor-bridge' # command to execute +EXEC_CMD_ARGS='-f $CONF_DIR/bridge.conf' # command arguments +EXEC_PRE_SCRIPT='' # execute script before +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a web server +IS_WEB_SERVER="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a database server +IS_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Does this service use a database server +USES_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set defualt type - [custom,sqlite,redis,postgres,mariadb,mysql,couchdb,mongodb,supabase] +DATABASE_SERVICE_TYPE="sqlite" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Show message before execute +PRE_EXEC_MESSAGE="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the wait time to execute __post_execute function - minutes +POST_EXECUTE_WAIT_TIME="1" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Update path var +PATH="$PATH:." +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Lets get containers ip address +IP4_ADDRESS="$(__get_ip4)" +IP6_ADDRESS="$(__get_ip6)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Where to save passwords to +ROOT_FILE_PREFIX="/config/secure/auth/root" # directory to save username/password for root user +USER_FILE_PREFIX="/config/secure/auth/user" # directory to save username/password for normal user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info password/random] +root_user_name="${TOR_ROOT_USER_NAME:-}" # root user name +root_user_pass="${TOR_ROOT_PASS_WORD:-}" # root user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Normal user info [password/random] +user_name="${TOR_USER_NAME:-}" # normal user name +user_pass="${TOR_USER_PASS_WORD:-}" # normal user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Load variables from config +[ -f "/config/env/tor.script.sh" ] && . "/config/env/tor.script.sh" # Generated by my dockermgr script +[ -f "/config/env/tor.sh" ] && . "/config/env/tor.sh" # Overwrite the variabes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional predefined variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Specifiy custom directories to be created +ADD_APPLICATION_FILES="" +ADD_APPLICATION_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +APPLICATION_FILES="" +APPLICATION_DIRS="$ETC_DIR $CONF_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional config dirs - will be Copied to /etc/$name +ADDITIONAL_CONFIG_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# define variables that need to be loaded into the service - escape quotes - var=\"value\",other=\"test\" +CMD_ENV="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Overwrite based on file/directory + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Per Application Variables or imports +TOR_DNS_ENABLED="${TOR_DNS_ENABLED:-yes}" +TOR_RELAY_ENABLED="${TOR_RELAY_ENABLED:-yes}" +TOR_BRIDGE_ENABLED="${TOR_BRIDGE_ENABLED:-yes}" +TOR_HIDDEN_ENABLED="${TOR_HIDDEN_ENABLED:-yes}" +RANDOM_NICK="$(head -n50 '/dev/random' | tr -dc 'a-zA-Z' | tr -d '[:space:]\042\047\134' | fold -w "32" | sed 's| ||g' | head -n 1)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom commands to run before copying to /config +__run_precopy() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + + # allow custom functions + if builtin type -t __run_precopy_local | grep -q 'function'; then __run_precopy_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom prerun functions - IE setup WWW_ROOT_DIR +__execute_prerun() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + + # allow custom functions + if builtin type -t __execute_prerun_local | grep -q 'function'; then __execute_prerun_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Run any pre-execution checks +__run_pre_execute_checks() { + # Set variables + local exitStatus=0 + local pre_execute_checks_MessageST="Running preexecute check for $SERVICE_NAME" # message to show at start + local pre_execute_checks_MessageEnd="Finished preexecute check for $SERVICE_NAME" # message to show at completion + __banner "$pre_execute_checks_MessageST" + # Put command to execute in parentheses + { + true + } + exitStatus=$? + __banner "$pre_execute_checks_MessageEnd: Status $exitStatus" + + # show exit message + if [ $exitStatus -ne 0 ]; then + echo "The pre-execution check has failed" >&2 + [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE" + exit 1 + fi + # allow custom functions + if builtin type -t __run_pre_execute_checks_local | grep -q 'function'; then __run_pre_execute_checks_local; fi + # exit function + return $exitStatus +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__update_conf_files() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # delete files + __rm "$CONF_DIR/bridge.conf" + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # custom commands + chmod 600 $RUN_DIR + chown -Rf ${SERVICE_USER:-$RUNAS_USER}:${SERVICE_GROUP:-$RUNAS_USER} $RUN_DIR + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # replace variables + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions + mkdir -p "$CONF_DIR/conf.d" + cat <>"$CONF_DIR/bridge.conf" +##### Bridge +RunAsDaemon 0 +HardwareAccel 1 +AddressDisableIPv6 0 + +#### control settings +ControlSocketsGroupWritable 1 +CookieAuthentication 1 +CookieAuthFileGroupReadable 1 +HashedControlPassword 16:C30604D1D90F341360A14D9A1048C1DF4A3CA2411444E52EE5B954C01F + +##### directiories and files +DataDirectory $DATA_DIR +ControlSocket $RUN_DIR/bridge.sock +CookieAuthFile $RUN_DIR/bridge.authcookie + +##### socks option +SOCKSPort 0 +SafeSocks ${TOR_SOCKS_SAFE:-0} +SocksTimeout ${TOR_SOCKS_TIMEOUT:-10} + +##### logging +LogMessageDomains 1 +Log notice file $LOG_DIR/bridge.log +#Log debug file $LOG_DIR/bridge.debug + +##### Bridge Settings +BridgeRelay 1 +ServerTransportPlugin obfs4 exec /usr/bin/lyrebird +ServerTransportListenAddr obfs4 0.0.0.0:${TOR_BRIDGE_PT_PORT:-57003} + +ORPort ${TOR_BRIDGE_OR_PORT:-57004} +DirPort ${TOR_BRIDGE_DIR_PORT:-57005} +Nickname ${TOR_BRIDGE_NICK_NAME:-$RANDOM_NICK} +ContactInfo ${TOR_BRIDGE_ADMIN:-tor-admin@$HOSTNAME} +AccountingMax ${TOR_BRIDGE_ACCOUNT_MAX:-250 GBytes} +RelayBandwidthRate ${TOR_BRIDGE_BANDWIDTH_RATE:-96 KB} +RelayBandwidthBurst ${TOR_BRIDGE_BANDWIDTH_BURST:-192 KB} +AccountingStart month 1 00:00 +PublishServerDescriptor 1 + +# Block ports +ExitPolicy reject *:25 +ExitPolicy reject *:465 +ExitPolicy reject *:587 +ExitPolicy reject *:135-139 +ExitPolicy accept *:* + +%include $CONF_DIR/conf.d/*.conf + +EOF + [ -f "$CONF_DIR/conf.d/default.conf" ] || touch "$CONF_DIR/conf.d/default.conf" + if [ "$TOR_DEBUG" = "yes" ]; then + sed -i 's|#Log debug|Log debug|g' "$CONF_DIR/bridge.conf" + fi + # allow custom functions + if builtin type -t __update_conf_files_local | grep -q 'function'; then __update_conf_files_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run before executing +__pre_execute() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute if directories is empty + # __is_dir_empty "$CONF_DIR" && true + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions to run after copying to /config + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # unset unneeded variables + unset sysname + # Lets wait a few seconds before continuing + sleep 5 + # allow custom functions + if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run after executing +__post_execute() { + local pid="" # init pid var + local retVal=0 # set default exit code + local ctime=${POST_EXECUTE_WAIT_TIME:-1} # how long to wait before executing + local waitTime=$((ctime * 60)) # convert minutes to seconds + local postMessageST="Running post commands for $SERVICE_NAME" # message to show at start + local postMessageEnd="Finished post commands for $SERVICE_NAME" # message to show at completion + # wait + sleep $waitTime + # execute commands after waiting + ( + # show message + __banner "$postMessageST" + # commands to execute + sleep 5 + # show exit message + __banner "$postMessageEnd: Status $retVal" + ) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & + pid=$! + ps ax | awk '{print $1}' | grep -v grep | grep -q "$execPid$" && retVal=0 || retVal=10 + # allow custom functions + if builtin type -t __post_execute_local | grep -q 'function'; then __post_execute_local; fi + # exit function + return $retVal +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__pre_message() { + local exitCode=0 + [ -n "$PRE_EXEC_MESSAGE" ] && eval echo "$PRE_EXEC_MESSAGE" + # execute commands + + # allow custom functions + if builtin type -t __pre_message_local | grep -q 'function'; then __pre_message_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to setup ssl support +__update_ssl_conf() { + local exitCode=0 + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute commands + + # allow custom functions + if builtin type -t __update_ssl_conf_local | grep -q 'function'; then __update_ssl_conf_local; fi + # set exitCode + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env() { + local exitCode=0 + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then + cat </dev/null +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info [password/random] +#ENV_ROOT_USER_NAME="${ENV_ROOT_USER_NAME:-$TOR_ROOT_USER_NAME}" # root user name +#ENV_ROOT_USER_PASS="${ENV_ROOT_USER_NAME:-$TOR_ROOT_PASS_WORD}" # root user password +#root_user_name="${ENV_ROOT_USER_NAME:-$root_user_name}" # +#root_user_pass="${ENV_ROOT_USER_PASS:-$root_user_pass}" # +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#Normal user info [password/random] +#ENV_USER_NAME="${ENV_USER_NAME:-$TOR_USER_NAME}" # +#ENV_USER_PASS="${ENV_USER_PASS:-$TOR_USER_PASS_WORD}" # +#user_name="${ENV_USER_NAME:-$user_name}" # normal user name +#user_pass="${ENV_USER_PASS:-$user_pass}" # normal user password + +EOF + fi + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" ]; then + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_precopy_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __execute_prerun_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_pre_execute_checks_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_conf_files_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __post_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_message_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_ssl_conf_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + fi + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" || exitCode=$((exitCode + 1)) + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" || exitCode=$((exitCode + 1)) + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# script to start server +__run_start_script() { + local runExitCode=0 + local workdir="$(eval echo "${WORK_DIR:-}")" # expand variables + local cmd="$(eval echo "${EXEC_CMD_BIN:-}")" # expand variables + local args="$(eval echo "${EXEC_CMD_ARGS:-}")" # expand variables + local name="$(eval echo "${EXEC_CMD_NAME:-}")" # expand variables + local pre="$(eval echo "${EXEC_PRE_SCRIPT:-}")" # expand variables + local extra_env="$(eval echo "${CMD_ENV//,/ }")" # expand variables + local lc_type="$(eval echo "${LANG:-${LC_ALL:-$LC_CTYPE}}")" # expand variables + local home="$(eval echo "${workdir//\/root/\/tmp\/docker}")" # expand variables + local path="$(eval echo "$PATH")" # expand variables + local message="$(eval echo "")" # expand variables + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + [ -f "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" ] && . "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" + # + if [ -z "$cmd" ]; then + __post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" + retVal=$? + echo "Initializing $SCRIPT_NAME has completed" + exit $retVal + else + # ensure the command exists + if [ ! -x "$cmd" ]; then + echo "$name is not a valid executable" + return 2 + fi + # check and exit if already running + if __proc_check "$name" || __proc_check "$cmd"; then + echo "$name is already running" >&2 + return 0 + else + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # show message if env exists + if [ -n "$cmd" ]; then + [ -n "$SERVICE_USER" ] && echo "Setting up $cmd to run as $SERVICE_USER" || SERVICE_USER="root" + [ -n "$SERVICE_PORT" ] && echo "$name will be running on port $SERVICE_PORT" || SERVICE_PORT="" + fi + if [ -n "$pre" ] && [ -n "$(command -v "$pre" 2>/dev/null)" ]; then + export cmd_exec="$pre $cmd $args" + message="Starting service: $name $args through $pre" + else + export cmd_exec="$cmd $args" + message="Starting service: $name $args" + fi + [ -n "$su_exec" ] && echo "using $su_exec" | tee -a -p "/data/logs/init.txt" + echo "$message" | tee -a -p "/data/logs/init.txt" + su_cmd touch "$SERVICE_PID_FILE" + if [ "$RESET_ENV" = "yes" ]; then + env_command="$(echo "env -i HOME=\"$home\" LC_CTYPE=\"$lc_type\" PATH=\"$path\" HOSTNAME=\"$sysname\" USER=\"${SERVICE_USER:-$RUNAS_USER}\" $extra_env")" + execute_command="$(__trim "$su_exec $env_command $cmd_exec")" + if [ ! -f "$START_SCRIPT" ]; then + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} with env +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 +exit \$retVal + +EOF + fi + else + if [ ! -f "$START_SCRIPT" ]; then + execute_command="$(__trim "$su_exec $cmd_exec")" + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 >&2 +exit \$retVal + +EOF + fi + fi + fi + [ -x "$START_SCRIPT" ] || chmod 755 -Rf "$START_SCRIPT" + [ "$CONTAINER_INIT" = "yes" ] || eval sh -c "$START_SCRIPT" + runExitCode=$? + fi + return $runExitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# username and password actions +__run_secure_function() { + local filesperms + if [ -n "$user_name" ] || [ -n "$user_pass" ]; then + for filesperms in "${USER_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + if [ -n "$root_user_name" ] || [ -n "$root_user_pass" ]; then + for filesperms in "${ROOT_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + unset filesperms +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow ENV_ variable - Import env file +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SERVICE_EXIT_CODE=0 # default exit code +# application specific +EXEC_CMD_NAME="$(basename -- "$EXEC_CMD_BIN")" # set the binary name +SERVICE_PID_FILE="/run/init.d/$EXEC_CMD_NAME.pid" # set the pid file location +SERVICE_PID_NUMBER="$(__pgrep)" # check if running +EXEC_CMD_BIN="$(type -P "$EXEC_CMD_BIN" || echo "$EXEC_CMD_BIN")" # set full path +EXEC_PRE_SCRIPT="$(type -P "$EXEC_PRE_SCRIPT" || echo "$EXEC_PRE_SCRIPT")" # set full path +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Only run check +__check_service "$1" && SERVICE_IS_RUNNING=yes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# ensure needed directories exists +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create auth directories +[ -n "$USER_FILE_PREFIX" ] && { [ -d "$USER_FILE_PREFIX" ] || mkdir -p "$USER_FILE_PREFIX"; } +[ -n "$ROOT_FILE_PREFIX" ] && { [ -d "$ROOT_FILE_PREFIX" ] || mkdir -p "$ROOT_FILE_PREFIX"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ -n "$RUNAS_USER" ] || RUNAS_USER="root" +[ -n "$SERVICE_USER" ] || SERVICE_USER="$RUNAS_USER" +[ -n "$SERVICE_GROUP" ] || SERVICE_GROUP="${SERVICE_USER:-$RUNAS_USER}" +[ "$IS_WEB_SERVER" = "yes" ] && RESET_ENV="yes" && __is_htdocs_mounted +[ "$IS_WEB_SERVER" = "yes" ] && [ -z "$SERVICE_PORT" ] && SERVICE_PORT="80" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Database env +if [ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ]; then + RESET_ENV="no" + DATABASE_CREATE="${ENV_DATABASE_CREATE:-$DATABASE_CREATE}" + DATABASE_USER_NORMAL="${ENV_DATABASE_USER:-${DATABASE_USER_NORMAL:-$user_name}}" + DATABASE_PASS_NORMAL="${ENV_DATABASE_PASSWORD:-${DATABASE_PASS_NORMAL:-$user_pass}}" + DATABASE_USER_ROOT="${ENV_DATABASE_ROOT_USER:-${DATABASE_USER_ROOT:-$root_user_name}}" + DATABASE_PASS_ROOT="${ENV_DATABASE_ROOT_PASSWORD:-${DATABASE_PASS_ROOT:-$root_user_pass}}" + if [ -n "$DATABASE_PASS_NORMAL" ] && [ ! -f "${USER_FILE_PREFIX}/db_pass_user" ]; then + echo "$DATABASE_PASS_NORMAL" >"${USER_FILE_PREFIX}/db_pass_user" + fi + if [ -n "$DATABASE_PASS_ROOT" ] && [ ! -f "${ROOT_FILE_PREFIX}/db_pass_root" ]; then + echo "$DATABASE_PASS_ROOT" >"${ROOT_FILE_PREFIX}/db_pass_root" + fi +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# [DATABASE_DIR_[SQLITE,REDIS,POSTGRES,MARIADB,COUCHDB,MONGODB,SUPABASE]] +if [ "$DATABASE_SERVICE_TYPE" = "custom" ]; then + DATABASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_BASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_CUSTOM:-/usr/local/share/httpd/admin/databases}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_CUSTOM:-/admin/dbadmin}" +elif [ "$SERVICE_NAME" = "redis" ] || [ "$DATABASE_SERVICE_TYPE" = "redis" ]; then + DATABASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_BASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_REDIS:-/usr/local/share/httpd/admin/redis}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_REDIS:-/admin/redis}" +elif [ "$SERVICE_NAME" = "postgres" ] || [ "$DATABASE_SERVICE_TYPE" = "postgres" ]; then + DATABASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_BASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_POSTGRES:-/usr/local/share/httpd/admin/postgres}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_POSTGRES:-/admin/postgres}" +elif [ "$SERVICE_NAME" = "mariadb" ] || [ "$DATABASE_SERVICE_TYPE" = "mariadb" ]; then + DATABASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MARIADB:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MARIADB:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "mysql" ] || [ "$DATABASE_SERVICE_TYPE" = "mysql" ]; then + DATABASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_BASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MYSQL:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MYSQL:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "couchdb" ] || [ "$DATABASE_SERVICE_TYPE" = "couchdb" ]; then + DATABASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_BASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_COUCHDB:-/usr/local/share/httpd/admin/couchdb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_COUCHDB:-/admin/couchdb}" +elif [ "$SERVICE_NAME" = "mongodb" ] || [ "$DATABASE_SERVICE_TYPE" = "mongodb" ]; then + DATABASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MONGODB:-/usr/local/share/httpd/admin/mongodb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MONGODB:-/admin/mongodb}" +elif [ "$SERVICE_NAME" = "supabase" ] || [ "$DATABASE_SERVICE_TYPE" = "supabase" ]; then + DATABASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_BASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SUPABASE:-/usr/local/share/httpd/admin/supabase}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SUPBASE:-/admin/supabase}" +elif [ "$SERVICE_NAME" = "sqlite" ] || [ "$DATABASE_SERVICE_TYPE" = "sqlite" ]; then + DATABASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_BASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SQLITE:-/usr/local/share/httpd/admin/sqlite}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SQLITE:-/admin/sqlite}" + [ -d "$DATABASE_DIR" ] || mkdir -p "$DATABASE_DIR" + chmod 777 "$DATABASE_DIR" +fi +[ -n "$DATABASE_ADMIN_WWW_ROOT" ] && { [ ! -d "$DATABASE_ADMIN_WWW_ROOT" ] || mkdir -p "${DATABASE_ADMIN_WWW_ROOT}"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow variables via imports - Overwrite existing +[ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ] && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set password to random if variable is random +[ "$user_pass" = "random" ] && user_pass="$(__random_password ${RANDOM_PASS_USER:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ "$root_user_pass" = "random" ] && root_user_pass="$(__random_password ${RANDOM_PASS_ROOT:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow setting initial users and passwords via environment and save to file +[ -n "$user_name" ] && echo "$user_name" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$user_pass" ] && echo "$user_pass" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" +[ -n "$root_user_name" ] && echo "$root_user_name" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$root_user_pass" ] && echo "$root_user_pass" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create needed dirs +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow per init script usernames and passwords +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_name" && user_name="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" && user_pass="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" && root_user_name="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" && root_user_pass="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${USER_FILE_PREFIX}/db_pass_user" && DATABASE_PASS_NORMAL="$(<"${USER_FILE_PREFIX}/db_pass_user")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/db_pass_root" && DATABASE_PASS_ROOT="$(<"${ROOT_FILE_PREFIX}/db_pass_root")" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set hostname for script +sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Setup /config directories +__init_config_etc +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# pre-run function +__execute_prerun +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create user if needed +__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Modify user if needed +__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Create base directories +__setup_directories +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set switch user command +__switch_to_user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize the home/working dir +__init_working_dir +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# show init message +__pre_message +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_db_users +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize ssl +__update_ssl_conf +__update_ssl_certs +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions in ${USER_FILE_PREFIX} and ${ROOT_FILE_PREFIX} +__run_secure_function +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_precopy +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Copy /config to /etc +for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do + __initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Replace variables +__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_database +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Updating config files +__update_conf_files +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run the pre execute commands +__pre_execute +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions +__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log" +errorCode=$? +if [ -n "$EXEC_CMD_BIN" ]; then + if [ "$errorCode" -eq 0 ]; then + SERVICE_EXIT_CODE=0 + SERVICE_IS_RUNNING="yes" + else + SERVICE_EXIT_CODE=$errorCode + SERVICE_IS_RUNNING="${SERVICE_IS_RUNNING:-no}" + [ -s "$SERVICE_PID_FILE" ] || rm -Rf "$SERVICE_PID_FILE" + fi + SERVICE_EXIT_CODE=0 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# start the post execute function in background +__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__banner "Initializing of $SERVICE_NAME has completed with statusCode: $SERVICE_EXIT_CODE" | tee -p -a "/data/logs/entrypoint.log" "/data/logs/init.txt" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $SERVICE_EXIT_CODE diff --git a/rootfs/usr/local/etc/docker/init.d/02-tor-relay.sh b/rootfs/usr/local/etc/docker/init.d/02-tor-relay.sh new file mode 100755 index 0000000..32559d8 --- /dev/null +++ b/rootfs/usr/local/etc/docker/init.d/02-tor-relay.sh @@ -0,0 +1,753 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501060902-git +# @@Author : Jason Hempstead +# @@Contact : jason@casjaysdev.pro +# @@License : LICENSE.md +# @@ReadME : tor.sh --help +# @@Copyright : Copyright: (c) 2025 Jason Hempstead, Casjays Developments +# @@Created : Monday, Jan 06, 2025 09:02 EST +# @@File : tor.sh +# @@Description : +# @@Changelog : New script +# @@TODO : Better documentation +# @@Other : +# @@Resource : +# @@Terminal App : no +# @@sudo/root : no +# @@Template : other/start-service +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1003,SC2016,SC2031,SC2120,SC2155,SC2199,SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Exit if service is disabled +if [ "$TOR_RELAY_ENABLED" != "yes" ]; then exit 0; fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run trap command on exit +trap 'retVal=$?;[ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE";exit $retVal' SIGINT SIGTERM +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# setup debugging - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}" +{ [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; } && echo "Enabling debugging" && set -xo pipefail -x$DEBUGGER_OPTIONS && export DEBUGGER="on" || set -o pipefail +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +export PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SCRIPT_FILE="$0" +SERVICE_NAME="tor-relay" +SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# exit if __start_init_scripts function hasn't been Initialized +if [ ! -f "/run/__start_init_scripts.pid" ]; then + echo "__start_init_scripts function hasn't been Initialized" >&2 + SERVICE_IS_RUNNING="no" + exit 1 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import the functions file +if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then + . "/usr/local/etc/docker/functions/entrypoint.sh" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import variables +for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do + [ -f "$set_env" ] && . "$set_env" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +printf '%s\n' "# - - - Initializing $SERVICE_NAME - - - #" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom functions + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Script to execute +START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Reset environment before executing service +RESET_ENV="yes" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set webroot +WWW_ROOT_DIR="/usr/local/share/httpd/default" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Default predefined variables +DATA_DIR="/data/tor/relay" # set data directory +CONF_DIR="/config/tor/relay" # set config directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the containers etc directory +ETC_DIR="/etc/tor/relay" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the var dir +VAR_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TMP_DIR="/tmp/tor" # set the temp dir +RUN_DIR="/run/tor/relay" # set scripts pid dir +LOG_DIR="/data/logs/tor" # set log directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the working dir +WORK_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# port which service is listening on +SERVICE_PORT="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User to use to launch service - IE: postgres +RUNAS_USER="root" # normally root +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User and group in which the service switches to - IE: nginx,apache,mysql,postgres +#SERVICE_USER="tor" # execute command as another user +#SERVICE_GROUP="tor" # Set the service group +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set password length +RANDOM_PASS_USER="" +RANDOM_PASS_ROOT="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set user and group ID +SERVICE_UID="0" # set the user id +SERVICE_GID="0" # set the group id +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# execute command variables - keep single quotes variables will be expanded later +EXEC_CMD_BIN='tor-relay' # command to execute +EXEC_CMD_ARGS='-f $CONF_DIR/relay.conf' # command arguments +EXEC_PRE_SCRIPT='' # execute script before +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a web server +IS_WEB_SERVER="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a database server +IS_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Does this service use a database server +USES_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set defualt type - [custom,sqlite,redis,postgres,mariadb,mysql,couchdb,mongodb,supabase] +DATABASE_SERVICE_TYPE="sqlite" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Show message before execute +PRE_EXEC_MESSAGE="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the wait time to execute __post_execute function - minutes +POST_EXECUTE_WAIT_TIME="1" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Update path var +PATH="$PATH:." +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Lets get containers ip address +IP4_ADDRESS="$(__get_ip4)" +IP6_ADDRESS="$(__get_ip6)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Where to save passwords to +ROOT_FILE_PREFIX="/config/secure/auth/root" # directory to save username/password for root user +USER_FILE_PREFIX="/config/secure/auth/user" # directory to save username/password for normal user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info password/random] +root_user_name="${TOR_ROOT_USER_NAME:-}" # root user name +root_user_pass="${TOR_ROOT_PASS_WORD:-}" # root user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Normal user info [password/random] +user_name="${TOR_USER_NAME:-}" # normal user name +user_pass="${TOR_USER_PASS_WORD:-}" # normal user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Load variables from config +[ -f "/config/env/tor.script.sh" ] && . "/config/env/tor.script.sh" # Generated by my dockermgr script +[ -f "/config/env/tor.sh" ] && . "/config/env/tor.sh" # Overwrite the variabes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional predefined variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Specifiy custom directories to be created +ADD_APPLICATION_FILES="" +ADD_APPLICATION_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +APPLICATION_FILES="" +APPLICATION_DIRS="$ETC_DIR $CONF_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional config dirs - will be Copied to /etc/$name +ADDITIONAL_CONFIG_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# define variables that need to be loaded into the service - escape quotes - var=\"value\",other=\"test\" +CMD_ENV="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Overwrite based on file/directory + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Per Application Variables or imports +TOR_DNS_ENABLED="${TOR_DNS_ENABLED:-yes}" +TOR_RELAY_ENABLED="${TOR_RELAY_ENABLED:-yes}" +TOR_BRIDGE_ENABLED="${TOR_BRIDGE_ENABLED:-yes}" +TOR_HIDDEN_ENABLED="${TOR_HIDDEN_ENABLED:-yes}" +RANDOM_NICK="$(head -n50 '/dev/random' | tr -dc 'a-zA-Z' | tr -d '[:space:]\042\047\134' | fold -w "32" | sed 's| ||g' | head -n 1)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom commands to run before copying to /config +__run_precopy() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + + # allow custom functions + if builtin type -t __run_precopy_local | grep -q 'function'; then __run_precopy_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom prerun functions - IE setup WWW_ROOT_DIR +__execute_prerun() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + + # allow custom functions + if builtin type -t __execute_prerun_local | grep -q 'function'; then __execute_prerun_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Run any pre-execution checks +__run_pre_execute_checks() { + # Set variables + local exitStatus=0 + local pre_execute_checks_MessageST="Running preexecute check for $SERVICE_NAME" # message to show at start + local pre_execute_checks_MessageEnd="Finished preexecute check for $SERVICE_NAME" # message to show at completion + __banner "$pre_execute_checks_MessageST" + # Put command to execute in parentheses + { + true + } + exitStatus=$? + __banner "$pre_execute_checks_MessageEnd: Status $exitStatus" + + # show exit message + if [ $exitStatus -ne 0 ]; then + echo "The pre-execution check has failed" >&2 + [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE" + exit 1 + fi + # allow custom functions + if builtin type -t __run_pre_execute_checks_local | grep -q 'function'; then __run_pre_execute_checks_local; fi + # exit function + return $exitStatus +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__update_conf_files() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # delete files + #__rm "" + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # custom commands + chmod 600 $RUN_DIR + chown -Rf ${SERVICE_USER:-$RUNAS_USER}:${SERVICE_GROUP:-$RUNAS_USER} $RUN_DIR + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # replace variables + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions + mkdir -p "$CONF_DIR/conf.d" + cat <"$CONF_DIR/relay.conf" +##### Relay +RunAsDaemon 0 +HardwareAccel 1 +AddressDisableIPv6 0 + +#### control settings +ControlSocketsGroupWritable 1 +CookieAuthentication 1 +CookieAuthFileGroupReadable 1 +HashedControlPassword 16:C30604D1D90F341360A14D9A1048C1DF4A3CA2411444E52EE5B954C01F + +##### directiories and files +DataDirectory $DATA_DIR +ControlSocket $RUN_DIR/relay.sock +CookieAuthFile $RUN_DIR/relay.authcookie + +##### socks option +SOCKSPort 0 +SafeSocks ${TOR_SOCKS_SAFE:-0} +SocksTimeout ${TOR_SOCKS_TIMEOUT:-10} + +##### logging +LogMessageDomains 1 +Log notice file $LOG_DIR/relay.log +#Log debug file $LOG_DIR/relay.debug + +##### Relay Settings +ServerTransportPlugin obfs4 exec /usr/bin/lyrebird +ServerTransportListenAddr obfs4 0.0.0.0:${TOR_RELAY_PORT:-57000} +ORPort ${TOR_RELAY_OR_PORT:-57001} +DirPort ${TOR_RELAY_DIR_PORT:-57002} + +ExitRelay 1 +PublishServerDescriptor 1 +Nickname ${TOR_RELAY_NICK_NAME:-$RANDOM_NICK} +ContactInfo ${TOR_RELAY_ADMIN:-tor-admin@$HOSTNAME} +AccountingMax ${TOR_RELAY_ACCOUNT_MAX:-250 GBytes} +RelayBandwidthRate ${TOR_RELAY_BANDWIDTH_RATE:-96 KB} +RelayBandwidthBurst ${TOR_RELAY_BANDWIDTH_BURST:-192 KB} +AccountingStart month 1 00:00 +DirPortFrontPage /usr/share/tor/html/exit.html + +# Block ports +ExitPolicy reject *:25 +ExitPolicy reject *:465 +ExitPolicy reject *:587 +ExitPolicy reject *:135-139 +ExitPolicy accept *:* + +%include $CONF_DIR/conf.d/*.conf + +EOF + [ -f "$CONF_DIR/conf.d/default.conf" ] || touch "$CONF_DIR/conf.d/default.conf" + if [ "$TOR_DEBUG" = "yes" ]; then + sed -i 's|#Log debug|Log debug|g' "$CONF_DIR/relay.conf" + fi + + # allow custom functions + if builtin type -t __update_conf_files_local | grep -q 'function'; then __update_conf_files_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run before executing +__pre_execute() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute if directories is empty + # __is_dir_empty "$CONF_DIR" && true + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions to run after copying to /config + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # unset unneeded variables + unset sysname + # Lets wait a few seconds before continuing + sleep 5 + # allow custom functions + if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run after executing +__post_execute() { + local pid="" # init pid var + local retVal=0 # set default exit code + local ctime=${POST_EXECUTE_WAIT_TIME:-1} # how long to wait before executing + local waitTime=$((ctime * 60)) # convert minutes to seconds + local postMessageST="Running post commands for $SERVICE_NAME" # message to show at start + local postMessageEnd="Finished post commands for $SERVICE_NAME" # message to show at completion + # wait + sleep $waitTime + # execute commands after waiting + ( + # show message + __banner "$postMessageST" + # commands to execute + sleep 5 + # show exit message + __banner "$postMessageEnd: Status $retVal" + ) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & + pid=$! + ps ax | awk '{print $1}' | grep -v grep | grep -q "$execPid$" && retVal=0 || retVal=10 + # allow custom functions + if builtin type -t __post_execute_local | grep -q 'function'; then __post_execute_local; fi + # exit function + return $retVal +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__pre_message() { + local exitCode=0 + [ -n "$PRE_EXEC_MESSAGE" ] && eval echo "$PRE_EXEC_MESSAGE" + # execute commands + + # allow custom functions + if builtin type -t __pre_message_local | grep -q 'function'; then __pre_message_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to setup ssl support +__update_ssl_conf() { + local exitCode=0 + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute commands + + # allow custom functions + if builtin type -t __update_ssl_conf_local | grep -q 'function'; then __update_ssl_conf_local; fi + # set exitCode + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env() { + local exitCode=0 + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then + cat </dev/null +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info [password/random] +#ENV_ROOT_USER_NAME="${ENV_ROOT_USER_NAME:-$TOR_ROOT_USER_NAME}" # root user name +#ENV_ROOT_USER_PASS="${ENV_ROOT_USER_NAME:-$TOR_ROOT_PASS_WORD}" # root user password +#root_user_name="${ENV_ROOT_USER_NAME:-$root_user_name}" # +#root_user_pass="${ENV_ROOT_USER_PASS:-$root_user_pass}" # +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#Normal user info [password/random] +#ENV_USER_NAME="${ENV_USER_NAME:-$TOR_USER_NAME}" # +#ENV_USER_PASS="${ENV_USER_PASS:-$TOR_USER_PASS_WORD}" # +#user_name="${ENV_USER_NAME:-$user_name}" # normal user name +#user_pass="${ENV_USER_PASS:-$user_pass}" # normal user password + +EOF + fi + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" ]; then + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_precopy_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __execute_prerun_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_pre_execute_checks_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_conf_files_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __post_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_message_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_ssl_conf_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + fi + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" || exitCode=$((exitCode + 1)) + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" || exitCode=$((exitCode + 1)) + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# script to start server +__run_start_script() { + local runExitCode=0 + local workdir="$(eval echo "${WORK_DIR:-}")" # expand variables + local cmd="$(eval echo "${EXEC_CMD_BIN:-}")" # expand variables + local args="$(eval echo "${EXEC_CMD_ARGS:-}")" # expand variables + local name="$(eval echo "${EXEC_CMD_NAME:-}")" # expand variables + local pre="$(eval echo "${EXEC_PRE_SCRIPT:-}")" # expand variables + local extra_env="$(eval echo "${CMD_ENV//,/ }")" # expand variables + local lc_type="$(eval echo "${LANG:-${LC_ALL:-$LC_CTYPE}}")" # expand variables + local home="$(eval echo "${workdir//\/root/\/tmp\/docker}")" # expand variables + local path="$(eval echo "$PATH")" # expand variables + local message="$(eval echo "")" # expand variables + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + [ -f "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" ] && . "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" + # + if [ -z "$cmd" ]; then + __post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" + retVal=$? + echo "Initializing $SCRIPT_NAME has completed" + exit $retVal + else + # ensure the command exists + if [ ! -x "$cmd" ]; then + echo "$name is not a valid executable" + return 2 + fi + # check and exit if already running + if __proc_check "$name" || __proc_check "$cmd"; then + echo "$name is already running" >&2 + return 0 + else + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # show message if env exists + if [ -n "$cmd" ]; then + [ -n "$SERVICE_USER" ] && echo "Setting up $cmd to run as $SERVICE_USER" || SERVICE_USER="root" + [ -n "$SERVICE_PORT" ] && echo "$name will be running on port $SERVICE_PORT" || SERVICE_PORT="" + fi + if [ -n "$pre" ] && [ -n "$(command -v "$pre" 2>/dev/null)" ]; then + export cmd_exec="$pre $cmd $args" + message="Starting service: $name $args through $pre" + else + export cmd_exec="$cmd $args" + message="Starting service: $name $args" + fi + [ -n "$su_exec" ] && echo "using $su_exec" | tee -a -p "/data/logs/init.txt" + echo "$message" | tee -a -p "/data/logs/init.txt" + su_cmd touch "$SERVICE_PID_FILE" + if [ "$RESET_ENV" = "yes" ]; then + env_command="$(echo "env -i HOME=\"$home\" LC_CTYPE=\"$lc_type\" PATH=\"$path\" HOSTNAME=\"$sysname\" USER=\"${SERVICE_USER:-$RUNAS_USER}\" $extra_env")" + execute_command="$(__trim "$su_exec $env_command $cmd_exec")" + if [ ! -f "$START_SCRIPT" ]; then + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} with env +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 +exit \$retVal + +EOF + fi + else + if [ ! -f "$START_SCRIPT" ]; then + execute_command="$(__trim "$su_exec $cmd_exec")" + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 >&2 +exit \$retVal + +EOF + fi + fi + fi + [ -x "$START_SCRIPT" ] || chmod 755 -Rf "$START_SCRIPT" + [ "$CONTAINER_INIT" = "yes" ] || eval sh -c "$START_SCRIPT" + runExitCode=$? + fi + return $runExitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# username and password actions +__run_secure_function() { + local filesperms + if [ -n "$user_name" ] || [ -n "$user_pass" ]; then + for filesperms in "${USER_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + if [ -n "$root_user_name" ] || [ -n "$root_user_pass" ]; then + for filesperms in "${ROOT_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + unset filesperms +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow ENV_ variable - Import env file +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SERVICE_EXIT_CODE=0 # default exit code +# application specific +EXEC_CMD_NAME="$(basename -- "$EXEC_CMD_BIN")" # set the binary name +SERVICE_PID_FILE="/run/init.d/$EXEC_CMD_NAME.pid" # set the pid file location +SERVICE_PID_NUMBER="$(__pgrep)" # check if running +EXEC_CMD_BIN="$(type -P "$EXEC_CMD_BIN" || echo "$EXEC_CMD_BIN")" # set full path +EXEC_PRE_SCRIPT="$(type -P "$EXEC_PRE_SCRIPT" || echo "$EXEC_PRE_SCRIPT")" # set full path +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Only run check +__check_service "$1" && SERVICE_IS_RUNNING=yes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# ensure needed directories exists +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create auth directories +[ -n "$USER_FILE_PREFIX" ] && { [ -d "$USER_FILE_PREFIX" ] || mkdir -p "$USER_FILE_PREFIX"; } +[ -n "$ROOT_FILE_PREFIX" ] && { [ -d "$ROOT_FILE_PREFIX" ] || mkdir -p "$ROOT_FILE_PREFIX"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ -n "$RUNAS_USER" ] || RUNAS_USER="root" +[ -n "$SERVICE_USER" ] || SERVICE_USER="$RUNAS_USER" +[ -n "$SERVICE_GROUP" ] || SERVICE_GROUP="${SERVICE_USER:-$RUNAS_USER}" +[ "$IS_WEB_SERVER" = "yes" ] && RESET_ENV="yes" && __is_htdocs_mounted +[ "$IS_WEB_SERVER" = "yes" ] && [ -z "$SERVICE_PORT" ] && SERVICE_PORT="80" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Database env +if [ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ]; then + RESET_ENV="no" + DATABASE_CREATE="${ENV_DATABASE_CREATE:-$DATABASE_CREATE}" + DATABASE_USER_NORMAL="${ENV_DATABASE_USER:-${DATABASE_USER_NORMAL:-$user_name}}" + DATABASE_PASS_NORMAL="${ENV_DATABASE_PASSWORD:-${DATABASE_PASS_NORMAL:-$user_pass}}" + DATABASE_USER_ROOT="${ENV_DATABASE_ROOT_USER:-${DATABASE_USER_ROOT:-$root_user_name}}" + DATABASE_PASS_ROOT="${ENV_DATABASE_ROOT_PASSWORD:-${DATABASE_PASS_ROOT:-$root_user_pass}}" + if [ -n "$DATABASE_PASS_NORMAL" ] && [ ! -f "${USER_FILE_PREFIX}/db_pass_user" ]; then + echo "$DATABASE_PASS_NORMAL" >"${USER_FILE_PREFIX}/db_pass_user" + fi + if [ -n "$DATABASE_PASS_ROOT" ] && [ ! -f "${ROOT_FILE_PREFIX}/db_pass_root" ]; then + echo "$DATABASE_PASS_ROOT" >"${ROOT_FILE_PREFIX}/db_pass_root" + fi +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# [DATABASE_DIR_[SQLITE,REDIS,POSTGRES,MARIADB,COUCHDB,MONGODB,SUPABASE]] +if [ "$DATABASE_SERVICE_TYPE" = "custom" ]; then + DATABASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_BASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_CUSTOM:-/usr/local/share/httpd/admin/databases}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_CUSTOM:-/admin/dbadmin}" +elif [ "$SERVICE_NAME" = "redis" ] || [ "$DATABASE_SERVICE_TYPE" = "redis" ]; then + DATABASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_BASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_REDIS:-/usr/local/share/httpd/admin/redis}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_REDIS:-/admin/redis}" +elif [ "$SERVICE_NAME" = "postgres" ] || [ "$DATABASE_SERVICE_TYPE" = "postgres" ]; then + DATABASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_BASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_POSTGRES:-/usr/local/share/httpd/admin/postgres}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_POSTGRES:-/admin/postgres}" +elif [ "$SERVICE_NAME" = "mariadb" ] || [ "$DATABASE_SERVICE_TYPE" = "mariadb" ]; then + DATABASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MARIADB:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MARIADB:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "mysql" ] || [ "$DATABASE_SERVICE_TYPE" = "mysql" ]; then + DATABASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_BASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MYSQL:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MYSQL:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "couchdb" ] || [ "$DATABASE_SERVICE_TYPE" = "couchdb" ]; then + DATABASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_BASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_COUCHDB:-/usr/local/share/httpd/admin/couchdb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_COUCHDB:-/admin/couchdb}" +elif [ "$SERVICE_NAME" = "mongodb" ] || [ "$DATABASE_SERVICE_TYPE" = "mongodb" ]; then + DATABASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MONGODB:-/usr/local/share/httpd/admin/mongodb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MONGODB:-/admin/mongodb}" +elif [ "$SERVICE_NAME" = "supabase" ] || [ "$DATABASE_SERVICE_TYPE" = "supabase" ]; then + DATABASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_BASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SUPABASE:-/usr/local/share/httpd/admin/supabase}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SUPBASE:-/admin/supabase}" +elif [ "$SERVICE_NAME" = "sqlite" ] || [ "$DATABASE_SERVICE_TYPE" = "sqlite" ]; then + DATABASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_BASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SQLITE:-/usr/local/share/httpd/admin/sqlite}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SQLITE:-/admin/sqlite}" + [ -d "$DATABASE_DIR" ] || mkdir -p "$DATABASE_DIR" + chmod 777 "$DATABASE_DIR" +fi +[ -n "$DATABASE_ADMIN_WWW_ROOT" ] && { [ ! -d "$DATABASE_ADMIN_WWW_ROOT" ] || mkdir -p "${DATABASE_ADMIN_WWW_ROOT}"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow variables via imports - Overwrite existing +[ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ] && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set password to random if variable is random +[ "$user_pass" = "random" ] && user_pass="$(__random_password ${RANDOM_PASS_USER:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ "$root_user_pass" = "random" ] && root_user_pass="$(__random_password ${RANDOM_PASS_ROOT:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow setting initial users and passwords via environment and save to file +[ -n "$user_name" ] && echo "$user_name" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$user_pass" ] && echo "$user_pass" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" +[ -n "$root_user_name" ] && echo "$root_user_name" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$root_user_pass" ] && echo "$root_user_pass" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create needed dirs +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow per init script usernames and passwords +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_name" && user_name="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" && user_pass="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" && root_user_name="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" && root_user_pass="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${USER_FILE_PREFIX}/db_pass_user" && DATABASE_PASS_NORMAL="$(<"${USER_FILE_PREFIX}/db_pass_user")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/db_pass_root" && DATABASE_PASS_ROOT="$(<"${ROOT_FILE_PREFIX}/db_pass_root")" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set hostname for script +sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Setup /config directories +__init_config_etc +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# pre-run function +__execute_prerun +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create user if needed +__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Modify user if needed +__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Create base directories +__setup_directories +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set switch user command +__switch_to_user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize the home/working dir +__init_working_dir +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# show init message +__pre_message +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_db_users +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize ssl +__update_ssl_conf +__update_ssl_certs +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions in ${USER_FILE_PREFIX} and ${ROOT_FILE_PREFIX} +__run_secure_function +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_precopy +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Copy /config to /etc +for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do + __initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Replace variables +__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_database +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Updating config files +__update_conf_files +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run the pre execute commands +__pre_execute +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions +__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log" +errorCode=$? +if [ -n "$EXEC_CMD_BIN" ]; then + if [ "$errorCode" -eq 0 ]; then + SERVICE_EXIT_CODE=0 + SERVICE_IS_RUNNING="yes" + else + SERVICE_EXIT_CODE=$errorCode + SERVICE_IS_RUNNING="${SERVICE_IS_RUNNING:-no}" + [ -s "$SERVICE_PID_FILE" ] || rm -Rf "$SERVICE_PID_FILE" + fi + SERVICE_EXIT_CODE=0 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# start the post execute function in background +__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__banner "Initializing of $SERVICE_NAME has completed with statusCode: $SERVICE_EXIT_CODE" | tee -p -a "/data/logs/entrypoint.log" "/data/logs/init.txt" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $SERVICE_EXIT_CODE diff --git a/rootfs/usr/local/etc/docker/init.d/03-tor-server.sh b/rootfs/usr/local/etc/docker/init.d/03-tor-server.sh new file mode 100755 index 0000000..c1dd744 --- /dev/null +++ b/rootfs/usr/local/etc/docker/init.d/03-tor-server.sh @@ -0,0 +1,806 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501060902-git +# @@Author : Jason Hempstead +# @@Contact : jason@casjaysdev.pro +# @@License : LICENSE.md +# @@ReadME : tor.sh --help +# @@Copyright : Copyright: (c) 2025 Jason Hempstead, Casjays Developments +# @@Created : Monday, Jan 06, 2025 09:02 EST +# @@File : tor.sh +# @@Description : +# @@Changelog : New script +# @@TODO : Better documentation +# @@Other : +# @@Resource : +# @@Terminal App : no +# @@sudo/root : no +# @@Template : other/start-service +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1003,SC2016,SC2031,SC2120,SC2155,SC2199,SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run trap command on exit +trap 'retVal=$?;[ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE";exit $retVal' SIGINT SIGTERM +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# setup debugging - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}" +{ [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; } && echo "Enabling debugging" && set -xo pipefail -x$DEBUGGER_OPTIONS && export DEBUGGER="on" || set -o pipefail +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +export PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SCRIPT_FILE="$0" +SERVICE_NAME="tor-server" +SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# exit if __start_init_scripts function hasn't been Initialized +if [ ! -f "/run/__start_init_scripts.pid" ]; then + echo "__start_init_scripts function hasn't been Initialized" >&2 + SERVICE_IS_RUNNING="no" + exit 1 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import the functions file +if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then + . "/usr/local/etc/docker/functions/entrypoint.sh" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import variables +for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do + [ -f "$set_env" ] && . "$set_env" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +printf '%s\n' "# - - - Initializing $SERVICE_NAME - - - #" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom functions + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Script to execute +START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Reset environment before executing service +RESET_ENV="yes" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set webroot +WWW_ROOT_DIR="/usr/local/share/httpd/default" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Default predefined variables +DATA_DIR="/data/tor/server" # set data directory +CONF_DIR="/config/tor/server" # set config directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the containers etc directory +ETC_DIR="/etc/tor/server" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the var dir +VAR_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TMP_DIR="/tmp/tor/server" # set the temp dir +RUN_DIR="/run/tor/server" # set scripts pid dir +LOG_DIR="/data/logs/tor" # set log directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the working dir +WORK_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# port which service is listening on +SERVICE_PORT="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User to use to launch service - IE: postgres +RUNAS_USER="root" # normally root +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User and group in which the service switches to - IE: nginx,apache,mysql,postgres +#SERVICE_USER="tor" # execute command as another user +#SERVICE_GROUP="tor" # Set the service group +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set password length +RANDOM_PASS_USER="" +RANDOM_PASS_ROOT="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set user and group ID +SERVICE_UID="0" # set the user id +SERVICE_GID="0" # set the group id +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# execute command variables - keep single quotes variables will be expanded later +EXEC_CMD_BIN='tor-server' # command to execute +EXEC_CMD_ARGS='-f $CONF_DIR/server.conf' # command arguments +EXEC_PRE_SCRIPT='' # execute script before +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a web server +IS_WEB_SERVER="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a database server +IS_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Does this service use a database server +USES_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set defualt type - [custom,sqlite,redis,postgres,mariadb,mysql,couchdb,mongodb,supabase] +DATABASE_SERVICE_TYPE="sqlite" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Show message before execute +PRE_EXEC_MESSAGE="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the wait time to execute __post_execute function - minutes +POST_EXECUTE_WAIT_TIME="5" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Update path var +PATH="$PATH:." +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Lets get containers ip address +IP4_ADDRESS="$(__get_ip4)" +IP6_ADDRESS="$(__get_ip6)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Where to save passwords to +ROOT_FILE_PREFIX="/config/secure/auth/root" # directory to save username/password for root user +USER_FILE_PREFIX="/config/secure/auth/user" # directory to save username/password for normal user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info password/random] +root_user_name="${TOR_ROOT_USER_NAME:-}" # root user name +root_user_pass="${TOR_ROOT_PASS_WORD:-}" # root user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Normal user info [password/random] +user_name="${TOR_USER_NAME:-}" # normal user name +user_pass="${TOR_USER_PASS_WORD:-}" # normal user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Load variables from config +[ -f "/config/env/tor.script.sh" ] && . "/config/env/tor.script.sh" # Generated by my dockermgr script +[ -f "/config/env/tor.sh" ] && . "/config/env/tor.sh" # Overwrite the variabes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional predefined variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional variables +TOR_HIDDEN_SERVERS="${TOR_HIDDEN_SERVERS//,/ }" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Specifiy custom directories to be created +ADD_APPLICATION_FILES="" +ADD_APPLICATION_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +APPLICATION_FILES="" +APPLICATION_DIRS="$ETC_DIR $CONF_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional config dirs - will be Copied to /etc/$name +ADDITIONAL_CONFIG_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# define variables that need to be loaded into the service - escape quotes - var=\"value\",other=\"test\" +CMD_ENV="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Overwrite based on file/directory + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Per Application Variables or imports +TOR_DNS_ENABLED="${TOR_DNS_ENABLED:-yes}" +TOR_RELAY_ENABLED="${TOR_RELAY_ENABLED:-yes}" +TOR_BRIDGE_ENABLED="${TOR_BRIDGE_ENABLED:-yes}" +TOR_HIDDEN_ENABLED="${TOR_HIDDEN_ENABLED:-yes}" +RANDOM_NICK="$(head -n50 '/dev/random' | tr -dc 'a-zA-Z' | tr -d '[:space:]\042\047\134' | fold -w "32" | sed 's| ||g' | head -n 1)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom commands to run before copying to /config +__run_precopy() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + + # allow custom functions + if builtin type -t __run_precopy_local | grep -q 'function'; then __run_precopy_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom prerun functions - IE setup WWW_ROOT_DIR +__execute_prerun() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + touch "/tmp/init_tor_services" + # allow custom functions + if builtin type -t __execute_prerun_local | grep -q 'function'; then __execute_prerun_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Run any pre-execution checks +__run_pre_execute_checks() { + # Set variables + local exitStatus=0 + local pre_execute_checks_MessageST="Running preexecute check for $SERVICE_NAME" # message to show at start + local pre_execute_checks_MessageEnd="Finished preexecute check for $SERVICE_NAME" # message to show at completion + __banner "$pre_execute_checks_MessageST" + # Put command to execute in parentheses + { + true + } + exitStatus=$? + __banner "$pre_execute_checks_MessageEnd: Status $exitStatus" + + # show exit message + if [ $exitStatus -ne 0 ]; then + echo "The pre-execution check has failed" >&2 + [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE" + exit 1 + fi + # allow custom functions + if builtin type -t __run_pre_execute_checks_local | grep -q 'function'; then __run_pre_execute_checks_local; fi + # exit function + return $exitStatus +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__update_conf_files() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # delete files + __rm "$CONF_DIR/server.conf" + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # custom commands + chmod 600 $RUN_DIR + chown -Rf ${SERVICE_USER:-$RUNAS_USER}:${SERVICE_GROUP:-$RUNAS_USER} $RUN_DIR + mkdir -p "/run/tor/sites" && chmod 777 "/run/tor/sites" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # replace variables + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + cat <>"$CONF_DIR/server.conf" +##### Server +RunAsDaemon 0 +HardwareAccel 1 +AddressDisableIPv6 0 +#VirtualAddrNetwork 10.0.0.0/12 + +#### control settings +ControlPort 127.0.0.1:9051 +ControlSocketsGroupWritable 1 +CookieAuthentication 1 +CookieAuthFileGroupReadable 1 +HashedControlPassword 16:C30604D1D90F341360A14D9A1048C1DF4A3CA2411444E52EE5B954C01F + +##### bandwidth and accounting (monitoring only) +Nickname ${TOR_SERVER_NICK_NAME:-$RANDOM_NICK} +ContactInfo ${TOR_SERVER_ADMIN:-tor-admin@$HOSTNAME} +AccountingMax ${TOR_SERVER_ACCOUNT_MAX:-250 GBytes} +AccountingStart month 1 00:00 + +##### directiories and files +DataDirectory $DATA_DIR +ControlSocket $RUN_DIR/server.sock +CookieAuthFile $RUN_DIR/server.authcookie + +##### socks option +SOCKSPort 0.0.0.0:9050 +SafeSocks ${TOR_SOCKS_SAFE:-0} +SocksTimeout ${TOR_SOCKS_TIMEOUT:-10} + +##### logging +LogMessageDomains 1 +Log notice file $LOG_DIR/server.log + +##### port mappings +TransPort 0.0.0.0:9040 +HTTPTunnelPort 0.0.0.0:9080 + +##### hidden services +HiddenServiceDir ${TOR_HIDDEN_SERVICE_DIR:-$DATA_DIR/hidden_service} +HiddenServicePort ${TOR_HIDDEN_SERVICE_PORT:-80 127.0.0.1:80} + +##### security +SafeLogging 1 +UseEntryGuards 1 +NumEntryGuards 3 +DisableAllSwap 1 + +##### exit relay +ExcludeNodes {ru},{cn},{ir},{kp},{sy} + +EOF + # define actions + if [ "$TOR_DNS_ENABLED" = "yes" ]; then + SHOW_HIDDEN_HOSTNAMES=yes + mkdir -p "$CONF_DIR/conf.d" + cat <>"$CONF_DIR/server.conf" +#### dns forwarder +Log notice file $LOG_DIR/dns.log +DNSPort 0.0.0.0:8053 +DNSListenAddress 0.0.0.0,[::] +AutomapHostsOnResolve 1 +AutomapHostsSuffixes .exit,.onion + +EOF + fi + + if [ "$TOR_HIDDEN_ENABLED" = "yes" ]; then + mkdir -p "$CONF_DIR/hidden.d" + mkdir -p "$DATA_DIR/services" + chmod 700 "$DATA_DIR/services" + cat <>"$CONF_DIR/server.conf" +#### hidden services +HiddenServiceDir $DATA_DIR/services/default +HiddenServicePort 80 127.0.0.1:80 +%include $CONF_DIR/hidden.d/*.conf + +EOF + fi + + cat <>"$CONF_DIR/server.conf" +##### include configurations +%include $CONF_DIR/conf.d/*.conf + +EOF + if [ "$TOR_DEBUG" = "yes" ]; then + sed -i 's|#Log debug|Log debug|g' "$CONF_DIR/server.conf" + fi + + # allow custom functions + if builtin type -t __update_conf_files_local | grep -q 'function'; then __update_conf_files_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run before executing +__pre_execute() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute if directories is empty + # __is_dir_empty "$CONF_DIR" && true + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions to run after copying to /config + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # unset unneeded variables + unset sysname + # Lets wait a few seconds before continuing + sleep 5 + # allow custom functions + if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run after executing +__post_execute() { + local pid="" # init pid var + local retVal=0 # set default exit code + local ctime=${POST_EXECUTE_WAIT_TIME:-1} # how long to wait before executing + local waitTime=$((ctime * 60)) # convert minutes to seconds + local postMessageST="Running post commands for $SERVICE_NAME" # message to show at start + local postMessageEnd="Finished post commands for $SERVICE_NAME" # message to show at completion + # wait + sleep $waitTime + # execute commands after waiting + ( + # commands to execute + while :; do + if pgrep unbound >/dev/null 2>&1; then + break + else + sleep 10 + fi + done + # show message + __banner "$postMessageST" + if [ -d "/data/htdocs/www" ]; then + WWW_ROOT_DIR="/data/htdocs/www" + fi + if [ -d "$DATA_DIR/services" ]; then + echo "Begin current hidden services"htdocs + [ -f "$WWW_ROOT_DIR/hostnames.html" ] && rm -f "$WWW_ROOT_DIR/hostnames.html" + for host in "$DATA_DIR/services"/*/hostname; do + d="$(dirname -- $host)" + name="$(basename "$d")" + url="$(<"$host")" + site="$(echo "$url" | sed 's|\.onion$||g')" + echo "$name: $url" + touch "/run/tor/sites/$site" + echo ''$name'
' >>"$WWW_ROOT_DIR/hostnames.html" + if [ "$name" = "default" ]; then echo "$site" >"$WWW_ROOT_DIR/default_host.txt"; fi + done + echo "End current hidden services" + fi + [ -f "/tmp/init_tor_services" ] && rm -Rf "/tmp/init_tor_services" + (while :; do sleep 10 && __pgrep $EXEC_CMD_BIN >/dev/null || eval $EXEC_CMD_BIN $EXEC_CMD_ARGS >/dev/null; done &) + # show exit message + __banner "$postMessageEnd: Status $retVal" + ) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & + pid=$! + ps ax | awk '{print $1}' | grep -v grep | grep -q "$execPid$" && retVal=0 || retVal=10 + # allow custom functions + if builtin type -t __post_execute_local | grep -q 'function'; then __post_execute_local; fi + # exit function + return $retVal +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__pre_message() { + local exitCode=0 + [ -n "$PRE_EXEC_MESSAGE" ] && eval echo "$PRE_EXEC_MESSAGE" + # execute commands + + # allow custom functions + if builtin type -t __pre_message_local | grep -q 'function'; then __pre_message_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to setup ssl support +__update_ssl_conf() { + local exitCode=0 + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute commands + + # allow custom functions + if builtin type -t __update_ssl_conf_local | grep -q 'function'; then __update_ssl_conf_local; fi + # set exitCode + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env() { + local exitCode=0 + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then + cat </dev/null +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info [password/random] +#ENV_ROOT_USER_NAME="${ENV_ROOT_USER_NAME:-$TOR_ROOT_USER_NAME}" # root user name +#ENV_ROOT_USER_PASS="${ENV_ROOT_USER_NAME:-$TOR_ROOT_PASS_WORD}" # root user password +#root_user_name="${ENV_ROOT_USER_NAME:-$root_user_name}" # +#root_user_pass="${ENV_ROOT_USER_PASS:-$root_user_pass}" # +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#Normal user info [password/random] +#ENV_USER_NAME="${ENV_USER_NAME:-$TOR_USER_NAME}" # +#ENV_USER_PASS="${ENV_USER_PASS:-$TOR_USER_PASS_WORD}" # +#user_name="${ENV_USER_NAME:-$user_name}" # normal user name +#user_pass="${ENV_USER_PASS:-$user_pass}" # normal user password + +EOF + fi + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" ]; then + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_precopy_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __execute_prerun_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_pre_execute_checks_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_conf_files_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __post_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_message_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_ssl_conf_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + fi + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" || exitCode=$((exitCode + 1)) + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" || exitCode=$((exitCode + 1)) + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# script to start server +__run_start_script() { + local runExitCode=0 + local workdir="$(eval echo "${WORK_DIR:-}")" # expand variables + local cmd="$(eval echo "${EXEC_CMD_BIN:-}")" # expand variables + local args="$(eval echo "${EXEC_CMD_ARGS:-}")" # expand variables + local name="$(eval echo "${EXEC_CMD_NAME:-}")" # expand variables + local pre="$(eval echo "${EXEC_PRE_SCRIPT:-}")" # expand variables + local extra_env="$(eval echo "${CMD_ENV//,/ }")" # expand variables + local lc_type="$(eval echo "${LANG:-${LC_ALL:-$LC_CTYPE}}")" # expand variables + local home="$(eval echo "${workdir//\/root/\/tmp\/docker}")" # expand variables + local path="$(eval echo "$PATH")" # expand variables + local message="$(eval echo "")" # expand variables + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + [ -f "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" ] && . "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" + # + if [ -z "$cmd" ]; then + __post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" + retVal=$? + echo "Initializing $SCRIPT_NAME has completed" + exit $retVal + else + # ensure the command exists + if [ ! -x "$cmd" ]; then + echo "$name is not a valid executable" + return 2 + fi + # check and exit if already running + if __proc_check "$name" || __proc_check "$cmd"; then + echo "$name is already running" >&2 + return 0 + else + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # show message if env exists + if [ -n "$cmd" ]; then + [ -n "$SERVICE_USER" ] && echo "Setting up $cmd to run as $SERVICE_USER" || SERVICE_USER="root" + [ -n "$SERVICE_PORT" ] && echo "$name will be running on port $SERVICE_PORT" || SERVICE_PORT="" + fi + if [ -n "$pre" ] && [ -n "$(command -v "$pre" 2>/dev/null)" ]; then + export cmd_exec="$pre $cmd $args" + message="Starting service: $name $args through $pre" + else + export cmd_exec="$cmd $args" + message="Starting service: $name $args" + fi + [ -n "$su_exec" ] && echo "using $su_exec" | tee -a -p "/data/logs/init.txt" + echo "$message" | tee -a -p "/data/logs/init.txt" + su_cmd touch "$SERVICE_PID_FILE" + if [ "$RESET_ENV" = "yes" ]; then + env_command="$(echo "env -i HOME=\"$home\" LC_CTYPE=\"$lc_type\" PATH=\"$path\" HOSTNAME=\"$sysname\" USER=\"${SERVICE_USER:-$RUNAS_USER}\" $extra_env")" + execute_command="$(__trim "$su_exec $env_command $cmd_exec")" + if [ ! -f "$START_SCRIPT" ]; then + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} with env +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 +exit \$retVal + +EOF + fi + else + if [ ! -f "$START_SCRIPT" ]; then + execute_command="$(__trim "$su_exec $cmd_exec")" + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 >&2 +exit \$retVal + +EOF + fi + fi + fi + [ -x "$START_SCRIPT" ] || chmod 755 -Rf "$START_SCRIPT" + [ "$CONTAINER_INIT" = "yes" ] || eval sh -c "$START_SCRIPT" + runExitCode=$? + fi + return $runExitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# username and password actions +__run_secure_function() { + local filesperms + if [ -n "$user_name" ] || [ -n "$user_pass" ]; then + for filesperms in "${USER_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + if [ -n "$root_user_name" ] || [ -n "$root_user_pass" ]; then + for filesperms in "${ROOT_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + unset filesperms +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow ENV_ variable - Import env file +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SERVICE_EXIT_CODE=0 # default exit code +# application specific +EXEC_CMD_NAME="$(basename -- "$EXEC_CMD_BIN")" # set the binary name +SERVICE_PID_FILE="/run/init.d/$EXEC_CMD_NAME.pid" # set the pid file location +SERVICE_PID_NUMBER="$(__pgrep)" # check if running +EXEC_CMD_BIN="$(type -P "$EXEC_CMD_BIN" || echo "$EXEC_CMD_BIN")" # set full path +EXEC_PRE_SCRIPT="$(type -P "$EXEC_PRE_SCRIPT" || echo "$EXEC_PRE_SCRIPT")" # set full path +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Only run check +__check_service "$1" && SERVICE_IS_RUNNING=yes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# ensure needed directories exists +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create auth directories +[ -n "$USER_FILE_PREFIX" ] && { [ -d "$USER_FILE_PREFIX" ] || mkdir -p "$USER_FILE_PREFIX"; } +[ -n "$ROOT_FILE_PREFIX" ] && { [ -d "$ROOT_FILE_PREFIX" ] || mkdir -p "$ROOT_FILE_PREFIX"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ -n "$RUNAS_USER" ] || RUNAS_USER="root" +[ -n "$SERVICE_USER" ] || SERVICE_USER="$RUNAS_USER" +[ -n "$SERVICE_GROUP" ] || SERVICE_GROUP="${SERVICE_USER:-$RUNAS_USER}" +[ "$IS_WEB_SERVER" = "yes" ] && RESET_ENV="yes" && __is_htdocs_mounted +[ "$IS_WEB_SERVER" = "yes" ] && [ -z "$SERVICE_PORT" ] && SERVICE_PORT="80" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Database env +if [ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ]; then + RESET_ENV="no" + DATABASE_CREATE="${ENV_DATABASE_CREATE:-$DATABASE_CREATE}" + DATABASE_USER_NORMAL="${ENV_DATABASE_USER:-${DATABASE_USER_NORMAL:-$user_name}}" + DATABASE_PASS_NORMAL="${ENV_DATABASE_PASSWORD:-${DATABASE_PASS_NORMAL:-$user_pass}}" + DATABASE_USER_ROOT="${ENV_DATABASE_ROOT_USER:-${DATABASE_USER_ROOT:-$root_user_name}}" + DATABASE_PASS_ROOT="${ENV_DATABASE_ROOT_PASSWORD:-${DATABASE_PASS_ROOT:-$root_user_pass}}" + if [ -n "$DATABASE_PASS_NORMAL" ] && [ ! -f "${USER_FILE_PREFIX}/db_pass_user" ]; then + echo "$DATABASE_PASS_NORMAL" >"${USER_FILE_PREFIX}/db_pass_user" + fi + if [ -n "$DATABASE_PASS_ROOT" ] && [ ! -f "${ROOT_FILE_PREFIX}/db_pass_root" ]; then + echo "$DATABASE_PASS_ROOT" >"${ROOT_FILE_PREFIX}/db_pass_root" + fi +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# [DATABASE_DIR_[SQLITE,REDIS,POSTGRES,MARIADB,COUCHDB,MONGODB,SUPABASE]] +if [ "$DATABASE_SERVICE_TYPE" = "custom" ]; then + DATABASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_BASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_CUSTOM:-/usr/local/share/httpd/admin/databases}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_CUSTOM:-/admin/dbadmin}" +elif [ "$SERVICE_NAME" = "redis" ] || [ "$DATABASE_SERVICE_TYPE" = "redis" ]; then + DATABASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_BASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_REDIS:-/usr/local/share/httpd/admin/redis}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_REDIS:-/admin/redis}" +elif [ "$SERVICE_NAME" = "postgres" ] || [ "$DATABASE_SERVICE_TYPE" = "postgres" ]; then + DATABASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_BASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_POSTGRES:-/usr/local/share/httpd/admin/postgres}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_POSTGRES:-/admin/postgres}" +elif [ "$SERVICE_NAME" = "mariadb" ] || [ "$DATABASE_SERVICE_TYPE" = "mariadb" ]; then + DATABASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MARIADB:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MARIADB:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "mysql" ] || [ "$DATABASE_SERVICE_TYPE" = "mysql" ]; then + DATABASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_BASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MYSQL:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MYSQL:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "couchdb" ] || [ "$DATABASE_SERVICE_TYPE" = "couchdb" ]; then + DATABASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_BASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_COUCHDB:-/usr/local/share/httpd/admin/couchdb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_COUCHDB:-/admin/couchdb}" +elif [ "$SERVICE_NAME" = "mongodb" ] || [ "$DATABASE_SERVICE_TYPE" = "mongodb" ]; then + DATABASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MONGODB:-/usr/local/share/httpd/admin/mongodb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MONGODB:-/admin/mongodb}" +elif [ "$SERVICE_NAME" = "supabase" ] || [ "$DATABASE_SERVICE_TYPE" = "supabase" ]; then + DATABASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_BASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SUPABASE:-/usr/local/share/httpd/admin/supabase}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SUPBASE:-/admin/supabase}" +elif [ "$SERVICE_NAME" = "sqlite" ] || [ "$DATABASE_SERVICE_TYPE" = "sqlite" ]; then + DATABASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_BASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SQLITE:-/usr/local/share/httpd/admin/sqlite}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SQLITE:-/admin/sqlite}" + [ -d "$DATABASE_DIR" ] || mkdir -p "$DATABASE_DIR" + chmod 777 "$DATABASE_DIR" +fi +[ -n "$DATABASE_ADMIN_WWW_ROOT" ] && { [ ! -d "$DATABASE_ADMIN_WWW_ROOT" ] || mkdir -p "${DATABASE_ADMIN_WWW_ROOT}"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow variables via imports - Overwrite existing +[ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ] && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set password to random if variable is random +[ "$user_pass" = "random" ] && user_pass="$(__random_password ${RANDOM_PASS_USER:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ "$root_user_pass" = "random" ] && root_user_pass="$(__random_password ${RANDOM_PASS_ROOT:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow setting initial users and passwords via environment and save to file +[ -n "$user_name" ] && echo "$user_name" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$user_pass" ] && echo "$user_pass" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" +[ -n "$root_user_name" ] && echo "$root_user_name" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$root_user_pass" ] && echo "$root_user_pass" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create needed dirs +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow per init script usernames and passwords +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_name" && user_name="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" && user_pass="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" && root_user_name="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" && root_user_pass="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${USER_FILE_PREFIX}/db_pass_user" && DATABASE_PASS_NORMAL="$(<"${USER_FILE_PREFIX}/db_pass_user")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/db_pass_root" && DATABASE_PASS_ROOT="$(<"${ROOT_FILE_PREFIX}/db_pass_root")" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set hostname for script +sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Setup /config directories +__init_config_etc +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# pre-run function +__execute_prerun +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create user if needed +__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Modify user if needed +__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Create base directories +__setup_directories +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set switch user command +__switch_to_user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize the home/working dir +__init_working_dir +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# show init message +__pre_message +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_db_users +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize ssl +__update_ssl_conf +__update_ssl_certs +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions in ${USER_FILE_PREFIX} and ${ROOT_FILE_PREFIX} +__run_secure_function +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_precopy +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Copy /config to /etc +for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do + __initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Replace variables +__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_database +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Updating config files +__update_conf_files +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run the pre execute commands +__pre_execute +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions +__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log" +errorCode=$? +if [ -n "$EXEC_CMD_BIN" ]; then + if [ "$errorCode" -eq 0 ]; then + SERVICE_EXIT_CODE=0 + SERVICE_IS_RUNNING="yes" + else + SERVICE_EXIT_CODE=$errorCode + SERVICE_IS_RUNNING="${SERVICE_IS_RUNNING:-no}" + [ -s "$SERVICE_PID_FILE" ] || rm -Rf "$SERVICE_PID_FILE" + fi + SERVICE_EXIT_CODE=0 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# start the post execute function in background +__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__banner "Initializing of $SERVICE_NAME has completed with statusCode: $SERVICE_EXIT_CODE" | tee -p -a "/data/logs/entrypoint.log" "/data/logs/init.txt" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $SERVICE_EXIT_CODE diff --git a/rootfs/usr/local/etc/docker/init.d/09-unbound.sh b/rootfs/usr/local/etc/docker/init.d/09-unbound.sh new file mode 100755 index 0000000..3ee5f47 --- /dev/null +++ b/rootfs/usr/local/etc/docker/init.d/09-unbound.sh @@ -0,0 +1,690 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501082150-git +# @@Author : Jason Hempstead +# @@Contact : jason@casjaysdev.pro +# @@License : LICENSE.md +# @@ReadME : 09-unbound.sh --help +# @@Copyright : Copyright: (c) 2025 Jason Hempstead, Casjays Developments +# @@Created : Wednesday, Jan 08, 2025 21:50 EST +# @@File : 09-unbound.sh +# @@Description : +# @@Changelog : New script +# @@TODO : Better documentation +# @@Other : +# @@Resource : +# @@Terminal App : no +# @@sudo/root : no +# @@Template : other/start-service +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1003,SC2016,SC2031,SC2120,SC2155,SC2199,SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run trap command on exit +trap 'retVal=$?;[ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE";exit $retVal' SIGINT SIGTERM +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# setup debugging - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}" +{ [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; } && echo "Enabling debugging" && set -xo pipefail -x$DEBUGGER_OPTIONS && export DEBUGGER="on" || set -o pipefail +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +export PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SCRIPT_FILE="$0" +SERVICE_NAME="unbound" +SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# exit if __start_init_scripts function hasn't been Initialized +if [ ! -f "/run/__start_init_scripts.pid" ]; then + echo "__start_init_scripts function hasn't been Initialized" >&2 + SERVICE_IS_RUNNING="no" + exit 1 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import the functions file +if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then + . "/usr/local/etc/docker/functions/entrypoint.sh" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import variables +for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do + [ -f "$set_env" ] && . "$set_env" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +printf '%s\n' "# - - - Initializing $SERVICE_NAME - - - #" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom functions + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Script to execute +START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Reset environment before executing service +RESET_ENV="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set webroot +WWW_ROOT_DIR="/usr/local/share/httpd/default" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Default predefined variables +DATA_DIR="/data/unbound" # set data directory +CONF_DIR="/config/unbound" # set config directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the containers etc directory +ETC_DIR="/etc/unbound" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the var dir +VAR_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TMP_DIR="/tmp/unbound" # set the temp dir +RUN_DIR="/run/unbound" # set scripts pid dir +LOG_DIR="/data/logs/unbound" # set log directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the working dir +WORK_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# port which service is listening on +SERVICE_PORT="9053" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User to use to launch service - IE: postgres +RUNAS_USER="root" # normally root +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User and group in which the service switches to - IE: nginx,apache,mysql,postgres +#SERVICE_USER="unbound" # execute command as another user +#SERVICE_GROUP="unbound" # Set the service group +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set password length +RANDOM_PASS_USER="" +RANDOM_PASS_ROOT="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set user and group ID +SERVICE_UID="0" # set the user id +SERVICE_GID="0" # set the group id +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# execute command variables - keep single quotes variables will be expanded later +EXEC_CMD_BIN='unbound' # command to execute +EXEC_CMD_ARGS='-d -c $CONF_DIR/unbound.conf ' # command arguments +EXEC_PRE_SCRIPT='unbound-checkconfig -f $CONF_DIR/unbound.conf' # execute script before +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a web server +IS_WEB_SERVER="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a database server +IS_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Does this service use a database server +USES_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set defualt type - [custom,sqlite,redis,postgres,mariadb,mysql,couchdb,mongodb,supabase] +DATABASE_SERVICE_TYPE="sqlite" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Show message before execute +PRE_EXEC_MESSAGE="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the wait time to execute __post_execute function - minutes +POST_EXECUTE_WAIT_TIME="1" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Update path var +PATH="$PATH:." +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Lets get containers ip address +IP4_ADDRESS="$(__get_ip4)" +IP6_ADDRESS="$(__get_ip6)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Where to save passwords to +ROOT_FILE_PREFIX="/config/secure/auth/root" # directory to save username/password for root user +USER_FILE_PREFIX="/config/secure/auth/user" # directory to save username/password for normal user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info password/random] +root_user_name="${UNBOUND_ROOT_USER_NAME:-}" # root user name +root_user_pass="${UNBOUND_ROOT_PASS_WORD:-}" # root user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Normal user info [password/random] +user_name="${UNBOUND_USER_NAME:-}" # normal user name +user_pass="${UNBOUND_USER_PASS_WORD:-}" # normal user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Load variables from config +[ -f "/config/env/unbound.script.sh" ] && . "/config/env/unbound.script.sh" # Generated by my dockermgr script +[ -f "/config/env/unbound.sh" ] && . "/config/env/unbound.sh" # Overwrite the variabes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional predefined variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Specifiy custom directories to be created +ADD_APPLICATION_FILES="" +ADD_APPLICATION_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +APPLICATION_FILES="$LOG_DIR/$SERVICE_NAME.log" +APPLICATION_DIRS="$ETC_DIR $CONF_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional config dirs - will be Copied to /etc/$name +ADDITIONAL_CONFIG_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# define variables that need to be loaded into the service - escape quotes - var=\"value\",other=\"test\" +CMD_ENV="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Overwrite based on file/directory + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Per Application Variables or imports + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom commands to run before copying to /config +__run_precopy() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + + # allow custom functions + if builtin type -t __run_precopy_local | grep -q 'function'; then __run_precopy_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom prerun functions - IE setup WWW_ROOT_DIR +__execute_prerun() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + + # allow custom functions + if builtin type -t __execute_prerun_local | grep -q 'function'; then __execute_prerun_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Run any pre-execution checks +__run_pre_execute_checks() { + # Set variables + local exitStatus=0 + local pre_execute_checks_MessageST="Running preexecute check for $SERVICE_NAME" # message to show at start + local pre_execute_checks_MessageEnd="Finished preexecute check for $SERVICE_NAME" # message to show at completion + __banner "$pre_execute_checks_MessageST" + # Put command to execute in parentheses + { + true + } + exitStatus=$? + __banner "$pre_execute_checks_MessageEnd: Status $exitStatus" + + # show exit message + if [ $exitStatus -ne 0 ]; then + echo "The pre-execution check has failed" >&2 + [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE" + exit 1 + fi + # allow custom functions + if builtin type -t __run_pre_execute_checks_local | grep -q 'function'; then __run_pre_execute_checks_local; fi + # exit function + return $exitStatus +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__update_conf_files() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # delete files + #__rm "" + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # custom commands + echo 'nameserver 127.0.0.1' >"/etc/resolv.conf" + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # replace variables + # __replace "" "" "$CONF_DIR/unbound.conf" + # replace variables recursively + # __find_replace "" "" "$CONF_DIR" + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions + + # allow custom functions + if builtin type -t __update_conf_files_local | grep -q 'function'; then __update_conf_files_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run before executing +__pre_execute() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute if directories is empty + # __is_dir_empty "$CONF_DIR" && true + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions to run after copying to /config + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # unset unneeded variables + unset sysname + # Lets wait a few seconds before continuing + sleep 5 + # allow custom functions + if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run after executing +__post_execute() { + local pid="" # init pid var + local retVal=0 # set default exit code + local ctime=${POST_EXECUTE_WAIT_TIME:-1} # how long to wait before executing + local waitTime=$((ctime * 60)) # convert minutes to seconds + local postMessageST="Running post commands for $SERVICE_NAME" # message to show at start + local postMessageEnd="Finished post commands for $SERVICE_NAME" # message to show at completion + # wait + sleep $waitTime + # execute commands after waiting + ( + # show message + __banner "$postMessageST" + # commands to execute + sleep 5 + # show exit message + __banner "$postMessageEnd: Status $retVal" + ) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & + pid=$! + ps ax | awk '{print $1}' | grep -v grep | grep -q "$execPid$" && retVal=0 || retVal=10 + # allow custom functions + if builtin type -t __post_execute_local | grep -q 'function'; then __post_execute_local; fi + # exit function + return $retVal +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__pre_message() { + local exitCode=0 + [ -n "$PRE_EXEC_MESSAGE" ] && eval echo "$PRE_EXEC_MESSAGE" + # execute commands + + # allow custom functions + if builtin type -t __pre_message_local | grep -q 'function'; then __pre_message_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to setup ssl support +__update_ssl_conf() { + local exitCode=0 + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute commands + + # allow custom functions + if builtin type -t __update_ssl_conf_local | grep -q 'function'; then __update_ssl_conf_local; fi + # set exitCode + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env() { + local exitCode=0 + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then + cat </dev/null +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info [password/random] +#ENV_ROOT_USER_NAME="${ENV_ROOT_USER_NAME:-$UNBOUND_ROOT_USER_NAME}" # root user name +#ENV_ROOT_USER_PASS="${ENV_ROOT_USER_NAME:-$UNBOUND_ROOT_PASS_WORD}" # root user password +#root_user_name="${ENV_ROOT_USER_NAME:-$root_user_name}" # +#root_user_pass="${ENV_ROOT_USER_PASS:-$root_user_pass}" # +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#Normal user info [password/random] +#ENV_USER_NAME="${ENV_USER_NAME:-$UNBOUND_USER_NAME}" # +#ENV_USER_PASS="${ENV_USER_PASS:-$UNBOUND_USER_PASS_WORD}" # +#user_name="${ENV_USER_NAME:-$user_name}" # normal user name +#user_pass="${ENV_USER_PASS:-$user_pass}" # normal user password + +EOF + fi + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" ]; then + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_precopy_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __execute_prerun_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_pre_execute_checks_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_conf_files_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __post_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_message_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_ssl_conf_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + fi + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" || exitCode=$((exitCode + 1)) + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" || exitCode=$((exitCode + 1)) + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# script to start server +__run_start_script() { + local runExitCode=0 + local workdir="$(eval echo "${WORK_DIR:-}")" # expand variables + local cmd="$(eval echo "${EXEC_CMD_BIN:-}")" # expand variables + local args="$(eval echo "${EXEC_CMD_ARGS:-}")" # expand variables + local name="$(eval echo "${EXEC_CMD_NAME:-}")" # expand variables + local pre="$(eval echo "${EXEC_PRE_SCRIPT:-}")" # expand variables + local extra_env="$(eval echo "${CMD_ENV//,/ }")" # expand variables + local lc_type="$(eval echo "${LANG:-${LC_ALL:-$LC_CTYPE}}")" # expand variables + local home="$(eval echo "${workdir//\/root/\/tmp\/docker}")" # expand variables + local path="$(eval echo "$PATH")" # expand variables + local message="$(eval echo "")" # expand variables + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + [ -f "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" ] && . "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" + # + if [ -z "$cmd" ]; then + __post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" + retVal=$? + echo "Initializing $SCRIPT_NAME has completed" + exit $retVal + else + # ensure the command exists + if [ ! -x "$cmd" ]; then + echo "$name is not a valid executable" + return 2 + fi + # check and exit if already running + if __proc_check "$name" || __proc_check "$cmd"; then + echo "$name is already running" >&2 + return 0 + else + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # show message if env exists + if [ -n "$cmd" ]; then + [ -n "$SERVICE_USER" ] && echo "Setting up $cmd to run as $SERVICE_USER" || SERVICE_USER="root" + [ -n "$SERVICE_PORT" ] && echo "$name will be running on port $SERVICE_PORT" || SERVICE_PORT="" + fi + if [ -n "$pre" ] && [ -n "$(command -v "$pre" 2>/dev/null)" ]; then + export cmd_exec="$pre $cmd $args" + message="Starting service: $name $args through $pre" + else + export cmd_exec="$cmd $args" + message="Starting service: $name $args" + fi + [ -n "$su_exec" ] && echo "using $su_exec" | tee -a -p "/data/logs/init.txt" + echo "$message" | tee -a -p "/data/logs/init.txt" + su_cmd touch "$SERVICE_PID_FILE" + if [ "$RESET_ENV" = "yes" ]; then + env_command="$(echo "env -i HOME=\"$home\" LC_CTYPE=\"$lc_type\" PATH=\"$path\" HOSTNAME=\"$sysname\" USER=\"${SERVICE_USER:-$RUNAS_USER}\" $extra_env")" + execute_command="$(__trim "$su_exec $env_command $cmd_exec")" + if [ ! -f "$START_SCRIPT" ]; then + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} with env +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 +exit \$retVal + +EOF + fi + else + if [ ! -f "$START_SCRIPT" ]; then + execute_command="$(__trim "$su_exec $cmd_exec")" + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 >&2 +exit \$retVal + +EOF + fi + fi + fi + [ -x "$START_SCRIPT" ] || chmod 755 -Rf "$START_SCRIPT" + [ "$CONTAINER_INIT" = "yes" ] || eval sh -c "$START_SCRIPT" + runExitCode=$? + fi + return $runExitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# username and password actions +__run_secure_function() { + local filesperms + if [ -n "$user_name" ] || [ -n "$user_pass" ]; then + for filesperms in "${USER_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + if [ -n "$root_user_name" ] || [ -n "$root_user_pass" ]; then + for filesperms in "${ROOT_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + unset filesperms +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow ENV_ variable - Import env file +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SERVICE_EXIT_CODE=0 # default exit code +# application specific +EXEC_CMD_NAME="$(basename -- "$EXEC_CMD_BIN")" # set the binary name +SERVICE_PID_FILE="/run/init.d/$EXEC_CMD_NAME.pid" # set the pid file location +SERVICE_PID_NUMBER="$(__pgrep)" # check if running +EXEC_CMD_BIN="$(type -P "$EXEC_CMD_BIN" || echo "$EXEC_CMD_BIN")" # set full path +EXEC_PRE_SCRIPT="$(type -P "$EXEC_PRE_SCRIPT" || echo "$EXEC_PRE_SCRIPT")" # set full path +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Only run check +__check_service "$1" && SERVICE_IS_RUNNING=yes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# ensure needed directories exists +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create auth directories +[ -n "$USER_FILE_PREFIX" ] && { [ -d "$USER_FILE_PREFIX" ] || mkdir -p "$USER_FILE_PREFIX"; } +[ -n "$ROOT_FILE_PREFIX" ] && { [ -d "$ROOT_FILE_PREFIX" ] || mkdir -p "$ROOT_FILE_PREFIX"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ -n "$RUNAS_USER" ] || RUNAS_USER="root" +[ -n "$SERVICE_USER" ] || SERVICE_USER="$RUNAS_USER" +[ -n "$SERVICE_GROUP" ] || SERVICE_GROUP="${SERVICE_USER:-$RUNAS_USER}" +[ "$IS_WEB_SERVER" = "yes" ] && RESET_ENV="yes" && __is_htdocs_mounted +[ "$IS_WEB_SERVER" = "yes" ] && [ -z "$SERVICE_PORT" ] && SERVICE_PORT="80" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Database env +if [ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ]; then + RESET_ENV="no" + DATABASE_CREATE="${ENV_DATABASE_CREATE:-$DATABASE_CREATE}" + DATABASE_USER_NORMAL="${ENV_DATABASE_USER:-${DATABASE_USER_NORMAL:-$user_name}}" + DATABASE_PASS_NORMAL="${ENV_DATABASE_PASSWORD:-${DATABASE_PASS_NORMAL:-$user_pass}}" + DATABASE_USER_ROOT="${ENV_DATABASE_ROOT_USER:-${DATABASE_USER_ROOT:-$root_user_name}}" + DATABASE_PASS_ROOT="${ENV_DATABASE_ROOT_PASSWORD:-${DATABASE_PASS_ROOT:-$root_user_pass}}" + if [ -n "$DATABASE_PASS_NORMAL" ] && [ ! -f "${USER_FILE_PREFIX}/db_pass_user" ]; then + echo "$DATABASE_PASS_NORMAL" >"${USER_FILE_PREFIX}/db_pass_user" + fi + if [ -n "$DATABASE_PASS_ROOT" ] && [ ! -f "${ROOT_FILE_PREFIX}/db_pass_root" ]; then + echo "$DATABASE_PASS_ROOT" >"${ROOT_FILE_PREFIX}/db_pass_root" + fi +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# [DATABASE_DIR_[SQLITE,REDIS,POSTGRES,MARIADB,COUCHDB,MONGODB,SUPABASE]] +if [ "$DATABASE_SERVICE_TYPE" = "custom" ]; then + DATABASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_BASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_CUSTOM:-/usr/local/share/httpd/admin/databases}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_CUSTOM:-/admin/dbadmin}" +elif [ "$SERVICE_NAME" = "redis" ] || [ "$DATABASE_SERVICE_TYPE" = "redis" ]; then + DATABASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_BASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_REDIS:-/usr/local/share/httpd/admin/redis}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_REDIS:-/admin/redis}" +elif [ "$SERVICE_NAME" = "postgres" ] || [ "$DATABASE_SERVICE_TYPE" = "postgres" ]; then + DATABASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_BASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_POSTGRES:-/usr/local/share/httpd/admin/postgres}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_POSTGRES:-/admin/postgres}" +elif [ "$SERVICE_NAME" = "mariadb" ] || [ "$DATABASE_SERVICE_TYPE" = "mariadb" ]; then + DATABASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MARIADB:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MARIADB:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "mysql" ] || [ "$DATABASE_SERVICE_TYPE" = "mysql" ]; then + DATABASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_BASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MYSQL:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MYSQL:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "couchdb" ] || [ "$DATABASE_SERVICE_TYPE" = "couchdb" ]; then + DATABASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_BASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_COUCHDB:-/usr/local/share/httpd/admin/couchdb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_COUCHDB:-/admin/couchdb}" +elif [ "$SERVICE_NAME" = "mongodb" ] || [ "$DATABASE_SERVICE_TYPE" = "mongodb" ]; then + DATABASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MONGODB:-/usr/local/share/httpd/admin/mongodb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MONGODB:-/admin/mongodb}" +elif [ "$SERVICE_NAME" = "supabase" ] || [ "$DATABASE_SERVICE_TYPE" = "supabase" ]; then + DATABASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_BASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SUPABASE:-/usr/local/share/httpd/admin/supabase}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SUPBASE:-/admin/supabase}" +elif [ "$SERVICE_NAME" = "sqlite" ] || [ "$DATABASE_SERVICE_TYPE" = "sqlite" ]; then + DATABASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_BASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SQLITE:-/usr/local/share/httpd/admin/sqlite}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SQLITE:-/admin/sqlite}" + [ -d "$DATABASE_DIR" ] || mkdir -p "$DATABASE_DIR" + chmod 777 "$DATABASE_DIR" +fi +[ -n "$DATABASE_ADMIN_WWW_ROOT" ] && { [ ! -d "$DATABASE_ADMIN_WWW_ROOT" ] || mkdir -p "${DATABASE_ADMIN_WWW_ROOT}"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow variables via imports - Overwrite existing +[ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ] && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set password to random if variable is random +[ "$user_pass" = "random" ] && user_pass="$(__random_password ${RANDOM_PASS_USER:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ "$root_user_pass" = "random" ] && root_user_pass="$(__random_password ${RANDOM_PASS_ROOT:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow setting initial users and passwords via environment and save to file +[ -n "$user_name" ] && echo "$user_name" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$user_pass" ] && echo "$user_pass" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" +[ -n "$root_user_name" ] && echo "$root_user_name" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$root_user_pass" ] && echo "$root_user_pass" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create needed dirs +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow per init script usernames and passwords +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_name" && user_name="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" && user_pass="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" && root_user_name="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" && root_user_pass="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${USER_FILE_PREFIX}/db_pass_user" && DATABASE_PASS_NORMAL="$(<"${USER_FILE_PREFIX}/db_pass_user")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/db_pass_root" && DATABASE_PASS_ROOT="$(<"${ROOT_FILE_PREFIX}/db_pass_root")" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set hostname for script +sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Setup /config directories +__init_config_etc +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# pre-run function +__execute_prerun +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create user if needed +__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Modify user if needed +__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Create base directories +__setup_directories +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set switch user command +__switch_to_user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize the home/working dir +__init_working_dir +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# show init message +__pre_message +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_db_users +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize ssl +__update_ssl_conf +__update_ssl_certs +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions in ${USER_FILE_PREFIX} and ${ROOT_FILE_PREFIX} +__run_secure_function +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_precopy +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Copy /config to /etc +for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do + __initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Replace variables +__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_database +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Updating config files +__update_conf_files +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run the pre execute commands +__pre_execute +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions +__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log" +errorCode=$? +if [ -n "$EXEC_CMD_BIN" ]; then + if [ "$errorCode" -eq 0 ]; then + SERVICE_EXIT_CODE=0 + SERVICE_IS_RUNNING="yes" + else + SERVICE_EXIT_CODE=$errorCode + SERVICE_IS_RUNNING="${SERVICE_IS_RUNNING:-no}" + [ -s "$SERVICE_PID_FILE" ] || rm -Rf "$SERVICE_PID_FILE" + fi + SERVICE_EXIT_CODE=0 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# start the post execute function in background +__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__banner "Initializing of $SERVICE_NAME has completed with statusCode: $SERVICE_EXIT_CODE" | tee -p -a "/data/logs/entrypoint.log" "/data/logs/init.txt" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $SERVICE_EXIT_CODE diff --git a/rootfs/usr/local/etc/docker/init.d/98-privoxy.sh b/rootfs/usr/local/etc/docker/init.d/98-privoxy.sh new file mode 100755 index 0000000..67f86c1 --- /dev/null +++ b/rootfs/usr/local/etc/docker/init.d/98-privoxy.sh @@ -0,0 +1,690 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501061124-git +# @@Author : Jason Hempstead +# @@Contact : jason@casjaysdev.pro +# @@License : LICENSE.md +# @@ReadME : privoxy.sh --help +# @@Copyright : Copyright: (c) 2025 Jason Hempstead, Casjays Developments +# @@Created : Monday, Jan 06, 2025 11:24 EST +# @@File : privoxy.sh +# @@Description : +# @@Changelog : New script +# @@TODO : Better documentation +# @@Other : +# @@Resource : +# @@Terminal App : no +# @@sudo/root : no +# @@Template : other/start-service +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1003,SC2016,SC2031,SC2120,SC2155,SC2199,SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run trap command on exit +trap 'retVal=$?;[ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE";exit $retVal' SIGINT SIGTERM +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# setup debugging - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}" +{ [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; } && echo "Enabling debugging" && set -xo pipefail -x$DEBUGGER_OPTIONS && export DEBUGGER="on" || set -o pipefail +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +export PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SCRIPT_FILE="$0" +SERVICE_NAME="privoxy" +SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# exit if __start_init_scripts function hasn't been Initialized +if [ ! -f "/run/__start_init_scripts.pid" ]; then + echo "__start_init_scripts function hasn't been Initialized" >&2 + SERVICE_IS_RUNNING="no" + exit 1 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import the functions file +if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then + . "/usr/local/etc/docker/functions/entrypoint.sh" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import variables +for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do + [ -f "$set_env" ] && . "$set_env" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +printf '%s\n' "# - - - Initializing $SERVICE_NAME - - - #" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom functions + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Script to execute +START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Reset environment before executing service +RESET_ENV="yes" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set webroot +WWW_ROOT_DIR="/usr/local/share/httpd/default" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Default predefined variables +DATA_DIR="/data/privoxy" # set data directory +CONF_DIR="/config/privoxy" # set config directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the containers etc directory +ETC_DIR="/etc/privoxy" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the var dir +VAR_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TMP_DIR="/tmp/privoxy" # set the temp dir +RUN_DIR="/run/privoxy" # set scripts pid dir +LOG_DIR="/data/logs/privoxy" # set log directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the working dir +WORK_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# port which service is listening on +SERVICE_PORT="8118" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User to use to launch service - IE: postgres +RUNAS_USER="root" # normally root +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User and group in which the service switches to - IE: nginx,apache,mysql,postgres +#SERVICE_USER="privoxy" # execute command as another user +#SERVICE_GROUP="privoxy" # Set the service group +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set password length +RANDOM_PASS_USER="" +RANDOM_PASS_ROOT="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set user and group ID +SERVICE_UID="0" # set the user id +SERVICE_GID="0" # set the group id +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# execute command variables - keep single quotes variables will be expanded later +EXEC_CMD_BIN='privoxy' # command to execute +EXEC_CMD_ARGS='--no-daemon $CONF_DIR/config' # command arguments +EXEC_PRE_SCRIPT='' # execute script before +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a web server +IS_WEB_SERVER="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a database server +IS_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Does this service use a database server +USES_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set defualt type - [custom,sqlite,redis,postgres,mariadb,mysql,couchdb,mongodb,supabase] +DATABASE_SERVICE_TYPE="sqlite" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Show message before execute +PRE_EXEC_MESSAGE="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the wait time to execute __post_execute function - minutes +POST_EXECUTE_WAIT_TIME="1" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Update path var +PATH="$PATH:." +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Lets get containers ip address +IP4_ADDRESS="$(__get_ip4)" +IP6_ADDRESS="$(__get_ip6)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Where to save passwords to +ROOT_FILE_PREFIX="/config/secure/auth/root" # directory to save username/password for root user +USER_FILE_PREFIX="/config/secure/auth/user" # directory to save username/password for normal user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info password/random] +root_user_name="${PRIVOXY_ROOT_USER_NAME:-}" # root user name +root_user_pass="${PRIVOXY_ROOT_PASS_WORD:-}" # root user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Normal user info [password/random] +user_name="${PRIVOXY_USER_NAME:-}" # normal user name +user_pass="${PRIVOXY_USER_PASS_WORD:-}" # normal user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Load variables from config +[ -f "/config/env/privoxy.script.sh" ] && . "/config/env/privoxy.script.sh" # Generated by my dockermgr script +[ -f "/config/env/privoxy.sh" ] && . "/config/env/privoxy.sh" # Overwrite the variabes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional predefined variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Specifiy custom directories to be created +ADD_APPLICATION_FILES="" +ADD_APPLICATION_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +APPLICATION_FILES="$LOG_DIR/$SERVICE_NAME.log" +APPLICATION_DIRS="$ETC_DIR $CONF_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional config dirs - will be Copied to /etc/$name +ADDITIONAL_CONFIG_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# define variables that need to be loaded into the service - escape quotes - var=\"value\",other=\"test\" +CMD_ENV="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Overwrite based on file/directory + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Per Application Variables or imports + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom commands to run before copying to /config +__run_precopy() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + + # allow custom functions + if builtin type -t __run_precopy_local | grep -q 'function'; then __run_precopy_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom prerun functions - IE setup WWW_ROOT_DIR +__execute_prerun() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + + # allow custom functions + if builtin type -t __execute_prerun_local | grep -q 'function'; then __execute_prerun_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Run any pre-execution checks +__run_pre_execute_checks() { + # Set variables + local exitStatus=0 + local pre_execute_checks_MessageST="Running preexecute check for $SERVICE_NAME" # message to show at start + local pre_execute_checks_MessageEnd="Finished preexecute check for $SERVICE_NAME" # message to show at completion + __banner "$pre_execute_checks_MessageST" + # Put command to execute in parentheses + { + true + } + exitStatus=$? + __banner "$pre_execute_checks_MessageEnd: Status $exitStatus" + + # show exit message + if [ $exitStatus -ne 0 ]; then + echo "The pre-execution check has failed" >&2 + [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE" + exit 1 + fi + # allow custom functions + if builtin type -t __run_pre_execute_checks_local | grep -q 'function'; then __run_pre_execute_checks_local; fi + # exit function + return $exitStatus +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__update_conf_files() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # delete files + #__rm "" + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # custom commands + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # replace variables + # __replace "" "" "$CONF_DIR/privoxy.conf" + # replace variables recursively + # __find_replace "" "" "$CONF_DIR" + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions + + # allow custom functions + if builtin type -t __update_conf_files_local | grep -q 'function'; then __update_conf_files_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run before executing +__pre_execute() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute if directories is empty + # __is_dir_empty "$CONF_DIR" && true + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions to run after copying to /config + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # unset unneeded variables + unset sysname + # Lets wait a few seconds before continuing + sleep 5 + # allow custom functions + if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run after executing +__post_execute() { + local pid="" # init pid var + local retVal=0 # set default exit code + local ctime=${POST_EXECUTE_WAIT_TIME:-1} # how long to wait before executing + local waitTime=$((ctime * 60)) # convert minutes to seconds + local postMessageST="Running post commands for $SERVICE_NAME" # message to show at start + local postMessageEnd="Finished post commands for $SERVICE_NAME" # message to show at completion + # wait + sleep $waitTime + # execute commands after waiting + ( + # show message + __banner "$postMessageST" + # commands to execute + sleep 5 + # show exit message + __banner "$postMessageEnd: Status $retVal" + ) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & + pid=$! + ps ax | awk '{print $1}' | grep -v grep | grep -q "$execPid$" && retVal=0 || retVal=10 + # allow custom functions + if builtin type -t __post_execute_local | grep -q 'function'; then __post_execute_local; fi + # exit function + return $retVal +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__pre_message() { + local exitCode=0 + [ -n "$PRE_EXEC_MESSAGE" ] && eval echo "$PRE_EXEC_MESSAGE" + # execute commands + + # allow custom functions + if builtin type -t __pre_message_local | grep -q 'function'; then __pre_message_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to setup ssl support +__update_ssl_conf() { + local exitCode=0 + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute commands + + # allow custom functions + if builtin type -t __update_ssl_conf_local | grep -q 'function'; then __update_ssl_conf_local; fi + # set exitCode + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env() { + local exitCode=0 + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then + cat </dev/null +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info [password/random] +#ENV_ROOT_USER_NAME="${ENV_ROOT_USER_NAME:-$PRIVOXY_ROOT_USER_NAME}" # root user name +#ENV_ROOT_USER_PASS="${ENV_ROOT_USER_NAME:-$PRIVOXY_ROOT_PASS_WORD}" # root user password +#root_user_name="${ENV_ROOT_USER_NAME:-$root_user_name}" # +#root_user_pass="${ENV_ROOT_USER_PASS:-$root_user_pass}" # +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#Normal user info [password/random] +#ENV_USER_NAME="${ENV_USER_NAME:-$PRIVOXY_USER_NAME}" # +#ENV_USER_PASS="${ENV_USER_PASS:-$PRIVOXY_USER_PASS_WORD}" # +#user_name="${ENV_USER_NAME:-$user_name}" # normal user name +#user_pass="${ENV_USER_PASS:-$user_pass}" # normal user password + +EOF + fi + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" ]; then + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_precopy_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __execute_prerun_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_pre_execute_checks_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_conf_files_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __post_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_message_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_ssl_conf_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + fi + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" || exitCode=$((exitCode + 1)) + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" || exitCode=$((exitCode + 1)) + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# script to start server +__run_start_script() { + local runExitCode=0 + local workdir="$(eval echo "${WORK_DIR:-}")" # expand variables + local cmd="$(eval echo "${EXEC_CMD_BIN:-}")" # expand variables + local args="$(eval echo "${EXEC_CMD_ARGS:-}")" # expand variables + local name="$(eval echo "${EXEC_CMD_NAME:-}")" # expand variables + local pre="$(eval echo "${EXEC_PRE_SCRIPT:-}")" # expand variables + local extra_env="$(eval echo "${CMD_ENV//,/ }")" # expand variables + local lc_type="$(eval echo "${LANG:-${LC_ALL:-$LC_CTYPE}}")" # expand variables + local home="$(eval echo "${workdir//\/root/\/tmp\/docker}")" # expand variables + local path="$(eval echo "$PATH")" # expand variables + local message="$(eval echo "")" # expand variables + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + [ -f "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" ] && . "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" + # + if [ -z "$cmd" ]; then + __post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" + retVal=$? + echo "Initializing $SCRIPT_NAME has completed" + exit $retVal + else + # ensure the command exists + if [ ! -x "$cmd" ]; then + echo "$name is not a valid executable" + return 2 + fi + # check and exit if already running + if __proc_check "$name" || __proc_check "$cmd"; then + echo "$name is already running" >&2 + return 0 + else + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # show message if env exists + if [ -n "$cmd" ]; then + [ -n "$SERVICE_USER" ] && echo "Setting up $cmd to run as $SERVICE_USER" || SERVICE_USER="root" + [ -n "$SERVICE_PORT" ] && echo "$name will be running on port $SERVICE_PORT" || SERVICE_PORT="" + fi + if [ -n "$pre" ] && [ -n "$(command -v "$pre" 2>/dev/null)" ]; then + export cmd_exec="$pre $cmd $args" + message="Starting service: $name $args through $pre" + else + export cmd_exec="$cmd $args" + message="Starting service: $name $args" + fi + [ -n "$su_exec" ] && echo "using $su_exec" | tee -a -p "/data/logs/init.txt" + echo "$message" | tee -a -p "/data/logs/init.txt" + su_cmd touch "$SERVICE_PID_FILE" + if [ "$RESET_ENV" = "yes" ]; then + env_command="$(echo "env -i HOME=\"$home\" LC_CTYPE=\"$lc_type\" PATH=\"$path\" HOSTNAME=\"$sysname\" USER=\"${SERVICE_USER:-$RUNAS_USER}\" $extra_env")" + execute_command="$(__trim "$su_exec $env_command $cmd_exec")" + if [ ! -f "$START_SCRIPT" ]; then + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} with env +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 +exit \$retVal + +EOF + fi + else + if [ ! -f "$START_SCRIPT" ]; then + execute_command="$(__trim "$su_exec $cmd_exec")" + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 >&2 +exit \$retVal + +EOF + fi + fi + fi + [ -x "$START_SCRIPT" ] || chmod 755 -Rf "$START_SCRIPT" + [ "$CONTAINER_INIT" = "yes" ] || eval sh -c "$START_SCRIPT" + runExitCode=$? + fi + return $runExitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# username and password actions +__run_secure_function() { + local filesperms + if [ -n "$user_name" ] || [ -n "$user_pass" ]; then + for filesperms in "${USER_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + if [ -n "$root_user_name" ] || [ -n "$root_user_pass" ]; then + for filesperms in "${ROOT_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + unset filesperms +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow ENV_ variable - Import env file +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SERVICE_EXIT_CODE=0 # default exit code +# application specific +EXEC_CMD_NAME="$(basename -- "$EXEC_CMD_BIN")" # set the binary name +SERVICE_PID_FILE="/run/init.d/$EXEC_CMD_NAME.pid" # set the pid file location +SERVICE_PID_NUMBER="$(__pgrep)" # check if running +EXEC_CMD_BIN="$(type -P "$EXEC_CMD_BIN" || echo "$EXEC_CMD_BIN")" # set full path +EXEC_PRE_SCRIPT="$(type -P "$EXEC_PRE_SCRIPT" || echo "$EXEC_PRE_SCRIPT")" # set full path +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Only run check +__check_service "$1" && SERVICE_IS_RUNNING=yes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# ensure needed directories exists +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create auth directories +[ -n "$USER_FILE_PREFIX" ] && { [ -d "$USER_FILE_PREFIX" ] || mkdir -p "$USER_FILE_PREFIX"; } +[ -n "$ROOT_FILE_PREFIX" ] && { [ -d "$ROOT_FILE_PREFIX" ] || mkdir -p "$ROOT_FILE_PREFIX"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ -n "$RUNAS_USER" ] || RUNAS_USER="root" +[ -n "$SERVICE_USER" ] || SERVICE_USER="$RUNAS_USER" +[ -n "$SERVICE_GROUP" ] || SERVICE_GROUP="${SERVICE_USER:-$RUNAS_USER}" +[ "$IS_WEB_SERVER" = "yes" ] && RESET_ENV="yes" && __is_htdocs_mounted +[ "$IS_WEB_SERVER" = "yes" ] && [ -z "$SERVICE_PORT" ] && SERVICE_PORT="80" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Database env +if [ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ]; then + RESET_ENV="no" + DATABASE_CREATE="${ENV_DATABASE_CREATE:-$DATABASE_CREATE}" + DATABASE_USER_NORMAL="${ENV_DATABASE_USER:-${DATABASE_USER_NORMAL:-$user_name}}" + DATABASE_PASS_NORMAL="${ENV_DATABASE_PASSWORD:-${DATABASE_PASS_NORMAL:-$user_pass}}" + DATABASE_USER_ROOT="${ENV_DATABASE_ROOT_USER:-${DATABASE_USER_ROOT:-$root_user_name}}" + DATABASE_PASS_ROOT="${ENV_DATABASE_ROOT_PASSWORD:-${DATABASE_PASS_ROOT:-$root_user_pass}}" + if [ -n "$DATABASE_PASS_NORMAL" ] && [ ! -f "${USER_FILE_PREFIX}/db_pass_user" ]; then + echo "$DATABASE_PASS_NORMAL" >"${USER_FILE_PREFIX}/db_pass_user" + fi + if [ -n "$DATABASE_PASS_ROOT" ] && [ ! -f "${ROOT_FILE_PREFIX}/db_pass_root" ]; then + echo "$DATABASE_PASS_ROOT" >"${ROOT_FILE_PREFIX}/db_pass_root" + fi +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# [DATABASE_DIR_[SQLITE,REDIS,POSTGRES,MARIADB,COUCHDB,MONGODB,SUPABASE]] +if [ "$DATABASE_SERVICE_TYPE" = "custom" ]; then + DATABASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_BASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_CUSTOM:-/usr/local/share/httpd/admin/databases}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_CUSTOM:-/admin/dbadmin}" +elif [ "$SERVICE_NAME" = "redis" ] || [ "$DATABASE_SERVICE_TYPE" = "redis" ]; then + DATABASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_BASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_REDIS:-/usr/local/share/httpd/admin/redis}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_REDIS:-/admin/redis}" +elif [ "$SERVICE_NAME" = "postgres" ] || [ "$DATABASE_SERVICE_TYPE" = "postgres" ]; then + DATABASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_BASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_POSTGRES:-/usr/local/share/httpd/admin/postgres}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_POSTGRES:-/admin/postgres}" +elif [ "$SERVICE_NAME" = "mariadb" ] || [ "$DATABASE_SERVICE_TYPE" = "mariadb" ]; then + DATABASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MARIADB:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MARIADB:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "mysql" ] || [ "$DATABASE_SERVICE_TYPE" = "mysql" ]; then + DATABASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_BASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MYSQL:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MYSQL:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "couchdb" ] || [ "$DATABASE_SERVICE_TYPE" = "couchdb" ]; then + DATABASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_BASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_COUCHDB:-/usr/local/share/httpd/admin/couchdb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_COUCHDB:-/admin/couchdb}" +elif [ "$SERVICE_NAME" = "mongodb" ] || [ "$DATABASE_SERVICE_TYPE" = "mongodb" ]; then + DATABASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MONGODB:-/usr/local/share/httpd/admin/mongodb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MONGODB:-/admin/mongodb}" +elif [ "$SERVICE_NAME" = "supabase" ] || [ "$DATABASE_SERVICE_TYPE" = "supabase" ]; then + DATABASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_BASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SUPABASE:-/usr/local/share/httpd/admin/supabase}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SUPBASE:-/admin/supabase}" +elif [ "$SERVICE_NAME" = "sqlite" ] || [ "$DATABASE_SERVICE_TYPE" = "sqlite" ]; then + DATABASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_BASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SQLITE:-/usr/local/share/httpd/admin/sqlite}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SQLITE:-/admin/sqlite}" + [ -d "$DATABASE_DIR" ] || mkdir -p "$DATABASE_DIR" + chmod 777 "$DATABASE_DIR" +fi +[ -n "$DATABASE_ADMIN_WWW_ROOT" ] && { [ ! -d "$DATABASE_ADMIN_WWW_ROOT" ] || mkdir -p "${DATABASE_ADMIN_WWW_ROOT}"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow variables via imports - Overwrite existing +[ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ] && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set password to random if variable is random +[ "$user_pass" = "random" ] && user_pass="$(__random_password ${RANDOM_PASS_USER:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ "$root_user_pass" = "random" ] && root_user_pass="$(__random_password ${RANDOM_PASS_ROOT:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow setting initial users and passwords via environment and save to file +[ -n "$user_name" ] && echo "$user_name" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$user_pass" ] && echo "$user_pass" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" +[ -n "$root_user_name" ] && echo "$root_user_name" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$root_user_pass" ] && echo "$root_user_pass" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create needed dirs +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow per init script usernames and passwords +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_name" && user_name="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" && user_pass="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" && root_user_name="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" && root_user_pass="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${USER_FILE_PREFIX}/db_pass_user" && DATABASE_PASS_NORMAL="$(<"${USER_FILE_PREFIX}/db_pass_user")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/db_pass_root" && DATABASE_PASS_ROOT="$(<"${ROOT_FILE_PREFIX}/db_pass_root")" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set hostname for script +sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Setup /config directories +__init_config_etc +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# pre-run function +__execute_prerun +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create user if needed +__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Modify user if needed +__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Create base directories +__setup_directories +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set switch user command +__switch_to_user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize the home/working dir +__init_working_dir +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# show init message +__pre_message +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_db_users +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize ssl +__update_ssl_conf +__update_ssl_certs +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions in ${USER_FILE_PREFIX} and ${ROOT_FILE_PREFIX} +__run_secure_function +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_precopy +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Copy /config to /etc +for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do + __initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Replace variables +__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_database +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Updating config files +__update_conf_files +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run the pre execute commands +__pre_execute +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions +__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log" +errorCode=$? +if [ -n "$EXEC_CMD_BIN" ]; then + if [ "$errorCode" -eq 0 ]; then + SERVICE_EXIT_CODE=0 + SERVICE_IS_RUNNING="yes" + else + SERVICE_EXIT_CODE=$errorCode + SERVICE_IS_RUNNING="${SERVICE_IS_RUNNING:-no}" + [ -s "$SERVICE_PID_FILE" ] || rm -Rf "$SERVICE_PID_FILE" + fi + SERVICE_EXIT_CODE=0 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# start the post execute function in background +__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__banner "Initializing of $SERVICE_NAME has completed with statusCode: $SERVICE_EXIT_CODE" | tee -p -a "/data/logs/entrypoint.log" "/data/logs/init.txt" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $SERVICE_EXIT_CODE diff --git a/rootfs/usr/local/etc/docker/init.d/zz-nginx.sh b/rootfs/usr/local/etc/docker/init.d/zz-nginx.sh new file mode 100755 index 0000000..725055d --- /dev/null +++ b/rootfs/usr/local/etc/docker/init.d/zz-nginx.sh @@ -0,0 +1,745 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +##@Version : 202501291320-git +# @@Author : Jason Hempstead +# @@Contact : jason@casjaysdev.pro +# @@License : LICENSE.md +# @@ReadME : zz-nginx.sh --help +# @@Copyright : Copyright: (c) 2025 Jason Hempstead, Casjays Developments +# @@Created : Wednesday, Jan 29, 2025 13:20 EST +# @@File : zz-nginx.sh +# @@Description : +# @@Changelog : New script +# @@TODO : Better documentation +# @@Other : +# @@Resource : +# @@Terminal App : no +# @@sudo/root : no +# @@Template : other/start-service +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1003,SC2016,SC2031,SC2120,SC2155,SC2199,SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run trap command on exit +trap 'retVal=$?;[ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE";exit $retVal' SIGINT SIGTERM +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# setup debugging - https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html +[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}" +{ [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; } && echo "Enabling debugging" && set -xo pipefail -x$DEBUGGER_OPTIONS && export DEBUGGER="on" || set -o pipefail +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +export PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SCRIPT_FILE="$0" +SERVICE_NAME="nginx" +SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# exit if __start_init_scripts function hasn't been Initialized +if [ ! -f "/run/__start_init_scripts.pid" ]; then + echo "__start_init_scripts function hasn't been Initialized" >&2 + SERVICE_IS_RUNNING="no" + exit 1 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import the functions file +if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then + . "/usr/local/etc/docker/functions/entrypoint.sh" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# import variables +for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do + [ -f "$set_env" ] && . "$set_env" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +printf '%s\n' "# - - - Initializing $SERVICE_NAME - - - #" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom functions +__onion_site_dir_is_empty() { [ "$(ls -A "/data/htdocs/onions/${1:-$onion_site}" 2>/dev/null | wc -l)" -eq 0 ] || return 1; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Script to execute +START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Reset environment before executing service +RESET_ENV="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set webroot +WWW_ROOT_DIR="/data/htdocs/www" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Default predefined variables +DATA_DIR="/data/nginx" # set data directory +CONF_DIR="/config/nginx" # set config directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the containers etc directory +ETC_DIR="/etc/nginx" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set the var dir +VAR_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TMP_DIR="/tmp/nginx" # set the temp dir +RUN_DIR="/run/nginx" # set scripts pid dir +LOG_DIR="/data/logs/nginx" # set log directory +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the working dir +WORK_DIR="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# port which service is listening on +SERVICE_PORT="80" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User to use to launch service - IE: postgres +RUNAS_USER="root" # normally root +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# User and group in which the service switches to - IE: nginx,apache,mysql,postgres +#SERVICE_USER="nginx" # execute command as another user +#SERVICE_GROUP="nginx" # Set the service group +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set password length +RANDOM_PASS_USER="" +RANDOM_PASS_ROOT="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set user and group ID +SERVICE_UID="0" # set the user id +SERVICE_GID="0" # set the group id +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# execute command variables - keep single quotes variables will be expanded later +EXEC_CMD_BIN='nginx' # command to execute +EXEC_CMD_ARGS='-c $ETC_DIR/nginx.conf' # command arguments +EXEC_PRE_SCRIPT='' # execute script before +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a web server +IS_WEB_SERVER="yes" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Is this service a database server +IS_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Does this service use a database server +USES_DATABASE_SERVICE="no" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set defualt type - [custom,sqlite,redis,postgres,mariadb,mysql,couchdb,mongodb,supabase] +DATABASE_SERVICE_TYPE="sqlite" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Show message before execute +PRE_EXEC_MESSAGE="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set the wait time to execute __post_execute function - minutes +POST_EXECUTE_WAIT_TIME="1" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Update path var +PATH="$PATH:." +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Lets get containers ip address +IP4_ADDRESS="$(__get_ip4)" +IP6_ADDRESS="$(__get_ip6)" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Where to save passwords to +ROOT_FILE_PREFIX="/config/secure/auth/root" # directory to save username/password for root user +USER_FILE_PREFIX="/config/secure/auth/user" # directory to save username/password for normal user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info password/random] +root_user_name="${NGINX_ROOT_USER_NAME:-}" # root user name +root_user_pass="${NGINX_ROOT_PASS_WORD:-}" # root user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Normal user info [password/random] +user_name="${NGINX_USER_NAME:-}" # normal user name +user_pass="${NGINX_USER_PASS_WORD:-}" # normal user password +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Load variables from config +[ -f "/config/env/nginx.script.sh" ] && . "/config/env/nginx.script.sh" # Generated by my dockermgr script +[ -f "/config/env/nginx.sh" ] && . "/config/env/nginx.sh" # Overwrite the variabes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional predefined variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional variables + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Specifiy custom directories to be created +ADD_APPLICATION_FILES="" +ADD_APPLICATION_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +APPLICATION_FILES="$LOG_DIR/$SERVICE_NAME.log" +APPLICATION_DIRS="$ETC_DIR $CONF_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional config dirs - will be Copied to /etc/$name +ADDITIONAL_CONFIG_DIRS="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# define variables that need to be loaded into the service - escape quotes - var=\"value\",other=\"test\" +CMD_ENV="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Overwrite based on file/directory + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Per Application Variables or imports + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom commands to run before copying to /config +__run_precopy() { + # Define environment + local hostname=${HOSTNAME} + # Define actions/commands + if [ ! -d "$WWW_ROOT_DIR" ] || __is_dir_empty "$WWW_ROOT_DIR"; then + mkdir -p "$WWW_ROOT_DIR" + if [ -d "/usr/share/httpd/default" ]; then + cp -Rf "/usr/share/httpd/default/." "$WWW_ROOT_DIR/" + [ -f "$WWW_ROOT_DIR/hidden_service.html" ] && rm -Rf "$WWW_ROOT_DIR/hidden_service.html" + else + echo "Welcome" >"$WWW_ROOT_DIR/index.php" + fi + fi + if [ -d "$WWW_ROOT_DIR/.git" ]; then + rm -Rf "$WWW_ROOT_DIR/.git" + fi + [ -d "$WWW_ROOT_DIR/.well-known" ] || mkdir -p "$WWW_ROOT_DIR/.well-known" + # allow custom functions + if builtin type -t __run_precopy_local | grep -q 'function'; then __run_precopy_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Custom prerun functions - IE setup WWW_ROOT_DIR +__execute_prerun() { + # Define environment + local hostname=${HOSTNAME} + local php_ver="${PHP_VERSION:-84}" + local php_fpm_bin="$(type -P php-fpm || type -P php-fpm$$php_ver || false)" + # Define actions/commands + if [ -n "$php_fpm_bin" ]; then + $php_fpm_bin --nodaemonize --fpm-config "/etc/php$php_ver/php-fpm.conf" & + fi + # allow custom functions + if builtin type -t __execute_prerun_local | grep -q 'function'; then __execute_prerun_local; fi +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Run any pre-execution checks +__run_pre_execute_checks() { + # Set variables + local exitStatus=0 + local pre_execute_checks_MessageST="Running preexecute check for $SERVICE_NAME" # message to show at start + local pre_execute_checks_MessageEnd="Finished preexecute check for $SERVICE_NAME" # message to show at completion + __banner "$pre_execute_checks_MessageST" + # Put command to execute in parentheses + { + true + } + exitStatus=$? + __banner "$pre_execute_checks_MessageEnd: Status $exitStatus" + + # show exit message + if [ $exitStatus -ne 0 ]; then + echo "The pre-execution check has failed" >&2 + [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE" + exit 1 + fi + # allow custom functions + if builtin type -t __run_pre_execute_checks_local | grep -q 'function'; then __run_pre_execute_checks_local; fi + # exit function + return $exitStatus +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__update_conf_files() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + local default_host="$DEFAULT_ONION_SITE" + if [ -f "$WWW_ROOT_DIR/default_host.txt" ]; then + default_host="${default_host:-$(<"$WWW_ROOT_DIR/default_host.txt")}" + rm -Rf "$WWW_ROOT_DIR/default_host.txt" + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # delete files + #__rm "" + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # custom commands + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # replace variables + # __replace "" "" "$CONF_DIR/nginx.conf" + # replace variables recursively + # __find_replace "" "" "$CONF_DIR" + if [ -n "$default_host" ] && [ -f "$WWW_ROOT_DIR/index.html" ]; then + sed -i 's|REPLACE_DEFAULT_TOR_ADDRESS|'$default_host'|g' "$WWW_ROOT_DIR/index.html" + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions + while :; do + echo "waiting for tor to start" + [ -f "/tmp/init_tor_services" ] && sleep 30 || break + done + echo "The tor server seems to have started " + for site in "/run/tor/sites"/*; do + onion_site="$(basename -- $site)" + __onion_site_dir_is_empty "$onion_site" && NEW_SITE="yes" + [ -d "/data/htdocs/onions/$onion_site" ] || mkdir -p "/data/htdocs/onions/$onion_site" + if [ "$default_host" = "$onion_site" ]; then + if __onion_site_dir_is_empty "$onion_site"; then + cp -Rfa "$WWW_ROOT_DIR/." "/data/htdocs/onions/$onion_site/" + fi + else + if [ "$NEW_SITE" = "yes" ]; then + if [ -f "/usr/share/httpd/default/hidden_service.html" ]; then + cp -Rf "/usr/share/httpd/default/hidden_service.html" "/data/htdocs/onions/$onion_site/index.html" + else + echo '
HTML Document Root: /data/htdocs/onions/'$onion_site'

' >"/data/htdocs/onions/$onion_site/index.html" + fi + fi + fi + if [ ! -f "/config/nginx/vhosts.d/$onion_site.onion.conf" ]; then + cp -Rf "/config/nginx/vhosts.d/template" "/config/nginx/vhosts.d/$onion_site.onion.conf" + sed -i 's|REPLACE_ONION_PORT|'$SERVICE_PORT'|g' "/config/nginx/vhosts.d/$onion_site.onion.conf" + sed -i 's|REPLACE_ONION_SITE|'$onion_site.onion'|g' "/config/nginx/vhosts.d/$onion_site.onion.conf" + sed -i 's|REPLACE_ONION_WWW_DIR|/data/htdocs/onions/'$onion_site'|g' "/config/nginx/vhosts.d/$onion_site.onion.conf" + sed -i 's|REPLACE_ONION_WWW_DIR|/data/htdocs/onions/'$onion_site'|g' "/data/htdocs/onions/$onion_site/index.html" + sed -i 's|REPLACE_DEFAULT_TOR_ADDRESS|'$onion_site'|g' "/data/htdocs/onions/$onion_site/index.html" + fi + unset NEW_SITE + echo "Created $onion_site.onion in /data/htdocs/onions/$onion_site" + done + # allow custom functions + if builtin type -t __update_conf_files_local | grep -q 'function'; then __update_conf_files_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run before executing +__pre_execute() { + local exitCode=0 # default exit code + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute if directories is empty + # __is_dir_empty "$CONF_DIR" && true + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # define actions to run after copying to /config + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # unset unneeded variables + unset sysname + # Lets wait a few seconds before continuing + sleep 5 + # allow custom functions + if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# function to run after executing +__post_execute() { + local pid="" # init pid var + local retVal=0 # set default exit code + local ctime=${POST_EXECUTE_WAIT_TIME:-1} # how long to wait before executing + local waitTime=$((ctime * 60)) # convert minutes to seconds + local postMessageST="Running post commands for $SERVICE_NAME" # message to show at start + local postMessageEnd="Finished post commands for $SERVICE_NAME" # message to show at completion + # wait + sleep $waitTime + # execute commands after waiting + ( + # show message + __banner "$postMessageST" + # commands to execute + sleep 5 + # show exit message + __banner "$postMessageEnd: Status $retVal" + ) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & + pid=$! + ps ax | awk '{print $1}' | grep -v grep | grep -q "$execPid$" && retVal=0 || retVal=10 + # allow custom functions + if builtin type -t __post_execute_local | grep -q 'function'; then __post_execute_local; fi + # exit function + return $retVal +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to update config files - IE: change port +__pre_message() { + local exitCode=0 + [ -n "$PRE_EXEC_MESSAGE" ] && eval echo "$PRE_EXEC_MESSAGE" + # execute commands + + # allow custom functions + if builtin type -t __pre_message_local | grep -q 'function'; then __pre_message_local; fi + # exit function + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# use this function to setup ssl support +__update_ssl_conf() { + local exitCode=0 + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + # execute commands + + # allow custom functions + if builtin type -t __update_ssl_conf_local | grep -q 'function'; then __update_ssl_conf_local; fi + # set exitCode + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env() { + local exitCode=0 + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then + cat </dev/null +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# root/admin user info [password/random] +#ENV_ROOT_USER_NAME="${ENV_ROOT_USER_NAME:-$NGINX_ROOT_USER_NAME}" # root user name +#ENV_ROOT_USER_PASS="${ENV_ROOT_USER_NAME:-$NGINX_ROOT_PASS_WORD}" # root user password +#root_user_name="${ENV_ROOT_USER_NAME:-$root_user_name}" # +#root_user_pass="${ENV_ROOT_USER_PASS:-$root_user_pass}" # +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +#Normal user info [password/random] +#ENV_USER_NAME="${ENV_USER_NAME:-$NGINX_USER_NAME}" # +#ENV_USER_PASS="${ENV_USER_PASS:-$NGINX_USER_PASS_WORD}" # +#user_name="${ENV_USER_NAME:-$user_name}" # normal user name +#user_pass="${ENV_USER_PASS:-$user_pass}" # normal user password + +EOF + fi + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" ]; then + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_precopy_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __execute_prerun_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __run_pre_execute_checks_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_conf_files_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __post_execute_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __pre_message_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + __update_ssl_conf_local() { true; } + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + fi + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" || exitCode=$((exitCode + 1)) + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" || exitCode=$((exitCode + 1)) + return $exitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# script to start server +__run_start_script() { + local runExitCode=0 + local workdir="$(eval echo "${WORK_DIR:-}")" # expand variables + local cmd="$(eval echo "${EXEC_CMD_BIN:-}")" # expand variables + local args="$(eval echo "${EXEC_CMD_ARGS:-}")" # expand variables + local name="$(eval echo "${EXEC_CMD_NAME:-}")" # expand variables + local pre="$(eval echo "${EXEC_PRE_SCRIPT:-}")" # expand variables + local extra_env="$(eval echo "${CMD_ENV//,/ }")" # expand variables + local lc_type="$(eval echo "${LANG:-${LC_ALL:-$LC_CTYPE}}")" # expand variables + local home="$(eval echo "${workdir//\/root/\/tmp\/docker}")" # expand variables + local path="$(eval echo "$PATH")" # expand variables + local message="$(eval echo "")" # expand variables + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" # set hostname + [ -f "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" ] && . "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" + # + if [ -z "$cmd" ]; then + __post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" + retVal=$? + echo "Initializing $SCRIPT_NAME has completed" + exit $retVal + else + # ensure the command exists + if [ ! -x "$cmd" ]; then + echo "$name is not a valid executable" + return 2 + fi + # check and exit if already running + if __proc_check "$name" || __proc_check "$cmd"; then + echo "$name is already running" >&2 + return 0 + else + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # show message if env exists + if [ -n "$cmd" ]; then + [ -n "$SERVICE_USER" ] && echo "Setting up $cmd to run as $SERVICE_USER" || SERVICE_USER="root" + [ -n "$SERVICE_PORT" ] && echo "$name will be running on port $SERVICE_PORT" || SERVICE_PORT="" + fi + if [ -n "$pre" ] && [ -n "$(command -v "$pre" 2>/dev/null)" ]; then + export cmd_exec="$pre $cmd $args" + message="Starting service: $name $args through $pre" + else + export cmd_exec="$cmd $args" + message="Starting service: $name $args" + fi + [ -n "$su_exec" ] && echo "using $su_exec" | tee -a -p "/data/logs/init.txt" + echo "$message" | tee -a -p "/data/logs/init.txt" + su_cmd touch "$SERVICE_PID_FILE" + if [ "$RESET_ENV" = "yes" ]; then + env_command="$(echo "env -i HOME=\"$home\" LC_CTYPE=\"$lc_type\" PATH=\"$path\" HOSTNAME=\"$sysname\" USER=\"${SERVICE_USER:-$RUNAS_USER}\" $extra_env")" + execute_command="$(__trim "$su_exec $env_command $cmd_exec")" + if [ ! -f "$START_SCRIPT" ]; then + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} with env +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 +exit \$retVal + +EOF + fi + else + if [ ! -f "$START_SCRIPT" ]; then + execute_command="$(__trim "$su_exec $cmd_exec")" + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;[ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ] && rm -Rf "\$SERVICE_PID_FILE";exit \$exitCode' EXIT +# +set -Eeo pipefail +# Setting up $cmd to run as ${SERVICE_USER:-root} +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 >&2 +exit \$retVal + +EOF + fi + fi + fi + [ -x "$START_SCRIPT" ] || chmod 755 -Rf "$START_SCRIPT" + [ "$CONTAINER_INIT" = "yes" ] || eval sh -c "$START_SCRIPT" + runExitCode=$? + fi + return $runExitCode +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# username and password actions +__run_secure_function() { + local filesperms + if [ -n "$user_name" ] || [ -n "$user_pass" ]; then + for filesperms in "${USER_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + if [ -n "$root_user_name" ] || [ -n "$root_user_pass" ]; then + for filesperms in "${ROOT_FILE_PREFIX}"/*; do + if [ -e "$filesperms" ]; then + chmod -Rf 600 "$filesperms" + chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null + fi + done 2>/dev/null | tee -p -a "/data/logs/init.txt" + fi + unset filesperms +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow ENV_ variable - Import env file +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SERVICE_EXIT_CODE=0 # default exit code +# application specific +EXEC_CMD_NAME="$(basename -- "$EXEC_CMD_BIN")" # set the binary name +SERVICE_PID_FILE="/run/init.d/$EXEC_CMD_NAME.pid" # set the pid file location +SERVICE_PID_NUMBER="$(__pgrep)" # check if running +EXEC_CMD_BIN="$(type -P "$EXEC_CMD_BIN" || echo "$EXEC_CMD_BIN")" # set full path +EXEC_PRE_SCRIPT="$(type -P "$EXEC_PRE_SCRIPT" || echo "$EXEC_PRE_SCRIPT")" # set full path +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Only run check +__check_service "$1" && SERVICE_IS_RUNNING=yes +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# ensure needed directories exists +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create auth directories +[ -n "$USER_FILE_PREFIX" ] && { [ -d "$USER_FILE_PREFIX" ] || mkdir -p "$USER_FILE_PREFIX"; } +[ -n "$ROOT_FILE_PREFIX" ] && { [ -d "$ROOT_FILE_PREFIX" ] || mkdir -p "$ROOT_FILE_PREFIX"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ -n "$RUNAS_USER" ] || RUNAS_USER="root" +[ -n "$SERVICE_USER" ] || SERVICE_USER="$RUNAS_USER" +[ -n "$SERVICE_GROUP" ] || SERVICE_GROUP="${SERVICE_USER:-$RUNAS_USER}" +[ "$IS_WEB_SERVER" = "yes" ] && RESET_ENV="yes" && __is_htdocs_mounted +[ "$IS_WEB_SERVER" = "yes" ] && [ -z "$SERVICE_PORT" ] && SERVICE_PORT="80" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Database env +if [ "$IS_DATABASE_SERVICE" = "yes" ] || [ "$USES_DATABASE_SERVICE" = "yes" ]; then + RESET_ENV="no" + DATABASE_CREATE="${ENV_DATABASE_CREATE:-$DATABASE_CREATE}" + DATABASE_USER_NORMAL="${ENV_DATABASE_USER:-${DATABASE_USER_NORMAL:-$user_name}}" + DATABASE_PASS_NORMAL="${ENV_DATABASE_PASSWORD:-${DATABASE_PASS_NORMAL:-$user_pass}}" + DATABASE_USER_ROOT="${ENV_DATABASE_ROOT_USER:-${DATABASE_USER_ROOT:-$root_user_name}}" + DATABASE_PASS_ROOT="${ENV_DATABASE_ROOT_PASSWORD:-${DATABASE_PASS_ROOT:-$root_user_pass}}" + if [ -n "$DATABASE_PASS_NORMAL" ] && [ ! -f "${USER_FILE_PREFIX}/db_pass_user" ]; then + echo "$DATABASE_PASS_NORMAL" >"${USER_FILE_PREFIX}/db_pass_user" + fi + if [ -n "$DATABASE_PASS_ROOT" ] && [ ! -f "${ROOT_FILE_PREFIX}/db_pass_root" ]; then + echo "$DATABASE_PASS_ROOT" >"${ROOT_FILE_PREFIX}/db_pass_root" + fi +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# [DATABASE_DIR_[SQLITE,REDIS,POSTGRES,MARIADB,COUCHDB,MONGODB,SUPABASE]] +if [ "$DATABASE_SERVICE_TYPE" = "custom" ]; then + DATABASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_BASE_DIR="${DATABASE_DIR_CUSTOM:-/data/db/custom}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_CUSTOM:-/usr/local/share/httpd/admin/databases}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_CUSTOM:-/admin/dbadmin}" +elif [ "$SERVICE_NAME" = "redis" ] || [ "$DATABASE_SERVICE_TYPE" = "redis" ]; then + DATABASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_BASE_DIR="${DATABASE_DIR_REDIS:-/data/db/redis}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_REDIS:-/usr/local/share/httpd/admin/redis}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_REDIS:-/admin/redis}" +elif [ "$SERVICE_NAME" = "postgres" ] || [ "$DATABASE_SERVICE_TYPE" = "postgres" ]; then + DATABASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_BASE_DIR="${DATABASE_DIR_POSTGRES:-/data/db/postgres}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_POSTGRES:-/usr/local/share/httpd/admin/postgres}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_POSTGRES:-/admin/postgres}" +elif [ "$SERVICE_NAME" = "mariadb" ] || [ "$DATABASE_SERVICE_TYPE" = "mariadb" ]; then + DATABASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MARIADB:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MARIADB:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "mysql" ] || [ "$DATABASE_SERVICE_TYPE" = "mysql" ]; then + DATABASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_BASE_DIR="${DATABASE_DIR_MYSQL:-/data/db/mysql}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MYSQL:-/usr/local/share/httpd/admin/mysql}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MYSQL:-/admin/mysql}" +elif [ "$SERVICE_NAME" = "couchdb" ] || [ "$DATABASE_SERVICE_TYPE" = "couchdb" ]; then + DATABASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_BASE_DIR="${DATABASE_DIR_COUCHDB:-/data/db/couchdb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_COUCHDB:-/usr/local/share/httpd/admin/couchdb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_COUCHDB:-/admin/couchdb}" +elif [ "$SERVICE_NAME" = "mongodb" ] || [ "$DATABASE_SERVICE_TYPE" = "mongodb" ]; then + DATABASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_BASE_DIR="${DATABASE_DIR_MONGODB:-/data/db/mongodb}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_MONGODB:-/usr/local/share/httpd/admin/mongodb}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_MONGODB:-/admin/mongodb}" +elif [ "$SERVICE_NAME" = "supabase" ] || [ "$DATABASE_SERVICE_TYPE" = "supabase" ]; then + DATABASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_BASE_DIR="${DATABASE_DIR_SUPABASE:-/data/db/supabase}" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SUPABASE:-/usr/local/share/httpd/admin/supabase}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SUPBASE:-/admin/supabase}" +elif [ "$SERVICE_NAME" = "sqlite" ] || [ "$DATABASE_SERVICE_TYPE" = "sqlite" ]; then + DATABASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_BASE_DIR="${DATABASE_DIR_SQLITE:-/data/db/sqlite}/$SERVER_NAME" + DATABASE_ADMIN_WWW_ROOT="${DATABASE_ADMIN_WWW_ROOT_SQLITE:-/usr/local/share/httpd/admin/sqlite}" + [ -d "$DATABASE_ADMIN_WWW_ROOT" ] && SERVER_ADMIN_URL="${SERVER_ADMIN_URL_SQLITE:-/admin/sqlite}" + [ -d "$DATABASE_DIR" ] || mkdir -p "$DATABASE_DIR" + chmod 777 "$DATABASE_DIR" +fi +[ -n "$DATABASE_ADMIN_WWW_ROOT" ] && { [ ! -d "$DATABASE_ADMIN_WWW_ROOT" ] || mkdir -p "${DATABASE_ADMIN_WWW_ROOT}"; } +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow variables via imports - Overwrite existing +[ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ] && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set password to random if variable is random +[ "$user_pass" = "random" ] && user_pass="$(__random_password ${RANDOM_PASS_USER:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ "$root_user_pass" = "random" ] && root_user_pass="$(__random_password ${RANDOM_PASS_ROOT:-16})" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow setting initial users and passwords via environment and save to file +[ -n "$user_name" ] && echo "$user_name" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$user_pass" ] && echo "$user_pass" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" +[ -n "$root_user_name" ] && echo "$root_user_name" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$root_user_pass" ] && echo "$root_user_pass" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create needed dirs +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Allow per init script usernames and passwords +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_name" && user_name="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" && user_pass="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" && root_user_name="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" && root_user_pass="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${USER_FILE_PREFIX}/db_pass_user" && DATABASE_PASS_NORMAL="$(<"${USER_FILE_PREFIX}/db_pass_user")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/db_pass_root" && DATABASE_PASS_ROOT="$(<"${ROOT_FILE_PREFIX}/db_pass_root")" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set hostname for script +sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__create_service_env +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Setup /config directories +__init_config_etc +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# pre-run function +__execute_prerun +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# create user if needed +__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Modify user if needed +__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Create base directories +__setup_directories +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# set switch user command +__switch_to_user +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize the home/working dir +__init_working_dir +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# show init message +__pre_message +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_db_users +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Initialize ssl +__update_ssl_conf +__update_ssl_certs +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions in ${USER_FILE_PREFIX} and ${ROOT_FILE_PREFIX} +__run_secure_function +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_precopy +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Copy /config to /etc +for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do + __initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Replace variables +__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__initialize_database +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Updating config files +__update_conf_files +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# run the pre execute commands +__pre_execute +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Set permissions +__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# +__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log" +errorCode=$? +if [ -n "$EXEC_CMD_BIN" ]; then + if [ "$errorCode" -eq 0 ]; then + SERVICE_EXIT_CODE=0 + SERVICE_IS_RUNNING="yes" + else + SERVICE_EXIT_CODE=$errorCode + SERVICE_IS_RUNNING="${SERVICE_IS_RUNNING:-no}" + [ -s "$SERVICE_PID_FILE" ] || rm -Rf "$SERVICE_PID_FILE" + fi + SERVICE_EXIT_CODE=0 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# start the post execute function in background +__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__banner "Initializing of $SERVICE_NAME has completed with statusCode: $SERVICE_EXIT_CODE" | tee -p -a "/data/logs/entrypoint.log" "/data/logs/init.txt" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +exit $SERVICE_EXIT_CODE diff --git a/rootfs/usr/share/httpd/default/hidden_service.html b/rootfs/usr/share/httpd/default/hidden_service.html new file mode 100644 index 0000000..a834212 --- /dev/null +++ b/rootfs/usr/share/httpd/default/hidden_service.html @@ -0,0 +1,22 @@ + + + + + + + + Welcome! + + +
+


+

+ Welcome to your hidden onion site!
+ This document is located in: REPLACE_ONION_WWW_DIR +

+
+ + diff --git a/rootfs/usr/share/httpd/default/index.css b/rootfs/usr/share/httpd/default/index.css new file mode 100644 index 0000000..bfe96d3 --- /dev/null +++ b/rootfs/usr/share/httpd/default/index.css @@ -0,0 +1,116 @@ +TD, +TH, +BODY { + font-family: Verdana, Helvetica, sans-serif; + font-size: 1.1rem; + font-weight: normal; + font-variant: normal; + text-transform: none; + text-decoration: none; + text-align: center; + text-wrap: balance; + background-color: #333; + color: #fff; + background-image: url('/index.png'); +} + +TH { + background-color: #333; + color: #ffffff; + border-top: 1px solid #678ca0; + vertical-align: middle; + height: 50px; +} + +TD { + background-color: 333; + border-top: 1px solid #678ca0; +} + +.box { + border: 1px solid #678ca0; + padding: 0px; + width: 100%; + background-color: #333; + margin-bottom: 10px; + width: 600px; +} + +H5, +H3 { + padding: 3px; + margin-top: 0px; + margin-bottom: 0px; + background-color: #333; + color: white; + font-family: Verdana, Helvetica, sans-serif; +} + +p { + text-align: center; +} + +div { + text-align: center; +} + +H3 { + font-size: 13px; +} + +H5 { + font-size: 10px; + text-align: right; + background-color: #333; + color: #678ca0; +} + +.spacer { + margin: 0px; + width: 100%; + background-color: #333; +} + +.leftspacer { + margin: 0px; + padding: 5px; + width: 100%; + text-align: left; + background-color: #333; +} + +.serviceup { + color: green; +} + +.servicedown { + color: red; +} + +A { + text-decoration: none; + color: #5d83a9; +} + +P.main { + margin-top: 5px; + margin-bottom: 5px; + text-align: center; + font-size: 10px; +} + +a:visited { + color: #c39; +} + +a:hover { + color: #f00; +} + +a:active { + color: #c0f; +} + +tr:hover { + background-color: #f5f5f5; +} diff --git a/rootfs/usr/share/httpd/default/index.html b/rootfs/usr/share/httpd/default/index.html new file mode 100644 index 0000000..76d15f8 --- /dev/null +++ b/rootfs/usr/share/httpd/default/index.html @@ -0,0 +1,30 @@ + + + + + + + + Welcome + + + +
+

+


+
+ Tor DNS is running on port 9053 and Tor Socks on 9050
+ Server address is: REPLACE_DEFAULT_TOR_ADDRESS
+
+ Other usefull onion sites
+ DuckDuckGo Search
+ Tor Hidden Wiki
+ Protonmail
+ Tor Project
+ Secure Drop
+ A very long list of other onion sites
+



+

+
+ + diff --git a/rootfs/usr/share/httpd/default/list.html b/rootfs/usr/share/httpd/default/list.html new file mode 100644 index 0000000..0ced704 --- /dev/null +++ b/rootfs/usr/share/httpd/default/list.html @@ -0,0 +1,1654 @@ + + + + + + + + + Welcome to your tor site + + +
+
+ +

Real-World Onion Sites

+

This is a list of substantial, commercial-or-social-good mainstream websites which provide onion services.

+
    +
  • no sites with an "onion-only" presence
  • +
  • no sites for products/technology with less than (arbitrary) 10,000 users
  • +
  • no nudity, exploitation, drugs, copyright infringement or sketchy-content sites
  • +
  • the editor reserves all rights to annotate or drop any or all entries as deemed fit
  • +
  • licensed: cc-by-sa
  • +
  • author/editor: alec muffett
  • +
+

Legend/Key for Symbols

+

You can find techical details and the legend/key for symbols in the footnotes section, below.

+

Regarding Updates and Suggestions

+
    +
  • This file (README.md) is auto-generated from a spreadsheet
  • +
  • Please submit an Issue for consideration / desired change requests
  • +
  • Do NOT submit changes NOR pull-requests for it
  • +
  • Re: SecureDrop - all SecureDrop entries are taken automatically from +https://securedrop.org/api/v1/directory/ and must be amended on that site, +not this one.
  • +
+
+

Index

+ +
+

Blogs

+

Alexander Færøy

+ +

Ctrl blog

+ +

Dropsafe | Alec Muffett

+ +

Kushal Das

+ +

Michael Altfield

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://michaelahgu3sqef5yz3u242nok2uczduq5oxqfkwq646tvjhdnl35id.onion/
  • +
  • plain: http://michaelahgu3sqef5yz3u242nok2uczduq5oxqfkwq646tvjhdnl35id.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Ming Di Leom

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://xw226dvxac7jzcpsf4xb64r4epr6o5hgn46dxlqk7gnjptakik6xnzqd.onion/
  • +
  • plain: https://xw226dvxac7jzcpsf4xb64r4epr6o5hgn46dxlqk7gnjptakik6xnzqd.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Nick Frichette

+ +

Shen's Essays

+ +

:arrow_up: return to top index

+
+

Civil Society and Community

+

Privacy International

+ +

Riseup Home

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion/
  • +
  • plain: http://vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Riseup Onion Index

+

provides shared notepad, file sharing, code hosting, and other services

+ +

Systemli Home

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://7sk2kov2xwx6cbc32phynrifegg6pklmzs7luwcggtzrnlsolxxuyfyd.onion/en/index.html
  • +
  • plain: http://7sk2kov2xwx6cbc32phynrifegg6pklmzs7luwcggtzrnlsolxxuyfyd.onion/en/index.html
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Systemli Onion Index

+

provides shared notepad, spreadsheet, pastebin, and other services

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://7sk2kov2xwx6cbc32phynrifegg6pklmzs7luwcggtzrnlsolxxuyfyd.onion/en/service/onion.html
  • +
  • plain: http://7sk2kov2xwx6cbc32phynrifegg6pklmzs7luwcggtzrnlsolxxuyfyd.onion/en/service/onion.html
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

WikiFesad

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://hyfs2rd42ij4opqkdxzycb7dolzwjtbmmm4mbpohc57mm76u6iyurxqd.onion/
  • +
  • plain: https://hyfs2rd42ij4opqkdxzycb7dolzwjtbmmm4mbpohc57mm76u6iyurxqd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+ +

english law firm; see also https://neilzone.co.uk/2022/03/upgrading-my-onion-site-to-https

+ +

:arrow_up: return to top index

+
+

Education

+

BBC Learning English

+

includes resources for many languages

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/learningenglish/
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/learningenglish/
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC Learning English: Mandarin

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/learningenglish/chinese
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/learningenglish/chinese
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

:arrow_up: return to top index

+
+

Government

+

US Central Intelligence Agency

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://ciadotgov4sjwlzihbbgxnqg3xiyrg7so2r2o3lt5wz5ypk4sxyjstad.onion/index.html
  • +
  • plain: http://ciadotgov4sjwlzihbbgxnqg3xiyrg7so2r2o3lt5wz5ypk4sxyjstad.onion/index.html
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

:arrow_up: return to top index

+
+

News

+

BBC

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcnewsd73hkzno2ini43t4gblxvycyac5aw4gnv7t2rccijh7745uqd.onion/
  • +
  • plain: https://www.bbcnewsd73hkzno2ini43t4gblxvycyac5aw4gnv7t2rccijh7745uqd.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Bellingcat

+ +

Bellingcat | es

+ +

Bellingcat | fr

+ +

Bellingcat | ru

+ +

Bellingcat | ua

+ +

Deutsche Welle

+

see language index in titlebar

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

ProPublica

+ +

Radio Free Europe | RFERL

+

https://www.rfa.org/about/releases/mirror_websites-04172020105949.html

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.rferlo2zxgv23tct66v45s5mecftol5vod3hf4rqbipfp46fqu2q56ad.onion/
  • +
  • plain: https://www.rferlo2zxgv23tct66v45s5mecftol5vod3hf4rqbipfp46fqu2q56ad.onion/
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

The Guardian

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.guardian2zotagl6tmjucg3lrhxdk4dw3lhbqnkvvkywawy3oqfoprid.onion/
  • +
  • plain: https://www.guardian2zotagl6tmjucg3lrhxdk4dw3lhbqnkvvkywawy3oqfoprid.onion/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

The Intercept

+ +

The New York Times

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.nytimesn7cgmftshazwhfgzm37qxb44r64ytbb2dj3x62d2lljsciiyd.onion/
  • +
  • plain: https://www.nytimesn7cgmftshazwhfgzm37qxb44r64ytbb2dj3x62d2lljsciiyd.onion/
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Voice of America | VOA

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.voanews5aitmne6gs2btokcacixclgfl43cv27sirgbauyyjylwpdtqd.onion/
  • +
  • plain: https://www.voanews5aitmne6gs2btokcacixclgfl43cv27sirgbauyyjylwpdtqd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Yahoo News

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://yahoonewsnqkxo423g7vuwr2mvkwmc5t4df5x44dfdfvmyzqgcyt3had.onion/
  • +
  • plain: https://yahoonewsnqkxo423g7vuwr2mvkwmc5t4df5x44dfdfvmyzqgcyt3had.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :question::question::question::question::question::question::question::question::question::question::question::question::question::question:
  • +
+

:arrow_up: return to top index

+
+

News BBC World Service

+

BBC News /afaanoromoo | Afaan Oromoo

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/afaanoromoo
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/afaanoromoo
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /afrique | Afrique

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/afrique
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/afrique
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /amharic | አማርኛ

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/amharic
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/amharic
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /arabic | عربي

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/arabic
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/arabic
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /azeri | Azərbaycanca

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/azeri
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/azeri
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /bengali | বাংলা

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/bengali
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/bengali
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /burmese | မြန်မာ

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/burmese
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/burmese
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /gahuza | Gahuza

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/gahuza
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/gahuza
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /gujarati | ગુજરાતી

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/gujarati
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/gujarati
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /hausa | Hausa

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/hausa
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/hausa
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /hindi | हिंदी

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/hindi
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/hindi
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /igbo | Ìgbò

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/igbo
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/igbo
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /indonesia | Indonesia

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/indonesia
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/indonesia
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /korean | 코리아

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/korean
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/korean
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /kyrgyz | Кыргыз КызMATы

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/kyrgyz
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/kyrgyz
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /marathi | मराठी

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/marathi
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/marathi
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /mundo | Mundo

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/mundo
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/mundo
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /nepali | नेपाली

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/nepali
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/nepali
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /pashto | پښتو

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/pashto
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/pashto
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /persian | فارسی

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/persian
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/persian
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /pidgin | Pidgin

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/pidgin
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/pidgin
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /portuguese | Brasil

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/portuguese
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/portuguese
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /punjabi | ਪੰਜਾਬੀ

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/punjabi
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/punjabi
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /russian | Русская служба

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/russian
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/russian
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /serbian/cyr | на српском

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/serbian/cyr
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/serbian/cyr
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /serbian/lat | na srpskom

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/serbian/lat
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/serbian/lat
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /sinhala | සිංහල

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/sinhala
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/sinhala
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /somali | Somali

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/somali
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/somali
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /swahili | Swahili

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/swahili
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/swahili
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /tamil | தமிழ்

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/tamil
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/tamil
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /telugu | తెలుగు

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/telugu
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/telugu
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /thai | ไทย

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/thai
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/thai
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /tigrinya | ትግርኛ

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/tigrinya
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/tigrinya
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /turkce | Türkçe

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/turkce
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/turkce
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /ukrainian | Україна

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/ukrainian
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/ukrainian
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /urdu | اردو

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/urdu
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/urdu
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /uzbek | O'zbek

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/uzbek
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/uzbek
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

BBC News /vietnamese | Tiếng Việt

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/vietnamese
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/vietnamese
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /yoruba | Yorùbá

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/yoruba
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/yoruba
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /zhongwen/simp | 中文

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/zhongwen/simp
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/zhongwen/simp
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News /zhongwen/trad | 中文

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/zhongwen/trad
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/zhongwen/trad
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

BBC News | In Your Language

+

language index

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/ws/languages
  • +
  • plain: https://www.bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion/ws/languages
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

:arrow_up: return to top index

+
+

News Deutsche Welle World

+

Deutsche Welle Albanian | Shqip

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/sq/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/sq/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Amharic | አማርኛ

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/am/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/am/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Arabic | العربية

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ar/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ar/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Bengali | বাংলা

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/bn/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/bn/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Bosnian | B/H/S

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/bs/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/bs/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Bulgarian | Български

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/bg/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/bg/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Chinese (Simplified) | 简

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/zh/?zhongwen=simp
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/zh/?zhongwen=simp
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Chinese (Traditional) | 繁

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/zh/?zhongwen=trad
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/zh/?zhongwen=trad
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Croatian | Hrvatski

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/hr/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/hr/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Dari | دری

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/fa-af/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/fa-af/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle English | English

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/en/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/en/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle French | Français

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/fr/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/fr/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle German | Deutsch

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/de/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/de/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Greek | Ελληνικά

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/el/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/el/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Hausa | Hausa

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ha/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ha/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Hindi | हिन्दी

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/hi/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/hi/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Indonesian | Indonesia

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/id/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/id/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Kiswahili | Kiswahili

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/sw/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/sw/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Macedonian | Македонски

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/mk/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/mk/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Pashto | پښتو

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ps/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ps/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Persian | فارسی

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/fa-ir/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/fa-ir/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Polish | Polski

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/pl/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/pl/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Portuguese | Português do Brasil

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/pt-br/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/pt-br/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Portuguese | Português para África

+

cannot find top-page redirect

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/pt-002/not%C3%ADcias/s-13918
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/pt-002/not%C3%ADcias/s-13918
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Deutsche Welle Romanian | Română

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ro/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ro/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Russian | Русский

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ru/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ru/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Serbian | Српски/Srpski

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/sr/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/sr/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Spanish | Español

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/es/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/es/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Turkish | Türkçe

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/tr/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/tr/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Ukrainian | Українська

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/uk/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/uk/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Deutsche Welle Urdu | اردو

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ur/
  • +
  • plain: https://www.dwnewsgngmhlplxy6o2twtfgjnrnjxbegbwqx6wnotdhkzt562tszfid.onion/ur/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

:arrow_up: return to top index

+
+

News RFERL & VOA

+

RFERL azatliq | Азатлык хәбәрләре

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.azatli7ifydxlltreov6fyvzwuflgggwdgry2cnxllzs7xpoh7qjmmid.onion/
  • +
  • plain: https://www.azatli7ifydxlltreov6fyvzwuflgggwdgry2cnxllzs7xpoh7qjmmid.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL currenttime.tv | Настоящее Время

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.currtv242aqatxhyqfyh3mtq2ubzxz7crvj7aon3zccrnwatc5gugvqd.onion/
  • +
  • plain: https://www.currtv242aqatxhyqfyh3mtq2ubzxz7crvj7aon3zccrnwatc5gugvqd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL europalibera md | Europa Liberă

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://moldova.eurolibaoxh6xnxcms7egvag474qnjeca5m6rvomwhmmkw2jkascwhqd.onion/
  • +
  • plain: https://moldova.eurolibaoxh6xnxcms7egvag474qnjeca5m6rvomwhmmkw2jkascwhqd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL europalibera ro | Europa Liberă

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://romania.eurolibaoxh6xnxcms7egvag474qnjeca5m6rvomwhmmkw2jkascwhqd.onion/
  • +
  • plain: https://romania.eurolibaoxh6xnxcms7egvag474qnjeca5m6rvomwhmmkw2jkascwhqd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL farda | رادیو فردا

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.farda7tcb3bmdtmsmwx7wofkxxjrcw4iiizin7zzcju2oega74cnzbid.onion/
  • +
  • plain: https://www.farda7tcb3bmdtmsmwx7wofkxxjrcw4iiizin7zzcju2oega74cnzbid.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL idelreal | Idel Реалии

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.idelraalduykh5md4f5kempsx2vhhvs53sf7td25imcsyscru7i63cyd.onion/
  • +
  • plain: https://www.idelraalduykh5md4f5kempsx2vhhvs53sf7td25imcsyscru7i63cyd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL kavkazr | Кавказ Реалии

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.kavkazrtsgiv5be4orqcben4bbr2zfikcx2zb4uceuhbu6vhlxbnbjqd.onion/
  • +
  • plain: https://www.kavkazrtsgiv5be4orqcben4bbr2zfikcx2zb4uceuhbu6vhlxbnbjqd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL krymr ktat | Qırım Aqiqat

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://ktat.krymr37vzmjc3lzijeokiaaa5scwqdveyeljh6eri4aqjqhkviv446id.onion/
  • +
  • plain: https://ktat.krymr37vzmjc3lzijeokiaaa5scwqdveyeljh6eri4aqjqhkviv446id.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL krymr ru | Крым Реалии

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://ru.krymr37vzmjc3lzijeokiaaa5scwqdveyeljh6eri4aqjqhkviv446id.onion/
  • +
  • plain: https://ru.krymr37vzmjc3lzijeokiaaa5scwqdveyeljh6eri4aqjqhkviv446id.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL krymr ua | Крим Реалії

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://ua.krymr37vzmjc3lzijeokiaaa5scwqdveyeljh6eri4aqjqhkviv446id.onion/
  • +
  • plain: https://ua.krymr37vzmjc3lzijeokiaaa5scwqdveyeljh6eri4aqjqhkviv446id.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL radiomarsho | Маршо Радион

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.marsho5jlvj4v5bv5zatvfzg6gd33hrykaejm2fpdxegxgqqazs76hqd.onion/
  • +
  • plain: https://www.marsho5jlvj4v5bv5zatvfzg6gd33hrykaejm2fpdxegxgqqazs76hqd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL severreal | Сибирь Реалии

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.severr375roaznysslbu4joiu2snztzwucsm46gghi34xglhh5w4cmyd.onion/
  • +
  • plain: https://www.severr375roaznysslbu4joiu2snztzwucsm46gghi34xglhh5w4cmyd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL sibreal | Сибирь Реалии

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.sibrealr32niwsfksyycn6dyci3wnssnq5xhg3g7kpkddyrzfh2fd4qd.onion/
  • +
  • plain: https://www.sibrealr32niwsfksyycn6dyci3wnssnq5xhg3g7kpkddyrzfh2fd4qd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

RFERL svaboda | Радыё Свабода

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.svabodmmmsdce3rmzoor5cw3byj6rqss4q6bh2yfhux2dbmobnpg5ead.onion/
  • +
  • plain: https://www.svabodmmmsdce3rmzoor5cw3byj6rqss4q6bh2yfhux2dbmobnpg5ead.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

VOA russian | Голоса Америки

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.golosamr2fr3ojunabk2zaa2hyislbt2ht34vjhfsdwpg2dyg2xaybqd.onion/
  • +
  • plain: https://www.golosamr2fr3ojunabk2zaa2hyislbt2ht34vjhfsdwpg2dyg2xaybqd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

VOA turkish | Amerika'nın Sesi

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.sesic3wy3ursfzn7odbol5ddurz2kr3rbfvgnowhwbaefjahzwwsycqd.onion/
  • +
  • plain: https://www.sesic3wy3ursfzn7odbol5ddurz2kr3rbfvgnowhwbaefjahzwwsycqd.onion/
  • +
  • proof: :crystal_ball: to be confirmed
  • +
  • check: :question::question::question::question::question::question::question::question::question::question::question::question::question::question:
  • +
+

:arrow_up: return to top index

+
+

Search Engines

+

Brave Search

+

works fine, but seems to block curl / upness-tester; ignore status codes below

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://search.brave4u7jddbv7cyviptqjc7jusxh72uik7zt6adtckl5f4nwy2v72qd.onion/
  • +
  • plain: https://search.brave4u7jddbv7cyviptqjc7jusxh72uik7zt6adtckl5f4nwy2v72qd.onion/
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

DuckDuckGo Search

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/
  • +
  • plain: https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

:arrow_up: return to top index

+
+

Social Networks

+

Facebook

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion/
  • +
  • plain: https://www.facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::white_check_mark::white_check_mark::eight_spoked_asterisk::white_check_mark::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::white_check_mark::white_check_mark::eight_spoked_asterisk:
  • +
+

Facebook Mobile

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://m.facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion/
  • +
  • plain: https://m.facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Reddit

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://www.reddittorjg6rue252oqsxryoxengawnmo46qy4kyii5wtqnwfj4ooad.onion/
  • +
  • plain: https://www.reddittorjg6rue252oqsxryoxengawnmo46qy4kyii5wtqnwfj4ooad.onion/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Twitter

+ +

:arrow_up: return to top index

+
+

Tech and Software

+

Ablative Hosting

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://hzwjmjimhr7bdmfv2doll4upibt5ojjmpo3pbp5ctwcg37n3hyk7qzid.onion/
  • +
  • plain: https://hzwjmjimhr7bdmfv2doll4upibt5ojjmpo3pbp5ctwcg37n3hyk7qzid.onion/
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

DEF CON Groups

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://jrw32khnmfehvdsvwdf34mywoqj5emvxh4mzbkls6jk2cb3thcgz6nid.onion/
  • +
  • plain: http://jrw32khnmfehvdsvwdf34mywoqj5emvxh4mzbkls6jk2cb3thcgz6nid.onion/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::question::eight_spoked_asterisk::question::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

DEF CON Home

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://g7ejphhubv5idbbu3hb3wawrs5adw7tkx7yjabnf65xtzztgg4hcsqqd.onion/
  • +
  • plain: http://g7ejphhubv5idbbu3hb3wawrs5adw7tkx7yjabnf65xtzztgg4hcsqqd.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::question::white_check_mark::question::white_check_mark::white_check_mark:
  • +
+

DEF CON Media

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://m6rqq6kocsyugo2laitup5nn32bwm3lh677chuodjfmggczoafzwfcad.onion/
  • +
  • plain: http://m6rqq6kocsyugo2laitup5nn32bwm3lh677chuodjfmggczoafzwfcad.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::question::white_check_mark::question::white_check_mark::white_check_mark:
  • +
+

Debian Onion Index

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://jvgypgbnfyvfopg5msp6nwr2sl2fd6xmnguq35n7rfkw3yungjn2i4yd.onion/
  • +
  • plain: http://jvgypgbnfyvfopg5msp6nwr2sl2fd6xmnguq35n7rfkw3yungjn2i4yd.onion/
  • +
  • proof: link
  • +
  • check: :timer_clock::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Hardened BSD Onion Index

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://lkiw4tmbudbr43hbyhm636sarn73vuow77czzohdbqdpjuq3vdzvenyd.onion/
  • +
  • plain: http://lkiw4tmbudbr43hbyhm636sarn73vuow77czzohdbqdpjuq3vdzvenyd.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Impreza Hosting

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion/
  • +
  • plain: https://imprezareshna326gqgmbdzwmnad2wnjmeowh45bs2buxarh5qummjad.onion/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

OnionShare

+ +

Qubes OS

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://www.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/
  • +
  • plain: http://www.qubesosfasa4zl44o4tws22di6kepyzfeqv3tg4e3ztknltfxqrymdad.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Tor Project Home

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion/
  • +
  • plain: http://2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Tor Project Onion Index

+

everything tor-related

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://xao2lxsmia2edq2n5zxg6uahx6xox2t7bfjw6b5vdzsxi7ezmqob6qid.onion/
  • +
  • plain: http://xao2lxsmia2edq2n5zxg6uahx6xox2t7bfjw6b5vdzsxi7ezmqob6qid.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Whonix Forums

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://forums.dds6qkxpwdeubwucdiaord2xgbbeyds25rbsgr73tbfpqpt4a6vjwsyd.onion/
  • +
  • plain: http://forums.dds6qkxpwdeubwucdiaord2xgbbeyds25rbsgr73tbfpqpt4a6vjwsyd.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Whonix Home

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://dds6qkxpwdeubwucdiaord2xgbbeyds25rbsgr73tbfpqpt4a6vjwsyd.onion/
  • +
  • plain: http://dds6qkxpwdeubwucdiaord2xgbbeyds25rbsgr73tbfpqpt4a6vjwsyd.onion/
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

keybase.io

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://keybase5wmilwokqirssclfnsqrjdsi7jdir5wy7y7iu3tanwmtp6oid.onion/
  • +
  • plain: http://keybase5wmilwokqirssclfnsqrjdsi7jdir5wy7y7iu3tanwmtp6oid.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

:arrow_up: return to top index

+
+

Web and Internet

+

Archive Today

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://archiveiya74codqgiixo33q62qlrqtkgmcitqx5u2oeqnmn5bpcbiyd.onion/
  • +
  • plain: http://archiveiya74codqgiixo33q62qlrqtkgmcitqx5u2oeqnmn5bpcbiyd.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Cloudflare Public DNS 1.1.1.1

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion/
  • +
  • plain: https://dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion/
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

HARICA Certificate Authority

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://4gmrlefxkq4mtan6a2lqwfwa7un4brjlatka75nwdczemqqwn3wznnad.onion/
  • +
  • plain: https://4gmrlefxkq4mtan6a2lqwfwa7un4brjlatka75nwdczemqqwn3wznnad.onion/
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Protonmail

+
    +
  • transport: :closed_lock_with_key: HTTPS
  • +
  • link: https://protonmailrmez3lotccipshtkleegetolb73fuirgj7r4o4vfu7ozyd.onion/
  • +
  • plain: https://protonmailrmez3lotccipshtkleegetolb73fuirgj7r4o4vfu7ozyd.onion/
  • +
  • proof: :lock: see tls/ssl certificate
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

:arrow_up: return to top index

+
+

SecureDrop

+

2600: The Hacker Quarterly

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: 2600.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://cy6wj77vryhcyh6go576hxycjz4wxlo4s5vevdinkw3armwzty5jozyd.onion
  • +
  • plain: http://cy6wj77vryhcyh6go576hxycjz4wxlo4s5vevdinkw3armwzty5jozyd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Aftenposten AS

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: aftenposten.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://tiykfvhb562gheutfnedysnhrxpxoztyszkqyroloyepwzxmxien77id.onion
  • +
  • plain: http://tiykfvhb562gheutfnedysnhrxpxoztyszkqyroloyepwzxmxien77id.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Aftonbladet

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: aftonbladet.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://xm33ge4kupk5o66eqxcd2r4fqcplpqb2sbdduf5z2nw4g2jrxe57luid.onion
  • +
  • plain: http://xm33ge4kupk5o66eqxcd2r4fqcplpqb2sbdduf5z2nw4g2jrxe57luid.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Bloomberg Industry Group

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: bloombergindustrygroup.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://33buewrpzrfpttl7kerqvtvzyo3ivumilwwmeqjryzajusltibaqc6ad.onion
  • +
  • plain: http://33buewrpzrfpttl7kerqvtvzyo3ivumilwwmeqjryzajusltibaqc6ad.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Bloomberg News

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: bloomberg.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://ogdwaroarq4p6rnfn2hl4crvldyruyc2g24435qtxmd3twhevg7dsqid.onion
  • +
  • plain: http://ogdwaroarq4p6rnfn2hl4crvldyruyc2g24435qtxmd3twhevg7dsqid.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

CBC

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: cbcrc.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://gppg43zz5d2yfuom3yfmxnnokn3zj4mekt55onlng3zs653ty4fio6qd.onion
  • +
  • plain: http://gppg43zz5d2yfuom3yfmxnnokn3zj4mekt55onlng3zs653ty4fio6qd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

CNN

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: cnn.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://qmifwf762qftydprw2adbg7hs2mkunac5xrz3cb5busaflji3rja5lid.onion
  • +
  • plain: http://qmifwf762qftydprw2adbg7hs2mkunac5xrz3cb5busaflji3rja5lid.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Dagbladet

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: dagbladet.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://ydbpz5knb6ji3bdtahhm3wo7sed6lsy5vqnwfpnhpez4bquvoexbz7qd.onion
  • +
  • plain: http://ydbpz5knb6ji3bdtahhm3wo7sed6lsy5vqnwfpnhpez4bquvoexbz7qd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Der Spiegel

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: spiegel.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://q6vdlj2ukulrqk37piqgxucpcwtxzdjhvjzqrfbevuhrzimsgjltmpqd.onion
  • +
  • plain: http://q6vdlj2ukulrqk37piqgxucpcwtxzdjhvjzqrfbevuhrzimsgjltmpqd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Financial Times

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: ft.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://nqu6crmtnzs2hs5abo2uqni53yqsnnwqnerdxuzyz5yxairxlzjzt6yd.onion
  • +
  • plain: http://nqu6crmtnzs2hs5abo2uqni53yqsnnwqnerdxuzyz5yxairxlzjzt6yd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Forbes

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: forbes.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://6zonlfhh7aqtfwoyvdlad3nxn6ljecx2k6tyyy3spt43nn54q6lvncid.onion
  • +
  • plain: http://6zonlfhh7aqtfwoyvdlad3nxn6ljecx2k6tyyy3spt43nn54q6lvncid.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Forbidden Stories

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: forbiddenstories.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://fg25fqpu2dnxp24xs3jlcley4hp2inshpzek44q3czkhq3zffoqk26id.onion
  • +
  • plain: http://fg25fqpu2dnxp24xs3jlcley4hp2inshpzek44q3czkhq3zffoqk26id.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Greekleaks

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: greekleaks.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://jatasaqcoe7lqdpcyxo7vl3e5tdvl5jgmtadfat77i25qdj6z6a4ulad.onion
  • +
  • plain: http://jatasaqcoe7lqdpcyxo7vl3e5tdvl5jgmtadfat77i25qdj6z6a4ulad.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Kenneth R. Rosen

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: kennethrrosen.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://dpsw5tvlh2pccviydqw2cz5tjszd34zcdj322oikydqvgsqwitxup7yd.onion
  • +
  • plain: http://dpsw5tvlh2pccviydqw2cz5tjszd34zcdj322oikydqvgsqwitxup7yd.onion
  • +
  • proof: link
  • +
  • check: :question::question::question::question::question::question::question::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

NOYB

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: noyb.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://xjc4s5z26i2z5tzjzj3w6jwzuomedzsahq4tccktwdcs6fldt4ojznqd.onion
  • +
  • plain: http://xjc4s5z26i2z5tzjzj3w6jwzuomedzsahq4tccktwdcs6fldt4ojznqd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

NRK

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: nrk.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://537ztcntpbmspja4mkpxldpsoc46mqlssnsaklqnfw3gnlpj5glcjgid.onion
  • +
  • plain: http://537ztcntpbmspja4mkpxldpsoc46mqlssnsaklqnfw3gnlpj5glcjgid.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

New York Times

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: nytimes.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://ej3kv4ebuugcmuwxctx5ic7zxh73rnxt42soi3tdneu2c2em55thufqd.onion
  • +
  • plain: http://ej3kv4ebuugcmuwxctx5ic7zxh73rnxt42soi3tdneu2c2em55thufqd.onion
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

News24

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: news24.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://uhmj4j5pnwbpmkebfze3qgjmkum465fvok376nxtpku5yvyv5takz6qd.onion
  • +
  • plain: http://uhmj4j5pnwbpmkebfze3qgjmkum465fvok376nxtpku5yvyv5takz6qd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

POLITICO

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: politico.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://mzi5yynpd6qqq3lnh7vnaojy36v3hcorytsut47zwkguhnorduyxwead.onion
  • +
  • plain: http://mzi5yynpd6qqq3lnh7vnaojy36v3hcorytsut47zwkguhnorduyxwead.onion
  • +
  • proof: link
  • +
  • check: :question::question::question::question::question::question::question::question::question::question::question::question::question::question:
  • +
+

Public Intelligence

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://z4gd5t2g6u6kqeqjeddvmvlhhjtjgslg4elh4ztnct7snskcd7phbiyd.onion
  • +
  • plain: http://z4gd5t2g6u6kqeqjeddvmvlhhjtjgslg4elh4ztnct7snskcd7phbiyd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Stefania Maurizi

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: maurizi.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://jxsb4ovmavjy3r64bak4ha63xwggf3nzf3vikvs23r2avm5rhzmaqtqd.onion
  • +
  • plain: http://jxsb4ovmavjy3r64bak4ha63xwggf3nzf3vikvs23r2avm5rhzmaqtqd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Süddeutsche Zeitung

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://udhauo3m3fh7v6yfiuornjzxn3fh6vlp4ooo3wogvghcnv5xik6mnayd.onion
  • +
  • plain: http://udhauo3m3fh7v6yfiuornjzxn3fh6vlp4ooo3wogvghcnv5xik6mnayd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Taz

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: taz.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://tazleakssvtc2lqrhkpvbzo6qwolcldzkzoexo7wombufd6a573bhlid.onion
  • +
  • plain: http://tazleakssvtc2lqrhkpvbzo6qwolcldzkzoexo7wombufd6a573bhlid.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

The Economist

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: theeconomist.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://mxmddqsh4jnr4gjan37ayin3fu5ecnejxge4wjhj4i45qq5djbxdjtad.onion
  • +
  • plain: http://mxmddqsh4jnr4gjan37ayin3fu5ecnejxge4wjhj4i45qq5djbxdjtad.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

The Globe and Mail

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: theglobeandmail.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://a4zum5ydurvljrohxqp2rjjal5kro4ge2q2qizuonf2jubkhcr627gad.onion
  • +
  • plain: http://a4zum5ydurvljrohxqp2rjjal5kro4ge2q2qizuonf2jubkhcr627gad.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

The Guardian

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: theguardian.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://xp44cagis447k3lpb4wwhcqukix6cgqokbuys24vmxmbzmaq2gjvc2yd.onion
  • +
  • plain: http://xp44cagis447k3lpb4wwhcqukix6cgqokbuys24vmxmbzmaq2gjvc2yd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

The Intercept

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: theintercept.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://lhollo6vzrft3w77mgm67fhfv3fjadmf7oinmafa7tbmupc273oi7kid.onion
  • +
  • plain: http://lhollo6vzrft3w77mgm67fhfv3fjadmf7oinmafa7tbmupc273oi7kid.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

The Washington Post

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: washingtonpost.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://vfnmxpa6fo4jdpyq3yneqhglluweax2uclvxkytfpmpkp5rsl75ir5qd.onion
  • +
  • plain: http://vfnmxpa6fo4jdpyq3yneqhglluweax2uclvxkytfpmpkp5rsl75ir5qd.onion
  • +
  • proof: link
  • +
  • check: :eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk::eight_spoked_asterisk:
  • +
+

Toronto Star

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: torontostar.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://yj3b7rgmglcocbbvzrwfbo4d6j2aa7thwupra4yqutbd27v3vxcpvgid.onion
  • +
  • plain: http://yj3b7rgmglcocbbvzrwfbo4d6j2aa7thwupra4yqutbd27v3vxcpvgid.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

Whistleblower Aid

+

via: https://securedrop.org/api/v1/directory/

+
    +
  • short: whistlebloweraid.securedrop.tor.onion
  • +
  • transport: :small_red_triangle: HTTP
  • +
  • link: http://kogbxf4ysay2qzozmg7ar45ijqmj2vxrwqa4upzqq2i7sqj7wv7wcdqd.onion
  • +
  • plain: http://kogbxf4ysay2qzozmg7ar45ijqmj2vxrwqa4upzqq2i7sqj7wv7wcdqd.onion
  • +
  • proof: link
  • +
  • check: :white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark::white_check_mark:
  • +
+

:arrow_up: return to top index

+
+

Flaky Sites

+

These sites have apparently stopped responding.

+

The New York Times: Chinese

+ +

treacherous.tech

+ +

:arrow_up: return to top index

+
+

Footnotes

+
    +
  • At the moment where an organisation runs 2+ onion addresses for +closely related services that do not reflect distinct languages / +national interests, I am posting a link to an index of their +onions. Examples: Riseup, Systemli, TorProject, ...
  • +
  • The master list of Onion SSL EV Certificates may be viewed at +https://crt.sh/?q=\.onion
  • +
+

RWOS Status Detector

+
    +
  • :white_check_mark: site up
  • +
  • :eight_spoked_asterisk: site up, and redirected to another page
  • +
  • :no_entry_sign: site up, but could not access the page
  • +
  • :stop_sign: site up, but reported a system error
  • +
  • :sos: site returned no data, or is down, or curl experienced a transient or permanent network error; may also reflect a problem with the RWOS server connection
  • +
  • :question: same as :sos: but curl specifically mentioned inability to fetch an onion descriptor
  • +
  • :exclamation: same as :sos: but curl specifically mentioned inability to connect to the server
  • +
  • :alarm_clock: same as :sos: but curl specifically mentioned connection timeout as an issue
  • +
  • :timer_clock: same as :sos: but curl specifically mentioned ttl expiry as an issue
  • +
  • :key: same as :sos: but curl specifically mentioned SSL certificates as an issue
  • +
  • :new: site is newly added, no data yet
  • +
+

You can also see the history of updates.

+

Codes & Exit Statuses

+

Mouse-over the icons for details of HTTP codes, curl exit statuses, +and the number of attempts made on each site.

+
    +
  • codes are from HTTP and are documented elsewhere; RWOS-internal ones include:
      +
    • 901 - malformed HTTP response
    • +
    • 902 - malformed HTTP response
    • +
    • 903 - malformed HTTP response, commonly including (e.g.) invalid HTTPS certificate
    • +
    • 904 - HTTP status code parse error
    • +
    • 910 - connection timeout
    • +
    +
  • +
  • exits are from Curl and are documented elsewhere; common ones include:
      +
    • 7 - "curl couldn't connect"
    • +
    • 52 - "curl got nothing", received no data from upstream
    • +
    +
  • +
+

TLS Security

+

Due to the fundamental protocol differences between HTTP and +HTTPS, it is not wise to consider HTTP-over-Onion to be "as secure +as HTTPS"; web browsers do and must treat HTTPS requests in +ways that are fundamentally different to HTTP, e.g.:

+
    +
  • with respect to cookie handling, or
  • +
  • where the trusted connection terminates, or
  • +
  • how to deal with loading embedded insecure content, or
  • +
  • whether to permit access to camera and microphone devices (WebRTC)
  • +
+

...and the necessity of broad adherence to web standards would make it +harmful to attempt to optimise just one browser (e.g. Tor Browser) to +elevate HTTP-over-Onion to the same levels of trust as HTTPS-over-TCP, +let alone HTTPS-over-Onion. Doubtless some browsers will attempt to +implement "better-than-default trust and security via HTTP over +onions", but this behaviour will not be standard, cannot be +relied upon by clients/users, and will therefore be risky.

+

tl;dr - HTTP-over-Onion should not be considered as secure as +HTTPS-over-Onion, and attempting to force it thusly will create a +future compatibility mess for the ecosystem of onion-capable browsers.

+

Feedback

+

The issues page +is the fastest and most effective way to submit a suggestion; if you +lack a Github account, try messaging @alecmuffett on Twitter.

+
+

Back to Top

+ + +
+
+ + diff --git a/rootfs/usr/share/tor/html/exit.html b/rootfs/usr/share/tor/html/exit.html new file mode 100644 index 0000000..ab702b3 --- /dev/null +++ b/rootfs/usr/share/tor/html/exit.html @@ -0,0 +1,337 @@ + + + + + + This is a Tor Exit Router + + + + +

+ This is a Tor Exit Router +

+ +

+ Most likely you are accessing this website because you had some issue with + the traffic coming from this IP. This router is part of the + Tor Anonymity Network, which is + dedicated to + providing privacy + to people who need it most: average computer users. This router IP should + be generating no other traffic, unless it has been compromised. +

+ +

+ + How Tor works + +

+ +

+ Tor sees use by + many important segments of the population, including whistle blowers, journalists, Chinese dissidents skirting the + Great Firewall and oppressive censorship, abuse victims, stalker targets, + the US military, and law enforcement, just to name a few. While Tor is not + designed for malicious computer users, it is true that they can use the + network for malicious ends. In reality however, the actual amount of + abuse is quite + low. This is largely because criminals and hackers have significantly + better access to privacy and anonymity than do the regular users whom they + prey upon. Criminals can and do + build, sell, and trade + far larger and + more powerful networks + than Tor on a daily basis. Thus, in the mind of this operator, the social + need for easily accessible censorship-resistant private, anonymous + communication trumps the risk of unskilled bad actors, who are almost + always more easily uncovered by traditional police work than by extensive + monitoring and surveillance anyway. +

+ +

+ In terms of applicable law, the best way to understand Tor is to consider + it a network of routers operating as common carriers, much like the + Internet backbone. However, unlike the Internet backbone routers, Tor + routers explicitly do not contain identifiable routing information about + the source of a packet, and no single Tor node can determine both the + origin and destination of a given transmission. +

+ +

+ As such, there is little the operator of this router can do to help you + track the connection further. This router maintains no logs of any of the + Tor traffic, so there is little that can be done to trace either + legitimate or illegitimate traffic (or to filter one from the other). + Attempts to seize this router will accomplish nothing. +

+ + + +

+ Furthermore, this machine also serves as a carrier of email, which means + that its contents are further protected under the ECPA. + 18 USC 2707 + explicitly allows for civil remedies ($1000/account + plus legal fees) in the event of a seizure executed without + good faith or probable cause (it should be clear at this point that + traffic with an originating IP address of FIXME_DNS_NAME should not + constitute probable cause to seize the machine). Similar considerations + exist for 1st amendment content on this machine. +

+ + + +

+ If you are a representative of a company who feels that this router is + being used to violate the DMCA, please be aware that this machine does not + host or contain any illegal content. Also be aware that network + infrastructure maintainers are not liable for the type of content that + passes over their equipment, in accordance with + DMCA "safe harbor" provisions. In other words, you will have just as much luck sending a takedown + notice to the Internet backbone providers. Please consult + EFF's prepared response + for more information on this matter. +

+ +

For more information, please consult the following documentation:

+ +
    +
  1. + Tor Overview +
  2. +
  3. + Tor Abuse FAQ +
  4. +
  5. + Tor Legal FAQ +
  6. +
+ +

+ That being said, if you still have a complaint about the router, you may + email the maintainer. If + complaints are related to a particular service that is being abused, I + will consider removing that service from my exit policy, which would + prevent my router from allowing that traffic to exit through it. I can + only do this on an IP+destination port basis, however. Common P2P ports + are already blocked. +

+ +

+ You also have the option of blocking this IP address and others on the Tor + network if you so desire. The Tor project provides a + web service + to fetch a list of all IP addresses of Tor exit nodes that allow exiting + to a specified IP:port combination, and an official + DNSRBL is also + available to determine if a given IP address is actually a Tor exit + server. Please be considerate when using these options. It would be + unfortunate to deny all Tor users access to your site indefinitely simply + because of a few bad apples. +

+ +