Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/razvandimescu/numa
Encryption/Decryption ToolsDNS & Subdomain EnumerationNetwork SecurityPrivacyDNS FuzzingDNS Analysis
GitHubrazvandimescu/numa

numa

Rust로 작성된 휴대용 DNS 리졸버 — .numa 로컬 도메인, 광고 차단, 개발자 오버라이드

저장소 보기
1.4k101713일 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
# Numa

[![CI](https://github.com/razvandimescu/numa/actions/workflows/ci.yml/badge.svg)](https://github.com/razvandimescu/numa/actions)
[![crates.io](https://img.shields.io/crates/v/numa.svg)](https://crates.io/crates/numa)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

**당신이 소유하는 DNS. 어디를 가든.** — [numa.rs](https://numa.rs)

단일 바이너리로 동작하는 휴대용 DNS 리졸버. 어떤 네트워크에서든 광고를 차단하고, 로컬 서비스에 이름을 붙이고(`frontend.numa`), 자동 복원 기능으로 어떤 호스트명이든 재정의하며, 모든 아웃바운드 쿼리를 **ODoH (RFC 9230)** 로 봉인하여 누가 당신인지와 무엇을 물었는지를 단일 주체가 동시에 볼 수 없게 합니다 — 모두 노트북에서, 클라우드 계정이나 라즈베리 파이 없이 가능합니다.

Rust로 처음부터 직접 구현했습니다. DNS 라이브러리는 전혀 사용하지 않았습니다. 캐싱, 광고 차단, 로컬 서비스 도메인을 기본 제공합니다. 선택적으로 루트 네임서버로부터의 재귀 해석과 완전한 DNSSEC 신뢰 체인 검증, 그리고 암호화된 클라이언트 연결(iOS Private DNS, systemd-resolved 등)을 위한 DNS-over-TLS 리스너를 제공합니다. `numa relay`를 실행하면 동일한 바이너리가 공용 ODoH 엔드포인트가 됩니다 — 현재 큐레이션된 DNSCrypt 목록에는 살아남은 릴레이가 하나뿐이므로, 모든 Numa 배포는 생태계를 실질적으로 확장합니다. 약 8MB 바이너리 하나에 모든 것이 내장되어 있습니다. 와이어 프로토콜 파서는 학습 프로젝트로 손으로 작성했으며, 이후 기능(재귀 리졸버, DNSSEC, 대시보드)은 AI의 도움을 받아 구축했습니다.

![Numa dashboard](https://assets.kitploit.com/production/public/readmes/13090/5d6f10865bf168b1b4d4b8a8223ff961e66cfc2fe7f91754e71f105f2f921cc0.gif)

## 빠른 시작

세 가지 방법이 있으며, 부담이 적은 순서대로입니다. 세 번째만이 시스템 DNS를 변경합니다.

### 1. Docker에서 사용해 보기 (호스트에 아무것도 설치하지 않음)

```bash
docker run -d --name numa -p 127.0.0.1:5553:53/udp -p 127.0.0.1:5553:53/tcp \
  -p 127.0.0.1:5380:5380 ghcr.io/razvandimescu/numa
dig @127.0.0.1 -p 5553 example.com
docker exec numa numa token            # dashboard password
```

`http://localhost:5380`을 열고 아무 사용자명과 해당 토큰으로 로그인하세요. 포트 5553은 호스트에서 이미 53을 점유하고 있는 무엇이든 피해갑니다. 호스트가 DNS로 Numa를 사용하지 않으므로 여기서는 `numa.numa`가 해석되지 않습니다. `docker rm -f numa`로 정리하세요.

### 2. 포그라운드에서 실행 (시스템 DNS는 그대로 유지)

바이너리를 설치하세요:

```bash
# macOS
brew install razvandimescu/tap/numa

# Linux
curl -fsSL https://raw.githubusercontent.com/razvandimescu/numa/main/install.sh | sh

# Arch Linux
pacman -S numa

# Windows — download from GitHub Releases
# All platforms
cargo install numa

# Nix
nix run github:razvandimescu/numa
```

```bash
sudo numa                              # Ctrl-C to stop (port 53 requires root/admin)
```

Numa는 포트 53에서 수신하지만, `numa install`을 실행하기 전까지 시스템은 기존 리졸버를 유지하므로 `dig @127.0.0.1 example.com`으로 테스트하세요. 대시보드는 `http://localhost:5380`에 있습니다. 포트 53이 사용 중이라면(Ubuntu/Mint의 systemd-resolved), [`numa.toml`](https://github.com/razvandimescu/numa/blob/main/numa.toml)에서 `bind_addr`을 설정하거나 Docker를 사용하세요.

### 3. 시스템 DNS로 설정

| Platform | Install | Uninstall |
|----------|---------|-----------|
| macOS | `sudo numa install` | `sudo numa uninstall` |
| Linux | `sudo numa install` | `sudo numa uninstall` |
| Windows | `numa install` (admin) + reboot | `numa uninstall` (admin) + reboot |

`install`은 서비스를 등록하고, 시스템 DNS를 Numa로 지정하며, 로컬 CA를 신뢰하도록 설정합니다. `uninstall`은 이 세 가지를 모두 되돌립니다. 설치 후 대시보드는 **http://numa.numa**에서도 접근할 수 있습니다.

macOS와 Linux에서 numa는 시스템 서비스(launchd/systemd)로 실행됩니다. systemd 유닛은 비특권(`DynamicUser=yes`, `CAP_NET_BIND_SERVICE`만)으로 실행되며, launchd 데몬은 root로 실행됩니다. `numa install`은 `numa uninstall`이 제거하는 drop-in을 통해 systemd-resolved를 재구성합니다. 포트 53을 점유하는 다른 프로세스(dnsmasq, NetworkManager의 것 포함)는 수동으로 중지해야 합니다. Windows에서는 numa가 레지스트리를 통해 로그인 시 자동 시작됩니다. 또한 Windows는 `127.0.0.2:53`을 바인딩하고(내장 Dnscache가 `127.0.0.1:53`을 소유함) 쿼리를 이곳으로 라우팅하는 NRPT 규칙을 설치합니다 — 따라서 `bind_addr`/`api_bind_addr`은 `127.0.0.1`이 아니라 `127.0.0.2`를 기준으로 편집하세요.

### 로그인

루프백(`localhost`, `127.0.0.1`, `numa.numa`)에서는 로그인이 필요하지 않습니다. Docker 포트 매핑이나 이 머신의 LAN 주소를 포함한 그 외의 모든 경우에는 API 토큰을 요구하며, Numa가 첫 시작 시 생성합니다. `sudo numa token`(Windows에서는 관리자 셸)으로 출력하고 아무 사용자명으로 로그인하세요. `[server] api_token` 또는 `NUMA_API_TOKEN`으로 직접 지정할 수 있습니다.

### 모든 흔적 제거

`uninstall`은 DNS를 복원하지만 데이터 디렉터리는 유지하므로, 재설치 시 동일한 토큰과 CA가 유지됩니다. 모든 것을 제거하려면 먼저 uninstall한 후 다음을 삭제하세요:

| Platform | Left behind |
|----------|-------------|
| macOS | the binary, `/usr/local/var/numa`, `/usr/local/var/log/numa.log` |
| Linux | the binary (`/usr/local/bin/numa` from install.sh), `/var/lib/numa`, `/etc/numa` |
| Windows | the binary, `%PROGRAMDATA%\numa` |

패키지 관리자 설치의 경우 `brew uninstall`, `pacman -R` 또는 `cargo uninstall`로 바이너리를 제거합니다. Linux에서 `numa install`은 원래 위치(예: `~/.cargo/bin`)에서 실행할 수 없는 바이너리를 `/usr/local/bin/numa`로 복사하며, uninstall은 그 복사본을 남겨둡니다.

사용자 설정을 만들었다면 `~/.config/numa`도 삭제하고, `[server] data_dir` 경로를 설정했다면 그 경로도 삭제하세요.

## 로컬 서비스

포트 번호를 외우는 대신 개발 서비스에 이름을 붙이세요:

```bash
curl -X POST localhost:5380/services \
  -d '{"name":"frontend","target_port":5173}'
```

이제 브라우저에서 `https://frontend.numa`가 작동합니다 — 녹색 자물쇠, 유효한 인증서, HMR을 위한 WebSocket 패스스루. mkcert도, nginx도, `/etc/hosts`도 필요 없습니다.

경로 기반 라우팅(`app.numa/api → :5001`)을 추가하고, LAN 검색을 통해 여러 머신 간에 서비스를 공유하거나, [`numa.toml`](https://github.com/razvandimescu/numa/blob/main/numa.toml)에서 모든 것을 구성하세요.

## 광고 차단 및 개인정보 보호

[Hagezi Pro](https://github.com/hagezi/dns-blocklists)를 통한 광고 및 트래커 차단, 매일 갱신됩니다. 카페, 호텔, 공항 등 어떤 네트워크에서든 작동합니다. 노트북과 함께 이동합니다.

세 가지 해석 모드:

- **`forward`** (기본값) — 기존 시스템 DNS로의 투명 프록시. 모든 것이 이전과 동일하게 작동하며, 그 위에 캐싱과 광고 차단이 추가됩니다. 캡티브 포털, VPN, 기업 DNS — 모두 존중됩니다.
- **`recursive`** — 루트 네임서버로부터 직접 해석. 업스트림 의존성 없음, 어떤 단일 주체도 당신의 전체 쿼리 패턴을 볼 수 없습니다. 완전한 신뢰 체인 검증을 위해 `[dnssec] enabled = true`를 추가하세요.
- **`auto`** — 시작 시 루트 서버를 탐색하여, 도달 가능하면 재귀, 그렇지 않으면 Quad9(`https://9.9.9.9/dns-query`)로 DoH를 통한 포워딩을 하며, 이 경우 Quad9이 당신의 쿼리를 보게 됩니다. 다른 제공자를 선택하려면 자체 `[upstream]`과 함께 `forward`를 사용하세요.

DNSSEC는 완전한 신뢰 체인을 검증합니다: RRSIG 서명, DNSKEY 검증, DS 위임, NSEC/NSEC3 부인 증명. [작동 방식 읽기 →](https://numa.rs/blog/posts/dnssec-from-scratch.html)

**DNS-over-TLS 리스너** (RFC 7858) — iOS Private DNS, systemd-resolved, stubby 같은 엄격한 클라이언트로부터 포트 853에서 암호화된 쿼리를 수락합니다. 두 가지 모드:

- **자체 서명** (기본값) — numa가 로컬 CA를 자동으로 생성합니다. `numa install`은 macOS, Linux(Debian/Ubuntu, Fedora/RHEL/SUSE, Arch), Windows의 시스템 신뢰 저장소에 이를 추가하고, `numa uninstall`은 이를 제거합니다. iOS에서는 `numa setup-phone`의 `.mobileconfig`를 설치하세요. Firefox는 자체 NSS 저장소를 유지하고 시스템 저장소를 무시합니다 — Firefox에서 `.numa` 서비스에 HTTPS가 필요하면 해당 CA를 수동으로 신뢰하세요.
- **자체 인증서 사용** — `[dot] cert_path` / `key_path`를 공개적으로 신뢰되는 인증서(예: numa 인스턴스를 가리키는 도메인에 대한 DNS-01 챌린지를 통한 Let's Encrypt)로 지정하세요. 클라이언트는 신뢰 저장소 설정 없이 연결됩니다 — AdGuard Home이나 Cloudflare `1.1.1.1`과 동일한 UX입니다.

ALPN `"dot"`은 두 모드 모두에서 광고되고 강제됩니다. ALPN이 일치하지 않는 핸드셰이크는 교차 프로토콜 혼동 방어로 거부됩니다.

**Oblivious DoH** (RFC 9230) — `[upstream] mode = "odoh"`([레시피](https://github.com/razvandimescu/numa/blob/main/recipes/odoh-upstream.md))를 사용하면 각 쿼리가 대상에게 HPKE로 봉인되어 릴레이를 통해 전송됩니다. 릴레이는 당신의 IP와 암호문을 보고, 대상은 질문과 릴레이의 IP를 보며, 쿼리를 리디렉션하는 릴레이는 새 목적지에게 복호화할 수 없는 것을 넘겨줍니다. Numa는 동일한 등록 가능 도메인을 공유하는 릴레이와 대상을 거부합니다. ODoH는 이후에 당신이 여는 연결을 숨기지 않습니다: ISP는 여전히 목적지 IP를 보고, ECH가 없으면 TLS 핸드셰이크의 호스트명도 봅니다.

**휴대폰 설정** — iPhone 또는 Android를 한 단계로 Numa에 연결하세요:

```bash
numa setup-phone
```

QR 코드를 출력합니다. 스캔하고, 프로필을 설치하고, 인증서 신뢰를 토글하세요 — 이제 휴대폰의 DNS가 TLS를 통해 Numa로 라우팅됩니다. `numa.toml`에서 `[mobile] enabled = true`가 필요합니다.

## LAN 검색

여러 머신에서 Numa를 실행하세요. mDNS를 통해 자동으로 서로를 찾습니다:

```
Machine A (192.168.1.5)              Machine B (192.168.1.20)
┌──────────────────────┐             ┌──────────────────────┐
│ Numa                 │    mDNS     │ Numa                 │
│  - api (port 8000)   │◄───────────►│  - grafana (3000)    │
│  - frontend (5173)   │  discovery  │                      │
└──────────────────────┘             └──────────────────────┘
```

Machine B에서: `curl http://api.numa` → Machine A의 포트 8000으로 프록시됩니다. `numa lan on`으로 활성화하세요.

**허브 모드**: `bind_addr = "0.0.0.0:53"`으로 인스턴스 하나를 실행하고 다른 기기의 DNS를 이곳으로 지정하세요 — 아무것도 설치하지 않고 광고 차단 + `.numa` 해석을 얻습니다. `bind_addr`은 특정 인터페이스 하위 집합을 바인딩하기 위해 목록도 허용합니다. 단계별 안내: [네트워크 전체 레시피](https://github.com/razvandimescu/numa/blob/main/recipes/network-wide.md).

## Docker

```bash
# Recommended — host networking (Linux)
docker run -d --name numa --network host -v numa-data:/var/lib/numa ghcr.io/razvandimescu/numa

# Port mapping (macOS/Windows Docker Desktop)
docker run -d --name numa -p 53:53/udp -p 53:53/tcp -p 5380:5380 -v numa-data:/var/lib/numa ghcr.io/razvandimescu/numa
```

대시보드는 `http://localhost:5380`에 있습니다. 포트 매핑을 사용하거나 다른 기기에서 접근하는 경우, 아무 사용자명과 `docker exec numa numa token`의 토큰으로 로그인하세요. `numa-data` 볼륨은 컨테이너를 재생성해도 토큰과 로컬 CA를 유지합니다. 이미지는 기본적으로 API와 프록시를 `0.0.0.0`에 바인딩합니다. 사용자 정의 설정으로 재정의하세요:

```bash
docker run -d --name numa --network host -v numa-data:/var/lib/numa \
  -v /path/to/numa.toml:/root/.config/numa/numa.toml \
  ghcr.io/razvandimescu/numa
```

멀티 아키텍처: `linux/amd64` 및 `linux/arm64`.

턴키 compose 레시피:
- [`packaging/client/`](https://github.com/razvandimescu/numa/blob/main/packaging/client) — ODoH 클라이언트 모드(익명 DNS), Numa + 스타터 `numa.toml`.
- [`packaging/relay/`](https://github.com/razvandimescu/numa/blob/main/packaging/relay) — 공용 ODoH 릴레이, Numa + Caddy + ACME.

## 비교

| | Pi-hole | AdGuard Home | Unbound | Numa |
|---|---|---|---|---|
| Local service proxy + auto TLS | — | — | — | `.numa` domains, HTTPS, WebSocket |
| LAN service discovery | — | — | — | mDNS, zero config |
| Developer overrides (REST API) | — | — | — | Auto-revert, scriptable |
| Recursive resolver | — | — | Yes | Yes, with SRTT selection |
| DNSSEC validation | — | — | Yes | Yes (RSA, ECDSA, Ed25519) |
| Ad blocking | Yes | Yes | — | Hagezi Pro |
| Per-client rules | Groups | Yes | Views / tags | By CIDR (`[[client_policy]]`), config file only |
| Web admin UI | Full | Full | — | Dashboard |
| Encrypted upstream (DoH/DoT) | Needs cloudflared | DoH only | DoT only | DoH + DoT (`tls://`) |
| Encrypted clients (DoT listener) | Needs stunnel sidecar | Yes | Yes | Native (RFC 7858) |
| DoH server endpoint | — | Yes | — | Yes (RFC 8484) |
| Request hedging | — | — | — | All protocols (UDP, DoH, DoT) |
| Serve-stale + prefetch | — | — | Prefetch at 90% TTL | RFC 8767, prefetch at 90% TTL |
| Conditional forwarding | — | Yes | Yes | Yes (per-suffix rules) |
| Portable (laptop) | No (appliance) | No (appliance) | Server | Single binary, macOS/Linux/Windows |
| Community maturity | 56K stars, 10 years | 33K stars | 20 years | New |

## Numa를 기본 DNS로 실행하기

**Numa가 중지되면.** `numa install`은 Numa를 launchd(macOS) 또는 systemd(Linux)에 등록하며, 이들은 종료 시 Numa를 재시작합니다. Numa가 유일한 리졸버라면 재시작될 때까지 DNS 조회가 실패합니다. Numa 사용을 중단하고 머신의 이전 DNS 설정을 복원하려면 `sudo numa uninstall`을 실행하세요.

Numa가 실행 중이지만 업스트림에 도달할 수 없는 경우, TTL을 최대 1시간 초과하여 캐시된 응답을 제공할 수 있습니다(RFC 8767). 캐시되지 않은 이름은 실패합니다.

**테스트.** DNS 파서는 이를 건드리는 모든 풀 리퀘스트에서 퍼징되며, 매주 더 긴 실행이 이루어집니다([`fuzz.yml`](https://github.com/razvandimescu/numa/blob/main/.github/workflows/fuzz.yml)). CI는 의존성에 대해 `cargo audit`을 실행하고 macOS와 Linux에서 Numa를 설치, 재설치, 제거합니다.

**리졸버 강화.** 재귀 모드에서 Numa는 쿼리 중인 존 외부의 응답 레코드를 버리고, 사설 또는 루프백 주소의 네임서버에 대한 쿼리를 거부하며, 각 조회의 업스트림 쿼리 수와 리퍼럴 깊이를 제한합니다. 일반 UDP를 통한 응답은 쿼리의 무작위 트랜잭션 ID와 질문과 일치해야 합니다. ANY 쿼리는 거부됩니다. DNSSEC 검증은 기본적으로 꺼져 있으며, `numa dnssec on`으로 켭니다. 취약점을 비공개로 보고하려면 [SECURITY.md](https://github.com/razvandimescu/numa/blob/main/SECURITY.md)를 참조하세요.

**Numa가 하지 않는 것.** DHCP 없음, 클러스터링 없음, 인스턴스 간 설정 동기화 없음. 대부분의 설정은 대시보드가 아니라 [`numa.toml`](https://github.com/razvandimescu/numa/blob/main/numa.toml)에 있습니다. 네트워크 전체를 위해서는 계속 켜져 있는 머신에서 실행하세요.

## 성능

캐시된 쿼리 0.1ms — Unbound 및 AdGuard Home과 동등합니다. 와이어 레벨 캐시는 원시 바이트를 저장하고 TTL을 제자리에서 패치합니다. 요청 헤징은 p99 스파이크를 제거합니다: 콜드 재귀 p99 538ms vs Unbound 748ms (−28%), σ 4배 더 좁음. [벤치마크 →](https://github.com/razvandimescu/numa/blob/main/benches)

## 더 알아보기

- [블로그: Numa를 tailnet 리졸버로 사용하기](https://numa.rs/blog/posts/numa-tailnet-resolver.html)
- [블로그: Rust로 DNS-over-TLS를 처음부터 구현하기](https://numa.rs/blog/posts/dot-from-scratch.html)
- [블로그: Rust로 DNSSEC를 처음부터 구현하기](https://numa.rs/blog/posts/dnssec-from-scratch.html)
- [블로그: DNS 리졸버를 처음부터 만들었습니다](https://numa.rs/blog/posts/dns-from-scratch.html)
- [설정 레퍼런스](https://github.com/razvandimescu/numa/blob/main/numa.toml) — 모든 옵션이 인라인으로 문서화됨; `numa config path`는 설치가 사용 중인 파일을 보여주고, `numa config edit`는 이를 엽니다
- [REST API](https://github.com/razvandimescu/numa/blob/main/src/api.rs) — 재정의, 캐시, 차단, 서비스, 진단
- [numa-metrics](https://github.com/razvandimescu/numa-metrics) — 영구 쿼리 기록 및 분석, 설계상 호스트 외부(SD 카드 쓰기 없음)

## 로드맵

- [x] DNS 포워딩, 캐싱, 광고 차단, 개발자 재정의
- [x] `.numa` 로컬 도메인 — 자동 TLS, 경로 라우팅, WebSocket 프록시
- [x] LAN 서비스 검색 — mDNS, 머신 간 DNS + 프록시
- [x] DNS-over-HTTPS — 암호화된 업스트림 + 서버 엔드포인트 (RFC 8484)
- [x] DNS-over-TLS — 암호화된 클라이언트 리스너 (RFC 7858) + 업스트림 포워딩 (`tls://`)
- [x] Oblivious DoH — 익명화된 클라이언트 모드 + 공용 릴레이 (`numa relay`, RFC 9230)
- [x] 재귀 해석 + DNSSEC — 신뢰 체인, NSEC/NSEC3
- [x] SRTT 기반 네임서버 선택
- [x] 다중 포워더 페일오버 — SRTT 순위가 있는 다중 업스트림, 폴백 풀
- [x] 요청 헤징 — 병렬 요청으로 패킷 손실과 테일 레이턴시 구제 (모든 프로토콜)
- [x] Serve-stale + 프리페치 — RFC 8767, TTL <10% 및 스테일 서브 시 백그라운드 갱신
- [x] 조건부 포워딩 — 스플릿 호라이즌 DNS를 위한 접미사별 규칙 (Tailscale, VPN)
- [x] 캐시 워밍 — 구성된 도메인에 대한 사전 해석
- [x] 모바일 온보딩 — `setup-phone` QR 플로우, 모바일 API, mobileconfig 프로필
- [ ] pkarr 통합 — Mainline DHT를 통한 자주권 DNS
- [ ] 전역 `.numa` 이름 — DHT 기반, 등록 기관 없음

## 라이선스

MIT
도구 다운로드