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

前書き

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

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

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

前提条件

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

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

スパイプとは何ですか?

`+ spiped `ユーティリティはインストールが簡単で、2つのネットワークソケット(通常のネットワークポートまたはUnixソケット)間の安全な通信のために設定されます。 2つのリモートサーバー間の暗号化通信を構成するために使用できます。 クライアントはローカルポートに接続し、リモートサーバーに転送する前に「 spiped 」で暗号化してラップします。 サーバー側では、「 spiped +」は設定されたポートでリッスンし、トラフィックを復号化してからローカルポート(この場合、Redisサーバーがリッスンするポート)に転送します。

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

  • Ubuntuは、デフォルトのリポジトリに `+ spiped +`のパッケージを保持しています。

  • Redisプロジェクトは現在提案しています `+ spiped +`を使用してトラフィックを暗号化します。

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

  • 新しいパイプは、それぞれの目的に使用されます。 これは状況によっては不利かもしれませんが、アクセスをきめ細かく制御できます。

欠点は次のとおりです。

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

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

  • 含まれているinitスクリプトはないため、ブート時に必要な接続を自動的に作成するには、initスクリプトを作成する必要があります。

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

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 `に設定しました。 ` spiped +`を設定した後、クライアントマシンからこのキーにアクセスしようとします。

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

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

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

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

各コンピューターにスパイプをインストールする

次に、各サーバーとクライアントに「+ spiped 」をインストールする必要があります。 前のセクションで何もインストールする必要がなかった場合、インストールする前にパッケージのインデックスを更新するために ` sudo apt-get update +`コマンドを必ず含めてください:

sudo apt-get install spiped

必要なソフトウェアがインストールされたので、2つのマシン間のトラフィックを暗号化するために「+ spiped +」が使用できる安全なキーを生成できます。

Redisサーバーで暗号化キーを生成する

次に、Redisサーバーの `+ / etc `内に ` spiped +`設定ディレクトリを作成して、暗号化のために生成するキーを保存します。

sudo mkdir /etc/spiped

次を入力して安全なキーを生成します。

sudo dd if=/dev/urandom of=/etc/spiped/redis.key bs=32 count=1

権限を調整して、生成されたキーファイルへのアクセスを制限します。

sudo chmod 600 /etc/spiped/redis.key

Redisサーバーでキーを使用できるようになったので、systemdユニットファイルを使用してサーバーに「+ spiped +」を設定できます。

Redisサーバー用のsystemdユニットファイルを作成する

`+ spiped +`ユーティリティは非常にシンプルで、設定ファイルの読み取りをサポートしていません。 各パイプは手動で構成する必要があるため、Ubuntuパッケージにはブート時にパイプを自動的に開始するためのinitスクリプトが付属していません。

これらの問題を解決するために、単純なsystemdユニットファイルを作成します。 `+ / etc / systemd / system`ディレクトリで新しいユニットファイルを開き、開始します:

sudo nano /etc/systemd/system/spiped-receive.service

内部で、ユニットを記述する「+ [Unit] +」セクションを作成し、ネットワークが利用可能になった後にこのユニットが開始されるように順序を確立します。

/etc/systemd/system/spiped-receive.service

[Unit]
Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target

次に、実行する実際のコマンドを定義するために、 `+ [Service] `セクションを開きます。 ` spiped +`で次のオプションを使用します。

  • + -F +:フォアグラウンドで実行します。 systemd initシステムは、可能であればフォアグラウンドで実行されているサービスを管理するように設計されています。 フォアグラウンドで実行すると、必要な構成が簡素化されます。

  • + -d +:ソースソケットからのトラフィックを復号化します。 これは、「+ spiped +」に暗号化の方向を伝え、ソースからのトラフィックを復号化し、ターゲットからのトラフィックを暗号化することを認識させます。

  • + -s +:これはソースソケットを定義します。 IPアドレスは角括弧で囲み、その後にコロン、次にポートを続ける必要があります。 Redisサーバーの場合、これはパブリックIPアドレスとRedisポートに設定する必要があります。

  • + -t +:ターゲットソケット。 これは、復号化後にトラフィックが転送される場所です。 Redisはデフォルトでローカルホスト上のポート6379をリッスンするため、使用する必要があります。

  • + -k +:使用するキーファイルを指定します。 これは、以前に生成した暗号化キーを指す必要があります。

これらのオプションはすべて、このセクションで必要な唯一の項目である単一の `+ ExecStart +`ディレクティブに含まれます。

/etc/systemd/system/spiped-receive.service

[Unit]
Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/bin/spiped -F -d -s []:6379 -t [127.0.0.1]:6379 -k /etc/spiped/redis.key

最後に、有効になっている場合にユニットを自動的に起動するタイミングをsystemdに伝えるために、 `+ [Install] +`セクションを含めます。

/etc/systemd/system/spiped-receive.service

[Unit]
Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/bin/spiped -F -d -s []:6379 -t [127.0.0.1]:6379 -k /etc/spiped/redis.key

[Install]
WantedBy=multi-user.target

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

スパイピングされたサービスを開始し、Redisサーバーのファイアウォールを調整します

次のように入力して、新しい「+ spiped +」ユニットを起動して有効にします。

sudo systemctl start spiped-receive.service
sudo systemctl enable spiped-receive.service

Redisサーバーで接続をリッスンしているサービスを確認すると、パブリックインターフェイスのポート6379でリッスンしている「+ spiped +」が表示されます。 また、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/spiped
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

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

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

sudo ufw allow 6379

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

暗号化キーをクライアントに転送する

暗号化キーをクライアントに転送するには、2つのサーバー間で安全な接続を確立する必要があります。 既存の設定を活用できるため、「+ ssh +」を使用します。

キーベースの認証を使用している場合、SSHキーをRedisサーバーに転送して接続を確立する必要があります。 これは、パスワードベースのシステムには必要ありません。

キーベース認証の追加手順

Redisサーバーから切断します。

exit

次に、ローカルマシンで、SSHエージェントが実行されており、秘密鍵が追加されていることを確認します。

eval `ssh-agent`
ssh-add

次に、Redisサーバーに再接続し、キーを転送するための `+ -A +`フラグを追加します。

ssh -A @

これで、以下の手順を続行できます。

キーの転送

キーファイルにアクセスするにはローカルの `+ sudo +`権限が必要なため、Redisサーバーからクライアントに接続します。 ファイルを転送できるようになりました。以下のコマンドの最後に必ずコロンを含めてください。

sudo -E scp /etc/spiped/redis.key @:

`+ scp +`を使用して、クライアントマシン上のユーザーのホームディレクトリに書き込みます。

キーを転送した後、クライアントマシンに `+ / etc / spiped +`ディレクトリを作成します。

sudo mkdir /etc/spiped

暗号化キーを新しいディレクトリに移動します。

sudo mv ~/redis.key /etc/spiped

アクセス許可をロックダウンして、アクセスを制限します。

sudo chmod 600 /etc/spiped/redis.key

クライアントがサーバーの暗号化キーのコピーを取得したので、 `+ spiped +`設定のクライアント側を設定できます。

Redisクライアント用のsystemdユニットファイルを作成する

Redisサーバーで行ったように、クライアント側で `+ spiped +`のsystemdユニットファイルを作成する必要があります。

次のように入力して、新しいsystemdユニットファイルを開きます。

sudo nano /etc/systemd/system/spiped-send.service

内部で、 `+ [Unit] +`セクションを開いてサービスを説明し、ネットワークの可用性に依存することを確立します。

/etc/systemd/system/spiped-send.service

[Unit]
Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target

次に、 `+ [Service] `セクションを開いて ` spiped +`プロセスを実行します。 ここで使用されるオプションは、Redisサーバーで使用されるオプションと非常に似ていますが、次の違いがあります。

  • + -e +:ソースソケットに入るトラフィックを暗号化する必要があることを指定します。 これにより、ソースソケットとターゲットソケットの関係が確立されます。

  • + -s +:前と同じようにソースソケットを定義します。 ただし、この場合、ソースは、ローカルRedisクライアントが接続できるローカルインターフェイス上の任意の利用可能なポートです。

  • + -t +:以前と同様に、ターゲットソケットを定義します。 クライアントの場合、これはリモートRedisサーバーのパブリックIPアドレスと開かれたポートになります。

これらは再び `+ ExecStart +`ディレクティブを使用して設定されます:

/etc/systemd/system/spiped-send.service

[Unit]
Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/bin/spiped -F -e -s [127.0.0.1]:8000 -t []:6379 -k /etc/spiped/redis.key

最後に、有効になっている場合にユニットをいつ開始するかを定義するための `+ [Install] +`セクションを含めます。

/etc/systemd/system/spiped-send.service

[Unit]
Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/bin/spiped -F -e -s [127.0.0.1]:8000 -t []:6379 -k /etc/spiped/redis.key

[Install]
WantedBy=multi-user.target

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

クライアントでスパイプされたサービスを開始し、接続をテストします

これで、クライアントで「+ spiped +」サービスを開始し、ブート時に自動的に開始できるようにできます。

sudo systemctl start spiped-send.service
sudo systemctl enable spiped-send.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      3264/spiped
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1705/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      1705/sshd

ご覧のとおり、「+ spiped +」はローカルポート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: Protocol error, got "\xac" as reply type byte

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

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

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

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

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

  • 暗号化キーを新しいクライアントに転送します

  • + spiped + systemdユニットファイルを新しいクライアントマシンにコピーします

  • `+ spiped +`サービスを開始し、起動時に開始できるようにします

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

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

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

  • 暗号化キーを一方のサーバーから他方のサーバーに「+ / etc / spiped +」ディレクトリにコピーします

  • 各サーバー(既存のサーバーを含む)で + spiped + systemdユニットファイルを作成して、各サーバーが各役割を提供するファイルを持つようにします。

  • 外部ポートをローカルRedisにマッピングする受信ユニットファイル

  • ローカルポートをリモートサーバーの公開ポートにマッピングする送信ユニットファイル

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

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

必要に応じて、各マシンで複数のクライアントユニットファイルを構成して、ローカルポートをリモートサーバーにマップできます。 このような場合、送信ユニットファイルのソースソケット仕様で、使用されていない別のローカルポートを選択してください。

結論

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