ココリーネの趣味部屋

RedSocksを使ってVMwareのVM上の通信をプロキシ経由にする

redsocksを使っている様子

VMwareのVM(仮想マシン)上の通信をまるごとプロキシ経由にしたいので調べたところ(透過型プロキシと言うらしい)Redsocksと言うツールで 実現できそうという事で試してみたのぜ。備忘録という感じでまとめるのぜ!!
この記事はあくまで手順だけを記載した感じなので、詳しく動作などを知りたい場合は他にもっと詳しく解説しているサイトがあると思うから そちらを参照してくださいオナシャス!!

ココリーネ
ココリーネ

本当はSquidと言うツールを使った方が楽で管理もしやすいみたいなんですが、今回は軽量化のためにRedSocksを使ったのぜ。

今回使用した環境

OS:alpine linux(ルーター兼プロキシ),windows11(クライアント)
Vmwareの仮想マシンを2つ作りそれぞれにインストールし、 alpine linuxにはRAM1GB、ストレージは2GB割り当てた。クライアントOS(今回はwindows)の方はお好みで...

alpine linuxの仮想マシン設定はこんな感じです。ネットワークアダプタは初期設定のままです(後で追加します)
alpine仮想マシンの設定
windows仮想マシンの設定(ホストオンリーアダプタを割り当てる) alpine仮想マシンの設定

ココリーネ
ココリーネ

alpine Linuxのeth1(仮想ネットワークカード1)でwindowsからのネットワーク通信を受け取り、 iptablesの力でalpine上のRedSocksとDNSCrypt-Proxyへリダイレクトします。 その過程で暗号化された通信がeth0からプロキシサーバに送られる...という算段です

alpine仮想マシンの設定
※イメージ図(Network Notepadで作成)

⚠️注意事項には全く似ていません!⚠️

プロキシと言うのはこちら側の通信を向こうのサーバーに肩代わりさせるという事なので、信頼できないプロキシやフリープロキシなどを 使う場合は機密情報を扱わないように気を付けてくださいオナシャス!!(何が起きても責任は取れ)ないです...

ちなみに今回アタイはIPRoyalと言う所のプロキシを使いました。(クーポンを使えばチョー割引になりますねぇ)

前準備

alpine linuxのインストール方法はこちらのページに詳しく載っているので参考にしてくださいオナシャス!!


ココリーネ
ココリーネ

alpine linuxは軽いんだけどubuntu等のディストリビューションとはターミナルのコマンドが全然違っており、ほほイキかけたのでパソコンに余裕が あればsystemdが使えるdebianやubuntuを使用した方がいいかもです。いや、alpineを使った事を後悔しております

こよりちゃん
こよりちゃん

コマンドくらい覚えなさい!

alpine linuxのインストールが終わったら、Vmwareの設定からホストオンリーアダプタを追加します。 (セットアップ中にホストオンリーアダプタがあると、リポジトリのミラーサーバーを見つけてくれない為)

alpine仮想マシンの設定

次に必要なパッケージをインストールするのですが、初期設定のリポジトリだと 今回使用するパッケージをインストールできないので、使用するリポジトリを変更します。

apk add nano
nano /etc/apk/repositories
#http://dl-cdn.alpinelinux.org/alpine/v3.xx/community
みたいな感じで書かれていると思うので、それの先頭のハッシュ(#)マークを削除して上書きする
コマンドのコピペが出来ないとほぼイキかけるので、ssh経由(teraterm等のソフトを使い)で接続できるようにします。
#sshが生きてるか確認、startedと出れば大丈夫。
rc-service sshd status 
#エディタでsshのコンフィグを編集
nano /etc/ssh/sshd_config
#エディタが開いたら、以下のように書かれている場所を
PermitRootLogin prohibit-password
#以下のように書き換える
PermitRootLogin yes
#書き換えたら、sshdサービスを再起動する
rc-service sshd restart

これでteratermからも、powershellやコマンドプロンプトからも、sshで仮想マシンに接続できるようになっているはずです!

#接続方法(powershellの場合)
ssh root@<仮想マシンのipアドレス(alpine上でip aとコマンドを打ち、eth0と出てきた項目に書いてあります)>

alpine LinuxのIPアドレスを固定する

MUR
MUR

あっ、おい待てい(江戸っ子)"/etc/network/interfaces"の設定でipアドレスを固定するのを忘れてるゾ

alpine LinuxのIPアドレスを固定するために"/etc/network/interfaces"の設定を開きます。

nano /etc/network/interfaces

以下をコピペか、同じように書き換えます。

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
    address 192.168.39.1
    netmask 255.255.255.0
野獣先輩
野獣先輩

eth0の設定はdhcpのままでもいいけど、もし固定にしたいなら以下のようにに設定してくださいねぇ。 sshでログインするIPアドレスも変わるので、そちらも考慮しておいてくださいよ...

#eth0を固定IPにする場合
auto eth0
iface eth0 inet static
    address 192.168.37.143 #例
    netmask 255.255.255.0
    gateway 192.168.37.1  # ルーターのIP

設定を変更したら、networkingサービスを再起動して変更を適用させてください。

rc-service networking restart
#starting....とずっと表示されていてコンソールに戻れない場合は、エンターキーを押すと戻れるはずです。

windows側の前準備

windows側の設定を開いて、ネットワークとインターネット→イーサネットから以下のようにIPアドレスを設定します

野獣先輩
野獣先輩

必ずalpine Linuxと同じサブネット上になるように設定してくれよな~

MUR
MUR

今回設定したサブネットマスクは255.255.255.0でホスト部を256個割り当てられるようにしてるから alpineと同じサブネット上の192.168.39.2~192.168.39.254の範囲でIPアドレスが設定できるゾ。 (192.168.39.1はalpine Linuxのeth1のアドレス、192.168.39.0はネットワークそのものを示すアドレス、 192.168.39.255はブロードキャストアドレスになっているから 設定しちゃだめだゾ)

KMR
KMR

ゲートウェイは通信の出入り口なので、eth1のアドレスを指定するんですね....(DNSも然り...)

windows設定の画面

設定が終わったら、windows側(クライアント)からalpine Linuxのeth1のIPアドレス宛にpingが通るか確認してくださいのぜ

こよりちゃん
こよりちゃん

alpine Linux上で"ip a"と打つことでインターフェースのIPアドレスを確認できるわ!

powershellの画面

セットアップ

必要なパッケージをインストールしていくのぜ。

apk update
apk add iptables redsocks curl dnscrypt-proxy
#サービスの自動起動設定
rc-update add redsocks default
rc-update add dnscrypt-proxy default
rc-update add iptables default
#IPフォワーディングの永続化
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

RedSocksの設定

タクヤさん
タクヤさん

レッドソックスとか野球チームみたいで笑っちゃうぜ!!シュワッチ!シュワッチ!

RedSocksのコンフィグファイルを開くのぜ。

nano /etc/redsocks/redsocks.conf
開いたら、以下のコンフィグ(gemini君に作ってもらった)を参考に設定してくださいナス!コピペすると壊れるかもだから 元々書いてある記述を書き換える形でやった方がいいかも...?
base {
    log_debug = off;
    log_info = on;
    log = "file:/var/log/redsocks.log";
    daemon = on;
    redirector = iptables;
    /* OSのファイルオープン上限を強制的に引き上げる */
    rlimit_nofile = 8192;
    /* 同時接続数、数千にするとAlpineのシステム上限(ulimit)に当たるので、まずは1024や2048あたりにするゾ */
    redsocks_conn_max = 2048;
    /* 枠が一杯になった時、何秒間通信がない接続を「アイドル」と見なして終了させるか */
    connpres_idle_timeout = 15;
}

redsocks {
    /* 0.0.0.0 でないと Windows (eth1) からの接続を拒絶しちゃうぜ? */
    local_ip = 0.0.0.0;
    local_port = 12345;

    /* ここにプロキシ情報を刻めって言ってんだろうが!(ビシッ) */
    ip = [プロキシIP];
    port = [プロキシのポート];
    type = socks5; /* または http-connect */

    /*パスワード付きのプロキシの場合はコメントアウト(//←これ)を外して入力するんだよ、あくしろよ、
    必ずダブルクォーテーションで囲んでね*/
    // login = "foobar";
    // password = "baz";
}

redsocksのコンフィグファイルを作っておくのぜ。

touch /var/log/redsocks.log
タクヤさん
タクヤさん

redudpの項目は特に触らなくても大丈夫だぜ!!(通信には主にTCPを使用し、今回DNSの通信に使うUDPはdnscrypt-proxyが代わりに担当しているため。)

設定が終わったらredsocksのサービスを再起動するのぜ。

rc-service redsocks restart

一応プロキシサーバーが生きてるかpingで確認しておくのもアリ?(プロキシによっては通らない場合があるかもです)

ping [プロキシのIPアドレス]:[ポート番号]
こよりちゃん
こよりちゃん

もしうまく繋がらない場合は"cat /var/log/redsocks.log"でログを確認してちょうだい! あとプロセスが暴走していてrestartできない場合は"killall -9 redsocks"で既存のredsocksプロセスを終了 させるといいわよ!

DNSCrypt-Proxyの設定

"/etc/dnscrypt-proxy/dnscrypt-proxy.toml"を開くのぜ。

nano /etc/dnscrypt-proxy/dnscrypt-proxy.toml

Grobal settingsの中のlisten_addresses = ['127.0.0.1:53']となっている部分を['0.0.0.0:5053']に変更してくれなのぜ。 (2つあるので注意!変更するのは左端に#が付いていない項目なのぜ)

listen_addresses = ['127.0.0.1:53']を→ listen_addresses = ['0.0.0.0:5053']に変更

同じくGrobal settingsの中にあるserver_namesの行を弄る(#のコメントアウトを外す)

# server_names = ['scaleway-fr', 'google', 'yandex', 'cloudflare']を → server_names = ['google', 'cloudflare']に変更(残すサーバーはお好みで)

設定が終わったら、dnscrypt-proxyのサービスを再起動します

rc-service dnscrypt-proxy restart
# 5053番ポートで起立しているか確認してくれゾ
netstat -nlpu | grep 5053
MUR
MUR

DNSは基本的にUDP通信なので、UDPのルートを隠ぺいしないとtcpの通信はプロキシ経由なのにDNSのアドレス解決は生IP経由というプライバシー的にはガバガバな事に なるから気を付けてくださいゾ。この「DNSだけが漏れてしまう現象」をDNSリーク(DNS Leak)と呼ぶゾ。

iptablesの設定

/etc/iptables/rules-saveにファイルを作成するのぜ。

nano /etc/iptables/rules-save

これ↓をそのままコピペして(これもgemini君に作ってもらった)、[本物のプロキシIP]と書いてあるところをプロキシのIPアドレスにしてくださいゾ

野獣先輩
野獣先輩

必ず[本物のプロキシIP]と書いてあるところをプロキシのIP(ポート番号は不要)に置き換えてくれよな~これをしないと エラーで繋がらないってはっきりわかんだね

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

# --- [1] Windowsからのパケット処理 ---
# HTTP/HTTPS (TCP) を redsocks (12345) へ
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 12345
-A PREROUTING -i eth1 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 12345
# Windows からの DNS (UDP 53) を直接 DNSCrypt-Proxy (5053ポート) へ強制連行
-A PREROUTING -i eth1 -p udp --dport 53 -j REDIRECT --to-ports 5053

# 先に DNS (UDP 53) だけを 5053 へ調教する
-A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 5053

# --- [2] Alpine自身の無限ループ防止 ---
# 【重要】自分自身への通信はスルー
-A OUTPUT -o lo -j RETURN
# 本物のプロキシ宛の通信を「RETURN」させてループを防ぐ(最重要!)
# 本物のプロキシIPと書いてあるところにプロキシのIPを入力するんだよ、あくしろよ
-A OUTPUT -d [本物のプロキシIP] -j RETURN

# --- [3] Alpine自身の通信を調教 ---
# 自分のTCP通信を redsocks(12345) へ
-A OUTPUT -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 12345
-A OUTPUT -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 12345

# --- マスカレード ---
-A POSTROUTING -j MASQUERADE
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# --- [4] QUIC (UDP 443) の完全封殺(ここを追記) ---
# Windows側(eth1)から外へ出ようとする QUIC を封殺
-A FORWARD -i eth1 -p udp --dport 443 -j DROP
# Alpine 自身が外へ出そうとする QUIC も封殺
-A OUTPUT -p udp --dport 443 -j DROP

# その他のフォワーディングは許可
-A FORWARD -j ACCEPT
COMMIT

こちらも設定が終わったらサービスを再起動

rc-service iptables restart
MUR
MUR

またgemini君に作ってもらったのか....ココリーネはいったいなにをやったんだゾ!?

ココリーネ
ココリーネ

通信して、restartした後に再度"/etc/iptables/rules-save"を開くと、左端に設定に準拠して通ったパケットの数[数字:数字]のようなものが追加されているはずなのぜ。 [0:0]になっていなければパケットが通っているので通信は出来ている...と判断できるはずなのぜ

こよりちゃん
こよりちゃん

うまく動かない場合は iptables -F && iptables -t nat -F とコマンドを打つことでiptablesの設定をリセットできるわ!

MUR
MUR

あ、おい待てい(江戸っ子)iptablesが起動している状態で設定を書き換えてもrestartした時点で前の設定に 書き換えられちゃうゾ。書き換えてrestartする前に"iptables-restore < /etc/iptables/rules-save"コマンドを実行して、メモリ上にある iptablesの直の設定を書き換える必要があるゾ

動作確認

ipleakや、dns leak test等のサイトにアクセスして、DNSの応答が生IPになっていなければ大丈夫なのぜ。

サイトが映っている画面

もし途中で繋がらなくなったら、dnscrypt-proxyがイっているのか、それともredsocksのプロキシがイっているのかを調べるのぜ。

#DNSが生きているか確認(応答が無ければDNSがイっている)
nslookup google.com [dnsに設定したipアドレス(今回は192.168.39.1)]
#プロキシが生きているか確認(応答が無ければコネクション数が限界に達している可能性)
curl -v http://g.co

どうしてもすぐ接続が途切れる場合は、OpenRC(alpine Linuxのサービスマネージャ)の設定を弄ってみるのぜ。

nano /etc/init.d/redsocks
#depend()の中に追記するのぜ
rc_ulimit="-n 8192"
#追記したらredsocksを再起動
rc-service redsocks restart
こよりちゃん
こよりちゃん

プロキシ側のキャパの問題もあるかもだから、無理しないことね!

拓也さん
拓也さん

無事サイトにアクセス出来ればおお~いいぜぇ~?

× 拡大画像