序章

RedisはオープンソースのKey-Valueデータストアであり、永続性のためにオプションのディスク書き込みを備えたインメモリストレージモデルを使用しています。 トランザクション、Pub / Subメッセージングパターン、自動フェイルオーバーなどの機能を備えています。 Redisには、ほとんどの言語で記述されたクライアントがあり、推奨される言語はそのWebサイトに掲載されています。

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

このガイドでは、PeerVPNと呼ばれる単純なVPNプログラムを介してRedisトラフィックをルーティングすることにより、Redisトラフィックを暗号化する方法を示します。 サーバー間のすべてのトラフィックは、VPNを介して安全にルーティングできます。 一部のソリューションとは異なり、これは特定のポートまたはサービスにバインドされていない一般的なサーバー間通信のための柔軟なソリューションを提供します。 ただし、このガイドでは、Redisトラフィックを保護するためのPeerVPNの構成に焦点を当てます。 デモのために2台のUbuntu16.04サーバーを使用します。

前提条件

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

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

PeerVPNとは何ですか?

PeerVPNは、メッシュトポロジを確立する非常にシンプルなVPNテクノロジーです。 これは、ノード間の通信を調停するために常に利用可能でなければならない中央サーバーがないことを意味します。 これは、既存のホストで何も再構成せずに、パーティ間に信頼できる環境を確立したい状況に最適です。 ノード間のすべてのトラフィックはVPNを介して暗号化でき、サービスとファイアウォールの両方は、VPNインターフェイスでのみトラフィックを受け入れるように構成できます。

PeerVPNを使用するいくつかの利点は次のとおりです。

  • シンプルで直感的な構成。 多くのVPNとは異なり、PeerVPNはごくわずかな作業でセットアップでき、中央サーバーを必要としません。
  • 暗号化されたネットワーク通信のための汎用ソリューション。 一部のトンネリングオプションとは異なり、VPNは任意のトラフィックに安全なネットワークを提供します。 暗号化された通信は一度だけ設定する必要があり、すべてのサービスで使用できます。
  • サーバー間の通信に必要な接続は1つだけです。 トンネリングソリューションとは異なり、2台のRedisサーバーが通信するために必要な構成は1つだけです。

いくつかの欠点は次のとおりです。

  • Ubuntuには現在、デフォルトのリポジトリにPeerVPNのパッケージがありません。
  • initスクリプトは含まれていないため、起動時に必要な接続を自動的に作成するには、initスクリプトを作成する必要があります。

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

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

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

注: Redisサーバーの命令は、後で接続をテストするために使用されるテストキーを設定します。 すでにRedisサーバーがインストールされている場合は、接続をテストするときに、このキーを設定するか、他の既知のキーを使用できます。

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

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

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

  1. sudo apt-add-repository ppa:chris-lea/redis-server
  2. sudo apt-get update
  3. sudo apt-get install redis-server

Enter と入力して、このプロセス中にプロンプトを受け入れます。

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

  1. redis-cli ping

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

Redis server output
PONG

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

  1. redis-cli set test 'success'

testキーを値successに設定しました。 PeerVPNを構成した後、クライアントマシンからこのキーにアクセスしようとします。

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

他のUbuntu16.04マシンはクライアントとして機能します。 必要なすべてのソフトウェアは、デフォルトのリポジトリのredis-toolsパッケージで入手できます。

  1. sudo apt-get update
  2. sudo apt-get install redis-tools

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

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

次に、各サーバーとクライアントにPeerVPNをインストールする必要があります。 上記のように、Ubuntuは現在そのリポジトリにPeerVPNパッケージを含めていません。

幸い、プロジェクトのWebサイトには、ダウンロードセクションにLinux用にコンパイルされたバイナリが含まれています。 そのページで静的にリンクされたLinuxバイナリのリンクを右クリックしてコピーし、最新バージョンであることを確認します。

各マシンで、/tmpディレクトリに移動し、curlを使用してコピーしたリンクをダウンロードします。

  1. cd /tmp
  2. curl -LO https://peervpn.net/files/peervpn-0-044-linux-x86.tar.gz

次のように入力して、ダウンロードしたtarballを抽出します。

  1. tar xzvf peervpn*

バイナリを/usr/local/binディレクトリにコピーし、設定例ファイルを/etcディレクトリにコピーします。

  1. sudo cp /tmp/peervpn*/peervpn /usr/local/bin
  2. sudo cp /tmp/peervpn*/peervpn.conf /etc

これでPeerVPNがシステムにインストールされ、使用できるようになりました。

PeerVPNネットワークを構成する

実行可能ファイルと構成ファイルを適切な場所に配置すると、各マシンでPeerVPNを構成できます。

安全な秘密鍵の生成

PeerVPNは、最大512文字の共有シークレットを使用して、ネットワークに対して正当なマシンを認証します。 ネットワークトラフィックの整合性を保護するには、強力な値を使用することが重要です。 これは共有シークレットであるため、ネットワークに1つの値を生成するだけで済みます(これを行うにはRedisサーバーマシンを使用しますが、どちらを選択してもかまいません)。

最大長の強力なシークレットを生成する簡単な方法の1つは、OpenSSLを使用することです。 wcを使用して512文字以下の出力を生成していることを確認します(このコマンドで382を調整して、出力の長さに影響を与えることができます)。

  1. openssl rand -base64 382 | tr -d '\n' | wc
Redis server output
0 1 512

長さが正しい場合は、wcを削除して、高エントロピーシークレットを生成します。 最後にechoを追加して、最後の新しい行を追加します。

  1. openssl rand -base64 382 | tr -d '\n' && echo

次のようなものが表示されるはずです(以下の値をコピーしないでください!)

Redis server output
ajHpYYMJYtv+m0K6yZbYmk8npPujlcv9QDozQZ06ucV2gsHoMGqyfd50X8OnY6hicj5iFNjDN/9QVTB3nhMOV2ufU/kfWCbtskUuk1zHWYZsvy71KnLRhA8W8dnu+NEKdIh28H2qUsiay7On5kOZPcrONvv/pHHYbxmFI2G9TyYT+CZWIAxUV/vUWl41VycjASmZYaSI6lWgYONopncNfDF5Z6oznPH8ge6sQsszbe1ZjNqLRUrx/jgL3fy7SXSLCIrsSuifBv/pb36d9/y+YPZEbxsMInoK5QEWrpIf/xjbMFlndtGc20olhh05h66qz/GiimLMivrN8g+PibVaBRUmWav/pngUvKYsEEPSc0wrr5ZuvpvBGTTKqPdR+soCnd/iWPzmwRBW56vBGxed3GNbkgmjDpTSnvNEN+gKPt07drHSbGqfFbdMdsKbjE+IWiqiVO1aviJsNpMhBO/o9uIcKxPmuze6loZKTh7/qjJuY62E//SsgFzDHDhP2w==

生成された出力をコピーして、PeerVPN構成で使用できるようにします。

PeerVPN構成の定義

PeerVPNを構成するには、各サーバーで/etc/peervpn.confファイルを開きます。

  1. sudo nano /etc/peervpn.conf

内部には、各構成オプションを説明するコメントがあります。 これらをお読みになり、利用可能な設定をよく理解してください。 構成は非常に簡単です。 ファイルの先頭に構成行を追加するか、ファイル全体のコメントで適切な行を検索、コメント解除、および定義することができます。

networknamepskを設定することから始めます。どちらも、VPN内の各マシンで同じである必要があります。 ネットワーク名はこの特定のネットワークの任意の識別子ですが、pskは前述の共有シークレットです。

/etc/peervpn.conf
networkname RedisNet
psk your_generated_secret

次に、PeerVPNがピアへの接続に使用できるportを明示的に設定して、ファイアウォールを簡単に調整できるようにします(このガイドでは7000を使用します)。 enabletunnelingを設定して、このマシンがネットワークのアクティブな部分になるようにします。 ipifconfigなどのツールに表示されるネットワークinterfaceの名前を設定します。

/etc/peervpn.conf
networkname RedisNet
psk your_generated_secret

port 7000
enabletunneling yes
interface peervpn0

VPNネットワークサイズを選択し、ifconfig4ディレクティブを使用して各サーバーに一意のVPNIPアドレスを割り当てる必要があります。 これは、CIDR表記を使用して行われます。 VPNネットワークを10.8.0.0/24と定義します。 これにより、すべて10.8.0から始まる254の潜在的なアドレス(必要以上に多く)が得られます。 各アドレスは一意である必要があるため、以下を使用します。

  • Redisサーバーの10.8.0.1/24
  • クライアントサーバーの10.8.0.2/24

最後に、initpeersを使用して、ネットワーク内にある他のサーバーを指定します。 PeerVPNは集中管理サーバーを使用しないため、VPNネットワークに参加するために、初期化中にこれらのホストに接続されます。 接続後、サーバーはネットワーク上の追加のピアに関する情報を自動的に受信します。

ピアは、パブリックIPアドレス(ではなくPeerVPN構成内で割り当てられたVPNIPアドレス)とPeerVPNリスニングポートを使用して指定する必要があります。 同じ行に追加のピアをスペースで区切って指定することもできます(例については、ファイル内のコメントを参照してください)。

/etc/peervpn.conf
networkname RedisNet<^>
psk your_generated_secret

port 7000
enabletunneling yes
interface peervpn0

# Increment the IP address below for each additional server
# For example, the second node on the network could be 10.8.0.2/24
ifconfig4 10.8.0.1/24
initpeers other_server_public_IP 7000

終了したら、ファイルを保存して閉じます。 両方のマシンには、ifconfig4initpeersの値のみが異なる、非常に類似した構成ファイルが必要です。

PeerVPNのsystemdユニットファイルを作成する

PeerVPNをサービスとして管理し、起動時にネットワークを開始するために、systemdユニットファイルを作成します。 開始するには、各マシンの/etc/systemd/systemディレクトリにある新しいユニットファイルを開きます。

  1. sudo nano /etc/systemd/system/peervpn.service

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

/etc/systemd/system/peervpn.service
[Unit]
Description=PeerVPN network service
Wants=network-online.target
After=network-online.target

次に、[Service]セクションを開いて、実行する実際のコマンドを定義します。 ここでは、ExecStartを使用してpeervpnバイナリを呼び出し、作成した構成ファイルを指定する必要があります。

/etc/systemd/system/peervpn.service
[Unit]
Description=PeerVPN network service
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/peervpn /etc/peervpn.conf

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

/etc/systemd/system/peervpn.service
[Unit]
Description=PeerVPN network service
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/peervpn /etc/peervpn.conf

[Install]
WantedBy=multi-user.target

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

PeerVPNサービスを開始し、ファイアウォールを調整します

次のように入力して、両方のマシンで新しいpeervpnユニットを起動して有効にします。

  1. sudo systemctl start peervpn.service
  2. sudo systemctl enable peervpn.service

サーバーで接続をリッスンしているサービスを確認すると、IPv4インターフェイスとIPv6インターフェイス(使用可能な場合)の両方について、ポート7000でPeerVPNがリッスンしていることがわかります。

  1. sudo netstat -plunt
Output
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 2662/redis-server 1 tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1724/sshd tcp6 0 0 :::22 :::* LISTEN 1724/sshd udp 0 0 0.0.0.0:7000 0.0.0.0:* 4609/peervpn udp6 0 0 :::7000 :::* 4609/peervpn

PeerVPNはパブリックインターフェイスをリッスンしていますが、ファイアウォールはトラフィックを通過させるように構成されていない可能性があります。 PeerVPNが接続をリッスンしているポート7000へのトラフィックと、10.8.0.0/24ネットワーク自体からのトラフィックを許可する必要があります。

  1. sudo ufw allow 7000
  2. sudo ufw allow from 10.8.0.0/24

これにより、PeerVPNがリッスンしているパブリックインターフェイスのポート7000へのアクセスが可能になります。 また、VPNからトラフィックが自由に流れるようになります。

VPNIPアドレスを使用して他のサーバーに到達できるかどうかを確認します。 たとえば、Redisサーバーから次のように入力できます。

  1. ping 10.8.0.2

問題なく接続できるはずです。

Redisサーバー設定を調整する

VPNが設定されたので、Redisがリッスンしているインターフェースを調整する必要があります。 デフォルトでは、Redisはローカルインターフェースにのみバインドします。

RedisサーバーでRedis構成ファイルを開きます。

  1. sudo nano /etc/redis/redis.conf

内部で、bindディレクティブを検索します。これは現在127.0.0.1に設定されているはずです。 RedisサーバーのVPNIPアドレスを最後に追加します。

/etc/redis/redis.conf
. . .
bind 127.0.0.1 10.8.0.1
. . .

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

次に、次のように入力してRedisサービスを再起動します。

  1. sudo systemctl restart redis-server.service

これで、VPNピアからの接続でRedisサービスを利用できるようになります。 これは、リスニングポートを再確認することで確認できます。

  1. sudo netstat -plunt
Redis server output
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 10.8.0.1:6379 0.0.0.0:* LISTEN 4767/redis-server 1 tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 4767/redis-server 1 tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1724/sshd tcp6 0 0 :::22 :::* LISTEN 1724/sshd udp 0 0 0.0.0.0:7000 0.0.0.0:* 4609/peervpn udp6 0 0 :::7000 :::* 4609/peervpn

この例の一番上の行で、RedisがVPNインターフェースをリッスンしていることがわかります。

Redisクライアントからの接続をテストする

VPNが実行され、RedisがVPNネットワークでリッスンしている状態で、RedisクライアントマシンがRedisサーバーにアクセスできることを確認するためにテストできます。

これを行うには、-hオプションを使用して、クライアントをRedisサーバーのVPNIPアドレスにポイントします。

  1. redis-cli -h 10.8.0.1 ping
Redis client output
PONG

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

  1. redis-cli -h 10.8.0.1 get test
Redis client output
"success"

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

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

上で概説した例では、単一のRedisサーバーと単一のクライアントの簡単な例を使用しました。 ただし、これは、より複雑な相互作用に対応するために簡単に拡張できます。

PeerVPNはメッシュネットワークを使用しているため、クライアントやサーバーを追加するのは簡単です。 新しいピアは、次の手順を完了する必要があります。

  • tarballをダウンロードし、ファイルを抽出して配布することにより、PeerVPNをインストールします

  • 他のサーバーからPeerVPN構成をコピーし、これらのディレクティブを調整します。

    • ifconfig4はVPNネットワーク内の未使用のIPアドレスに設定する必要があります
    • initpeersは、少なくとも1つ、できればすべての既存のピアを指す必要があります
  • PeerVPNsystemdユニットファイルを新しいクライアントマシンにコピーします

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

  • ファイアウォールで外部ポートとVPNネットワークを開きます

  • (Redisサーバーの場合のみ)新しいVPNインターフェースにバインドするようにRedis構成を調整します

結論

Redisは、多くのデプロイメントにとって非常に貴重な強力で柔軟なツールです。 ただし、安全でない環境でRedisを操作することは、サーバーとデータを攻撃や盗難に対して脆弱なままにする大きな責任です。 信頼できる関係者だけがネットワークを構築していない場合は、他の手段でトラフィックを保護することが不可欠です。 このガイドで概説されている方法は、Redisパーティ間の通信を保護するための1つの方法にすぎません。 その他のオプションには、tunnelまたはspipedを使用した暗号化トンネルの構成が含まれます。