Rocky Linux 9にRedisをインストールしてセキュアにする方法
はじめに
Redisはキャッシングに優れたオープンソースのインメモリのキーバリューデータストアです。柔軟性、パフォーマンス、スケーラビリティ、そして多言語サポートで知られる非リレーショナルデータベースです。
Redisは、信頼できるクライアントが信頼できる環境で使用することを目的として設計されており、独自の堅牢なセキュリティ機能はありません。ただし、Redisにはパスワード認証や一部のコマンドの名前変更や無効化など、いくつかのセキュリティ機能があります。このチュートリアルでは、Redisのインストール方法とこれらのセキュリティ機能の設定方法について説明します。また、Rocky Linux 9上のスタンドアロンのRedisインストールのセキュリティを向上させるいくつかの他の設定もカバーします。
Redisサーバとクライアントアプリケーションが異なるホストまたは異なるデータセンタにある場合には、このガイドでは対応していません。セキュリティの弱いネットワークや信頼できないネットワークを経由するRedisトラフィックが必要な場合には、別の設定が必要です。たとえば、SSLプロキシやRedisマシン間のVPNの設定などが必要です。
必要条件
このチュートリアルを完了するためには、Rocky Linux 9を実行しているサーバーが必要です。このサーバーには、管理特権を持つ非ルートユーザーと、Firewalldで構成されたファイアウォールが必要です。セットアップするには、Rocky Linux 9の初期サーバーセットアップガイドに従ってください。
ステップ1 – Redisのインストールと起動
DNFパッケージマネージャーを使用してRedisをインストールすることができます。DNFを使ってRedisとその依存関係、そしてユーザーフレンドリーなテキストエディタであるnanoをインストールすることができます。nanoをインストールする必要はありませんが、このガイド全体で例として使用します。
- sudo dnf install redis nano
このコマンドを実行すると、選択したパッケージをインストールするか確認が表示されます。インストールを希望する場合は「y」を押してからENTERキーを押してください。
. . . Total download size: 2.0 M Installed size: 7.4 M Is this ok [y/N]: y
その後、インストール中に自動生成されたRedisの設定ファイルには、重要な構成変更が1つ必要です。
お好きなテキストエディタでこのファイルを開いてください。ここではnanoを使用します。
- sudo nano /etc/redis/redis.conf
ファイル内で「supervised」ディレクティブを探します。このディレクティブはRedisをサービスとして管理するための初期化システムを宣言することができ、より操作を制御できます。デフォルトでは、supervisedディレクティブは「no」に設定されています。Rocky Linuxを使用している場合は、systemd初期化システムを使用しているため、必要に応じて(先頭の#を削除して)行のコメントを解除し、これをsystemdに変更してください。
. . .
# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
# supervised no - no supervision interaction
# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
# supervised auto - detect upstart or systemd method based on
# UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
# They do not enable continuous liveness pings back to your supervisor.
supervised systemd
. . .
現時点では、Redisの設定ファイルで行う必要があるのはこの変更だけです。完了したら保存して閉じてください。もしファイルの編集にnanoを使用していた場合は、CTRL + Xで保存して終了し、プロンプトが表示されたらYとEnterキーを押してください。
ファイルを編集したら、Redisサービスを起動してください。
- sudo systemctl start redis.service
もしRedisを起動時に起動させたい場合は、enableコマンドを使って有効にすることができます。
- sudo systemctl enable redis
.サービスト名の後ろには、このコマンドには.serviceの接尾辞が含まれていないことに注意してください。通常、systemctlコマンドでは、サービス名から自動的にこの接尾辞を削除することができるため、この接尾辞を省略できます。
以下を実行することで、Redisのステータスを確認することができます。
- sudo systemctl status redis
● 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が実際に稼働していることを確認したら、このコマンドを使用してその機能をテストすることができます。
- redis-cli ping
これはPONGという応答を表示するはずです。
PONG
もし、それが事実ならば、サーバー上でRedisが起動しており、セキュリティを向上させるために設定を開始できることを意味します。
ステップ2- Redisの構成とファイアウォールによるセキュリティの設定
Redisを保護する効果的な方法は、Redisが動作しているサーバー自体を安全にすることです。これを実現するには、RedisがlocalhostまたはプライベートIPアドレスにのみバインドされ、さらにサーバー上でファイアウォールが稼働していることを確認します。
ただし、別のチュートリアルを使用してRedisをセットアップした場合、設定ファイルを更新してどこからでも接続できるようにするかもしれません。これはlocalhostやプライベートIPにバインドするよりも安全ではありません。
これを修正するために、お好みのテキストエディタでRedisの設定ファイルを再度開いてください。
- sudo nano /etc/redis/redis.conf
「bind」で始まる行を見つけて、行がコメントアウトされていないか無効にされていないことを確認してください。必要な場合には、行の先頭の#記号を取り除いてください。
/etc/redis/redis.conf
. . .
bind 127.0.0.1 -::1
Redisを別のIPアドレスにバインドする必要がある場合(Redisへ別のホストからアクセスする場合など)は、プライベートIPアドレスにバインドすることを強くお勧めします。パブリックIPアドレスにバインドすると、Redisインターフェースが外部の第三者に公開される可能性が高まります。
. . .
bind your_private_ip
バインドディレクティブがコメントアウトされていないことを確認したら、ファイルを保存し閉じることができます。
前提のInitial Server Setupチュートリアルに従って、サーバーにfirewalldをインストールし、別のホストからRedisに接続する予定がない場合、Redisの追加のファイアウォールルールは必要ありません。なぜなら、ファイアウォールルールによって明示的に許可されない限り、デフォルトではすべての受信トラフィックは破棄されるからです。デフォルトの単独インストールのRedisサーバーは、ループバックインターフェース(127.0.0.1またはlocalhost)でのみリスニングしているため、デフォルトポートでの受信トラフィックに対して心配する必要はありません。
ただし、別のホストからRedisにアクセスする予定がある場合は、firewall-cmdコマンドを使用してfirewalldの設定を変更する必要があります。再度言いますが、サービスに公開されているホストの数を制限するために、ホストのプライベートIPアドレスを使用してRedisサーバーへのアクセスを許可するようにしてください。
最初に、あなたのfirewalldポリシーに専用のRedisゾーンを追加してください。
- sudo firewall-cmd –permanent –new-zone=redis
デフォルトでは、Redisはポート番号6379を使用しますので、開放してほしいポートを指定してください。
- sudo firewall-cmd –permanent –zone=redis –add-port=6379/tcp
次に、ファイアウォールを通過してRedisにアクセスできるように許可されるべきプライベートIPアドレスを指定してください。
- sudo firewall-cmd –permanent –zone=redis –add-source=client_server_private_IP
これらのコマンドを実行した後、新しいルールを適用するためにファイアウォールを再読み込みしてください。
- sudo firewall-cmd –reload
この構成では、ファイアウォールがクライアントのIPアドレスからのパケットに遭遇した場合、それに対して専用のRedisゾーンのルールが適用されます。その他の接続はデフォルトのパブリックゾーンで処理されます。デフォルトゾーンのサービスは、明示的に一致しない接続だけでなく、すべての接続に適用されるため、Redisゾーンに他のサービス(例:SSH)を追加する必要はありません。そのルールはその接続に自動的に適用されます。
ファイアウォールツールの種類は問いませんが、firewalld、ufw、またはiptablesのいずれかを使用すると、ファイアウォールを作動させることが重要です。未知のユーザーがサーバーにアクセスできないようにするためです。次のステップでは、Redisのアクセスを強力なパスワードで制限します。
ステップ3 – Redisパスワードの設定
Redisのパスワードを設定すると、その中に組み込まれたセキュリティ機能の1つである「認証コマンド」を有効にすることができます。このコマンドにより、データベースへのアクセスを許可する前にクライアントが認証する必要があります。bind設定と同様に、パスワードはRedisの設定ファイルである「/etc/redis/redis.conf」に直接設定されます。そのファイルを開きなおしてください。
- sudo nano /etc/redis/redis.conf
「SECURITY」セクションにスクロールし、コメントされた指示の中から、以下のように記載された指令を探してください。
. . .
# requirepass foobared
#を削除してコメントを外して、foobaredを自分が選んだ非常に強力なパスワードに変更してください。
Note
このコマンドをそのまま入力すると、同じパスワードが常に生成されますので注意してください。一意のパスワードを作成するには、引用符内の文字列を他の単語やフレーズに変更してください:
echo “digital-ocean” | sha256sum
生成されたパスワードは覚えにくいですが、Redisに必要なタイプの非常に強力で長いパスワードです。そのコマンドの出力をrequirepassの新しい値としてコピー&ペーストした後、次のようになります:
/etc/redis/redis.conf
. . .
requirepass password_copied_from_output
また、より短いパスワードを希望する場合は、別のチェックサムの出力を使用することもできます。再度引用符内の単語を変更し、このコマンドと同じパスワードが生成されないようにしてください:
echo “digital-ocean” | sha1sum
パスワードを設定したら、ファイルを保存して閉じ、Redisを再起動してください。
- sudo systemctl restart redis
パスワードが機能するかテストするために、Redisクライアントを開いてみてください。
- redis-cli
Redisのパスワードが機能するかをテストするために使用されるコマンドのシーケンスが以下に示されています。最初のコマンドでは、認証前にキーを値に設定しようとします。
- set key1 10
認証がまだ行われていないため、それは機能しません。そのため、Redisはエラーを返します。
(error) NOAUTH Authentication required.
次のコマンドは、Redisの設定ファイルで指定されたパスワードを使って認証を行います。
- auth your_redis_password
Redisは、あなたが認証されたことを認識します。
OK
その後、前のコマンドを再実行すれば成功するはずです。 (Sono ato, mae no komando o sai jikkō sureba seikō suru hazu desu.)
- set key1 10
OK
get key1 コマンドは、新しいキーの値をRedisに問い合わせます。
- get key1
“10”
最後のコマンドはredis-cliを終了します。exitコマンドでも終了することができます。
- 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
これは網羅的なリストではありませんが、このリストにあるコマンドのすべてを名前の変更または無効化することで、データストアのセキュリティを向上させることができます。特定のコマンドを無効化するか、名前を変更するかは、あなたの具体的なニーズによります。問題のあるコマンドを絶対に使用しないことがわかっている場合は無効化してください。そうでなければ、名前を変更する必要があります。
認証パスワードのように、Redisのコマンドの名前変更や無効化は、/etc/redis/redis.confファイルのセキュリティセクションで設定されています。Redisのコマンドの有効化または無効化を行うには、編集用にもう一度設定ファイルを開いてください。
- sudo nano /etc/redis/redis.conf
Note
コマンドを無効化または削除するには、以下のように名前を空に変更します。
# 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 ""
コマンドの名前を変更するためには、以下の例のように別の名前を付けてください。名前を変更したコマンドは他の人には推測しにくく、自分にとっては簡単に覚えられるようにしてください。
# 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 ""
rename-command SHUTDOWN SHUTDOWN_MENOT
rename-command CONFIG ASC12_CONFIG
変更内容を保存してファイルを閉じてください。その後、Redisを再起動して変更内容を適用してください。
- sudo systemctl restart redis.service
新しいコマンドをテストするために、Redisのコマンドラインに入力してください。
- redis-cli
以前定義したパスワードを使用して、自分自身を認証してください。
- auth your_redis_password
OK
CONFIGコマンドをASC12_CONFIGに変更した場合、configコマンドを使用しようとすると失敗します。
- config get requirepass
(error) ERR unknown command ‘config’
名前が変更されたコマンドを呼び出すと成功します。Redisのコマンドは大文字小文字を区別しませんので、注意してください。
- asc12_config get requirepass
1) “requirepass” 2) “your_redis_password”
最後に、redis-cliから出ることができます。
- exit
Warning
/etc/redis/redis.conf
. . .
# コマンドの名前を変更する際、AOF ファイルに記録されるか、レプリカに送信されるコマンドを変更する場合、問題が発生する可能性があることに留意してください。
. . .
つまり、変更されたコマンドがAOFファイルに存在しない場合、または存在しているがAOFファイルがレプリカに送信されていない場合は、問題は発生しないということです。コマンドを変更する際にはそれを念頭に置いてください。コマンドの名前を変更する最適なタイミングは、AOF永続化を使用していない場合やRedisを使用するアプリケーションが展開される前です。
ステップ5:データディレクトリの所有権とファイルのパーミッションの設定
この手順では、Redisのインストールのセキュリティプロファイルを向上させるために行う必要がある、所有権とパーミッションの変更について説明します。これは、Redisのデータにアクセスする必要のあるユーザーのみが読み取り権限を持つことを確認することを含みます。デフォルトでは、そのユーザーはredisユーザーです。
Redisのデータディレクトリを親ディレクトリの長いリストにgrepして確認することができます。以下に、このコマンドとその出力を示します。
- ls -l /var/lib | grep redis
drwxr-x—. 2 redis redis 22 Sep 6 22:22 redis
この出力は、Redisデータディレクトリがredisユーザーに所有され、redisグループにも二次アクセスが許可されていることを示しています。この所有権の設定はセキュアであり、フォルダのパーミッションも、8進数表記を使用して750に設定されています。
もしRedisのデータディレクトリのパーミッションが安全ではない場合、chmodコマンドを実行することでRedisのユーザーとグループにのみアクセス権を持たせることができます。次の例では、このフォルダのパーミッション設定を770に変更します。
- sudo chmod 770 /var/lib/redis
変更する必要がある他の許可は、Redisの設定ファイルの許可です。デフォルトでは、ファイルの許可は640であり、所有者はrootで、2次の所有者はrootグループです。
- ls -l /etc/redis/redis.conf
-rw-r—–. 1 redis root 62192 Sep 6 22:20 /etc/redis/redis.conf
その権限(640)は、Redisの設定ファイルがredisユーザーとrootグループのみが読み取れることを意味します。設定ファイルにはステップ4で設定した暗号化されていないパスワードが含まれているため、redis.confはredisユーザーの所有とredisグループの権限を持つ必要があります。これを設定するには、以下のコマンドを実行してください。
- sudo chown redis:redis /etc/redis/redis.conf
その後、権限を変更して、ファイルの所有者だけが読み書きできるようにしてください。
- sudo chmod 600 /etc/redis/redis.conf
前回のlsコマンドを再実行することで、新しい所有権とアクセス権を確認することができます。
- ls -l /var/lib | grep redis
total 40 drwxrwx—. 2 redis redis 22 Sep 6 22:22 redis
- ls -l /etc/redis/redis.conf
total 40 -rw——-. 1 redis redis 62192 Sep 6 22:20 /etc/redis/redis.conf
最後に、これらの変更を反映するためにRedisを再起動してください。
- sudo systemctl restart redis
それにより、お使いのRedisのインストールはセキュリティが確保されました。
結論
サーバーにログインした場合、Redis固有のセキュリティ機能を回避することが可能ですので、それを念頭に置いてください。そのため、このチュートリアルで最も重要なセキュリティ機能はファイアウォールです。ファイアウォールによって、不明なユーザーが最初の段階でサーバーにログインするのを防ぐことができます。
信頼できないネットワーク上でRedis通信を安全に行う場合、Redis開発者が公式Redisセキュリティガイドで推奨するように、SSLプロキシを使用する必要があります。