{"id":50769726,"url":"https://github.com/wilfried-tech/sidedns","last_synced_at":"2026-06-11T17:01:33.744Z","repository":{"id":363412889,"uuid":"1220065291","full_name":"Wilfried-Tech/sidedns","owner":"Wilfried-Tech","description":"SideDNS is a local DNS router and transparent HTTP/HTTPS proxy for developers.  It lets you map any domain name to any local service — and undo it completely when you're done. Route any domain to any local service. Instantly. Without touching your system.","archived":false,"fork":false,"pushed_at":"2026-06-08T20:51:21.000Z","size":84,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-08T21:14:35.740Z","etag":null,"topics":["cli","cross-platform","dev-tools","dns","gui","local-development","networking","proxy","rust","tauri"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Wilfried-Tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-24T14:04:45.000Z","updated_at":"2026-06-08T20:51:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Wilfried-Tech/sidedns","commit_stats":null,"previous_names":["wilfried-tech/sidedns"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Wilfried-Tech/sidedns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wilfried-Tech%2Fsidedns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wilfried-Tech%2Fsidedns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wilfried-Tech%2Fsidedns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wilfried-Tech%2Fsidedns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Wilfried-Tech","download_url":"https://codeload.github.com/Wilfried-Tech/sidedns/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wilfried-Tech%2Fsidedns/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34208761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","cross-platform","dev-tools","dns","gui","local-development","networking","proxy","rust","tauri"],"created_at":"2026-06-11T17:01:31.226Z","updated_at":"2026-06-11T17:01:33.229Z","avatar_url":"https://github.com/Wilfried-Tech.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SideDNS\n\n**Route any domain to any local service. Instantly. Without touching your system.**\n\n[![Platform](https://img.shields.io/badge/Platform-Windows_%7C_macOS_%7C_Linux-blue)](#platform-support)\n[![CI](https://github.com/Wilfried-Tech/sidedns/actions/workflows/ci.yml/badge.svg)](https://github.com/Wilfried-Tech/sidedns/actions/workflows/ci.yml)\n[![Release](https://github.com/Wilfried-Tech/sidedns/actions/workflows/release.yml/badge.svg)](https://github.com/Wilfried-Tech/sidedns/actions/workflows/release.yml)\n[![Crates.io](https://img.shields.io/crates/v/sidedns?logo=rust)](https://crates.io/crates/sidedns)\n[![Crates.io Downloads](https://img.shields.io/crates/d/sidedns)](https://crates.io/crates/sidedns)\n[![docs.rs](https://img.shields.io/docsrs/sidedns-core?logo=docs.rs\u0026label=docs.rs)](https://docs.rs/sidedns-core)\n[![License](https://img.shields.io/badge/License-MIT-green)](LICENSE)\n\n*Stop editing `/etc/hosts`. Stop hardcoding ports. Stop breaking your DNS when you close the terminal.*\n\n---\n\n## What is SideDNS?\n\nSideDNS is a local DNS router and transparent HTTP/HTTPS proxy for developers.  \nIt lets you map any domain name to any local service — and undo it completely when you're done.\n\n```bash\nsidedns add api.myapp.com --port 3000\n# → api.myapp.com now resolves to your local server, system-wide, instantly\n\nsidedns daemon stop\n# → everything reverts. no residue. your machine is exactly as you left it.\n```\n\nNo permanent config changes. No manual cleanup. No broken DNS after a crash.\n\n---\n\n## Why SideDNS?\n\n| Problem | Common workaround | SideDNS |\n| ------- | ----------------- | ------- |\n| Test a local API as `api.prod.com` | Edit `/etc/hosts` manually | `sidedns add api.prod.com --port 3000` |\n| Multiple services with real domain names | Per-app proxy configs | One daemon, system-wide |\n| HTTPS locally with a real certificate | Self-sign manually, fight the browser | `sidedns cert install --trust` + `--https` |\n| Clean up when done | Remember to undo everything | `sidedns daemon stop` undoes everything |\n| One command to launch + route | Two terminals, manual wiring | `sidedns run -d api.local fastapi dev` |\n\n---\n\n## Features\n\n- **Transparent DNS routing** — rules apply system-wide, to every app on the machine\n- **HTTP \u0026 HTTPS proxy** — TLS termination with on-demand signed certificates\n- **WebSocket support** — upgrades are tunneled transparently\n- **Ephemeral rules** — `sidedns run` creates a rule for the lifetime of a command, then removes it\n- **Wildcard domains** — `*.myapp.local` matches all subdomains\n- **Auto port detection** — `sidedns run` can detect which port your process opened\n- **Daemon lifecycle** — background process, PID-managed, graceful shutdown\n- **Watch mode** — `sidedns watch` streams rule changes in real time\n- **Live event stream** — `sidedns watch` streams rule changes in real time\n- **Safe by design** — warns before routing public domains, `sidedns clean` removes any residue\n- **Cross-platform** — Windows, macOS, Linux\n\n---\n\n## Architecture\n\n```text\n┌───────────────────────────────────────────────────────┐\n│                    sidedns daemon                     │\n│                                                       │\n│  ┌──────────────┐  ┌───────────────┐  ┌───────────┐   │\n│  │  DNS Server  │  │  HTTP/HTTPS   │  │    IPC    │   │\n│  │ 127.0.53.53  │  │  Proxy :80    │  │  Server   │   │\n│  │    port 53   │  │  \u0026 :443       │  │           │   │\n│  └──────┬───────┘  └──────┬────────┘  └─────┬─────┘   │\n│         │                 │                 │         │\n│         └─────────────────┴────────────────►│         │\n│                                        SharedState    │\n│                                        (RuleStore)    │\n└───────────────────────────────────────────────────────┘\n         ▲                                    ▲\n         │ DNS queries                        │ IPC commands\n    System DNS                          CLI / GUI\n    (all apps)                    sidedns add / remove / ...\n```\n\nThe daemon runs a DNS server, a reverse proxy, and an IPC server — all sharing the same rule store via a lock-free arc-swap structure. CLI and GUI communicate exclusively through IPC.\n\nDNS returns the proxy IP (`127.0.0.42`), not the target service IP directly. This is necessary because DNS has no concept of ports — the proxy bridges the gap.\n\nRules are stored in a lock-free [arc-swap](https://crates.io/crates/arc-swap) structure. DNS and proxy reads never block, even during writes.\n\n### Ephemeral vs persistent rules\n\n| | Persistent | Ephemeral |\n| ----- | --------- | --------- |\n| Created by | `sidedns add` | `sidedns run` |\n| Survives restart | Yes | No |\n| Removed by | `sidedns remove` | Command exit / crash |\n| Priority | Normal | Higher (shadows persistent rules) |\n\n---\n\n## Installation\n\n### cargo install\n\n```bash\ncargo install sidedns\n```\n\n### Pre-built binaries\n\nDownload the latest binary for your platform from the [Releases](https://github.com/Wilfried-Tech/sidedns/releases) page.\n\n| Platform | File |\n| -------- | ---- |\n| Linux x86_64 (glibc) | `sidedns-vX.Y.Z-x86_64-unknown-linux-gnu.tar.gz` |\n| Linux x86_64 (musl) | `sidedns-vX.Y.Z-x86_64-unknown-linux-musl.tar.gz` |\n| Linux ARM64 | `sidedns-vX.Y.Z-aarch64-unknown-linux-gnu.tar.gz` |\n| macOS Intel | `sidedns-vX.Y.Z-x86_64-apple-darwin.tar.gz` |\n| macOS Apple Silicon | `sidedns-vX.Y.Z-aarch64-apple-darwin.tar.gz` |\n| Windows x86_64 | `sidedns-vX.Y.Z-x86_64-pc-windows-msvc.zip` |\n\nEach archive includes a `.sha256` checksum file.\n\n### From source\n\n```bash\ngit clone https://github.com/Wilfried-Tech/sidedns\ncd sidedns\ncargo build --release\n```\n\nThe `sidedns` binary is in `target/release/`.\n\n### Platform requirements\n\n| OS | Required |\n| -- | -------- |\n| Linux | `systemd-resolved` or compatible |\n| macOS | macOS 12+ |\n| Windows | Windows 10+ (PowerShell, admin for DNS config) |\n\n---\n\n## Quick Start\n\n```bash\n# 1. Start the daemon (background by default)\nsidedns daemon start\n\n# 2. Add a rule\nsidedns add api.local --port 3000\n\n# 3. Your service at localhost:3000 is now reachable at http://api.local\ncurl http://api.local/health\n\n# 4. Done for the day\nsidedns daemon stop\n```\n\n---\n\n## Command Reference\n\n### `sidedns daemon`\n\nManage the background daemon process.\n\n```bash\nsidedns daemon start            # start in background (default)\nsidedns daemon start --no-background   # run in foreground (for debugging)\nsidedns daemon stop             # graceful shutdown + revert DNS config\n```\n\n### `sidedns add`\n\nAdd or replace a DNS routing rule.\n\n```bash\nsidedns add \u003cdomain\u003e [options]\n\nOptions:\n  -i, --ip \u003cIP\u003e      Target IP address  [default: 127.0.0.1]\n  -p, --port \u003cPORT\u003e  Target port        [default: 80]\n      --https        Enable HTTPS TLS proxy for this rule\n```\n\n```bash\n# Basic HTTP rule\nsidedns add api.local --port 3000\n\n# With a specific IP\nsidedns add db.internal --ip 192.168.1.10 --port 5432\n\n# HTTPS with TLS termination (requires cert install)\nsidedns add secure.local --port 4000 --https\n\n# Wildcard — matches all subdomains\nsidedns add \"*.myapp.local\" --port 8080\n```\n\n### `sidedns remove`\n\nRemove a routing rule.\n\n```bash\nsidedns remove api.local\n```\n\n### `sidedns list`\n\nList all active routing rules (persistent and ephemeral).\n\n```bash\nsidedns list\n```\n\n```text\nDOMAIN                    IP                 PORT          SECURE\napi.local                 127.0.0.1          3000          no\nsecure.local              127.0.0.1          4000          yes\n*.myapp.local             127.0.0.1          8080          no\n```\n\n### `sidedns resolve`\n\nResolve a domain to its configured target.\n\n```bash\nsidedns resolve api.local\n# → api.local → 127.0.0.1:3000\n```\n\n### `sidedns run`\n\nRun a command with an ephemeral DNS rule active for its lifetime.  \nThe rule is created before the command starts and removed when it exits — even on crash.\n\n```bash\nsidedns run -d \u003cdomain\u003e [--ip IP] [--port PORT] [--https] -- \u003ccommand\u003e [args...]\n```\n\n```bash\n# Auto-detect port after launch\nsidedns run -d api.local -- npm run dev\n\n# Explicit port\nsidedns run -d api.local --port 3000 -- cargo run\n\n# HTTPS proxy\nsidedns run -d secure.local --port 4000 --https -- python -m uvicorn app:app\n\n# Works with any command\nsidedns run -d backend.test --port 8080 -- ./my-server\n```\n\n**Port auto-detection**: if `--port` is omitted, SideDNS waits for your process to open a port and configures the rule automatically. If multiple ports are opened, it prompts you to choose.\n\n### `sidedns status`\n\nShow whether the daemon is running and how many rules are active.\n\n```bash\nsidedns status\n# daemon: running\n# rules:  3\n```\n\n### `sidedns watch`\n\nStream rule changes to stdout in real time. Useful for scripting or monitoring.\n\n```bash\nsidedns watch\n```\n\n### `sidedns cert`\n\nManage the root CA certificate used for HTTPS proxying.\n\n```bash\n# Generate the CA (if not already done) and install it\nsidedns cert install\n\n# Generate + install + trust in all stores (requires admin)\nsidedns cert install --trust\n\n# Trust in specific stores\nsidedns cert trust --system\nsidedns cert trust --nss        # Firefox + Chrome on Linux\nsidedns cert trust --java       # Java keystore via keytool\n\n# Remove from all trust stores\nsidedns cert untrust\n\n# Untrust in specific stores\nsidedns cert untrust [--system | --nss | --java]\n\n# Uninstall the CA files entirely\nsidedns cert uninstall\n```\n\n### `sidedns clean`\n\nRemove any residual DNS configuration that may have been left behind by a previous crash or incomplete shutdown.\n\n```bash\nsidedns clean\n```\n\nRun this if DNS resolution seems broken after an unexpected daemon termination.\n\n---\n\n## HTTPS Support\n\nSideDNS can terminate TLS for your local services, giving them a valid HTTPS certificate that browsers trust.\n\n### How it works\n\n1. SideDNS generates a local root CA and stores it in your data directory\n2. You install and trust it once with `sidedns cert install --trust`\n3. For each rule with `--https`, SideDNS signs a certificate on demand using that CA\n4. The HTTPS proxy listens on `:443`, terminates TLS, and forwards plain HTTP to your service\n5. Browsers see a valid certificate — no warnings\n\n### Setup\n\n```bash\n# Requires admin/sudo\nsudo sidedns cert install --trust\n```\n\nFirefox users: Firefox uses its own certificate store, independent of the system.\n\n```bash\n# Trust in Firefox/Chrome (Linux, via certutil)\nsudo sidedns cert trust --nss\n```\n\nFirefox manual trust (all platforms):  \n`Settings → Privacy \u0026 Security → View Certificates → Authorities → Import → select the CA file`  \nThe CA file is at the path shown by `sidedns cert install`.\n\n### Supported trust stores\n\n| Store | Tool used | Platforms |\n| ----- | --------- | --------- |\n| System | `security` / `certutil` / distro tools | macOS, Windows, Linux |\n| NSS (Firefox, Chrome) | `certutil` (libnss3-tools) | Linux, macOS |\n| Java | `keytool` | All (requires JDK) |\n\n---\n\n## Domain Safety\n\nSideDNS accepts any valid domain name — there are no hard restrictions.\n\nThis is intentional: developers sometimes need to shadow real domains for integration testing, service mocking, or infrastructure simulation.\n\n**However**, routing a real public domain (like `api.stripe.com`) through SideDNS means **every application on your machine** — not just your browser — will resolve that domain to your local service while the daemon is running. This includes CLI tools, package managers, background services, and anything else making network calls.\n\nSideDNS surfaces a clear warning when you add a rule for a domain that appears to be a real public domain, and asks for explicit confirmation. For domains that are clearly local (`.local`, `.test`, `.internal`, `.localhost`, `.example`), no confirmation is required.\n\nIf the daemon stops unexpectedly, run `sidedns clean` to ensure no stale DNS configuration remains.\n\n---\n\n## Platform Support\n\n### DNS configuration strategy\n\nSideDNS uses **split DNS** — it routes only the domains you configure through its local resolver, leaving all other DNS traffic untouched. This makes it compatible with VPNs and other DNS tools running simultaneously.\n\n| Platform | Mechanism | Admin required |\n| ----- | --------- | --------- |\n| Linux | `systemd-resolved` drop-in config | Yes (for DNS config) |\n| macOS | `/etc/resolver/\u003cdomain\u003e` files | Yes (for DNS config) |\n| Windows | NRPT (Name Resolution Policy Table) | Yes (for DNS config) |\n\nThe daemon itself runs as a regular user process. Only the DNS system configuration step requires elevated privileges, performed at `daemon start` and reverted at `daemon stop`.\n\n### VPN compatibility\n\nBecause SideDNS uses split DNS (not global DNS replacement), it is compatible with most VPN setups. Your VPN's DNS configuration handles its own namespaces; SideDNS only intercepts the domains you explicitly configure.\n\n---\n\n## How It Works Internally\n\n### DNS resolution flow\n\n```plain\nApplication makes DNS query for \"api.local\"\n    ↓\nSystem DNS → split DNS routes \"api.local\" to SideDNS (127.0.53.53:53)\n    ↓\nSideDNS DNS server: rule found → returns 127.0.0.42 (proxy address)\nSideDNS DNS server: no rule → forwards to upstream DNS (your real resolver)\n    ↓\nApplication connects to 127.0.0.42:80 or :443\n    ↓\nSideDNS proxy: reads Host header → looks up rule → forwards to target ip:port\n```\n\n### Rule store\n\nRules are stored in a lock-free arc-swap structure. Reads (DNS server, HTTP proxy) are non-blocking and never contend with writes. Writes (IPC add/remove) clone and atomically swap the rule set.\n\nPersistent rules survive daemon restarts (stored via `confy`). Ephemeral rules (`sidedns run`) exist only in memory.\n\n---\n\n## Contributing\n\nPRs and issues welcome. The codebase is structured as a Cargo workspace:\n\n```text\nsidedns/\n├── core/       # daemon logic: DNS, proxy, IPC, certs, rule store\n└── cli/        # CLI binary + command handlers\n```\n\nRun tests:\n\n```bash\ncargo test -p sidedns-core\ncargo test -p sidedns-cli\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\nIssues and PRs are welcome. Please open an issue before starting work on a significant feature.\n\n---\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilfried-tech%2Fsidedns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwilfried-tech%2Fsidedns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilfried-tech%2Fsidedns/lists"}