chore: snapshot before production push
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# Darkproxy AI Coding Guidelines
|
||||
|
||||
## Project Overview
|
||||
Darkproxy is a multi-container Docker stack enabling anonymous proxying across darknet (I2P, Tor) and clearnet. It chains SOCKS5 proxies through custom DNS resolvers, combining Yggdrasil networking, CoreDNS service orchestration, and blockchain-based TLD resolvers (Alfis, EmerCoin, meshname).
|
||||
|
||||
## Architecture
|
||||
**Fixed container IPs on `darkproxy` network (10.5.0.0/16)**:
|
||||
- `10.5.0.2`: i2pd_yggdrasil - I2P + Yggdrasil IPv6 tunneling
|
||||
- `10.5.0.3`: alfis - Blockchain resolver for .anon/.ygg/.btn/.conf TLDs
|
||||
- `10.5.0.4`: coredns - CoreDNS (PopuraDNS) DNS orchestration hub
|
||||
- `10.5.0.5`: unbound - Recursive clearnet DNS
|
||||
- `10.5.0.6`: pihole - DNS filtering + upstream forwarder
|
||||
- `10.5.0.7`: tor_yggdrasil - Tor + Yggdrasil tunneling
|
||||
- `10.5.0.8`: dark3proxy - SOCKS5/HTTP proxy (main entrypoint)
|
||||
- `10.5.0.9`: emc - EmerCoin resolver for .emc/.coin/.lib domains
|
||||
|
||||
**Data flow**: Client → dark3proxy (10.5.0.8:1080 SOCKS5) → pihole DNS (10.5.0.6) → coredns (10.5.0.4) → TLD-specific resolvers → upstream SOCKS backends (i2pd/tor).
|
||||
|
||||
## Key Workflows
|
||||
**Build custom images** (with version pinning via build args):
|
||||
- I2P: `cd i2pd_yggdrasil_docker/src && ./make_docker_image.sh` (sets I2PD_VERSION=2.58.0, YGGDRASIL_VERSION=v0.5.12, UBUNTU_VERSION=24.04)
|
||||
- Tor: `cd tor_yggdrasil_docker && ./build_image.sh` (same versions via git describe fallback)
|
||||
- 3proxy: No build script—uses GitHub release binary download in Dockerfile
|
||||
|
||||
**Deploy/Debug**:
|
||||
- Start: `docker-compose up --build` from root
|
||||
- Logs: `docker-compose logs -f coredns` (or dark3proxy, i2pd_yggdrasil, tor_yggdrasil)
|
||||
- Shell: `docker exec -it darkdns /bin/sh` (use container_name from compose)
|
||||
- Health: Each service has `healthcheck` or ping-based validation in entrypoint
|
||||
|
||||
**Add new TLD resolver**:
|
||||
1. In docker-compose.yml: add new service with fixed IP in 10.5.0.x range, ensure internal network access
|
||||
2. In PopuraDNS/Corefile: add block like `newtld.:53 { acl { allow net 10.0.0.0/8 ...; block }; forward . 10.5.0.X:53 }`
|
||||
3. Rebuild coredns: `docker-compose up --build coredns`
|
||||
|
||||
## Conventions
|
||||
**Secrets/Environment**: Stored in `secrets/` directory (tz.txt for timezone, YGGDRASIL_GENERATE_KEYS.txt for key generation). Mounted as Docker secrets, referenced in environment via `/run/secrets/`.
|
||||
|
||||
**Proxy Routing Logic** (in `3proxy/first-instanse.cfg`):
|
||||
- Parent rules chain traffic: i2p domains → i2pd SOCKS (10.5.0.2:4447), onion → tor SOCKS (10.5.0.7:9050), Yggdrasil (200::/7) → local SOCKS, clearnet → tor fallback
|
||||
- Blacklist format: `{{vk.com,ok.ru,...}}` (blocks these domains)
|
||||
|
||||
**DNS Stacking**: pihole (ad-filtering) → coredns (routing) → specialists. pihole upstreams to coredns (10.5.0.4), coredns forwards TLDs to resolvers. ACLs in Corefile block external networks; only 10.0.0.0/8, 127.0.0.1, fc00::/7 allowed.
|
||||
|
||||
**Yggdrasil Key Generation**: Services `i2pd_yggdrasil` and `tor_yggdrasil` run Python utils (yggdrasil_get_keys, yggdrasil_find_public_peers) in entrypoint—generates strong keys + finds optimal peers unless YGGDRASIL_GENERATE_KEYS=false.
|
||||
|
||||
**Networking**: All services require `sysctls: net.ipv6.conf.all.disable_ipv6=0` for Yggdrasil IPv6. Tunneling services (i2pd_yggdrasil, tor_yggdrasil) need `privileged: true`, `cap_add: NET_ADMIN`, `/dev/net/tun:/dev/net/tun`.
|
||||
|
||||
## Examples
|
||||
- **Port Mapping** (via Yggdrasil IP 100.117.196.19): SOCKS on 2000→1080, 3proxy-eagle web 2002→8161, I2P console 2001→7070
|
||||
- **Config Mounting**: Read-only volumes for configs—e.g., `./unbound/unbound.conf:/opt/unbound/etc/unbound/unbound.conf`
|
||||
- **Image Tagging**: Custom builds tag as `service_name:${TAG_VERSION}` (git tag) and `:latest`; published to registry (host60/ prefix in docker-compose)
|
||||
|
||||
Reference files: [docker-compose.yml](docker-compose.yml), [PopuraDNS/Corefile](PopuraDNS/Corefile), [3proxy/first-instanse.cfg](3proxy/first-instanse.cfg), [i2pd_yggdrasil_docker/src/make_docker_image.sh](i2pd_yggdrasil_docker/src/make_docker_image.sh), [tor_yggdrasil_docker/build_image.sh](tor_yggdrasil_docker/build_image.sh)</content>
|
||||
<parameter name="filePath">/home/sommopfle/darkproxy/.github/copilot-instructions.md
|
||||
@@ -0,0 +1,63 @@
|
||||
name: "Configuration validation"
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'docker-compose.yml'
|
||||
- 'PopuraDNS/**'
|
||||
- '.github/workflows/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'docker-compose.yml'
|
||||
- 'PopuraDNS/**'
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Run full validation script
|
||||
run: |
|
||||
chmod +x scripts/validate-config.sh
|
||||
scripts/validate-config.sh
|
||||
|
||||
smoke:
|
||||
needs: lint
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
docker:
|
||||
image: docker:24-dind
|
||||
privileged: true
|
||||
options: >-
|
||||
--cpus=2 --memory=4g
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Start stack and wait for health
|
||||
run: |
|
||||
docker compose up -d --build
|
||||
# wait up to 120 seconds for each container's healthcheck to pass
|
||||
for svc in darkdns darkpihole darkunbound darkalfis darkemer dark3proxy darktor darkproxy; do
|
||||
echo "waiting for $svc"
|
||||
for i in {1..24}; do
|
||||
status=$(docker inspect -f '{{.State.Health.Status}}' $svc 2>/dev/null || echo none)
|
||||
if [ "$status" = "healthy" ]; then
|
||||
echo "$svc healthy" && break
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
done
|
||||
docker compose ps
|
||||
|
||||
# quick DNS smoke tests via CoreDNS container
|
||||
echo "testing onion resolution"
|
||||
docker exec darkdns dig +short @127.0.0.1 -p 53 facebookcorewwwi.onion
|
||||
echo "testing i2p resolution"
|
||||
docker exec darkdns dig +short @127.0.0.1 -p 53 stats.i2p
|
||||
|
||||
docker compose down
|
||||
@@ -0,0 +1,7 @@
|
||||
i2pd/data/
|
||||
tor/data/
|
||||
|
||||
# runtime secrets should not be committed
|
||||
secrets/
|
||||
|
||||
generated.yml
|
||||
@@ -0,0 +1,74 @@
|
||||
# Stage 1: Build
|
||||
FROM --platform=$BUILDPLATFORM ubuntu:22.04 AS builder
|
||||
|
||||
ARG BUILDPLATFORM
|
||||
ARG TARGETPLATFORM
|
||||
ARG TARGETARCH
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install build dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
qtbase5-dev \
|
||||
qtchooser \
|
||||
qt5-qmake \
|
||||
qtbase5-dev-tools \
|
||||
wget \
|
||||
git \
|
||||
build-essential \
|
||||
libqt5core5a \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Download appropriate 3proxy binary based on architecture
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; then \
|
||||
wget -O 3proxy.deb https://github.com/3proxy/3proxy/releases/download/0.9.4/3proxy-0.9.4.x86_64.deb; \
|
||||
elif [ "$TARGETARCH" = "arm64" ]; then \
|
||||
wget -O 3proxy.deb https://github.com/3proxy/3proxy/releases/download/0.9.4/3proxy-0.9.4.aarch64.deb || \
|
||||
{ echo "ARM64 binary not available, using x86_64"; wget -O 3proxy.deb https://github.com/3proxy/3proxy/releases/download/0.9.4/3proxy-0.9.4.x86_64.deb; }; \
|
||||
elif [ "$TARGETARCH" = "arm" ]; then \
|
||||
wget -O 3proxy.deb https://github.com/3proxy/3proxy/releases/download/0.9.4/3proxy-0.9.4.armv7l.deb || \
|
||||
{ echo "ARMv7 binary not available"; exit 1; }; \
|
||||
fi && \
|
||||
dpkg -i 3proxy.deb || true
|
||||
|
||||
# Build 3proxy-eagle in a dedicated source directory
|
||||
RUN git clone https://gitea.darkness.services/acetone/3proxy-eagle.git /src/3proxy-eagle \
|
||||
&& cd /src/3proxy-eagle \
|
||||
&& find . -name "*.cpp" -o -name "*.h" | xargs sed -i 's/127\.0\.0\.1/0.0.0.0/g' \
|
||||
&& cd /src/3proxy-eagle/src \
|
||||
&& qmake 3proxy-eagle.pro \
|
||||
&& make -j$(nproc)
|
||||
|
||||
# Stage 2: Runtime
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ARG TARGETARCH
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libqt5core5a \
|
||||
libqt5network5 \
|
||||
libqt5xml5 \
|
||||
libqt5sql5 \
|
||||
libqt5sql5-sqlite \
|
||||
ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy binaries using the correct absolute paths from Stage 1
|
||||
COPY --from=builder /usr/bin/3proxy /usr/bin/3proxy
|
||||
COPY --from=builder /src/3proxy-eagle/src/3proxy-eagle /usr/bin/3proxy-eagle
|
||||
|
||||
# Setup config directories
|
||||
RUN mkdir -p /etc/3proxy /etc/3proxy-eagle/data
|
||||
|
||||
# Ensure these files exist in your local directory where you run 'docker build'
|
||||
#COPY first-instanse.cfg /etc/3proxy/
|
||||
#COPY second-instanse.cfg /etc/3proxy/
|
||||
|
||||
EXPOSE 8161
|
||||
|
||||
# Run in foreground
|
||||
CMD ["/usr/bin/3proxy-eagle", \
|
||||
"-i", "/usr/bin/3proxy,/etc/3proxy/first-instanse.cfg", \
|
||||
"-i", "/usr/bin/3proxy,/etc/3proxy/second-instanse.cfg", \
|
||||
"-w", "/etc/3proxy-eagle/data", \
|
||||
"-t", "DarkProxy"]
|
||||
@@ -0,0 +1,45 @@
|
||||
# regular 3proxy configuration
|
||||
fakeresolve
|
||||
flush
|
||||
auth iponly
|
||||
admin -p8161 -a0.0.0.0
|
||||
# strict required by 3proxy-eagle log lines
|
||||
log
|
||||
logformat " type=%N destination=%n to=%O from=%I"
|
||||
|
||||
# 3proxy-eagle black list format
|
||||
{{vk.com,ok.ru,mail.ru,gosuslugi.ru,127.0.0.1}}
|
||||
|
||||
# regular 3proxy configuration again
|
||||
|
||||
# expose a lightweight status socket for Prometheus scraping
|
||||
# the exporter will connect here and convert counters to metrics
|
||||
monitor -p6800
|
||||
|
||||
## i2p sites
|
||||
allow * * *.i2p
|
||||
#parent 1000 http 127.0.0.1 4444
|
||||
parent 1000 socks5+ 10.5.0.2 4447
|
||||
|
||||
## yggdrasil (127.0.0.1 1085 is second instanse)
|
||||
allow * * 200::/7
|
||||
parent 1000 socks5+ 127.0.0.1 1085
|
||||
## ygg domains resolving by alfis
|
||||
allow * * *.ygg
|
||||
parent 1000 socks5+ 127.0.0.1 1085
|
||||
## meshnames domains resolving by meshnamed
|
||||
allow * * *.meshname
|
||||
parent 1000 socks5+ 127.0.0.1 1085
|
||||
allow * * *.meship
|
||||
parent 1000 socks5+ 127.0.0.1 1085
|
||||
|
||||
## onion sites
|
||||
allow * * *.onion
|
||||
parent 1000 socks5+ 10.5.0.7 9050
|
||||
|
||||
## clearnet via another proxy or change to tor (9050)
|
||||
allow *
|
||||
parent 1000 socks5+ 10.5.0.7 9050
|
||||
|
||||
socks -olSO_REUSEADDR,SO_REUSEPORT -ocTCP_TIMESTAMPS,TCP_NODELAY -osTCP_NODELAY -46 -i0.0.0.0 -p1080
|
||||
proxy -olSO_REUSEADDR,SO_REUSEPORT -ocTCP_TIMESTAMPS,TCP_NODELAY -osTCP_NODELAY -46 -a1 -i0.0.0.0 -p3128
|
||||
@@ -0,0 +1,8 @@
|
||||
auth iponly
|
||||
# allow only Yggdrasil network subnet by this instanse
|
||||
# otherwise all ygg/meshname/meship domains with
|
||||
# non-yggdrasil addresses goes bypass any rules
|
||||
# and potentially can deanonimaze outproxy machine
|
||||
allow * * 200::/7
|
||||
deny *
|
||||
socks -olSO_REUSEADDR,SO_REUSEPORT -ocTCP_TIMESTAMPS,TCP_NODELAY -osTCP_NODELAY -64 -i127.0.0.1 -p1085
|
||||
Submodule
+1
Submodule PopuraDNS added at 749c8a6300
@@ -0,0 +1,173 @@
|
||||
Welcome to darkproxy...
|
||||
|
||||
This container runs the following vontainers in the stack.
|
||||
|
||||
3proxy-eagle - Socks5/http proxy
|
||||
- DNS
|
||||
- pihole - ad blocking and metrics
|
||||
- PopuraDNS - non-recursive DNS forwards requests to the following:
|
||||
Alfis - Blockchain based yggdrasil resolver
|
||||
EmerCoin - Resolves EMC domains
|
||||
UnBound - Recursive DNS for Clearnet domains
|
||||
* .onion and .i2p domain names are now resolved via the stack (see DNS section below)
|
||||
- I2PD over Yggdrasil container (`container_name: darki2p`)
|
||||
* Yggdrasil IP network stack
|
||||
* Socks5 server for I2P
|
||||
- Tor container
|
||||
|
||||
The system offers a DNS that resolves many darknet and clearnet IP's. The
|
||||
stack now handles:
|
||||
|
||||
* `*.onion` – forwarded to Tor's DNSPort running in the `darktor` container at
|
||||
10.5.0.7:9053.
|
||||
* `*.i2p` – served by the built-in DNS server inside the `darki2p` container
|
||||
(10.5.0.2:53) which is enabled via the `[dns]` section in `i2pd.conf`.
|
||||
|
||||
You can query these directly from any container on the `darkproxy` network, for
|
||||
example:
|
||||
|
||||
```sh
|
||||
# Tor .onion domains
|
||||
docker run --rm --network darkproxy infoblox/dig dig @10.5.0.4 facebookcorewwwi.onion
|
||||
|
||||
# I2P .i2p domains
|
||||
docker run --rm --network darkproxy infoblox/dig dig @10.5.0.4 stats.i2p
|
||||
|
||||
# Ethereum Name Service (.eth) via Cloudflare fallback
|
||||
docker run --rm --network darkproxy infoblox/dig dig @10.5.0.4 vitalik.eth
|
||||
|
||||
# Other supported TLDs: .bit, .alt, .loki, .zil, .web3, .exit, .onion4, .onion6
|
||||
docker run --rm --network darkproxy infoblox/dig dig @10.5.0.4 example.bit
|
||||
```
|
||||
|
||||
> **Note:** the CoreDNS service at `10.5.0.4` no longer enforces an ACL for
|
||||
> the root zone – it will happily perform recursive lookups for any client.
|
||||
> Queries from your host should now work without the “refused to do a recursive
|
||||
> query” error. If you later reintroduce an ACL, update this note accordingly.
|
||||
|
||||
|
||||
## Supported TLDs and resolvers
|
||||
|
||||
The stack now provides DNS resolution for a comprehensive set of alternative TLDs:
|
||||
|
||||
| TLD | Resolver | Purpose |
|
||||
|-----|----------|---------|
|
||||
| `.onion`, `.exit`, `.onion4`, `.onion6` | Tor DNSPort (10.5.0.7:9053) | Tor hidden services |
|
||||
| `.i2p` | i2pd DNS (10.5.0.2:53) | I2P eepsite names |
|
||||
| `.eth` | Cloudflare 1.1.1.1 | Ethereum Name Service |
|
||||
| `.bit` | Google 8.8.8.8 | Namecoin names |
|
||||
| `.alt` | alt-root 185.121.177.177 | Alternative DNS root |
|
||||
| `.loki` | Cloudflare 1.1.1.1 | Lokinet privacy network |
|
||||
| `.zil` | Cloudflare 1.1.1.1 | Zilliqa blockchain |
|
||||
| `.web3` | Cloudflare 1.1.1.1 | General blockchain namespace |
|
||||
| Alfis TLDs | Alfis (10.5.0.3) | `.anon`, `.btn`, `.conf`, `.index`, `.merch`, `.mirror`, `.mob`, `.screen`, `.srv`, `.ygg` |
|
||||
| EmerCoin TLDs | EmerCoin (10.5.0.9) | `.emc`, `.coin`, `.lib`, `.bazar`, `.enum` |
|
||||
| OpenNIC TLDs | OpenNIC public resolvers | `.bbs`, `.chan`, `.cyb`, `.dyn`, `.epic`, `.geek`, `.gopher`, `.indy`, `.libre`, `.neo`, `.null`, `.o`, `.oss`, `.oz`, `.parody`, `.pirate`, `.fur`, `.ku`, `.rm`, `.te`, `.ti`, `.uu`, `.ko` |
|
||||
| Clearnet | Unbound (10.5.0.5) | All other domains via recursive resolution |
|
||||
|
||||
|
||||
## Configuration validation and drift tests
|
||||
|
||||
A simple automation is included to help detect accidental changes to the
|
||||
compose and DNS configuration:
|
||||
|
||||
1. **Local check** – run `scripts/validate-config.sh` (or its PowerShell equivalent).
|
||||
- The script requires `docker` to be installed; it will generate a normalized
|
||||
manifest and compare it against `docker-compose.lock.yml`.
|
||||
- If the baseline file does not exist it will be created; commit the file after
|
||||
review.
|
||||
- CoreDNS syntax is also validated using either a local `coredns` binary or a
|
||||
container.
|
||||
|
||||
2. **CI workflow** – `.github/workflows/config-validation.yml` is triggered on
|
||||
pushes or pull requests affecting `docker-compose.yml` or `PopuraDNS/`.
|
||||
The job executes the same `docker compose config` comparison and runs the
|
||||
Corefile check inside a container.
|
||||
|
||||
3. **Updating the baseline** – when intentional changes are made to the
|
||||
compose file, regenerate the baseline:
|
||||
|
||||
```sh
|
||||
scripts/validate-config.sh # fails with drift
|
||||
cp generated.yml docker-compose.lock.yml
|
||||
git add docker-compose.lock.yml
|
||||
```
|
||||
|
||||
These steps ensure that configuration drift is caught early and reviewers can
|
||||
see what has changed.
|
||||
|
||||
|
||||
## Monitoring the proxy
|
||||
|
||||
A lightweight Prometheus/Grafana stack is included to expose 3proxy metrics
|
||||
and give you visibility into traffic volumes, connected sessions, etc.
|
||||
|
||||
### how it works
|
||||
|
||||
* `3proxy` is configured with `monitor -p6800`, which sets up a plain-text
|
||||
status socket. Samples look like `PROXY CONNS 12` or `SOCKS IN 345`.
|
||||
* `monitor/exporter.py` polls that socket every few seconds and exports
|
||||
the counters on HTTP port **9100** in Prometheus format.
|
||||
* The `docker-compose.yml` file now defines three new services:
|
||||
`3proxy_exporter`, `prometheus` and `grafana`.
|
||||
Prometheus scrapes the exporter and Grafana points at Prometheus as a data
|
||||
source.
|
||||
|
||||
### building & running
|
||||
|
||||
The exporter lives in `monitor/`; build the image and start the stack:
|
||||
|
||||
```sh
|
||||
# build everything including the new services
|
||||
docker-compose build 3proxy_exporter prometheus grafana
|
||||
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
Prometheus will be accessible on port **9090**, Grafana on **3000** (admin
|
||||
password `secret`). Use Grafana to create or import dashboards – a simple
|
||||
example JSON is provided in `monitor/3proxy-dashboard.json`. You can import
|
||||
that file directly or build your own panels using metrics such as
|
||||
`proxy_conns` and `proxy_bytes_in`.
|
||||
|
||||
### tips
|
||||
|
||||
* Alerts can be added in Prometheus rules, e.g. fire when `proxy_conns`
|
||||
exceeds a threshold for several minutes.
|
||||
* If you don’t want the full stack, you can still query the monitor port
|
||||
directly with `nc`; nothing in the proxy depends on the exporter.
|
||||
* The `scripts/validate-config.sh` script warns if a 3proxy config lacks a
|
||||
`monitor` line.
|
||||
|
||||
## Production readiness checklist
|
||||
|
||||
Make sure you never commit real secrets. The `secrets/` directory is now
|
||||
included in `.gitignore`; both timezone and Yggdrasil key files live there and
|
||||
are mounted into containers at runtime.
|
||||
|
||||
Before deploying to a live environment, run the validation script and resolve
|
||||
any warnings or errors. The script covers:
|
||||
|
||||
* YAML syntax and drift against the committed baseline
|
||||
* CoreDNS/PopuraDNS Corefile syntax
|
||||
* Unbound configuration syntax
|
||||
* Presence of required secret files
|
||||
* Simple 3proxy configuration sanity (presence of `socks`/`proxy` rules)
|
||||
* Detection of `:latest` image tags (pin to fixed versions)
|
||||
* Verification that restart policies exist
|
||||
|
||||
The GitHub Actions workflow also includes a **smoke test** job that spins up
|
||||
all services in `docker-compose.yml` using a Docker‑in‑Docker service and
|
||||
waits for each container’s healthcheck to report `healthy`. This gives an
|
||||
additional layer of confidence that the stack can be built and started
|
||||
successfully.
|
||||
|
||||
You can also extend the script with additional service-specific checks such as
|
||||
running `docker run ...` commands to exercise the images, scanning the
|
||||
`3proxy` config more deeply, or linting other mounted configuration files.
|
||||
|
||||
Run the script locally via `./scripts/validate-config.sh` (or
|
||||
`.scripts/validate-config.ps1` on Windows) and review the output carefully.
|
||||
CI will execute the same validations automatically on pull requests.
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# ARM-specific override for darkproxy stack
|
||||
# Use together with the main compose file:
|
||||
#
|
||||
# docker compose -f docker-compose.yml -f docker-compose.arm.yml up --build
|
||||
#
|
||||
# This file adds `platform: linux/arm64` hints to services so the correct
|
||||
# architecture is selected when running on an ARM host. It does **not** replace
|
||||
# any images; if an image is not available for ARM (e.g. alfis, unbound, the
|
||||
# prebuilt tor_yggdrasil) Docker will attempt emulation via QEMU or fall back to
|
||||
# amd64.
|
||||
#
|
||||
# You can also modify this file to swap in ARM-specific images or build
|
||||
# instructions if you have them.
|
||||
|
||||
services:
|
||||
dark3proxy:
|
||||
platform: linux/arm64
|
||||
|
||||
i2pd_yggdrasil:
|
||||
platform: linux/arm64
|
||||
|
||||
tor_yggdrasil:
|
||||
platform: linux/arm64
|
||||
|
||||
alfis:
|
||||
platform: linux/arm64
|
||||
|
||||
coredns:
|
||||
platform: linux/arm64
|
||||
|
||||
unbound:
|
||||
platform: linux/arm64
|
||||
|
||||
pihole:
|
||||
platform: linux/arm64
|
||||
|
||||
emc:
|
||||
platform: linux/arm64
|
||||
|
||||
geth:
|
||||
platform: linux/arm64
|
||||
|
||||
# networks, volumes, and secrets are inherited from the base compose file
|
||||
@@ -0,0 +1,269 @@
|
||||
services:
|
||||
dark3proxy:
|
||||
container_name: dark3proxy
|
||||
image: host60/darkproxy-dark3proxy:v1.0
|
||||
build:
|
||||
context: ./3proxy/.
|
||||
dns:
|
||||
- "10.5.0.6"
|
||||
dns_search: internal.namespace #namespace used in internal DNS
|
||||
volumes:
|
||||
- "./3proxy/first-instanse.cfg:/etc/3proxy/first-instanse.cfg"
|
||||
- "./3proxy/second-instanse.cfg:/etc/3proxy/second-instanse.cfg"
|
||||
restart: unless-stopped
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
ports:
|
||||
- 100.117.196.19:2000:1080 # socks port
|
||||
- 100.117.196.19:2002:8161 # 3proxy-eagle web page
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.8
|
||||
|
||||
i2pd_yggdrasil:
|
||||
container_name: darki2p
|
||||
# image: i2pd_yggdrasil:latest
|
||||
image: host60/i2pd_yggdrasil:v1.0
|
||||
privileged: true
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
ports:
|
||||
# I2P Service Ports
|
||||
# - "2827:2827" # BOB Bridge
|
||||
# - "4444:4444" # HTTP Proxy
|
||||
# - "4447:4447" # SOCKS Proxy
|
||||
- "100.117.196.19:2001:7070" # Webconsole
|
||||
# - "7650:7650" # I2PControl
|
||||
# - "7654:7654" # I2CP
|
||||
# - "7656:7656" # SAM Bridge (TCP)
|
||||
- "10765:10765" # Main I2P Listener
|
||||
# [dns] section enabled in i2pd.conf; DNS port is 53 (accessible internally at 10.5.0.2:53)
|
||||
# mapping to host is possible if desired, e.g. 10853:53/udp
|
||||
# Yggdrasil Ports
|
||||
- "10654:10654" # Yggdrasil Listener
|
||||
environment:
|
||||
tz: /run/secrets/tz
|
||||
secrets:
|
||||
- tz
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "bash", "-c", "pgrep i2pd && pgrep yggdrasil"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
mac_address: ce:22:b8:0e:6e:78
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.2
|
||||
|
||||
tor_yggdrasil:
|
||||
image: host60/tor_yggdrasil:v1.0
|
||||
# image: tor_yggdrasil:latest
|
||||
# container_name: tor_over_yggdrasil
|
||||
container_name: darktor
|
||||
# platform removed; image is amd64-only
|
||||
cap_add:
|
||||
- NET_ADMIN # Required for network tunnel management
|
||||
security_opt:
|
||||
- no-new-privileges:true # Security enhancement - prevent privilege esca>
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun # TUN device for Yggdrasil network interface
|
||||
ports:
|
||||
# - "127.0.0.1:9050:9050/tcp" # SOCKS5 proxy port (Tor) for application-l>
|
||||
- "10655:10655/tcp" # Yggdrasil peer connections
|
||||
secrets:
|
||||
- YGGDRASIL_GENERATE_KEYS
|
||||
environment:
|
||||
YGGDRASIL_GENERATE_KEYS: /run/secrets/YGGDRASIL_GENERATE_KEYS # Generate new Yggdrasil keys on startup
|
||||
restart: unless-stopped # Auto-restart unless manually stopped
|
||||
dns:
|
||||
- "10.5.0.6"
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.7
|
||||
|
||||
alfis:
|
||||
image: cofob/alfis
|
||||
# platform removed; image is amd64 only
|
||||
container_name: darkalfis
|
||||
volumes:
|
||||
- darkalfis_data:/storage
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 10s
|
||||
dns:
|
||||
- "10.5.0.6"
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.3
|
||||
|
||||
coredns:
|
||||
# image: darkdns
|
||||
image: host60/darkdns:v1.0
|
||||
build:
|
||||
context: ./PopuraDNS
|
||||
dockerfile: Dockerfile
|
||||
container_name: darkdns
|
||||
restart: unless-stopped
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m" # Maximum log file size
|
||||
max-file: "3" # Maximum of 3 rotating log files
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.4
|
||||
|
||||
unbound:
|
||||
container_name: darkunbound
|
||||
image: mvance/unbound:latest
|
||||
# platform removed; image is amd64-only
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.5
|
||||
volumes:
|
||||
- type: bind
|
||||
read_only: true
|
||||
source: ./unbound/unbound.conf
|
||||
target: /opt/unbound/etc/unbound/unbound.conf
|
||||
- "./unbound/forward-records.conf:/opt/unbound/etc/unbound/forward-records.conf"
|
||||
- "./unbound/a-records.conf:/opt/unbound/etc/unbound/a-records.conf"
|
||||
# ports:
|
||||
# - "5053:5053/tcp"
|
||||
# - "5053:5053/udp"
|
||||
# healthcheck:
|
||||
# disable: true
|
||||
restart: unless-stopped
|
||||
|
||||
pihole:
|
||||
container_name: darkpihole
|
||||
image: pihole/pihole:latest
|
||||
platform: linux/arm64
|
||||
# For DHCP it is recommended to remove these ports and instead add: network_mode: "host"
|
||||
ports:
|
||||
# DNS Ports
|
||||
# - "53:53/tcp"
|
||||
# - "53:53/udp"
|
||||
# Default HTTP Port
|
||||
# - "80:80/tcp"
|
||||
# Default HTTPs Port. FTL will generate a self-signed certificate
|
||||
# - "443:443/tcp
|
||||
# Uncomment the line below if you are using Pi-hole as your DHCP server
|
||||
# - "67:67/udp"
|
||||
# Uncomment the line below if you are using Pi-hole as your NTP server
|
||||
# - "123:123/udp"
|
||||
- "100.117.196.19:2003:80/tcp" # pihole web port
|
||||
environment:
|
||||
# Set the appropriate timezone for your location (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), e.g:
|
||||
TZ: 'America/Detroit'
|
||||
# WEBPASSWORD: 'set a secure password here or it will be random'
|
||||
# FTLCONF_webserver_api_password: 'darkproxy'
|
||||
# If using Docker's default `bridge` network setting the dns listening mode should be set to 'all'
|
||||
# FTLCONF_dns_listeningMode: 'all'
|
||||
PIHOLE_DNS_: 10.5.0.4
|
||||
TEMPERATUREUNIT: f
|
||||
WEBTHEME: lcars
|
||||
WEBPASSWORD: darkproxy
|
||||
FTLCONF_dns_upstreams: coredns
|
||||
# Volumes store your data between container upgrades
|
||||
volumes:
|
||||
# For persisting Pi-hole's databases and common configuration file
|
||||
- './pihole/etc-pihole:/etc/pihole'
|
||||
# Uncomment the below if you have custom dnsmasq config files that you want to persist. Not needed for most starting fresh with Pi-hole v6. If you're upgrading from v5 you and have used this directory before, you should keep it enabled for the first v6 container start to allow for a complete migration. It can be removed afterwards. Needs environment variable FTLCONF_misc_etc_dnsmasq_d: 'true'
|
||||
- './pihole/etc-dnsmasq.d:/etc/dnsmasq.d'
|
||||
cap_add:
|
||||
# See https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
|
||||
# Required if you are using Pi-hole as your DHCP server, else not needed
|
||||
- NET_ADMIN
|
||||
# Required if you are using Pi-hole as your NTP client to be able to set the host's system time
|
||||
# - SYS_TIME
|
||||
# Optional, if Pi-hole should get some more processing time
|
||||
- SYS_NICE
|
||||
restart: unless-stopped # Recommended but not required (DHCP needs NET_ADMIN)
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
healthcheck:
|
||||
test: ["CMD", "dig", "+short", "+norecurse", "+timeout=2", "@127.0.0.1", "google.com"]
|
||||
interval: 1m
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.6
|
||||
|
||||
geth:
|
||||
image: ethereum/client-go:latest
|
||||
platform: linux/arm64
|
||||
container_name: darkgeth
|
||||
command:
|
||||
- --syncmode=light
|
||||
- --http
|
||||
- --http.addr=0.0.0.0
|
||||
- --http.port=8545
|
||||
- --http.api=eth,net,web3
|
||||
- --cache=256
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.10
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 30s
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8545"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 120s
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
|
||||
emc:
|
||||
image: wg00/emercoin:0.8.4
|
||||
platform: linux/arm64
|
||||
container_name: darkemer
|
||||
volumes:
|
||||
- emc_data:/emc
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.9
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 30s
|
||||
|
||||
volumes:
|
||||
darkalfis_data:
|
||||
name: darkalfis_data
|
||||
emc_data:
|
||||
name: emc_data
|
||||
tor-data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
darkproxy:
|
||||
# name: darkproxy
|
||||
enable_ipv6: true
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 10.5.0.0/16
|
||||
gateway: 10.5.0.1
|
||||
- subnet: 2001:0BC5::/112
|
||||
gateway: 2001:0BC5::1
|
||||
|
||||
secrets:
|
||||
tz:
|
||||
file: ./secrets/tz.txt
|
||||
YGGDRASIL_GENERATE_KEYS:
|
||||
file: ./secrets/YGGDRASIL_GENERATE_KEYS.txt
|
||||
@@ -0,0 +1,311 @@
|
||||
services:
|
||||
dark3proxy:
|
||||
container_name: dark3proxy
|
||||
image: host60/darkproxy-dark3proxy:v1.0
|
||||
build:
|
||||
context: ./3proxy/.
|
||||
dns:
|
||||
- "10.5.0.6"
|
||||
dns_search: internal.namespace #namespace used in internal DNS
|
||||
volumes:
|
||||
- "./3proxy/first-instanse.cfg:/etc/3proxy/first-instanse.cfg"
|
||||
- "./3proxy/second-instanse.cfg:/etc/3proxy/second-instanse.cfg"
|
||||
restart: unless-stopped
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
ports:
|
||||
- 2000:1080 # socks port
|
||||
- 2002:8161 # 3proxy-eagle web page
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.8
|
||||
|
||||
i2pd_yggdrasil:
|
||||
container_name: darki2p
|
||||
image: host60/i2pd_yggdrasil:v1.3
|
||||
# image: i2pd_yggdrasil:latest
|
||||
privileged: true
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
ports:
|
||||
# I2P Service Ports
|
||||
# - "2827:2827" # BOB Bridge
|
||||
# - "4444:4444" # HTTP Proxy
|
||||
# - "4447:4447" # SOCKS Proxy
|
||||
- "2001:7070" # Webconsole
|
||||
# - "7650:7650" # I2PControl
|
||||
# - "7654:7654" # I2CP
|
||||
# - "7656:7656" # SAM Bridge (TCP)
|
||||
- "10765:10765" # Main I2P Listener
|
||||
# I2P name resolution occurs over the SOCKS proxy; there is no
|
||||
# separate DNS listener in this build (the `dns` section in i2pd.conf
|
||||
# is currently disabled because the shipped i2pd release doesn't
|
||||
# support it). SOCKS remains on port 4447 and will resolve *.i2p names.
|
||||
# mapping to host is possible if desired, e.g. 10853:53/udp
|
||||
# Yggdrasil Ports
|
||||
- "10654:10654" # Yggdrasil Listener
|
||||
environment:
|
||||
tz: /run/secrets/tz
|
||||
secrets:
|
||||
- tz
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "bash", "-c", "pgrep i2pd && pgrep yggdrasil"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
mac_address: ce:22:b8:0e:6e:78
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.2
|
||||
|
||||
tor_yggdrasil:
|
||||
image: host60/tor_yggdrasil:v1.0
|
||||
# image: tor_yggdrasil:latest
|
||||
# container_name: tor_over_yggdrasil
|
||||
container_name: darktor
|
||||
# platform removed; image is amd64-only
|
||||
cap_add:
|
||||
- NET_ADMIN # Required for network tunnel management
|
||||
security_opt:
|
||||
- no-new-privileges:true # Security enhancement - prevent privilege esca>
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun # TUN device for Yggdrasil network interface
|
||||
ports:
|
||||
# - "127.0.0.1:9050:9050/tcp" # SOCKS5 proxy port (Tor) for application-l>
|
||||
- "10655:10655/tcp" # Yggdrasil peer connections
|
||||
secrets:
|
||||
- YGGDRASIL_GENERATE_KEYS
|
||||
environment:
|
||||
YGGDRASIL_GENERATE_KEYS: /run/secrets/YGGDRASIL_GENERATE_KEYS # Generate new Yggdrasil keys on startup
|
||||
restart: unless-stopped # Auto-restart unless manually stopped
|
||||
dns:
|
||||
- "10.5.0.6"
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.7
|
||||
|
||||
alfis:
|
||||
image: cofob/alfis
|
||||
# platform removed; image is amd64 only
|
||||
container_name: darkalfis
|
||||
volumes:
|
||||
- darkalfis_data:/storage
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 10s
|
||||
dns:
|
||||
- "10.5.0.6"
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.3
|
||||
|
||||
coredns:
|
||||
# image: darkdns
|
||||
image: host60/darkdns:v1.0
|
||||
build:
|
||||
context: ./PopuraDNS
|
||||
dockerfile: Dockerfile
|
||||
container_name: darkdns
|
||||
restart: unless-stopped
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m" # Maximum log file size
|
||||
max-file: "3" # Maximum of 3 rotating log files
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.4
|
||||
|
||||
unbound:
|
||||
container_name: darkunbound
|
||||
image: mvance/unbound:latest
|
||||
# platform removed; image is amd64-only
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.5
|
||||
volumes:
|
||||
- type: bind
|
||||
read_only: true
|
||||
source: ./unbound/unbound.conf
|
||||
target: /opt/unbound/etc/unbound/unbound.conf
|
||||
- "./unbound/forward-records.conf:/opt/unbound/etc/unbound/forward-records.conf"
|
||||
- "./unbound/a-records.conf:/opt/unbound/etc/unbound/a-records.conf"
|
||||
# ports:
|
||||
# - "5053:5053/tcp"
|
||||
# - "5053:5053/udp"
|
||||
# healthcheck:
|
||||
# disable: true
|
||||
restart: unless-stopped
|
||||
|
||||
pihole:
|
||||
container_name: darkpihole
|
||||
image: pihole/pihole:latest
|
||||
platform: linux/arm64
|
||||
# For DHCP it is recommended to remove these ports and instead add: network_mode: "host"
|
||||
ports:
|
||||
# DNS Ports
|
||||
# - "53:53/tcp"
|
||||
# - "53:53/udp"
|
||||
# Default HTTP Port
|
||||
# - "80:80/tcp"
|
||||
# Default HTTPs Port. FTL will generate a self-signed certificate
|
||||
# - "443:443/tcp
|
||||
# Uncomment the line below if you are using Pi-hole as your DHCP server
|
||||
# - "67:67/udp"
|
||||
# Uncomment the line below if you are using Pi-hole as your NTP server
|
||||
# - "123:123/udp"
|
||||
- "2003:80/tcp" # pihole web port
|
||||
environment:
|
||||
# Set the appropriate timezone for your location (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), e.g:
|
||||
TZ: 'America/Detroit'
|
||||
# WEBPASSWORD: 'set a secure password here or it will be random'
|
||||
# FTLCONF_webserver_api_password: 'darkproxy'
|
||||
# If using Docker's default `bridge` network setting the dns listening mode should be set to 'all'
|
||||
# FTLCONF_dns_listeningMode: 'all'
|
||||
PIHOLE_DNS_: 10.5.0.4
|
||||
TEMPERATUREUNIT: f
|
||||
WEBTHEME: lcars
|
||||
WEBPASSWORD: darkproxy
|
||||
FTLCONF_dns_upstreams: coredns
|
||||
# Volumes store your data between container upgrades
|
||||
volumes:
|
||||
# For persisting Pi-hole's databases and common configuration file
|
||||
- './pihole/etc-pihole:/etc/pihole'
|
||||
# Uncomment the below if you have custom dnsmasq config files that you want to persist. Not needed for most starting fresh with Pi-hole v6. If you're upgrading from v5 you and have used this directory before, you should keep it enabled for the first v6 container start to allow for a complete migration. It can be removed afterwards. Needs environment variable FTLCONF_misc_etc_dnsmasq_d: 'true'
|
||||
- './pihole/etc-dnsmasq.d:/etc/dnsmasq.d'
|
||||
cap_add:
|
||||
# See https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
|
||||
# Required if you are using Pi-hole as your DHCP server, else not needed
|
||||
- NET_ADMIN
|
||||
# Required if you are using Pi-hole as your NTP client to be able to set the host's system time
|
||||
# - SYS_TIME
|
||||
# Optional, if Pi-hole should get some more processing time
|
||||
- SYS_NICE
|
||||
restart: unless-stopped # Recommended but not required (DHCP needs NET_ADMIN)
|
||||
sysctls:
|
||||
- "net.ipv6.conf.all.disable_ipv6=0"
|
||||
healthcheck:
|
||||
test: ["CMD", "dig", "+short", "+norecurse", "+timeout=2", "@127.0.0.1", "google.com"]
|
||||
interval: 1m
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.6
|
||||
|
||||
emc:
|
||||
image: wg00/emercoin:0.8.4
|
||||
platform: linux/arm64
|
||||
container_name: darkemer
|
||||
volumes:
|
||||
- emc_data:/emc
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.9
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 30s
|
||||
|
||||
tailscale:
|
||||
build:
|
||||
context: ./tailscale
|
||||
dockerfile: Dockerfile
|
||||
container_name: darkscale
|
||||
hostname: darkproxy-exit
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
environment:
|
||||
# ⚠️ Get your own auth key from https://login.tailscale.com/admin/settings/keys
|
||||
- TS_AUTHKEY=${TS_AUTHKEY:-tskey-YOUR-AUTH-KEY-HERE}
|
||||
- TS_EXTRA_ARGS=--accept-dns=false --advertise-exit-node
|
||||
- TS_STATE_DIR=/var/lib/tailscale
|
||||
volumes:
|
||||
- tailscale_data:/var/lib/tailscale
|
||||
networks:
|
||||
darkproxy:
|
||||
ipv4_address: 10.5.0.10
|
||||
sysctls:
|
||||
- net.ipv4.ip_forward=1
|
||||
- net.ipv6.conf.all.forwarding=1
|
||||
restart: unless-stopped
|
||||
|
||||
# monitoring exporter for 3proxy metrics
|
||||
3proxy_exporter:
|
||||
container_name: dark3proxy-exporter
|
||||
build:
|
||||
context: ./monitor
|
||||
image: darkproxy-3proxy-exporter:latest
|
||||
depends_on:
|
||||
- dark3proxy
|
||||
networks:
|
||||
- darkproxy
|
||||
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
container_name: darkprom
|
||||
volumes:
|
||||
- ./monitor/prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
||||
ports:
|
||||
- "9090:9090"
|
||||
networks:
|
||||
- darkproxy
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana:latest
|
||||
container_name: darkgraf
|
||||
ports:
|
||||
- "2005:3000"
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_PASSWORD=secret
|
||||
volumes:
|
||||
- grafana-data:/var/lib/grafana
|
||||
networks:
|
||||
- darkproxy
|
||||
|
||||
volumes:
|
||||
darkalfis_data:
|
||||
name: darkalfis_data
|
||||
emc_data:
|
||||
name: emc_data
|
||||
tor-data:
|
||||
driver: local
|
||||
tailscale_data:
|
||||
name: tailscale_data
|
||||
grafana-data:
|
||||
name: grafana-data
|
||||
|
||||
networks:
|
||||
darkproxy:
|
||||
# name: darkproxy
|
||||
enable_ipv6: true
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 10.5.0.0/16
|
||||
gateway: 10.5.0.1
|
||||
- subnet: 2001:0BC5::/112
|
||||
gateway: 2001:0BC5::1
|
||||
|
||||
secrets:
|
||||
tz:
|
||||
file: ./secrets/tz.txt
|
||||
YGGDRASIL_GENERATE_KEYS:
|
||||
file: ./secrets/YGGDRASIL_GENERATE_KEYS.txt
|
||||
|
||||
Submodule
+1
Submodule i2pd_yggdrasil_docker added at 82f003e327
@@ -0,0 +1,37 @@
|
||||
# Pi-hole: A black hole for Internet advertisements
|
||||
# (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
||||
# Network-wide ad blocking via your own hardware.
|
||||
#
|
||||
# Dnsmasq config for Pi-hole's FTLDNS
|
||||
#
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY POPULATED BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
# #
|
||||
# IF YOU WISH TO CHANGE THE UPSTREAM SERVERS, CHANGE THEM IN: #
|
||||
# /etc/pihole/setupVars.conf #
|
||||
# #
|
||||
# ANY OTHER CHANGES SHOULD BE MADE IN A SEPARATE CONFIG FILE #
|
||||
# WITHIN /etc/dnsmasq.d/yourname.conf #
|
||||
###############################################################################
|
||||
|
||||
addn-hosts=/etc/pihole/local.list
|
||||
addn-hosts=/etc/pihole/custom.list
|
||||
|
||||
|
||||
localise-queries
|
||||
|
||||
|
||||
no-resolv
|
||||
|
||||
log-queries
|
||||
log-facility=/var/log/pihole/pihole.log
|
||||
|
||||
log-async
|
||||
cache-size=10000
|
||||
server=172.30.0.9
|
||||
server=2001:db9::a
|
||||
interface=eth0
|
||||
@@ -0,0 +1,42 @@
|
||||
# Pi-hole: A black hole for Internet advertisements
|
||||
# (c) 2021 Pi-hole, LLC (https://pi-hole.net)
|
||||
# Network-wide ad blocking via your own hardware.
|
||||
#
|
||||
# RFC 6761 config file for Pi-hole
|
||||
#
|
||||
# This file is copyright under the latest version of the EUPL.
|
||||
# Please see LICENSE file for your rights under this license.
|
||||
|
||||
###############################################################################
|
||||
# FILE AUTOMATICALLY POPULATED BY PI-HOLE INSTALL/UPDATE PROCEDURE. #
|
||||
# ANY CHANGES MADE TO THIS FILE AFTER INSTALL WILL BE LOST ON THE NEXT UPDATE #
|
||||
# #
|
||||
# CHANGES SHOULD BE MADE IN A SEPARATE CONFIG FILE #
|
||||
# WITHIN /etc/dnsmasq.d/yourname.conf #
|
||||
###############################################################################
|
||||
|
||||
# RFC 6761: Caching DNS servers SHOULD recognize
|
||||
# test, localhost, invalid
|
||||
# names as special and SHOULD NOT attempt to look up NS records for them, or
|
||||
# otherwise query authoritative DNS servers in an attempt to resolve these
|
||||
# names.
|
||||
server=/test/
|
||||
server=/localhost/
|
||||
server=/invalid/
|
||||
|
||||
# The same RFC requests something similar for
|
||||
# 10.in-addr.arpa. 21.172.in-addr.arpa. 27.172.in-addr.arpa.
|
||||
# 16.172.in-addr.arpa. 22.172.in-addr.arpa. 28.172.in-addr.arpa.
|
||||
# 17.172.in-addr.arpa. 23.172.in-addr.arpa. 29.172.in-addr.arpa.
|
||||
# 18.172.in-addr.arpa. 24.172.in-addr.arpa. 30.172.in-addr.arpa.
|
||||
# 19.172.in-addr.arpa. 25.172.in-addr.arpa. 31.172.in-addr.arpa.
|
||||
# 20.172.in-addr.arpa. 26.172.in-addr.arpa. 168.192.in-addr.arpa.
|
||||
# Pi-hole implements this via the dnsmasq option "bogus-priv" (see
|
||||
# 01-pihole.conf) because this also covers IPv6.
|
||||
|
||||
# OpenWRT furthermore blocks bind, local, onion domains
|
||||
# see https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob_plain;f=package/network/services/dnsmasq/files/rfc6761.conf;hb=HEAD
|
||||
# and https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml
|
||||
# We do not include the ".local" rule ourselves, see https://github.com/pi-hole/pi-hole/pull/4282#discussion_r689112972
|
||||
server=/bind/
|
||||
server=/onion/
|
||||
@@ -0,0 +1,155 @@
|
||||
# PowerShell counterpart to validate-config.sh
|
||||
# Run this in a PowerShell session; it will perform the same checks.
|
||||
|
||||
param(
|
||||
[string]$BaselineFile = "docker-compose.lock.yml"
|
||||
)
|
||||
|
||||
function Assert-Error($msg) {
|
||||
Write-Error $msg
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (Get-Command docker -ErrorAction SilentlyContinue) {
|
||||
Write-Host "[validate-config] generating normalized compose manifest"
|
||||
docker compose config | Set-Content -Path generated.yml -Encoding utf8
|
||||
if (Test-Path $BaselineFile) {
|
||||
Write-Host "[validate-config] comparing against baseline $BaselineFile"
|
||||
$diff = Compare-Object -ReferenceObject (Get-Content $BaselineFile) -DifferenceObject (Get-Content generated.yml) -SyncWindow 0
|
||||
if ($diff) {
|
||||
Write-Host "[validate-config] configuration drift detected!"
|
||||
Assert-Error "Please review and, if the change is intentional, update $BaselineFile."
|
||||
}
|
||||
Write-Host "[validate-config] docker-compose.yml matches baseline"
|
||||
} else {
|
||||
Write-Host "[validate-config] baseline file not found, creating $BaselineFile"
|
||||
Copy-Item generated.yml $BaselineFile
|
||||
Write-Host "[validate-config] please commit $BaselineFile to the repository"
|
||||
}
|
||||
} else {
|
||||
Write-Host "[validate-config] docker binary not found; skipping compose validation"
|
||||
}
|
||||
|
||||
# CoreDNS check
|
||||
if (Get-Command coredns -ErrorAction SilentlyContinue) {
|
||||
Write-Host "[validate-config] checking PopuraDNS/Corefile with local coredns"
|
||||
coredns -conf PopuraDNS/Corefile -dns.port=0
|
||||
$canCheckCorefile = $true
|
||||
} elseif (Get-Command docker -ErrorAction SilentlyContinue) {
|
||||
Write-Host "[validate-config] checking PopuraDNS/Corefile with container"
|
||||
docker run --rm -v "${PWD}/PopuraDNS/Corefile:/etc/coredns/Corefile:ro" `
|
||||
coredns/coredns:latest -conf /etc/coredns/Corefile -dns.port=0
|
||||
$canCheckCorefile = $true
|
||||
} else {
|
||||
Write-Host "[validate-config] cannot check Corefile syntax (no coredns or docker)"
|
||||
$canCheckCorefile = $false
|
||||
}
|
||||
|
||||
# ensure onion and i2p zones are present in Corefile
|
||||
if ($canCheckCorefile) {
|
||||
foreach ($zone in @('onion.:53','i2p.:53','eth.:53','bit.:53','alt.:53','loki.:53','zil.:53','web3.:53','exit.:53','onion4.:53','onion6.:53')) {
|
||||
if (-not (Select-String -Path PopuraDNS/Corefile -Pattern $zone -Quiet)) {
|
||||
Assert-Error "[validate-config] error: Corefile missing $zone block"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# verify i2pd DNS server is enabled in its config
|
||||
if (Select-String -Path 'i2pd_yggdrasil_docker/src/i2pd.conf' -Pattern '\[dns\]' -Quiet) {
|
||||
$dnsSection = Select-String -Path 'i2pd_yggdrasil_docker/src/i2pd.conf' -Pattern 'enabled' -Context 0,1 | Where-Object { $_.Line -match 'true' }
|
||||
if (-not $dnsSection) {
|
||||
Write-Host "[validate-config] warning: i2pd DNS section present but not enabled"
|
||||
}
|
||||
} else {
|
||||
Write-Host "[validate-config] warning: i2pd.conf missing [dns] section"
|
||||
}
|
||||
|
||||
# tor config should contain DNSPort
|
||||
if (-not (Select-String -Path 'tor_yggdrasil_docker/torrc' -Pattern '^DNSPort' -Quiet)) {
|
||||
Write-Host "[validate-config] warning: torrc does not specify DNSPort; onion DNS will not work"
|
||||
}
|
||||
|
||||
# optional live DNS smoke queries (requires dig)
|
||||
if (Get-Command dig -ErrorAction SilentlyContinue) {
|
||||
Write-Host "[validate-config] performing live DNS query for .onion via CoreDNS"
|
||||
$res = dig @10.5.0.4 -p 53 facebookcorewwwi.onion +short
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Assert-Error "[validate-config] onion query failed"
|
||||
}
|
||||
Write-Host "[validate-config] performing live DNS query for .i2p via CoreDNS"
|
||||
$res = dig @10.5.0.4 -p 53 stats.i2p +short
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Assert-Error "[validate-config] i2p query failed"
|
||||
}
|
||||
}
|
||||
|
||||
# ensure referenced secrets exist
|
||||
foreach ($s in @("./secrets/tz.txt", "./secrets/YGGDRASIL_GENERATE_KEYS.txt")) {
|
||||
if (-not (Test-Path $s)) {
|
||||
Assert-Error "[validate-config] error: secret file $s is missing"
|
||||
}
|
||||
}
|
||||
|
||||
# check for :latest tags
|
||||
if (Select-String -Path docker-compose.yml -Pattern 'image: .*:latest' -Quiet) {
|
||||
Write-Host "[validate-config] warning: some services use the ':latest' image tag;" `
|
||||
"pin to a specific version before deploying to production."
|
||||
}
|
||||
|
||||
# warn if no healthchecks defined
|
||||
if (-not (Select-String -Path docker-compose.yml -Pattern 'healthcheck:' -Quiet)) {
|
||||
Write-Host "[validate-config] warning: no healthcheck definitions found in docker-compose.yml"
|
||||
}
|
||||
|
||||
Write-Host "[validate-config] warning: some services use the ':latest' image tag;" `
|
||||
"pin to a specific version before deploying to production."
|
||||
}
|
||||
|
||||
# verify restart policies exist
|
||||
if (-not (Select-String -Path docker-compose.yml -Pattern 'restart:' -Quiet)) {
|
||||
Write-Host "[validate-config] warning: some services lack a restart policy."
|
||||
}
|
||||
|
||||
# detect duplicate host ports
|
||||
$ports = Select-String -Path docker-compose.yml -Pattern ':[0-9]+:' -AllMatches | ForEach-Object { $_.Matches } | ForEach-Object { $_.Value.Trim(':') } | Sort-Object
|
||||
$dups = $ports | Group-Object | Where-Object { $_.Count -gt 1 } | Select-Object -ExpandProperty Name
|
||||
if ($dups) {
|
||||
Write-Host "[validate-config] warning: duplicate host port mappings detected: $($dups -join ' ')"
|
||||
}
|
||||
|
||||
# unbound configuration syntax check
|
||||
if (Get-Command unbound-checkconf -ErrorAction SilentlyContinue) {
|
||||
Write-Host "[validate-config] checking unbound configuration locally"
|
||||
unbound-checkconf -c unbound/unbound.conf
|
||||
} elseif (Get-Command docker -ErrorAction SilentlyContinue) {
|
||||
Write-Host "[validate-config] checking unbound configuration in container"
|
||||
docker run --rm -v "${PWD}/unbound/unbound.conf:/etc/unbound/unbound.conf:ro" `
|
||||
mvance/unbound:latest unbound-checkconf -c /etc/unbound/unbound.conf
|
||||
} else {
|
||||
Write-Host "[validate-config] cannot check unbound config (no unbound-checkconf or docker)"
|
||||
}
|
||||
|
||||
# basic 3proxy config sanity
|
||||
foreach ($cfg in @('3proxy/first-instanse.cfg','3proxy/second-instanse.cfg')) {
|
||||
if (-not (Test-Path $cfg)) {
|
||||
Assert-Error "[validate-config] error: missing 3proxy config $cfg"
|
||||
}
|
||||
if (-not (Select-String -Path $cfg -Pattern 'socks|proxy' -Quiet)) {
|
||||
Write-Host "[validate-config] warning: $cfg does not contain socks/proxy directives"
|
||||
}
|
||||
}
|
||||
|
||||
# simple sanity checks
|
||||
if (Select-String -Path docker-compose.yml -Pattern 'container_name: darkproxy' -Quiet) {
|
||||
Write-Host "[validate-config] warning: 'container_name: darkproxy' appears in compose; this may" `
|
||||
"conflict with network or project name."
|
||||
}
|
||||
|
||||
if (Select-String -Path docker-compose.yml -Pattern 'PIHOLE_DNS_' -Quiet) {
|
||||
if (Select-String -Path docker-compose.yml -Pattern 'PIHOLE_DNS_:' -Quiet) {
|
||||
Write-Host "[validate-config] warning: PIHOLE_DNS_ variable ends with underscore;" `
|
||||
"consider using PIHOLE_DNS_1, PIHOLE_DNS_2 etc."
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "[validate-config] all validations passed"
|
||||
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env bash
|
||||
# Utility to validate the Compose file and other service configurations.
|
||||
# Intended to be run locally or in CI; it exits non-zero on any failure.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BASELINE_FILE="docker-compose.lock.yml"
|
||||
TEMP_FILE=$(mktemp)
|
||||
|
||||
# validate docker-compose configuration if Docker is present
|
||||
if command -v docker >/dev/null 2>&1; then
|
||||
echo "[validate-config] generating normalized compose manifest"
|
||||
docker compose config > "$TEMP_FILE"
|
||||
|
||||
if [ -f "$BASELINE_FILE" ]; then
|
||||
echo "[validate-config] comparing against baseline $BASELINE_FILE"
|
||||
if ! diff -u "$BASELINE_FILE" "$TEMP_FILE"; then
|
||||
echo "[validate-config] configuration drift detected!"
|
||||
echo "Please review and, if the change is intentional, update $BASELINE_FILE."
|
||||
exit 1
|
||||
fi
|
||||
echo "[validate-config] docker-compose.yml matches baseline"
|
||||
else
|
||||
echo "[validate-config] baseline file not found, creating $BASELINE_FILE"
|
||||
cp "$TEMP_FILE" "$BASELINE_FILE"
|
||||
echo "[validate-config] please commit $BASELINE_FILE to the repository"
|
||||
fi
|
||||
else
|
||||
echo "[validate-config] docker binary not found; skipping compose validation"
|
||||
fi
|
||||
|
||||
# CoreDNS syntax check (use local binary or container fallback)
|
||||
if command -v coredns >/dev/null 2>&1; then
|
||||
echo "[validate-config] checking PopuraDNS/Corefile with local coredns"
|
||||
coredns -conf PopuraDNS/Corefile -dns.port=0
|
||||
elif command -v docker >/dev/null 2>&1; then
|
||||
echo "[validate-config] checking PopuraDNS/Corefile with container"
|
||||
docker run --rm -v "${PWD}/PopuraDNS/Corefile:/etc/coredns/Corefile:ro" \
|
||||
coredns/coredns:latest -conf /etc/coredns/Corefile -dns.port=0
|
||||
else
|
||||
echo "[validate-config] cannot check Corefile syntax (no coredns or docker)"
|
||||
fi
|
||||
|
||||
# ensure onion and i2p zones are present in Corefile
|
||||
for zone in "onion.:53" "i2p.:53" "eth.:53" "bit.:53" "alt.:53" "loki.:53" "zil.:53" "web3.:53" "exit.:53" "onion4.:53" "onion6.:53"; do
|
||||
if ! grep -q "$zone" PopuraDNS/Corefile; then
|
||||
echo "[validate-config] error: Corefile missing $zone block" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# verify i2pd DNS server is enabled in its config
|
||||
if grep -q "\[dns\]" i2pd_yggdrasil_docker/src/i2pd.conf; then
|
||||
if ! awk '/\[dns\]/,/\[/{if($0~/enabled/ && $0~/true/) ok=1} END{exit !ok}' i2pd_yggdrasil_docker/src/i2pd.conf; then
|
||||
echo "[validate-config] warning: i2pd DNS section present but not enabled"
|
||||
fi
|
||||
else
|
||||
echo "[validate-config] warning: i2pd.conf missing [dns] section"
|
||||
fi
|
||||
|
||||
# tor configuration should expose DNSPort for onion resolution
|
||||
if ! grep -q '^DNSPort' tor_yggdrasil_docker/torrc; then
|
||||
echo "[validate-config] warning: torrc does not specify DNSPort; onion DNS will not work"
|
||||
fi
|
||||
|
||||
# optional live DNS smoke queries (requires dig)
|
||||
if command -v dig >/dev/null 2>&1; then
|
||||
echo "[validate-config] performing live DNS query for .onion via CoreDNS"
|
||||
if ! dig @10.5.0.4 -p 53 facebookcorewwwi.onion +short >/dev/null; then
|
||||
echo "[validate-config] onion query failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "[validate-config] performing live DNS query for .i2p via CoreDNS"
|
||||
if ! dig @10.5.0.4 -p 53 stats.i2p +short >/dev/null; then
|
||||
echo "[validate-config] i2p query failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ensure referenced secrets exist
|
||||
for s in ./secrets/tz.txt ./secrets/YGGDRASIL_GENERATE_KEYS.txt; do
|
||||
if [ ! -f "$s" ]; then
|
||||
echo "[validate-config] error: secret file $s is missing" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# check for :latest tags (discouraged in prod)
|
||||
if grep -qE 'image: .*:latest' docker-compose.yml; then
|
||||
echo "[validate-config] warning: some services use the ':latest' image tag;" \
|
||||
"pin to a specific version before deploying to production."
|
||||
fi
|
||||
|
||||
# warn if there are no healthchecks at all
|
||||
if ! grep -q 'healthcheck:' docker-compose.yml; then
|
||||
echo "[validate-config] warning: no healthcheck definitions found in docker-compose.yml"
|
||||
fi
|
||||
|
||||
echo "[validate-config] warning: some services use the ':latest' image tag;" \
|
||||
"pin to a specific version before deploying to production."
|
||||
fi
|
||||
|
||||
# verify every service has a restart policy
|
||||
if ! grep -q "restart:" docker-compose.yml; then
|
||||
echo "[validate-config] warning: some services lack a restart policy."
|
||||
fi
|
||||
|
||||
# detect duplicate host ports
|
||||
ports=$(grep -oP ':[0-9]+:' docker-compose.yml | tr -d ':' | sort)
|
||||
if [ -n "$(echo "$ports" | uniq -d)" ]; then
|
||||
echo "[validate-config] warning: duplicate host port mappings detected:" $(echo "$ports" | uniq -d)
|
||||
fi
|
||||
|
||||
# unbound configuration syntax check
|
||||
if command -v unbound-checkconf >/dev/null 2>&1; then
|
||||
echo "[validate-config] checking unbound configuration locally"
|
||||
unbound-checkconf -c unbound/unbound.conf
|
||||
elif command -v docker >/dev/null 2>&1; then
|
||||
echo "[validate-config] checking unbound configuration in container"
|
||||
docker run --rm -v "${PWD}/unbound/unbound.conf:/etc/unbound/unbound.conf:ro" \
|
||||
mvance/unbound:latest unbound-checkconf -c /etc/unbound/unbound.conf
|
||||
else
|
||||
echo "[validate-config] cannot check unbound config (no unbound-checkconf or docker)"
|
||||
fi
|
||||
|
||||
# very basic 3proxy config sanity
|
||||
for cfg in 3proxy/first-instanse.cfg 3proxy/second-instanse.cfg; do
|
||||
if [ ! -f "$cfg" ]; then
|
||||
echo "[validate-config] error: missing 3proxy config $cfg" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -qE 'socks|proxy' "$cfg"; then
|
||||
echo "[validate-config] warning: $cfg does not contain socks/proxy directives"
|
||||
fi
|
||||
done
|
||||
|
||||
# simple sanity checks
|
||||
if grep -q "container_name: darkproxy" docker-compose.yml; then
|
||||
echo "[validate-config] warning: 'container_name: darkproxy' appears in compose;" \
|
||||
"this may conflict with network or project name."
|
||||
fi
|
||||
|
||||
# ensure Pi-hole DNS environment is correctly formatted
|
||||
if grep -q "PIHOLE_DNS_" docker-compose.yml | grep -q "PIHOLE_DNS_:"; then
|
||||
echo "[validate-config] warning: PIHOLE_DNS_ variable ends with underscore;" \
|
||||
"consider using PIHOLE_DNS_1, PIHOLE_DNS_2 etc."
|
||||
fi
|
||||
|
||||
echo "[validate-config] all validations passed"
|
||||
Submodule
+1
Submodule tor_yggdrasil_docker added at 4e14ce6ed6
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
# Most of this is credited to
|
||||
# https://trac.torproject.org/projects/tor/wiki/doc/TransparentProxy
|
||||
# With a few minor edits
|
||||
|
||||
# to run iptables commands you need to be root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "Please run as root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### set variables
|
||||
# destinations you don't want routed through Tor
|
||||
_non_tor="192.168.1.0/24 192.168.0.0/24"
|
||||
|
||||
# get the UID that Tor runs as
|
||||
_tor_uid=$(docker exec -u tor tor id -u)
|
||||
|
||||
# Tor's TransPort
|
||||
_trans_port="9040"
|
||||
_dns_port="5353"
|
||||
|
||||
### set iptables *nat
|
||||
iptables -t nat -A OUTPUT -m owner --uid-owner $_tor_uid -j RETURN
|
||||
#iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports $_dns_port
|
||||
|
||||
# allow clearnet access for hosts in $_non_tor
|
||||
for _clearnet in $_non_tor 127.0.0.0/9 127.128.0.0/10; do
|
||||
iptables -t nat -A OUTPUT -d $_clearnet -j RETURN
|
||||
done
|
||||
|
||||
# redirect all other output to Tor's TransPort
|
||||
iptables -t nat -A OUTPUT -p tcp --syn -j REDIRECT --to-ports $_trans_port
|
||||
|
||||
### set iptables *filter
|
||||
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
# allow clearnet access for hosts in $_non_tor
|
||||
for _clearnet in $_non_tor 127.0.0.0/8; do
|
||||
iptables -A OUTPUT -d $_clearnet -j ACCEPT
|
||||
done
|
||||
|
||||
# allow only Tor output
|
||||
iptables -A OUTPUT -m owner --uid-owner $_tor_uid -j ACCEPT
|
||||
#iptables -A OUTPUT -j REJECT
|
||||
Reference in New Issue
Block a user