← Quay lại blog

SOCKS5 vs SOCKS5h: Khắc phục rò rỉ DNS trong Python, curl và Selenium

Tìm hiểu lý do tại sao khi làm việc qua SOCKS5, các yêu cầu DNS đi trực tiếp từ IP của bạn, sự khác biệt giữa SOCKS5h và cách khắc phục lỗ hổng này trong Python, curl, Selenium và trình duyệt chống phát hiện.

📅30 tháng 10, 2026

Bạn đã thiết lập proxy SOCKS5, lưu lượng có vẻ như đi qua nó, IP trong trình duyệt hiển thị đúng — nhưng các trang web vẫn thấy khu vực thực tế của bạn hoặc nhà cung cấp bắt đầu nghi ngờ điều gì đó. Nguyên nhân gần như luôn giống nhau: các yêu cầu DNS đi trực tiếp từ máy tính của bạn, bỏ qua proxy. Trong bài viết này, chúng ta sẽ tìm hiểu lý do tại sao điều này xảy ra, sự khác biệt giữa SOCKS5 và SOCKS5h và cách khắc phục rò rỉ này trong mã và trong các công cụ sẵn có.

SOCKS5 là gì và sự khác biệt với SOCKS5h

SOCKS5 là một giao thức proxy hoạt động ở cấp độ kết nối TCP/UDP và không phân tích nội dung của các gói tin, khác với proxy HTTP(S). Điều này làm cho nó trở nên đa năng: thông qua SOCKS5, bạn có thể proxy hầu như bất kỳ lưu lượng nào — trình duyệt, Telegram, ứng dụng torrent, script Python. Nhưng phiên bản cổ điển của SOCKS5 có một đặc điểm quan trọng: việc phân giải tên miền (DNS) theo mặc định được thực hiện ở phía khách hàng, tức là trên máy tính của bạn, chứ không phải trên máy chủ proxy.

SOCKS5h là cùng một giao thức, nhưng với modifier "h" (hostname), chỉ định cho ứng dụng khách không tự phân giải tên miền mà gửi nó như nó là đến máy chủ proxy, và máy chủ proxy sẽ thực hiện yêu cầu DNS thay mặt cho nó. Sự khác biệt chỉ nằm ở một chữ cái, nhưng hậu quả đối với tính ẩn danh và sự ổn định trong hoạt động là rất lớn.

Quan trọng là phải hiểu rằng: SOCKS5h không phải là một giao thức riêng biệt, mà là một thỏa thuận ở cấp độ thư viện hoặc ứng dụng cụ thể về cách tạo yêu cầu đến proxy. Máy chủ proxy hoạt động giống nhau trong cả hai trường hợp, chỉ khác nhau ở chỗ ai khởi xướng việc phân giải DNS — khách hàng hay máy chủ.

Tại sao các yêu cầu DNS lại bỏ qua proxy

Khi bạn truy cập một địa chỉ dạng https://example.com, trước khi thiết lập kết nối, ứng dụng cần biết địa chỉ IP của miền này. Quá trình này được gọi là phân giải DNS. Khi làm việc qua SOCKS5 thông thường, nhiều thư viện và cài đặt hệ thống thực hiện việc phân giải qua máy chủ DNS hệ thống — cái mà được chỉ định trong cài đặt mạng của nhà cung cấp hoặc router của bạn.

Kết quả là một tình huống nghịch lý: chính lưu lượng HTTP/TCP đi qua proxy và trông như thể yêu cầu đến từ IP của máy chủ proxy, trong khi yêu cầu DNS "IP của example.com là gì?" lại đi trực tiếp từ IP thực tế của bạn đến máy chủ DNS của nhà cung cấp. Đây chính là rò rỉ DNS (DNS leak). Trang web hoặc dịch vụ phân tích hoạt động mạng ở cấp độ sâu hơn (và các phương pháp phát hiện như vậy được các hệ thống chống gian lận Facebook, Google, TikTok sử dụng tích cực), có thể thấy sự không nhất quán giữa IP của kết nối và nguồn của yêu cầu DNS.

Nguyên nhân là do giao thức SOCKS5 ban đầu được phát triển như một lớp vận chuyển cho các kết nối IP đã sẵn sàng, chứ không phải cho việc phân giải tên. Các nhà phát triển thư viện và tiện ích đã phải thực hiện riêng chức năng truyền yêu cầu DNS qua đường hầm — từ đó SOCKS5h ra đời như một chỉ dẫn rõ ràng "hãy tự phân giải miền, đừng để tôi làm".

Rò rỉ DNS nguy hiểm như thế nào trong thực tế

Đối với nhà phát triển parser hoặc script tự động hóa, rò rỉ DNS không phải là lý thuyết trừu tượng, mà là lý do cụ thể dẫn đến việc bị khóa và cấm tài khoản. Chúng ta hãy xem xét một vài kịch bản.

Parsing các thị trường và trang web. Nếu bạn đang parse Wildberries, Ozon hoặc một nguồn khác qua proxy từ khu vực cần thiết, nhưng các yêu cầu DNS lại đi qua nhà cung cấp, hệ thống chống bot có thể ghi nhận sự không nhất quán về địa lý và tăng mức độ nghi ngờ của phiên làm việc — thậm chí đến mức captcha hoặc tạm thời khóa IP của proxy.

Đa tài khoản và phân bổ lưu lượng. Khi làm việc với Facebook Ads, TikTok Ads hoặc Google Ads qua nhiều tài khoản, các hệ thống chống gian lận phân tích hàng chục thông số, bao gồm cả dấu vân tay DNS. Nếu các yêu cầu DNS của nhiều tài khoản "khác nhau" đột nhiên đi qua cùng một máy chủ DNS của nhà cung cấp, đây là tín hiệu để gộp các tài khoản thành một cụm — và do đó, chuỗi cấm (chain-ban).

Tự động hóa trong Selenium/Playwright. Các script mô phỏng hành động của người dùng trong trình duyệt đặc biệt dễ bị tổn thương: chính trình duyệt có thể phân giải DNS qua cài đặt hệ thống của OS, bỏ qua proxy chỉ được chỉ định cho lưu lượng HTTP. Kết quả là toàn bộ fingerprint mạng còn lại tiết lộ vị trí thực tế.

Đối với hầu hết các nhiệm vụ này, việc sử dụng proxy cư trú với việc phân giải DNS được cấu hình chính xác ở phía máy chủ là rất quan trọng — điều này giảm thiểu đáng kể nguy cơ phát hiện qua các dấu hiệu mạng.

Cách kiểm tra xem có rò rỉ DNS hay không

Trước khi sửa chữa vấn đề, bạn nên chắc chắn rằng nó thực sự tồn tại. Dưới đây là một vài cách kiểm tra nhanh.

  1. Mở trang web dnsleaktest.com hoặc ipleak.net qua kết nối proxy của bạn và chạy bài kiểm tra mở rộng (Extended test).
  2. So sánh danh sách các máy chủ DNS trong kết quả với nhà cung cấp internet thực tế của bạn. Nếu bạn thấy nhà cung cấp thay vì trung tâm dữ liệu của proxy — rò rỉ đã được xác nhận.
  3. Đối với dòng lệnh, hãy sử dụng bộ lệnh tcpdump hoặc Wireshark, lọc lưu lượng theo cổng 53 (DNS) — nếu các gói đi trực tiếp đến máy chủ của nhà cung cấp, thay vì qua đường hầm proxy, vấn đề nằm ở phía bạn.
  4. Trong Python, bạn có thể nhanh chóng kiểm tra việc phân giải bằng cách sử dụng socket.getaddrinfo() trước và sau khi bật proxy — nếu IP trùng khớp với kết quả không có proxy, việc phân giải đang diễn ra cục bộ.

Khắc phục trong Python (requests, PySocks, urllib3)

Lỗi thường gặp nhất trong các script Python là việc sử dụng thư viện requests cùng với PySocks mà không chỉ định rõ ràng sơ đồ socks5h. Sự khác biệt chỉ nằm ở một ký tự, nhưng chính nó quyết định ai sẽ phân giải miền.

import requests

# XẤU: DNS được phân giải cục bộ, bỏ qua proxy
proxies_leak = {
    "http": "socks5://user:pass@proxy_host:1080",
    "https": "socks5://user:pass@proxy_host:1080",
}

# TỐT: DNS được phân giải ở phía máy chủ proxy
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])

Để hoạt động chính xác với sơ đồ socks5h qua requests, bạn sẽ cần cài đặt phụ thuộc:

pip install "requests[socks]" PySocks

Nếu bạn sử dụng urllib3 ở cấp độ thấp, ví dụ sẽ như sau:

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)

Đối với các script bất đồng bộ trên aiohttp, thư viện aiohttp-socks được sử dụng, nơi sơ đồ được chỉ định giống như sau:

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())

Khắc phục trong curl

Trong curl cũng có hai cờ khác nhau cho proxy SOCKS5, và sự nhầm lẫn giữa chúng là nguyên nhân cổ điển của rò rỉ DNS trong các script bash.

# XẤU: phân giải trên máy cục bộ
curl --socks5 proxy_host:1080 https://example.com

# TỐT: phân giải ở phía máy chủ proxy
curl --socks5-hostname proxy_host:1080 https://example.com

# Với xác thực
curl --socks5-hostname user:pass@proxy_host:1080 https://example.com

Cờ --socks5-hostname là tương đương trực tiếp với socks5h trong các công cụ khác. Nó thông báo cho curl: "đừng động vào DNS, chỉ cần truyền miền đến máy chủ proxy như nó là".

Khắc phục trong Selenium và Playwright

Với tự động hóa trình duyệt, tình huống phức tạp hơn: chính Chrome hoặc Firefox có thể phân giải DNS qua cài đặt hệ thống theo mặc định, bỏ qua proxy chỉ được chỉ định ở cấp độ yêu cầu mạng. Đối với Selenium với Chrome, bạn cần bật rõ ràng việc phân giải qua proxy bằng cách sử dụng cờ khởi động trình duyệt.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--proxy-server=socks5://proxy_host:1080")
# Cờ quan trọng: phân giải DNS qua proxy
options.add_argument("--host-resolver-rules=MAP * ~NOTFOUND , EXCLUDE proxy_host")

driver = webdriver.Chrome(options=options)
driver.get("https://example.com")

Trong Playwright, tình huống đơn giản hơn: thư viện mặc định phân giải DNS qua proxy nếu nó được chỉ định trong cấu hình ngữ cảnh trình duyệt.

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()

Tuy nhiên, luôn luôn kiểm tra hành vi thực tế qua dnsleaktest.com sau khi cấu hình — hành vi có thể khác nhau giữa các phiên bản Chromium.

Cấu hình trong trình duyệt chống phát hiện

Nếu bạn không viết mã mà làm việc qua các trình duyệt chống phát hiện như Dolphin Anty, AdsPower, Multilogin hoặc GoLogin — tin tốt là hầu hết trong số chúng đã tự động phân giải DNS qua máy chủ proxy khi chọn giao thức SOCKS5, mà không cần chỉ định "h" bằng tay. Đây là một trong những lợi thế chính của chúng so với các script tự viết.

Tuy nhiên, bạn nên kiểm tra điều này trong thực tế: mở hồ sơ trong trình duyệt chống phát hiện, truy cập dnsleaktest.com và chạy bài kiểm tra mở rộng ngay trong hồ sơ. Nếu bạn thấy các máy chủ DNS tương ứng với khu vực của proxy của bạn, chứ không phải nhà cung cấp thực tế của bạn — cấu hình là chính xác. Nếu không, hãy liên hệ với hỗ trợ của trình duyệt chống phát hiện cụ thể hoặc thay đổi loại proxy sang HTTP(S), nơi vấn đề phân giải DNS không xảy ra nghiêm trọng như vậy, vì proxy HTTP luôn làm việc với các URL đầy đủ.

Đối với việc tạo tài khoản trên Instagram, TikTok và quản lý các tài khoản quảng cáo trên Facebook Ads, proxy di động hoạt động tốt — nhờ vào việc xoay vòng IP động của các nhà mạng, chúng ít bị nghi ngờ bởi các hệ thống chống gian lận hơn, ngay cả khi có một chút rò rỉ DNS trong chuỗi.

Bảng so sánh các giao thức proxy

Giao thức Ai phân giải DNS Nguy cơ rò rỉ Nơi áp dụng
SOCKS5 Khách hàng (máy tính của bạn) Cao Chỉ khi DNS không quan trọng (kiểm tra cục bộ)
SOCKS5h Máy chủ proxy Thấp Parsing, đa tài khoản, tự động hóa
Proxy HTTP/HTTPS Máy chủ proxy (theo mặc định) Thấp Lưu lượng web, trình duyệt, yêu cầu API

Nếu nhiệm vụ của bạn là thu thập dữ liệu tốc độ cao mà không phụ thuộc vào khu vực cụ thể của người dùng, hãy xem xét proxy trung tâm dữ liệu — chúng rẻ hơn tính theo khối lượng lưu lượng và hoạt động tốt khi kết hợp với SOCKS5h cho việc parsing, nơi tốc độ quan trọng hơn là việc che giấu dưới dạng người dùng thực.

Danh sách kiểm tra trước khi khởi động dự án

  • Sử dụng sơ đồ socks5h://, không phải socks5:// trong tất cả các thư viện và cấu hình.
  • Đối với curl, sử dụng cờ --socks5-hostname, không phải --socks5.
  • Trong Selenium, đã thêm cờ --host-resolver-rules hoặc sử dụng Playwright với phân giải proxy tích hợp.
  • Đã kiểm tra kết quả trên dnsleaktest.com hoặc ipleak.net sau khi cấu hình, không phải trước.
  • Trong trình duyệt chống phát hiện, đã kiểm tra dấu vân tay DNS bên trong chính hồ sơ, không chỉ IP bên ngoài.
  • Đối với các nhiệm vụ có yêu cầu cao về tính ẩn danh, xem xét sử dụng proxy cư trú hoặc di động thay vì proxy trung tâm dữ liệu.

Kết luận

Sự khác biệt giữa SOCKS5 và SOCKS5h chỉ là một chữ cái, nhưng nó quyết định ai sẽ phân giải yêu cầu DNS: máy tính của bạn hay máy chủ proxy. Rò rỉ DNS là một trong những nguyên nhân khó phát hiện nhưng thường gặp nhất dẫn đến việc bị phát hiện khi parsing, đa tài khoản và tự động hóa các tài khoản quảng cáo. Kiểm tra qua dnsleaktest.com và chỉ định rõ ràng sơ đồ socks5h trong mã, lệnh curl hoặc cài đặt tự động hóa trình duyệt sẽ khắc phục lỗ hổng này chỉ trong vài phút.

Nếu bạn chỉ đang chọn cơ sở hạ tầng cho nhiệm vụ — cho việc parsing và làm việc với API, proxy trung tâm dữ liệu là lựa chọn tốt hơn, cho đa tài khoản và mạng xã hội — proxy cư trú, và cho dấu vân tay mạng tự nhiên nhất khi làm việc với các ứng dụng di động — proxy di động. Trong bất kỳ trường hợp nào, việc cấu hình chính xác việc phân giải DNS qua SOCKS5h vẫn là bước cần thiết trước khi khởi động dự án trong môi trường sản xuất.