現在、私は次のデザインを持っています:
データはリモートサーバーから中央サーバーに定期的に送信されます。
コマンドは、セントラルサーバーから個々のリモートサーバーに、リモートサーバーで実行されているREST APIへのPOSTの形式で発行されます。
セキュリティが心配です。最も重要なことは、リモートサーバーに不正なコマンドが発行されないようにすることです。
現在、トークンベースの認証を使用しています。各リモートサーバーには、中央サーバーによって発行された有効期限なしのトークンがあり、リモートサーバーのファイルシステム上の構成ファイルに格納されています。このトークンは、リモートサーバーから送信されたPOSTリクエストのAuthorizationヘッダーで渡されます。
通信の他の方向も同様に機能します。各リモートサーバーは、中央クラウドサーバーと同じネットワーク内のリレーショナルデータベースに格納されている中央サーバーのトークンを生成します。
このデザインに関する私の問題:
この設計をどのように改善すればよいですか?中央クラウドサーバーからリモートデバイスへの通信は、RESTである必要はありません。 api。私が必要としているのは、2つのサーバー間の何らかの双方向ハンドシェイクです。 REST APIでそれをどのように実現できますか?
いくつかのメモ:
私が検討したいくつかのこと:
主にプログラムのセキュリティに関心がある(つまり、誰かがクライアントにコマンドを発行できないようにする)ため、脅威モデルも特定する必要があります。たとえば、プログラムにコマンドを送信して玄関のドアを開ける場合、アプリケーションを設計する際のアプローチは、「hello world!」などの無意味なデータを送信する場合とは大きく異なります。
それを定義したら、データベース内のパスワードをハッシュ化して安全な場所にキーをロックするか、プレーンテキストのパスワードが重要でないデータに対して機能するかを決定できます。すべての詳細を知らなくても、私はあなたのアプリケーションに話そうとします。
すでにSSL/TLSを使用しているので、すばらしいスタートです。認証の形式を実装しました。これは、クライアントが正当であることをサーバーに証明する方法です。ホストを物理的に制御できるので、誰も物理的にアクセスできないと思います。静的IPがある場合は、ホワイトリストと可能なファイアウォールを投入して、特定のhttpメソッド(GET、POST)を制限します。サーバーでこれをすべて行うには、Nginxなどのフロントエンドプロキシを検討します。クライアントにデータベースへのクリーンカット接続を許可しないことを強くお勧めします。サーバーにデータベースへの接続のみを許可します。あなたはデータベースにパスワードを保存していると言っていますが、それらをハッシュ/ソルトしてみませんか?繰り返しますが、脅威のモデルによって異なります。
クライアントマシンはあなたの物理的なアクセス下にありますが、盗まれる可能性があると述べました。攻撃者がボックスに物理的にアクセスできる場合、すべての賭けは無効になります。ここで最善の策は、クライアントが危険にさらされていることをできるだけ早く特定することです。すでにトークンを使用しています。有効期限がないのはなぜですか。
最後に、クライアントからサーバーに送信されるすべてのデータは、サニタイズおよびチェックする必要があります。データがどのように見えるかがわかっている場合は、テンプレートを設定し、受信したデータと一致しない場合は拒否します。