Go(net/http)
Go では、HTTP ミドルウェアが標準の http.Handler 実装をラップして受信ネットワークトラフィックをインターセプトします。ProxyTracer を Go HTTP サーバーに組み込むことで、高い並行処理環境下でも確定的な IP 評価を実現できます。
ミドルウェアの実装
このミドルウェアは r.RemoteAddr からリモート IP を抽出し、永続的な http.Client を使用して ProxyTracer API にクエリを実行して、接続がフラグ付けされた場合に即座に 403 Forbidden JSON ペイロードを書き込みます。
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 // ハンドラーチェーンをショートサーキット(即時終了)
}
}
} else {
// フェイルオープン: エラーをログに記録し、稼働率を維持するためリクエストの通過を許可
log.Printf("ProxyTracer API error: %v", err)
}
}
// 4. トラフィックは正常です。次のハンドラーへ処理を渡します
next.ServeHTTP(w, r)
})
}使用方法
使用方法: main.go のエントリポイントで、ルートの http.ServeMux または個別のルーターハンドラーを ProxyTracerMiddleware でラップします。
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/api/secure-data", secureHandler)
// マルチプレクサ全体をProxyTracerミドルウェアでラップ
log.Fatal(http.ListenAndServe(":8080", middleware.ProxyTracer(mux)))
}最終更新日: