序章

Redisは、オープンソースのKey-Valueキャッシュおよびストレージシステムであり、ハッシュ、リスト、セット、ビットマップなどのいくつかのデータ型を高度にサポートしているため、データ構造サーバーとも呼ばれます。 また、クラスタリングをサポートしているため、可用性が高くスケーラブルな環境で役立ちます。

このチュートリアルでは、Ubuntu16.04で実行されているPHPアプリケーションのセッションハンドラーとして使用される外部Redisサーバーをインストールして構成する方法を説明します。

セッションハンドラーは、セッションに保存されたデータの保存と取得を担当します。 デフォルトでは、PHPはこれにfilesを使用します。 これは単一のサーバーでは十分に機能しますが、セッション情報が単一のサーバーに関連付けられているため、パフォーマンスとスケーラビリティに大きな制限があります。

外部セッションハンドラーは、複数のアプリケーションサーバーで使用できる共有セッションデータの中央の場所を提供します。 これは、ロードバランサーの背後にスケーラブルPHP環境を作成する場合に重要です。これは、どのアプリケーションサーバーが個々のリクエストを処理するかに関係なく、同じセッションデータが利用できるためです。

前提条件

このチュートリアルでは、2台のサーバーを使用してセッション処理を構成します。 フォローするには、次のものが必要です。

  • Ubuntu16.04でLAMPまたはLEMPを実行しているPHPWebサーバー。 このサーバーをwebと呼びます。
  • 2番目のクリーンなUbuntu16.04サーバー。Redisがインストールされます。 このサーバーをredisと呼びます。

root以外のユーザーが必要です sudo これらの各サーバーで構成された特権。 また、各サーバーで基本的なファイアウォールが実行されていると想定します。 両方のサーバーでUbuntu16.04初期サーバーセットアップガイドに従って、これらの要件の両方をセットアップできます。

ステップ1:Redisサーバーとクライアントソフトウェアをインストールする

最初のステップは、両方のマシンに必要なソフトウェアをインストールすることです。 redisマシンにはRedisサーバーが必要です。 web マシンに、セッション処理用のRedis PHP拡張機能と、テスト用のRedisコマンドラインクライアントをインストールします。

Redisサーバーのインストール

最初に行う必要があるのは、redisマシンでRedisサーバーを実行することです。

ChrisLeaが提供する信頼できるPPAリポジトリを備えた通常のUbuntuパッケージマネージャーを使用します。 これは、Redisの最新の安定バージョンを確実に入手するために必要です。

注:一般的なセキュリティアドバイスとして、信頼できるソースからのPPAのみを使用する必要があります。

まず、以下を実行してPPAリポジトリを追加します。

  1. sudo apt-add-repository ppa:chris-lea/redis-server

プレス ENTER 確認するために。

次に、パッケージインデックスを更新し、次のように入力してRedisサーバーをインストールします。

  1. sudo apt-get update
  2. sudo apt-get install redis-server

これで、Redisがサーバーにインストールされて実行されているはずです。 次のように入力して、サービスが実行され、接続を受け入れていることをテストします。

  1. redis-cli ping
Redis server output
PONG

これにより、ポート6379localhostで実行されているRedisインスタンスに接続されます。 応答としてPONGを取得する必要があります。

RedisクライアントとPHP拡張機能のインストール

次に、RedisコマンドラインクライアントとRedisPHP拡張機能をwebサーバーにインストールします。 コマンドラインクライアントを使用して、接続と認証を簡単にテストします。 PHP拡張機能を使用して、セッションデータを保存します。

ローカルパッケージインデックスを更新し、次のように入力してwebサーバーにソフトウェアをインストールします。

  1. sudo apt-get update
  2. sudo apt-get install redis-tools php-redis

これで、にアクセスできるはずです。 redis-cli ツール。ただし、テストするサーバーへのアクセスはまだありません。

ステップ2:外部接続を受け入れるようにRedisを構成する

デフォルトでは、Redisはからの接続のみを許可します localhost、これは基本的に、Redisがインストールされているサーバーの内部からのみアクセスできることを意味します。 他のサーバーからの接続を許可するには、この構成を変更する必要があります。

Redisはネイティブ暗号化オプションを提供せず、信頼できるピアの分離されたネットワークにデプロイされていることを前提としています。 つまり、外部接続を安全に許可するには、両方のサーバーが分離されたネットワーク上にあるか、別の方法でサーバー間のトラフィックを保護する必要があります。

Redisが分離されたネットワークにデプロイされている場合…

サーバーが分離されたネットワークで動作している場合は、おそらく、分離されたネットワークのIPアドレスにバインドするようにRedisの構成ファイルを調整するだけで済みます。

redis サーバーで、Redis構成ファイルをバックアップして開きます。

  1. sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
  2. sudo nano /etc/redis/redis.conf

を見つける bind Redisサーバーの分離されたネットワークIPアドレスを追加します。

/etc/redis/redis.conf
bind 127.0.0.1 isolated_IP_address

ファイルを保存して閉じます。 次のように入力して、サービスを再起動します。

  1. sudo systemctl restart redis-server.service

Redisポートへのアクセスを開きます。

  1. sudo ufw allow 6379

これで、Redisは分離されたネットワークからの接続を受け入れることができます。

Redisが分離されたネットワークにデプロイされていない場合…

分離されていない、または制御していないネットワークの場合、トラフィックを他の手段で保護することが不可欠です。 Redisサーバーへのトラフィックを保護するには、次のような多くのオプションがあります。

  • stunnel を使用したトンネル: redis サーバーに着信トンネルを設定し、webサーバーに発信トンネルを設定する必要があります。 Webサーバーはローカルポートに接続して、リモートのRedisサービスと通信します。
  • spiped を使用したトンネリング:webサーバーは spiped クライアントマシン。 各サーバーにsystemdユニットファイルを作成する必要があります。 Webサーバーはローカルポートに接続して、リモートのRedisサービスと通信します。
  • PeerVPNを使用したVPNのセットアップ:VPN上で両方のサーバーにアクセスできる必要があります。 web サーバーは、VPNIPアドレスを使用してredisサーバーにアクセスできるようになります。

上記のいずれかの方法を使用して、webサーバーからredisサーバーへの安全なアクセスを構成します。 webマシンがリモートマシンのRedisサービスに接続するために使用するIPアドレスとポートを知っている必要があります。

この時点で、WebサーバーからRedisサーバーに安全にアクセスできるはずです。

ステップ3:Redisサーバーのパスワードを設定する

Redisインストールにセキュリティの層を追加するには、サーバーデータにアクセスするためのパスワードを設定することをお勧めします。 Redis構成ファイルを次の場所で編集します /etc/redis/redis.conf:

  1. sudo nano /etc/redis/redis.conf

を見つける requirepass ディレクティブを設定し、強力なパスフレーズに設定します。 Redisトラフィックは外部から保護されている必要がありますが、これによりRedis自体に認証が提供されます。 Redisは高速で、パスワードの試行をレート制限しないため、ブルートフォース攻撃から保護するために強力で複雑なパスフレーズを選択してください。

/etc/redis/redis.conf
requirepass yourverycomplexpasswordhere

終了したら、ファイルを保存して閉じます。

Redisサービスを再起動して、変更を実装します。

  1. sudo systemctl restart redis-server.service

これで、Redisサーバーは認証されていないリクエストを拒否するはずです。

ステップ4:Redisの接続と認証をテストする

変更が期待どおりに機能するかどうかをテストするには、webマシンからRedisサービスに接続します。

デフォルトでは、Redisサーバーはローカルインターフェイスで6379をリッスンしますが、上記で説明した各ネットワークセキュリティオプションは、外部の関係者に対して何らかの方法でデフォルトを変更します。 使用できます redis-cli クライアントと -h IPアドレスと -p リモートサービスへの接続に必要なポートを指定するオプション。 デフォルトのオプション(それぞれ127.0.0.1と6379)を使用している場合は、これらのいずれかを省略できます。

使用する値は、ネットワークトラフィックを保護するために使用した方法によって異なります。

  • 分離ネットワーク:Redisサーバーの分離ネットワークIPアドレスを使用します。 デフォルトのRedisポート(6379)が使用されているため、言及する必要はありません。 redis-cli -h redis_isolated_IP
  • stunnelまたはspiped:リモートRedisサービスにトンネリングするローカルポートを使用します。 redis-cli -p 8000
  • PeerVPN :RedisサーバーのVPNIPアドレスを使用します。 redis-cli -h 10.8.0.1

一般的な形式は次のとおりです。

  1. redis-cli -h ip_to_contact_redis -p port_to_contact_redis

webサーバーからリモートRedisインスタンスに接続できるはずです。

パスワードを定義してデータにアクセスしようとすると、AUTHエラーが発生するはずです。

  1. keys *
Web server output
(error) NOAUTH Authentication required.

認証するには、を実行する必要があります AUTH コマンド、で定義したのと同じパスワードを提供します /etc/redis/redis.conf ファイル:

  1. AUTH yourverycomplexpasswordhere

クレデンシャルが受け入れられたことを示す応答としてOKが表示されます。

Web server output
OK

次に、Redis内で設定されているキーを一覧表示します。

  1. keys *

これが新しいRedisサーバーの場合、出力は次のようになります。

Web server output
(empty list or set)

この出力は、Redisサーバーが空であることを意味します。これはまさに私たちが期待していることです。 web サーバーは、このRedisサーバーをセッションハンドラーとして使用するようにまだ構成されていません。

次のように入力して、コマンドシェルに戻ります。

  1. exit

認証で正常に接続できることを確認したので、Redisをデフォルトのセッションハンドラーにすることができます。

手順5:RedisをWebサーバーのデフォルトのセッションハンドラーとして設定する

次に、を編集する必要があります php.ini web サーバー上のファイルを使用して、PHPのデフォルトのセッションハンドラーを変更します。 このファイルの場所は、現在のスタックによって異なります。

デフォルトのリポジトリからインストールされたUbuntu16.04のLAMPスタックの場合、これは通常です /etc/php/7.0/apache2/php.ini. Ubuntu16.04のLEMPスタックの場合、パスは通常 /etc/php/7.0/fpm/php.ini. これらの場所のいずれかが正しいことを確認した場合は、次のセクションをスキップしてください。

(オプション)正しいphp.iniファイルを見つける

メインの場所がわからない場合 php.ini ファイル、あなたはを使用して見つけることができます phpinfo() 関数。 webサーバーで次のファイルを開きます info.php ドキュメントルート内。デフォルトでは次のようになります。 /var/www/html LAMPとLEMPの両方の場合:

  1. sudo nano /var/www/html/info.php

次のコードをファイルに配置します。

/var/www/html/info.php
<?php
phpinfo();

ブラウザでwebサーバーのドメイン名またはIPアドレスにアクセスし、続いて /info.php:

http://web_server_domain_or_IP/info.php

「ロードされた構成ファイル」を含む行を探すと、メインの正確な場所が見つかります。 php.ini ロードされました。

終了したら、環境に関する機密情報が表示されるため、ファイルを削除します。

  1. sudo rm /var/www/html/info.php

ファイルの場所がわかったので、編集に進むことができます。

構成の変更

を開きます php.ini 編集用のファイル。

デフォルト構成でLAMPスタックを使用している場合、必要なコマンドは次のとおりです。

  1. sudo nano /etc/php/7.0/apache2/php.ini

デフォルト構成でLEMPスタックを使用している場合、必要なコマンドは次のとおりです。

  1. sudo nano /etc/php/7.0/fpm/php.ini

を使用して別のパスを発見した場合 phpinfo() 上で概説した方法では、代わりにそのパスをここに置き換えてください。

の内部 php.ini ファイル、を含む行を検索します session.save_handler. デフォルト値は files. これをに変更します redis RedisPHP拡張機能を使用します。

[label php.ini] 
session.save_handler = redis

次に、を含む行を見つけます session.save_path. コメントを外して値を変更し、Redis接続文字列が含まれるようにする必要があります。

接続文字列は、次の形式を使用して、すべて1行で作成できます。

tcp://IP_address:port?auth=redis_password

繰り返しますが、適切な値は、選択した安全なネットワーク戦略によって異なります。 に提供したのと同じ値を使用します redis-cli 以前のコマンド。 たとえば、使用していた場合 stunnel また spipedsession.save_path おそらく次のようになります。

[label php.ini] 
session.save_path = "tcp://127.0.0.1:8000?auth=yourverycomplexpasswordhere"

終了したら、ファイルを保存して閉じます。 次に、PHPサービスを再起動して、変更を実装します。

LAMP 環境では、次のように入力します。

  1. sudo systemctl restart apache2

LEMP 環境では、次のように入力します。

  1. sudo systemctl restart php7.0-fpm

これで、セッションハンドラーとしてRedisを使用するようにPHPを構成する必要があります。

ステップ6:Redisセッション処理をテストする

セッションがRedisによって処理されるようにするには、セッションに情報を格納するPHPスクリプトまたはアプリケーションが必要になります。 カウンターを実装する簡単なスクリプトを使用します。 ページをリロードするたびに、印刷された数字が増加します。

名前の付いたファイルを作成します test.php ドキュメントルートフォルダ内のwebサーバー:

  1. sudo nano /var/www/html/test.php

内部に、次のコードを貼り付けます。

[label /var/www/html/test.php] 
<?php
//simple counter to test sessions. should increment on each page reload.
session_start();
$count = isset($_SESSION['count']) ? $_SESSION['count'] : 1;

echo $count;

$_SESSION['count'] = ++$count;

ファイルを保存して閉じます。

ブラウザでwebサーバーのパブリックIPアドレスを指定し、その後に /test.php スクリプトにアクセスするには:

http://web_server_public_IP/test.php

ページをリロードするたびに表示される数が増えるはずです。

次に、 redis マシンで、 redis-cli セッションを開きます。 ローカルインスタンスに接続しているため、IPアドレスやポートを指定する必要はありません。

  1. redis-cli

Redisパスワードを使用して認証します。

  1. AUTH yourverycomplexpasswordhere
Redis server output
OK

次に、既存のキーを確認します。

  1. keys *

PHPセッションの新しいエントリが表示されます。

Redis server output
1) "PHPREDIS_SESSION:2ofnvhhr6gdvp88u0c4e7kb800"

キーの値を尋ねると、現在のカウンター値を確認できるはずです。

  1. get PHPREDIS_SESSION:2ofnvhhr6gdvp88u0c4e7kb800
Redis server output
"count|i:6;"

これは、セッション情報がRedisサーバーに保存されていることを示しています。 追加のWebサーバーをRedisサーバーに接続して、セッションを一元管理できます。

結論

Redisは、PHPのセッションハンドラーとしても使用できる強力で高速なKey-Valueストレージサービスであり、セッションストレージ用の分散システムを提供することでスケーラブルなPHP環境を実現します。 PHPアプリケーションのスケーリングの詳細については、次の記事を確認してください:PHPアプリケーションの水平方向のスケーリング