Go (net/http)
Go는 매우 빠른 네트워크 서비스를 위해 설계되었습니다. ProxyTracer는 10ms 이내에 응답하기 때문에 표준 net/http 미들웨어 핸들러 내에서 이를 호출하면 고루틴에 눈에 띄는 병목 현상이 발생하지 않습니다.
미들웨어
이 구현은 'X-Forwarded-For' 헤더에서 IP를 안전하게 추출하고, 엄격한 시간 제한을 적용한 Go의 기본 'http.Client'를 활용하며, 악의적인 연결이 무거운 애플리케이션 로직에 도달하기 직전에 삭제합니다.
package middleware
import (
"encoding/json"
"log"
"net/http"
"os"
"strings"
"time"
)
// ProxyTracerResponse는 {"proxy": true|false} JSON 응답에 정확히 매핑됩니다
type ProxyTracerResponse struct {
Proxy bool `json:"proxy"`
}
func ProxyTracer(next http.Handler) http.Handler {
apiKey := os.Getenv("PROXYTRACER_API_KEY")
// 엄격한 500ms 타임아웃을 적용한 재사용 가능한 클라이언트 초기화
client := &http.Client{
Timeout: 500 * time.Millisecond,
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 1. 로드 밸런서 뒤의 실제 IP를 안전하게 추출
ip := r.Header.Get("X-Forwarded-For")
if ip == "" {
ip = strings.Split(r.RemoteAddr, ":")[0]
} else {
ip = strings.Split(ip, ",")[0]
}
ip = strings.TrimSpace(ip)
// 로컬 개발 환경인 경우 통과
if ip == "127.0.0.1" || ip == "::1" || ip == "" {
next.ServeHTTP(w, r)
return
}
// 2. ProxyTracer API 쿼리
req, err := http.NewRequest("GET", "https://api.proxytracer.com/v1/check/"+ip, nil)
if err == nil {
req.Header.Set("Authorization", "Bearer "+apiKey)
resp, err := client.Do(req)
if err == nil && resp.StatusCode == http.StatusOK {
defer resp.Body.Close()
var ptResp ProxyTracerResponse
if err := json.NewDecoder(resp.Body).Decode(&ptResp); err == nil {
// 3. 프록시/VPN이 감지되면 연결 차단
if ptResp.Proxy {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusForbidden)
w.Write([]byte(`{"error": "Access Denied: VPN or Proxy detected."}`))
return // 핸들러 체인 숏서킷(short-circuit)
}
}
} else {
// Fail open: 가동 시간 보장을 위해 오류를 기록하고 요청 통과 허용
log.Printf("ProxyTracer API error: %v", err)
}
}
// 4. 정상 트래픽인 경우 다음 핸들러로 전달
next.ServeHTTP(w, r)
})
}사용법
간단히 미들웨어로 기본 라우터나 민감한 특정 엔드포인트를 래핑하세요.
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/api/secure-data", secureHandler)
// 전체 멀티플렉서를 ProxyTracer 미들웨어로 래핑
log.Fatal(http.ListenAndServe(":8080", middleware.ProxyTracer(mux)))
}최종 수정일: