Rocky Linux 8にRedisをインストールしてセキュリティを強化する方法

イントロダクション

Redisは、キャッシュに優れたオープンソースのインメモリキーバリューデータストアです。Redisは、柔軟性、パフォーマンス、スケーラビリティ、そして広範な言語サポートで知られる非関係型データベースです。

Redisは、信頼できるクライアントが信頼できる環境で使用することを想定して設計されており、独自の堅牢なセキュリティ機能はありません。ただし、Redisにはパスワード認証や一部のコマンドの名前変更や無効化など、いくつかのセキュリティ機能があります。このチュートリアルでは、Redisのインストール方法とこれらのセキュリティ機能の設定方法について説明します。また、Rocky Linux 8上のスタンドアロンRedisインストールのセキュリティを向上させるためのいくつかの他の設定についてもカバーします。

なお、このガイドはRedisサーバーとクライアントアプリケーションが異なるホストまたは異なるデータセンターにある場合を対象としていません。Redisトラフィックが安全で信頼できないネットワークを経由する場合は、SSLプロキシやVPNの設定など、異なる設定が必要になります。

DigitalOceanの管理されたRedisサービスも利用することができます。

前提条件

このチュートリアルを完了するには、Rocky Linux 8を実行するサーバーが必要です。このサーバーには、管理特権を持つ非ルートユーザーと、firewalldで構成されたファイアウォールが設定されている必要があります。これを設定するには、Rocky Linux 8の初期サーバーセットアップガイドに従ってください。

ステップ1 – Redisのインストールと起動

DNFパッケージマネージャーを使用してRedisをインストールできます。DNFを使用すると、Redisとその依存関係、およびユーザーフレンドリーなテキストエディタであるnanoを一括でインストールできます。nanoをインストールする必要はありませんが、このガイド全体で例として使用します。

  1. sudo dnf install redis nano

このコマンドは、選択したパッケージをインストールするかどうかの確認を求められます。インストールする場合は、yを押してからENTERキーを押してください。

Output
. . . Total download size: 1.5 M Installed size: 5.4 M Is this ok [y/N]: y

その後、インストール中に自動的に生成されたRedisの設定ファイルで重要な設定変更を行う必要があります。

お好みのテキストエディタでこのファイルを開いてください。ここではnanoを使用します。

  1. sudo nano /etc/redis.conf

ファイル内で、supervisedディレクティブを見つけてください。このディレクティブを使用すると、Redisをサービスとして管理するためのinitシステムを宣言することができ、その動作に対してより多くの制御を提供します。デフォルトではsupervisedディレクティブはnoに設定されています。Rocky Linuxを実行しているため、systemd initシステムを使用するため、これをsystemdに変更してください。

/etc/redis.conf
. . .

# もしRedisをupstartまたはsystemdから実行している場合、Redisは
# 監視ツリーと対話できます。オプション:
#   supervised no      - 監視の対話なし
#   supervised upstart - RedisをSIGSTOPモードにすることでupstartにシグナルを送る
#   supervised systemd - $NOTIFY_SOCKETにREADY=1を書くことでsystemdにシグナルを送る
#   supervised auto    - UPSTART_JOBまたはNOTIFY_SOCKET環境変数に基づいて
#                        upstartまたはsystemdの方法を自動的に検出する
# 注: これらの監視方法は "プロセスが準備完了" というシグナルのみ送ります。
#       これらは、監視ツールに対して連続的な生存確認を有効にするものではありません。
supervised systemd

. . .

この時点でRedisの設定ファイルで行う必要がある唯一の変更はこれだけですので、終了時に保存して閉じてください。ファイルを編集するためにnanoを使用した場合は、CTRL + Xで保存して終了し、プロンプトが表示されたらY、Enterを押します。

ファイルの編集が完了したら、Redisサービスを起動します。

  1. sudo systemctl start redis.service

Redisを起動時に開始する場合は、enableコマンドを使用して有効にすることができます。

  1. sudo systemctl enable redis

このコマンドには、ユニットファイル名の後ろに.serviceの接尾辞が含まれていないことに注意してください。通常、systemctlコマンドではこの接尾辞を省略することができます。なぜなら、サービス名から自動的に解析されるからです。

次のコマンドを実行して、Redisの状態を確認できます:

  1. sudo systemctl status redis
Output
● redis.service - Redis persistent key-value database Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/redis.service.d └─limit.conf Active: active (running) since Tue 2022-09-06 22:11:52 UTC; 40s ago Main PID: 14478 (redis-server) Tasks: 4 (limit: 11152) Memory: 6.6M CGroup: /system.slice/redis.service └─14478 /usr/bin/redis-server 127.0.0.1:6379

Redisが実行されていることを確認したら、次のコマンドでその機能をテストすることができます:

  1. redis-cli ping

これにより、応答としてPONGが表示されるはずです:

Output
PONG

この場合、サーバー上でRedisが実行されていることを意味し、セキュリティを向上させるために設定を開始できます。

ステップ2 — Redisの設定とファイアウォールによるセキュリティの強化

Redisを保護する効果的な方法は、実行中のサーバーをセキュリティで保護することです。これは、RedisがlocalhostまたはプライベートIPアドレスにのみバインドされ、サーバーにファイアウォールが設定されていることを確認することによって実現できます。

ただし、他のチュートリアルを使用してRedisを設定した場合は、設定ファイルを更新してどこからでも接続できるようにしている可能性があります。これはlocalhostやプライベートIPにバインドするよりも安全ではありません。

これを修正するには、お好みのテキストエディタでRedisの設定ファイルを再度開いてください。

  1. sudo nano /etc/redis.conf

bindで始まる行を探し、必要な場合は行の先頭の#を削除して、コメントアウトまたは無効化されていないことを確認してください。

/etc/redis.conf
. . .
bind 127.0.0.1

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

/etc/redis.conf
. . .
bind your_private_ip

bindディレクティブがコメントアウトされていないことを確認した後、ファイルを保存して閉じることができます。

前提条件の「初期サーバーセットアップチュートリアル」に従い、サーバーにfirewalldをインストールし、別のホストからRedisに接続する予定がない場合は、Redisのために追加のファイアウォールルールを追加する必要はありません。なぜなら、デフォルトの単独インストールのRedisサーバーはループバックインターフェース(127.0.0.1またはlocalhost)のみをリッスンしているため、デフォルトポートへの着信トラフィックには心配する必要がないからです。

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

まず、専用のRedisゾーンをfirewalldポリシーに追加してください。

  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ゾーンで処理されます。デフォルトゾーンのサービスは、明示的に一致しない接続に対しても適用されるため、Redisゾーンに他のサービス(例:SSH)を追加する必要はありません。

ファイアウォールツールの使用方法はどれを使用しても機能しますが、firewalldufw、またはiptablesを使用していることが重要です。ファイアウォールが稼働していることで、不正な個人がサーバーにアクセスできないようにします。次のステップでは、Redisが強力なパスワードでのみアクセス可能になるように設定します。

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

Redisのパスワードを設定すると、その内部のセキュリティ機能であるauthコマンドが有効になり、データベースへのアクセスを許可する前にクライアントの認証が必要となります。パスワードはRedisの設定ファイルである/etc/redis.confに直接設定されます。ファイルを開いてください:

  1. sudo nano /etc/redis.conf

SECURITYセクションまでスクロールし、以下のコメント付きの指示文を探してください:

/etc/redis.conf
. . .
# requirepass foobared

コメントアウトを解除するために、#を削除し、foobaredを自分で選んだ非常に強力なパスワードに変更してください。

注意: パスワードを自分で考える代わりに、apgpwgenなどのツールを使用してパスワードを生成することができます。ただし、パスワードを生成するためだけにアプリケーションをインストールしたくない場合は、以下のコマンドを使用することができます。このコマンドは文字列の値をエコーし、次のsha256sumコマンドにパイプで渡すことにより、文字列のSHA256チェックサムを表示します。

このコマンドをそのまま入力すると、毎回同じパスワードが生成されますので注意してください。一意のパスワードを生成するには、引用符内の文字列を他の単語やフレーズに変更してください:

  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

パスワードが機能するかどうかをテストするために、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にアクセスすることは非常に困難になります。ただし、既にRedisコマンドラインクライアントを使用していて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 nano /etc/redis.conf

注意: これらは例です。自分に合った無効化または名前変更を選択する必要があります。Redisのコマンドについて詳しく学び、どのように誤用される可能性があるかを確認するには、redis.io/commandsを参照してください。

コマンドを無効化または削除するには、次のように空の文字列に名前を変更します:

/etc/redis.conf
# コマンドを完全に削除するには、
# 空の文字列に名前を変更することも可能です:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""

コマンドの名前を変更するには、以下の例のように別の名前を指定します。名前を変更したコマンドは他の人には推測しにくく、自分には覚えやすいようにしてください:

/etc/redis.conf
# コマンドを完全に削除するには、
# 空の文字列に名前を変更することも可能です:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
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'

代わりに、名前を変更したコマンドを使用すると成功します。Redisのコマンドは大文字小文字を区別しませんので、注意してください:

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

最後に、redis-cliから終了することができます:

  1. exit

警告: コマンドの名前変更に関しては、/etc/redis.confファイルのSECURITYセクションの最後に注意書きがあります。

/etc/redis.conf
. . .

# コマンドの名前を変更する際には、AOFファイルに記録されたコマンド名やレプリカに送信されるコマンド名を変更しないように注意してください。
# もし変更したコマンドがAOFファイルに存在しない場合や、存在するがレプリカに送信されていない場合は問題ありません。

. . .

コマンド名を変更する際には、これを念頭に置いてください。コマンド名を変更する最適なタイミングは、AOF永続化を使用していない場合や、Redisを使用するアプリケーションが展開される前(つまり、インストール直後)です。

ステップ5 — データディレクトリの所有者とファイルのパーミッションの設定

このステップでは、Redisインストールのセキュリティプロファイルを向上させるために行う所有者とパーミッションの変更について説明します。Redisへのアクセスが必要なユーザーのみがデータに読み取り権限を持つようにすることが重要です。デフォルトでは、そのユーザーはredisユーザーです。

このことを確認するために、親ディレクトリの長いリストにRedisのデータディレクトリをgrepコマンドで検索してください。以下にコマンドとその出力を示します:

  1. ls -l /var/lib | grep redis
Output
drwxr-x---. 2 redis redis 22 Sep 6 22:22 redis

この出力は、Redisのデータディレクトリがredisユーザーの所有であり、redisグループにセカンダリアクセスが許可されていることを示しています。この所有設定は安全であり、フォルダのパーミッションは8進数表記を使用して750に設定されています。

Redisのデータディレクトリのパーミッションが安全でない場合、chmodコマンドを実行してRedisユーザーとグループのみがフォルダとその内容にアクセスできるようにすることができます。次の例では、このフォルダのパーミッション設定を770に変更します:

  1. sudo chmod 770 /var/lib/redis

変更が必要なもう1つのパーミッションは、Redisの設定ファイルのものです。デフォルトでは、ファイルのパーミッションは640であり、所有者はrootであり、セカンダリの所有者はrootグループです:

  1. ls -l /etc/redis.conf
Output
-rw-r-----. 1 redis root 62192 Sep 6 22:20 /etc/redis.conf

このパーミッション(640)は、Redisの設定ファイルがredisユーザーとrootグループのみが読み取れることを意味します。設定ファイルには、ステップ4で設定した暗号化されていないパスワードが含まれているため、redis.confredisユーザーの所有で、セカンダリの所有者はredisグループである必要があります。これを設定するには、次のコマンドを実行します:

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

その後、所有者だけがファイルを読み書きできるようにパーミッションを変更します:

  1. sudo chmod 600 /etc/redis.conf

前のlsコマンドを再度実行して新しい所有者とパーミッションを確認できます:

  1. ls -l /var/lib | grep redis
Output
total 40 drwxrwx---. 2 redis redis 22 Sep 6 22:22 redis
  1. ls -l /etc/redis.conf
Output
total 40 -rw-------. 1 redis redis 62192 Sep 6 22:20 /etc/redis.conf

最後に、これらの変更を反映するためにRedisを再起動します:

  1. sudo systemctl restart redis

以上で、Redisのインストールがセキュリティ強化されました。

結論

ログイン済みのサーバーには、Redis固有のセキュリティ機能を回避することが可能です。そのため、このチュートリアルで最も重要なセキュリティ機能はファイアウォールです。ファイアウォールにより、未知のユーザーが最初にサーバーにログインすることを防ぎます。

信頼できないネットワーク上でRedis通信を安全にするには、Redis開発者が勧めるようにSSLプロキシを使用する必要があります。これについては、公式Redisセキュリティガイドで推奨されています。

Source:
https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-rocky-linux-8