SSHトンネルを介して接続されたクライアントにのみWebサーバートラフィックを制限します。

SSHトンネルを介して接続されたクライアントにのみWebサーバートラフィックを制限します。

注:ここがこの質問をするのに適した場所なのか、それとも私が正しい質問をしているのかわかりません。私が間違っている場合は、ご了承ください、問題を解決する方法、または正しいStackExchangeサイトに移動する方法を教えてください。

一部のクライアント(Ubuntuホスト1と2)にのみ接続したいWebサーバーがあり、これらのクライアントがSSHトンネルを介してWebサーバーに接続したい場合、他のすべてのクライアントはWebサーバーへのアクセスを拒否する必要があります。 。

設定は次のとおりです。 Ubuntuホスト(または他のホスト)がWebサーバーに直接接続しようとすると、アクセスが拒否されます(またはサーバーがまったく応答しないことをお勧めします)。 SSHトンネルを介してサーバーに接続しなければWebサーバーにアクセスできません。

                    ┌─────────────────────────────────────────────────── ────────────────┐
                    │アクセス拒否│
┌────────────────────┴─┐ │
│ │ ┌───────────────────────────┐ │
│ │ SSH トンネル │ Web サーバー │ │
│ Ubuntuホスト1◀─────────────────────────────────┤││
│ ┌───────────────┼──────────────────┼───────────── ─── ────┐ │ │
│ │ │ │ アクセス許可 │ │ │
└──────────────────────┘ │ │ │ │ │
                                       │ │ │ │ │
┌────────────────────┐ │ │ ┌─▼───────────┤ │
│ │ │ │ アクセス許可 │ Python │ │
│ ├───────────────┼──────────────────┼───────────── ─── ─► http.server │←─┘
│Ubuntuホスト2◀──────────────┘││ポート= 8080│
│ │ │ │ ホスト=0.0.0.0│◀─┐
│ │ └────────────────┴──────────────┘ │
└────────────────────┬─┘│
                    │アクセス拒否│
                    └───────────────────────────────────────────────── ──────────────────┘

次のようにしてこれを達成できます。

Webサーバーで(Webサーバー.example.com):

  1. 走るpython3 server.py
  2. SSH経由でUbuntuシステムに接続
ssh ubuntu-host-1.example.com -R 8080:web-server.example.com:8080
ssh ubuntu-host-2.example.com -R 8080:web-server.example.com:8080

コードは次のとおりです。server.py(からpythonbasics.org):

# Python 3 server example
from http.server import BaseHTTPRequestHandler, HTTPServer
import time, logging, ipaddress

hostName = "0.0.0.0"
serverPort = 8080
allowed_net = ipaddress.ip_network('172.16.0.0/12')
priv_net = list(allowed_net.hosts())

class MyServer(BaseHTTPRequestHandler):
    def do_GET(self):
        client = ipaddress.ip_address(self.client_address[0])
        if client in priv_net:
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
            self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
            self.wfile.write(bytes("<p>IP: %s</p>" % self.client_address[0], "utf-8"))
            self.wfile.write(bytes("<body>", "utf-8"))
            self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
            self.wfile.write(bytes("</body></html>", "utf-8"))
        else:
            self.send_response(404)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
            self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
            self.wfile.write(bytes("<p>IP: %s</p>" % self.client_address[0], "utf-8"))
            self.wfile.write(bytes("<body>", "utf-8"))
            self.wfile.write(bytes("<p>Access Denied</p>", "utf-8"))
            self.wfile.write(bytes("</body></html>", "utf-8"))



if __name__ == "__main__":        
    webServer = HTTPServer((hostName, serverPort), MyServer)
    print("Server started http://%s:%s" % (hostName, serverPort))

    try:
        webServer.serve_forever()
    except KeyboardInterrupt:
        pass

    webServer.server_close()
    print("Server stopped.")

ご覧のとおり、私のWebサーバーコードでは、クライアントがSSHトンネルの外部(つまり172.16.0.0/12ネットワークの一部ではない)から接続している場合を処理する必要があります。

サーバーがすべてのインターフェイス(0.0.0.0)を受信することなく、SSHトンネルを介して接続されたクライアントにのみサービスを提供する方法はありますか?

注:UbuntuホストからWebサーバーにSSHトンネルを開くことはできません。反対でなければなりません

答え1

あなたの図に基づいて、SSHトンネルとWebサーバーが同じシステム上で実行されていることを理解してください。この場合、Python HTTPサーバーへのすべての有効な接続は「localhost」から到着します。

もしそうなら、すべてのインターフェイスをバインドしないことがlocalhost望ましいソリューションになります。これは、127.0.0.1以外のIPでは、Webサーバーがリッスンしていないため、Webサーバーに到達できないためです。

関連情報