├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yml ├── scripts └── docker-entrypoint ├── set-ipv6-in-torrc.sh ├── tests ├── docker-compose.yml ├── tor-data │ └── keys │ │ ├── ed25519_master_id_secret_key │ │ └── secret_id_key └── torrc ├── tor-data └── .keep └── torrc /.gitignore: -------------------------------------------------------------------------------- 1 | # OS generated files # 2 | .DS_Store 3 | .DS_Store? 4 | ._* 5 | .Spotlight-V100 6 | .Trashes 7 | Icon? 8 | ehthumbs.db 9 | Thumbs.db 10 | 11 | # Private files 12 | production/ 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dist: bionic 3 | services: docker 4 | 5 | before_install: 6 | # Upgrade Docker. 7 | - sudo apt-get update 8 | - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce 9 | - docker --version 10 | 11 | script: 12 | # Test building Dockerfile. 13 | - docker build -t local-tor-server . 14 | 15 | ## Test running the container with commands from the Readme 16 | 17 | - echo "*** Quickstart - Tor relay server ***" 18 | - mkdir -vp tor-data 19 | - docker run -d --init --name=tor-server_relay_1 --net=host -e TOR_NICKNAME=Tor4 -e CONTACT_EMAIL=tor4@example.org -v $PWD/tests/tor-data:/var/lib/tor --restart=always local-tor-server 20 | - sleep 30 21 | - docker logs tor-server_relay_1 22 | - docker cp tor-server_relay_1:/usr/local/etc/tor/torrc.sample ./ 23 | - cat torrc.sample 24 | - docker stop tor-server_relay_1 25 | - docker rm tor-server_relay_1 26 | 27 | - echo "*** Run Tor with a mounted `torrc` configuration ***" 28 | - mkdir -vp tor-data 29 | - docker run -d --init --name=tor-server_relay_1 --net=host -e TOR_NICKNAME=Tor4 -e CONTACT_EMAIL=tor4@example.org -v $PWD/tests/tor-data:/var/lib/tor -v $PWD/tests/torrc:/etc/tor/torrc --restart=always local-tor-server 30 | - sleep 30 31 | - docker logs tor-server_relay_1 32 | - docker cp tor-server_relay_1:/var/lib/tor/keys/secret_id_key ./ 33 | - docker cp tor-server_relay_1:/var/lib/tor/keys/ed25519_master_id_secret_key ./ 34 | - cat secret_id_key 35 | - docker stop tor-server_relay_1 36 | - docker rm tor-server_relay_1 37 | 38 | - echo "*** Mount customized torrc and the identity keys from a previous Tor relay server installation ***" 39 | - docker run -d --init --name=tor-server_relay_1 --net=host -v $PWD/tests/torrc:/etc/tor/torrc -v $PWD/tests/tor-data/keys/secret_id_key:/var/lib/tor/keys/secret_id_key -v $PWD/tests/tor-data/keys/ed25519_master_id_secret_key:/var/lib/tor/ed25519_master_id_secret_key --restart=always local-tor-server 40 | - sleep 30 41 | - docker logs tor-server_relay_1 42 | - docker stop tor-server_relay_1 43 | - docker rm tor-server_relay_1 44 | 45 | - echo "Run a Tor relay server as obfuscated bridge with docker-compose with locally built image" 46 | - docker-compose --version 47 | - cd tests 48 | - docker-compose up -d 49 | - sleep 80 50 | - docker-compose logs 51 | - docker-compose exec -T relay cat /var/lib/tor/fingerprint 52 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Dockerfile for Tor Relay Server with obfs4proxy (Multi-Stage build) 2 | FROM golang:alpine AS go-build 3 | 4 | # Build /go/bin/obfs4proxy & /go/bin/meek-server 5 | RUN apk --no-cache add --update git \ 6 | && go get -v git.torproject.org/pluggable-transports/obfs4.git/obfs4proxy \ 7 | && go get -v git.torproject.org/pluggable-transports/meek.git/meek-server \ 8 | && cp -rv /go/bin /usr/local/ 9 | 10 | FROM alpine:latest AS tor-build 11 | ARG TOR_GPG_KEY=0x6AFEE6D49E92B601 12 | 13 | # Install prerequisites 14 | RUN apk --no-cache add --update \ 15 | gnupg \ 16 | build-base \ 17 | libevent \ 18 | libevent-dev \ 19 | libressl \ 20 | libressl-dev \ 21 | xz-libs \ 22 | xz-dev \ 23 | zlib \ 24 | zlib-dev \ 25 | zstd \ 26 | zstd-libs \ 27 | zstd-dev \ 28 | # Install Tor from source, incl. GeoIP files (get latest release version number from Tor ReleaseNotes) 29 | && TOR_VERSION=$(wget -q https://gitweb.torproject.org/tor.git/plain/ReleaseNotes -O - | grep -E -m1 '^Changes in version\s[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\s' | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\.[0-9][\s]*\).*$/\1/') \ 30 | && TOR_TARBALL_NAME="tor-${TOR_VERSION}.tar.gz" \ 31 | && TOR_TARBALL_LINK="https://dist.torproject.org/${TOR_TARBALL_NAME}" \ 32 | && wget -q $TOR_TARBALL_LINK \ 33 | && wget $TOR_TARBALL_LINK.asc \ 34 | # Reliably fetch the TOR_GPG_KEY 35 | && found=''; \ 36 | for server in \ 37 | ha.pool.sks-keyservers.net \ 38 | hkp://keyserver.ubuntu.com:80 \ 39 | hkp://p80.pool.sks-keyservers.net:80 \ 40 | ipv4.pool.sks-keyservers.net \ 41 | keys.gnupg.net \ 42 | pgp.mit.edu \ 43 | ; do \ 44 | echo "Fetching GPG key $TOR_GPG_KEY from $server"; \ 45 | gpg --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$TOR_GPG_KEY" && found=yes && break; \ 46 | done; \ 47 | test -z "$found" && echo >&2 "error: failed to fetch GPG key $TOR_GPG_KEY" && exit 1; \ 48 | gpg --verify $TOR_TARBALL_NAME.asc \ 49 | && tar xf $TOR_TARBALL_NAME \ 50 | && cd tor-$TOR_VERSION \ 51 | && ./configure \ 52 | && make install \ 53 | && ls -R /usr/local/ 54 | # Main files created (plus docs): 55 | # /usr/local/bin/tor 56 | # /usr/local/bin/tor-gencert 57 | # /usr/local/bin/tor-resolve 58 | # /usr/local/bin/torify 59 | # /usr/local/share/tor/geoip 60 | # /usr/local/share/tor/geoip6 61 | # /usr/local/etc/tor/torrc.sample 62 | 63 | FROM alpine:latest 64 | MAINTAINER Christian chriswayg@gmail.com 65 | 66 | # If no Nickname is set, a random string will be added to 'Tor4' 67 | ENV TOR_USER=tord \ 68 | TOR_NICKNAME=Tor4 69 | 70 | # Installing dependencies of Tor and pwgen 71 | RUN apk --no-cache add --update \ 72 | libevent \ 73 | libressl \ 74 | xz-libs \ 75 | zstd-libs \ 76 | zlib \ 77 | zstd \ 78 | pwgen 79 | 80 | # Copy obfs4proxy & meek-server 81 | COPY --from=go-build /usr/local/bin/ /usr/local/bin/ 82 | 83 | # Copy Tor 84 | COPY --from=tor-build /usr/local/ /usr/local/ 85 | 86 | # Create an unprivileged tor user 87 | RUN addgroup -g 19001 -S $TOR_USER && adduser -u 19001 -G $TOR_USER -S $TOR_USER 88 | 89 | # Copy Tor configuration file 90 | COPY ./torrc /etc/tor/torrc 91 | 92 | # Copy docker-entrypoint 93 | COPY ./scripts/ /usr/local/bin/ 94 | 95 | # Persist data 96 | VOLUME /etc/tor /var/lib/tor 97 | 98 | # ORPort, DirPort, SocksPort, ObfsproxyPort, MeekPort 99 | EXPOSE 9001 9030 9050 54444 7002 100 | 101 | ENTRYPOINT ["docker-entrypoint"] 102 | CMD ["tor", "-f", "/etc/tor/torrc"] 103 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 Christian Wagner https://github.com/chriswayg/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Tor Relay Server on Docker (Alpine) 2 | [![Build Status](https://travis-ci.org/chriswayg/tor-alpine.svg?branch=master)](https://travis-ci.org/chriswayg/tor-alpine) 3 | [![](https://images.microbadger.com/badges/image/chriswayg/tor-alpine.svg)](https://microbadger.com/images/chriswayg/tor-alpine) 4 | 5 | #### A complete, efficient and secure Tor relay server Docker image 6 | *This docker image, when rebuilt, will update automatically to the latest Alpine base image and install the latest current stable version of Tor server. It will run Tor as an unprivileged regular user, as recommended by torproject.org.* 7 | 8 | It includes the latest Tor Alpine package from torproject.org which is installed and configured according the Tor project recommendations. Additionally it can be run as a hidden bridge using and obfs4proxy as well as meek. 9 | 10 | The Tor network relies on volunteers to donate bandwidth. The more people who run relays, the faster the Tor network will be. If you have at least 2 megabits/s for both upload and download, please help out Tor by configuring your server to be a Tor relay too. 11 | 12 | ![Tor](https://media.torproject.org/image/official-images/2011-tor-logo-flat.svg "Tor logo") 13 | 14 | [Tor](https://www.torproject.org) is free software and an open network that helps you defend against 15 | traffic analysis, a form of network surveillance that threatens personal 16 | freedom and privacy, confidential business activities and relationships, and 17 | state security. 18 | 19 | - Tor prevents people from learning your location or browsing habits. 20 | - Tor is for web browsers, instant messaging clients, and more. 21 | - Tor is free and open source for Windows, Mac, Linux/Unix, and Android 22 | 23 | ### Quickstart - Tor relay server in minutes 24 | 25 | - Prerequisites: A [Linux server hosted at a Tor friendly ISP](https://trac.torproject.org/projects/tor/wiki/doc/GoodBadISPs) with Docker installed (see [Install Docker and Docker Compose](#install-docker-and-docker-compose) below) 26 | 27 | Create a directory for your Tor server data. Then set your own Nickname (only letters and numbers) and an optional contact Email (which will be published on the Tor network) using environment variables: 28 | ``` 29 | mkdir -vp tor-data && \ 30 | docker run -d --init --name=tor-server_relay_1 --net=host \ 31 | -e TOR_NICKNAME=Tor4 \ 32 | -e CONTACT_EMAIL=tor4@example.org \ 33 | -v $PWD/tor-data:/var/lib/tor \ 34 | --restart=always chriswayg/tor-alpine 35 | ``` 36 | 37 | This command will run a Tor relay server with a safe default configuration (not as an exit node). The server will autostart after restarting the host system. If you do not change the default Nickname 'Tor4', the startup script will add a randomized, pronouncable suffix to create a unique name. All Tor data will be preserved in the mounted Data Directory, even if you upgrade or remove the container. 38 | 39 | Check with ```docker logs -f tor-server_relay_1``` If you see the message: ```[notice] Self-testing indicates your ORPort is reachable from the outside. Excellent. Publishing server descriptor.``` at the bottom after a while, your server started successfully. Then wait a bit longer and search for your server here: [Relay Search](https://metrics.torproject.org/rs.html) 40 | 41 | ### Customize Tor configuration 42 | You may want to configure additional options to control your monthly data usage, or to run Tor as a hidden obfuscated bridge. Look at the Tor manual with all [Configuration File Options](https://www.torproject.org/docs/tor-manual.html.en). Also refer to a recent fully commented `torrc.sample`: 43 | 44 | `docker cp tor-server_relay_1:/usr/local/etc/tor/torrc.sample ./` 45 | 46 | For customisation copy `torrc` to the host and configure the desired settings. 47 | ``` 48 | ##=================== /etc/torrc =====================## 49 | # Run Tor as a regular user (do not change this) 50 | User tord 51 | DataDirectory /var/lib/tor 52 | 53 | # Port to advertise for incoming Tor connections. 54 | ORPort 9001 # common ports are 9001, 443 55 | #ORPort [IPv6-address]:9001 56 | 57 | # Mirror directory information for others 58 | DirPort 9030 59 | 60 | # Run as a relay only (change policy to enable exit node) 61 | ExitPolicy reject *:* # no exits allowed 62 | ExitPolicy reject6 *:* 63 | 64 | # Run Tor only as a server (no local applications) 65 | SocksPort 0 66 | ControlSocket 0 67 | 68 | #Nickname Tor4example # only use letters and numbers 69 | #ContactInfo tor4@example.org 70 | ``` 71 | 72 | #### Run Tor with a mounted `torrc` configuration 73 | 74 | Mount your customized `torrc` from the current directory of the host into the container with this command: 75 | ``` 76 | nano torrc 77 | 78 | mkdir -vp tor-data && \ 79 | docker run -d --init --name=tor-server_relay_1 --net=host \ 80 | -e TOR_NICKNAME=Tor4 \ 81 | -e CONTACT_EMAIL=tor4@example.org \ 82 | -v $PWD/tor-data:/var/lib/tor \ 83 | -v $PWD/torrc:/etc/tor/torrc \ 84 | --restart=always chriswayg/tor-alpine 85 | ``` 86 | 87 | ### Move or upgrade the Tor relay 88 | 89 | When upgrading your Tor relay, or moving it on a different computer, the important part is to keep the same identity keys. Keeping backups of the identity keys so you can restore a relay in the future is the recommended way to ensure the reputation of the relay won't be wasted. 90 | 91 | ``` 92 | mkdir -vp tor-data/keys/ && \ 93 | docker cp tor-server_relay_1:/var/lib/tor/keys/secret_id_key ./tor-data/keys/ && \ 94 | docker cp tor-server_relay_1:/var/lib/tor/keys/ed25519_master_id_secret_key ./tor-data/keys/ 95 | ``` 96 | You can also reuse these identity keys from a previous Tor relay server installation, to continue with the same Fingerprint and ID, by inserting the following lines, in the previous command: 97 | ``` 98 | -v $PWD/tor-data/keys/secret_id_key:/var/lib/tor/keys/secret_id_key \ 99 | -v $PWD/tor-data/keys/ed25519_master_id_secret_key:/var/lib/tor/ed25519_master_id_secret_key \ 100 | ``` 101 | 102 | ### Run Tor using docker-compose (recommended) 103 | 104 | Adapt the example `docker-compose.yml` with your settings or clone it from [Github](https://github.com/chriswayg/tor-alpine). 105 | ``` 106 | version: '2.2' 107 | services: 108 | relay: 109 | image: chriswayg/tor-alpine 110 | init: true 111 | restart: always 112 | network_mode: host 113 | environment: 114 | TOR_NICKNAME: Tor4 115 | CONTACT_EMAIL: tor4@example.org 116 | volumes: 117 | - ./tor-data/:/var/lib/tor/ 118 | - ./torrc:/etc/tor/torrc 119 | 120 | ``` 121 | 122 | ##### Configure and run the Tor relay server 123 | 124 | - Configure the `docker-compose.yml` and optionally the `torrc` file, with your individual settings. Possibly install `git` first. 125 | ``` 126 | cd /opt && git clone https://github.com/chriswayg/tor-alpine.git && cd tor-alpine 127 | nano docker-compose.yml 128 | ``` 129 | 130 | - Start a new instance of the Tor relay server and display the logs. 131 | ``` 132 | docker-compose up -d 133 | docker-compose logs -f 134 | ``` 135 | 136 | - As examples for running commands in the container, show the current fingerprint or enter a bash shell. 137 | ``` 138 | docker-compose exec -T relay cat /var/lib/tor/fingerprint 139 | docker-compose exec relay bash 140 | ``` 141 | 142 | - Enter a container which is restarting with an error to inspect it 143 | ``` 144 | docker run -it --entrypoint=/bin/sh chriswayg/tor-alpine --login 145 | ``` 146 | 147 | ### Run Tor relay with IPv6 148 | 149 | If your host supports IPv6, please enable it! The host system or VPS (for example Vultr) needs to have IPv6 activated. From your host server try to ping any IPv6 host: `ping6 -c 5 ipv6.google.com` Then find out your external IPv6 address with this command: 150 | 151 | `dig +short -6 myip.opendns.com aaaa @resolver1.ipv6-sandbox.opendns.com` 152 | 153 | If that works fine, activate IPv6 for Docker by adding the following to the file `daemon.json` on the docker host and restarting Docker. 154 | 155 | - use the IPv6 subnet/64 address from your provider for `fixed-cidr-v6` 156 | 157 | ``` 158 | nano /etc/docker/daemon.json 159 | 160 | { 161 | "ipv6": true, 162 | "fixed-cidr-v6": "21ch:ange:this:addr::/64" 163 | } 164 | 165 | systemctl restart docker && systemctl status docker 166 | ``` 167 | 168 | My sample Tor relay server configurations use `network_mode: host` which makes it easier to use IPv6. - Next make your Tor relay reachable via IPv6 by adding the applicable IPv6 address at the ORPort line in your `torrc` configuration: 169 | 170 | `ORPort [IPv6-address]:9001` 171 | 172 | Or use the included helper script to add the main IPv6 address of your host to your `torrc`, for example: 173 | 174 | `bash scripts/set-ipv6-in-torrc.sh torrc` 175 | 176 | - Restart the container and test, that the Tor relay can reach the outside world: 177 | ``` 178 | docker-compose restart 179 | docker-compose logs 180 | docker-compose exec -T relay ping6 -c 5 ipv6.google.com 181 | ``` 182 | 183 | You should see something like this in the log: `[notice] Opening OR listener on [2200:2400:4400:4a61:5400:4ff:f444:e448]:9001` 184 | 185 | - IPv6 info for Tor and Docker: 186 | 1. [A Tor relay operators IPv6 HOWTO](https://trac.torproject.org/projects/tor/wiki/doc/IPv6RelayHowto) 187 | 2. [Walkthrough: Enabling IPv6 Functionality for Docker & Docker Compose](http://collabnix.com/enabling-ipv6-functionality-for-docker-and-docker-compose/) 188 | 3. [Basic Configuration of Docker Engine with IPv6](http://www.debug-all.com/?p=128) 189 | 4. [Docker, IPv6 and –net=”host”](http://www.debug-all.com/?p=163) 190 | 5. [Docker Networking 101 – Host mode](http://www.dasblinkenlichten.com/docker-networking-101-host-mode/) 191 | 5. When using the host network driver for a container, that container’s network stack is not isolated from the Docker host. If you run a container which binds to port 9001 and you use host networking, the container’s application will be available on port 9001 on the host’s IP address. 192 | 193 | --- 194 | 195 | ### Install Docker and Docker Compose 196 | 197 | Links how to install 198 | 199 | - [Docker](https://docs.docker.com/install/) 200 | - [Docker Compose](https://docs.docker.com/compose/install/) 201 | 202 | After the installation process is finished, you may need to enable the service and make sure it is started (e.g. CentOS). 203 | 204 | ``` 205 | systemctl enable docker 206 | systemctl start docker 207 | ``` 208 | 209 | Please use the latest Docker engine available and do not use the engine that ships with your distro's repository. 210 | 211 | ### Guides 212 | 213 | - [Tor Relay Guide](https://trac.torproject.org/projects/tor/wiki/TorRelayGuide) 214 | - [Tor on Debian Installation Instructions](https://www.torproject.org/docs/debian.html.en) 215 | - [Torproject - git repo](https://github.com/torproject/tor) 216 | - [obfs4proxy on Debian - Guide to run an obfuscated bridge to help censored users connect to the Tor network.](https://trac.torproject.org/projects/tor/wiki/doc/PluggableTransports/obfs4proxy) 217 | - [obfs4 - The obfourscator - Github](https://github.com/Yawning/obfs4) 218 | - [How to use the “meek” pluggable transport](https://blog.torproject.org/how-use-meek-pluggable-transport) 219 | - [meek-server for Tor meek bridge](https://github.com/arlolra/meek/tree/master/meek-server) 220 | - Originally based on: https://github.com/vimagick/dockerfiles/tree/master/tor 221 | 222 | ### License: 223 | - MIT 224 | 225 | ##### For a very similar image based on tor-alpine use `chriswayg/tor-server` 226 | - https://hub.docker.com/r/chriswayg/tor-server 227 | - https://github.com/chriswayg/tor-server 228 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.2' 2 | services: 3 | relay: 4 | image: chriswayg/tor-alpine 5 | init: true 6 | restart: always 7 | network_mode: host 8 | ## the ports are not needed with network_mode host 9 | #ports: 10 | #- "9001:9001" 11 | #- "9030:9030" 12 | #- "54444:54444" 13 | #- "7002:7002" 14 | volumes: 15 | ## mount and DataDirectory and custom `torrc` here 16 | - ./tor-data/:/var/lib/tor/ 17 | - ./torrc:/etc/tor/torrc 18 | ## alternatively mount previously saved identity keys here 19 | #- ./tests/tor-data/keys/secret_id_key:/var/lib/tor/keys/secret_id_key 20 | #- ./tests/tor-data/keys/ed25519_master_id_secret_key:/var/lib/tor/keys/secret_id_key 21 | -------------------------------------------------------------------------------- /scripts/docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -o errexit 3 | 4 | chmodf() { find $2 -type f -exec chmod -v $1 {} \; 5 | } 6 | chmodd() { find $2 -type d -exec chmod -v $1 {} \; 7 | } 8 | 9 | echo -e "\n========================================================" 10 | # If DataDirectory, identity keys or torrc is mounted here, 11 | # ownership needs to be changed to the TOR_USER user 12 | chown -Rv ${TOR_USER}:${TOR_USER} /var/lib/tor 13 | # fix permissions 14 | chmodd 700 /var/lib/tor 15 | chmodf 600 /var/lib/tor 16 | 17 | if [ ! -e /tor-config-done ]; then 18 | touch /tor-config-done # only run this once 19 | 20 | # Add Nickname from env variable or randomized, if none has been set 21 | if ! grep -q '^Nickname ' /etc/tor/torrc; then 22 | if [ ${TOR_NICKNAME} == "Tor4" ] || [ -z "${TOR_NICKNAME}" ]; then 23 | # if user did not change the default Nickname, genetrate a random pronounceable one 24 | RPW=$(pwgen -0A 8) 25 | TOR_NICKNAME="Tor4${RPW}" 26 | echo "Setting random Nickname: ${TOR_NICKNAME}" 27 | else 28 | echo "Setting chosen Nickname: ${TOR_NICKNAME}" 29 | fi 30 | echo -e "\nNickname ${TOR_NICKNAME}" >> /etc/tor/torrc 31 | fi 32 | 33 | # Add Contact_Email from env variable, if none has been set in torrc 34 | if ! grep -q '^ContactInfo ' /etc/tor/torrc; then 35 | # if CONTACT_EMAIL is not null 36 | if [ -n "${CONTACT_EMAIL}" ]; then 37 | echo "Setting Contact Email: ${CONTACT_EMAIL}" 38 | echo -e "\nContactInfo ${CONTACT_EMAIL}" >> /etc/tor/torrc 39 | fi 40 | fi 41 | fi 42 | 43 | echo -e "\n========================================================" 44 | # Display OS version, Tor version & torrc in log 45 | echo -e "Alpine Version: \c" && cat /etc/alpine-release 46 | tor --version 47 | obfs4proxy -version 48 | cat /etc/tor/torrc 49 | echo -e "========================================================\n" 50 | 51 | # else default to run whatever the user wanted like "bash" 52 | exec "$@" 53 | -------------------------------------------------------------------------------- /set-ipv6-in-torrc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -o errexit 3 | # usage: ./set-ipv6-in-torrc.sh ./torrc 4 | 5 | if [ $# -eq 1 ]; then 6 | # Check if the input file actually exists. 7 | if ! [[ -f "$1" ]]; then 8 | echo "The file $1 does not exist!" 9 | exit 1 10 | fi 11 | else 12 | echo "Usage: $0 [/host-path/to/torrc]" 13 | exit 1 14 | fi 15 | 16 | # Try to automatically set external ipv6, if none has been set in torrc 17 | if ! grep -q '^ORPort \[' ${1}; then 18 | IPV6=$(dig +short -6 myip.opendns.com aaaa @resolver1.ipv6-sandbox.opendns.com) 19 | echo "Setting IPv6 on ORPort 9001: ${IPV6}" 20 | echo -e "\nORPort [${IPV6}]:9001" >> ${1} 21 | else 22 | echo "IPv6 has been set already!" 23 | fi 24 | -------------------------------------------------------------------------------- /tests/docker-compose.yml: -------------------------------------------------------------------------------- 1 | ## This configuration is used for testing within Travis 2 | version: '2.2' 3 | services: 4 | relay: 5 | image: local-tor-server 6 | init: true 7 | restart: always 8 | network_mode: host 9 | ## the ports are not needed with network_mode host 10 | #ports: 11 | #- "9001:9001" 12 | #- "9030:9030" 13 | #- "54444:54444" 14 | #- "7002:7002" 15 | volumes: 16 | ## mount and DataDirectory and custom `torrc` here 17 | - ./tor-data/:/var/lib/tor/ 18 | - ./torrc:/etc/tor/torrc 19 | ## alternatively mount previously saved identity keys here 20 | #- ./tests/tor-data/keys/secret_id_key:/var/lib/tor/keys/secret_id_key 21 | #- ./tests/tor-data/keys/ed25519_master_id_secret_key:/var/lib/tor/keys/secret_id_key 22 | -------------------------------------------------------------------------------- /tests/tor-data/keys/ed25519_master_id_secret_key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chriswayg/tor-alpine/d3adec5b372880cd9dd879471d727b31e3008d9e/tests/tor-data/keys/ed25519_master_id_secret_key -------------------------------------------------------------------------------- /tests/tor-data/keys/secret_id_key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQCilPfwLCfzfFQ7wAcyISrmajqGKj/9J7Pk+Ci8NHqSxdNcAPIn 3 | kQn2cVs3msf0hXb1qG0zeLPo5NLcsKOBfkTQDwRDKRP9FVlFkrf+E2/kkiZsgcrR 4 | WVjQq6YxuVcUmar22UTS04WndeHykO4npy+0sAsz/Ctc1g1jXMi0a6TG9QIDAQAB 5 | AoGAK0/KOWZaAkiF3CENCbLCTf3Qt3s77sIL75yYpYLJgJ5I70KlQBsob0nFhiuq 6 | xx5jEZCb/tFSBGIpNnesJ0wvIl1p2Uea2mm19f+pz7c/IrUOXkjVvM8ykTSJ0MdS 7 | Kr5AP2ZEuxIy9fmZy8Pc5roHxRMM6aD3hc98BnrXDR7ybkECQQDYesMI9lt6C0b+ 8 | whygo2M9/1QRZ0raH3ePltrcUcgloicefCIGlw0A/QuJqm2ajYdfwJMinrgSzRx9 9 | /7F0jWgFAkEAwENIxCmgEs1RHv9CZhpZ8Pi57vk1sMd4S81WOxlMRWvOVD6EVDJy 10 | NpwB+Buk802oiyJPWuOKE3lu9e4fv6DGMQJANmZbHqRyBnBRDfIPqZqFdO313U28 11 | tKWVsQKyywzOJA7kj7eYAVnyDZ6JSLYIRv9r1ncZQmjqTuc2Ur9vg5+JVQJAFGFN 12 | flW3PSb8eV+vhyk17YBAHV/XXCTY0Jg0ktEsr5Ms7Osvlck/KCDDaKxtgMjzm8QI 13 | S2chRM0zgOg7/1EokQJBAMZUEATBS+L+uUOfxBkdGTn+/vO0Cb6QrowaQnDGQVaS 14 | Leg+E9EZ/pF4meV5YEsd0vZTIZq6TNcMTuGZSXJf+9Y= 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /tests/torrc: -------------------------------------------------------------------------------- 1 | ##=================== /etc/torrc =====================## 2 | # see /usr/local/etc/tor/torrc.sample and https://www.torproject.org/docs/tor-manual.html.en 3 | 4 | # Run Tor as a regular user (do not change this) 5 | User tord 6 | DataDirectory /var/lib/tor 7 | 8 | # Server's public IP Address (usually automatic) 9 | #Address 10.10.10.10 10 | 11 | # Port to advertise for incoming Tor connections. 12 | ORPort 9001 # common ports are 9001, 443 13 | #ORPort [IPv6-address]:9001 14 | 15 | # Mirror directory information for others (optional, not used on bridge) 16 | #DirPort 9030 # common ports are 9030, 80 17 | 18 | # Run Tor only as a server (no local applications) 19 | SocksPort 0 20 | ControlSocket 0 21 | 22 | # Run as a relay only (change policy to enable exit node) 23 | ExitPolicy reject *:* # no exits allowed 24 | ExitPolicy reject6 *:* 25 | ExitRelay 1 26 | IPv6Exit 1 27 | 28 | # Set limits 29 | #AccountingMax 999 GB 30 | RelayBandwidthRate 512 KB # Throttle traffic to 31 | RelayBandwidthBurst 1024 KB # But allow bursts up to 32 | MaxMemInQueues 512 MB # Limit Memory usage to 33 | 34 | ## Run Tor as obfuscated bridge 35 | # https://trac.torproject.org/projects/tor/wiki/doc/PluggableTransports/obfs4proxy 36 | ServerTransportPlugin obfs4 exec /usr/local/bin/obfs4proxy 37 | ServerTransportListenAddr obfs4 0.0.0.0:54444 38 | ExtORPort auto 39 | BridgeRelay 1 40 | 41 | ## If no Nickname or ContactInfo is set, docker-entrypoint will use 42 | ## the environment variables to add Nickname/ContactInfo below 43 | Nickname Tor4example # only use letters and numbers 44 | ContactInfo tor4@example.org 45 | -------------------------------------------------------------------------------- /tor-data/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chriswayg/tor-alpine/d3adec5b372880cd9dd879471d727b31e3008d9e/tor-data/.keep -------------------------------------------------------------------------------- /torrc: -------------------------------------------------------------------------------- 1 | ##=================== /etc/torrc =====================## 2 | # https://www.torproject.org/docs/tor-manual.html.en 3 | 4 | # Run Tor as a regular user (do not change this) 5 | User tord 6 | DataDirectory /var/lib/tor 7 | 8 | # Server's public IP Address (usually automatic) 9 | #Address 10.10.10.10 10 | 11 | # Port to advertise for incoming Tor connections. 12 | ORPort 9001 # common ports are 9001, 443 13 | #ORPort [IPv6-address]:9001 14 | 15 | # Mirror directory information for others (optional, not used on bridge) 16 | DirPort 9030 # common ports are 9030, 80 17 | 18 | # Run Tor only as a server (no local applications) 19 | SocksPort 0 20 | ControlSocket 0 21 | 22 | # Run as a relay only (change policy to enable exit node) 23 | ExitPolicy reject *:* # no exits allowed 24 | ExitPolicy reject6 *:* 25 | ExitRelay 1 26 | IPv6Exit 1 27 | 28 | # Set limits 29 | #AccountingMax 999 GB 30 | #RelayBandwidthRate 512 KB # Throttle traffic to 31 | #RelayBandwidthBurst 1024 KB # But allow bursts up to 32 | #MaxMemInQueues 512 MB # Limit Memory usage to 33 | 34 | ## Run Tor as obfuscated bridge 35 | # https://trac.torproject.org/projects/tor/wiki/doc/PluggableTransports/obfs4proxy 36 | #ServerTransportPlugin obfs4 exec /usr/local/bin/obfs4proxy 37 | #ServerTransportListenAddr obfs4 0.0.0.0:54444 38 | #ExtORPort auto 39 | #BridgeRelay 1 40 | 41 | ## If no Nickname or ContactInfo is set, docker-entrypoint will use 42 | ## the environment variables to add Nickname/ContactInfo below 43 | #Nickname Tor4example # only use letters and numbers 44 | #ContactInfo tor4@example.org 45 | 46 | ## Use meek-server 47 | #ServerTransportPlugin meek exec /usr/local/bin/meek-server --port 7002 --cert cert.pem --key key.pem 48 | --------------------------------------------------------------------------------