nginxの設定 いろいろ

nginx のインストール(Ubuntu)
アプリケーションインストール前のおまじない
初回実行時は時間がかかる場合があります。
以下のコマンドでパッケージ情報を更新・アップグレードします。
sudo apt-get update
sudo apt-get upgrade
nginx のインストール
次のコマンドで nginx をインストールします。
sudo apt install nginx
インストール確認
以下のコマンドで nginx のバージョンが表示されれば、インストールは成功です。
nginx -v
nginx の起動と自動起動設定
起動確認
nginx
のインストールと同時にウェブサーバーは自動起動されます。
起動状況は以下のコマンドで確認できます。
sudo systemctl status nginx
出力例:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2022-10-20 15:15:44 JST; 53s ago
Docs: man:nginx(8)
Process: 36839 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Process: 36840 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Main PID: 36934 (nginx)
Tasks: 3 (limit: 1033)
Memory: 7.0M
CPU: 40ms
CGroup: /system.slice/nginx.service
├─36934 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
├─36937 nginx: worker process
└─36938 nginx: worker process
自動起動設定
起動・有効化:
sudo systemctl start nginx
sudo systemctl enable nginx
自動起動の解除:
sudo systemctl stop nginx
sudo systemctl disable nginx
ウェブサーバーへのアクセス確認
レンタルサーバーでパケットフィルターを利用している場合は、Web
に使用する 80/443 ポートへのアクセスを許可してください。
設定完了後、ブラウザからサーバーの IP
アドレスにアクセスし、以下のような nginx
のスタート画面が表示されることを確認します。

nginx のドキュメントルート変更
nginx
のドキュメントルートを変更するには、/etc/nginx/sites-enabled/default
ファイルを編集します。
ドキュメントルートの変更手順
sudo vi /etc/nginx/sites-enabled/default
ファイル内の以下の行を修正します。
- # root /var/www/html;
+ root /home/ubuntu/example.com/output;
設定反映
設定変更後、nginx を再起動して変更内容を反映させます。
sudo systemctl restart nginx
注意: Web ドキュメントを ubuntu
のホームディレクトリ配下に配置する場合、/home/ubuntu
ディレクトリの権限が 755
になっていることを確認してください。
www あり・なしの統一
DNS 設定
まず、利用中のネームサーバー(DNS)で www のサブドメインを追加してください。

nginx の設定変更
/etc/nginx/sites-enabled/default
に以下の設定を追加します。
これにより、www でアクセスされた場合、www なしのドメインへ 301
リダイレクトされます。
server {
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}
Let’s Encryptをnginxへ導入するまで
cerbotのインストール
無料のSSL証明書を発行してhttps通信できるようにするため、Let’s Encryptをnginxへ導入します。まずは、Let’s Encryptを簡単に導入してくれるアプリケーション「cerbot」をインストールします。
sudo apt install certbot python3-certbot-nginx
インストールされたバージョンは次のとおり。
$ certbot --version
certbot 1.21.0
443ポートの開放
ファイアーウォールやパケットフィルターなどを使っている場合は、443ポートを開放します。
certbotでSSL証明書を発行
それではcertbotを使って、SSL証明書を発行しましょう。
sudo certbot --nginx -d example.com
example.com
はnginxですでに設定してあるドメインになります。
certbotでSSL証明書の自動更新
SSL証明書は3か月のみ有効なので、期限が迫ってきたら自動で更新できるようにしておきましょう。
$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for example.com.fun
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--dry-run
(テストモード)を実行して
success
が表示されていればOKです。
nginxの設定ファイルにSSL証明書のパスが追加されていることを確認します
sudo vi /etc/nginx/sites-enabled/default
次の画像の通り、ssl_certificate(SSL証明書)、ssl_certificate_key(秘密鍵)のパスが追加されていればOKです。
nginxの構文チェック
次のコマンドでnginxの構文チェックをし、問題がないか確かめておきましょう。
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
ブラウザからドメインへhttpsでアクセスできるか確認
ブラウザでドメインへhttpsアクセスして、証明書が確認できればLet’s Encryptの設定完了です。

www・httpアクセスをhttps・wwwなしへリダイレクト
wwwありとなしを統一することで、SEO効果が見込める可能性があるようです。wwwありとなしのドメインの両方でアクセスできてしまうと、Google検索エンジンが二つのページが存在すると勘違いしてしまう可能性があり、評価が分散されてしまう恐れがあるからです。
さて、先述でwwwありをwwwなしに統一する設定をnginxで行いました。httpの場合はスムーズにできるのですが、Let’s Encryptを使ったhttpsの場合はちょっと工夫が必要です。
前回の設定だけですと、http://www
へのアクセスはリダイレクトできても https://www
のアクセスは次のようにエラーになってしまいます。
実はこの記事の前半で設定した証明書は、www付きのドメインアクセスでは使用できません。つまりは、www付きドメイン用のSSL証明書も別途用意しなければならないということです。 といっても解説した手順でやればとても簡単ですので、めんどくさがらずに進めてみましょう。次のコマンドで、www付きドメインのSSL証明書を発行、自動更新します。
sudo certbot --nginx -d www.example.com
証明書がインストールできたら
/etc/nginx/sites-enabled/default
を以下のように修正します。
server {
server_name www.example.com example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
root /home/ubuntu/somewhere;
index index.html;
server_name example.com;
....
最初のserverディレクティブでは、
http://www.example.com
へのアクセスを
https://example.com
へリダイレクトさせてます。
2番目のserverディレクティブでは、
https://www.example.com
へのアクセスを
https://example.com
へリダイレクトさせてます。この2番目のserverディレクティブを有効にするために、ww付きドメインのSSL証明書が必要だったわけですね。
最後のserverディレクティブは、すでに設定してきたメインの記述ですので変更は加えません。
設定ファイルの変更をおこなったら、文法チェックをし、nginxを再起動させましょう。
sudo nginx -t
sudo systemctl restart nginx
これでwwwあり・httpアクセスを、https・wwwなしにリダイレクト、統一できました。
登録したドメインをCertbotから削除する
Certbotに登録したドメインを削除するには、以下の手順を実行してください。
登録された証明書を確認
まず、現在登録されている証明書を確認します。
sudo certbot certificates
出力例:
Found the following certs:
Certificate Name: www.example.com
...
削除したいドメイン名(Certificate Name
)をメモしてください。
ドメインを削除
以下のコマンドを使用して、指定した証明書を削除します。
sudo certbot delete --cert-name www.example.com
削除確認
再度、証明書リストを確認して削除が完了したことを確認します。
sudo certbot certificates
削除したドメインが表示されなければ、削除成功です。
必要に応じて、Nginx の設定から該当ドメインに関する記述も削除してください。その後、Nginx を再読み込みします。
sudo systemctl reload nginx
nginxでVirtualHostを設定する
nginxで複数のドメインを管理するためのVirtualHost設定は非常に簡単です。既存のサーバー設定と同じ内容を元に、ドメイン部分だけ変更することで新たなサーバー設定を作成できます。
Ubuntuでは、nginxのサーバー設定は/etc/nginx/sites-available
および/etc/nginx/sites-enabled
ディレクトリに格納されています。既定ではdefault
というファイルが用意されていますが、複数のドメインを管理する際は、各ドメイン毎にファイルを分けると管理が容易になります。
既存の設定ファイルについて
/etc/nginx/sites-enabled/default
はシンボリックリンクになっており、実際の設定ファイルは/etc/nginx/sites-available/default
に存在します。このファイルを元に、各サーバー毎の設定ファイルを作成していきます。
defaultファイルをコピーする
まずは、既存のdefault
ファイルを元に新しいサーバー設定ファイルを作成します。ここでは例としてドメイン名「101010.fun」で設定する場合を示します。
cd /etc/nginx/sites-available
sudo cp default 101010.fun
この時点で、/etc/nginx/sites-available
ディレクトリ内に新しいファイル「101010.fun」が作成されます。
シンボリックリンクの作成
次に、/etc/nginx/sites-enabled
ディレクトリに新しい設定ファイルへのシンボリックリンクを作成します。
cd /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/101010.fun 101010.fun
これで、nginxは新しい設定ファイルも読み込むようになります。現在のディレクトリ内の一覧は以下のようになります。
ls -l
total 8
lrwxrwxrwx 1 root root 37 Dec 6 11:52 101010.fun -> /etc/nginx/sites-available/101010.fun
lrwxrwxrwx 1 root root 34 Oct 20 15:15 default -> /etc/nginx/sites-available/default
設定ファイルの編集
あとは、新規作成した「101010.fun」ファイル内の内容を、該当ドメインや必要な設定内容に合わせて編集します。
例えば、ドメイン名の設定やSSL証明書の設定(Let’s
Encryptなど)を行います。
古いサーバーから新しいサーバーに移行する場合は、ドメインのDNS設定をあらかじめ新しいサーバーのIPに変更しておくことを忘れないでください。DNS設定が正しくないと、Let’s
EncryptによるSSL証明書の発行に失敗する可能性があります。
nginxでPHPを動かす
Apacheの場合、PHPはモジュールとして組み込まれているため、Apacheを起動するだけでPHPが利用可能な状態になります。しかし、nginxの場合は、自前でPHP用のプロセスを立ち上げ、FastCGI経由で接続する設定が必要です。調べたところ、PHPを動かすには FastCGI Process Manager (FPM) に対応した php-fpm を使用するのが望ましいようです。
php-fpmのインストール
以下のコマンドで php-fpm
をインストールします。
sudo apt install -y php-fpm
PHPのインストール確認
PHPがインストールされているかどうかを以下のコマンドで確認します。
$ which php
/usr/bin/php
$ which php-fpm8.1
/usr/sbin/php-fpm8.1
$ php -v
PHP 8.1.2-1ubuntu2.9 (cli) (built: Oct 19 2022 14:58:09) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
with Zend OPcache v8.1.2-1ubuntu2.9, Copyright (c), by Zend Technologies
$ php-fpm8.1 -v
PHP 8.1.2-1ubuntu2.9 (fpm-fcgi) (built: Oct 19 2022 14:58:09)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
with Zend OPcache v8.1.2-1ubuntu2.9, Copyright (c), by Zend Technologies
nginxとphp-fpmの接続
nginxとphp-fpmの接続は、TCPまたはUNIXドメインソケットを使用して行います。ここではUNIXドメインソケットを使用します。
php-fpm.conf
には、以下のように
include=/etc/php/8.1/fpm/pool.d/*.conf
と記述されており、/etc/php/8.1/fpm/pool.d/
ディレクトリ以下の .conf
ファイル(実際には
www.conf
の設定)が読み込まれます。www.conf
の内容を確認してみます。
vi /etc/php/8.1/fpm/pool.d/www.conf
このファイル内の listen
に、UNIXドメインソケットの接続先
が記述されています。後ほどこのアドレスをメモしておきます。
listen = /run/php/php8.1-fpm.sock
PHPプロセスの確認
php-fpm
をインストールすると、自動的にPHP関連のデーモンプロセスが起動されるため、php-fpm
の起動設定は特に必要ありません。
systemctl list-unit-files --type=service | grep php
php8.1-fpm.service enabled enabled
phpsessionclean.service static -
ls /run/php | grep php
php-fpm.sock
php8.1-fpm.pid
php8.1-fpm.sock
nginxの設定
次に、nginxからPHPを利用できるように、php-fpm
への接続設定を行います。以下のコマンドで対象となるサーバー設定ファイルを編集します。
sudo vi /etc/nginx/sites-enabled/default
編集内容は以下の通りです。.php
のURLがリクエストされた場合、UNIXドメインソケット経由でphp-fpmへ処理を渡す設定となっています。
server {
root /somewehere;
index index.html index.php;
server_name xxxxxxxx;
...
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
過去に設定した リバースプロキシ の設定と非常に似ています。
設定内容に誤りがないか確認後、nginxを再起動します。
sudo nginx -t
sudo systemctl restart nginx
test.php
ファイルを新規作成し、以下の内容を記述してサーバー上に配置します。ブラウザでアクセスし、PHP情報が表示されれば設定が正しく反映されたことになります。
<?php phpinfo(); ?>

なお、UNIXドメインソケットで通信しているかどうかは、以下のように
netstat
コマンドで確認できます。
sudo apt install net-tools
netstat -a --unix | grep php
unix 2 [ ACC ] STREAM LISTENING 15992968 /run/php/php8.1-fpm.sock
デフォルトの404エラーページを変更する
バージョン情報を非表示にする
nginxのデフォルトの404エラーページには、nginxのバージョン情報やOSの情報が表示されます。セキュリティ上望ましくないため、これらの情報を非表示にする方法を解説します。

まず、nginx.conf
の設定ファイルを開きます。
$ sudo vi /etc/nginx/nginx.conf
設定ファイル内で「server_tokens off」という行がコメントアウトされている場合は、コメントアウトを解除して有効にします。

設定変更後、nginxを再起動します。
sudo systemctl restart nginx
これで、404エラー発生時にバージョン情報やOS情報が非表示になります。

オリジナルの404エラーページを表示する
サイトのデザインに合わせてオリジナルの404エラーページを表示させたい場合は、以下の手順で設定を行います。
まず、default
ファイルを編集します。
sudo vi /etc/nginx/sites-enabled/default
次に、オリジナルの404.html
を用意し、server
ディレクティブ内に以下のように記述して、404ページのファイルパスを指定します。
※root
ディレクティブには404.html
が存在するディレクトリを指定してください。
server {
:
error_page 404 /404.html;
location = /404.html {
root /somewhere_dir;
}
:
:
}
最後に、nginxを再起動します。
sudo systemctl restart nginx
アクセスログとエラーログの確認方法
nginxのログファイルがある場所
デフォルト設定では、ログファイルは以下の場所に保存されます(ubuntu)。
項目 | 場所 |
---|---|
アクセスログ | /var/log/nginx/access.log |
エラーログ | /var/log/nginx/error.log |
access.log
の例
220.213.212.146 - - [23/Oct/2022:21:42:52 +0900] "GET /images_small/niku-udon/eyecatch.jpg HTTP/2.0" 200 23571 "https://k.araisun.com/noodles/teuchi-udon.html" "Mozilla/5.0 (Linux; Android 4.4.2; LaVieTab PC-TE510S1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
...
error.log
の例
2022/10/23 07:33:12 [crit] 52949#52949: *2381 SSL_do_handshake() failed (SSL: error:0A00006C:SSL routines::bad key share) while SSL handshaking, client: 154.89.5.78, server: 0.0.0.0:443
※ error.log
には 404
エラーなども記録されます。
エラーログの整形出力
以下のコマンドは、open()
を含むログ行から対象ファイルを抜き出し、重複件数をカウントして、件数の多い順にソートして出力するものです。
grep 'open()' error.log | awk -F'"' '{print $2}' | sort | uniq -c | sort -nr
この方法により、404エラーが多発しているページを一目で確認でき、アクセスの傾向把握に役立ちます。
「SSL_do_handshake() failed」とは?
エラーログを確認していると、SSL_do_handshake() failed
というエラーが見受けられます。
こちらの記事
によると、サイバー攻撃に起因してログが失敗したもののようです。エラーが発生しているため、セキュリティ的には問題ないと考えられます。また、SSLプロトコルの
SSLv2、SSLv3、TLSv1 は古く脆弱性があるため、使用せず、TLSv1.2
以降を利用することが望ましいとされています。
「.well-known/traffic-advice」とは?
.well-known/traffic-advice
は、Google Chrome
の先読み機能によるアクセスです。先読み機能を使用していない場合、アクセスを禁止するため、.well-known/traffic-advice
ファイルを作成し、以下の内容を記述しておきます。
[
{"user_agent": "prefetch-proxy", "disallow": true}
]
これにより、エラーログに該当の記録が出力されなくなるはずです。
ちなみに、well-known
関連のエラーログ抽出方法は以下の通りです。
grep ".well-known" /var/log/nginx/error.log.1 | sed -E 's/.* open\(\) "([^"]+)".*/\1/g' | uniq
不正なアクセス対処(PHP編)
PHPを使用していない環境では、.php 拡張子へのリクエストが大量に来るのは不要なアクセスとなり、ログに無駄なエントリが残ります。そこで、Nginxの設定でPHPファイルへのアクセスを拒否する方法が有効です。以下の設定を追加することで、.php リクエストに対してレスポンスを返さず、接続を切断(444エラーを返す)できます。
location ~ \.php$ {
return 444;
}
「444」は、Nginx独自のステータスコードで、クライアントに何も返さずに接続を強制的に切断することを意味します。この方法により、PHPを使用していない場合の不要なアクセスを効果的にブロックし、ログの無駄な記録を防ぐことができます。
リダイレクトを行う rewrite の使い方
nginx を使ったサーバー構築では、基本的に Apache のような
.htaccess
は機能しません。nginx で 301
リダイレクトなどを行いたい場合は、nginx の設定ファイルに
rewrite
でルールを記述する必要があります。ここでは
rewrite
の使い方をまとめておきます。
rewrite の概要
nginx でリダイレクトを行うためには、rewrite
ディレクティブを使用します。このディレクティブは、指定した条件に一致するリクエスト
URI を別の URI に書き換えたり、外部の URL
へリダイレクトさせたりすることができます。rewrite
ディレクティブは、サーバーやロケーションコンテキスト内で使用することができます。
基本的な構文は以下の通りです:
rewrite regex replacement [flag];
パラメータ
パラメータ | 説明 |
---|---|
regex |
リダイレクトを適用するための正規表現パターン |
replacement |
リダイレクト先の URI または外部 URL |
flag |
リダイレクトの動作を制御するオプション |
flag オプション
パラメータ | 説明 |
---|---|
last |
現在のリライト処理を終了し、改めてリライト処理を開始 |
break |
現在のリライト処理を終了し、さらなる処理を行わない |
redirect |
一時的なリダイレクト (302) を行う |
permanent |
永続的なリダイレクト (301) を行う |
単純なリダイレクト
以下の設定例では、/old-page
へのアクセスを
/new-page
に 301 リダイレクトします。
rewrite ^/old-page$ /new-page permanent;
複雑なリダイレクト
複数のサブディレクトリに対してリダイレクトを適用する場合、正規表現を使用します。
rewrite ^/old-site/(.*)$ /new-site/$1 permanent;
この例では、/old-site
以下の任意のパスへのアクセスを、同じサブパスを保持しつつ
/new-site
へリダイレクトします。
便利な機能:
return
ディレクティブ
リダイレクトを行う別の方法として、return
ディレクティブがあります。これは、条件に応じてリダイレクトやエラーページの表示をよりシンプルに設定することができます。
location /old-page {
return 301 /new-page;
}
この方法では、特定のリクエスト URI
に対して簡潔にリダイレクトを設定でき、rewrite
ディレクティブを使用するよりも読みやすく、パフォーマンスの面でも効率的です。また、HTTP
ステータスコードを直接指定できるため、リダイレクトの種類を容易に制御できます。
nginx のリダイレクト設定は非常に柔軟であり、サイトの構造変更や URL スキームの更新、外部サイトへのリダイレクトなど、さまざまなシナリオに対応できます。適切なディレクティブや正規表現を使用することで、必要なリダイレクトルールを効率的に実装できます。
nginx の設定を変更した後は、 sudo nginx -t
でテストし、 sudo systemctl reload nginx
で設定を反映させます。
rewrite ディレクティブを別ファイルで管理する
これらの rewrite
ディレクティブを
server
ディレクティブへ直接記述しても良いのですが、rewrite
ルールが多すぎると管理が大変になります。そこで、rewrite
ルールを別ファイルで管理する方法を紹介します。これには
include
ディレクティブを使用します。include
ディレクティブを使用することで、外部の設定ファイルを読み込み、メインの
nginx 設定ファイルをすっきりと保つことができます。
手順
- リダイレクトルールを含む新しいファイルを作成します。例えば、
/etc/nginx/sites-available/redirects.conf
といったパスに保存します。
- この新しいファイルに、すべての
rewrite
ルールを記述します。
- メインの nginx
設定ファイル(または適切なサーバーブロック設定ファイル)にて、次のように
include
ディレクティブを使用して、作成したリダイレクトルールファイルを読み込みます。
server {
# その他の設定 ...
# リダイレクトルールを含む外部ファイルを読み込む
include /etc/nginx/sites-available/redirects.conf;
# その他の設定 ...
}
この手順により、nginx 設定のメンテナンスが容易になり、特定の種類の設定を集中管理できるようになります。また、将来的にリダイレクトルールを追加または変更する際に、メインの設定ファイルを直接編集する必要がなくなり、エラーのリスクを減らすことができます。
include
ディレクティブは非常に強力で、サーバー設定の柔軟性と再利用性を高めます。ただし、複数の
include
ファイルを使用する場合は、それらのファイル間での設定の競合に注意する必要があります。また、nginx
の設定を変更した後は、設定のテストと nginx
の再起動またはリロードが必要です。
nginx の設定を変更した後は、 sudo nginx -t
でテストし、 sudo systemctl reload nginx
で設定を反映させます。