ShadowSocksとSoftetherを443ポートで同時待ち受け

最初の記事からかなり日が経ってしまいましたが、ついに本題の記事を書きます。日本語の情報はあまり無かったのでこの記事が他の方の役に立つことを願います。

今回は、ShadowSocksとSoftetherの共存環境を作成しました。

概要を説明すると、443ポートでHAProxyが待ち受けし、通信内容でShadowSocksとSoftetherに通信を振り分けています。SoftetherのクライアントアプリがSNIに対応しているため、HAProxyで判定しています。
また、HAProxyがUDP通信に対応していないため、今回の方法だとSoftetherのUDP高速化機能が使えません。(個人的にはあまり恩恵を受けた記憶がないというか・・・そもそも443ポートを使いたい理由ってセキュリティ的に443くらいしか使えない時だからあまり問題ないかも・・・)

ちなみにShadowSocks libevに拡張機能を追加することで似たようなことができるらしいですが、私の環境ではうまく動きませんでした。ちなみに、後日知人から聞いた話だとSentOS8だとパッケージ名が変わっているものがあるらしく、依存関係で正常動作しないことがあるそうなのでそれが原因だったかもしれません。

前提環境

今回の記事は以下のことを前提に進めます。もし、一から構築するのであれば他の記事も参考にしてください。

  • CentOS8
  • ShadowSocksがインストールされている
  • Softetherがインストールされている
    サーバーにドメインが紐ついている

もし、インストールがまだであれば以下の記事を参考にインストールして下さい。

ドメインの紐付けは、SNIとかは意識せずに通常の方法でサーバーIPとドメイン名を紐つけてあり、IPが正引き出来ればば大丈夫です。

HAProxyのインストール

今回の主役であるHAProxyをインストール設定していきます。上のリンクでインストールをしている場合既にShadowSocks、Softetherが443ポートを利用しています。このままだと起動時にポートが競合するので一度両ソフトを停止します。
以下のコマンドで停止できます。(上記記事で設定している場合)

#ShadowSocksの停止
systemctl stop ss.service
systemctl disable ss.service

#softetherの停止
systemctl stop vpnserver.service
systemctl disable vpnserver.service

#必要であれば停止の確認をする
systemctl status ss.service
systemctl status vpnserver.service

アプリを停止したら以下のコマンドでHAProxyをインストールします。

dnf -y install haproxy

HAProxyの設定

インストール後、HAProxyのコンフィグファイルを書き換え設定します。

vi /etc/haproxy/haproxy.cfg

追記内容は以下です。

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend https
    mode	tcp
    bind   	*:443
    tcp-request inspect-delay 5s
    tcp-request content accept if { req.ssl_hello_type 1 }
    acl vpn-server req_ssl_sni -i <サーバーのドメイン名>#ShadowSocksにドメイン名で接続する場合削除
    acl vpn-server req_ssl_sni -i <サーバーのドメイン名>/tcp#NAT-T mode
    use_backend bk-vpn-server if vpn-server    
    
    default_backend     bk-ss-server

frontend ssl
    mode tcp
    bind *:443
    tcp-request inspect-delay 5s
    tcp-request content accept  if  HTTP
    tcp-request content accept if { req.ssl_hello_type 1 }
    acl vpn-server req_ssl_sni -i <サーバーのドメイン名>#ShadowSocksにドメイン名で接続する場合削除
    acl vpn-server req_ssl_sni -i <サーバーのドメイン名>/tcp#NAT-T mode
    use_backend bk-vpn-server if vpn-server 


    default_backend bk-ss-server
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend bk-vpn-server
    mode 	tcp
    server      default 127.0.0.1:3000#Softetherのポート

backend bk-ss-server
    mode        tcp
    server      default 127.0.0.1:2000#ShadowSocksのポート

振り分けの設定は、Softetherが接続ドメイン名をサーバーに伝えるため、指定のドメイン名を取得した場合はSoftetherに通信を流し、そうでない場合はShadowSocksに通信を流しています。

ちなみにSoftetherは接続の際にhttpsで接続後SSLで通信をするようなので両方の通信を判定できるようにしないと途中で切断されてしまいます。また、前述の通りHAProxyがUDP通信に対応していないため、SoftetherのUDP高速化機能が使えません。そのため、通常の通信からNAT-Tモードと同じ通信になります。

もしShadowSocksにドメイン名で接続したいのであればコンフィグの指定の行を削除することで通信が可能ですが、Softetherの設定が分かりにくくなるのでおすすめはしません。

defaultsやglobalは変更した記憶がないのとバージョンによって違うので記述しません。

ShadowSocksの設定変更

ShadowSocksのコンフィグファイルから接続用のポート番号を変更します。
以下のコマンドで変更を行って下さい。(私と同じ設定の場合のパスです)

vi /snap/bin/config.json
{
   "server"["[::1]", "127.0.0.1"],
   "mode":"tcp_and_udp",
   "server_port":2000,
   "password":"password",
   "timeout":60,
   "method":"chacha20-ietf-poly1305",
   "nameserver":"1.1.1.1",
   "reuse_port": true,
   "no_delay": true,
   "fast_open": true,
   "ipv6_first": true
}

変更箇所は”server_port”です。
“server_port”は任意のポートを指定して下さい。指定する際はHAProxyのShadowSocksのポート番号と同じになるようにして下さい。

Softetherの設定変更

Softetherは管理マネージャからサーバーに接続し、トップ画面左下にあるポートの削除、追加の項目からTCPポート3000を指定することで設定できます。この際、競合を避けるためTCP443ポートを無効、もしくは削除して下さい。

すみません・・・画像が用意できませんでした・・・そのうち用意します・・・

また、コマンドラインからも設定できますが今回は割愛します。

起動

全ての設定が終わったら起動していきます。順番はそこまで気にする必要はありませんが、
ベストはHAProxy→ShadowSocks→Softetherです。

以下のコマンドで起動と、自動起動の登録を行って下さい。

#HAProxyの起動
systemctl start haproxy
systemctl enable haproxy

#ShadowSocksの起動
systemctl stop ss.service
systemctl disable ss.service

#softetherの起動
systemctl stop vpnserver.service
systemctl disable vpnserver.service

#起動の確認をする
systemctl status haproxy
systemctl status ss.service
systemctl status vpnserver.service

ステータスにfaildeなどの表示がなく、各クライアントから同時に接続ができれば正常に設定ができています。

HAProxyでログを見る

設定に間違えがあると想定外の通信が混じったり競合したりします。(実際競合してネットが途切れ途切れになったことがあります。)
そんな時はログを見ることでどの通信がどこに割り振られたかを確認することで原因を究明することができるので参考までに記載しておきます。

以下のコマンドで設定を書き換えます。

vi /etc/rsyslog.conf
# Provides UDP syslog reception
# for parameters see http://www.rsyslog.com/doc/imudp.html
#module(load="imudp") # needs to be done just once #ここと
#input(type="imudp" port="514") #ここのコメントを外す

・任意の文字列の検索方法
1,vim内で”esc”キーを押す
2,”:/<任意の文字列>”を入力しエンターを押す

ログの出力先を設定します。

vi /etc/rsyslog.d/haproxy.conf

以下の内容を入力して下さい。

local2.info                       /var/log/haproxy.log
local2.* ~

最後にHAProxyを再起動して終わりです。

 service rsyslog restart
 service haproxy restart

ログは以下に保存されます。

cat /var/log/haproxy.log

終わりに

今回のSoftetherとShadowSocksの共存サーバーは以前からやりたいと思っていたもので、日本語の情報があまりなかったため、英語の読めない自分は割と苦労しました。この記事が誰かの役に立つことを願います。

参考サイト

Enhanced SSL Load Balancing with Server Name Indication (SNI) TLS Extension - HAProxy Technologies
In this blog post we show how to enable enhanced SSL load balancing with the Server Name Indication (SNI) TLS Extension in HAProxy and HAProxy ALOHA.
Haproxyを用いて443ポートで複数サービスをホストする - Qiita
はじめに グローバルIPが1つしかないプライベートなサーバーで443ポートはかなり貴重です。 元々SSH,OpenVPN,HTTPSといった各サービスの標準ポートを使えば何ら問題はないんですが、80,443しか通さない強固なプ...
HAPRoxy — HTTPS Load Balancing on SNI
These notes are aimed at understanding what HAProxy offers to load balance HTTPS traffic and the difference between mode HTTP and mode TCP…
健忘録技術
スポンサーリンク
Probiees

コメント

タイトルとURLをコピーしました