イントロダクション
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
をインストールする必要はありませんが、このガイド全体で例として使用します。
- 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
を使用します。
- sudo nano /etc/redis.conf
ファイル内で、supervised
ディレクティブを見つけてください。このディレクティブを使用すると、Redisをサービスとして管理するためのinitシステムを宣言することができ、その動作に対してより多くの制御を提供します。デフォルトではsupervised
ディレクティブはno
に設定されています。Rocky Linuxを実行しているため、systemd initシステムを使用するため、これをsystemd
に変更してください。
. . .
# もし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サービスを起動します。
- sudo systemctl start redis.service
Redisを起動時に開始する場合は、enable
コマンドを使用して有効にすることができます。
- sudo systemctl enable redis
このコマンドには、ユニットファイル名の後ろに.service
の接尾辞が含まれていないことに注意してください。通常、systemctl
コマンドではこの接尾辞を省略することができます。なぜなら、サービス名から自動的に解析されるからです。
次のコマンドを実行して、Redisの状態を確認できます:
- 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が実行されていることを確認したら、次のコマンドでその機能をテストすることができます:
- redis-cli ping
これにより、応答としてPONG
が表示されるはずです:
OutputPONG
この場合、サーバー上でRedisが実行されていることを意味し、セキュリティを向上させるために設定を開始できます。
ステップ2 — Redisの設定とファイアウォールによるセキュリティの強化
Redisを保護する効果的な方法は、実行中のサーバーをセキュリティで保護することです。これは、RedisがlocalhostまたはプライベートIPアドレスにのみバインドされ、サーバーにファイアウォールが設定されていることを確認することによって実現できます。
ただし、他のチュートリアルを使用してRedisを設定した場合は、設定ファイルを更新してどこからでも接続できるようにしている可能性があります。これはlocalhostやプライベートIPにバインドするよりも安全ではありません。
これを修正するには、お好みのテキストエディタでRedisの設定ファイルを再度開いてください。
- sudo nano /etc/redis.conf
bind
で始まる行を探し、必要な場合は行の先頭の#
を削除して、コメントアウトまたは無効化されていないことを確認してください。
. . .
bind 127.0.0.1
Redisを別のIPアドレスにバインドする必要がある場合(別のホストからRedisにアクセスする場合など)、プライベートIPアドレスにバインドすることを強くお勧めします。パブリックIPアドレスにバインドすると、Redisインターフェースが外部のパーティーに公開される可能性が高まります。
. . .
bind your_private_ip
bind
ディレクティブがコメントアウトされていないことを確認した後、ファイルを保存して閉じることができます。
前提条件の「初期サーバーセットアップチュートリアル」に従い、サーバーにfirewalldをインストールし、別のホストからRedisに接続する予定がない場合は、Redisのために追加のファイアウォールルールを追加する必要はありません。なぜなら、デフォルトの単独インストールのRedisサーバーはループバックインターフェース(127.0.0.1
またはlocalhost)のみをリッスンしているため、デフォルトポートへの着信トラフィックには心配する必要がないからです。
ただし、別のホストからRedisにアクセスする予定がある場合は、firewall-cmd
コマンドを使用してfirewalldの設定にいくつかの変更を加える必要があります。再度、サービスが公開されるホストの数を制限するために、ホストのプライベートIPアドレスを使用してRedisサーバーへのアクセスのみを許可する必要があります。
まず、専用のRedisゾーンをfirewalldポリシーに追加してください。
- 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ゾーンのルールをその接続に適用します。他の接続はデフォルトのpublic
ゾーンで処理されます。デフォルトゾーンのサービスは、明示的に一致しない接続に対しても適用されるため、Redisゾーンに他のサービス(例:SSH)を追加する必要はありません。
ファイアウォールツールの使用方法はどれを使用しても機能しますが、firewalld
、ufw
、またはiptables
を使用していることが重要です。ファイアウォールが稼働していることで、不正な個人がサーバーにアクセスできないようにします。次のステップでは、Redisが強力なパスワードでのみアクセス可能になるように設定します。
ステップ3 — Redisパスワードの設定
Redisのパスワードを設定すると、その内部のセキュリティ機能であるauth
コマンドが有効になり、データベースへのアクセスを許可する前にクライアントの認証が必要となります。パスワードはRedisの設定ファイルである/etc/redis.conf
に直接設定されます。ファイルを開いてください:
- sudo nano /etc/redis.conf
SECURITY
セクションまでスクロールし、以下のコメント付きの指示文を探してください:
. . .
# requirepass foobared
コメントアウトを解除するために、#
を削除し、foobared
を自分で選んだ非常に強力なパスワードに変更してください。
注意: パスワードを自分で考える代わりに、apg
やpwgen
などのツールを使用してパスワードを生成することができます。ただし、パスワードを生成するためだけにアプリケーションをインストールしたくない場合は、以下のコマンドを使用することができます。このコマンドは文字列の値をエコーし、次のsha256sum
コマンドにパイプで渡すことにより、文字列のSHA256チェックサムを表示します。
このコマンドをそのまま入力すると、毎回同じパスワードが生成されますので注意してください。一意のパスワードを生成するには、引用符内の文字列を他の単語やフレーズに変更してください:
- echo "digital-ocean" | sha256sum
生成されたパスワードは記憶に残りにくいかもしれませんが、Redisに必要な強力で長いパスワードです。このコマンドの出力をrequirepass
の新しい値としてコピー&ペーストした後、以下のようになるはずです:
. . .
requirepass password_copied_from_output
もしくは、より短いパスワードを好む場合は、異なるチェックサムの出力を使用することもできます。再度、引用符内の単語を変更して、このコマンドとは異なるパスワードが生成されるようにしてください。
- echo "digital-ocean" | sha1sum
パスワードを設定した後、ファイルを保存して閉じ、Redisを再起動します。
- sudo systemctl restart redis
パスワードが機能するかどうかをテストするために、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-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
これは包括的なリストではありませんが、このリストのすべてのコマンドの名前を変更または無効化することで、データストアのセキュリティを向上させることができます。特定のコマンドを無効化するか、名前を変更するかは、具体的なニーズによります。悪用される可能性のあるコマンドを使用しないことがわかっている場合は、無効化することができます。それ以外の場合は、名前を変更することをお勧めします。
認証パスワードと同様に、コマンドの名前を変更または無効化する設定は、/etc/redis.conf
ファイルのSECURITY
セクションで行われます。Redisコマンドの有効化または無効化を行うには、編集用に構成ファイルを開きます。
- sudo nano /etc/redis.conf
注意: これらは例です。自分に合った無効化または名前変更を選択する必要があります。Redisのコマンドについて詳しく学び、どのように誤用される可能性があるかを確認するには、redis.io/commandsを参照してください。
コマンドを無効化または削除するには、次のように空の文字列に名前を変更します:
# コマンドを完全に削除するには、
# 空の文字列に名前を変更することも可能です:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
コマンドの名前を変更するには、以下の例のように別の名前を指定します。名前を変更したコマンドは他の人には推測しにくく、自分には覚えやすいようにしてください:
# コマンドを完全に削除するには、
# 空の文字列に名前を変更することも可能です:
#
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
OutputOK
CONFIG
コマンドをASC12_CONFIG
に名前変更したと仮定し、config
コマンドを使用しようとすると失敗します:
- config get requirepass
Output(error) ERR unknown command 'config'
代わりに、名前を変更したコマンドを使用すると成功します。Redisのコマンドは大文字小文字を区別しませんので、注意してください:
- asc12_config get requirepass
Output1) "requirepass"
2) "your_redis_password"
最後に、redis-cli
から終了することができます:
- exit
警告: コマンドの名前変更に関しては、/etc/redis.conf
ファイルのSECURITY
セクションの最後に注意書きがあります。
. . .
# コマンドの名前を変更する際には、AOFファイルに記録されたコマンド名やレプリカに送信されるコマンド名を変更しないように注意してください。
# もし変更したコマンドがAOFファイルに存在しない場合や、存在するがレプリカに送信されていない場合は問題ありません。
. . .
コマンド名を変更する際には、これを念頭に置いてください。コマンド名を変更する最適なタイミングは、AOF永続化を使用していない場合や、Redisを使用するアプリケーションが展開される前(つまり、インストール直後)です。
ステップ5 — データディレクトリの所有者とファイルのパーミッションの設定
このステップでは、Redisインストールのセキュリティプロファイルを向上させるために行う所有者とパーミッションの変更について説明します。Redisへのアクセスが必要なユーザーのみがデータに読み取り権限を持つようにすることが重要です。デフォルトでは、そのユーザーはredisユーザーです。
このことを確認するために、親ディレクトリの長いリストにRedisのデータディレクトリをgrepコマンドで検索してください。以下にコマンドとその出力を示します:
- ls -l /var/lib | grep redis
Outputdrwxr-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
変更が必要なもう1つのパーミッションは、Redisの設定ファイルのものです。デフォルトでは、ファイルのパーミッションは640
であり、所有者はrootであり、セカンダリの所有者はrootグループです:
- 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.conf
はredisユーザーの所有で、セカンダリの所有者はredisグループである必要があります。これを設定するには、次のコマンドを実行します:
- sudo chown redis:redis /etc/redis.conf
その後、所有者だけがファイルを読み書きできるようにパーミッションを変更します:
- sudo chmod 600 /etc/redis.conf
前のls
コマンドを再度実行して新しい所有者とパーミッションを確認できます:
- ls -l /var/lib | grep redis
Outputtotal 40
drwxrwx---. 2 redis redis 22 Sep 6 22:22 redis
- ls -l /etc/redis.conf
Outputtotal 40
-rw-------. 1 redis redis 62192 Sep 6 22:20 /etc/redis.conf
最後に、これらの変更を反映するためにRedisを再起動します:
- 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