Files
auto-ci d66f208f0e
Configuration validation / lint (push) Has been cancelled
Configuration validation / smoke (push) Has been cancelled
feat(namecoin): switch .bit resolution to true on-chain via local namecoind RPC
2026-03-01 22:47:32 -05:00

257 lines
9.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Welcome to darkproxy...
## Production hardening defaults
The stack now uses safer defaults for production:
* Sensitive passwords are loaded from Docker secrets instead of inline values.
* Admin/monitoring ports are bound to `127.0.0.1` on the host.
* 3proxy now requires authentication (`auth strong`).
Before starting in production, set these secret files:
```sh
printf 'proxyuser:CL:YOUR_STRONG_PROXY_PASSWORD\n' > secrets/3proxy_users.txt
printf 'YOUR_STRONG_PIHOLE_PASSWORD\n' > secrets/pihole_webpassword.txt
printf 'YOUR_STRONG_GRAFANA_PASSWORD\n' > secrets/grafana_admin_password.txt
```
SOCKS clients must now authenticate to 3proxy with credentials from
`secrets/3proxy_users.txt`.
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 local ensdns service
docker run --rm --network darkproxy infoblox/dig dig @10.5.0.4 vitalik.eth
# ENS address/content hash records (TXT)
docker run --rm --network darkproxy infoblox/dig dig @10.5.0.4 TXT 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.
### Host-side quick tests (no extra images)
Run DNS queries from your host by executing `dig` in the existing `darkpihole`
container:
```sh
docker exec darkpihole dig @10.5.0.4 TXT vitalik.eth +short
docker exec darkpihole dig @10.5.0.4 A vitalik.eth +short
```
Expected behavior:
* `TXT` includes `address=` and (if present) `contenthash=`.
* `A` returns a CNAME fallback like `<name>.eth.limo.`.
## 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` | ensdns (10.5.0.11) via CoreDNS | Ethereum Name Service (local resolver) |
| `.bit` | namecoindns (10.5.0.12) via CoreDNS | Namecoin names (local resolver service) |
| `.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.
## Local ENS (.eth) client
If you want to resolve Ethereum ENS names locally from the host, use the
standalone client script:
```sh
python3 -m venv .venv-ens
source .venv-ens/bin/activate
pip install -r scripts/requirements-ens.txt
python3 scripts/resolve_ens.py vitalik.eth --pretty
```
Options:
* `--rpc <url>` to set a custom Ethereum JSON-RPC endpoint.
* `--include-text` to include common ENS text records.
Example:
```sh
python3 scripts/resolve_ens.py ens.eth --include-text --pretty
```
## Local Namecoin (.bit) resolver (true on-chain)
`.bit` lookups are routed through a local blockchain-backed resolver path:
* CoreDNS forwards `bit.:53` to `10.5.0.12:53` (`namecoindns`).
* `namecoindns` queries local `namecoind` JSON-RPC (`10.5.0.13:8336`).
* `namecoind` syncs the Namecoin blockchain and serves on-chain records.
Quick test:
```sh
docker exec darkpihole dig @10.5.0.4 A id.bit
docker exec darkpihole dig @10.5.0.4 TXT id.bit
```
If your environment returns `NXDOMAIN` for `.bit`, configure Namecoin-capable
records in Namecoin itself and wait for local `namecoind` sync completion.
> **Important:** initial blockchain sync can take significant time. During sync,
> `.bit` responses may be empty or incomplete.
## 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 dont 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 DockerinDocker service and
waits for each containers 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.