###序章

Redis は、キャッシュに優れたオープンソースのメモリ内データ構造ストアです。 非リレーショナルデータベースであるRedisは、その柔軟性、パフォーマンス、スケーラビリティ、および幅広い言語サポートで知られています。

Redisは、信頼できる環境で信頼できるクライアントが使用できるように設計されており、独自の堅牢なセキュリティ機能はありません。 ただし、Redisにはいくつかのセキュリティ機能があり、基本的な暗号化されていないパスワードとコマンドの名前変更と無効化が含まれています。 このチュートリアルでは、これらのセキュリティ機能を構成する方法について説明し、CentOS7でのスタンドアロンRedisインストールのセキュリティを強化できるその他の設定についても説明します。

このガイドは、Redisサーバーとクライアントアプリケーションが異なるホストまたは異なるデータセンターにある状況には対応していないことに注意してください。 Redisトラフィックが安全でない、または信頼できないネットワークを通過する必要があるインストールでは、Redisマシン間にSSLプロキシまたは VPN を設定するなど、異なる構成のセットが必要になります。

##前提条件

このチュートリアルに従うには、次のものが必要です。

  • CentOS7初期サーバーセットアップを使用して構成された1つのCentOS7ドロップレット。
  • このガイドを使用してインストールおよび構成されたFirewalldは、「ファイアウォールをオンにする」手順まで含まれています。

これらの前提条件が整ったら、Redisをインストールして、いくつかの初期構成タスクを実行する準備が整います。

##ステップ1—Redisのインストール

Redisをインストールする前に、まず Enterprise Linux(EPEL)リポジトリ用の追加パッケージをサーバーのパッケージリストに追加する必要があります。 EPELは、多数のオープンソースアドオンソフトウェアパッケージを含むパッケージリポジトリであり、そのほとんどはFedoraプロジェクトによって維持されています。

yumを使用してEPELをインストールできます。

  1. sudo yum install epel-release

EPELのインストールが完了したら、yumを使用してRedisをインストールできます。

  1. sudo yum install redis -y

これが完了するまでに数分かかる場合があります。 インストールが完了したら、Redisサービスを開始します。

  1. sudo systemctl start redis.service

起動時にRedisを起動する場合は、enableコマンドで有効にできます。

  1. sudo systemctl enable redis

次のコマンドを実行して、Redisのステータスを確認できます。

  1. sudo systemctl status redis.service
Output
● redis.service - Redis persistent key-value database Loaded: loaded (/usr/lib/systemd/system/redis.service; disabled; vendor preset: disabled) Drop-In: /etc/systemd/system/redis.service.d └─limit.conf Active: active (running) since Thu 2018-03-01 15:50:38 UTC; 7s ago Main PID: 3962 (redis-server) CGroup: /system.slice/redis.service └─3962 /usr/bin/redis-server 127.0.0.1:6379

Redisが実際に実行されていることを確認したら、次のコマンドを使用してセットアップをテストします。

  1. redis-cli ping

これにより、応答としてPONGが出力されます。 この場合は、サーバーでRedisを実行していることを意味し、セキュリティを強化するための構成を開始できます。

ステップ2—Redisをバインドしてファイアウォールで保護する

Redisを保護する効果的な方法は、Redisを実行しているサーバーを保護することです。 これを行うには、RedisがローカルホストまたはプライベートIPアドレスのいずれかにのみバインドされ、サーバーでファイアウォールが稼働していることを確認します。

ただし、このチュートリアルを使用してRedisクラスターをセットアップすることを選択した場合は、ローカルホストやプライベートIPへのバインドほど安全ではない、どこからでも接続できるように構成ファイルを更新します。

これを修正するには、編集用にRedis構成ファイルを開きます。

  1. sudo vi /etc/redis.conf

bindで始まる行を見つけて、コメントが外されていることを確認します。

/etc/redis.conf
bind 127.0.0.1

別のホストからRedisにアクセスする場合のように、Redisを別のIPアドレスにバインドする必要がある場合は、強くプライベートIPアドレスにバインドすることをお勧めします。 パブリックIPアドレスにバインドすると、Redisインターフェースが外部の関係者に公開される可能性が高くなります。

/etc/redis.conf
bind your_private_ip

前提条件に従い、サーバーにfirewalldをインストールしていて、別のホストからRedisに接続する予定がない場合は、Redisにファイアウォールルールを追加する必要はありません。 結局のところ、ファイアウォールルールで明示的に許可されていない限り、着信トラフィックはデフォルトでドロップされます。 Redisサーバーのデフォルトのスタンドアロンインストールはループバックインターフェイス(127.0.0.1またはlocalhost)でのみリッスンしているため、デフォルトのポートでの着信トラフィックについて心配する必要はありません。

ただし、別のホストからRedisにアクセスする予定がある場合は、firewall-cmdコマンドを使用してfirewalld構成にいくつかの変更を加える必要があります。 繰り返しになりますが、サービスが公開されるホストの数を制限するために、プライベートIPアドレスを使用してホストからのRedisサーバーへのアクセスのみを許可する必要があります。

まず、Firewalldポリシーに専用のRedisゾーンを追加します。

  1. sudo firewall-cmd --permanent --new-zone=redis

次に、開くポートを指定します。 Redisはデフォルトでポート6379を使用します。

  1. sudo firewall-cmd --permanent --zone=redis --add-port=6379/tcp

次に、ファイアウォールを通過してRedisにアクセスできるようにするプライベートIPアドレスを指定します。

  1. sudo firewall-cmd --permanent --zone=redis --add-source=client_server_private_IP

これらのコマンドを実行した後、ファイアウォールをリロードして新しいルールを実装します。

  1. sudo firewall-cmd --reload

この構成では、ファイアウォールがクライアントのIPアドレスからのパケットを検出すると、専用のRedisゾーンのルールをその接続に適用します。 他のすべての接続は、デフォルトのpublicゾーンで処理されます。 デフォルトゾーンのサービスは、明示的に一致しない接続だけでなく、すべての接続に適用されるため、他のサービスを追加する必要はありません(例: SSH)これらのルールがその接続に自動的に適用されるため、Redisゾーンに接続します。

Iptables を使用してファイアウォールを設定することを選択した場合は、次のコマンドを使用して、Redisが使用しているポートへのアクセスをセカンダリホストに許可する必要があります。

  1. sudo iptables -A INPUT -i lo -j ACCEPT
  2. sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
  3. sudo iptables -A INPUT -p tcp -s client_servers_private_IP/32 --dport 6379 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
  4. sudo iptables -P INPUT DROP

ディストリビューションが提供するメカニズムを使用して、Iptablesファイアウォールルールを保存してください。 Iptablesの詳細については、Iptablesエッセンシャルガイドをご覧ください。

どちらのファイアウォールツールを使用しても機能することに注意してください。 重要なのは、ファイアウォールが稼働していて、未知の個人がサーバーにアクセスできないようにすることです。 次のステップでは、強力なパスワードでのみアクセスできるようにRedisを構成します。

##ステップ3—Redisパスワードの設定

CentOS 7 チュートリアルでRedisクラスターを構成する方法を使用してRedisをインストールした場合は、そのパスワードを構成しておく必要があります。 あなたの裁量で、あなたはこのセクションに従うことによって今より安全なパスワードを作ることができます。 パスワードをまだ設定していない場合は、このセクションの手順に、データベースサーバーのパスワードを設定する方法が示されています。

Redisパスワードを設定すると、組み込みのセキュリティ機能の1つであるauthコマンドが有効になります。このコマンドでは、クライアントがデータベースへのアクセスを許可される前に認証する必要があります。 bind設定と同様に、パスワードはRedisの構成ファイル/etc/redis.confで直接構成されます。 そのファイルを再度開きます。

  1. sudo vi /etc/redis.conf

SECURITYセクションまでスクロールし、次のようなコメント付きディレクティブを探します。

/etc/redis.conf
# requirepass foobared

#を削除してコメントを解除し、foobaredを選択した非常に強力なパスワードに変更します。 パスワードを自分で作成するのではなく、apgpwgenなどのツールを使用してパスワードを生成することができます。 ただし、パスワードを生成するためだけにアプリケーションをインストールしたくない場合は、以下のコマンドを使用できます。

このコマンドを記述どおりに入力すると、毎回同じパスワードが生成されることに注意してください。 これが生成するものとは異なるパスワードを作成するには、引用符で囲まれた単語を他の単語またはフレーズに変更します。

  1. echo "digital-ocean" | sha256sum

生成されたパスワードは発音できませんが、非常に強力で非常に長いパスワードであり、Redisに必要なパスワードのタイプとまったく同じです。 そのコマンドの出力をrequirepassの新しい値としてコピーして貼り付けた後、次のようになります。

/etc/redis.conf
requirepass password_copied_from_output

より短いパスワードが必要な場合は、代わりに以下のコマンドの出力を使用してください。 繰り返しますが、引用符で囲まれた単語を変更して、これと同じパスワードが生成されないようにします。

  1. echo "digital-ocean" | sha1sum

パスワードを設定したら、ファイルを保存して閉じ、Redisを再起動します。

  1. sudo systemctl restart redis.service

パスワードが機能することをテストするには、Redisコマンドラインにアクセスします。

  1. redis-cli

以下は、Redisパスワードが機能するかどうかをテストするために使用される一連のコマンドです。 最初のコマンドは、認証前にキーを値に設定しようとします。

  1. set key1 10

まだ認証されていないため、これは機能しません。そのため、Redisはエラーを返します。

Output
(error) NOAUTH Authentication required.

次のコマンドは、Redis構成ファイルで指定されたパスワードで認証します。

  1. auth your_redis_password

Redisは、認証されたことを確認します。

Output
OK

その後、前のコマンドを再度実行すると成功するはずです。

  1. set key1 10
Output
OK

get key1コマンドは、Redisに新しいキーの値を問い合わせます。

  1. get key1
Output
"10"

この最後のコマンドはredis-cliを終了します。 exitを使用することもできます。

  1. quit

これで、許可されていないユーザーがRedisインストールにアクセスするのは非常に困難になります。 ただし、SSLまたはVPNがなくても、Redisにリモートで接続している場合は、暗号化されていないパスワードが外部の関係者に表示されることに注意してください。

次に、Redisコマンドの名前を変更して、Redisを悪意のある攻撃者からさらに保護する方法を見ていきます。

ステップ4—危険なコマンドの名前を変更する

Redisに組み込まれている他のセキュリティ機能を使用すると、危険と見なされる特定のコマンドの名前を変更したり、完全に無効にしたりできます。 許可されていないユーザーが実行した場合、このようなコマンドを使用して、データを再構成、破棄、またはその他の方法でワイプすることができます。 危険であることがわかっているコマンドには、次のものがあります。

  • FLUSHDB
  • FLUSHALL
  • KEYS
  • PEXPIRE
  • DEL
  • CONFIG
  • SHUTDOWN
  • BGREWRITEAOF
  • BGSAVE
  • SAVE
  • SPOP
  • SREM
    RENAME
    DEBUG

これは包括的なリストではありませんが、そのリスト内のすべてのコマンドの名前を変更するか無効にすることは、良い出発点です。

コマンドを無効にするか名前を変更するかは、サイト固有です。 悪用される可能性のあるコマンドを決して使用しないことがわかっている場合は、それを無効にすることができます。 それ以外の場合は、代わりに名前を変更する必要があります。

認証パスワードと同様に、コマンドの名前変更または無効化は、/etc/redis.confファイルのSECURITYセクションで構成されます。 Redisコマンドを有効または無効にするには、構成ファイルを開いてもう一度編集します。

  1. sudo vi /etc/redis.conf

:これらは例です。 自分にとって意味のあるコマンドを無効にするか、名前を変更するかを選択する必要があります。 redis.io/commands で、自分でコマンドを確認し、それらがどのように悪用される可能性があるかを判断できます。

コマンドを無効にするか強制終了するには、次に示すように、コマンドの名前を空の文字列に変更します。

/etc/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.conf
rename-command CONFIG ""
rename-command SHUTDOWN SHUTDOWN_MENOT
rename-command CONFIG ASC12_CONFIG

変更を保存してファイルを閉じてから、Redisを再起動して変更を適用します。

  1. sudo systemctl restart redis.service

新しいコマンドをテストするには、Redisコマンドラインを入力します。

  1. redis-cli

前に定義したパスワードを使用して自分自身を認証します。

  1. auth your_redis_password
Output
OK

CONFIGコマンドの名前をASC12_CONFIGに変更したとすると、configコマンドの使用は失敗するはずです。

  1. config get requirepass
Output
(error) ERR unknown command 'config'

名前が変更されたコマンドの呼び出しは成功するはずです(大文字と小文字は区別されません)。

  1. asc12_config get requirepass
Output
1) "requirepass" 2) "your_redis_password"

最後に、redis-cliを終了できます。

  1. exit

すでにRedisコマンドラインを使用してからRedisを再起動する場合は、再認証する必要があることに注意してください。 それ以外の場合、コマンドを入力すると次のエラーが発生します。

Output
NOAUTH Authentication required.

コマンドの名前変更に関しては、/etc/redis.confファイルのSECURITYセクションの最後に次のような注意事項があります。

/etc/redis.conf
. . .

# Please note that changing the name of commands that are logged into the
# AOF file or transmitted to slaves may cause problems.

. . .

つまり、名前が変更されたコマンドがAOFファイルにない場合、またはAOFファイルがスレーブに送信されていない場合は、問題はありません。 コマンドの名前を変更するときは、このことを覚えておいてください。 コマンドの名前を変更するのに最適なタイミングは、AOF永続性を使用していないとき、またはインストール直後(つまり、Redisを使用するアプリケーションがデプロイされる前)です。

AOFを使用していて、マスタースレーブのインストールを処理している場合は、プロジェクトのGitHubの問題ページからこの回答を検討してください。 以下は、作者の質問に対する回答です。

コマンドはAOFに記録され、送信されたのと同じ方法でスレーブに複製されるため、同じ名前変更がないインスタンスでAOFを再生しようとすると、コマンドを実行できないため、不整合が発生する可能性があります(スレーブについても同じです)。

このような場合に名前の変更を処理する最善の方法は、名前が変更されたコマンドがマスタースレーブインストールのすべてのインスタンスに適用されていることを確認することです。

手順5—データディレクトリの所有権とファイルのアクセス許可を設定する

このステップでは、Redisインストールのセキュリティプロファイルを改善するために行うことができる所有権と権限の変更をいくつか検討します。 これには、Redisにアクセスする必要があるユーザーのみがデータを読み取る権限を持っていることを確認する必要があります。 そのユーザーは、デフォルトではredisユーザーです。

これは、親ディレクトリの長いリストでRedisデータディレクトリをgrep-ingすることで確認できます。 コマンドとその出力を以下に示します。

  1. ls -l /var/lib | grep redis
Output
drwxr-xr-x 2 redis redis 4096 Aug 6 09:32 redis

Redisデータディレクトリがredisユーザーによって所有されており、redisグループにセカンダリアクセスが付与されていることがわかります。 この所有権設定は安全ですが、フォルダーのアクセス許可(755に設定されています)は安全ではありません。 Redisユーザーのみがフォルダーとそのコンテンツにアクセスできるようにするには、アクセス許可の設定を770に変更します。

  1. sudo chmod 770 /var/lib/redis

変更する必要がある他の権限は、Redis構成ファイルの権限です。 デフォルトでは、ファイル権限は644で、 root が所有し、rootグループが2次所有権を持ちます。

  1. ls -l /etc/redis.conf
Output
-rw-r--r-- 1 root root 30176 Jan 14 2014 /etc/redis.conf

その許可(644)は誰でも読み取り可能です。 これは、構成ファイルに手順4で構成した暗号化されていないパスワードが含まれているため、セキュリティの問題が発生します。つまり、構成ファイルの所有権とアクセス許可を変更する必要があります。 理想的には、 redis ユーザーが所有し、redisグループが二次所有する必要があります。 これを行うには、次のコマンドを実行します。

  1. sudo chown redis:redis /etc/redis.conf

次に、ファイルの所有者のみがファイルの読み取りや書き込みを行えるように、アクセス許可を変更します。

  1. sudo chmod 600 /etc/redis.conf

次を使用して、新しい所有権と権限を確認できます。

  1. ls -l /etc/redis.conf
Output
total 40 -rw------- 1 redis redis 29716 Sep 22 18:32 /etc/redis.conf

最後に、Redisを再起動します。

  1. sudo systemctl restart redis.service

おめでとうございます。Redisのインストールがより安全になりました。

結論

誰かがサーバーにログインすると、Redis固有のセキュリティ機能を簡単に回避できることに注意してください。 これが、このチュートリアルで取り上げる最も重要なセキュリティ機能がファイアウォールである理由です。ファイアウォールは、未知のユーザーが最初にサーバーにログインするのを防ぎます。

信頼できないネットワークを介してRedis通信を保護しようとしている場合は、公式RedisセキュリティガイドでRedis開発者が推奨しているように、SSLプロキシを使用する必要があります。