Browse Source

onion-service -> onion-service-status-mail

Fabian Peter Hammerle 4 years ago
parent
commit
79e7e72dbf
8 changed files with 158 additions and 128 deletions
  1. 0 29
      CHANGELOG.md
  2. 27 27
      Dockerfile
  3. 17 33
      README.md
  4. 34 8
      ansible-playbook.yml
  5. 22 9
      docker-compose.yml
  6. 0 10
      entrypoint.sh
  7. 58 0
      monitor.sh
  8. 0 12
      torrc.template

+ 0 - 29
CHANGELOG.md

@@ -5,32 +5,3 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
-
-## [1.0.0] - 2019-12-29
-### Changed
-- tor v0.3.3.7 -> v0.3.5.8
-
-### Added
-- healthcheck via `nc`
-- enable hardware acceleration if available
-- sample ansible playbook
-- sample `docker-compose.yml`
-
-### Fixes
-- split `COPY --chown` into `COPY` & `RUN chmod`
-  to improve backward compatibility
-
-## [0.2] - 2019-01-03
-### Changed
-- create v3 service (previously v2)
-
-### Added
-- option to create v2 service by setting `$VERSION`
-  (`docker run -e VERSION=2 …`)
-
-## [0.1] - 2018-12-27
-
-[Unreleased]: https://github.com/fphammerle/docker-onion-service/compare/v1.0.0...HEAD
-[1.0.0]: https://github.com/fphammerle/docker-onion-service/compare/0.2-tor0.3.3.7-amd64...v1.0.0
-[0.2]: https://github.com/fphammerle/docker-onion-service/compare/0.1-tor0.3.3.7-amd64...0.2-tor0.3.3.7-amd64
-[0.1]: https://github.com/fphammerle/docker-onion-service/tree/0.1-tor0.3.3.7-amd64

+ 27 - 27
Dockerfile

@@ -1,30 +1,30 @@
-FROM alpine:3.10
+FROM alpine:3.11
 
-ARG TOR_PACKAGE_VERSION=0.3.5.8-r0
+ARG DUMB_INIT_PACKAGE_VERSION=1.2.2-r1
 ARG NETCAT_PACKAGE_VERSION=1.130-r1
+ARG DMA_REPOSITORY=http://dl-cdn.alpinelinux.org/alpine/edge/testing
+ARG DMA_PACKAGE_VERSION=0.12-r0
 RUN apk add --no-cache \
-    netcat-openbsd=${NETCAT_PACKAGE_VERSION} \
-    tor=${TOR_PACKAGE_VERSION}
-
-RUN adduser -S onion
-RUN mkdir -m u=rwx,g=,o= /onion-service && chown onion /onion-service
-VOLUME /onion-service
-
-COPY torrc.template /
-RUN chmod a+r /torrc.template
-
-ENV VERSION 3
-ENV VIRTUAL_PORT 80
-ENV TARGET 1.2.3.4:8080
-
-COPY entrypoint.sh /
-RUN chmod a+rx /entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
-
-USER onion
-
-CMD ["tor", "-f", "/tmp/torrc"]
-
-HEALTHCHECK CMD \
-    nc -x localhost:9050 -z "$(cat /onion-service/hostname)" "$VIRTUAL_PORT" \
-    || exit 1
+        dumb-init=${DUMB_INIT_PACKAGE_VERSION} \
+        netcat-openbsd=${NETCAT_PACKAGE_VERSION} \
+    && apk add --repository=${DMA_REPOSITORY} --no-cache \
+        dma=${DMA_PACKAGE_VERSION} \
+    && adduser -S -G mail report
+
+VOLUME /var/spool/dma
+
+ENV TOR_HOST= \
+    TOR_PORT=9050 \
+    ONION_SERVICE_HOST= \
+    ONION_SERVICE_PORT= \
+    TIMEOUT_SECONDS=4 \
+    SLEEP_DURATION=16s \
+    RECIPIENT_ADDRESS= \
+    VERBOSE=
+
+COPY --chown=report:nobody monitor.sh /
+USER report
+ENTRYPOINT ["dumb-init", "--"]
+CMD ["/monitor.sh"]
+
+HEALTHCHECK CMD nc -z "$TOR_HOST" "$TOR_PORT" || exit 1

+ 17 - 33
README.md

@@ -1,45 +1,29 @@
-# docker: hidden tor .onion service 🐳
+# docker: status report for .onion services 🐳
 
-repo: https://github.com/fphammerle/docker-onion-service
+send email when tor .onion service goes online or offline
 
-docker hub: https://hub.docker.com/r/fphammerle/onion-service
+[//]: # (TODO repo: https://github.com/fphammerle/docker-onion-service-status-mail)
 
-signed tags: https://github.com/fphammerle/docker-onion-service/tags
+[//]: # (TODO docker hub: https://hub.docker.com/r/fphammerle/onion-service-status-mail)
 
-defaults to creating a [v3](https://trac.torproject.org/projects/tor/wiki/doc/NextGenOnions) service
-
-## example 1
-
-```sh
-$ docker run --name onion-service \
-    -e VIRTUAL_PORT=80 -e TARGET=1.2.3.4:8080 \
-    fphammerle/onion-service
-```
-
-## example 2
-
-```sh
-$ docker create --name onion-service \
-    --env VERSION=3 \
-    --env VIRTUAL_PORT=80 \
-    --env TARGET=1.2.3.4:8080 \
-    --volume onion-key:/onion-service \
-    --restart unless-stopped \
-    --cap-drop all --security-opt no-new-privileges \
-    fphammerle/onion-service:latest
-
-$ docker start onion-service
-```
-
-## retrieve hostname
+[//]: # (TODO signed tags: https://github.com/fphammerle/docker-onion-service-status-mail/tags)
 
 ```sh
-$ docker exec onion-service cat /onion-service/hostname
-abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrst.onion
+$ sudo docker network create tor
+$ sudo docker run -d --network tor \
+    --name tor_proxy \
+    fphammerle/tor-proxy
+$ sudo docker run -d --network tor \
+    -e TOR_HOST=tor_proxy -e TOR_PORT=9050 \
+    -e ONION_SERVICE_HOST=change-me.onion \
+    -e ONION_SERVICE_PORT=80 \
+    -e RECIPIENT_ADDRESS=me@example.com \
+    --name onion_service_monitor  \
+    fphammerle/onion-service-status-mail
 ```
 
 ## docker-compose 🐙
 
-1. `git clone https://github.com/fphammerle/docker-onion-service`
+1. `git clone https://github.com/fphammerle/docker-onion-service-status-mail`
 2. edit `docker-compose.yml`
 3. `docker-compose up --build`

+ 34 - 8
ansible-playbook.yml

@@ -1,15 +1,41 @@
 - hosts: [some-host]
   become: true
   tasks:
+  - docker_network:
+      name: tor
+  - docker_container:
+      name: tor_proxy
+      # 1.0.0-tor0.4.1.6-amd64
+      image: fphammerle/tor-proxy@sha256:ad55d07b1b21c35fa044dc3e1ea6c7d8494f39eb89491ddad35c245340f7cd4b
+      networks:
+      - name: tor
+      purge_networks: yes
+      restart_policy: unless-stopped
+      memory: 128M
+      cpu_quota: 5000
+      cpu_period: 10000
+      security_opts: [no-new-privileges]
   - docker_volume:
-      name: onion_service_key
+      name: onion_service_monitor_mail_queue
   - docker_container:
-      name: onion_service
-      # 0.2-tor0.3.3.7-amd64
-      image: fphammerle/onion-service@sha256:51b5ee67fea1587421fd3dd982cc58f7554b68fe051d316d6d120e560675d2b8
+      name: onion_service_monitor
+      # TODO add image hash
+      image: fphammerle/onion-service-status-mail
       env:
-        VIRTUAL_PORT: 80
-        TARGET: 1.2.3.4:8080
-      volumes: ['onion_service_key:/onion-service']
-      memory: 128M
+        TOR_HOST: tor_proxy
+        TOR_PORT: 9050
+        ONION_SERVICE_HOST: change-me.onion
+        ONION_SERVICE_PORT: 80
+        # TIMEOUT_SECONDS: 8
+        # SLEEP_DURATION: 1m
+        RECIPIENT_ADDRESS: change.me@domain.tld
+      volumes:
+      - onion_service_monitor_mail_queue:/var/spool/dma:rw
+      networks:
+      - name: tor
+      purge_networks: yes
       restart_policy: unless-stopped
+      memory: 64M
+      cpu_quota: 2000
+      cpu_period: 10000
+      security_opts: [no-new-privileges]

+ 22 - 9
docker-compose.yml

@@ -1,20 +1,33 @@
 version: '2.2'
 
 volumes:
-  key:
+  mail_queue:
 
 services:
-  onion:
+  tor_proxy:
+    # 1.0.0-tor0.4.1.6-amd64
+    image: fphammerle/tor-proxy@sha256:ad55d07b1b21c35fa044dc3e1ea6c7d8494f39eb89491ddad35c245340f7cd4b
+    security_opt: ['no-new-privileges']
+    restart: unless-stopped
+    cpus: 0.5
+    mem_limit: 128m
+  monitor:
     build: .
-    image: fphammerle/onion-service
-    volumes:
-    - key:/onion-service:rw
+    image: fphammerle/onion-service-status-mail
     environment:
-      VIRTUAL_PORT: 80
-      TARGET: 1.2.3.4:8080
+      TOR_HOST: tor_proxy
+      TOR_PORT: 9050
+      ONION_SERVICE_HOST: change-me.onion
+      ONION_SERVICE_PORT: 80
+      # TIMEOUT_SECONDS: 8
+      # SLEEP_DURATION: 1m
+      RECIPIENT_ADDRESS: change.me@domain.tld
+      # VERBOSE: 1
+    volumes:
+    - mail_queue:/var/spool/dma:rw
     security_opt: [no-new-privileges]
     restart: unless-stopped
-    cpus: 0.5
-    mem_limit: 128m
+    cpus: 0.2
+    mem_limit: 64m
 
 # https://docs.docker.com/compose/compose-file/

+ 0 - 10
entrypoint.sh

@@ -1,10 +0,0 @@
-#!/bin/sh
-
-set -ex
-
-sed -e "s#{version}#$VERSION#" \
-    -e "s#{virtual_port}#$VIRTUAL_PORT#" \
-    -e "s#{target}#$TARGET#" \
-    /torrc.template >/tmp/torrc
-
-exec "$@"

+ 58 - 0
monitor.sh

@@ -0,0 +1,58 @@
+#!/bin/sh
+
+set -e
+
+if [ -z "$TOR_HOST" ]; then
+    echo 'missing $TOR_HOST'
+    exit 1
+elif [ -z "$ONION_SERVICE_HOST" ]; then
+    echo 'missing $ONION_SERVICE_HOST'
+    exit 1
+elif [ -z "$ONION_SERVICE_PORT" ]; then
+    echo 'missing $ONION_SERVICE_PORT'
+    exit 1
+elif [ -z "$RECIPIENT_ADDRESS" ]; then
+    echo 'missing $RECIPIENT_ADDRESS'
+    exit 1
+fi
+
+sender_address="onion-service-status@$(hostname).local"
+
+ping_onion_service() {(
+    if [ ! -z "$VERBOSE" ]; then
+        set -x
+    fi
+    nc -z -w "$TIMEOUT_SECONDS" -x "$TOR_HOST:$TOR_PORT" "$ONION_SERVICE_HOST" "$ONION_SERVICE_PORT"
+)}
+
+send_report() {(
+    if [ ! -z "$VERBOSE" ]; then
+        set -x
+    fi
+    echo -e "From: ${sender_address}\nSubject: $ONION_SERVICE_HOST:$ONION_SERVICE_PORT $1\n" \
+        | sendmail "$RECIPIENT_ADDRESS"
+)}
+
+last_state=""
+while : ; do
+    if ! nc -z -w "$TIMEOUT_SECONDS" "$TOR_HOST" "$TOR_PORT"; then
+        echo "failed to connect to tor proxy at $TOR_HOST:$TOR_PORT"
+    else
+        if ping_onion_service; then
+            if [ "$last_state" == "offline" ]; then
+                echo went online
+                send_report online
+            fi
+            last_state="online"
+        else
+            if [ "$last_state" == "online" ]; then
+                echo went offline
+                send_report offline
+            fi
+            last_state="offline"
+        fi
+    fi
+    # flush queue
+    dma -q1
+    sleep "$SLEEP_DURATION"
+done

+ 0 - 12
torrc.template

@@ -1,12 +0,0 @@
-Log notice stdout
-
-# healthcheck
-SocksPort 9050
-
-# https://www.torproject.org/docs/tor-onion-service
-HiddenServiceDir /onion-service
-HiddenServiceVersion {version}
-HiddenServicePort {virtual_port} {target}
-
-# try to
-HardwareAccel 1