Ubuntu 18.04 サーバー: Nginx、PHP、および MariaDB のインストールと設定

Ubuntu 18.04 で Nginx、PHP-FPM、および MariaDB を一緒に使用するには、それぞれのパッケージをインストールし、Nginx の PHP リクエストを PHP-FPM ソケットに渡し、その後、別々のアカウントでデータベースを設定する必要があります。以下の例はローカルのみの練習で、既存のサイトは変更せず、ウェブアプリケーションにはデータベースの root アカウントを使用しません。

練習の範囲と準備

Ubuntu 18.04 の一般的なセキュリティサポートは終了しました。Ubuntu Pro の Extended Security Maintenance (ESM) が適用されているか、および各パッケージのサポート範囲を Ubuntu セキュリティメンテナンススケジュール で確認してください。また、サポートされているバージョンで新しいオペレーティング環境を構築することを推奨します。本記事では、既存の 18.04 サーバを理解するための例として、デフォルトリポジトリの PHP 7.2 を使用します。

管理者権限とリポジトリアクセスを持つ別のテストサーバを準備します。Nginx はウェブリクエストを処理し、PHP-FPM(FastCGI プロセスマネージャ)が PHP コードを実行し、MariaDB がデータを保存します。例は 127.0.0.1:8080 内でのみ受け取ることができるため、サーバの外部から直接アクセスすることはできません。公共のインターネットアクセスを行う場合は、別途ファイアウォール、ドメイン、TLS 証明書、およびセキュリティレビューが必要です。

既存のサービスやデータがあるサーバーでは、変更を行う前にバックアップおよびリカバリ手順を準備してください。以下の実習パス、アカウント、データベース名、またはポート8080が既に使用されている場合は、そのまま進めず、別のテスト環境を使用してください。ポートの使用状況は以下のコマンドで確認できます。出力がない場合、そのポートにはTCPリスナーが存在しません。

sudo ss -lntp | grep ':8080 '

パッケージのインストールとサービスの確認

パッケージのインストールにより、Nginxのデフォルトサイトが自動的に起動して80番ポートで待ち受ける場合があります。実習サイトをローカルの8080番に制限しても、デフォルトサイトのアクセスは制限されません。インストール前にネットワークとファイアウォールでテストサーバーを隔離し、既存サービスへの影響を確認してください。

パッケージリストを更新した後、Nginx、PHP 7.2 FPM(MySQLドライバー付き)、MariaDBサーバー、および確認用のcurlをインストールします。リポジトリやサポートの問題でパッケージが使用できない場合は、進行する前にエラーを解消してください。

sudo apt update
sudo apt install nginx php7.2-fpm php7.2-mysql mariadb-server curl

インストール後、以下のコマンドを使用してサービスの状態および PHP-FPM ソケットを確認してください。サービスが起動していない場合は、原因を特定してサービスを起動してください。ソケットのパスが異なる場合は、実際のパスに合わせて以下の Nginx 設定を調整してください。

systemctl is-active nginx php7.2-fpm mariadb
ls -l /run/php/

3 つのサービスそれぞれが active であるか確認してください。php7.2-fpm.sock が存在しない場合は、systemctl status php7.2-fpm およびサービスログで原因を確認してください。PHP のバージョンが異なる場合は、パッケージとソケットパスの両方を変更する必要があります。

Nginx と PHP-FPM の接続

新しい練習用ディレクトリと設定ファイルを作成します。/var/www/lnmp-demo、/etc/nginx/sites-available/lnmp-demo、または /etc/nginx/sites-enabled/lnmp-demo がすでに存在する場合は上書きしないでください。クリーンなサーバー上で既存のパスがないことを確認した後、以下の編集コマンドを実行してください。

sudo mkdir /var/www/lnmp-demo
sudo nano /etc/nginx/sites-available/lnmp-demo

以下の完全なサーバーブロックをエディターに保存します。fastcgi_pass は先に確認した PHP-FPM ソケットと一致している必要があります。snippets/fastcgi-php.conf は Ubuntu Nginx パッケージからの設定スニペットです。ファイルが存在しない場合は、ディストリビューションの FastCGI 設定を確認してください。

server {
    listen 127.0.0.1:8080;
    server_name localhost;
    root /var/www/lnmp-demo;
    index index.php;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    }
}

構成ファイルを有効化して確認します。nginx -tが成功した場合にのみリロードします。失敗した場合は、エラー、ポート、ソケットパスを確認して修正し、再度確認します。問題が発生した場合は、この実習で作成したシンボリックリンクのみを削除し、既存のサイト構成を維持するために再確認およびリロードします。

sudo ln -s /etc/nginx/sites-available/lnmp-demo /etc/nginx/sites-enabled/lnmp-demo
sudo nginx -t
sudo systemctl reload nginx

NginxのFastCGI接続は、Nginx公式ガイドでも確認できます。

PHPの実行を確認

以下のパスにファイルが存在しないことを確認し、新しいファイルを作成します。以下のコードをエディタに保存してください。

sudo nano /var/www/lnmp-demo/index.php
<?php
header('Content-Type: text/plain; charset=UTF-8');
echo "PHP is working\n";
echo 'SAPI: ' . PHP_SAPI . "\n";

同じサーバーで次のコマンドを実行してください。PHP is working と SAPI: fpm-fcgi が表示された場合、Nginx は PHP-FPM を通じてコードを実行しています。PHP コードがそのまま表示される場合は、設定が適用されていないため、テストファイルを公開せずに FastCGI 設定を再確認してください。

curl http://127.0.0.1:8080/

502 エラーが発生する場合は、PHP-FPM サービス、ソケットパス、権限を確認してください。404 エラーが発生する場合は、ドキュメントディレクトリとファイルパスを確認してください。詳細なサーバー設定を公開する phpinfo() ページは公開しないでください。

MariaDB データベースと別アカウント

MariaDBの管理者認証は、インストール方法に依存します。ローカルソケット認証が設定されている場合、次のコマンドで管理コンソールを開くことができます。失敗した場合は、既存の管理者認証方法を確認してください。MYSQL_HISTFILE=/dev/nullは、このクライアントセッションでコマンド履歴ファイルを残さないことを指定します。

sudo env MYSQL_HISTFILE=/dev/null mysql

以下は、新しい練習用データベースとローカル専用アカウントを作成するSQLです。同じ名前が既に存在する場合は、既存のエントリを変更せず、別の名前を使用してください。実行する前に、CHANGE_ME_STRONG_PASSWORDを長く、ユニークなパスワードに置き換え、SQL文字列内の引用符やバックスラッシュが正しくエスケープされていることを確認してください。

CREATE DATABASE lnmp_demo CHARACTER SET utf8mb4;
CREATE USER 'lnmp_demo'@'localhost' IDENTIFIED BY 'CHANGE_ME_STRONG_PASSWORD';
GRANT SELECT ON lnmp_demo.* TO 'lnmp_demo'@'localhost';
EXIT;

このサンプルアカウントはデータベースに対して読み取り専用の権限を持っています。実際のアプリケーションで書き込みやスキーマ変更権限が必要な場合は、必要な権限のみを別途付与してください。管理者アカウントの認証プラグインを直接変更したり、ウェブアプリケーションにroot権限を与えたりしないでください。アカウントと認証の詳細については、MariaDB CREATE USER ドキュメントを参照してください。

新しいアカウントがローカルで接続できることを確認してください。パスワードをコマンドラインに直接書き込まず、プロンプトで入力してください。接続後、SELECT DATABASE(), CURRENT_USER(); を実行するとデータベースと認証されたアカウントが表示されます。 EXIT; を使用してコンソールを終了してください。

mysql -u lnmp_demo -p lnmp_demo

PHPでデータベース接続を確認する

以下は、上で作成したアカウントを使用した一時的な検証方法です。認証情報はウェブドキュメントディレクトリの外に保管してください。/etc/lnmp-demo が既に存在する場合は、上書きせず、別のテスト環境を使用してください。これは PHP-FPM が www-data グループで実行されるデフォルト設定を前提としています。

sudo install -d -m 750 -o root -g www-data /etc/lnmp-demo
sudo install -m 640 -o root -g www-data /dev/null /etc/lnmp-demo/db.php
sudo nano /etc/lnmp-demo/db.php

以下の内容をファイルに挿入し、データベースアカウントに設定した値にパスワードを置き換えてください。PHP の文字列内に引用符やバックスラッシュがある場合は、正しくエスケープしてください。同じ www-data 権限で動作する他のアプリケーションもファイルを読むことができるため、共有サーバーでは別の隔離が必要です。

<?php
return array(
    'user' => 'lnmp_demo',
    'password' => 'CHANGE_ME_STRONG_PASSWORD',
);

/var/www/lnmp-demo/db-check.php が存在しないことを確認し、以下のコードを保存してください。ウェブ上の応答でエラーメッセージやパスワードを公開しないよう、成功か失敗かのみを示してください。

sudo nano /var/www/lnmp-demo/db-check.php
<?php
header('Content-Type: text/plain; charset=UTF-8');
ini_set('display_errors', '0');
$config = require '/etc/lnmp-demo/db.php';
try {
    $db = new PDO('mysql:host=localhost;dbname=lnmp_demo;charset=utf8mb4',
        $config['user'], $config['password'],
        array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
    echo "Database connection OK\n";
} catch (PDOException $e) {
    http_response_code(500);
    echo "Database connection failed\n";
}
curl -i http://127.0.0.1:8080/db-check.php

HTTP 200 が返され、Database connection OK が表示された場合、PHP から MariaDB への接続は成功しています。失敗した場合は、PHP の MySQL 拡張、サービスの状態、ソケット認証、およびアカウント/パスワードを確認してください。確認後、臨時の PHP ファイルや資格情報ファイルを安全に削除し、不要になった練習用アカウントおよびデータベースを、実際の対象とバックアップの両方でチェックしてクリーンアップしてください。

本番環境に適用する前に

この実習環境は、ローカル接続の確認用に設定されています。実際のサービスを公開する前に、サポートされているOSおよびPHPのバージョンに移行し、環境に応じてNginxのサーバー名とドキュメントルート、HTTPS証明書、ファイアウォール、およびクラウドネットワークのルールを構成してください。また、PHPファイルのアップロード/実行範囲、FPMユーザーの分離、MariaDBのネットワークアクセス、バックアップ、および復旧についても確認する必要があります。

MariaDBのセキュリティ設定ツールは、インストールされているバージョンに応じてmysql_secure_installationまたはmariadb-secure-installationとして提供されます。既存のサービスに影響を与える可能性があるため、各質問を読み、環境に応じて選択してください。詳細な項目はMariaDBセキュリティ設定ツールの説明に記載されています。