Обработка сессий PHP при помощи сервера Redis в Ubuntu 16.04

Redis – это открытое нереляционное хранилище данных и кэша типа «ключ-значение». Также Redis является сервером преобразования структур данных, предназначенным для расширенной поддержки нескольких типов данных (хэша, списков, множеств, битовых массивов и т.п.). Кроме того, Redis поддерживает кластеризацию, потому его часто используют в высокопроизводительных и масштабируемых средах.

Данное руководство поможет установить и настроить сервер Redis для обработки PHP-сессий приложения в системе Ubuntu 16.04.

Обработчик сессий отвечает за хранение и извлечение данных, сохраненных в сессиях; по умолчанию PHP использует для этого файлы. Вместе с балансировщиком нагрузки обработчик сессий может быть использован для создания масштабируемой среды PHP, в которой все ноды приложения смогут подключаться к ведущему серверу для обмена данными.

Требования

Для выполнения данного руководства использовались два сервера.

Итак, для работы понадобится:

  • Сервер 1(в руководстве он будет называться web): предварительно установленный веб-сервер; можно использовать стек LAMP или LEMP.
  • Сервер 2 (в руководстве он будет называться redis): свежий сервер Ubuntu 16.04, на котором будет установлен Redis.
  • Доступ SSH.
  • Пользователь с доступом к sudo на каждом сервере (инструкции по настройке такого пользователя – здесь).
  • Базовый брандмауэр.

1: Установка сервера и клиента Redis

Сначала нужно установить Redis на оба сервера: на сервер redis установите пакет Redis server, а на сервер web – PHP-расширение Redis для обработки сессий и клиент командной строки.

Установка Redis Server

Подключитесь к машине redis и установите необходимый пакет. Для этого подойдёт репозиторий PPA. Используйте наиболее актуальную версию Redis.

Примечание: Используйте PPA только из надёжных и безопасных источников.

Добавьте PPA:

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

Чтобы подтвердить, нажмите Enter.

Обновите индекс пакетов и установите сервер Redis:

sudo apt-get update
sudo apt-get install redis-server

Чтобы убедиться, что установка прошла успешно, введите команду:

redis-cli ping

Команда создаст подключение к Redis с локального хоста на порт 6379. Если установка прошла успешно, команда вернёт:

PONG

Установка клиента и PHP-расширения Redis

Перейдите на сервер web. Здесь нужно установить клиент командной строки (для проверки подключения) и PHP-расширения Redis (для хранения данных).

Обновите индекс пакетов и установите программы:

sudo apt-get update
sudo apt-get install redis-tools php-redis

Теперь у вас есть доступ к инструменту redis-cli, но пока что сервер не принимает внешних соединений.

2: Настройка Redis для поддержки внешних соединений

По умолчанию Redis поддерживает подключения только с локального хоста. Это значит, что Redis доступен только с того сервера, на котором он установлен. Эту настройку нужно изменить.

По умолчанию Redis не предоставляет шифрования, поскольку предполагает развёртывание в изолированной сети заведомо безопасных серверов. Следовательно, чтобы все внешние соединения были безопасными, оба сервера должны находиться в изолированной сети, либо же вы должны защитить трафик между серверами при помощи специальных инструментов шифрования.

Изолированная сеть

Если серверы находятся в изолированной сети, достаточно просто отредактировать конфигурационный файл Redis и добавить IP-адрес сети.

Перейдите на сервер redis, создайте резервную копию конфигурационного файла Redis и откройте его:

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

Найдите строку bind и вставьте IP-адрес сети, в которой находится сервер Redis.

bind 127.0.0.1 isolated_IP_address

Сохраните и закройте файл. Перезапустите сервис:

sudo systemctl restart redis-server.service

Откройте доступ к порту в брандмауэре.

sudo ufw allow 6379

Теперь сервер Redis может принимать внешние соединения в изолированной сети.

Инструменты шифрования

Если сервер развёрнут вне изолированной среды, обязательно нужно защитить трафик между серверами. Существует несколько способов сделать это:

  • Инструмент stunnel – инструмент для туннелирования. Позволяет настроить входящий туннель на сервере redis и исходящий туннель на сервере web. Сервер web будет подключаться к локальному порту для связи с удаленным сервисом Redis.
  • Инструмент spiped: сервер web будет использоваться в качестве клиента spiped.на каждом сервере нужно создать юнит-файл system. Сервер web будет подключаться к локальному порту для связи с удаленным сервисом Redis.
  • PeerVPN: оба сервера будут помещены в VPN. Сервер web будет подключаться к серверу redis с помощью IP-адреса VPN.

Выберите один из предложенных методов и зашифруйте трафик между серверами.

3: Пароль для сервера Redis

Чтобы повысить уровень безопасности сервера Redis, нужно защитить его данные паролем. Отредактируйте конфигурационный файл /etc/redis/redis.conf.

sudo nano /etc/redis/redis.conf

Раскомментируйте строку requirepass и установите надёжный пароль. Этот пароль необходим для аутентификации Redis. Выберите сложный фразовый пароль, чтобы предотвратить brute force атаки.

requirepass yourverycomplexpasswordhere

Сохраните и закройте файл. Перезапустите сервис Redis:

sudo systemctl restart redis-server.service

4: Тестирование подключения и авторизации Redis

Чтобы убедиться в том, что все настройки работают должным образом, подключитесь к Redis с сервера web.

По умолчанию сервис Redis прослушивает порт 6379 на локальном интерфейсе. Однако данные могут отличаться в зависимости от настроек безопасности трафика Redis (раздел 2). С помощью клиента redis-cli и флага –h можно указать IP-адрес, с помощью флага –p – задать порт удалённого сервиса, к которому нужно подключиться.

Примечание: Если вы используете нестандартные параметры, замените 127.0.0.1 и порт 6379 соответствующими данными.

Итак, если серверы работают в изолированной среде, вам нужно использовать IP-адрес этой сети и стандартный порт 6379 (его можно не указывать).

redis-cli -h redis_isolated_IP

Если вы используете stunnel или spiped, укажите номер локального порта, который подключен к удаленному сервису Redis:

redis-cli -p 8000

Если вы используете PeerVPN, укажите IP-адрес VPN:

redis-cli -h 10.8.0.1

Общий синтаксис команды выглядит так:

redis-cli -h ip_to_contact_redis -p port_to_contact_redis

Теперь вы можете подключиться к удалённому сервису Redis с сервера web.

Если вы определили пароль, вы не получите доступа к данным, а на экране появится ошибка AUTH:

keys *
(error) NOAUTH Authentication required.

Чтобы пройти аутентификацию, нужно запустить команду AUTH и указать пароль, указанный в файле /etc/redis/redis.conf.

AUTH yourverycomplexpasswordhere

Если всё сработало, на экране появится вывод:

OK

Теперь снова запустите:

keys *

На экране появится примерно такой вывод:

(empty list or set)

Это значит, что на сервере Redis пока что нет никаких данных; это нормальное поведение сервера, поскольку сервер web пока что не может использовать его в качестве обработчика сессий.

Вернитесь в командную строку:

exit

5: Настройка обработки сессий

Оставайтесь на сервере web. Откройте файл php.ini, в котором можно определить стандартный обработчик сессий PHP. Место хранения файла зависит от используемого программного стека.

В стеке LAMP в Ubuntu 16.04 этот файл обычно находится в /etc/php/7.0/apache2/php.ini. В стеке LEMP в системе Ubuntu 16.04 файл, как правило, хранится в /etc/php/7.0/fpm/php.ini.

Поиск файла php.ini (опционально)

Примечание: Если вы уже нашли файл php.ini, пропустите этот раздел.

Если вы не знаете точного пути файла php.ini, его можно быстро узнать при помощи функции phpinfo(). Просто откройте в каталоге /var/www/html файл info.php:

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

и поместите в него следующий код:

<?php
phpinfo();

Затем откройте скрипт в браузере и найдите строку Loaded Configuration File. В ней указано местонахождение нужного файла.

http://web_server_domain_or_IP/info.php

Примечание: После этого рекомендуется удалить файл info.php, поскольку он открывает доступ к конфиденциальным данным о сервере.

Изменение настроек

Откройте файл php.ini.

Стек LAMP:
sudo nano /etc/php/7.0/apache2/php.ini
Стек LEMP:
sudo nano /etc/php/7.0/fpm/php.ini

Примечание: Если путь к файлу php.ini отличается, укажите правильный путь.

В файле php.ini найдите строку session.save_handler. По умолчанию она имеет значение files. Замените значение на redis, чтобы использовать PHP-расширение Redis вместо файлов.

session.save_handler = redis

Теперь вы должны найти строку session.save_path. Раскомментируйте ее и измените значение, указав строку подключения Redis в таком формате:

tcp://IP_address:port?auth=redis_password

Опять же, правильные значения зависят от выбранного вами метода защиты данных. используйте те же данные, что и в разделе 4. Например, если вы используете stunnel или spiped, строка session.save_path будет иметь такой вид:

session.save_path = "tcp://127.0.0.1:8000?auth=yourverycomplexpasswordhere"

Сохраните и закройте файл.

Затем перезапустите сервер PHP.

В LAMP:
sudo systemctl restart apache2
В LEMP:
sudo systemctl restart php7.0-fpm

6: Тестирование обработки сессий

Чтобы убедиться в том, что Redis успешно обрабатывает сессии PHP, создайте PHP-скрипт или приложение, хранящее информацию в сессиях. В данном руководстве используется простой скрипт-счётчик: он увеличивает номер при каждой перезагрузке страницы.

На сервере web создайте файл test.php и поместите его в каталог document root.

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

Примечание: Если ваш каталог document root находится в другом месте, откорректируйте эту команду.

Добавьте в файл такой код:

<?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;

Сохраните и закройте файл.

Чтобы получить доступ к скрипту в браузере, откройте ссылку:

http://web_server_public_IP/test.php

Номер на странице должен увеличиваться после каждого обновления страницы.

Это значит, что теперь данные сессий хранятся в Redis. Чтобы убедиться в этом, откройте новую сессию с помощью redis-cli на сервере redis. При подключении к локальному интерфейсу IP указывать не нужно:

redis-cli

Укажите пароль Redis:

AUTH yourverycomplexpasswordhere
OK

Извлеките данные при помощи команды keys *:

keys *

Вы увидите новую запись PHP-сессии:

1) "PHPREDIS_SESSION:2ofnvhhr6gdvp88u0c4e7kb800"

Если вы запросите значение ключа, вы увидите текущее значение счётчика:

get PHPREDIS_SESSION:2ofnvhhr6gdvp88u0c4e7kb800
"count|i:6;"

Это значит, что информация сессии хранится на сервере Redis. Аналогичным образом к серверу Redis можно подключить дополнительные веб-серверы.

Tags: , ,

Добавить комментарий