FreeBSD 14 + Nginx + PHP + MariaDB + Postfixの環境を構築(2024年版)

ConohaでFreeBSDの仮想マシンを設定しているときの覚書。

環境: Conoha VPS 8GBプラン, FreeBSD 14.0

目次

  1. 初期設定
  2. Nginxをインストール
  3. php8.3をインストール
  4. MariaDBをインストール
  5. phpMyAdminをインストール
  6. SSL設定
  7. Postfix + DKIM(送信ドメイン認証)をインストール


1.初期設定

keymapが日本語になっているので英語キーボードへ変更する。
管理画面のコンソールから設定する(keymap="jp"をコメントアウト)。
# less /etc/rc.conf

#keymap="jp"

あとはSSHでログイン。
FreeBSDのシステムアップデート。
# freebsd-update fetch
# freebsd-update install

パッケージマネージャをアップデート。
インストール済みパッケージを確認。
# pkg update
# pkg upgrade
# pkg info

Timezone確認。
# date

時刻があってなければタイムゾーンを設定。
# bsdconfig

シェルを確認してBashをインストール。
# echo $SHELL
# pkg search bash
# pkg install bash bash-completion

画面の指示通りにする。
ログインシェルなので.bashrcでなくて.bash_profileに記述する。
# vi .bash_profile

bashに切り替えてデフォルトをBashにする。
# bash
# chsh -s /usr/local/bin/bash

vimをインストール。
# pkg install vim

デフォルトのエディタをviからvimに変更する。
(lessからvで起動するための設定)
# less .bash_profile

export EDITOR="/usr/local/bin/vim"

シェルの再読み込みして環境変数確認。
# source .bash_profile
# printenv

vimの設定ファイルvimrcの場所を確認。
# vim --version

デフォルトで/usr/local/share/vim/vim91/defaults.vimが読み込まれている。

追加のvim設定ファイルを作成する。
# cd
# vim .vimrc

" デフォルト設定: /usr/local/share/vim/vim91/defaults.vim

" バックスペースで削除
set backspace=indent,eol,start

" 行番号表示
set number

" ステータスバーを常に表示
set laststatus=2

" 構文ハイライト
syntax on

" Escの2回押しでハイライト消去
nnoremap <Esc><Esc> :nohlsearch<CR><ESC>

" インクリメンタルサーチ
set incsearch

" 大文字小文字を区別しない
" 検索文字に大文字を含んでいたら区別する。
set ignorecase smartcase

" ハイライト検索
set hlsearch

" マウスの設定を取り消す
set mouse-=a

vim設定ファイルを読み込む。
(vimを起動してコマンドを実行して終了する)
# vim -c ':source ~/.vimrc | quit'

hostnameを変更する。
# less /etc/rc.conf

hostname="conoha.company.co.jp"

再起動
# reboot

gitをインストールして確認。
# pkg install git
# git --version

git version 2.45.1

Global設定しておく。
# git config --global user.name "Daiki"
# git config --global user.email "suganuma@company.co.jp"


2.Nginxをインストール

FreeNginxと本家のどっちをインストールするか悩む。
一応まだ本家の方にしておく。
# pkg search nginx
# pkg install nginx
# nginx -V

nginx version: nginx/1.24.0
built with OpenSSL 3.0.12 24 Oct 2023
TLS SNI support enabled
configure arguments: --prefix=/usr/local/etc/nginx --with-cc-opt='-I /usr/local/include' --conf-path=/usr/local/etc/nginx/nginx.conf --sbin-path=/usr/local/sbin/nginx --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx/error.log --user=www --group=www ...

自動起動ON、起動、確認。
# service nginx enable
# service nginx start
# service nginx status

設定ファイルを編集。
# cd /usr/local/etc/nginx/
# less nginx.conf

worker_processes  auto;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;

    include /usr/local/etc/nginx/conf.d/*.conf;
}

conf.dを作る。
サーバーの共通設定をcloneしておく。
# mkdir conf.d
# cd conf.d/
# git clone git@gitlab.com:settings/nginx-global.git include

CentOSとfastcgi_cache_pathは同じにしたいので場所を作る。
(PHPからキャッシュをクリアときに絶対パスで指定しているから)
# mkdir -p /var/cache/nginx/fastcgi_www
# chown -R www:www /var/cache/nginx/


3. php8.3をインストール

pkg経由でインストール。
php83-filterとphp83-mysqliはphpMyAdminのために必要。
php83-pgsqlはPostgreSQLに接続するために必要。
# pkg search php8
# pkg install php83 php83-curl php83-filter php83-gd php83-mbstring php83-mysqli php83-session php83-xml php83-zip php83-pgsql

確認。
# php --version

PHP 8.3.6 (cli) (built: Apr 18 2024 01:10:55) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.6, Copyright (c) Zend Technologies

ビルドオプションを表示してconfigの場所やphp-fpm実行ユーザーを確認。
# php-config --configure-options

--disable-all 
--program-prefix= 
--with-config-file-scan-dir=/usr/local/etc/php 
--with-layout=GNU 
--with-libxml 
--with-openssl 
--with-password-argon2=/usr/local 
--enable-dtrace 
--enable-embed 
--enable-fpm 
--with-fpm-group=www 
--with-fpm-user=www 
--enable-mysqlnd 
--with-external-pcre=/usr/local 
--prefix=/usr/local 
--localstatedir=/var 
--mandir=/usr/local/share/man 
--infodir=/usr/local/share/info/ 

phpinfoでタイムゾーン、mysqlnd、iniファイル置き場を確認。
# php -i | less

iniファイル置き場はコマンドでも確認できる。
# php --ini

iniファイルを作る。
# cd /usr/local/etc
# cp php.ini-production php.ini

タイムゾーンを設定する。
# less php.ini

date.timezone = "Asia/Tokyo"

読み込まれているか確認して現在時刻を確認。
# php --ini
# php -r 'echo date("Y/m/d H:i");'

php-fpmをUnix socketでlistenする。
セッションの置き場所も記述する。
# less php-fpm.d/www.conf

;listen = 127.0.0.1:9000
listen = /var/run/php-fpm.sock
listen.owner = www
listen.group = www
listen.mode = 0660 
php_value[session.save_path] = /var/tmp/php/session 

phpセッションの置き場所を作って権限変更。
# mkdir /var/tmp/php
# mkdir /var/tmp/php/session
# chown -R www:www /var/tmp/php

php-fpmの自動起動ON、起動、確認。
# service php-fpm enable
# service php-fpm start
# service php-fpm status

git cloneして共通設定ファイル群はCentOS用になっているので、Unix socketのpathを変更する。
# less /usr/local/etc/nginx/conf.d/include/fastcgi_php.inc

#fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_pass unix:/var/run/php-fpm.sock;

nginx再読み込み。
# service nginx reload


4. MariaDBをインストール

前と同じだったので省略。
参考: FreeBSD + Nginx + PHP + MariaDBの環境を構築

本番用サーバーなのでチューニング設定を追記する。
# less /usr/local/etc/mysql/conf.d/server.cnf

[server]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
thread_handling = pool-of-threads
max_connections = 100

# Tuning
performance_schema = ON
skip-name-resolve

sort_buffer_size = 4M
query_cache_size = 256M
query_cache_limit = 4M

table_open_cache = 10K
table_definition_cache = 2K
tmp_table_size = 128M
max_heap_table_size = 128M

# InnoDB
innodb_buffer_pool_size = 512M
innodb_log_buffer_size = 128M
innodb_ft_min_token_size = 2       # Fulltext Index
innodb_ft_num_word_optimize = 4000 # Fulltext Index
innodb_ft_enable_stopword = OFF    # Fulltext Index
innodb_ft_cache_size = 16M         # Fulltext Index

# MyISAM/Aria
key_buffer_size = 256K
myisam_sort_buffer_size = 256K
aria_sort_buffer_size = 256K
aria_pagecache_buffer_size = 256K

# Slow Query
slow_query_log = ON
long_query_time = 1
log_output = TABLE


5. phpMyAdminをインストール

公式サイトから最新版をダウンロードして配置
# mkdir /home
# mkdir /home/httpd
# cd /home/httpd
# curl -O https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-english.tar.gz
# tar xzvf phpMyAdmin-5.2.1-english.tar.gz
# mv phpMyAdmin-5.2.1-english phpMyAdmin
# rm phpMyAdmin-5.2.1-english.tar.gz

configファイル編集。
localhostを127.0.0.1に変更する。
(mysqliはlocalhostだとmysqli.default_socketを参照するらしい)
# cd phpMyAdmin
# cp config.sample.inc.php config.inc.php
# less config.inc.php

$cfg['Servers'][$i]['host'] = '127.0.0.1';

tmpディレクトリを作る。
# mkdir tmp
# chmod 777 tmp/

nginxの設定ファイルを作る。
(IPv6をlistenするとcertbotで失敗するときがある。逆にIPv6がないと失敗する場合もある)
# cd /usr/local/etc/nginx/conf.d/
# vim 01_phpMyAdmin.conf

server {
    listen       80;
    server_name  phpmyadmin.conoha.hoge.jp;

    root    /home/httpd/phpMyAdmin/;
    index   index.php index.html index.htm;
    charset utf-8;

    location ~* \.php$ {
        include conf.d/include/fastcgi_php.inc;
        client_max_body_size 20M;
    }
}

nginx再読み込み。
# nginx -t
# service nginx reload

ブラウザで表示して確認。


6. SSL設定

DH公開鍵暗号の素数ファイルを作る。5分ほど掛かった。
# openssl dhparam -out /etc/ssl/dhparam.pem 4096

certbotをインストール。
# pkg search certbot
# pkg install py39-certbot

定期実行する方法が画面に表示されたので設定してみる。
# vim /etc/periodic.conf

weekly_certbot_enable="YES"

phpMyAdmin用の証明書をcertbotで取得。
# certbot certonly --webroot -w /home/httpd/phpMyAdmin -d phpmyadmin.conoha.hoge.jp

Basic認証用も設定。
htpasswdコマンドをインストールから。
# pkg search htpasswd
# pkg install py39-htpasswd
# cd /home/httpd/
# htpasswd.py -c -b ./.htpasswd conoha password

nginx設定ファイル編集。
# cd /usr/local/etc/nginx/conf.d/
# less 01_phpMyAdmin.conf

server {
    include conf.d/include/ssl_listen.inc;
    server_name  phpmyadmin.conoha.hoge.jp;

    root    /home/httpd/phpMyAdmin/;
    index   index.php index.html index.htm;
    charset utf-8;

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

    # Basic Authentication
    auth_basic    "Secret Area for conoha";
    auth_basic_user_file  "/home/httpd/.htpasswd";

    # IP Limitation
    include conf.d/include/allow/webrec-office.inc;
    deny all;

    # Accept for Let's Encrypt(certbot)
    location /.well-known/acme-challenge {
        auth_basic off;
        access_log off;
        allow all;
    }

    location ~* \.php$ {
        include conf.d/include/fastcgi_php.inc;
        client_max_body_size 20M;
    }

    include conf.d/include/gzip.inc;
    include conf.d/include/ssl.inc;
    ssl_certificate         /usr/local/etc/letsencrypt/live/phpmyadmin.conoha.hoge.jp/fullchain.pem;
    ssl_certificate_key     /usr/local/etc/letsencrypt/live/phpmyadmin.conoha.hoge.jp/privkey.pem;
    ssl_trusted_certificate /usr/local/etc/letsencrypt/live/phpmyadmin.conoha.hoge.jp/chain.pem;
}
nginx再読み込み。
# nginx -t
# service nginx reload

ブラウザで表示して確認。


7. Postfix + DKIM(送信ドメイン認証)をインストール

FreeBSDは標準でSendmailがインストール済み。
Postfixの方が使いやすいので切り替える。

Postfixをインストール。
親切に次やることが画面に表示された。
# pkg search postfix
# pkg install postfix

===============================================================
Postfix was *not* activated in /usr/local/etc/mail/mailer.conf!

To finish installation run the following commands:

  mkdir -p /usr/local/etc/mail
  install -m 0644 /usr/local/share/postfix/mailer.conf.postfix /usr/local/etc/mail/mailer.conf
===============================================================

=====
Message from postfix-3.9.0,1:

--
To use postfix instead of sendmail:
  - clear sendmail queue and stop the sendmail daemons

Run the following commands to enable postfix during startup:
  - sysrc postfix_enable="YES"
  - sysrc sendmail_enable="NONE"

If postfix is *not* already activated in /usr/local/etc/mail/mailer.conf
  - mv /usr/local/etc/mail/mailer.conf /usr/local/etc/mail/mailer.conf.old
  - install -d /usr/local/etc/mail
  - install -m 0644 /usr/local/share/postfix/mailer.conf.postfix /usr/local/etc/mail/mailer.conf

Disable sendmail(8) specific tasks,
add the following lines to /etc/periodic.conf(.local):
  daily_clean_hoststat_enable="NO"
  daily_status_mail_rejects_enable="NO"
  daily_status_include_submit_mailq="NO"
  daily_submit_queuerun="NO"

If you are using SASL, you need to make sure that postfix has access to read
the sasldb file.  This is accomplished by adding postfix to group mail and
making the /usr/local/etc/sasldb* file(s) readable by group mail (this should
be the default for new installs).

まずはsendmailのデーモンを止める。
# service sendmail status

sendmail is not running.
sendmail_msp_queue is not running.

動いてなかった。

指示された通りに実行する。
Postfixを自動起動して、Sendmailを止める。
# sysrc postfix_enable="YES"
# sysrc sendmail_enable="NONE"

確認。
# less /etc/rc.conf

設定フォルダを作ってメール設定ファイルをコピーする。
# mkdir -p /usr/local/etc/mail
# install -m 0644 /usr/local/share/postfix/mailer.conf.postfix /usr/local/etc/mail/mailer.conf

/etc/periodic.confに記述しろとあるのでやっておく。
# less /etc/periodic.conf

daily_clean_hoststat_enable="NO"
daily_status_mail_rejects_enable="NO"
daily_status_include_submit_mailq="NO"
daily_submit_queuerun="NO"

再起動してPostfixが起動しているか確認。
# reboot

Postfxを確認してメールを送ってみる。
# service postfix status
# mail hoge@gmail.com
# less /var/log/maillog

ちゃんとpostfixで送ろうとしている。Gmailからはブロックされるけど。
あとはCentOSのときとほとんど一緒。
参考: CentOS Stream 8 + Nginx + PHP + MariaDB + Postfixの環境を構築(2021年版)

設定ファイルを編集。
# less /usr/local/etc/postfix/main.cf

myhostname = conoha.hoge.jp
mydomain = hoge.jp
myorigin = $mydomain
inet_interfaces = localhost
mydestination = localhost

postfix再起動。
# service postfix restart

ドメインのDNS情報を編集してSPF認証が通るようにしておく。

Gmailに送信してみてメールログを確認。
# mail hoge@gmail.com
# less /var/log/maillog

無事送れた。

今度はDKIMの設定をする。
ARC(Authenticated Received Chain)もやろうとしたけど後回し。
参考: CentOS9にOpenARCをインストール
検索してインストール。
# pkg search dkim
# pkg install opendkim

画面に指示されている通りrc.confに記載する。
# sysrc milteropendkim_enable="YES"
# less /etc/rc.conf

OpenDKIMの設定ファイルを確認。
# less /usr/local/etc/mail/opendkim.conf

FreeBSDは/var/db/dkimに鍵ファイルをインストールするのがお作法みたい。
設定ファイルを編集。
# less /usr/local/etc/mail/opendkim.conf

#Domain hoge.jp
#KeyFile                        /var/db/dkim/example.private
KeyTable /var/db/dkim/KeyTable
SigningTable /var/db/dkim/SigningTable
Mode sv
Selector www01
Socket inet:8891@localhost
UMask  022

KeyTableとSigningTableを作成する。
# mkdir /var/db/dkim/
# cd /var/db/dkim/
# vim KeyTable

www01._domainkey.hoge.jp hoge.jp:www01:/var/db/dkim/keys/hoge.jp/www01.private

# vim SigningTable

*@hoge.jp   www01._domainkey.hoge.jp

公開鍵と秘密鍵を生成する。
# mkdir -p keys/hoge.jp
# opendkim-genkey --bits=2048 -D keys/hoge.jp/ -d hoge.jp -s www01

公開鍵をDNSに登録する。
# more keys/hoge.jp/www01.txt

opendkimの実行ユーザーを確認してファイル権限を変更。
# less /usr/local/etc/rc.d/milter-opendkim
# chown -R mailnull:mailnull keys/

opendkim起動。
# service milter-opendkim start

待ち受け中のポート確認。
# netstat -an -p tcp

postfix設定ファイル編集。
# less /usr/local/etc/postfix/main.cf

#
# OPENDKIM
#
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept

postfix再起動。
# service postfix restart

別コンソールでメールログを監視しておいてメールを送信してみる。
# tail -f /var/log/maillog
# mail hoge@gmail.com

milterが起動しない。

Unix Socketで起動するように変更してみた。
# less /usr/local/etc/mail/opendkim.conf

#Socket                 inet:8891@127.0.0.1
Socket                  local:/var/run/milteropendkim/socket

# less /usr/local/etc/postfix/main.cf

#smtpd_milters = inet:127.0.0.1:8891
smtpd_milters = unix:/var/run/milteropendkim/socket

権限を変更してサービス再起動。
# chown -R mailnull:mailnull /var/run/milteropendkim
# service milter-opendkim restart
# service postfix restart

メール送信テスト
# mail hoge@gmail.com

メールログにエラーが出た。

May 29 16:12:08 conoha01 postfix/cleanup[4825]: warning: connect to Milter service unix:/var/run/milteropendkim/socket: Permission denied

UMaskを変更してみた。
# less /usr/local/etc/mail/opendkim.conf

#UMask                  022
UMask                   000

サービス再起動してメール送信テスト
# service milter-opendkim restart
# mail hoge@gmail.com

エラーは出なくなったけど、milterされてない。
DKIMの詳細ログを表示するように設定変更。
# less /usr/local/etc/mail/opendkim.conf

# LogWhy                no
LogWhy          yes

メール送信してみると下記エラー。

May 29 16:27:04 www01 opendkim[4952]: 01DD975B3C: no signing table match for 'root@hoge.jp'

調べてみるとSigningTableを指定するときに「refile:」がなかったのでワイルドカードが発動しないのが原因。
# less /usr/local/etc/mail/opendkim.conf

KeyTable /var/db/dkim/KeyTable
SigningTable refile:/var/db/dkim/SigningTable

あと成功しても「SyslogSuccess           Yes」にしとかないとmaillogに出力しないことも分かった。

最終的なOpenDKIMの設定ファイルはこれ。
# less /usr/local/etc/mail/opendkim.conf

KeyTable              /var/db/dkim/KeyTable
SigningTable         refile:/var/db/dkim/SigningTable
Mode                    sv
Selector                www01
Socket                  local:/var/run/milteropendkim/socket
Syslog                  Yes
SyslogSuccess       Yes
UMask                  000


【関連記事】