
모든 IP, 도메인 또는 ASN에 대한 OSINT 정보
이 프로젝트가 작업에 도움이 되신다면, 지속적인 유지보수와 새로운 기능을 지원해 주세요.
ETH 기부 지갑
0x11282eE5726B3370c8B480e321b3B2aA13686582
QR 코드를 스캔하거나 위의 지갑 주소를 복사하세요.
15개 소스에 걸친 통합 호스트 인텔리전스 — 모든 IP, 도메인 또는 ASN을 조회하여 즉각적인 보안 상태, 인프라 세부 정보 및 위협 상관 관계를 확인하세요. 전적으로 Cloudflare 무료 티어에서 실행됩니다.
라이브: swiy.co/seekyou``` $ curl "https://seekyou.seekyou.workers.dev/api/lookup?q=1.1.1.1"
{ "query": { "raw": "1.1.1.1", "type": "ip", "normalised": "1.1.1.1" }, "core": { "internetdb": { "status": "ok", "data": { "ports": [80,443], "vulns": [] } }, "geo": { "status": "cached", "data": { "country": "US", "org": "AS13335 Cloudflare" } }, "bgp": { "status": "ok", "data": { "name": "CLOUDFLARENET", "rir": "ARIN" } }, ... }, "meta": { "durationMs": 312, "cacheHits": 4, "sourcesQueried": 15, "sourcesFailed": 0 } }
## 스크린샷
<div align="center">
### 랜딩 페이지
<img src="https://assets.kitploit.com/production/public/readmes/7467/e00ec4ba8b3e5460ae1e03360cf6540e58d92acc5522c8693445512b591fed29.png" alt="SeekYou 결과 페이지" width="800" />
### 결과 페이지
<img src="https://assets.kitploit.com/production/public/readmes/7467/09b165feca9927ad4cd50c3ebd28c72e09a0355d72b9ca14d795bf1d04448c92.png" alt="SeekYou 랜딩 페이지" width="800" />
### 데모
<a href="https://www.youtube.com/watch?v=b86tAUUqd34">
<img src="https://assets.kitploit.com/production/public/readmes/7467/8762e8b464816b9a69d929514441f8c7ee9f9ee9719f95b9c5e33ac1672575f8.jpg" alt="SeekYou 데모" width="800" />
</a>
</div>
---
## 목차
- [SeekYou](#seekyou)
- [스크린샷](#screenshots)
- [랜딩 페이지](#landing-page)
- [결과 페이지](#results-page)
- [데모](#demo)
- [목차](#table-of-contents)
- [SeekYou의 기능](#what-seekyou-does)
- [사용 사례](#use-cases)
- [합법적 사용 정책](#lawful-use-policy)
- [관련 도구](#related-tools)
- [아키텍처 개요](#architecture-overview)
- [실행 모델](#execution-model)
- [데이터 소스](#data-sources)
- [프로젝트 구조](#project-structure)
- [주요 설계 결정](#key-design-decisions)
- [에지 우선, Node.js 없음](#edge-first-no-nodejs)
- [계층형 병렬 실행](#layered-parallel-execution)
- [우아한 성능 저하](#graceful-degradation)
- [분할 D1 + KV 저장소](#split-d1--kv-storage)
- [무료 티어 최적화](#free-tier-optimization)
- [Fire-and-forget D1 쓰기](#fire-and-forget-d1-writes)
- [캐싱 전략](#caching-strategy)
- [속도 제한](#rate-limiting)
- [회로 차단기](#circuit-breakers)
- [키 순환 — GrayHatWarfare](#key-rotation--grayhatwarfare)
- [D1 지속성](#d1-persistence)
- [스키마 (`schema.sql`)](#schema-schemasql)
- [스키마 적용](#apply-schema)
- [헬퍼 함수](#helper-functions)
- [Cron 워커](#cron-worker)
- [타입이 지정된 diff (`lib/diff.ts`)](#typed-diff-libdiffts)
- [웹훅 페이로드](#webhook-payload)
- [개발 환경 설정](#development-setup)
- [사전 요구사항](#prerequisites)
- [로컬 개발](#local-development)
- [Cloudflare 리소스 생성 (처음)](#create-cloudflare-resources-first-time)
- [배포](#deployment)
- [빌드 및 배포](#build-and-deploy)
- [Wrangler 설정 (`wrangler.toml`)](#wrangler-configuration-wranglertoml)
- [비밀 및 환경 변수](#secrets-and-environment-variables)
- [필수 비밀](#required-secrets)
- [`.env.example` (로컬 개발 전용)](#envexample-local-dev-only)
- [라이선스](#license)
- [저자](#author)
- [감사의 말](#acknowledgments)
---
## SeekYou의 기능
SeekYou는 **호스트 인텔리전스 도구**입니다 — IP 주소, 도메인 이름 또는 ASN을 입력하면 통합된 보고서를 제공합니다:
| 카테고리 | 얻을 수 있는 정보 |
|---|---|
| 네트워크 | 열린 포트, CPE, BGP 접두사, 업스트림, 피어, RIR |
| 신원 | RDAP 등록 정보, 연락처, 등록 기관, 네임서버 |
| 지리 | 국가, 도시, ISP, 프록시/호스팅/모바일 플래그 |
| 인증서 | crt.sh 기록, SAN, 발급자 체인 |
| DNS | 패시브 DNS 기록, Robtex 역방향/정방향 DNS |
| 위협 | URLhaus, ThreatFox, MalwareBazaar, Feodo, SSLBL |
| CVE | NVD + CIRCL 보강(InternetDB가 보고하는 모든 CVE ID에 대해) |
| 정찰 | GrayHatWarfare 노출된 버킷, Wayback CDX 스냅샷 |
모든 소스는 병렬로 쿼리됩니다. 실패하는 소스는 "사용 불가" 배지로 표시되며 — 페이지가 깨지지 않습니다.
---
## 사용 사례
**보안 운영** — 로그에서 의심스러운 IP를 신속하게 프로파일링하고, IOC를 연관시키며, 노출된 서비스와 CVE를 식별하고, 악성 도메인을 추적합니다.
**네트워크 운영** — BGP 라우팅, RDAP/WHOIS 할당 데이터, 과거 DNS 기록, SSL 인증서 변경 사항을 검사합니다.
**침투 테스팅** — 포트/서비스/CPE를 열거하고, 노출된 버킷, 보관된 페이지, 서브도메인 및 ASN 관계를 발견합니다.
**위협 인텔리전스** — 단일 쿼리로 5개의 위협 피드에 대해 C2 인프라를 확인합니다.
**규정 준수 및 위험 관리** — 공급업체 인프라를 프로파일링하고, 노출된 클라우드 스토리지를 탐지하며, 섀도 IT를 식별합니다.
---
## 합법적 사용 정책
SeekYou는 **합법적인 보안 연구, 네트워크 운영 및 위협 인텔리전스**를 위해 설계되었습니다. 이 도구를 사용함으로써 귀하는 다음에 동의하게 됩니다:
**허용되는 사용:**
- 귀하가 소유하거나 모니터링할 권한이 있는 네트워크에 대한 보안 운영 및 침해 대응
- 위협 인텔리전스 연구 및 IOC 연관 분석
- 조직 내 네트워크 문제 해결 및 인프라 감사
- 대상 조직의 명시적인 서면 승인을 받은 침투 테스트
- 사이버 보안 분야의 학술 연구 및 교육
- 적절한 승인을 받은 규정 준수 감사 및 공급업체 위험 평가
**금지되는 사용:**
- 귀하가 소유하거나 명시적 테스트 허가를 받지 않은 시스템에 대한 무단 접근, 정찰 또는 공격
- 개인이나 조직에 대한 괴롭힘, 스토킹 또는 개인 정보 침해
- 사기, 신원 도용 또는 사이버 범죄를 포함한 불법 활동 지원
- 허가 없이 보안 통제 또는 접근 제한을 우회하는 행위
- CFAA(미국), 컴퓨터 남용법(영국), GDPR(EU) 또는 해당 관할권의 동등한 법률을 포함한 관련 법률 위반
**귀하의 책임:**
- 귀하가 소유하지 않은 인프라를 쿼리하기 전에 적절한 승인을 받았는지 확인하십시오.
- 속도 제한을 준수하고 서비스 또는 업스트림 데이터 소스를 남용하지 마십시오.
- 해당 관할권의 모든 관련 법률 및 규정을 준수하십시오.
- 데이터를 책임감 있게 사용하고, 조정된 공개 없이 발견 내용을 무기화하지 마십시오.
- 호스트를 쿼리한다고 해서 해당 호스트에 접근하거나 악용할 권한이 부여되는 것은 아닙니다.
**면책 조항:**
저자와 기여자는 이 도구의 오용에 대해 어떠한 책임도 지지 않습니다. 사용자는 자신의 활동이 관련 법률을 준수하는지 확인할 전적인 책임이 있습니다. 공개 소스에서 수집된 데이터는 불완전하거나, 오래되었거나, 부정확할 수 있습니다. 조치를 취하기 전에 항상 권위 있는 채널을 통해 결과를 확인하십시오.
SeekYou를 통해 취약점을 발견한 경우, 책임 있는 공개 절차를 따르고 공개 전에 영향을 받은 당사자에게 알리십시오.
---
## 관련 도구
SeekYou는 개인 정보 보호에 중점을 둔 보안 툴킷의 일부입니다. 전체 제품군을 살펴보십시오:
| 도구 | 설명 | 라이브 URL |
|---|---|---|
| **TimeSeal** | 암호학적 타임스탬핑 서비스 — 콘텐츠를 공개하지 않고 특정 시간에 문서 존재를 증명합니다 | [timeseal.online](https://timeseal.online) |
| **SanctumVault** | 제로 지식 암호화 볼트 — 민감한 데이터 저장을 위한 클라이언트 측 암호화 | [sanctumvault.online](https://sanctumvault.online) |
| **GhostChat** | 일회성 암호화 메시징 — 서버 로그 없이 자체 파괴되는 대화 | [ghost-chat.pages.dev](https://ghost-chat.pages.dev) |
| **XMRProof** | 모네로 결제 확인 — XMR 거래의 암호학적 증명 생성 | [xmrproof.pages.dev](https://xmrproof.pages.dev) |
| **GhostReceipt** | 익명 영수증 생성 — 신원 노출 없이 검증 가능한 거래 기록 생성 | [ghostreceipt.pages.dev](https://ghostreceipt.pages.dev) |
| **SeekYou** | 호스트 인텔리전스 수집기 — IP, 도메인 및 ASN에 대해 15개 소스에 걸친 통합 OSINT | [seekyou.seekyou.workers.dev](https://seekyou.seekyou.workers.dev) |
| **HoneypotScan** | 허니팟 탐지 서비스 — 연구에서 가짜 시스템 식별 및 오탐 방지 | [honeypotscan.pages.dev](https://honeypotscan.pages.dev) |
모든 도구는 개인 정보 보호 우선 설계 원칙으로 Cloudflare의 에지 네트워크에서 실행됩니다.
---
## 아키텍처 개요```
Browser / curl
│
▼
┌─────────────────────────────────────┐
│ Cloudflare Pages │
│ Next.js App Router (SSR) │
│ │
│ app/page.tsx search form │
│ app/host/[query]/page.tsx │
│ └─ streams /api/stream?q=… │
│ app/api/recent/route.ts │
│ └─ recent searches for homepage │
│ app/targets/page.tsx │
│ └─ monitoring dashboard │
│ app/api/targets/route.ts │
│ └─ saved targets CRUD │
│ returns riskScore + lastDiff │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ app/api/lookup/route.ts │
│ (Workers runtime via opennextjs) │
│ • input validation │
│ • per-IP rate limiting (KV) │
│ • ctx.waitUntil(recordSearch()) │
└──────────────┬──────────────────────┘
│ runLookup()
▼
┌─────────────────────────────────────┐
│ worker/lookup.ts — orchestrator │
│ 4-layer Promise.allSettled │
└──┬──────────────────────────────────┘
│
├─► Layer 1+2 (parallel, 12 sources):
│ InternetDB · IPinfo · RIPE stat · RDAP · crt.sh · HackerTarget · Robtex
│ URLhaus · ThreatFox · MalwareBazaar · Feodo · SSLBL
├─► Layer 3 (after L1): NVD CVE enrichment (only if vulns found, batched 10-at-a-time)
└─► Layer 4 (parallel): GrayHatWarfare · Wayback (domain queries only)
│
▼
┌──────────────────────┐ ┌──────────────────────┐
│ D1 │ │ KV │
│ source response cache│ │ rate limiting │
│ (TTL per source) │ │ circuit breakers │
│ searches │ │ concurrency counters │
│ saved_targets │ │ │
└──────────────────────┘ └──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ seekyou-cron (Worker) │
│ wrangler.cron.toml │
│ • hourly blocklist refresh │
│ • hourly saved-target re-query │
│ + typed diff (lib/diff.ts) │
│ + webhook on hasChanges │
└─────────────────────────────────────┘
레이어 1과 2는 동시에 실행됩니다(하나의 Promise.allSettled에서 12개의 소스). 레이어 3은 레이어 1이 완료된 후 시작됩니다 — InternetDB의 CVE ID는 NVD 보강을 구동하며, API에 과부하를 방지하기 위해 10개씩 배치 처리됩니다. 레이어 4는 레이어 3과 병렬로 실행되지만 도메인 쿼리에만 해당됩니다. IP/ASN은 이를 완전히 건너뜁니다. 총 벽시계 시간 ≈ 최대(레이어 1+2) + 최대(레이어 3+4).
?refresh=1을 사용하여 모든 쿼리를 강제 새로고침하여 D1 캐시를 우회하고 모든 업스트림에서 실시간 데이터를 가져옵니다.
Feodo와 SSLBL은 일괄 블록리스트로 가져와지며 크론 워커에 의해 매시간 새로 고쳐집니다 — 쿼리당 업스트림 호출이 없습니다.
SeekYou/ ├── app/ │ ├── page.tsx # Homepage — search form + recent searches │ ├── layout.tsx # Root layout │ ├── globals.css │ ├── about/ # About page │ ├── faq/ # FAQ page │ ├── targets/ │ │ └── page.tsx # /targets — monitoring dashboard (risk + diffs) │ ├── host/[query]/ │ │ └── page.tsx # SSR host report page (streams via /api/stream) │ ├── api/ │ │ ├── lookup/route.ts # GET /api/lookup?q=&refresh=1 │ │ ├── stream/route.ts # GET /api/stream?q= (SSE streaming) │ │ ├── recent/route.ts # GET /api/recent?limit=5 │ │ ├── batch/route.ts # POST /api/batch (multi-query) │ │ ├── targets/route.ts # GET /api/targets (+ riskScore, lastDiff) · POST │ │ ├── targets/[id]/route.ts # DELETE /api/targets/:id │ │ └── admin/reset-breaker/ # POST — manual circuit-breaker reset │ └── components/ │ ├── AnimatedTagline.tsx │ ├── Card.tsx │ ├── CopyButton.tsx │ ├── CveDrawer.tsx │ ├── DecryptedText.tsx │ ├── ExportButton.tsx # JSON export (client, zero backend) │ ├── Footer.tsx │ ├── RecentSearches.tsx # Recent queries from D1 (client) │ ├── RiskBadge.tsx # Risk score pill with breakdown tooltip │ ├── SaveButton.tsx # Save/unsave target │ ├── ScrollProgress.tsx │ ├── ShareButton.tsx │ ├── VulnsStream.tsx # Streaming CVE results │ └── ui/ # Shared UI primitives ├── worker/ │ ├── lookup.ts # 4-layer orchestrator │ ├── cron.ts # Hourly blocklist refresh + target sweep w/ typed diff │ ├── index.ts │ └── sources/ │ ├── internetdb.ts │ ├── ipapi.ts │ ├── bgpview.ts │ ├── rdap.ts │ ├── crtsh.ts │ ├── passivedns.ts │ ├── robtex.ts │ ├── abusech.ts # URLhaus + ThreatFox + MalwareBazaar │ ├── nvd.ts # NVD + CIRCL CVE enrichment │ ├── osv.ts # OSV.dev re-export (via nvd.ts) │ ├── grayhatwarfare.ts │ └── wayback.ts ├── lib/ │ ├── types.ts # All TypeScript interfaces │ ├── cache.ts # D1 cache wrapper (cacheGet/cachePut, bypass on forceRefresh) │ ├── config.ts # All magic numbers: TTLs, timeouts, limits │ ├── diff.ts # TargetDiff — typed change detection between snapshots │ ├── errors.ts # Unified error format + ErrorCode enum │ ├── hooks.ts # Shared React hooks │ ├── keyring.ts # GHW 18-key rotation │ ├── logger.ts # Structured logging │ ├── merge.ts # Result merging │ ├── normalize.ts # Threat indicator normalization │ ├── ratelimit.ts # KV-based per-IP rate limiter + circuit breakers │ ├── results.ts # SourceResult helpers │ ├── risk.ts # computeRiskScore — scored 0–100 with breakdown │ ├── searches.ts # D1 helpers: recordSearch, getRecentSearches │ ├── targets.ts # D1 helpers: saveTarget, listTargets, removeTarget │ ├── textAnimation.ts # Text animation utility │ ├── useHostStream.ts # SSE streaming hook for host results │ ├── validate.ts # Query parsing (IPv4/v6/domain/ASN) │ └── utils.ts ├── test/ │ ├── cache.test.ts │ ├── diff.test.ts # Tests for diffHostResults + summariseDiff │ ├── keyring.test.ts │ ├── logger.test.ts │ ├── merge.test.ts │ ├── normalize.test.ts │ ├── results.test.ts │ ├── risk.test.ts │ ├── validate.test.ts │ └── sources/ ├── docs/ │ ├── ROADMAP.md │ ├── Spec.md │ └── LICENSE.md ├── public/ │ └── publiceth.svg # Donation QR code ├── schema.sql # D1 schema (apply with wrangler d1 execute) ├── wrangler.toml # Pages build config (KV + D1 bindings) ├── wrangler.cron.toml # Cron worker config (separate deploy) ├── next.config.ts ├── open-next.config.ts └── vitest.config.ts
---
## 주요 설계 결정
### 엣지 우선, Node.js 없음
`@opennextjs/cloudflare`를 통한 Workers 런타임 — `runtime = 'edge'` 내보내기가 필요하지 않습니다. 전체적으로 순수 Web API 사용. 전 세계 콜드 스타트 50ms 미만.
### 계층적 병렬 실행
레이어 1+2가 함께 실행됨(12개 소스). 레이어 3(CVE 보강)은 InternetDB에서 취약점을 찾은 경우에만 실행되며, 10개씩 배치 처리됨. 레이어 4(GHW + Wayback)는 레이어 3과 병렬로 실행되지만, IP/ASN 쿼리의 경우 완전히 생략됨. 총 소요 시간 ≈ 각 웨이브에서 가장 느린 소스의 시간, 모든 소스의 합계가 아님.
### 정상적 성능 저하
모든 소스는 회로 차단기 + try/catch로 래핑됨. 실패한 소스는 `{ status: 'error' }` 배지가 됨. 페이지는 항상 렌더링됨.
### D1 + KV 스토리지 분할
소스 응답 캐시는 **KV**가 아닌 **D1**에 저장됨 — 값은 한 번 기록되고, 가끔 읽히며, KV의 쓰기 할당량 비용이 빠르게 누적될 만큼 큼. **KV**는 핫 경로 카운터(속도 제한, 회로 차단기, 동시 실행 중인 요청 수 추적)에만 독점적으로 사용됨. 각 소스는 자체 TTL을 가짐(CVE 30일, BGP/RDAP 24시간, 코어 지오/포트 1시간, abuse.ch 30분). `?refresh=1`은 모든 패처에 `forceRefresh: true`를 전달하여 필요 시 D1 캐시를 우회함.
### 무료 티어 최적화
GrayHatWarfare는 18개 키 로테이션(하루 1,800회 요청). NVD는 요청 배치 사용(최대 10개 동시). Feodo/SSLBL은 크론 워커에 의해 벌크 목록으로 가져와져 KV에 캐시됨 — 쿼리당 업스트림 비용 제로.
### 발사 후 망각 D1 쓰기
`recordSearch()`는 `ctx.waitUntil()` 내에서 호출됨 — API 응답에 지연 시간을 추가하지 않음. D1 쓰기는 응답이 플러시된 후에 발생함.
---
## 캐싱 전략
소스 응답은 **D1**에 캐시되며, `expires_at` 열을 통해 수동 TTL이 적용됨. KV는 응답 캐싱에 사용되지 않음 — 대기 시간이 짧은 원자적 증가가 중요한 속도 제한, 회로 차단기, 동시 실행 중인 요청 카운터에 예약되어 있음.```typescript
// lib/cache.ts
export async function cacheGet<T>(
db: D1Database,
key: string,
bypass?: boolean, // true when ?refresh=1
): Promise<T | null>
export async function cachePut<T>(
db: D1Database,
key: string,
value: T,
ttl: number, // seconds
): Promise<void>
Cache 키는 source:normalised_query 패턴을 따릅니다. 예: internetdb:1.1.1.1, crtsh:example.com
소스별 TTL (lib/cache.ts에서 발췌):
오류는 절대 캐싱되지 않습니다. 실패한 요청은 다음 요청 시 항상 재시도됩니다. 만료된 행은 miss로 반환되고 지연 덮어쓰기가 이루어지며, 백그라운드 정리는 필요하지 않습니다.
KV 기반 슬라이딩 윈도우: IP당 시간당 100개 요청. lib/ratelimit.ts에 구현되어 있으며, 조회 실행 전에 app/api/lookup/route.ts에서 적용됩니다.
모든 응답에 속도 제한 헤더가 반환됩니다:``` X-RateLimit-Limit: 100 X-RateLimit-Remaining: 87 X-RateLimit-Reset: 1716912000
소진 시, API는 `429`와 함께 `Retry-After`를 반환합니다.
---
## 서킷 브레이커
각 소스에는 KV에 추적되는 서킷 브레이커가 있습니다. 소스가 5분 창에서 **50% 실패율**을 초과하면 (최소 4회 요청), 브레이커가 열리고 소스는 **15분** 동안 건너뛰며 (`{ status: 'skipped' }` 반환), 이후 자동 복구됩니다.
모든 브레이커의 현재 상태는 모든 API 응답의 `meta.circuitBreakers`에 포함됩니다.
프로덕션에서 브레이커를 수동으로 재설정하려면:```bash
curl -X POST https://seekyou.seekyou.workers.dev/api/admin/reset-breaker \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"source": "nvd"}'
GrayHatWarfare는 API 키당 일 100회 요청을 허용합니다. SeekYou는 최대 18개의 키를 순환하여 사실상 일 1,800회 요청을 가능하게 합니다:```typescript // lib/keyring.ts — round-robin across keys with remaining quota const key = await keyRing.next(env, 'GRAYHATWARFARE_API_KEY')
Keys are named `GRAYHATWARFARE_API_KEY_1`부터 `GRAYHATWARFARE_API_KEY_18`까지이며 Wrangler 비밀로 저장됩니다.
---
## D1 영속성
### 스키마 (`schema.sql`)```sql
CREATE TABLE IF NOT EXISTS searches (
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
query TEXT NOT NULL,
query_type TEXT NOT NULL CHECK (query_type IN ('ip','domain','asn')),
result_json TEXT NOT NULL,
duration_ms INTEGER,
created_at INTEGER NOT NULL DEFAULT (unixepoch())
);
CREATE INDEX IF NOT EXISTS idx_searches_query
ON searches (query, created_at DESC);
CREATE TABLE IF NOT EXISTS saved_targets (
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
query TEXT NOT NULL UNIQUE,
label TEXT,
notes TEXT,
result_json TEXT, -- snapshot of last cron lookup
checked_at INTEGER, -- unix seconds — when cron last re-queried
created_at INTEGER NOT NULL DEFAULT (unixepoch())
);
CREATE INDEX IF NOT EXISTS idx_saved_targets_created
ON saved_targets (created_at DESC);
wrangler d1 execute seekyou --file=schema.sql
### 도우미 함수들
**`lib/searches.ts`** — 검색 기록:```typescript
// Write a search row (fire-and-forget safe)
await recordSearch(db, query, queryType, resultJson, durationMs)
// Read last N distinct queries for the homepage (default 5)
const recent = await getRecentSearches(db, 5)
// → [{ query: '1.1.1.1', query_type: 'ip', created_at: 1716912000 }, ...]
lib/targets.ts — 저장된 대상:```typescript
// Upsert a target (idempotent on query)
const id = await saveTarget(db, query, label, notes)
// List all saved targets const targets = await listTargets(db)
// Remove by id await removeTarget(db, id)
// Fetch one (used by cron before re-querying) const target = await getTarget(db, id)
// Write latest snapshot after cron re-query await updateTargetSnapshot(db, id, resultJson)
---
## Cron 작업자
별도의 `wrangler.cron.toml`을 통해 배포된 독립 실행형 Worker(`worker/cron.ts`)입니다. **시간별 트리거**로 실행되며 두 가지 작업을 수행합니다.
1. **차단 목록 갱신** — Feodo/SSLBL 대량 목록이 오래되었는지 확인하고 필요하면 다시 다운로드합니다.
2. **저장된 대상 스위프** — 저장된 모든 대상을 다시 쿼리하고, 유형화된 `TargetDiff`를 계산하여 최신 스냅샷을 D1에 유지하며, 변경 사항이 감지되면 웹훅 페이로드를 POST합니다.
### 유형화된 diff (`lib/diff.ts`)
다시 쿼리할 때마다 `diffHostResults(prev, next)`는 구조화된 `TargetDiff`를 생성하며, 다음을 포함합니다.
| 신호 | 감지 내용 |
|---|---|
| `ports` | 열린/닫힌 포트 (포트별 방향) |
| `cves` | 나타나거나 해결된 CVE, CVSS 심각도 및 점수 포함 |
| `threats` | URLhaus, Feodo, SSLBL, ThreatFox 피드 변경 사항 |
| `geo` | 국가, ASN 또는 기본 호스트 이름 변경 사항 |
| `certExpiry` | 30일 이내에 만료되거나 새로 만료된 인증서 (인증서당 한 번만 발생) |
| `risk` | 위험 점수 델타 — Δ ≥ 5점일 때만 `hasChanges`에 표시 |
`summariseDiff(diff, query)`는 구조체를 로그 및 웹훅 릴레이를 위한 사람이 읽을 수 있는 문자열로 변환합니다.
### 웹훅 페이로드
`diff.hasChanges`가 true이고 `WEBHOOK_URL`이 설정된 경우, cron이 POST합니다.```json
{
"sentAt": 1716912000,
"events": [
{
"targetId": "abc123",
"query": "1.2.3.4",
"checkedAt": 1716912000,
"summary": "1.2.3.4:\n port 3389 opened\n CVE-2021-44228 appeared [CRITICAL 10]",
"diff": {
"diffedAt": 1716912000,
"hasChanges": true,
"ports": [{ "port": 3389, "direction": "opened" }],
"cves": [{ "id": "CVE-2021-44228", "direction": "appeared", "severity": "CRITICAL", "score": 10 }],
"threats": [],
"geo": [],
"certExpiry": [],
"risk": { "prev": 20, "next": 55, "delta": 35 }
}
}
]
}
diff 필드는 완전히 구조화되어 있어, 사용자는 문자열 줄을 파싱하지 않고도 특정 변경 유형을 분기할 수 있습니다. summary 필드는 Slack/Discord 중계를 위해 사전 포맷되어 있습니다.
cron 워커를 배포하세요:
wrangler deploy --config wrangler.cron.toml
```
크론 워커의 시크릿은 별도로 설정됩니다:```bash
wrangler secret put NVD_KEY --config wrangler.cron.toml
wrangler secret put ABUSECH_KEY --config wrangler.cron.toml
wrangler secret put WEBHOOK_URL --config wrangler.cron.toml # optional — fires on any hasChanges
```
## 개발 환경 설정
### 사전 요구 사항
- Node.js 18+
- Wrangler CLI (`npm i -g wrangler`)
- Cloudflare 계정 (무료 티어로 충분함)
### 로컬 개발```bash
git clone https://github.com/Teycir/SeekYou
cd SeekYou
npm install
# Copy example env — fill in your keys
cp .env.example .env
# Run Next.js dev server (KV/D1 stubbed via Wrangler local)
npm run dev
```
앱은 `http://localhost:3000`에서 사용할 수 있습니다. 로컬 개발에서 KV 및 D1은 Wrangler의 로컬 SQLite 기반 에뮬레이션을 사용합니다 — 기본 테스트에는 Cloudflare 계정 액세스가 필요하지 않습니다.
### Cloudflare 리소스 생성 (처음)```bash
# Create KV namespace — copy the ID into wrangler.toml
wrangler kv namespace create KV
# Create D1 database — copy the ID into wrangler.toml
wrangler d1 create seekyou
# Apply schema
wrangler d1 execute seekyou --file=schema.sql
```
---
## 배포
### 빌드 및 배포```bash
# Build + deploy to Cloudflare Pages
bash scripts/deploy.sh
```
The script runs `opennextjs-cloudflare build`, prepares the Pages output directory, and calls `wrangler pages deploy .open-next`. Do **not** use `npm run deploy` or bare `wrangler deploy` — those target the Workers (non-Pages) runtime and will fail.
To deploy the cron worker separately:```bash
wrangler deploy --config wrangler.cron.toml
```
### Wrangler 구성 (`wrangler.toml`)```toml
name = "seekyou"
pages_build_output_dir = ".open-next"
compatibility_date = "2025-05-01"
compatibility_flags = ["nodejs_compat"]
[[kv_namespaces]]
binding = "KV"
id = "<your-kv-id>"
[[d1_databases]]
binding = "DB"
database_name = "seekyou"
database_id = "<your-d1-id>"
```
---
## 비밀 및 환경 변수
모든 비밀은 Wrangler 비밀로 저장됩니다 — 소스 코드나 `.env` 파일에는 절대 저장하지 않습니다.
### 필수 비밀```bash
wrangler secret put NVD_KEY # NVD API key (optional — higher rate limits)
wrangler secret put ABUSECH_KEY # abuse.ch API key (URLhaus/ThreatFox/MalwareBazaar)
wrangler secret put ADMIN_TOKEN # Bearer token for /api/admin/* endpoints
# GrayHatWarfare — repeat for each key you have (1–18)
wrangler secret put GRAYHATWARFARE_API_KEY_1
wrangler secret put GRAYHATWARFARE_API_KEY_2
# ... up to GRAYHATWARFARE_API_KEY_18
```
### `.env.example` (로컬 개발 전용)```bash
NVD_KEY=your_nvd_key_here
ABUSECH_KEY=your_abusech_key_here
ADMIN_TOKEN=change_me
GRAYHATWARFARE_API_KEY_1=your_ghw_key_here
```
> **보안 참고:** 절대로 `.env`를 커밋하지 마세요. `.gitignore`에 포함되어 있습니다. 만약 비밀이 커밋된 적이 있다면, 모든 키를 교체하고 BFG(`bfg --delete-files .env`)로 git 히스토리를 정리하세요.
---
## 라이선스
**Business Source License 1.1 (BSL)**
Copyright © 2026 Teycir Ben Soltane <[email protected]>
허용: 개인 사용, 연구, 교육, 비상업적 프로젝트, 내부 비즈니스 도구.
제한: 상업용 SaaS 제공, 서비스 형태 재판매, 경쟁 제품.
출시일로부터 4년 후, 이 소프트웨어는 Apache 2.0으로 전환됩니다.
전체 약관은 [docs/LICENSE.md](https://github.com/teycir/seekyou/blob/HEAD/docs/LICENSE.md)를 참조하세요.
---
## 저자
**Teycir Ben Soltane**
이메일: [email protected]
GitHub: [@Teycir](https://github.com/Teycir)
---
## 감사의 말
- [InternetDB](https://internetdb.shodan.io) (Shodan)
- [IPinfo](https://ipinfo.io)
- [RIPE stat](https://stat.ripe.net)
- [RDAP](https://rdap.org)
- [crt.sh](https://crt.sh)
- [HackerTarget](https://hackertarget.com)
- [Robtex](https://www.robtex.com)
- [abuse.ch](https://abuse.ch) — URLhaus, ThreatFox, MalwareBazaar, Feodo, SSLBL
- [NVD](https://nvd.nist.gov) (NIST)
- [CIRCL](https://www.circl.lu/services/cve-search/)
- [OSV.dev](https://osv.dev)
- [GrayHatWarfare](https://grayhatwarfare.com)
- [Internet Archive](https://web.archive.org) (Wayback Machine)
---
## 🌐 관련 프로젝트
더 많은 개인정보 보호 우선 및 보안 도구를 살펴보세요:
### 개인정보 보호 및 암호화
- **[Timeseal](https://github.com/Teycir/Timeseal)** - Dead Man's Switch가 포함된 시간 잠금 암호화 금고. AES-256 분할 키 암호화, 임시 봉인.
- **[Sanctum](https://github.com/Teycir/Sanctum)** - 암호학적 그럴듯한 부인 가능성을 제공하는 제로 트러스트 암호화 금고. XChaCha20-Poly1305, Argon2id.
- **[GhostChat](https://github.com/Teycir/GhostChat)** - WebRTC를 통한 진정한 P2P 암호화 채팅. 서버 없음, 저장소 없음, 자동 삭제 메시지.
- **[xmrproof](https://github.com/Teycir/xmrproof)** - 모네로 결제 확인, 100% 클라이언트 측.
- **[GhostReceipt](https://github.com/Teycir/GhostReceipt)** - 영지식 증명을 사용한 익명 영수증 생성.
### 보안 도구
- **[BurpAPISecuritySuite](https://github.com/Teycir/BurpAPISecuritySuite)** - API 보안 테스트를 위한 Burp Suite 확장. 15가지 공격 유형, 108개 이상의 페이로드, BOLA/IDOR 탐지.
- **[Mcpwn](https://github.com/Teycir/Mcpwn)** - Model Context Protocol 서버를 위한 자동화된 보안 스캐너. RCE, 경로 순회, 프롬프트 인젝션 탐지.
- **[DiffCatcher](https://github.com/Teycir/DiffCatcher)** - Git 저장소 발견, diff 캡처, 코드 요소 추출.
- **[HoneypotScan](https://github.com/Teycir/HoneypotScan)** - 보안 연구를 위한 허니팟 탐지 서비스.
- **[CheckAPI](https://github.com/Teycir/CheckAPI)** - 여러 제공업체를 위한 LLM API 키 검증기. 개인정보 보호 우선, 클라이언트 측 검증.
### MCP 보안 서버
- **[burp-mcp-server](https://github.com/Teycir/burp-mcp-server)** - Burp Suite Professional을 위한 MCP 서버. AI 어시스턴트를 통한 취약점 스캐닝.
- **[nuclei-mcp](https://github.com/Teycir/nuclei-mcp)** - Nuclei를 위한 MCP 서버. 다중 대상 스캐닝, 심각도 필터링.
- **[nmap-mcp](https://github.com/Teycir/nmap-mcp)** - Nmap을 위한 MCP 서버. 스텔스 정찰, 취약점/NSE 스캐닝.
- **[frida-mcp](https://github.com/Teycir/frida-mcp)** - Frida를 위한 MCP 서버. 동적 계측, SSL 고정 우회.
---
## 💼 제공 서비스
- 🔒 **개인정보 보호 우선 개발** - P2P 애플리케이션, 암호화 통신, 영지식 시스템
- 🚀 **웹 애플리케이션 개발** - Next.js, React, TypeScript를 사용한 풀스택 개발
- 🔧 **에지 컴퓨팅 솔루션** - Cloudflare Workers, Pages, D1, KV, Durable Objects
- 🛡️ **보안 도구 개발** - Burp 확장, 침투 테스트 도구, 자동화 프레임워크
- 🤖 **AI 통합** - LLM 기반 애플리케이션, 지능형 자동화, 맞춤형 AI 솔루션
- 🔍 **OSINT 및 위협 인텔리전스** - 맞춤형 정찰 도구, 위협 피드 집계, IOC 상관 관계
**문의하기**: [teycirbensoltane.tn](https://teycirbensoltane.tn) | 프리랜스 프로젝트 및 컨설팅 가능
---
<div align="center">
**💚로 제작: [Teycir Ben Soltane](https://teycirbensoltane.tn)**
</div>
| 레이어 | 소스 | 제공하는 것 | 인증 필요 |
|---|
| 1 | InternetDB | 열린 포트, CPE, CVE ID | 아니요 |
| 1 | IPinfo | 지역, ISP, ASN, 애니캐스트 플래그 | 아니요 |
| 1 | RIPE stat | BGP 프리픽스, ASN 보유자, RIR | 아니요 |
| 1 | RDAP | 등록, 연락처, 네임서버, CIDR | 아니요 |
| 2 | crt.sh | 인증서 기록, SAN, 발급자 체인 | 아니요 |
| 2 | HackerTarget | 패시브 DNS — 역방향 IP 및 호스트 검색 | 아니요 |
| 2 | Robtex | 역방향/정방향 DNS, AS 정보 | 아니요 |
| 2 | URLhaus | 악성코드 유포 URL | ABUSECH_KEY |
| 2 | ThreatFox | IOC 데이터베이스 | ABUSECH_KEY |
| 2 | MalwareBazaar | 악성코드 샘플 메타데이터 | ABUSECH_KEY |
| 2 | Feodo Tracker | 봇넷 C2 IP | 아니요 (일괄 다운로드) |
| 2 | SSLBL | 악성 SSL 인증서 | 아니요 (일괄 다운로드) |
| 3 | NVD + CIRCL | CVE 세부 정보, CVSS v2/v3 점수 | NVD_KEY (선택 사항) |
| 4 | GrayHatWarfare | 노출된 S3/Azure/GCS 버킷 | GRAYHATWARFARE_API_KEY_1..18 |
| 4 | Wayback | 과거 CDX 스냅샷 | 아니요 |
| 소스 | TTL |
|---|
| CVE (NVD/CIRCL) | 30일 |
| Wayback | 7일 |
| BGP, RDAP, Robtex | 24시간 |
| crt.sh, HackerTarget 수동 DNS | 12시간 |
| GrayHatWarfare | 6시간 |
| InternetDB, IPinfo | 1시간 |
| Feodo, SSLBL (대량) | 1시간 |
| URLhaus, ThreatFox, MalwareBazaar | 30분 |