HTTP・SOCKS・透過プロキシ・UDP

提供:Turgenev's Wiki
2025年4月2日 (水) 17:28時点におけるTurgenev (トーク | 投稿記録)による版 (Notion-MW)

SOCKS・透過プロキシ・UDP-over-TCPなどを中心に、ネットワークの変更に使えるプロキシ関連の各種技術を雑にまとめた。

近年はGo製のものが多い。また検閲に対抗するためか、中国系(中国語でissueが投稿されているなど)のものが多い。gost, go-proxy, hysteria, txthinking/socks5, things-go/socks5などはいずれもその2つに当てはまる。たまにロシア系もある。

大規模・多機能系

以下のものは機能が多くて分類できないのでソフトウェアごとに紹介する。

gost

GO Simple Tunnelの略らしい。安定版のv2系(https://github.com/ginuerzh/gost, https://v2.gost.run/)と開発中のv3系(https://github.com/go-gost, https://gost.run/)で大きく仕様が異なる。v3は開発中と言いつつv2系のページを見るとかなりv3推しに見える。

starはバージョン2が16k、バージョン3が5kほど。

イメージとしては、TCPによるシンプルなトンネルプロトコル(これがgost)(暗号化無し)と他の大量のプロトコルの間の相互変換を実装しているような感じと思われる。

非常に多機能で、このページで紹介している多くソフトウェアの基本機能をカバーしていると言ってもいいくらい。UDP-over-TCP系は基本これ1つで十分。機能の豊富さに比して明らかにドキュメントが不足しており、エラーメッセージも親切ではない(起動時ではなく実際にパケットが来てからエラーが出るような感じ)。

go-proxy

https://github.com/snail007/goproxy

これも見た感じgostと同じくらいか一部では上回るくらい多機能に見えるが、この雰囲気にしては珍しく有料版があり、無料版だと一部機能が制限されているようなので、あまり使ったことはない。

GFW回避

中国政府の検閲システムであるグレート・ファイアウォール(GFW)に対抗することを主な目的とするもの。

shadowsocks

SOCKSに暗号化を施した独自プロトコルで、いくつかの実装がある。https://github.com/shadowsocks/shadowsocks-rustなどが主流とみられる。

VPN以外のGFW回避ソフトウェアだとおそらくもっともメジャー。

サーバーとクライアントに分かれていて、クライアント側では透過プロキシにも対応している。

Hysteria

通信路がHTTP/3に偽装した形で暗号化される。shadowsocksの次世代に位置付けられるソフトウェアのように見える。

SOCKS5サーバー部分にはtxthinking/socks5を使っている。

SNI Proxy

HTTP・HTTPSのリバースプロキシで、host(HTTPの場合)あるいはsni(HTTPSの場合)に基づいてアクセスを振り分けるものをSNI Proxyと呼ぶことがあるらしい。NginxHAProxyのような汎用のプロキシサーバーでも使える機能だが、これを専門とするソフトウェアもある。

dlundquist/sniproxy

https://github.com/dlundquist/sniproxy starは2.6kほど。2024年に更新あり。非推奨である理由(HTTP/2とかQUICでうまくいかないとか)も書いてある。

tcpproxy

https://github.com/inetaf/tcpproxy starは1.3kほど。ライブラリ用途がメインか。

ameshkov/sniproxy

https://github.com/ameshkov/sniproxy starは70ほど。上流のSOCKS5, HTTPプロキシへの転送機能がある。

puxxustc/sniproxy

https://github.com/puxxustc/sniproxy starもほぼなく更新も9年前。

SOCKSプロキシサーバー

Dante

Dante - A free SOCKS server

企業(Inferno Nettverk A/S)によるオープンソースなSOCKS5実装で、有償サポートまであるらしい。見るからに古臭いHPで、メンテされているかどうか不安になるが、つい最近2024年末にもアップデートがあり、次期バージョンの計画についても記載されている。

Cで書かれていて、おそらく最も正確なSOCKS5実装だろう。コメントも親切で、リファレンス実装のような雰囲気がある。他の透過プロキシクライアントなどをテストする際はDanteでテストして動けば安心感がある。

OpenSSH

現実的に最もよく使われているSOCKSサーバーは間違いなくOpenSSHだろう。しかし、UDP-over-TCPの問題があるため、UDPはサポートされていない。

ssh -Dでforward方向のプロキシを建てるのが有名だが、OpenSSH 7.6からは-Rでreverse方向にも建てられるようになった。クライアント側が7.6以上であればよい。

  • 参考: OpenSSH 7.6ssh(1): add support for reverse dynamic forwarding

socks-with-udp-over-ssh

https://github.com/ge9/socks-with-udp-over-ssh

TCP接続(あるいは任意のバイトストリーム)の上にUDP付きのSOCKS5を通すために自分が実装したツール。サーバー側とクライアント側に分かれている。しかし実装した後にgostで同じことができることに気付いた。

経緯・使い方などはroot権限のないssh上にUDPを通す方法について(ポートフォワード、SOCKS5プロキシなど) - turgenev’s blogに書いてある。

3proxy

3proxy tiny free proxy server for Windows, Linux, Unix: SOCKS, HTTP, FTP proxy

https://github.com/3proxy/3proxy

ロシア系。エラーメッセージなどがかなり不親切だが、ちゃんと動くソフト。

fast-socks5

https://github.com/dizda/fast-socks5 Rust製では最も有名か。starは500ほど。使ったことなし

txthinking/socks5

https://github.com/txthinking/socks5

starは700前後。hysteriaやtrojan-goなどいくつかの大きなプロジェクトで使われており、go製のSOCKS5関連ライブラリでは一番メジャーか。

クライアントもある。

自分のfork(https://github.com/ge9/socks5)ではFull Cone NATを追加した

armon/go-socks5

https://github.com/armon/go-socks5

starは2kだが、最終更新2016年でUDP Associateも無し。Wireproxyで以前使われていたが使われなくなった(https://github.com/whyvl/wireproxy/issues/15)。

ここからフォークされたものが複数ある。

things-go/go-socks5

https://github.com/things-go/go-socks5

armon/go-socks5からのフォーク(GitHub上ではfork扱いではない)。starは400個ほど。UDP Associateはサポートしているがバグあり(自分のPRが採用されるかどうかで揉めてるhttps://github.com/things-go/go-socks5/pull/63)。

Wireproxyで使われている。

自分のフォーク https://github.com/ge9/go-socks5 ではFull Cone NATを追加した

haxii/socks5

https://github.com/haxii/socks5

armon/go-socks5からのfork。UDP Associate対応。starは50個前後。最終更新2019年。

wzshiming/socks5

https://github.com/wzshiming/socks5

クライアントもある。

starは90個ほど。最終更新2024年。

とりあえずredsocksと組み合わせでUDP透過プロキシ動作確認済。

Wireproxyで使用が検討された(https://github.com/whyvl/wireproxy/issues/15)が結局使用されず。

haochen233/socks5

https://github.com/haochen233/socks5

クライアントもある。

UDP Associateはサポートしているが、starは49とさらに少なく、最終更新も2021年。

同じくWireproxyで使用が検討された(https://github.com/whyvl/wireproxy/issues/15)が結局使用されず。

tun系

tun2proxy

https://github.com/tun2proxy/tun2proxy

透過SOCKSプロキシクライアント

透過プロキシを用いて特定アプリケーションのTCP・UDP通信をSOCKS5経由にする方法(Windows・Linux(iptables TPROXY)・Androidなど) - turgenev’s blogで扱った内容。

バックにSOCKS(SOCKS5)プロキシを用いてTCP・UDPのレイヤで透過プロキシを行うもの。基本的には管理者権限(最低でもCAP_NET_ADMIN)が必要。

redsocks

semigodking/redsocks (fork元のdarkk/redsocksはメンテされておらず、TCPのTPROXYに非対応)

*nix対応。BSD系で動かすことができたという話はFreeBSD/OpenBSD/NetBSDで透過プロキシのredsocksを動かしてみる - turgenev’s blogに書いた。

ProxiFyre

https://github.com/wiresock/proxifyre Windows用の透過SOCKSクライアント。管理者権限必要。TCP/UDP両方対応。インストールも簡単で、よくできている。

hev-socks5-tproxy

https://github.com/heiher/hev-socks5-tproxy Linux向け。redsocksより若干知名度は下がるものの、きちんとメンテされている。

Proxifier

https://www.proxifier.com/ 見た感じ機能は十分そうだが、有料なので試していない。

ライブラリ関数ハック系

ライブラリ関数レベルでの置き換えになるため厳密性・安定性に欠ける(異常終了する場合もある)ものの、root権限がない場合に有効な手法。

Linux(LD_PRELOAD)

libc依存でないプログラム(Go製のものなど)には効かない。

socksify

後述のDanteの一部。UDP/TCP両対応。唯一のUDP対応のものである。

route {
  from: 0.0.0.0/0 to: 0.0.0.0/0 via: 192.168.1.1 port = 1080
}

こんな感じの/etc/socks.confを作るか、SOCKS5_SERVER=192.168.1.1:1080 socksify curl http://ipv4.icanhazip.com とかでもよい。

Macでも動くはずだが、筆者が唯一試したMac環境ではcurlに対してさえうまく動作しなかった(socksifyを使わないのと全く同様に動作するだけだった)(DYLD_FORCE_FLAT_NAMESPACE=1は指定している)。

proxychains-ng(proxychains)

ngはnew generationの略で、proxychainsの後継である。ただしコマンド名はproxychains4である。

多段プロキシを構成するためのソフトウェア。

UDP非対応(https://github.com/rofl0r/proxychains-ng/issues/336)。ただしDNSに対応したproxy_dnsというオプションがあり、これを有効にするとDNS以外のUDP通信が正常に機能しなくなる副作用がある(https://github.com/rofl0r/proxychains-ng/issues/103)。

torsocks(tsocks)

多分、メンテされていないtsocksがTorに取り込まれてtorsocksになったような感じ。tsocksは非常に古く、多分2010年以降には更新されていないが、知名度は高く、今でも多分そこそこ使われてそう。

torsocksはアクティブなはず。ただし、Torでない普通のSOCKS5を指定しても動かないようである(やり方が悪いかも)。

tsocksはUDPには対応していない。torsocksもそうだが、まずそもそもTor自体がUDPに対応していない。

Windows(DLL Hijacking)

どのDLLを置き換えたらいいか自明ではなさそうなので、LD_PRELOADと違って対象とするソフトウェアごとに実装が必要そう。そもそも不可能なソフトウェアもLD_PRELOADの場合より多そう。よく見かけるのはDiscordを対象にしたもので、ロシア系のものが多い。筆者は使ったことがない。

discord-drover

https://github.com/hdrover/discord-drover

discord-voice-proxy

https://github.com/runetfreedom/discord-voice-proxy

HTTPプロキシ

Squid, Privoxyなどが有名。

Squidには透過プロキシ機能があるが、redsocksなどとは動作の細かい部分が異なる。squidで透過プロキシ(intercept, tproxy)を動かす - turgenev’s blogに書いた。

SOCKS関連の話題

ブラウザのSOCKS5プロキシのWebRTC対応

基本的に現在主流のブラウザ(Firefox, Chrome)のSOCKS5プロキシ機能(拡張機能で設定する場合を含む)はUDPには対応していないため、Discordの通話などWebRTC関係の機能を使うと生IPが漏洩する(またはそれを防ごうとすると単にその機能が使えない)。これは原理的に実装が不可能なわけではなく、単に需要が少ないから実装されていないだけである。

従って、ブラウザのWebRTCをプロキシさせたい場合はVPNや透過プロキシなどroot/管理者権限が必要な手法を使うことになる。ただしLinux+Firefoxの場合はsocksifyが使えるのでrootが無くても可能。

UDP AssociateリクエストのDST.ADDRとDST.PORT

クライアントがサーバー側にUDP Associateリクエストをするとき、この2フィールドには通信したい宛先ではなく(←というかそもそもそれが複数ある場合もある)、クライアント側がUDP Associateに使用する予定のポートを入れる。指定しない場合(例えばNATがある場合、これを予測するのは難しくなる)は、全ビットを0に設定する必要がある。

これによってサーバー側は、UDPパケットが送られてきたタイミングでそれが事前に通知されたものと一致するかどうか確認できるというわけである。

この部分に誤ってクライアント側が通信したい宛先ポートを入れるよう実装していたSOCKS5クライアントがいくつかある。

VPN(tun)

tun2proxy

https://github.com/tun2proxy/tun2proxy

Rust製。starは700ほど。SOCKSとHTTPをtunにしてくれる。

hev-socks5-tunnel

https://github.com/heiher/hev-socks5-tunnel

hev-socks5-tproxyの作者による。Androidアプリのhttps://github.com/heiher/sockstunもここから。

プロキシプロトコル間の変換

socks-to-http-proxy

https://github.com/KaranGauswami/socks-to-http-proxy

名前の通り、socksをhttpにしてくれる。starは250ほど。

privoxy

基本的にはHTTPプロキシソフトウェア。socksプロキシをhttpプロキシとして使えるようにする機能はあるが、より大がかり(一般ユーザーでの実行がしづらい)

UDP・Wireguard関連

UDPでサーバー→クライアントにデータ送信

https://github.com/prof7bit/udp-reverse-tunnel

これを使うと、サーバー側だけでポートが開けられるとしても事実上クライアント側で開けられるのと同等になるのでreverseをするのが楽になる

wgslirpy

https://github.com/vi/wgslirpy

Slirp(ユーザーランドで動くPPPサーバーのようなもの)のような形で実装されたWireguardサーバー。rootなしでWireguardサーバーとして動作する。

wireproxy

https://github.com/whyvl/wireproxy

wgslirpyの逆のような(?)ツール。Wireguardクライアントであるが、SOCKSサーバーとして動作する。

依存ライブラリのUDP Associate対応が不完全(自分がプルリクを送っている)だが、クライアントによってはうまくUDP Associateが動く(https://github.com/whyvl/wireproxy/issues/30)。

  • 自分でカスタマイズしてCone NATを加えたthings-go/go-socks5を使えば(go.modreplace github.com/things-go/go-socks5 => ../../go-socks5などとする)、以下のようなコードをroutine.goのsocks5.Optionのところに追加することでCone NATにできる。

    socks5.WithDialUDP(func(laddr, raddr *net.UDPAddr) (net.PacketConn, error) { return vt.Tnet.DialUDP(laddr, raddr) }),
    

Wireguard通信の確立: 各パターンでのやり方

各状況に応じて、2端末間でUDPの暗号化された通信路を確立するための方法を書いた。

  • forwardは「クライアント→サーバー」、reverseは「サーバー→クライアント」という意味。「サーバー」は、「ポートが開放できる方」という意味合い。

どっちもrootあり

普通にWireguardを使う

サーバーのみrootあり

forward

サーバーはWireguard、クライアントは普通にWireproxyでいける

reverse

udp-reverse-tunnelで頑張って逆にする(あるいはホールパンチング)。

その上で、wgslirpyを使うか、Hysteriaを使うか

クライアントのみrootあり

↑さっきと逆

forward

wgslirpyを使うか、Hysteriaを使うか

reverse

udp-reverse-tunnelで頑張ったうえで普通にWireguardとWireproxy

どっちもrootなし

この場合そもそもWireguardを使うメリットはあまりないかも。というのとrootがないならポート開放も無理そう

forward

Hysteriaでいけそう。

reverse

udp-reverse-tunnelしてHysteria?かな