SOCKS5 프록시를 설정했지만 트래픽이 그를 통해 흐르는 것처럼 보이고 브라우저에 표시되는 IP가 올바른데도 불구하고 웹사이트가 여전히 귀하의 실제 지역을 감지하거나 제공업체가 의심을 품기 시작합니다. 그 이유는 거의 항상 동일합니다: DNS 요청이 프록시를 우회하여 귀하의 컴퓨터에서 직접 나갑니다. 이 기사에서는 이러한 일이 발생하는 이유, SOCKS5와 SOCKS5h의 차이점, 그리고 코드와 기존 도구에서 이 누수를 어떻게 막을 수 있는지에 대해 설명합니다.
SOCKS5란 무엇이며 SOCKS5h와의 차이점
SOCKS5는 TCP/UDP 연결 수준에서 작동하는 프록시 프로토콜로, HTTP(S) 프록시와 달리 패킷의 내용을 해석하지 않습니다. 이는 SOCKS5가 매우 유연하다는 것을 의미합니다: 브라우저, Telegram, 토렌트 클라이언트, Python 스크립트 등 거의 모든 트래픽을 프록시할 수 있습니다. 그러나 전통적인 SOCKS5 구현에는 중요한 특징이 있습니다: 도메인 이름 해석(DNS)은 기본적으로 클라이언트 측, 즉 귀하의 컴퓨터에서 수행되며, 프록시 서버 측에서는 수행되지 않습니다.
SOCKS5h는 동일한 프로토콜이지만 "h"(hostname) 수정자가 추가되어 클라이언트 애플리케이션에 도메인을 스스로 해석하지 말고 그대로 프록시 서버에 전송하도록 지시합니다. 그러면 프록시가 자신의 이름으로 DNS 요청을 수행합니다. 한 글자의 차이지만, 익명성과 안정성 측면에서 그 결과는 근본적으로 다릅니다.
중요한 점은 SOCKS5h가 별도의 프로토콜이 아니라 특정 라이브러리나 애플리케이션 수준에서 프록시에 대한 요청을 형성하는 방법에 대한 합의라는 것입니다. 실제 프록시 서버는 두 경우 모두 동일하게 작동하며, DNS 해석을 누가 시작하는지만 다릅니다 — 클라이언트인지 서버인지.
왜 DNS 요청이 프록시를 우회하는가
https://example.com와 같은 주소에 접근할 때, 연결을 설정하기 전에 애플리케이션은 해당 도메인의 IP 주소를 알아야 합니다. 이 과정을 DNS 해석이라고 합니다. 일반적인 SOCKS5를 사용할 때 많은 라이브러리와 시스템 설정이 시스템 DNS 서버를 통해 해석을 수행합니다 — 이는 귀하의 제공업체나 라우터의 네트워크 설정에 지정된 것입니다.
결과적으로 역설적인 상황이 발생합니다: HTTP/TCP 트래픽은 프록시를 통해 나가고 요청이 프록시 서버의 IP에서 온 것처럼 보이지만, DNS 요청 "example.com의 IP는 무엇인가?"는 귀하의 실제 IP에서 제공업체의 DNS 서버로 직접 나갑니다. 이것이 바로 DNS 누수(DNS leak)입니다. 네트워크 활동을 더 깊이 분석하는 웹사이트나 서비스(이러한 탐지 방법은 Facebook, Google, TikTok의 안티사기 시스템에서 활발히 사용됨)는 연결 IP와 DNS 요청의 출처 간의 불일치를 볼 수 있습니다.
그 이유는 SOCKS5 프로토콜이 원래 이미 설정된 IP 연결을 위한 전송 수준으로 개발되었기 때문이며, 이름 해석을 위한 것이 아닙니다. 라이브러리 및 유틸리티 개발자들은 DNS 요청을 터널을 통해 전달하는 기능을 별도로 구현해야 했습니다 — 그래서 SOCKS5h가 "도메인을 스스로 해석하지 말고 나에게 그대로 전달하라"는 명시적인 지시로 등장했습니다.
실제로 DNS 누수가 위험한 이유
파서나 자동화 스크립트를 개발하는 사람에게 DNS 누수는 추상적인 이론이 아니라 계정 차단 및 금지의 구체적인 원인입니다. 몇 가지 시나리오를 살펴보겠습니다.
마켓플레이스 및 웹사이트 파싱. Wildberries, Ozon 또는 다른 리소스를 필요한 지역의 프록시를 통해 파싱하는 경우, DNS 요청이 제공업체를 통해 나가면 안티봇 시스템이 지리적 위치의 불일치를 감지하고 세션의 의심 수준을 높일 수 있습니다 — CAPTCHA 또는 프록시 IP의 일시적 차단에 이를 수 있습니다.
멀티 계정 및 트래픽 중재. Facebook Ads, TikTok Ads 또는 Google Ads와 함께 여러 계정을 사용할 때 안티사기 시스템은 DNS 지문을 포함한 수십 가지 매개변수를 분석합니다. 여러 "다른" 계정의 DNS 요청이 갑자기 동일한 제공업체의 DNS 서버를 통해 나가면, 이는 계정을 하나의 클러스터로 통합하라는 신호가 됩니다 — 결과적으로 차단 체인(chain-ban)이 발생할 수 있습니다.
Selenium/Playwright에서의 자동화. 브라우저에서 사용자 행동을 에뮬레이트하는 스크립트는 특히 취약합니다: 브라우저 자체가 시스템 설정을 통해 DNS를 해석할 수 있으며, HTTP 트래픽을 위해서만 설정된 프록시를 무시할 수 있습니다. 결국 나머지 네트워크 지문이 실제 위치를 드러내게 됩니다.
이러한 작업의 대부분에서는 주거용 프록시를 사용하는 것이 중요합니다. 서버 측에서 올바르게 설정된 DNS 해석을 통해 네트워크 신호에 대한 탐지 위험을 크게 줄일 수 있습니다.
DNS 누수가 있는지 확인하는 방법
문제를 해결하기 전에 실제로 문제가 있는지 확인하는 것이 좋습니다. 다음은 몇 가지 빠른 확인 방법입니다.
- 귀하의 프록시 연결을 통해
dnsleaktest.com또는ipleak.net웹사이트를 열고 확장 테스트(Extended test)를 실행합니다. - 결과에서 DNS 서버 목록을 실제 인터넷 제공업체와 비교합니다. 제공업체 대신 데이터 센터의 프록시가 보인다면 누수가 확인된 것입니다.
- 명령줄에서
tcpdump또는Wireshark를 사용하여 포트 53(DNS)로 트래픽을 필터링합니다 — 패킷이 프록시 터널을 통해서가 아니라 제공업체의 서버로 직접 간다면 문제는 귀하의 측에 있습니다. - Python에서는
socket.getaddrinfo()를 통해 프록시를 켠 후와 끈 후의 해석을 빠르게 확인할 수 있습니다 — IP가 프록시 없이 얻은 결과와 일치한다면 해석이 로컬에서 이루어지고 있는 것입니다.
Python에서 수정하기 (requests, PySocks, urllib3)
Python 스크립트에서 가장 흔한 오류는 requests 라이브러리를 PySocks와 함께 사용할 때 socks5h 스킴을 명시적으로 지정하지 않는 것입니다. 한 문자 차이지만, 이 문자가 도메인을 해석하는 주체를 결정합니다.
import requests
# 나쁨: DNS가 로컬에서 해석되어 프록시를 우회함
proxies_leak = {
"http": "socks5://user:pass@proxy_host:1080",
"https": "socks5://user:pass@proxy_host:1080",
}
# 좋음: DNS가 프록시 서버 측에서 해석됨
proxies_safe = {
"http": "socks5h://user:pass@proxy_host:1080",
"https": "socks5h://user:pass@proxy_host:1080",
}
response = requests.get("https://example.com", proxies=proxies_safe, timeout=10)
print(response.status_code)
print(response.text[:200])
socks5h 스킴이 requests를 통해 올바르게 작동하려면 다음 종속성을 설치해야 합니다:
pip install "requests[socks]" PySocks
저수준의 urllib3를 직접 사용하는 경우 예제는 다음과 같습니다:
from urllib3.contrib.socks import SOCKSProxyManager
proxy = SOCKSProxyManager(
"socks5h://user:pass@proxy_host:1080",
num_pools=10
)
response = proxy.request("GET", "https://example.com")
print(response.status)
aiohttp에서 비동기 스크립트를 사용할 경우 aiohttp-socks 라이브러리를 사용하며, 스킴은 다음과 같이 지정합니다:
import aiohttp
from aiohttp_socks import ProxyConnector
connector = ProxyConnector.from_url("socks5h://user:pass@proxy_host:1080")
async def fetch():
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get("https://example.com") as resp:
print(await resp.text())
curl에서 수정하기
curl에서도 SOCKS5 프록시에 대해 두 가지 다른 플래그가 있으며, 이들 간의 혼동은 bash 스크립트에서 DNS 누수의 전형적인 원인입니다.
# 나쁨: 로컬 머신에서 해석
curl --socks5 proxy_host:1080 https://example.com
# 좋음: 프록시 서버 측에서 해석
curl --socks5-hostname proxy_host:1080 https://example.com
# 인증 포함
curl --socks5-hostname user:pass@proxy_host:1080 https://example.com
--socks5-hostname 플래그는 다른 도구에서 socks5h와 동일한 기능을 합니다. curl에게 "DNS를 건드리지 말고, 도메인을 프록시 서버에 그대로 전달하라"고 지시합니다.
Selenium 및 Playwright에서 수정하기
브라우저 자동화의 경우 상황이 더 복잡합니다: Chrome 또는 Firefox는 기본적으로 시스템 설정을 통해 DNS를 해석할 수 있으며, 네트워크 요청 수준에서만 설정된 프록시를 무시할 수 있습니다. Selenium과 Chrome을 사용할 때는 브라우저를 시작할 때 프록시를 통해 DNS를 해석하도록 명시적으로 설정해야 합니다.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--proxy-server=socks5://proxy_host:1080")
# 매우 중요한 플래그: 프록시를 통해 DNS 해석
options.add_argument("--host-resolver-rules=MAP * ~NOTFOUND , EXCLUDE proxy_host")
driver = webdriver.Chrome(options=options)
driver.get("https://example.com")
Playwright에서는 상황이 더 간단합니다: 라이브러리는 기본적으로 브라우저 컨텍스트 설정에서 지정된 경우 프록시를 통해 DNS를 해석합니다.
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={"server": "socks5://proxy_host:1080"}
)
page = browser.new_page()
page.goto("https://example.com")
print(page.title())
browser.close()
그럼에도 불구하고 설정 후 항상 dnsleaktest.com을 통해 실제 동작을 확인하는 것이 좋습니다 — Chromium의 버전 간 동작이 다를 수 있습니다.
안티탐지 브라우저에서 설정하기
코드를 작성하지 않고 Dolphin Anty, AdsPower, Multilogin 또는 GoLogin과 같은 안티탐지 브라우저를 사용하는 경우, 대부분의 브라우저가 SOCKS5 프로토콜을 선택할 때 DNS를 자동으로 프록시 서버를 통해 해석한다는 좋은 소식이 있습니다. 이는 수동으로 "h"를 지정할 필요가 없습니다. 이것은 사용자 정의 스크립트에 비해 그들의 주요 장점 중 하나입니다.
그러나 실제로 이를 확인하는 것이 좋습니다: 안티탐지 브라우저에서 프로필을 열고 dnsleaktest.com으로 이동하여 프로필 내에서 확장 테스트를 실행합니다. 프록시의 지역과 일치하는 DNS 서버가 보이고 실제 제공업체가 보이지 않는다면 설정이 올바른 것입니다. 그렇지 않다면 특정 안티탐지 브라우저의 지원팀에 문의하거나 프록시 유형을 HTTP(S)로 변경하십시오. HTTP 프록시는 항상 전체 URL로 작업하기 때문에 DNS 해석 문제는 그렇게 심각하게 발생하지 않습니다.
Instagram, TikTok 계정을 생성하고 Facebook Ads 광고 계정을 운영하는 데는 모바일 프록시가 좋은 성능을 보입니다 — 이동통신사의 동적 IP 회전 덕분에 안티사기 시스템의 의심을 덜 받습니다. 작은 DNS 누수가 발생하더라도 말입니다.
프록시 프로토콜 비교표
| 프로토콜 | 누가 DNS를 해석하는가 | 누수 위험 | 어디에 적용할 것인가 |
|---|---|---|---|
| SOCKS5 | 클라이언트 (귀하의 컴퓨터) | 높음 | DNS가 중요하지 않은 경우에만 (로컬 테스트) |
| SOCKS5h | 프록시 서버 | 낮음 | 파싱, 멀티 계정, 자동화 |
| HTTP/HTTPS 프록시 | 프록시 서버 (기본값) | 낮음 | 웹 트래픽, 브라우저, API 요청 |
귀하의 작업이 특정 사용자 지역에 구애받지 않는 고속 데이터 수집이라면 데이터 센터 프록시를 고려하십시오 — 이들은 트래픽 양에 비해 저렴하며 SOCKS5h와 함께 사용하면 속도가 중요하고 주거 사용자로 가장할 필요가 없는 파싱에 적합합니다.
프로젝트 시작 전 체크리스트
socks5h://스킴을 모든 라이브러리 및 구성에서 사용하고socks5://를 사용하지 마십시오.- curl에서는
--socks5-hostname플래그를 사용하고--socks5를 사용하지 마십시오. - Selenium에서는
--host-resolver-rules플래그를 추가하거나 Playwright를 사용하여 내장된 프록시 해석을 사용하십시오. - 설정 후 dnsleaktest.com 또는 ipleak.net에서 결과를 확인했는지, 설정 전에 확인하지 않았는지 확인하십시오.
- 안티탐지 브라우저에서 DNS 지문을 프로필 내에서 테스트했는지, 외부 IP만 확인하지 않았는지 확인하십시오.
- 높은 익명성 요구 사항이 있는 작업에는 데이터 센터 대신 주거용 또는 모바일 프록시를 고려하십시오.
결론
SOCKS5와 SOCKS5h의 차이는 문자 하나에 불과하지만, 이는 DNS 요청을 해석하는 주체가 귀하의 컴퓨터인지 프록시 서버인지 결정합니다. DNS 누수는 파싱, 멀티 계정 및 광고 관리 자동화에서 탐지의 가장 눈에 띄지 않는, 그러나 빈번한 원인 중 하나입니다. dnsleaktest.com을 통한 확인과 코드, curl 명령 또는 브라우저 자동화 설정에서 socks5h 스킴을 명시적으로 지정하는 것은 이 구멍을 몇 분 안에 막을 수 있습니다.
작업에 필요한 인프라를 선택하는 경우 — 파싱 및 API 작업에는 데이터 센터 프록시가 더 적합하고, 멀티 계정 및 소셜 미디어에는 주거용 프록시가 적합하며, 모바일 애플리케이션 작업 시 최대한 자연스러운 네트워크 지문을 위해서는 모바일 프록시가 적합합니다. 이 모든 경우에서 SOCKS5h를 통한 DNS 해석의 올바른 설정은 프로덕션에서 프로젝트를 시작하기 전에 필수 단계로 남아 있습니다.