diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml new file mode 100644 index 0000000..34361ee --- /dev/null +++ b/.github/workflows/docker.yaml @@ -0,0 +1,44 @@ +name: Create and publish the Docker image + +on: + push: + branches: + - master + tags: + - '*' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/on-push-branch.yml b/.github/workflows/on-push-branch.yml deleted file mode 100644 index c740cba..0000000 --- a/.github/workflows/on-push-branch.yml +++ /dev/null @@ -1,87 +0,0 @@ -name: Docker build on push -env: - DOCKER_CLI_EXPERIMENTAL: enabled - -on: - push: - branches: - - 'nolim1t-*' - -jobs: - build: - runs-on: ubuntu-22.04 - name: Build on push with branch looking like nolim1t* - steps: - - name: Checkout repo - uses: actions/checkout@v2 - - - name: Set env variables - run: | - echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//-/g')" >> $GITHUB_ENV - echo "SHORTSHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "DOCKER_HUB_REPO=tor" >> $GITHUB_ENV - - - name: Show set env variables - run: | - printf " BRANCH: %s\n" "$BRANCH" - printf " SHORTSHA: %s\n" "$SHORTSHA" - printf " REPO: %s\n" "$GITHUB_REPOSITORY" - printf " COMMIT ID: %s\n" "$GITHUB_SHA" - printf " DOCKER REPO: %s\n" "$DOCKER_HUB_REPO" - printf " GITHUB_ACTOR: %s\n" "$GITHUB_ACTOR" - printf " GITHUB_REPOSITORY: %s\n" "$GITHUB_REPOSITORY" - - - name: Login to Docker Hub - run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - - - name: Setup Docker buildx action - uses: crazy-max/ghaction-docker-buildx@v1 - id: buildx - with: - buildx-version: latest - qemu-version: latest - - - name: Show available Docker buildx platforms - run: echo ${{ steps.buildx.outputs.platforms }} - - - name: Cache Docker layers - uses: actions/cache@v2 - id: cache - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - - name: Build against branch - run: | - docker buildx build \ - --cache-from "type=local,src=/tmp/.buildx-cache" \ - --cache-to "type=local,dest=/tmp/.buildx-cache" \ - --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ - --tag ${{ secrets.DOCKER_HUB_USER }}/$DOCKER_HUB_REPO:$BRANCH-$SHORTSHA \ - --output "type=registry" . - - - name: Build against latest tag - run: | - docker buildx build \ - --cache-from "type=local,src=/tmp/.buildx-cache" \ - --cache-to "type=local,dest=/tmp/.buildx-cache" \ - --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ - --tag ${{ secrets.DOCKER_HUB_USER }}/$DOCKER_HUB_REPO:latest \ - --output "type=registry" . - - - name: Login and push (to branch specific tag - $BRANCH-$SHORTSHA) to GHCR with MAINTAINER_USER and MAINTAINER_TOKEN if exists - run: | - if [[ ! -z ${{ secrets.MAINTAINER_TOKEN }} ]] && [[ ! -z ${{ secrets.MAINTAINER_USER }} ]]; then - echo "${{ secrets.MAINTAINER_TOKEN }}" | docker login https://ghcr.io -u "${{ secrets.MAINTAINER_USER }}" --password-stdin - docker buildx build \ - --cache-from "type=local,src=/tmp/.buildx-cache" \ - --cache-to "type=local,dest=/tmp/.buildx-cache" \ - --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ - --tag ghcr.io/${{ secrets.DOCKER_HUB_USER }}/docker-tor:$BRANCH-$SHORTSHA \ - --output "type=registry" . - else - echo "MAINTAINER_TOKEN and MAINTAINER_USER do no exist! Skipping!" - fi - diff --git a/.github/workflows/on-push-master.yml b/.github/workflows/on-push-master.yml deleted file mode 100644 index 3f509da..0000000 --- a/.github/workflows/on-push-master.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: Docker build on push -env: - DOCKER_CLI_EXPERIMENTAL: enabled - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - -on: - push: - branches: - - master - -jobs: - build: - runs-on: ubuntu-22.04 - name: Build and push all the stuff defined in this repo - steps: - - name: Checkout repo - uses: actions/checkout@v2 - - - name: Set env variables - run: | - echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//-/g')" >> $GITHUB_ENV - echo "SHORTSHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "DOCKER_HUB_REPO=tor" >> $GITHUB_ENV - - - name: Show set env variables - run: | - printf " BRANCH: %s\n" "$BRANCH" - printf " SHORTSHA: %s\n" "$SHORTSHA" - printf " REPO: %s\n" "$GITHUB_REPOSITORY" - printf " COMMIT ID: %s\n" "$GITHUB_SHA" - printf " DOCKER REPO: %s\n" "$DOCKER_HUB_REPO" - printf " GITHUB_ACTOR: %s\n" "$GITHUB_ACTOR" - printf " GITHUB_REPOSITORY: %s\n" "$GITHUB_REPOSITORY" - - - name: Login to Docker Hub - run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - - - name: Setup Docker buildx action - uses: crazy-max/ghaction-docker-buildx@v1 - id: buildx - with: - buildx-version: latest - qemu-version: latest - - - name: Show available Docker buildx platforms - run: echo ${{ steps.buildx.outputs.platforms }} - - - name: Cache Docker layers - uses: actions/cache@v2 - id: cache - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - - name: Build against master - run: | - docker buildx build \ - --cache-from "type=local,src=/tmp/.buildx-cache" \ - --cache-to "type=local,dest=/tmp/.buildx-cache" \ - --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ - --tag ${{ secrets.DOCKER_HUB_USER }}/$DOCKER_HUB_REPO:master-$SHORTSHA \ - --output "type=registry" . - - - name: Build against latest tag - run: | - docker buildx build \ - --cache-from "type=local,src=/tmp/.buildx-cache" \ - --cache-to "type=local,dest=/tmp/.buildx-cache" \ - --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ - --tag ${{ secrets.DOCKER_HUB_USER }}/$DOCKER_HUB_REPO:latest \ - --output "type=registry" . - diff --git a/.github/workflows/on-tag.yml b/.github/workflows/on-tag.yml deleted file mode 100644 index 6898667..0000000 --- a/.github/workflows/on-tag.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Docker build on tag -env: - DOCKER_CLI_EXPERIMENTAL: enabled - ACTIONS_ALLOW_UNSECURE_COMMANDS: true - TAG_FMT: '^refs/tags/(((.?[0-9]+){3,4}))$' - -on: - push: - tags: [ '*' ] - -jobs: - build: - runs-on: ubuntu-22.04 - name: Build TOR - steps: - - name: Setup Environment - run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV - - - name: Show set environment variables - run: | - printf " TAG: %s\n" "$TAG" - - - name: Login to Docker Hub - run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin - - - name: Checkout project - uses: actions/checkout@v2 - - - name: Setup Docker buildx action - uses: crazy-max/ghaction-docker-buildx@v1 - id: buildx - with: - buildx-version: latest - qemu-version: latest - - - name: Show available Docker buildx platforms - run: echo ${{ steps.buildx.outputs.platforms }} - - - name: Cache Docker layers - uses: actions/cache@v2 - id: cache - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - - - name: Run Docker buildx against the tag and push - run: | - docker buildx build \ - --cache-from "type=local,src=/tmp/.buildx-cache" \ - --cache-to "type=local,dest=/tmp/.buildx-cache" \ - --build-arg VERSION=$TAG \ - --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ - --tag ${{ secrets.DOCKER_HUB_USER }}/tor:$TAG \ - --output "type=registry" . - - - name: build and push against latest - run: | - docker buildx build \ - --cache-from "type=local,src=/tmp/.buildx-cache" \ - --cache-to "type=local,dest=/tmp/.buildx-cache" \ - --build-arg VERSION=$TAG \ - --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ - --tag ${{ secrets.DOCKER_HUB_USER }}/tor:latest \ - --output "type=registry" . - diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml deleted file mode 100644 index 1b07aae..0000000 --- a/.github/workflows/update-readme.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Update Docker Hub README everytime it changes on master - -on: - push: - branches: - - master - paths: - - README.md - - '.github/workflows/update-readme.yml' - -jobs: - sync: - name: Update README to Docker Hub - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v2.0.0 - - name: Sync README.md and Description to Docker Hub using meeDamian action (my fork) - uses: nolim1t/sync-readme@v1.0.6 - with: - user: ${{ secrets.DOCKER_USERNAME }} - pass: ${{ secrets.DOCKER_PASSWORD }} - slug: lncm/tor - description: true diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 137a5a7..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,134 +0,0 @@ -variables: - CI_BUILD_IMAGE: "registry.gitlab.com/ericvh/docker-buildx-qemu" - CI_BUILDX_ARCHS: "linux/amd64,linux/arm64,linux/386,linux/arm/v7,linux/arm/v6" - -.build: - image: $CI_BUILD_IMAGE - stage: build - timeout: 5h 30m - services: - - name: docker:dind - entrypoint: ["env", "-u", "DOCKER_HOST"] - command: ["dockerd-entrypoint.sh"] - variables: - DOCKER_HOST: tcp://docker:2375/ - DOCKER_DRIVER: overlay2 - DOCKER_TLS_CERTDIR: "" - before_script: - - | - echo "CI_BUILD_IMAGE is $CI_BUILD_IMAGE" - echo "CI_COMMIT_REF_NAME is $CI_COMMIT_REF_NAME" - echo "CI_REGISTRY_IMAGE is $CI_REGISTRY_IMAGE" - echo "CI_COMMIT_REF_SLUG is $CI_COMMIT_REF_SLUG" - echo "CI_COMMIT_SHA is $CI_COMMIT_SHAE" - echo "CI_REGISTRY is $CI_REGISTRY" - echo "CI_PROJECT_NAMESPACE is $CI_PROJECT_NAMESPACE" - echo "CI_PROJECT_NAME is $CI_PROJECT_NAME" - if [[ -z "$CI_COMMIT_TAG" ]]; then - echo "Commit tag not set" - export CI_APPLICATION_REPOSITORY=${CI_APPLICATION_REPOSITORY:-$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG} - echo "CI_APPLICATION_REPOSITORY is $CI_APPLICATION_REPOSITORY" - export CI_APPLICATION_TAG=${CI_APPLICATION_TAG:-$CI_COMMIT_SHA} - else - echo "CI_COMMIT_TAG is $CI_COMMIT_TAG" - echo "CI_REGISTRY_IMAGE is $CI_REGISTRY_IMAGE" - export CI_APPLICATION_REPOSITORY=${CI_APPLICATION_REPOSITORY:-$CI_REGISTRY_IMAGE} - echo "CI_APPLICATION_REPOSITORY is $CI_APPLICATION_REPOSITORY" - export CI_APPLICATION_TAG=${CI_APPLICATION_TAG:-$CI_COMMIT_TAG} - fi - - | - if [[ -z $DOCKER_USERNAME ]] && [[ -z $DOCKER_PASSWORD ]]; then - echo "Setting gitlab containers (Username $CI_REGISTRY_USER) credentials" - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY - else - echo "Setting docker username ($DOCKER_USERNAME) and password" - echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - fi - -build:buildx-master: - extends: .build - only: - refs: - - master - variables: - - $CI_BUILDX_ARCHS - script: - - update-binfmts --enable - - docker buildx create --driver docker-container --use - - docker buildx inspect --bootstrap - - docker buildx ls - - | - if [[ -z $DOCKER_USERNAME ]] && [[ -z $DOCKER_PASSWORD ]]; then - echo "Build to gitlab only" - docker buildx build --platform $CI_BUILDX_ARCHS --progress plain --pull -t "$CI_REGISTRY_IMAGE" --push . - else - echo "Build to docker hub" - if [[ ! -z $CI_COMMIT_TAG ]]; then - echo "Building to tag ($CI_COMMIT_TAG)" - docker buildx build \ - --platform $CI_BUILDX_ARCHS \ - --tag $DOCKER_USERNAME/buildx-test:$CI_COMMITTAG \ - --output "type=registry" . - else - echo "Building to latest" - docker buildx build \ - --platform $CI_BUILDX_ARCHS \ - --tag $DOCKER_USERNAME/$CI_PROJECT_NAME:latest \ - --output "type=registry" . - fi - fi - -build:buildx-tags-or-branch: - extends: .build - only: - variables: - - $CI_BUILDX_ARCHS - except: - refs: - - master - script: - - update-binfmts --enable - - | - echo "Variables set by CI" - echo "CI_APPLICATION_TAG: $CI_APPLICATION_TAG" - echo "CI_COMMIT_TAG: $CI_COMMIT_TAG" - echo "CI_COMMIT_BRANCH: $CI_COMMIT_BRANCH" - echo "CI_COMMIT_SHORT_SHA: $CI_COMMIT_SHORT_SHA" - - | - echo "Setup buildx" - docker buildx inspect --bootstrap - docker buildx ls - docker buildx create --driver docker-container --use - - if [[ -z $DOCKER_USERNAME ]] && [[ -z $DOCKER_PASSWORD ]]; then - echo "Build to gitlab containers" - if [ ! -z $CI_COMMIT_TAG ]; then - echo "Building $CI_COMMIT_TAG (tag mode)" - echo "Repo to push to $CI_APPLICATION_REPOSITORY:$CI_COMMIT_TAG-$CI_COMMIT_SHORT_SHA" - docker buildx build --platform $CI_BUILDX_ARCHS --progress plain --pull -t "$CI_APPLICATION_REPOSITORY:$CI_COMMIT_TAG-$CI_COMMIT_SHORT_SHA" --push . - else - echo "Not building by tag as CI_COMMIT_TAG is empty" - fi - if [ ! -z $CI_COMMIT_BRANCH ]; then - echo "Building $CI_COMMIT_BRANCH (branch mode)" - echo "Repo to push to $CI_APPLICATION_REPOSITORY:$CI_COMMIT_SHORT_SHA" - docker buildx build --platform $CI_BUILDX_ARCHS --progress plain --pull -t "$CI_APPLICATION_REPOSITORY:$CI_COMMIT_SHORT_SHA" --push . - else - echo "Not building by branch as CI_COMMIT_BRANCH is empty" - fi - else - echo "Build to dockerhub" - if [[ ! -z $CI_COMMIT_TAG ]]; then - echo "Building to tag ($CI_COMMIT_TAG)" - docker buildx build \ - --platform $CI_BUILDX_ARCHS \ - --tag $DOCKER_USERNAME/$CI_PROJECT_NAME:$CI_COMMITTAG \ - --output "type=registry" . - else - echo "Building to latest" - docker buildx build \ - --platform $CI_BUILDX_ARCHS \ - --tag $DOCKER_USERNAME/$CI_PROJECT_NAME:latest \ - --output "type=registry" . - fi - fi diff --git a/Dockerfile b/Dockerfile index 93f9a6b..8327b35 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,20 +1,22 @@ -ARG VERSION=0.4.7.13 +ARG VERSION=0.4.9.5 +ARG TOR_TARBALL_SHA256=c949c2f86b348e64891976f6b1e49c177655b23df97193049bf1b8cd3099e179 ARG USER=toruser ARG UID=1000 ARG DIR=/data -FROM debian:11-slim as preparer-base +FROM debian:13-slim AS preparer-base RUN apt update RUN apt -y install gpg gpg-agent curl # Add tor key -ENV KEYS 514102454D0A87DB0767A1EBBE6A0531C18A9179 B74417EDDF22AC9F9E90F49142E86A2A11F48D36 7A02B3521DC75C542BA015456AFEE6D49E92B601 +# Grabbed from https://gitlab.torproject.org/tpo/core/tor/-/blob/main/README.md#keys-that-can-sign-a-release +ENV KEYS="514102454D0A87DB0767A1EBBE6A0531C18A9179 B74417EDDF22AC9F9E90F49142E86A2A11F48D36 2133BC600AB133E1D826D173FE43009C4607B1FB" #RUN curl -s https://openpgpkey.torproject.org/.well-known/openpgpkey/torproject.org/hu/kounek7zrdx745qydx6p59t9mqjpuhdf |gpg --import - -RUN gpg --keyserver keyserver.ubuntu.com --recv-keys $KEYS +RUN gpg --keyserver keys.openpgp.org --recv-keys $KEYS RUN gpg --list-keys | tail -n +3 | tee /tmp/keys.txt && \ gpg --list-keys $KEYS | diff - /tmp/keys.txt @@ -22,10 +24,13 @@ RUN gpg --list-keys | tail -n +3 | tee /tmp/keys.txt && \ FROM preparer-base AS preparer-release ARG VERSION +ARG TOR_TARBALL_SHA256 ADD https://dist.torproject.org/tor-$VERSION.tar.gz.sha256sum.asc ./ ADD https://dist.torproject.org/tor-$VERSION.tar.gz.sha256sum ./ -ADD https://dist.torproject.org/tor-$VERSION.tar.gz ./ +ADD --checksum="sha256:$TOR_TARBALL_SHA256" \ + https://dist.torproject.org/tor-$VERSION.tar.gz \ + ./ RUN gpg --verify tor-$VERSION.tar.gz.sha256sum.asc RUN sha256sum -c tor-$VERSION.tar.gz.sha256sum @@ -35,7 +40,7 @@ RUN tar -xzf "/tor-$VERSION.tar.gz" && \ FROM preparer-release AS preparer -FROM debian:11-slim as builder +FROM debian:13-slim AS builder ARG VERSION @@ -55,13 +60,14 @@ RUN ls -la /etc/tor RUN ls -la /var/lib RUN ls -la /var/lib/tor -FROM debian:11-slim as final +FROM debian:13-slim AS final ARG VERSION ARG USER +ARG UID ARG DIR -LABEL maintainer="nolim1t (@nolim1t)" +LABEL maintainer="m0wer" # Libraries (linked) COPY --from=builder /usr/lib /usr/lib @@ -69,10 +75,24 @@ COPY --from=builder /usr/lib /usr/lib COPY --from=builder /usr/local/bin/tor* /usr/local/bin/ # NOTE: Default GID == UID == 1000 -RUN adduser --disabled-password \ - --home "$DIR/" \ - --gecos "" \ - "$USER" +RUN groupadd -g $UID $USER && \ + useradd -m -u $UID -g $USER -s /bin/bash -d $DIR $USER + +# Copy default torrc configuration +RUN mkdir -p /etc/tor && \ + chown "$USER":"$USER" /etc/tor +COPY --chown=$USER:$USER torrc-dist /etc/tor/torrc + +# Create data and runtime directories with correct ownership and +# permissions so that Tor can write hidden service keys, cache, and +# control socket when running as the unprivileged user. +RUN mkdir -p /var/lib/tor /var/run/tor && \ + chown "$USER":"$USER" /var/lib/tor /var/run/tor && \ + chmod 700 /var/lib/tor + +COPY --chown=$USER:$USER docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + USER $USER VOLUME /etc/tor @@ -80,4 +100,5 @@ VOLUME /var/lib/tor EXPOSE 9050 9051 29050 29051 -ENTRYPOINT ["tor"] +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["tor"] diff --git a/README.md b/README.md index 1baf822..929423a 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,117 @@ # Tor as a Docker container +Tor service as a docker container, supporting multiple platforms/architectures (amd64, arm64). -[![Build on push](https://github.com/lncm/docker-tor/workflows/Docker%20build%20on%20push/badge.svg)](https://github.com/lncm/docker-tor/actions?query=workflow%3A%22Docker+build+on+push%22) -[![Build on tag deploy](https://github.com/lncm/docker-tor/workflows/Docker%20build%20on%20tag/badge.svg)](https://github.com/lncm/docker-tor/actions?query=workflow%3A%22Docker+build+on+tag%22) -![Version](https://img.shields.io/github/v/release/lncm/docker-tor?sort=semver) -![Docker Pulls Count](https://img.shields.io/docker/pulls/lncm/tor.svg?style=flat) +## Goal -Tor service as a docker container, supporting multiple platforms/architectures (armv6, armv7, arm64, amd64) the LNCM way (inclusive) - -## Usage instructions +This project provides Docker images for the latest non-alpha Tor release from [https://dist.torproject.org/](https://dist.torproject.org/?C=M;O=D). ## Tags -> **NOTE:** For an always up-to-date list see: https://hub.docker.com/r/lncm/tor/tags +* `latest` - Latest tagged release +* `master` - Latest commit on master branch +* Version tags (e.g., `0.4.8.21`) - Specific Tor versions + +## Usage + +### Default Configuration (SOCKS Proxy) -* `latest` -* `0.4.7.9` -* [`0.4.7.8`](https://hub.docker.com/layers/tor/lncm/tor/0.4.7.8/images/sha256-98269e8123cdeae9dfcb85d9a148d6b59181034de1ba5091d8e26d84af739f28?context=explore) -* [`0.4.7.7`](https://hub.docker.com/layers/tor/lncm/tor/0.4.7.7/images/sha256-35c3e00eb757ed9b1c04ded2245a15ab52ff7bf626b78b07febded4fd8bc435f?context=explore) -* `0.4.6.8` -* `0.4.5.11` -* [`0.4.7.1-alpha`](https://hub.docker.com/layers/lncm/tor/0.4.7.1-alpha/images/sha256-8fda0d219af1846f2ef6f083c62783bcd1d54b04246c835b561df1238dbe091c?context=explore) -* [`0.4.4.8`](https://hub.docker.com/layers/lncm/tor/0.4.4.8/images/sha256-701ea4a103327422ec560882ce4cf454130bca773a44fbc6d15070118d81f184) [`0.4.5.7`](https://hub.docker.com/layers/lncm/tor/0.4.5.7/images/sha256-5a00971a00143b46e57fd2ce577fe54ed6a5450fa9f463f6876b3616b5dc1dbb) -* [`0.4.5.6`](https://gitweb.torproject.org/tor.git/plain/ChangeLog?h=tor-0.4.5.6) -* `0.4.4.7` -* `0.4.5.5-rc` `0.4.5.3-rc` -* `0.4.4.5` `0.4.4.6` -* `0.4.4.4-rc` `0.4.3.6` +By default, when run without a mounted configuration, the container listens on all interfaces on port 9050 as a SOCKS proxy: -## Maintainer release notes +```bash +docker run -d --name tor -p 9050:9050 ghcr.io/m0wer/docker-tor:latest +``` -The github action takes in the current tag from [upstream](https://dist.torproject.org/) and then fetches, verifies and compiles this. +This allows you to use Tor as a proxy for your applications. -To grab a new version simply just tag a new version +### Advanced Usage -Example: +For more advanced configurations (control port, custom settings, etc.), mount your own `torrc` configuration file: ```bash -git tag -s 0.4.7.9 +docker run -d \ + --name tor \ + -v $PWD/torrc:/etc/tor/torrc \ + ghcr.io/m0wer/docker-tor:latest ``` -Would Release ```0.4.7.9``` of tor. +**For hidden services**, you must mount `/var/lib/tor` to persist your hidden service keys and allow Tor to create the necessary directories: -As a maintainer, you should also update the documentation too. +```bash +docker run -d \ + --name tor \ + -v $PWD/torrc:/etc/tor/torrc \ + -v $PWD/data:/var/lib/tor \ + ghcr.io/m0wer/docker-tor:latest +``` -### Environment Variables +The entrypoint automatically fixes directory and file permissions (`0700` for +directories, `0600` for files) inside `/var/lib/tor` so that Tor's strict +permission checks pass. The mounted host directory and any pre-existing key +files **must be owned by the UID the container runs as** (default `1000`). -> **Note** In order to trigger builds This repository uses the following environment variables: +When running with a custom `user:` in Docker Compose or `--user` on the CLI, +make sure the host directory ownership matches: -* `DOCKER_HUB_USER` - the username for docker hub -* `DOCKER_USERNAME` - The username for dockerhub. -* `DOCKER_PASSWORD` - The password for dockerhub -* `DOCKER_TOKEN` - the token for docker hub which can push to this projecta (not used currently) -* `GITHUB_TOKEN` - The token of the current user (this is added automatically) -* `GITHUB_ACTOR` - The user to login to docker.pkg.github.com -* `GITHUB_REPOSITORY` - The repository pathname (used for the push to githubs package registry) +```bash +# Example: prepare a hidden service data directory for UID 1000 +mkdir -p ./tor-data +chown -R 1000:1000 ./tor-data +chmod 700 ./tor-data +``` -## Running +### Disabling the SOCKS Proxy and Control Port -> this assumes `0.4.7.9` version. But you can substitute this for others +If you are only running hidden services and do not need SOCKS proxy or control +port access, disable them in your `torrc` for a smaller attack surface: -### Command Line +``` +SocksPort 0 +ControlPort 0 +``` -To run this from the command line you would need to create an example [config file](https://github.com/torproject/tor/blob/master/src/config/torrc.sample.in) or use the [cut down config file](https://raw.githubusercontent.com/lncm/docker-tor/master/torrc-dist) in this repo. +### Docker Compose -Then you would need to run: +For convenience, a [docker-compose.yml-dist](docker-compose.yml-dist) file is available: ```bash -docker run --rm -d \ - --network host \ - --name tor \ - -v $PWD/data:/etc/tor \ - -v $PWD/data:/var/lib/tor \ - -v $PWD/run:/var/run/tor \ - lncm/tor:0.4.7.9 - +docker compose -f docker-compose.yml-dist up ``` -This assumes you have a directory called `data` and a directory called `run` in the current `$PWD`. And the config file `torrc` should live in data. -### Docker-compose +### Configuration Examples -For your convenience, we have a [docker-compose](https://github.com/lncm/docker-tor/blob/master/docker-compose.yml-dist) file available for you to use too. +The default [torrc-dist](torrc-dist) configuration provides a minimal SOCKS proxy setup. It includes commented examples for: +- Control port with cookie authentication +- Hidden services (SSH, Bitcoin P2P) -By default this uses host networking and requires `data` and `run` folders to be created and with a [valid torrc file](https://github.com/torproject/tor/blob/master/src/config/torrc.sample.in) +**Note**: Both control port (with cookie auth) and hidden services require mounting `/var/lib/tor` as shown in the Advanced Usage section above. + +For a full configuration reference, see the [official Tor configuration documentation](https://github.com/torproject/tor/blob/main/src/config/torrc.sample.in). + +### Using the Control Port + +If you enable the control port with cookie authentication, you can interact with Tor using tools like `nyx` or libraries that support the Tor control protocol. The authentication cookie will be stored in `/var/lib/tor/control_auth_cookie`. ### Generating Tor Passwords +If you prefer password authentication over cookie authentication for the control port, you can generate a hashed password: + +```bash +docker run --rm ghcr.io/m0wer/docker-tor:latest --hash-password mypassword +``` + +Then use `HashedControlPassword` in your torrc instead of `CookieAuthentication`. + +## Building + +To update to a new Tor version: + +1. Check [dist.torproject.org](https://dist.torproject.org/?C=M;O=D) for the latest non-alpha release +2. Update `VERSION` and `TOR_TARBALL_SHA256` in the Dockerfile +3. Tag and push to trigger the build: + ```bash -docker run --rm \ - --name tor \ - lncm/tor:0.4.7.8 \ - --hash-password passwordtogenerate +git tag 0.4.8.21 +git push origin 0.4.8.21 ``` diff --git a/docker-compose.yml-dist b/docker-compose.yml-dist index 4cb7fad..e4e1827 100644 --- a/docker-compose.yml-dist +++ b/docker-compose.yml-dist @@ -1,13 +1,11 @@ -version: "3.8" - services: - tor: - image: lncm/tor:0.4.7.9 - container_name: tor - volumes: - - ${PWD}/data:/etc/tor - - ${PWD}/data:/var/lib/tor - - ${PWD}/run:/var/run/tor - restart: on-failure - network_mode: host - stop_grace_period: 10m30s + tor: + image: ghcr.io/m0wer/docker-tor:latest + container_name: tor + volumes: + - ${PWD}/data:/etc/tor + - ${PWD}/data:/var/lib/tor + - ${PWD}/run:/var/run/tor + restart: on-failure + network_mode: host + stop_grace_period: 10m30s diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..2b3a014 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,41 @@ +#!/bin/bash +set -euo pipefail + +# Fix permissions on /var/lib/tor and its contents so Tor can read/write +# hidden service keys when running as an unprivileged user. +# +# Tor enforces strict permission checks: +# - HiddenServiceDir must be mode 0700 +# - Key files must be mode 0600 +# - All must be owned by the running user + +fix_permissions() { + local dir="$1" + + if [ ! -d "$dir" ]; then + return + fi + + # Fix directory permissions: Tor requires 0700 on data dirs + if [ -w "$dir" ]; then + chmod 700 "$dir" 2>/dev/null || true + fi + + # Fix subdirectory permissions (hidden service dirs) + find "$dir" -mindepth 1 -maxdepth 1 -type d -writable 2>/dev/null | while read -r subdir; do + chmod 700 "$subdir" 2>/dev/null || true + # Fix key file permissions inside hidden service dirs + find "$subdir" -maxdepth 1 -type f -writable 2>/dev/null | while read -r file; do + chmod 600 "$file" 2>/dev/null || true + done + done + + # Fix key/data file permissions directly in the data dir + find "$dir" -maxdepth 1 -type f -writable 2>/dev/null | while read -r file; do + chmod 600 "$file" 2>/dev/null || true + done +} + +fix_permissions /var/lib/tor + +exec "$@" diff --git a/torrc-dist b/torrc-dist index 0f82b26..bf48ddd 100644 --- a/torrc-dist +++ b/torrc-dist @@ -1,19 +1,25 @@ -# This is a sample configuration +# Minimal Tor configuration for SOCKS proxy -# Ports -SocksPort 127.0.0.1:9050 -ControlPort 127.0.0.1:9051 +# SOCKS proxy listening on all interfaces +SocksPort 0.0.0.0:9050 -# Default Password (Please change) -# Refer to https://github.com/lncm/docker-tor#generating-tor-passwords -HashedControlPassword 16:C171CBB3DECE55156066E90509F28E3E5FDFACFB6211701926A200E70D +# For advanced usage, uncomment and configure the following: -# SSH v3 -HiddenServiceDir /var/lib/tor/ssh -HiddenServiceVersion 3 -HiddenServicePort 22 127.0.0.1:22 +# Control port (requires mounting /var/lib/tor volume for cookie auth) +# ControlPort 127.0.0.1:9051 +# CookieAuthentication 1 +# CookieAuthFile /var/lib/tor/control_auth_cookie -# Bitcoin P2P v3 -HiddenServiceDir /var/lib/tor/bitcoin-p2p -HiddenServiceVersion 3 -HiddenServicePort 8333 127.0.0.1:8333 +# Hidden services (requires mounting /var/lib/tor volume) +# HiddenServiceDir /var/lib/tor/ssh +# HiddenServiceVersion 3 +# HiddenServicePort 22 127.0.0.1:22 + +# HiddenServiceDir /var/lib/tor/bitcoin-p2p +# HiddenServiceVersion 3 +# HiddenServicePort 8333 127.0.0.1:8333 + +# For hidden-service-only setups, disable SOCKS proxy and control port +# to reduce attack surface: +# SocksPort 0 +# ControlPort 0