Ubuntu16.04でPeerVPNを使用してRedisへのトラフィックを暗号化する方法
序章
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サーバーソフトウェアを最初のマシンにインストールします。
- 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
に設定しました。 PeerVPNを構成した後、クライアントマシンからこのキーにアクセスしようとします。
Redisクライアントのインストール
他のUbuntu16.04マシンはクライアントとして機能します。 必要なすべてのソフトウェアは、デフォルトのリポジトリのredis-tools
パッケージで入手できます。
- sudo apt-get update
- sudo apt-get install redis-tools
リモートRedisサーバーのデフォルト構成とファイアウォールがアクティブになっているため、現在、リモートRedisインスタンスに接続してテストすることはできません。
各コンピューターにPeerVPNをインストールする
次に、各サーバーとクライアントにPeerVPNをインストールする必要があります。 上記のように、Ubuntuは現在そのリポジトリにPeerVPNパッケージを含めていません。
幸い、プロジェクトのWebサイトには、ダウンロードセクションにLinux用にコンパイルされたバイナリが含まれています。 そのページで静的にリンクされたLinuxバイナリのリンクを右クリックしてコピーし、最新バージョンであることを確認します。
各マシンで、/tmp
ディレクトリに移動し、curl
を使用してコピーしたリンクをダウンロードします。
- cd /tmp
- curl -LO https://peervpn.net/files/peervpn-0-044-linux-x86.tar.gz
次のように入力して、ダウンロードしたtarballを抽出します。
- tar xzvf peervpn*
バイナリを/usr/local/bin
ディレクトリにコピーし、設定例ファイルを/etc
ディレクトリにコピーします。
- sudo cp /tmp/peervpn*/peervpn /usr/local/bin
- sudo cp /tmp/peervpn*/peervpn.conf /etc
これでPeerVPNがシステムにインストールされ、使用できるようになりました。
PeerVPNネットワークを構成する
実行可能ファイルと構成ファイルを適切な場所に配置すると、各マシンでPeerVPNを構成できます。
安全な秘密鍵の生成
PeerVPNは、最大512文字の共有シークレットを使用して、ネットワークに対して正当なマシンを認証します。 ネットワークトラフィックの整合性を保護するには、強力な値を使用することが重要です。 これは共有シークレットであるため、ネットワークに1つの値を生成するだけで済みます(これを行うにはRedisサーバーマシンを使用しますが、どちらを選択してもかまいません)。
最大長の強力なシークレットを生成する簡単な方法の1つは、OpenSSLを使用することです。 wc
を使用して512文字以下の出力を生成していることを確認します(このコマンドで382を調整して、出力の長さに影響を与えることができます)。
- openssl rand -base64 382 | tr -d '\n' | wc
Redis server output 0 1 512
長さが正しい場合は、wc
を削除して、高エントロピーシークレットを生成します。 最後にecho
を追加して、最後の新しい行を追加します。
- openssl rand -base64 382 | tr -d '\n' && echo
次のようなものが表示されるはずです(以下の値をコピーしないでください!):
Redis server outputajHpYYMJYtv+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
ファイルを開きます。
- sudo nano /etc/peervpn.conf
内部には、各構成オプションを説明するコメントがあります。 これらをお読みになり、利用可能な設定をよく理解してください。 構成は非常に簡単です。 ファイルの先頭に構成行を追加するか、ファイル全体のコメントで適切な行を検索、コメント解除、および定義することができます。
networkname
とpsk
を設定することから始めます。どちらも、VPN内の各マシンで同じである必要があります。 ネットワーク名はこの特定のネットワークの任意の識別子ですが、psk
は前述の共有シークレットです。
networkname RedisNet
psk your_generated_secret
次に、PeerVPNがピアへの接続に使用できるport
を明示的に設定して、ファイアウォールを簡単に調整できるようにします(このガイドでは7000を使用します)。 enabletunneling
を設定して、このマシンがネットワークのアクティブな部分になるようにします。 ip
やifconfig
などのツールに表示されるネットワークinterface
の名前を設定します。
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リスニングポートを使用して指定する必要があります。 同じ行に追加のピアをスペースで区切って指定することもできます(例については、ファイル内のコメントを参照してください)。
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
終了したら、ファイルを保存して閉じます。 両方のマシンには、ifconfig4
とinitpeers
の値のみが異なる、非常に類似した構成ファイルが必要です。
PeerVPNのsystemdユニットファイルを作成する
PeerVPNをサービスとして管理し、起動時にネットワークを開始するために、systemdユニットファイルを作成します。 開始するには、各マシンの/etc/systemd/system
ディレクトリにある新しいユニットファイルを開きます。
- sudo nano /etc/systemd/system/peervpn.service
内部に、[Unit]
セクションを作成してユニットを説明し、ネットワークが利用可能になった後にこのユニットが開始されるように順序を確立します。
[Unit]
Description=PeerVPN network service
Wants=network-online.target
After=network-online.target
次に、[Service]
セクションを開いて、実行する実際のコマンドを定義します。 ここでは、ExecStart
を使用してpeervpn
バイナリを呼び出し、作成した構成ファイルを指定する必要があります。
[Unit]
Description=PeerVPN network service
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/local/bin/peervpn /etc/peervpn.conf
最後に、[Install]
セクションを含めて、有効になっている場合にユニットを自動的に起動するタイミングをsystemdに通知します。
[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
ユニットを起動して有効にします。
- sudo systemctl start peervpn.service
- sudo systemctl enable peervpn.service
サーバーで接続をリッスンしているサービスを確認すると、IPv4インターフェイスとIPv6インターフェイス(使用可能な場合)の両方について、ポート7000でPeerVPNがリッスンしていることがわかります。
- sudo netstat -plunt
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: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ネットワーク自体からのトラフィックを許可する必要があります。
- sudo ufw allow 7000
- sudo ufw allow from 10.8.0.0/24
これにより、PeerVPNがリッスンしているパブリックインターフェイスのポート7000へのアクセスが可能になります。 また、VPNからトラフィックが自由に流れるようになります。
VPNIPアドレスを使用して他のサーバーに到達できるかどうかを確認します。 たとえば、Redisサーバーから次のように入力できます。
- ping 10.8.0.2
問題なく接続できるはずです。
Redisサーバー設定を調整する
VPNが設定されたので、Redisがリッスンしているインターフェースを調整する必要があります。 デフォルトでは、Redisはローカルインターフェースにのみバインドします。
RedisサーバーでRedis構成ファイルを開きます。
- sudo nano /etc/redis/redis.conf
内部で、bind
ディレクティブを検索します。これは現在127.0.0.1に設定されているはずです。 RedisサーバーのVPNIPアドレスを最後に追加します。
. . .
bind 127.0.0.1 10.8.0.1
. . .
終了したら、ファイルを保存して閉じます。
次に、次のように入力してRedisサービスを再起動します。
- sudo systemctl restart redis-server.service
これで、VPNピアからの接続で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 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アドレスにポイントします。
- redis-cli -h 10.8.0.1 ping
Redis client outputPONG
このガイドの冒頭で設定したテストキーをクエリします。
- 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を使用した暗号化トンネルの構成が含まれます。