Linux PHP セキュリティ 技術解説

Laravel 10の実行環境(本番サーバ用)を構築した話。PHPのバージョンアップ、SSL化もしたよ。

コトの発端

Laravelで開発したアプリを世にリリースしたいよね。本番環境としてのNginx + PHPの環境を構築してみた。

概要

Laravel 10の本家サイトの「Laravel 10.x デプロイ」を参考に、SSL化をしつつインフラを構築した。淡々と実践した方法を備忘録として書き記す。

https://readouble.com/laravel/10.x/ja/deployment.html

Laravel 10はPHP8.1以上を要求するので、PHP本体のバージョンアップも実施することとした。

環境あたりをまとめると、Ubuntu 22.04.4 LTS + Nginx + PHP8.1(7.4からのバージョンアップ)といったところ。

PHPのアップデート(PHP7.4→PHP8.1)

Laravel 10の最低要件を満たすため、下記サイトを参考にサーバのPHPのバージョンをアップグレードすることにした。

Ubuntu 20.04 にPHP8.xをインストールして、バージョンを切り替える。

必要なモジュールと必要なバージョンを決め、下記のコマンドにてインストールした。

sudo apt install php8.1
sudo apt install php8.1-fpm php8.1-common php8.1-mysql php8.1-gmp php8.1-curl php8.1-intl php8.1-mbstring php8.1-xmlrpc php8.1-gd php8.1-xml php8.1-cli php8.1-zip

# 実行されているバージョンの確認
php -v

# 希望したバージョンになっていなければ、下記コマンドを実行して切り替える。(あっきーの場合はすでに8.1に切り替わっていました。)
sudo update-alternatives --config php

PHPなどのアップグレードは、既存システムの不具合の元になったりするのでよく考えてから実施してね。

DNSへのサブドメイン登録

SSL化したいドメインをDNSに登録しておく。レコードが伝播するまでに時間がかかるので一番最初に済ましておくことをおすすめ。

Let's Encryptの証明書を取得

サブドメインをDNSに登録できたら証明書を取得する。証明書の取得に80ポートを使うらしく、稼働中のNginxを停止させてから取得を行なった。

sudo systemctl stop nginx
sudo letsencrypt certonly --standalone -d laravel.unluckysystems.com
sudo systemctl start nginx

出力されたメッセージより、証明書ファイルは下記に保存された様子。

Certificate is saved at: /etc/letsencrypt/live/laravel.unluckysystems.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/laraveln.unluckysystems.com/privkey.pem

Nginxのバーチャルサーバ設定(.conf)

Laravel 10本家サイトの.confの設定を参考に、SSL化のための証明書パスなどを追加してファイルを作成した。

サーバに送られたリクエストのすべてはpublic/index.phpに届くように確実に設定すべしとのこと。確かに上位ディレクトリに届いてしまうとパスワードとか書いたenvファイルとか丸見えになるよね。

# .confファイルの作成場所(新規)
sudo vim /etc/nginx/sites-available/laravel_unluckysystems.conf

confファイル全文

laravel.unluckysystems.comのドキュメントルートをLaravelプロジェクトのpublicに設定した。

あとはSSL化のための証明書情報等を設定し、PHP-fpmのバージョンを自身の環境である8.1に変更した。

server {
    listen 80;
    listen [::]:80;
    server_name laravel.unluckysystems.com;
    ssl_certificate /etc/letsencrypt/live/laravel.unluckysystems.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/laravel.unluckysystems.com/privkey.pem;

    location ^~ /.well-known/acme-challenge/{
        default_type "text/plain";
        root /var/www/laravel_unluckysystems/public;
    }

    location / {
        return 301 https://laravel.unluckysystems.com$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443;
    server_name laravel.unluckysystems.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/laravel.unluckysystems.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/laravel.unluckysystems.com/privkey.pem;

    root /var/www/laravel_unluckysystems/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

confファイルを保存したら有効化しよう

site-enabledにシンボリックリンクを貼って、、、

sudo ln -s /etc/nginx/sites-available/laravel_unluckysystems.conf /etc/nginx/sites-enabled/

Nginxを再起動して設定を反映する。

sudo systemctl restart nginx

接続

登録したドメインに対して、証明書エラーなく、httpsでアクセスできるようになっていれば成功。やったね。

証明書の更新

Let's Encryptで取得したSSL/TLS用の証明書は期限が短いので切れないように下記コマンドにて更新する必要がある。

cronとかで仕込んでおくと定期的に手動更新せずにすみ、メンテナンスフリーになる。

sudo letsencrypt renew

おまけ

Laravelのプロジェクトファイルをただ適当に本番環境においても、パーミッション関係のエラー出やすいので調整しようね。

いつもの

記事の内容は無保証です。

  • この記事を書いた人
あっきー

あっきー

とある企業の研究者。研究分野以外に手を出しすぎて毎日が慌ただしい。 研究者の肩書きが正しいかどうかは万年の謎。 得意ジャンルはデータベースとセキュリティーですが、AIやIoT、アプリ開発など、手広く活動しています。

-Linux, PHP, セキュリティ, 技術解説
-, , ,

Translate »