Nginxは2番目のクライアントが接続するとすぐに最初のクライアントを切断します

Nginxは2番目のクライアントが接続するとすぐに最初のクライアントを切断します

Nginx をリバース プロキシ ポート 445 に設定しようとしていますが、クライアント A が Nginx 経由で共有に接続し、クライアント B が接続するたびに、クライアント A が共有をアクティブに使用していた (たとえば、大きなファイルをダウンロードしている) にもかかわらず、Nginx によってクライアント A の接続が切断されます。クライアント A が使用を終了する前に、Nginx がクライアント B の接続を再利用しているようです。

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

stream {

    server {
         listen 445;
         proxy_pass storage:445;
    }
}

一方の接続を切断してもう一方の接続を確立することなく、クライアント A と B の両方が同時に共有を使用できるようにするには、上記の構成ファイルに何が欠けているのでしょうか?

追加のコンテキスト:
Nginx v. 1.17.1 は、Ubuntu 18.04.2 LTS 仮想マシン 4 vCPU および 4Gb メモリ上で実行されています。

私はすでに、Nginx の代わりに iptables を使用してこの制御を作成し、ポート 445 の接続を共有サーバーに転送しようとしましたが、結果は同様でした。クライアント B が接続すると、クライアント A の接続が切断されます。

クライアント A と B が Nginx を介さずにストレージ共有に直接接続する場合、共有は正常に機能します。

Nginx ドキュメントの推奨設定 (limit_conn、so_keepalive、reuseport....) をかなり試しましたが、誤って使用した可能性があります。

Wireshark から、クライアント B が接続すると、Nginx がクライアント A に [FIN、ACK] パケットを送信することがわかります。

クライアント A の接続が影響を受けたときの Nginx のログ: *[エラー] 32110#32110:7 プロキシおよびアップストリームからの読み取り中に recv() が失敗しました (104: ピアによって接続がリセットされました)... しかし、このログは、クライアント A が [FIN、ACK] パケットを受信した後に Nginx に送信する [RST、ACK] パケットに関連していることがわかりました。

編集:
新しいバージョン 1.17.3 で試しましたが、成功しませんでした。

答え1

SMB サーバー側では、同じマシンが異なるユーザーを使用して接続しようとしているため、接続が切断されると思います。これは、iptables と Nginx によるマスカレードを使用する場合も同様です。

引き続き iptables を使用しますが、SMB サーバーへのトラフィックをマスカレードせず、転送のみを許可します。

iptables -t nat -A PREROUTING -p tcp -m tcp --dport 445 -j DNAT --to-destination storage:445
iptables -t filter -A FORWARD -d storage/32 -p tcp -m tcp --dport 445 -j ACCEPT

SMB サーバーからクライアントが存在するネットワークへのトラフィックがプロキシ/転送サーバー経由でルーティングされるようにします。

次に、プロキシ/転送サーバーで、クライアント ネットワークへのトラフィックをマスカレードする必要があります。例:

iptables -t nat -A POSTROUTING -d 192.168.0.0/24 -o eth0 -j MASQUERADE

これにより、SMB サーバーはクライアントの IP からのトラフィックを受信しますが、クライアントの通信はプロキシ/転送サーバーと行われ、複数のクライアントが接続しても切断されることはありません。

関連情報