diff --git a/README.md b/README.md new file mode 100644 index 0000000..a48e933 --- /dev/null +++ b/README.md @@ -0,0 +1,99 @@ +# WHOIS API + +Vercel Edge Function 기반 WHOIS 조회 API 서버 + +## 기능 + +- 다양한 TLD(gTLD, ccTLD) 지원 +- 자동 WHOIS 서버 감지 +- 도메인 정보 파싱 (등록자, 만료일, 네임서버 등) +- 사설 ccSLD 감지 및 안내 + +## API 사용법 + +### 엔드포인트 + +``` +GET /api/whois/{domain} +``` + +### 요청 예시 + +```bash +curl https://your-domain.vercel.app/api/whois/example.com +``` + +### 응답 예시 + +```json +{ + "domain": "example.com", + "whois_server": "whois.verisign-grs.com", + "raw": "...", + "parsed": { + "registrar": "Example Registrar", + "creation_date": "1995-08-14", + "expiration_date": "2025-08-13", + "name_servers": ["ns1.example.com", "ns2.example.com"] + }, + "query_time_ms": 234 +} +``` + +## 지원 TLD + +### Generic TLDs +com, net, org, info, biz, io, co, app, dev, xyz, online, site, tech, store, blog 등 + +### Country Code TLDs +kr, jp, cn, uk, de, fr, ru, au, br, in, it, es, nl, se, no, fi, dk, pl, cz, at, ch, be, ca, mx, ar, cl, nz 등 + +## 사설 ccSLD 처리 + +다음 사설 ccSLD는 공개 WHOIS를 제공하지 않아 별도 안내를 반환합니다: + +| ccSLD | 운영자 | 비고 | +|-------|--------|------| +| it.com | it.com Domains Ltd | 런던 소재 사설 레지스트리 | +| uk.com | CentralNic | WHOIS 미제공 | +| us.com | CentralNic | WHOIS 미제공 | +| eu.com | CentralNic | WHOIS 미제공 | +| de.com | CentralNic | WHOIS 미제공 | +| br.com | CentralNic | WHOIS 미제공 | +| cn.com | CentralNic | WHOIS 미제공 | +| jpn.com | CentralNic | WHOIS 미제공 | +| kr.com | CentralNic | WHOIS 미제공 | +| ru.com | CentralNic | WHOIS 미제공 | +| za.com | CentralNic | WHOIS 미제공 | + +### 사설 ccSLD 응답 예시 + +```json +{ + "domain": "example.it.com", + "whois_supported": false, + "ccSLD": "it.com", + "message": "it.com is a private ccSLD that does not provide public WHOIS data", + "message_ko": "it.com은(는) 공개 WHOIS를 제공하지 않는 사설 ccSLD입니다", + "suggestion": "Use registrar account API or contact the registry directly", + "suggestion_ko": "등록기관 계정 API를 사용하거나 레지스트리에 직접 문의하세요", + "query_time_ms": 1 +} +``` + +## 로컬 개발 + +```bash +npm install +npm run dev +``` + +## 배포 + +```bash +npm run deploy +``` + +## 라이선스 + +MIT diff --git a/api/whois/[domain].ts b/api/whois/[domain].ts index 87f34c4..adebd24 100644 --- a/api/whois/[domain].ts +++ b/api/whois/[domain].ts @@ -1,6 +1,32 @@ import { createConnection } from 'net'; import type { VercelRequest, VercelResponse } from '@vercel/node'; +// WHOIS 미지원 사설 ccSLD 목록 +const UNSUPPORTED_CCSLDS = [ + 'it.com', // it.com Domains Ltd (런던) - 사설 레지스트리 + 'uk.com', // CentralNic - WHOIS 미제공 + 'us.com', // CentralNic - WHOIS 미제공 + 'eu.com', // CentralNic - WHOIS 미제공 + 'de.com', // CentralNic - WHOIS 미제공 + 'br.com', // CentralNic - WHOIS 미제공 + 'cn.com', // CentralNic - WHOIS 미제공 + 'jpn.com', // CentralNic - WHOIS 미제공 + 'kr.com', // CentralNic - WHOIS 미제공 + 'ru.com', // CentralNic - WHOIS 미제공 + 'za.com', // CentralNic - WHOIS 미제공 +]; + +function isUnsupportedCcSLD(domain: string): string | null { + const parts = domain.toLowerCase().split('.'); + if (parts.length >= 3) { + const ccSLD = parts.slice(-2).join('.'); + if (UNSUPPORTED_CCSLDS.includes(ccSLD)) { + return ccSLD; + } + } + return null; +} + // TLD to WHOIS server mapping const WHOIS_SERVERS: Record = { // Generic TLDs @@ -175,6 +201,21 @@ export default async function handler(req: VercelRequest, res: VercelResponse) { const domainName = domain.toLowerCase().trim(); const startTime = Date.now(); + // 사설 ccSLD WHOIS 미지원 체크 + const unsupportedCcSLD = isUnsupportedCcSLD(domainName); + if (unsupportedCcSLD) { + return res.status(200).json({ + domain: domainName, + whois_supported: false, + ccSLD: unsupportedCcSLD, + message: `${unsupportedCcSLD} is a private ccSLD that does not provide public WHOIS data`, + message_ko: `${unsupportedCcSLD}은(는) 공개 WHOIS를 제공하지 않는 사설 ccSLD입니다`, + suggestion: 'Use registrar account API or contact the registry directly', + suggestion_ko: '등록기관 계정 API를 사용하거나 레지스트리에 직접 문의하세요', + query_time_ms: Date.now() - startTime, + }); + } + try { const whoisServer = getWhoisServer(domainName); let raw = await queryWhois(whoisServer, domainName);