前書き
Redisは、メモリ内、NoSQL、キーと値のキャッシュおよびストアであり、ディスクに永続化することもできます。 trusted environmentのtrusted clientsが使用するように設計されており、独自の堅牢なセキュリティ機能はありません。 その点を強調するために、official Redis websiteからの引用を次に示します。
Redisは、信頼できる環境内の信頼できるクライアントがアクセスできるように設計されています。 これは、通常、Redisインスタンスをインターネットに直接公開すること、または一般的に、信頼されていないクライアントがRedis TCPポートまたはUNIXソケットに直接アクセスできる環境に公開することはお勧めできません。
…
一般に、Redisは最大限のセキュリティのためではなく、最大限のパフォーマンスとシンプルさのために最適化されています。
それにもかかわらず、Redisにはいくつかの基本的なセキュリティ機能が組み込まれています。 これらには、暗号化されていないパスワードを作成する機能と、コマンドの名前を変更して無効にする自由が含まれます。 特に、真のアクセス制御システムが欠けています。
これらの機能だけでは、Redisインストールのセキュリティを保証できません。 ただし、それらを構成することは、データベースを完全に保護しないままにすることからの大きな一歩です。
このチュートリアルでは、Redisが持ついくつかのセキュリティ機能を設定する方法を読み、Ubuntuサーバー上のスタンドアロンRedisインストールのセキュリティ体制を強化するシステムの設定をいくつか変更します。
このガイドは、Redisサーバーとクライアントアプリケーションが異なるホストまたは異なるデータセンターにある状況を扱っていないことに注意してください。 Redisトラフィックが安全でないネットワークまたは信頼できないネットワークを通過する必要があるインストールでは、ここに示すものに加えて、SSLプロキシやRedisマシン間のVPNの設定など、まったく異なる構成のセットが必要です。
前提条件
このチュートリアルでは、次のものが必要です。
-
Ubuntu 18.04サーバー。 このサーバーには、
sudo
権限を持つroot以外のユーザーと、Initial Server Setup Guide for Ubuntu 18.04に従って構成できるUFWで設定されたファイアウォールも必要です。 -
Redisがサーバーにインストールおよび構成されます。 これは、this guide for Ubuntu 18.04 serversに従って設定できます。
[[step-1 -—- verifying-that-redis-is-running]] ==ステップ1—Redisが実行されていることを確認する
まず、非rootユーザーでサーバーにSSHで接続します。
Redisが機能していることを確認するには、redis-cli
コマンドでRedisコマンドラインを開きます。
redis-cli
[。注意]##
Note:Redisのパスワードをすでに設定している場合は、接続後にauth
コマンドで認証する必要があります。
auth your_redis_password
OutputOK
Redisのパスワードを設定していない場合は、このチュートリアルのステップ4でその方法を読むことができます。
ping
コマンドを使用して接続をテストします。
ping
Redisが正常に機能している場合、次のように表示されます。
OutputPONG
これに続いて、Redisコマンドラインを終了します。
quit
Redisが正常に動作していることを確認したら、サーバーのセキュリティを強化するための最も重要なステップであるファイアウォールの設定に進むことができます。
[[step-2 -—- securing-the-server-with-ufw]] ==ステップ2—UFWでサーバーを保護する
Redisは、サーバーで実行されている単なるアプリケーションです。 独自の基本的なセキュリティ機能はごくわずかであるため、真にセキュリティを確保するための最初のステップは、実行中のサーバーを保護することです。 Ubuntu 18.04サーバーのような公開サーバーの場合、Initial Server Setup Guide for Ubuntu 18.04で説明されているようにファイアウォールを構成することが最初のステップです。 Follow that link and set up your firewall now if you haven’t already done so.
ファイアウォールを設定しているかどうか、またはファイアウォールがアクティブかどうかわからない場合は、次を実行して確認できます。
sudo ufw status
Ubuntu 18.04の初期サーバーセットアップガイドに従った場合、次の出力が表示されます。
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
そのガイドを使用してファイアウォールルールを実装した場合、明示的に許可されない限り、デフォルトでUFWはすべての着信トラフィックをドロップするため、Redisに追加のルールを追加する必要はありません。 Redisサーバーのデフォルトのスタンドアロンインストールはループバックインターフェイス(127.0.0.1
またはlocalhost)でのみリッスンしているため、デフォルトのポートでの着信トラフィックについて心配する必要はありません。
ルールを追加する方法の詳細については、このguide on common UFW rules and commandsを参照してください。
[[step-3 -—- binding-to-localhost]] ==ステップ3—localhostへのバインド
デフォルトでは、Redisはlocalhostからのみアクセスできます。 ただし、前提条件セクションに記載されているチュートリアルとは異なるチュートリアルに従ってRedisを構成した場合は、構成ファイルを更新して、どこからでも接続できるようにしている可能性があります。 これは、localhostへのバインドほど安全ではありません。
編集のためにRedis構成ファイルを開きます。
sudo nano /etc/redis/redis.conf
この行を見つけて、コメントが外されていることを確認します(#
が存在する場合は削除します)。
/etc/redis/redis.conf
bind 127.0.0.1
終了したら、ファイルを保存して閉じます(CTRL + X
、Y
、ENTER
の順に押します)。
次に、サービスを再起動して、systemdが変更を読み取ることを確認します。
sudo systemctl restart redis
この変更が有効になったことを確認するには、次のnetstat
コマンドを実行します。
sudo netstat -lnp | grep redis
Outputtcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 2855/redis-server 1
この出力は、構成ファイルに加えた変更を反映して、redis-server
プログラムがlocalhost(127.0.0.1
)にバインドされていることを示しています。 その列に別のIPアドレス(たとえば、0.0.0.0
)が表示されている場合は、正しい行のコメントを解除したことを再確認して、Redisサービスを再起動する必要があります。
Redisインストールがlocalhostのみをリッスンしているため、悪意のあるアクターがサーバーにリクエストを送信したり、サーバーにアクセスしたりすることがより困難になります。 ただし、Redisは現在、ユーザーが自身の構成または保持しているデータを変更する前に自分自身を認証することを要求するように設定されていません。 これを解決するために、Redisでは、Redisクライアント(redis-cli
)を介して変更を加える前に、ユーザーにパスワードによる認証を要求することができます。
[[step-4 -—- configuring-a-redis-password]] ==ステップ4—Redisパスワードの設定
Redisパスワードを設定すると、2つの組み込みセキュリティ機能の1つであるauth
コマンドが有効になります。このコマンドでは、クライアントがデータベースにアクセスするために認証する必要があります。 パスワードはRedisの構成ファイル/etc/redis/redis.conf
で直接構成されているため、お好みのエディターでそのファイルを再度開きます。
sudo nano /etc/redis/redis.conf
SECURITY
セクションまでスクロールし、次のようなコメント付きディレクティブを探します。
/etc/redis/redis.conf
# requirepass foobared
#
を削除してコメントを解除し、foobared
を安全なパスワードに変更します。
[。注意]##
Note:redis.conf
ファイルのrequirepass
ディレクティブの上に、コメント付きの警告があります。
/etc/redis/redis.conf
# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#
したがって、非常に強力で非常に長い値をパスワードとして指定することが重要です。 次の例のように、自分でパスワードを作成するのではなく、openssl
コマンドを使用してランダムなパスワードを生成できます。 2番目のopenssl
コマンドへのパイプは、最初のコマンドによって出力された改行を削除します。
openssl rand 60 | openssl base64 -A
出力は次のようになります。
OutputRBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE
そのコマンドの出力をrequirepass
の新しい値としてコピーして貼り付けた後、次のようになります。
/etc/redis/redis.confrequirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE
パスワードを設定した後、ファイルを保存し、Redisを再起動します。
sudo systemctl restart redis.service
パスワードが機能することをテストするには、Redisコマンドラインにアクセスします。
redis-cli
以下は、Redisパスワードが機能するかどうかをテストするために使用される一連のコマンドを示しています。 最初のコマンドは、認証前にキーを値に設定しようとします。
set key1 10
認証されなかったため機能しません。そのため、Redisはエラーを返します。
Output(error) NOAUTH Authentication required.
次のコマンドは、Redis構成ファイルで指定されたパスワードで認証します。
auth your_redis_password
Redisは次のことを認めます:
OutputOK
その後、前のコマンドを再度実行すると成功します:
set key1 10
OutputOK
get key1
は、Redisに新しいキーの値を照会します。
get key1
Output"10"
認証後にRedisクライアントでコマンドを実行できることを確認したら、redis-cli
を終了できます。
quit
次に、Redisコマンドの名前の変更について説明します。Redisコマンドは、誤って入力した場合や悪意のあるアクターによって入力された場合、マシンに重大な損傷を与える可能性があります。
[[step-5 -—- renaming-dangerous-commands]] ==ステップ5—Dangerousコマンドの名前を変更する
Redisに組み込まれている他のセキュリティ機能には、危険と見なされる特定のコマンドの名前変更または完全な無効化が含まれます。
誤って、または権限のないユーザーによって実行された場合、そのようなコマンドを使用して、データを再構成、破棄、または消去することができます。 認証パスワードと同様に、コマンドの名前変更または無効化は、/etc/redis/redis.conf
ファイルの同じSECURITY
セクションで構成されます。
危険と見なされるコマンドには、FLUSHDB、FLUSHALL、KEYS、PEXPIRE、DEL、CONFIG、SHUTDOWNが含まれます。 s、BGREWRITEAOF、BGSAVE、SAVE、SPOP、SREM、RENAME、およびDEBUG。 これは包括的なリストではありませんが、そのリスト内のすべてのコマンドの名前を変更または無効にすることは、Redisサーバーのセキュリティを強化するための良い出発点です。
コマンドを無効にするか名前を変更するかは、特定のニーズまたはサイトのニーズによって異なります。 悪用される可能性のあるコマンドを使用しないことがわかっている場合は、無効にすることができます。 それ以外の場合は、名前を変更することをお勧めします。
Redisコマンドを有効または無効にするには、構成ファイルをもう一度開きます。
sudo nano /etc/redis/redis.conf
[.warning]#Warning:コマンドを無効にして名前を変更する方法を示す次の手順は例です。 自分にとって意味のあるコマンドを無効にするか、名前を変更することだけを選択する必要があります。 コマンドの完全なリストを自分で確認し、redis.io/commands。
でどのように誤用される可能性があるかを判断できます。
コマンドを無効にするには、以下に示すように、空の文字列に名前を変更します(他の文字を含まない一対の引用符で表されます)。
/etc/redis/redis.conf
. . .
# It is also possible to completely kill a command by renaming it into
# an empty string:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
. . .
コマンドの名前を変更するには、次の例に示すように別の名前を付けます。 名前が変更されたコマンドは、他の人が推測するのは難しいはずですが、覚えやすくする必要があります。
/etc/redis/redis.conf
. . .
rename-command CONFIG ""
rename-command SHUTDOWN SHUTDOWN_MENOT
rename-command CONFIG ASC12_CONFIG
. . .
変更を保存してファイルを閉じます。
コマンドの名前を変更した後、Redisを再起動して変更を適用します。
sudo systemctl restart redis.service
新しいコマンドをテストするには、Redisコマンドラインを入力します。
redis-cli
次に、認証:
auth your_redis_password
OutputOK
前の例のように、CONFIG
コマンドの名前をASC12_CONFIG
に変更したと仮定します。 まず、元のCONFIG
コマンドを使用してみてください。 名前を変更したため、失敗するはずです。
config get requirepass
Output(error) ERR unknown command 'config'
ただし、名前を変更したコマンドの呼び出しは成功します。 大文字と小文字は区別されません。
asc12_config get requirepass
Output1) "requirepass"
2) "your_redis_password"
最後に、redis-cli
を終了できます。
exit
既にRedisコマンドラインを使用していて、Redisを再起動する場合は、再認証する必要があることに注意してください。 それ以外の場合、コマンドを入力するとこのエラーが発生します。
OutputNOAUTH Authentication required.
[。警告]##
コマンドの名前変更の慣行に関して、/etc/redis/redis.conf
のSECURITY
セクションの最後に次のような注意事項があります。
Please note that changing the name of commands that are logged into the AOF file or transmitted to slaves may cause problems.
注意: Redisプロジェクトでは、「マスター」と「スレーブ」という用語を使用することを選択しますが、DigitalOceanは通常、「プライマリ」と「セカンダリ」の代替を好みます。混乱を避けるために、ここのRedisドキュメントで使用されている用語を使用することを選択しました。
つまり、名前を変更したコマンドがAOFファイルにない場合、またはAOFファイルがスレーブに送信されていない場合は、問題はありません。
したがって、コマンドの名前を変更しようとするときは、そのことに留意してください。 コマンドの名前を変更する最適なタイミングは、AOF永続性を使用していないとき、またはインストール直後、つまりRedisを使用するアプリケーションがデプロイされる前です。
AOFを使用していて、マスタースレーブのインストールを処理している場合は、this answer from the project’s GitHub issue pageを考慮してください。 以下は、著者の質問への返信です。
コマンドはAOFに記録され、送信されたのと同じ方法でスレーブに複製されるため、同じ名前変更を持たないインスタンスでAOFを再生しようとすると、コマンドを実行できないため、不整合が発生する可能性があります(スレーブについても同じ)。
したがって、そのような場合に名前の変更を処理する最良の方法は、名前が変更されたコマンドがマスタースレーブインストールのすべてのインスタンスに適用されることを確認することです。
結論
サーバーに誰かがログインすると、導入したRedis固有のセキュリティ機能を簡単に回避できることに注意してください。 したがって、最も重要なセキュリティ機能はファイアウォールであり、悪意のある攻撃者がそのフェンスを飛び越えることを非常に困難にします。
信頼できないネットワークを介してRedis通信を保護しようとしている場合は、official Redis security guideでRedis開発者が推奨しているように、SSLプロキシを使用する必要があります。