Go HTTP 클라이언트의 SOCKS5 호스트 이름 해석
Go 표준 HTTP transport에서 socks5와 socks5h가 서로 다른 DNS 모드를 선택하지 않는 이유를 알아봅니다.
Go 1.27.3 표준 HTTP transport에서 socks5와 socks5h는 대상 이름을 같은 방식으로 처리합니다. 호스트 이름 대상은 호스트 이름으로 프록시에 전달됩니다. 스킴을 바꿔도 curl처럼 로컬 DNS와 원격 DNS가 전환되지 않습니다.
package main
import (
"fmt"
"log"
"net/http"
"net/url"
"time"
)
func main() {
proxyURL, err := url.Parse("socks5://203.0.113.10:1080")
if err != nil {
log.Fatal(err)
}
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.Proxy = http.ProxyURL(proxyURL)
defer transport.CloseIdleConnections()
client := &http.Client{
Transport: transport,
Timeout: 15 * time.Second,
}
response, err := client.Get("https://example.com/")
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
fmt.Println(response.StatusCode)
}
문서용 주소를 자신의 SOCKS5 엔드포인트로 바꾸세요. 후보는 SOCKS5 프록시 목록에서 찾을 수 있습니다. 예제는 net/http 자체 transport를 사용하며, 다른 Go 라이브러리는 다르게 동작할 수 있습니다.
그래도 두 이름은 구분해야 합니다. 숫자 프록시 주소는 프록시 호스트 조회가 필요 없지만, 이름으로 지정한 프록시는 SOCKS 요청 전에 로컬에서 찾아야 합니다. 숫자 대상에는 해석할 대상 이름이 없으므로 호스트 이름 처리 방식을 보여 줄 수 없습니다. 실제 SOCKS 선택을 확인하려면 대상 필드에 이름이 담겼는지 주소가 담겼는지 살펴보세요.
표준 transport는 http, https, socks5, socks5h 프록시 스킴을 지원합니다. 일반적인 SOCKS 표기만으로 엔드포인트의 SOCKS5 지원이 입증되지는 않습니다. 예제는 TCP로 HTTP를 보내며 다른 SOCKS 명령이나 UDP 릴레이는 테스트하지 않습니다.