# GeoIP REST (Go Fiber) 간단한 GeoIP 조회 API입니다. 기본은 `GeoLite2-City.mmdb`를 사용해 IP를 나라/지역/도시/위도/경도로 매핑하며, 선택적으로 PostgreSQL + `maxminddb_fdw`로 가져온 데이터를 조회할 수 있습니다. 초기 적재 후에는 DB만으로 조회가 가능하도록 읽기 전용 테이블과 함수가 생성됩니다. ## 요구 사항 - Go 1.25+ - `GeoLite2-City.mmdb` (레포지토리 루트에 위치) - Docker / Docker Compose (컨테이너 실행 시) ## 설치 및 실행 ### 로컬 (Go) ```bash go mod tidy # 필요한 경우 go.sum 생성 PORT=8080 GEOIP_DB_PATH=./GeoLite2-City.mmdb go run ./cmd/server ``` ### Docker 최초 실행시 ```bash docker network create --driver bridge --attachable geo-ip ``` ### Docker Compose (PostgreSQL + FDW + API) ```bash docker compose up --build ``` - 서비스 - `postgres` (5432): `Dockerfile.postgres`로 `maxminddb_fdw`를 빌드하여 확장 설치 후 `GeoLite2-City.mmdb`를 FDW로 읽고, 로컬 테이블로 적재합니다. 초기 적재 완료 후 mmdb 없이도 DB에서 조회가 가능합니다. - `api` (8080): 기본적으로 Postgres 백엔드(`GEOIP_BACKEND=postgres`)를 사용해 조회합니다. - 볼륨 - `./GeoLite2-City.mmdb:/initial_data/GeoLite2-City.mmdb:ro` (Postgres 초기 적재용) - `pgdata` (DB 데이터 지속) ## 환경 변수 - 공통 - `PORT` (기본 `8080`): 서버 리스닝 포트 - `GEOIP_BACKEND` (`mmdb`|`postgres`, 기본 `mmdb`) - MMDB 모드 - `GEOIP_DB_PATH` (기본 `/initial_data/GeoLite2-City.mmdb`): GeoIP 데이터베이스 경로 - Postgres 모드 - `DATABASE_URL`: 예) `postgres://geoip_readonly:geoip_readonly@postgres:5432/geoip?sslmode=disable` - `GEOIP_LOOKUP_QUERY` (선택): 기본은 `geoip.lookup_city($1)` 사용 ## 사용법 - 헬스체크: `GET /health` - 조회: `GET /lookup?ip=` - `ip` 생략 시 호출자 IP를 사용 예시: ```bash curl "http://localhost:8080/lookup?ip=1.1.1.1" ``` 응답 예시: ```json { "IP": "1.1.1.1", "Country": "Australia", "Region": "Queensland", "City": "South Brisbane", "Address": "South Brisbane, Queensland, Australia", "Latitude": -27.4748, "Longitude": 153.017 } ``` ## 개발 참고 - 주요 코드: `cmd/server/main.go`, `internal/geo` (MMDB/Postgres resolver) - 테스트 실행: `go test ./...` - Postgres 통합 테스트 실행 시 `GEOIP_TEST_DATABASE_URL`을 설정하면 DB 백엔드 조회 테스트가 수행됩니다(미설정 시 skip). - 컨테이너 빌드: `docker build -t geoip:local .` ## Postgres/FDW 쿼리 예시 - 단건 조회 함수 (CIDR 매칭): `SELECT * FROM geoip.lookup_city('1.1.1.1');` - 원시 테이블 조회: `SELECT * FROM geoip.city_blocks LIMIT 5;` - API는 `lookup_city(inet)`를 사용하여 가장 구체적인 네트워크(prefix) 한 건을 반환합니다. ## 보안 및 운영 주의사항 - GeoLite2 라이선스 준수: `GeoLite2-City.mmdb` 교체 시 기존 파일을 대체하여 재시작하세요. - Postgres 포트(5432) 외부 노출 시 방화벽/보안 그룹으로 제한하고 강한 비밀번호를 사용하세요. - DB는 읽기 전용 계정(`geoip_readonly`)을 기본으로 사용하며, 초기 스키마에서 `default_transaction_read_only`를 강제합니다.