Ubuntu 16.04でStunnelを使用してRedisへのトラフィックを暗号化する方法

前書き

Redisはオープンソースのキーと値のデータストアであり、永続化のためにオプションのディスク書き込みを伴うメモリ内ストレージモデルを使用します。 トランザクション、pub / subメッセージングパターン、および他の機能の中での自動フェールオーバーを備えています。 Redisには、ほとんどの言語で書かれたクライアントがあり、推奨される言語はhttp://redis.io/clients [彼らのウェブサイト]で紹介されています。

Redisは、独自の暗号化機能を提供しません。 信頼できる関係者のみがアクセスできる隔離されたプライベートネットワークに展開されているという前提の下で動作します。 ご使用の環境がその仮定と一致しない場合、Redisトラフィックを暗号化で個別にラップする必要があります。

このガイドでは、 `+ stunnel +`と呼ばれる安全なトンネリングプログラムを使用してRedisトラフィックを暗号化する方法を示します。 Redisクライアントとサーバー間のトラフィックは、専用のSSL暗号化トンネルを介してルーティングされます。 2台のUbuntu 16.04サーバーを使用してデモを行います。

前提条件

開始するには、各マシンで `+ sudo +`権限が設定された非rootユーザーが必要です。 さらに、このガイドでは、基本的なファイアウォールが設定されていることを前提としています。 Ubuntu 16.04初期サーバーセットアップガイドに従ってこれらの要件を満たすことができます。

続行する準備ができたら、以下に従ってください。

スタンネルとは何ですか?

基本的な暗号化通信の場合、 `+ stunnel `ユーティリティのインストールと設定は簡単です。 2台のマシン間で暗号化された転送を可能にします。 クライアントはローカルポートに接続し、リモートサーバーに転送する前に「 stunnel 」で暗号化してラップします。 サーバー側では、 ` stunnel +`は設定されたポートでリッスンし、ローカルポート(この場合、Redisサーバーがリッスンするポート)に転送する前にトラフィックを復号化します。

`+ stunnel +`を使用する利点は次のとおりです。

  • Ubuntuはデフォルトのリポジトリで `+ stunnel +`のパッケージを管理しています

  • Ubuntuには、ブート時にプロセスを自動的に開始するinitスクリプトが含まれています

  • 設定は簡単で直感的です

  • 目的ごとに新しいトンネルが使用されます。 これは状況によっては不利かもしれませんが、アクセスをきめ細かく制御できます。

欠点は次のとおりです。

  • クライアントは、デフォルトではないローカルポートに接続することでリモートマシンに接続しますが、これは最初は直感的ではないかもしれません。

  • レプリケーションまたはクラスタリングのために2つのRedisサーバーを接続する場合、サーバー間通信用に各マシンで2つのトンネルを構成する必要があります(1つは送信トラフィック用、もう1つは受信トラフィック用)。

これらの特性を念頭に置いて、始めましょう。

Redisサーバーおよびクライアントパッケージをインストールする

始める前に、1台のマシンにRedisサーバーをインストールし、もう1台のマシンにクライアントパッケージを用意する必要があります。 これらのいずれかまたは両方がすでに設定されている場合は、お気軽にスキップしてください。

Redisサーバーのインストール

Chris Lea’s Redis server PPAを使用して、Redisの最新バージョンをインストールします。 サードパーティのリポジトリを使用する場合は、常に注意してください。 この場合、Chris Leaは信頼できるパッケージャーであり、いくつかの人気のあるオープンソースプロジェクトの高品質で最新のパッケージを維持しています。

次のように入力して、PPAを追加し、最初のマシンにRedisサーバーソフトウェアをインストールします。

sudo apt-add-repository ppa:chris-lea/redis-server
sudo apt-get update
sudo apt-get install redis-server
  • Enter *と入力して、このプロセス中にプロンプ​​トを受け入れます。

インストールが完了したら、次のように入力して、Redisサービスにローカルに接続できることをテストします。

redis-cli ping

ソフトウェアがインストールされて実行されている場合、次のように表示されます。

Redis server outputPONG

後で使用できるキーを設定しましょう。

redis-cli set test 'success'
  • test *キーの値を `+ success `に設定しました。 ` stunnel +`を設定した後、クライアントマシンからこのキーにアクセスしようとします。

Redisクライアントのインストール

他のUbuntu 16.04マシンはクライアントとして機能します。 必要なすべてのソフトウェアは、デフォルトのリポジトリの `+ redis-tools +`パッケージで利用可能です:

sudo apt-get update
sudo apt-get install redis-tools

リモートRedisサーバーのデフォルト構成とファイアウォールがアクティブになっているため、現在、テストするためにリモートRedisインスタンスに接続することはできません。

各コンピューターにstunnelをインストールして有効にする

次に、各サーバーとクライアントに `+ stunnel `をインストールする必要があります。 Ubuntuには、デフォルトのリポジトリに ` stunnel4 `と呼ばれるバージョン4のユーティリティが含まれています。 前のセクションで何もインストールする必要がなかった場合、インストールする前にパッケージのインデックスを更新するために ` sudo apt-get update +`コマンドを必ず含めてください:

# sudo apt-get update
sudo apt-get install stunnel4

Ubuntuの `+ stunnel `サービスは、systemdで管理できる古いSysVinitスクリプトを使用して起動します。 ネイティブのsystemdメソッドを使用するのではなく、起動時にサービスを開始するように設定するには、 ` / etc / default / stunnel4 +`ファイルを変更する必要があります。

sudo nano /etc/default/stunnel4

`+ ENABLED +`オプションを「1」に設定して、起動時にサービスを開始できるようにします。

/ etc / default / stunnel4

. . .
ENABLED=
. . .

各サーバーでファイルを保存して閉じます。

次に、通信の暗号化に使用される自己署名SSL証明書とキーを作成します。

Redisサーバーで自己署名SSL証明書とキーを作成する

Redisサーバーで、 `+ / etc / stunnel `ディレクトリに自己署名SSL証明書とキーを作成します。 これは、 ` stunnel `の2つのインスタンス間の接続を暗号化するために使用されます。 「 redis-server +」という名前を使用して、証明書とキーファイルを参照します。

sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/stunnel/.key -out /etc/stunnel/.crt

作成する証明書に関する情報の入力を求められます。 これは内部でのみ使用されるため、値はそれほど重要ではないので、好きなものを入力してください。 あなたは以下の例を見ることができます:

Redis server output. . .
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

次のように入力して、生成された `+ .key +`ファイルへのアクセスを制限します。

sudo chmod 600 /etc/stunnel/.key

SSL証明書とキーができたので、Redisサーバーの `+ stunnel`設定ファイルを作成できます。

Redisサーバーのstunnel設定ファイルを作成する

Redisサーバーの `+ / etc / stunnel `ディレクトリ内にある ` .conf +`で終わるファイルを開き、開始します。

sudo nano /etc/stunnel/.conf

内部では、メインセクションでPIDファイルを書き込む場所を指定します。 `+ / run +`ディレクトリはこれらのタイプのファイルを保存するように設計されているため、以下を使用します。

/etc/stunnel/redis.conf

pid = /run/stunnel-redis.pid

次に、Redisサービスへのアクセスを構成するセクションを作成します。 これは好きなように呼び出すことができます( `+ redis-server`と呼びます)。 このセクションでは、この構成を、後でこのマシンで構成する必要がある他のトンネルから分離します。

`+ cert `ディレクティブと ` key +`ディレクティブをそれぞれ使用して、Redisサーバー自身の証明書とキーの場所を指定する必要があります。

ここでは、着信データのトンネルも定義します。 Redisサーバーの外部IPアドレスのデフォルトのRedisポート(ポート6379)へのトラフィックを「+ accept 」で暗号化します。 次に、_local_インターフェースのデフォルトのRedisポートへのトラフィックを「+接続」して、復号化されたトラフィックをデポジットします。 これは、Redisサービスが実際にリッスンしている場所です。

/etc/stunnel/redis.conf

pid = /run/stunnel-redis.pid

[redis-server]
cert = /etc/stunnel/.crt
key = /etc/stunnel/.key
accept = :6379
connect = 127.0.0.1:6379

終了したら、ファイルを保存して閉じます。

stunnelを再起動してファイアウォールを構成する

Redisサーバーで `+ stunnel +`が設定されたので、次のように入力してサービスを再起動できます。

sudo systemctl restart stunnel4.service

Redisサーバーで接続をリッスンしているサービスを確認すると、パブリックインターフェイスのポート6379でリッスンしている `+ stunnel +`が表示されます。 また、Redisがローカルインターフェイス上の同じポートをリッスンしていることも確認してください。

sudo netstat -plunt
Redis server outputActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :6379          0.0.0.0:*               LISTEN      4292/stunnel4
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      2679/redis-server 1
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1720/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      1720/sshd

`+ stunnel +`はパブリックインターフェイスでリッスンしていますが、ファイアウォールはまだトラフィックを通過させるように設定されていない可能性があります。

ポート6379へのすべてのトラフィックを許可するには、次を入力します。

sudo ufw allow 6379

これにより、 `+ stunnel `がリッスンしているパブリックインターフェイスのポート6379へのアクセスが開かれます。 ` stunnel +`ポートは暗号化されたトラフィックのみを受け入れます。

証明書をクライアントに配布する

各Redisクライアントには、Redisサーバーの証明書ファイルのコピーが必要です。 `+ .crt +`ファイルを配布する最も簡単な方法は、サーバー上のファイルの内容を単純に出力し、その内容を接続マシン上の対応するファイルにコピーすることです。

次のように入力して、Redisサーバー上の `+ .crt +`ファイルの内容を出力します。

cat /etc/stunnel/.crt
Redis server output-----BEGIN CERTIFICATE-----
MIIEGTCCAwGgAwIBAgIJALUdz8P8q8UPMA0GCSqGSIb3DQEBCwUAMIGiMQswCQYD
VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENp

. . .

Tq7WJk77tk4nPI8iGv1WuK8xTAm5aOncxP16VoMpsDMV+GB1p3nBkMQ/GKF8pPXU
fn6BnDWKmeZqAlBM+MGYAfkbZWdBslrWasCJzs+tehTqL0LLJ6d3Gi9biBPb
-----END CERTIFICATE-----

表示された証明書を* BEGIN CERTIFICATEおよびEND CERTIFICATE *とマークされた行を含めてクリップボードにコピーします。

クライアントマシンで、 `+ / etc / stunnel +`ディレクトリにある同じ名前のファイルを開きます:

sudo nano /etc/stunnel/.crt

Redisサーバーからコピーしたコンテンツを貼り付けます。 完了したら、ファイルを保存して閉じます。

Redis Client stunnel設定ファイルを作成します

クライアントがサーバーの証明書のコピーを取得したので、 `+ stunnel +`設定のクライアント側を設定できます。

クライアントマシンの `+ / etc / stunnel `ディレクトリにある ` .conf `で終わるファイルを開きます。 ファイルを再度「 redis.conf +」と呼びます。

sudo nano /etc/stunnel/.conf

内部では、サービスがプロセスIDを再度保存するPIDファイルを指定します。

/etc/stunnel/redis.conf

pid = /run/stunnel-redis.pid

次に、送信データ用のトンネルを構成するセクションを追加します。 これには好きな名前を付けることができます( `+ redis-client`と呼びます)。 このセクションでは、この構成を、後でこのマシンで構成する必要がある他のトンネルから分離します。

`+ client `ディレクティブを使用して、このセクションをクライアント設定として明示的にマークする必要があります。 ` accept `ディレクティブを設定して、ローカルインターフェースの未使用ポートでリッスンし、ローカルRedisクライアントからの接続を処理します(この例ではポート8000​​を使用します)。 ` connect +`ディレクティブをRedisサーバーのパブリックIPアドレスと開いたポートに設定します。

次に、 `+ CAfile `を使用して、Redisサーバーの証明書のコピーをポイントします。 また、 ` verify `を4に設定する必要があります。これにより、 ` stunnel +`は証明書チェーンに関係なく証明書のみをチェックします(証明書に自己署名したため)。

/etc/stunnel/redis.conf

pid = /run/stunnel-redis.pid

[redis-client]
client = yes
accept = 127.0.0.1:
connect = :6379
CAfile = /etc/stunnel/.crt
verify = 4

完了したら、ファイルを保存して閉じます。

Client Serviceの再起動と接続のテスト

クライアントで `+ stunnel +`サービスを再起動して、変更を実装します。

sudo systemctl restart stunnel4.service

クライアントのトンネルが適切にセットアップされたことを確認します。

sudo netstat -plunt
Redis client outputActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      3809/stunnel4
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1714/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      1714/sshd

ご覧のとおり、 `+ stunnel +`はローカルポート8000​​で接続を待機しています。

これで、クライアントがローカルインターフェースのポート8000​​を指すようにすることで、リモートRedisインスタンスに接続できるようになります。

redis-cli -p 8000 ping
Redis client outputPONG

このガイドの冒頭で設定したテストキーを照会します。

redis-cli -p 8000 get test
Redis client output"success"

これにより、リモートデータベースに正常にアクセスできることが確認されます。

トンネルを使用せずにリモートRedisサーバーと通信できないことを確認するには、リモートポートに直接接続してみます。

redis-cli -h  -p 6379 ping
Redis client outputError: Connection reset by peer

ご覧のとおり、トラフィックは、トンネルを介して正しく暗号化されている場合にのみ、リモートRedisポートで受け入れられます。

マルチクライアントおよびサーバー間通信の上記の例を拡張する

上記で概説した例では、単一のRedisサーバーと単一のクライアントの簡単な例を使用しました。 ただし、これらの同じ方法は、より複雑な相互作用に適用できます。

この例を拡張して複数のクライアントを処理するのは簡単です。 上記の以下のアクションを実行する必要があります。

  • 新しいクライアントにRedisクライアントソフトウェアと `+ stunnel +`パッケージをインストールします

  • `+ stunnel +`ソフトウェアを有効にして起動時に起動する

  • サーバーの証明書ファイルを `+ / etc / stunnel +`ディレクトリにコピーします

  • `+ stunnel +`クライアント設定ファイルを新しいクライアントマシンにコピーします

  • `+ stunnel +`サービスを再起動します

安全なサーバー間通信をセットアップするには(たとえば、レプリケーションまたはクラスタリング用)、2つの並列トンネルをセットアップする必要があります。

  • 新しいサーバーにRedisサーバーパッケージと `+ stunnel +`をインストールします

  • `+ stunnel +`ソフトウェアを有効にして起動時に起動する

  • 新しいRedisサーバーの新しい証明書とキーファイルを生成します(ファイルに一意の名前を使用します)

  • 各証明書ファイルを1つのサーバーから別のサーバーに `+ / etc / stunnel +`ディレクトリにコピーします

  • 各サーバー(既存のサーバーを含む)で `+ stunnel +`構成ファイルを編集または作成して、以下が含まれるようにします。

  • 外部ポートをローカルRedisにマッピングするサーバーセクション

  • ローカルポートをリモートサーバーの公開ポートにマッピングするクライアントセクション

  • 新しいRedisサーバーのファイアウォールで外部ポートを開きます

  • Redis構成ファイルを調整して、各Redisインスタンスがローカルにマッピングされたポートに接続してリモートサーバーにアクセスするように構成します(必要なディレクティブはサーバーの関係によって異なります。 詳細については、Redisのドキュメントを参照してください。

両方のサーバーの `+ stunnel +`設定ファイルは次のようになります。

サーバー間通信用のstunnel構成ファイル

pid = /run/stunnel-redis.pid

[redis-server]
cert = /etc/stunnel/.crt
key = /etc/stunnel/.key
accept = :6379
connect = 127.0.0.1:6379

[redis-client]
client = yes
accept = 127.0.0.1:
connect = :6379
CAfile = /etc/stunnel/.crt
verify = 4

必要に応じて、各マシンで複数のクライアントセクションを構成して、ローカルポートをリモートサーバーにマップできます。 これらの場合、各リモートサーバーに対して `+ accept +`ディレクティブを使用して、異なる未使用のローカルポートを選択してください。

結論

Redisは強力で柔軟なツールであり、多くの展開にとって非常に貴重です。 ただし、Redisを安全でない環境で運用することは、サーバーやデータを攻撃や盗難に対して脆弱なままにする大きな問題です。 信頼できる関係者のみが存在する分離されたネットワークがない場合は、他の手段でトラフィックを保護することが不可欠です。 このガイドで概説されている方法は、Redisパーティ間の通信を保護するための1つの方法にすぎません。 その他のオプションには、https://www.digitalocean.com/community/tutorials/how-to-encrypt-traffic-to-redis-with-spiped-on-ubuntu-16-04 [tunneling with spiped]またはhttps://が含まれます。 www.digitalocean.com/community/tutorials/how-to-encrypt-traffic-to-redis-with-peervpn-on-ubuntu-16-04[VPNのセットアップ]。

Related