Mautic のサーバー設定例

[Mautic Advent Calendar 2016](http://www.adventar.org/calendars/1402) の3日目の記事として、 **Mautic** のサーバー設定について検討してみました。
ちょっと盛り込みすぎて内容が散漫かつ中途半端になってしまいましたが、タイムリミットということで、参考までに。

# インストール環境
以下の環境で検討しました。

* VirtualBox 5.0.28
* 仮想マシンのメインメモリー 2GB
* CentOS 7.2.1511 (minimal)
* Apache 2.4.6 (updates)
* MySQL 5.7 (mysql57-community)

* PHP 7.0.13 (remi-php70)
* Mautic 2.2.1

Mautic 自体の具体的なインストール手順は「[マーケティングオートメーションの Mautic をインストールする](http://qiita.com/bezeklik/items/3cd61156367909e31421)」を参照してください。

# パフォーマンス対策
VirtualBox 上の簡単な検証では、 OPCache + APCu と mod_deflate 以外は目立った改善が見られませんでした。
特に PHP-FPM でパフォーマンスが改善しなかったので後でもう少し検証してみたいところです。
また、他に nginx や Varnish でリバースプロキシを用意してやるとよいかもしれません。

## 負荷テスト
### Siege
パフォーマンスを確認するための負荷テストツールとして、ページ内で参照するリソースもリクエストを投げてくれる Siege を利用しました。詳細は「[負荷テストツール Siege](http://qiita.com/bezeklik/items/79f806174fb99302a64a)」を参照してください。

ここではテスト対象として Mautic のランディングページ /test を作成し、別サーバーにインストールした Siege からテストしています。

```bash
siege -c 10 --time=1M http://192.168.56.101/test
```
```
Transactions:                    530 hits
Availability:                 100.00 %
Elapsed time:                  59.93 secs
Data transferred:              11.18 MB
Response time:                  1.08 secs
Transaction rate:               8.84 trans/sec
Throughput:                     0.19 MB/sec
Concurrency:                    9.55
Successful transactions:         470
Failed transactions:               0
Longest transaction:            3.92
Shortest transaction:           0.00
```

```bash
siege -c 50 --time=3M http://192.168.56.101/test
```
```
Transactions:                    758 hits
Availability:                 100.00 %
Elapsed time:                 179.28 secs
Data transferred:              12.30 MB
Response time:                  9.95 secs
Transaction rate:               4.23 trans/sec
Throughput:                     0.07 MB/sec
Concurrency:                   42.06
Successful transactions:         688
Failed transactions:               0
Longest transaction:           71.06
Shortest transaction:           0.00
```

## CentOS
### 不要サービスの停止
以下のコマンドでサービスの一覧が確認出来ます。

```bash
systemctl list-units --type=service
```
```text:出力例
UNIT                               LOAD   ACTIVE SUB     DESCRIPTION
auditd.service                     loaded active running Security Auditing Service
crond.service                      loaded active running Command Scheduler
dbus.service                       loaded active running D-Bus System Message Bus
firewalld.service                  loaded active running firewalld - dynamic firewall daemon
getty@tty1.service                 loaded active running Getty on tty1
httpd.service                      loaded active running The Apache HTTP Server
kdump.service                      loaded active exited  Crash recovery kernel arming
kmod-static-nodes.service          loaded active exited  Create list of required static device nodes for the current kernel
lvm2-lvmetad.service               loaded active running LVM2 metadata daemon
lvm2-monitor.service               loaded active exited  Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
lvm2-pvscan@8:2.service            loaded active exited  LVM2 PV scan on device 8:2
mysqld.service                     loaded active running MySQL Server
network.service                    loaded active exited  LSB: Bring up/down networking
NetworkManager.service             loaded active running Network Manager
polkit.service                     loaded active running Authorization Manager
postfix.service                    loaded active running Postfix Mail Transport Agent
psacct.service                     loaded active exited  Kernel process accounting
rhel-dmesg.service                 loaded active exited  Dump dmesg to /var/log/dmesg
rhel-import-state.service          loaded active exited  Import network configuration from initramfs
rhel-readonly.service              loaded active exited  Configure read-only root support
rsyslog.service                    loaded active running System Logging Service
sshd.service                       loaded active running OpenSSH server daemon
systemd-journal-flush.service      loaded active exited  Flush Journal to Persistent Storage
systemd-journald.service           loaded active running Journal Service
systemd-logind.service             loaded active running Login Service
systemd-random-seed.service        loaded active exited  Load/Save Random Seed
systemd-remount-fs.service         loaded active exited  Remount Root and Kernel File Systems
systemd-sysctl.service             loaded active exited  Apply Kernel Variables
systemd-tmpfiles-setup-dev.service loaded active exited  Create Static Device Nodes in /dev
systemd-tmpfiles-setup.service     loaded active exited  Create Volatile Files and Directories
systemd-udev-trigger.service       loaded active exited  udev Coldplug all Devices
systemd-udevd.service              loaded active running udev Kernel Device Manager
systemd-update-utmp.service        loaded active exited  Update UTMP about System Boot/Shutdown
systemd-user-sessions.service      loaded active exited  Permit User Sessions
systemd-vconsole-setup.service     loaded active exited  Setup Virtual Console
tuned.service                      loaded active running Dynamic System Tuning Daemon
wpa_supplicant.service             loaded active running WPA Supplicant daemon

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

37 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
```

### Tuned
デフォルトの virtual-guest から throughput-performance にプロファイルを変更してみましたが、VirtualBox 上ではパフォーマンスが向上しませんでした。

```bash
tuned-adm list
```
```text:出力例
Available profiles:
- balanced
- desktop
- latency-performance
- network-latency
- network-throughput
- powersave
- throughput-performance
- virtual-guest
- virtual-host
Current active profile: virtual-guest
```
```bash
tuned-adm profile throughput-performance
```


## Apache
### MaxRequestWorkers (MaxClients) の調整
apachetuner.php という MaxRequestWorkers 適正値自動計算スクリプトを作成しました。近いうちに GitHub などで公開できればと思います。

```bash
php apachetuner.php
```
Siege で負荷を掛けて実行した結果が以下の通りです。余裕を見て 96 あたりが無難でしょうか。

```
カーネル名:       Linux
カーネルバージョン: 3.10.0-327.36.3.el7.x86_64
Apacheバージョン:  2.4.6
Apache MPM:      prefork
物理メモリ:        1840.01 MB
利用可能メモリ:     964.04 MB
Apache
 全プロセス使用メモリ:       429.37 MB
 子プロセス起動数:         10
 親プロセス使用メモリ:       45.79 MB
 子プロセス合計共有メモリ:   383.585 MB
 子プロセス最小共有メモリ:   37.45 MB
 子プロセス最大非共有メモリ: 8.34 MB (親プロセスメモリ - 子プロセス最小共有メモリ)
 MaxRequestWorkers最大値: 110 (使用可能メモリ / 子プロセス最大非共有メモリ)
５６
PID           	6388*	8358	8359	8360	22228	22229	22230	22234	22267	22296	22343
Size          	658048	665964	668012	665964	665964	665844	667892	665852	665868	663916	665916
Rss           	46888	52324	54552	54752	48988	48884	51036	48928	48904	46928	48872
Pss           	20251	15131	17219	17321	13930	13835	15986	13878	13855	11878	13824
Shared        	31188	41232	41472	41660	38356	38344	38344	38344	38344	38344	38344
Shared_Ratio  	66	78	76	76	78	78	75	78	78	81	78
Shared_Clean  	10016	6844	6844	6844	6600	6596	6596	6596	6596	6596	6596
Shared_Dirty  	21172	34388	34628	34816	31756	31748	31748	31748	31748	31748	31748
Private       	15700	11092	13080	13092	10632	10540	12692	10584	10560	8584	10528
Private_Ratio 	33	21	23	23	21	21	24	21	21	18	21
Private_Clean 	1428	0	0	0	0	0	0	0	0	0	0
Private_Dirty 	14272	11092	13080	13092	10632	10540	12692	10584	10560	8584	10528
Referenced    	42184	45192	47416	47608	41792	41664	43844	41712	41700	39764	41736
Anonymous     	17500	25144	27252	25116	25208	25116	27268	25160	25136	23160	25100
KernelPageSize	3484	3496	3496	3496	3496	3496	3496	3496	3492	3492	3492
MMUPageSize   	3484	3496	3496	3496	3496	3496	3496	3496	3492	3492	3492
```

詳しくは「[Apache の MaxClients の適正値](http://qiita.com/bezeklik/items/14e27417f9cc93ca7222)」を参照してください。

### mod_deflate
mod_deflate でコンテンツを圧縮します。
今回は /mtc.js が 129000 bytes から 43068 bytes と 33% 程度、 /themes/skyline/css/skyline.css が 1605 bytes から 686 bytes と 43% 程度に圧縮されたようです。

```bash
cat << "_EOF_" > /etc/httpd/conf.d/mod_deflate.conf
<IfModule deflate_module>
    # 圧縮率の設定
    DeflateCompressionLevel 1
    <Location />
        BrowserMatch ^Mozilla/4 gzip-only-text/html
        BrowserMatch ^Mozilla/4\.0[678] no-gzip
        BrowserMatch \bMSIE\s(7|8) !no-gzip !gzip-only-text/html

        # 画像等は再圧縮させない
        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary

        # プロキシサーバに圧縮済みのキャッシュを送信する対象を制限
        Header append Vary Accept-Encoding env=!dont-vary

        # 圧縮するファイルのMimeTypeをmod_filterを使って指定
        FilterDeclare Compression CONTENT_SET
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'text/html'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'text/plain'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'text/css'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'text/javascript'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'text/xml'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'application/xhtml'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'application/xml'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'application/xhtml+xml'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'application/rss+xml'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'application/atom+xml'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'application/javascript'"
        FilterProvider Compression DEFLATE "%{CONTENT_TYPE} = 'image/svg-xml'"
        FilterChain Compression
    </Location>
</IfModule>
_EOF_
```

## MySQL
### MySQLTuner
```
curl -sL mysqltuner.pl -o mysqltuner.pl
perl mysqltuner.pl
```

## PHP
### Zend OPCache + APCu
PHP アクセラレーターの Zend OPCache と APCu をインストールします。

```
yum install php-opcache php-pecl-apcu
```

パフォーマンスは2倍ちょっと向上するようです。

```
Transactions:                   1141 hits
Availability:                 100.00 %
Elapsed time:                  59.10 secs
Data transferred:              20.15 MB
Response time:                  0.48 secs
Transaction rate:              19.31 trans/sec
Throughput:                     0.34 MB/sec
Concurrency:                    9.32
Successful transactions:         850
Failed transactions:               0
Longest transaction:            3.37
Shortest transaction:           0.00
```

### php-fpm

FPM (FastCGI Process Manager) は PHP の FastCGI 実装のひとつで、以下のようにインストールしてみます。

```
yum install php-fpm
cat << "_EOF_" > /etc/httpd/conf.d/php_fpm.conf
<FilesMatch \.php$>
    SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
_EOF_
systemctl start php-fpm && systemctl enable php-fpm
```

今回のケースでは php-fpm を入れるとパフォーマンスが低下するようです。

```
Transactions:                    944 hits
Availability:                 100.00 %
Elapsed time:                  59.82 secs
Data transferred:              19.89 MB
Response time:                  0.60 secs
Transaction rate:              15.78 trans/sec
Throughput:                     0.33 MB/sec
Concurrency:                    9.41
Successful transactions:         842
Failed transactions:               0
Longest transaction:            3.64
Shortest transaction:           0.00
```

### Memcached
```
yum install memcached php-pecl-memcached
sed -i '/session.save/s/^;//' /etc/php.d/50-memcached.ini
systemctl start memcached && systemctl enable memcached
```

Mautic (Symfony) 側で設定が上書きされて Memcached を使ってくれていないようで、パフォーマンスが低下します。config.yml も見当たらないので今回は断念します。

```
Transactions:                    943 hits
Availability:                 100.00 %
Elapsed time:                  59.14 secs
Data transferred:              19.78 MB
Response time:                  0.59 secs
Transaction rate:              15.95 trans/sec
Throughput:                     0.33 MB/sec
Concurrency:                    9.44
Successful transactions:         843
Failed transactions:               0
Longest transaction:            3.39
Shortest transaction:           0.00
```

# セキュリティ設定
セキュリティ対策を行うとどうしてもサーバーのパフォーマンスは落ちるので、無理に全てをサーバーないで行わなくても良いかもしれません。

## CentOS

### 各種設定
Lynis でサジェストされる内容に以下のように対応します。
詳細は「[Linuxセキュリティ監査ツール Lynis](http://qiita.com/bezeklik/items/cf9be2deb546c69123e7)」を参照してください。

```bash
sed -i.org "s/#smtpd_banner = \$myhostname ESMTP \$mail_name$/smtpd_banner = \$myhostname ESMTP/" /etc/postfix/main.cf
sed -i.org 's/PASS_MIN_DAYS\t0/PASS_MIN_DAYS\t1/' /etc/login.defs
sed -i 's/PASS_MAX_DAYS\t99999/PASS_MAX_DAYS\t3650/' /etc/login.defs
sed -i.org "s/umask 002/umask 027/" /etc/profile
sed -i "s/umask 022/umask 027/" /etc/profile
echo "blacklist usb-storage" > /etc/modprobe.d/blacklist-usbstorage.conf
echo "blacklist firewire_core" > /etc/modprobe.d/blacklist-firewire.conf
echo "blacklist firewire_ohci" >> /etc/modprobe.d/blacklist-firewire.conf
sed -i '/::1/s/^/#/' /etc/hosts
yum install yum-utils arpwatch psacct sysstat
systemctl enable arpwatch psacct && systemctl start arpwatch psacct
sed -i.org 's/#AllowTcpForwarding yes/AllowTcpForwarding no/' /etc/ssh/sshd_config
sed -i 's/#ClientAliveCountMax 3/ClientAliveCountMax 2/' /etc/ssh/sshd_config
sed -i 's/#Compression delayed/Compression no/' /etc/ssh/sshd_config
sed -i 's/#LogLevel INFO/LogLevel VERBOSE/' /etc/ssh/sshd_config
sed -i 's/#MaxAuthTries 6/MaxAuthTries 1/' /etc/ssh/sshd_config
sed -i 's/#MaxSessions 10/MaxSessions 2/' /etc/ssh/sshd_config
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#Port 22/Port 10022/' /etc/ssh/sshd_config
sed -i 's/#TCPKeepAlive yes/TCPKeepAlive no/' /etc/ssh/sshd_config
sed -i 's/#UseDNS yes/UseDNS no/' /etc/ssh/sshd_config
sed -i 's/X11Forwarding yes/X11Forwarding no/' /etc/ssh/sshd_config
sed -i 's/#AllowAgentForwarding yes/AllowAgentForwarding no/' /etc/ssh/sshd_config
(echo; echo "Unauthorized access to this machine is prohibited."; echo "Disconnect now if you are not an authorized user."; echo) > /etc/issue
(echo; echo "Unauthorized access to this machine is prohibited."; echo "Disconnect now if you are not an authorized user."; echo) > /etc/issue.net
lynis --quick --verbose --tests KRNL-6000
grep "different value" /var/log/lynis.log | awk '{ gsub("Expected",""); gsub(",",""); print $6 $16 }'
grep "different value" /var/log/lynis.log | awk '{ gsub("Expected",""); gsub(",",""); print $6 $16 }' >> /etc/sysctl.conf
sysctl -p
lynis --quick --verbose --tests HRDN-7222
grep "world executable" /var/log/lynis.log | awk '{ print $5 }' | xargs ls -l
grep "world executable" /var/log/lynis.log | awk '{ print $5 }' | xargs chmod 700
yum install epel-release && yum update
yum install rkhunter unhide
rkhunter -c --rwo --sk
```

### Fail2ban
ブルートフォース攻撃対策に Fail2ban をインストールします。
詳細は「[ブルートフォース攻撃対策 Fail2ban](http://qiita.com/bezeklik/items/75d93d6bb1770bfa7c2e)」や「[DoS攻撃/ブルートフォース攻撃対策アプリの近況](http://qiita.com/bezeklik/items/6d86a162e278f576e4ca)」を参照してください。

### NIDS
ネットワーク型侵入検知システム (NIDS) として **Suricata** をインストールします。

### HIDS
ホスト型侵入検知システム (HIDS) として **OSSEC** をインストールします。
詳細は「[ファイル改ざん検知ツール OSSEC](http://qiita.com/bezeklik/items/2143c02f1432d90f5c38)」を参照してください。

## Apache
### 設定ファイル (conf)
詳しくは「[Apacheセキュリティ設定](http://qiita.com/bezeklik/items/1c4145652661cf5b2271)」を参照してください。

```bash
cat /dev/null > /etc/httpd/conf.d/autoindex.conf
cat /dev/null > /etc/httpd/conf.d/welcome.conf
```
```apache
cat << _EOF_ > /etc/httpd/conf.d/security.conf
# バージョン情報の隠蔽
ServerTokens Prod 
Header unset X-Powered-By
# httpoxy 対策
RequestHeader unset Proxy
# クリックジャッキング対策
Header append X-Frame-Options SAMEORIGIN
# XSS対策
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options nosniff
# XST対策
TraceEnable Off

<Directory /var/www/html>
    # .htaccess の有効化
    AllowOverride All
    # ファイル一覧出力の禁止
    Options -Indexes
    # Apache 2.2以前の対策
    <IfVersion < 2.3>
        # バージョン情報の隠蔽
        ServerSignature Off
        # ETagのinode情報の隠蔽
        FileETag MTime Size
    </IfVersion>
</Directory>
_EOF_
```
```apache
cat << _EOF_ > /etc/httpd/conf.d/security_strict.conf
# DoS 攻撃対策
LimitRequestBody 10485760
LimitRequestFields 20
# slowloris 対策
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500

<Directory /var/www/html>
    # HTTPメソッドの制限
    <IfVersion > 2.4>
        Require method GET POST
    </IfVersion>
    <IfVersion < 2.3>
        <Limit GET POST>
            Order allow,deny
            Allow from all
        </Limit>
        <LimitExcept GET POST>
            Order deny,allow
            Deny from all
        </LimitExcept>
    </IfVersion>
</Directory>
_EOF_
```

### mod_evasive
詳しくは「[DoS攻撃対策モジュール mod_evasive](http://qiita.com/bezeklik/items/b3db4c0d5487f7120e73)」を参照してください。

### mod_qos
詳しくは「[帯域制限モジュール mod_qos](http://qiita.com/bezeklik/items/a6d95cc03df49ea15381)」を参照してください。

### ModSecurity (mod_security)
WAF として ModSecurity をインストールします。
詳しくは「[オープンソースWAF ModSecurity](http://qiita.com/bezeklik/items/76bf942f4a9e0a2919d8)」を参照してください。

```
cat << "_EOF_" >> /etc/httpd/conf.d/mod_security_rule_mautic.conf
SecRuleRemoveById 950911
SecRuleRemoveById 981173
SecRuleRemoveById 981242
SecRuleRemoveById 981243
SecRuleRemoveById 981245
SecRuleRemoveById 981257
_EOF_
```

## MySQL
### mysql_secure_installation
`mysql_secure_installation` コマンドを実行すると、セキュリティ対策として以下の内容を実施できます。

* root パスワード変更
* 匿名ユーザーの削除
* リモートからの root ユーザーでのログイン禁止
* test データベースの削除
* 特権テーブルのリロード

```bash
Securing the MySQL server deployment.

Enter password for user root:

The existing password for the user account root has expired. Please set a new password.

New password:

Re-enter new password:
The 'validate_password' plugin is installed on the server.
The subsequent steps will run with the existing configuration
of the plugin.
Using existing password for root.

Estimated strength of the password: 100
Change the password for root ? ((Press y|Y for Yes, any other key for No) : # 100なら空エンター

 ... skipping.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y # 匿名ユーザーの削除
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y # リモートrootログイン禁止
Success.

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y # testデータベースの削除
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y # 特権テーブルのリロード
Success.

All done!
```

## PHP
### 設定ファイル
詳細は追って別の記事にまとめたいと思います。
設定することで多少パフォーマンスが落ちます。

```ini
cat << _EOF_ > /etc/php.d/99-security.ini
date.timezone = Asia/Tokyo           ; タイムゾーンの設定 (デフォルト: GMT) PHP 5.1.0 ~
display_errors = Off                 ; エラー出力 (デフォルト: 1)
enable_dl = Off                      ; dl()の禁止 (デフォルト: 1)
expose_php = Off                     ; HTTPヘッダのPHPバージョンの非表示 (デフォルト: 1)
log_errors_max_len = 4096            ; エラーログの出力制限の拡大 (デフォルト: 1024)
session.cookie_httponly = On         ; JavaScriptのCookie読み込み禁止 (デフォルト: "")
session.hash_function = sha512       ; セッションID生成アルゴリズムの強化 (デフォルト: 0)
session.hash_bits_per_character = 6  ; セッションIDの使用可能文字を増やす (デフォルト: 4)
_EOF_
```
```ini
cat << _EOF_ > /etc/php.d/99-security-encoding.ini
default_charset = UTF-8
output_buffering = Off
mbstring.encoding_translation = On
mbstring.http_input = UTF-8
mbstring.http_output = pass
mbstring.internal_encoding = UTF-8
mbstring.language = Japanese
mbstring.substitute_character = "?"
_EOF_
```
```ini
cat << "_EOF_" > /etc/php.d/99-security-strict.ini
; ファイルアップロード
;file_uploads = Off                   ; HTTP ファイルアップロード (デフォルト: 1)
max_file_uploads = 1                 ; 同時アップロードファイル最大数 (デフォルト: 20)

; タイムアウト
default_socket_timeout = 20          ;  (デフォルト: 60)
max_execution_time = 20              ; 1リクエストあたりの最大実行時間（秒） (デフォルト: 30)
max_input_time = 20                  ;  (デフォルト: -1)

; 上限設定
max_input_nesting_level = 10         ; (デフォルト: 64)
max_input_vars = 100                 ; (デフォルト: 1000)
memory_limit = 64M                   ; 1リクエストあたりの最大メモリ使用量 (デフォルト: 128M)
post_max_size = 4M                   ; POSTリクエストの許容サイズ (デフォルト: 8M)
upload_max_filesize = 1M             ; ファイルアップロードの許容サイズ (デフォルト: 2M)

mbstring.strict_detection = On       ; 厳格なエンコーディング検出 (デフォルト: 0)
;session.cookie_secure = 1            ; (デフォルト: "")
open_basedir = /usr/share/:/var/www/ ; (デフォルト: NULL)
allow_url_fopen = Off                ;  (デフォルト: 1)
allow_url_include = Off              ;  (デフォルト: 0) PHP 5.2.0 ~
disable_functions = phpinfo,eval     ; 指定システム関数の禁止 (デフォルト: "")
session.name = SECUREID              ; 	(デフォルト: PHPSESSID)
_EOF_
```

### Suhosin
Remi リポジトリーでは PHP セキュリティ強化モジュールの Suhosin がパッケージ化されているのでこれをインストールします。
ただし PHP 7.x 用の suhosin7 の README には、プレアルファ版なので本番環境では使用しないようにとの注意書きがあります。

以下はデフォルトの設定値です。

```
suhosin.cookie.checkraddr => 0 => 0
suhosin.cookie.cryptdocroot => On => On
suhosin.cookie.cryptkey => [ protected ] => [ protected ]
suhosin.cookie.cryptlist => no value => no value
suhosin.cookie.cryptraddr => 0 => 0
suhosin.cookie.cryptua => On => On
suhosin.cookie.disallow_nul => 1 => 1
suhosin.cookie.disallow_ws => 1 => 1
suhosin.cookie.encrypt => Off => Off
suhosin.cookie.max_array_depth => 50 => 50
suhosin.cookie.max_array_index_length => 64 => 64
suhosin.cookie.max_name_length => 64 => 64
suhosin.cookie.max_totalname_length => 256 => 256
suhosin.cookie.max_value_length => 10000 => 10000
suhosin.cookie.max_vars => 100 => 100
suhosin.cookie.plainlist => no value => no value
suhosin.coredump => Off => Off
suhosin.disable.display_errors => Off => Off
suhosin.executor.allow_symlink => Off => Off
suhosin.executor.disable_emodifier => Off => Off
suhosin.executor.eval.blacklist => no value => no value
suhosin.executor.eval.whitelist => no value => no value
suhosin.executor.func.blacklist => no value => no value
suhosin.executor.func.whitelist => no value => no value
suhosin.executor.include.allow_writable_files => On => On
suhosin.executor.include.blacklist => no value => no value
suhosin.executor.include.max_traversal => 0 => 0
suhosin.executor.include.whitelist => no value => no value
suhosin.executor.max_depth => 750 => 750
suhosin.get.disallow_nul => 1 => 1
suhosin.get.disallow_ws => 0 => 0
suhosin.get.max_array_depth => 50 => 50
suhosin.get.max_array_index_length => 64 => 64
suhosin.get.max_name_length => 64 => 64
suhosin.get.max_totalname_length => 256 => 256
suhosin.get.max_value_length => 512 => 512
suhosin.get.max_vars => 100 => 100
suhosin.log.file => 0 => 0
suhosin.log.file.name => no value => no value
suhosin.log.file.time => On => On
suhosin.log.sapi => 0 => 0
suhosin.log.stdout => 0 => 0
suhosin.log.use-x-forwarded-for => Off => Off
suhosin.memory_limit => 0 => 0
suhosin.mt_srand.ignore => On => On
suhosin.multiheader => Off => Off
suhosin.perdir => 0 => 0
suhosin.post.disallow_nul => 1 => 1
suhosin.post.disallow_ws => 0 => 0
suhosin.post.max_array_depth => 50 => 50
suhosin.post.max_array_index_length => 64 => 64
suhosin.post.max_name_length => 64 => 64
suhosin.post.max_totalname_length => 256 => 256
suhosin.post.max_value_length => 1000000 => 1000000
suhosin.post.max_vars => 1000 => 1000
suhosin.protectkey => On => On
suhosin.rand.reseed_every_request => Off => Off
suhosin.rand.seedingkey => [ protected ] => [ protected ]
suhosin.request.array_index_char_blacklist => '"+<>;() => '"+<>;()
suhosin.request.array_index_char_whitelist => no value => no value
suhosin.request.disallow_nul => 1 => 1
suhosin.request.disallow_ws => 0 => 0
suhosin.request.max_array_depth => 50 => 50
suhosin.request.max_array_index_length => 64 => 64
suhosin.request.max_totalname_length => 256 => 256
suhosin.request.max_value_length => 1000000 => 1000000
suhosin.request.max_varname_length => 64 => 64
suhosin.request.max_vars => 1000 => 1000
suhosin.server.encode => On => On
suhosin.server.strip => On => On
suhosin.session.checkraddr => 0 => 0
suhosin.session.cryptdocroot => On => On
suhosin.session.cryptkey => [ protected ] => [ protected ]
suhosin.session.cryptraddr => 0 => 0
suhosin.session.cryptua => Off => Off
suhosin.session.encrypt => On => On
suhosin.session.max_id_length => 128 => 128
suhosin.simulation => Off => Off
suhosin.srand.ignore => On => On
```

上手くいかない場合はシミュレーションモードに変更してみましょう。

```bash
cat << "_EOF_" >> /etc/php.d/40-suhosin7.ini
suhosin.simulation = On
_EOF_
```

詳しくは「[PHPセキュリティ強化モジュール Suhosin](http://qiita.com/bezeklik/items/5e8b1f76465e39dc6cd0)」を参照してください。