Proxy-seller

HTTP/3 および SOCKS5 経由の UDP

Updated:

レジデンシャルプロキシは、SOCKS5経由でUDPトラフィックを転送します。これを使用して、レジデンシャルIPからHTTP/3(QUIC)経由でウェブサイトを開いたり、DNS、WebRTC、VoIP、オンラインゲームなど、その他のUDPプロトコルをルーティングしたりできます。

既存のすべてのリストで動作します — ホスト、ポート、ログインID、パスワードはすべて同じです。有効化や注文の手順は一切必要ありません。

仕組み

HTTP/3はQUIC上で動作し、QUICはUDP上で動作します。HTTPプロキシプロトコルはTCPのみを扱うため、UDPトラフィックはSOCKS5を経由します。

トラフィック

HTTPプロキシ

SOCKS5

TCP:HTTP/1.1、HTTP/2、その他のTCPプロトコル

✅

✅

UDP:HTTP/3 (QUIC)、DNS、WebRTC、VoIP、ゲーム

—

✅

最初のデータグラムがあなたのマシンから送信される前に、3つのやり取りが行われます:

  1. 接続と認証

    アプリはゲートウェイに対してSOCKS5接続を確立し、リストに登録されたログインIDとパスワードを使用してログインします。

  2. UDPリレーをリクエストする

    それはUDP ASSOCIATE リクエスト(RFC 1928)。ゲートウェイは、中継アドレス(ゲートウェイのIPアドレスと30000~39999の範囲のポート番号)を応答として返します。

  3. データグラムを送信する

    このアプリは、そのリレーにUDPデータグラムを送信します。各データグラムは、宛先を指定する短いSOCKS5ヘッダーで始まります。トラフィックは住宅用出口IPから送信され、応答も同じ経路で戻ってきます。

リレーは、SOCKS5 TCP接続が開いている間のみ稼働します。制御接続を閉じると、リレーも同時に閉じられます。

接続設定

設定

価値

手順

ユーザー名/パスワード認証付きのSOCKS5

ホスト

res.proxy-seller.com (ヨーロッパ)、us.res.proxy-seller.com (米国)、asia.res.proxy-seller.com (アジア)

移植

リストにある任意のポート(10000~10999)

ログインとパスワード

リストに記載されているログインIDとパスワード

UDPリレー

ゲートウェイのIPアドレス、ポート30000~39999

HTTPとSOCKS5は、ホスト、ポート、ログイン名、パスワードを共有しています。ゲートウェイはプロトコルを自動的に判別します。接続文字列をSOCKS5に変更するには、スキームのみを変更し、それ以外は変更しないでください:

http://LOGIN:[email protected]:10000
socks5://LOGIN:[email protected]:10000

ゲートウェイは単なるエントリポイントに過ぎません。どのゲートウェイを使用する場合でも、出口IPとその場所はリスト設定から取得されます。そのため、サーバーからの遅延が最も少ないゲートウェイを選択してください。

ネットワークで送信トラフィックが制限されている場合は、ポート30000~39999でのゲートウェイへのUDP通信を許可してください。以下のUDPチェックでタイムアウトが発生する主な原因は、この範囲がブロックされていることです。

ご自身で確認してください

  1. 接続を確認してください

    SOCKS5クライアントであればどれでも構いません —curl これで十分です:

    curl -x socks5h://LOGIN:[email protected]:10000 https://api.ipify.org

    応答はプロキシの出口IPです。socks5h://、ドメイン名の解決は、お使いのマシンではなくプロキシによって行われます。

  2. UDPを確認してください

    このスクリプトはPythonの標準ライブラリのみを使用しています。SOCKS5経由でログインし、UDPリレーを開いて、それを通じて1つのDNSクエリを送信します。OpenDNSリゾルバーが応答します。myip.opendns.com クエリの発信元アドレスを特定するため、このスクリプトはUDPトラフィックの送信元IPを出力します。

    以下の名前で保存してくださいsocks5_udp.py、ログインIDとパスワードを設定し、実行してくださいpython socks5_udp.py.

    """UDP through a residential proxy: SOCKS5 login, UDP ASSOCIATE and one DNS query.
    
    The OpenDNS resolver answers "myip.opendns.com" with the IP the query came from,
    so the script prints the exit IP your UDP traffic leaves from.
    """
    import os
    import socket
    import struct
    
    PROXY_HOST = "res.proxy-seller.com"
    PROXY_PORT = 10000
    LOGIN = "LOGIN"
    PASSWORD = "PASSWORD"
    
    
    def recv_exact(sock, n):
        data = b""
        while len(data) < n:
            chunk = sock.recv(n - len(data))
            if not chunk:
                raise ConnectionError("proxy closed the connection")
            data += chunk
        return data
    
    
    def udp_associate(host, port, login, password):
        """SOCKS5 login (RFC 1929) and UDP ASSOCIATE (RFC 1928).
    
        Returns the TCP control connection and the UDP relay address.
        The relay works while the TCP connection stays open.
        """
        tcp = socket.create_connection((host, port), timeout=15)
        tcp.sendall(b"\x05\x01\x02")  # SOCKS5, one auth method: username/password
        if recv_exact(tcp, 2)[1] != 0x02:
            raise RuntimeError("username/password authentication is not available")
        tcp.sendall(b"\x01" + bytes([len(login)]) + login.encode()
                    + bytes([len(password)]) + password.encode())
        if recv_exact(tcp, 2)[1] != 0x00:
            raise RuntimeError("wrong login or password")
        tcp.sendall(b"\x05\x03\x00\x01" + bytes(6))  # UDP ASSOCIATE, client address 0.0.0.0:0
        _, reply, _, atyp = recv_exact(tcp, 4)
        if reply != 0x00:
            raise RuntimeError(f"UDP ASSOCIATE failed, reply code {reply}")
        if atyp == 0x01:
            relay_ip = socket.inet_ntoa(recv_exact(tcp, 4))
        elif atyp == 0x03:
            relay_ip = recv_exact(tcp, recv_exact(tcp, 1)[0]).decode()
        else:
            raise RuntimeError("IPv6 relay address is not handled in this example")
        relay_port = struct.unpack("!H", recv_exact(tcp, 2))[0]
        if relay_ip == "0.0.0.0":
            relay_ip = tcp.getpeername()[0]
        return tcp, (relay_ip, relay_port)
    
    
    def strip_udp_header(datagram):
        """Remove the SOCKS5 UDP header from a datagram received from the relay."""
        atyp = datagram[3]
        if atyp == 0x01:  # IPv4
            return datagram[10:]
        if atyp == 0x04:  # IPv6
            return datagram[22:]
        return datagram[7 + datagram[4]:]  # domain name
    
    
    if __name__ == "__main__":
        tcp, relay = udp_associate(PROXY_HOST, PROXY_PORT, LOGIN, PASSWORD)
        print("UDP relay:", f"{relay[0]}:{relay[1]}")
    
        # DNS query "myip.opendns.com, type A" without EDNS: the answer ends with the IPv4 address
        query = (os.urandom(2) + b"\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00"
                 + b"\x04myip\x07opendns\x03com\x00" + b"\x00\x01\x00\x01")
        # every datagram to the relay starts with a SOCKS5 UDP header: RSV, FRAG, ATYP=IPv4, destination
        header = b"\x00\x00\x00\x01" + socket.inet_aton("208.67.222.222") + struct.pack("!H", 53)
    
        udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udp.settimeout(10)
        udp.sendto(header + query, relay)
        answer = strip_udp_header(udp.recv(4096))
        print("Exit IP over UDP:", socket.inet_ntoa(answer[-4:]))
        udp.close()
        tcp.close()

    出力例:

    UDP relay: 103.152.136.28:39631
    Exit IP over UDP: 203.0.113.45
  3. HTTP/3リクエストを送信する

    HTTP/3の場合、リクエストのQUICパケットは同じUDPリレーを経由します。この例では、aioquic ライブラリ(Python 3.11 以降)。これはhttps://cloudflare-quic.com/cdn-cgi/trace、プロトコルとクライアントのIPアドレスを表示するプレーンテキストのページ。

    依存関係をインストールし、スクリプトをhttp3_via_socks5.py の横にsocks5_udp.py、そして実行してください:

    pip install aioquic certifi
    python http3_via_socks5.py
    """HTTP/3 (QUIC) request to a website through a residential proxy.
    
    QUIC packets go to the SOCKS5 UDP relay; the website sees an HTTP/3 connection from the exit IP.
    Requires: pip install aioquic certifi, and socks5_udp.py from the previous example in the same folder.
    """
    import socket
    import struct
    import time
    
    import certifi
    from aioquic.h3.connection import H3_ALPN, H3Connection
    from aioquic.h3.events import DataReceived, HeadersReceived
    from aioquic.quic.configuration import QuicConfiguration
    from aioquic.quic.connection import QuicConnection
    from aioquic.quic.events import ConnectionTerminated, HandshakeCompleted
    
    from socks5_udp import LOGIN, PASSWORD, PROXY_HOST, PROXY_PORT, strip_udp_header, udp_associate
    
    TARGET_HOST = "cloudflare-quic.com"
    TARGET_PATH = "/cdn-cgi/trace"  # plain text: shows the protocol (http=http/3) and the client IP
    
    tcp, relay = udp_associate(PROXY_HOST, PROXY_PORT, LOGIN, PASSWORD)
    udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # the destination goes into the SOCKS5 UDP header as a domain name (ATYP=3): the proxy resolves it
    header = b"\x00\x00\x00\x03" + bytes([len(TARGET_HOST)]) + TARGET_HOST.encode() + struct.pack("!H", 443)
    
    config = QuicConfiguration(is_client=True, alpn_protocols=H3_ALPN, server_name=TARGET_HOST)
    config.load_verify_locations(certifi.where())
    quic = QuicConnection(configuration=config)
    peer = ("0.0.0.0", 443)  # placeholder: only the proxy knows the real address
    quic.connect(peer, now=time.time())
    h3 = H3Connection(quic)
    
    
    def send_pending():
        for datagram, _ in quic.datagrams_to_send(now=time.time()):
            udp.sendto(header + datagram, relay)
    
    
    send_pending()
    stream_id, body, done = None, b"", False
    deadline = time.time() + 20
    while not done and time.time() < deadline:
        timer = quic.get_timer()
        udp.settimeout(0.5 if timer is None else min(0.5, max(0.01, timer - time.time())))
        try:
            quic.receive_datagram(strip_udp_header(udp.recv(65535)), peer, now=time.time())
        except socket.timeout:
            if timer is not None and time.time() >= timer:
                quic.handle_timer(now=time.time())
        event = quic.next_event()
        while event is not None:
            if isinstance(event, HandshakeCompleted):
                stream_id = quic.get_next_available_stream_id()
                h3.send_headers(stream_id, [
                    (b":method", b"GET"), (b":scheme", b"https"),
                    (b":authority", TARGET_HOST.encode()), (b":path", TARGET_PATH.encode()),
                ], end_stream=True)
            elif isinstance(event, ConnectionTerminated):
                done = True
            for h3_event in h3.handle_event(event):
                if isinstance(h3_event, (HeadersReceived, DataReceived)) and h3_event.stream_id == stream_id:
                    if isinstance(h3_event, DataReceived):
                        body += h3_event.data
                    done = done or h3_event.stream_ended
            event = quic.next_event()
        send_pending()
    
    print(body.decode() or "No HTTP/3 response within 20 seconds")
    quic.close()
    send_pending()
    udp.close()
    tcp.close()

    出力(短縮版):

    ip=203.0.113.45
    http=http/3
    loc=GB
    tls=TLSv1.3

    http=http/3 は、そのウェブサイトがHTTP/3経由でリクエストを受信したことを意味します。ip およびloc は、プロキシの出口IPとその国です。

ブラウザやその他のアプリにおけるHTTP/3

アプリがプロキシ経由でUDPを送信できるのは、SOCKS5経由のUDPに対応している場合に限られます(UDP ASSOCIATE)。

ChromeおよびFirefoxは、自身の設定で設定されたSOCKS5プロキシ経由でUDPを送信しません。その結果、ウェブサイトはHTTP/3ではなく、HTTP/2またはHTTP/1.1で開かれます。

ブラウザやその他のアプリでHTTP/3を使用するには、SOCKS5経由でUDPを転送するツールを介してトラフィックをルーティングします。アプリはプロキシを認識しないため、通常通りHTTP/3を使用し、ツールがゲートウェイを介してQUICパケットを送信します。

Windows、macOS、Linux。以下を追加してください。socks リストの詳細とtun アプリへのトラフィックをキャプチャするためのインバウンド接続。UDPはsocks デフォルトではアウトバウンド:

{
  "type": "socks",
  "tag": "residential",
  "server": "res.proxy-seller.com",
  "server_port": 10000,
  "version": "5",
  "username": "LOGIN",
  "password": "PASSWORD"
}

Windows。選択したアプリのトラフィック(UDPおよびQUICを含む)をSOCKS5経由でルーティングします。プロキシ経由で通信させるアプリを選択し、プロファイルでホスト、ポート、ログイン名、パスワードを指定してください。

制限事項

  • UDPはSOCKS5でのみ動作します。HTTPプロキシ接続ではTCPが使用されます。

  • HTTPS(TLS)またはHTTP/3を介してプロキシ自体に接続することはサポートされていません。代わりに、http:// またはsocks5://.

  • UDPセッションでは、同じポート上のTCP接続とは異なる送信元IPアドレスが割り当てられる場合があります。

よくある質問(FAQ)

いいえ。UDPおよびHTTP/3は、すべてのリストで動作し、すでに持っているログインIDとパスワードで利用できます。

いいえ。TCP 上の HTTP および SOCKS5 は、これまでと全く同じように動作し続けます。

サーバーからレイテンシが最も低いもの。ゲートウェイは出口IPやその場所を変更しません。これらはリスト設定から取得されます。

ファイアウォールやホスティングプロバイダが、ポート30000~39999におけるゲートウェイへのUDP送信をブロックしていないことを確認してください。また、UDPを送信している間はSOCKS5のTCP接続を開いたままにしておいてください。この接続が閉じられると、中継も同時に切断されます。

新しいリストが有効になるまで1~2分かかります。それまでは、プロキシからエラー407が返される場合があります。しばらく待ってから、もう一度お試しください。

On this page