v1.7.2 — External Datasources + Dynamic VPC CIDR
Prometheus, Loki, ClickHouse 등 7종 외부 데이터소스를 Grafana 스타일로 관리할 수 있는 기능을 추가했습니다. SSRF 방어와 SQL Injection 방지를 포함한 보안 계층, 동적 VPC CIDR 설정, 그리고 데이터소스 연결 문제를 진단하는 전용 에이전트도 함께 릴리스합니다.
외부 데이터소스 7종 · SSRF 방어 · SQL Injection 방지 · 동적 VPC CIDR · 데이터소스 진단 에이전트
외부 데이터소스 관리
Grafana의 데이터소스 관리와 유사한 방식으로 외부 관측성(Observability) 도구를 AWSops에서 직접 연결하고 쿼리할 수 있습니다.
지원 데이터소스 7종
| 타입 | 쿼리 언어 | 주요 용도 |
|---|---|---|
| Prometheus | PromQL | 메트릭 수집/쿼리 |
| Loki | LogQL | 로그 집계/검색 |
| Tempo | TraceQL | 분산 추적 |
| ClickHouse | SQL | 분석용 데이터 웨어하우스 |
| Jaeger | Trace API | 분산 추적 |
| Dynatrace | API | APM / 풀스택 관측 |
| Datadog | API | 모니터링 / APM |
기능 상세
| 기능 | 설명 |
|---|---|
| CRUD | 데이터소스 등록/수정/삭제 (Admin 전용) |
| Connection Test | 원클릭 연결 테스트 + 응답 시간(ms) 측정 |
| Query Execution | 타입별 쿼리 언어로 즉시 실행 |
| 4종 인증 | None, Basic Auth, Bearer Token, Custom Header |
| Credential Masking | API 응답에서 비밀번호/토큰 → *** 마스킹 |
| i18n | 한국어 + 영어 지원 |
인증 설정 예시
4가지 인증 방식을 지원하며, 데이터소스 타입에 따라 적절한 방식을 선택합니다:
// src/lib/datasource-client.ts
type AuthType = 'none' | 'basic' | 'bearer' | 'custom-header';
// Basic Auth → Authorization: Basic base64(user:pass)
// Bearer Token → Authorization: Bearer <token>
// Custom Header → 사용자 지정 헤더명: 값
config.json 데이터소스 설정
data/config.json에 datasources 배열을 추가하여 데이터소스를 관리합니다:
{
"costEnabled": true,
"agentRuntimeArn": "arn:aws:bedrock-agentcore:...",
"datasources": [
{
"id": "prom-1",
"name": "Production Prometheus",
"type": "prometheus",
"url": "https://prometheus.example.com:9090",
"authType": "bearer",
"authConfig": { "token": "***" },
"isDefault": true
},
{
"id": "ch-1",
"name": "Analytics ClickHouse",
"type": "clickhouse",
"url": "https://clickhouse.example.com:8443",
"authType": "basic",
"authConfig": { "username": "reader", "password": "***" }
}
]
}
기존 accounts[] 배열과 동일한 패턴입니다 — data/config.json만 수정하면 코드 변경 없이 데이터소스를 추가/제거할 수 있습니다. Admin 권한을 가진 사용자만 CRUD 작업이 가능합니다.
보안: SSRF 방어
외부 URL에 요청을 보내기 전에 SSRF(Server-Side Request Forgery) 공격을 방지하는 검증 계층을 적용합니다.
// src/lib/datasource-client.ts (간소화)
function validateUrl(url: string): void {
const parsed = new URL(url);
const hostname = parsed.hostname;
// Private IP 대역 차단
const privatePatterns = [
/^10\./, // 10.0.0.0/8
/^172\.(1[6-9]|2\d|3[01])\./, // 172.16.0.0/12
/^192\.168\./, // 192.168.0.0/16
/^127\./, // Loopback
/^169\.254\./, // Link-local
/^0\./, // Current network
];
// Cloud metadata endpoint 차단
if (hostname === '169.254.169.254') {
throw new Error('SSRF blocked: cloud metadata endpoint');
}
for (const pattern of privatePatterns) {
if (pattern.test(hostname)) {
throw new Error(`SSRF blocked: private IP range (${hostname})`);
}
}
}
외부 URL을 사용자가 입력하는 모든 기능에서 SSRF 방어는 필수입니다. 방어가 없으면 공격자가 http://169.254.169.254/latest/meta-data/로 EC2 IAM 자격증명을 탈취하거나, 내부 네트워크의 서비스에 접근할 수 있습니다. AWSops는 Private IP 대역, Cloud metadata endpoint, Link-local, Loopback 주소를 모두 차단합니다.
보안: ClickHouse SQL Injection 방지
ClickHouse 쿼리는 사용자 입력을 직접 문자열에 삽입하지 않고 파라미터화된 쿼리를 사용합니다:
// src/lib/datasource-client.ts — ClickHouse 쿼리 실행
// 위험: 직접 문자열 보간 (사용하지 않음)
// const query = `SELECT * FROM logs WHERE service = '${userInput}'`;
// 안전: 파라미터화된 쿼리
const response = await fetch(`${url}/?param_service=${encodeURIComponent(service)}`, {
method: 'POST',
body: `SELECT * FROM logs WHERE service = {service:String}`,
headers: { 'Content-Type': 'text/plain' },
});
ClickHouse는 {name:Type} 형식의 파라미터 바인딩을 지원합니다. URL 쿼리 파라미터로 param_name=value를 전달하면 서버가 안전하게 바인딩합니다. 이 방식은 SQL Injection을 원천 차단합니다.
PromQL 쿼리 예시
Prometheus 데이터소스에서 PromQL로 메트릭을 조회하는 예시:
# 최근 5분간 CPU 사용률 (Pod별)
rate(container_cpu_usage_seconds_total{namespace="production"}[5m])
# 메모리 사용량 상위 10개 Pod
topk(10, container_memory_working_set_bytes{namespace="production"})
# HTTP 요청 에러율 (5xx)
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m])) * 100
// API를 통한 PromQL 실행
const response = await fetch('/awsops/api/datasources', {
method: 'POST',
body: JSON.stringify({
action: 'query',
datasourceId: 'prom-1',
query: 'rate(container_cpu_usage_seconds_total{namespace="production"}[5m])',
}),
});
Dynamic VPC CIDR
CDK 스택에서 VPC CIDR을 컨텍스트 파라미터로 설정할 수 있게 변경했습니다.
Before / After
| 항목 | Before (v1.7.1) | After (v1.7.2) |
|---|---|---|
| VPC CIDR | 하드코딩 | newVpcCidr 컨텍스트 파라미터 |
| 기본값 | — | 10.10.0.0/16 |
| TGW Route CIDR | tgwRouteCidr (단일) | tgwRouteCidrs (복수, 콤마 구분) |
| 하위 호환 | — | tgwRouteCidr 기존 파라미터 유지 |
# 기본 VPC CIDR (10.10.0.0/16)
cdk deploy -c newVpcCidr=10.10.0.0/16
# 커스텀 VPC CIDR + 다중 TGW 라우트
cdk deploy \
-c newVpcCidr=10.20.0.0/16 \
-c tgwRouteCidrs=10.10.0.0/16,10.30.0.0/16,172.16.0.0/12
기존 tgwRouteCidr 파라미터는 그대로 동작합니다. 새로운 tgwRouteCidrs는 콤마로 구분된 여러 CIDR을 지원하며, 두 파라미터를 동시에 사용할 수도 있습니다. tgwRouteCidrs가 우선 적용됩니다.
데이터소스 진단 에이전트
외부 데이터소스 연결 문제를 체계적으로 진단하는 전용 에이전트가 추가되었습니다. AI 라우팅에 priority 11 datasource 라우트가 신규 등록됩니다.
| 항목 | Before (v1.7.1) | After (v1.7.2) |
|---|---|---|
| AI 라우트 수 | 10 | 11 |
| 신규 라우트 | — | datasource (priority 11) |
| 진단 대상 | — | 네트워크, 인증, SSL/TLS, DNS |
진단 에이전트가 확인하는 항목:
- 네트워크: 대상 호스트 도달 가능 여부, 방화벽/보안그룹 설정
- 인증: 자격증명 유효성, 토큰 만료, 권한 부족
- SSL/TLS: 인증서 유효성, 만료, 체인 문제
- DNS: 호스트명 해석 실패, DNS 전파 지연
버전 비교
| 항목 | v1.7.1 | v1.7.2 | 변경 |
|---|---|---|---|
| 페이지 | 36 | 37 | +datasources |
| API 라우트 | 13 | 14 | +datasources API |
| AI 라우트 | 10 | 11 | +datasource 진단 |
| 데이터소스 타입 | 0 | 7 | 신규 기능 |
| 인증 방식 | — | 4종 | None/Basic/Bearer/Custom |
주요 파일 변경
| 파일 | 변경 내용 |
|---|---|
src/app/datasources/page.tsx | 데이터소스 관리 페이지 (Registry + Explore) |
src/app/api/datasources/route.ts | 데이터소스 CRUD + 연결 테스트 + 쿼리 실행 API |
src/lib/datasource-client.ts | HTTP 클라이언트 (SSRF 방어 + 인증 + 쿼리) |
src/lib/datasource-registry.ts | 7종 데이터소스 타입 레지스트리 |
src/lib/app-config.ts | DatasourceConfig 타입 추가 |
src/components/layout/Sidebar.tsx | Monitoring 카테고리에 Datasources 추가 |
infra-cdk/lib/awsops-stack.ts | newVpcCidr 컨텍스트 파라미터 + tgwRouteCidrs |
src/app/api/ai/route.ts | datasource 라우트 (priority 11) 추가 |
이번 데이터소스 페이지는 기존 Steampipe 쿼리가 아닌 외부 HTTP 엔드포인트와 통신하는 첫 번째 페이지입니다. 향후 외부 서비스를 연동할 때 datasource-client.ts의 SSRF 방어 + 인증 계층을 참고하세요.