なぜ Redis は純粋な速度を追求して設計されています。ミリ秒未満のレイテンシを実現するため、歴史的に重いセキュリティレイヤーは排除され、ファイアウォールの背後で安全に動作することが前提とされてきました。しかし、自動化されたポートスキャナーや複雑なクラウド VPC が存在する現代において、その前提は大きなリスクとなります。
私は午前2時、ある苦い経験からこれを学びました。「内部用」だと思っていた開発用インスタンスが検索エンジンにインデックスされ、ボットによってデータが完全に消去されたのです。攻撃者が FLUSHALL を実行するのに1秒もかかりません。インスタンスが公開されている場合、データ紛失のリスクだけでなく、リモートコード実行や、より広範なインフラへの侵入の足がかりとして、高性能なエンジンを攻撃者に明け渡すことになります。
防御戦略の評価
Redis デプロイメントを保護するには、通常 3 つのパスがあります。ほとんどの本番環境では 3 番目の選択肢を目指すべきです。
1. 「ネットワークを信頼する」モデル
これはセキュリティグループと VPC の分離に完全に依存します。Redis はパスワードなしで動作します。シンプルですが、単一障害点となります。ファイアウォールルールの設定ミスや、踏み台サーバー(Jump box)の侵害が一度発生すれば、侵入者にデータへの完全な制御権を与えてしまいます。
2. 基本的なパスワード保護(レガシー)
requirepass ディレクティブを使用して単一のグローバルパスワードを設定します。何もないよりはマシですが、不十分な対策です。読み取り専用の監視ツールと高権限のアプリケーションスクリプトを区別できないため、監査はほぼ不可能です。
3. 最新の多層防御(推奨)
バージョン 6.0 以降、Redis はアクセス制御リスト(ACL)とネイティブ TLS をサポートしています。これにより、最小権限の原則を適用できます。アプリケーションに対して、特定のキーパターンや特定のコマンドのみへのアクセスを許可し、同時に通信中のすべてのデータを暗号化できます。
本番環境におけるセキュリティのトレードオフ
| セキュリティレイヤー | パフォーマンスへの影響 | 主なメリット |
|---|---|---|
| ネットワークバインディング | 0% | 外部のインターネットベースのスキャンの 100% を排除します。 |
| ACL ユーザー | 無視できる程度 (<1%) | 誤った FLUSHALL や CONFIG の変更を防止します。 |
| TLS 暗号化 | CPU オーバーヘッド 15-20% | マルチテナントクラウドにおけるパケットスニッフィングから機密データを保護します。 |
本番環境のブループリント
単一の門番に頼ってはいけません。一つの防御層が破られても、他の層が食い止められるように多層防御を構築しましょう。
- ネットワーク: プライベート IP にバインドし、
iptablesや UFW を使用して特定のアプリケーションノードをホワイトリストに登録します。 - アイデンティティ: デフォルトユーザーを無効化し、各マイクロサービスに固有の認証情報を発行します。
- 暗号化: 特にデータがアベイラビリティゾーンやリージョンをまたぐ場合は、TLS を強制します。
実装:インスタンスを強化する方法
ステップ 1:ネットワーク分離
Redis はデフォルトで 0.0.0.0 をリスニングすることが多いです。これを直ちに内部プライベート IP に変更してください。redis.conf を開き、bind 行を探します。
# ローカルループバックと内部プライベートネットワークのみをリスニングする
bind 127.0.0.1 10.0.5.15
# 保護モードが有効であることを確認する
protected-mode yes
次に、OS レベルでドアをロックします。アプリケーションサーバーが 10.0.5.20 にある場合、そのソースからのトラフィックのみに制限します。
# アプリケーションサーバー以外からのすべての Redis トラフィックをブロックする
sudo ufw allow from 10.0.5.20 to any port 6379
sudo ufw default deny incoming
ステップ 2:きめ細かな ACL
古い requirepass はもう使いません。ACL を使用して制限付きユーザーを作成します。例えば、キャッシュサービスがサーバーをシャットダウンしたり、キースペースを全消去したりできるようにすべきではありません。
Redis CLI で以下のコマンドを実行し、cache: で始まるキーのみを操作できる制限付きユーザーを作成します。
# 強力なパスワードと制限されたスコープを持つユーザーを作成する
ACL SETUSER app_cache on >StrongPassword123! ~cache:* +@all -@dangerous
# 危険な 'default' ユーザーを無効化する
ACL SETUSER default off
-@dangerous フラグは非常に有用です。FLUSHALL、CONFIG、KEYS などのリスクの高いコマンドへのアクセスを一括で削除できます。
ステップ 3:TLS によるトラフィックの暗号化
現代のクラウド環境において、クリアテキスト(平文)は大きなリスクです。TLS を有効にするには、redis.crt、redis.key、ca.crt を用意する必要があります。設定を更新して、標準ポートから暗号化ポートに切り替えます。
# 非セキュアなポートを閉じる
port 0
# TLS ポートを開く
tls-port 6379
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
# 相互 TLS (mTLS) を強制する
tls-auth-clients yes
CLI でデバッグする必要がある場合は、証明書フラグを渡すのを忘れないでください。そうしないと接続が拒否されます。
redis-cli --tls --cacert /etc/redis/tls/ca.crt -h 10.0.5.15 -p 6379
ステップ 4:コマンドのリネーム(最終手段)
まだ ACL を完全に導入できていない場合は、スクリプトから危険なコマンドを隠すことができます。これにより難読化のレイヤーが加わり、ほとんどの自動攻撃を阻止できます。以下を redis.conf に追加します。
rename-command FLUSHALL "MGMT_FLUSH_8831"
rename-command CONFIG "MGMT_CONFIG_2219"
rename-command SHUTDOWN ""
コマンドを空文字列に設定すると、そのコマンドは完全に無効化され、許可されたユーザーであっても呼び出すことができなくなります。
メンテナンスと監視
セキュリティは一度設定して終わりではなく、継続的なプロセスです。AUTH エラーがないかログを監視してください。ログイン失敗の急増は、通常、スキャナーが外周の防御を突破したことを意味します。
最後に、バージョンを常に最新の状態に保ってください。2022 年の Lua サンドボックス脱出(CVE-2022-0543)のような脆弱性は、どれほど完璧な設定であっても、古いソフトウェアでは身を守れないことを証明しています。パッチ適用を自動化し、常に警戒を怠らないようにしましょう。

