PHP-FPMでchrootを設定すると分離効果が高く、システムのセキュリティが向上しますが、リーズナブルなPHPを確立したい場合は、 FPM Chroot 環境 debootstrap などを使って作成するよりも少し難しくて面倒ですが、関連情報を参考にしながら PHP-FPM の Chroot 実行環境を整理して皆さんに共有します。
この記事では、Ubuntu 14.04.2 を例として取り上げます。php-fpm は、ppa:ondrej/php5-5.6 によって提供される PHP5.6 バージョンを使用します。これは、システムと Debian の php-fpm およびシステム ディレクトリ構造と一致している必要があります。システム。 CentOSの調整はご自身で行ってください。
php-fpm の chroot 環境設定は、使用されるサーバー フロントエンドとは関係がなく、chroot を実行するために Apache/Nginx も必要ありません。もちろん、その方が安全ですが、より複雑です。
1. ディレクトリ構造を作成します
chroot のディレクトリ選択は /var/www/chroot で、ページ ファイルは /var/www/chroot/public に配置されます。
次のコマンドを実行して、基本的なディレクトリ構造を確立します:
リーリー現時点でのディレクトリ構造は次のとおりで、後でいくつかの新しいものが追加される予定です:
リーリー注1: このソフトリンクは、Apache/nginxによってphp-fpmに渡されたSCRIPT_FILENAMEがchrootに入った後にファイルが見つからない(phpページにアクセスすると「ファイルが見つかりません」が返される)という問題を解決するために使用されます。
nginx を例に挙げると、通常は SCRIPT_FILENAME を $document_root$fastcgi_script_name に設定し、php-fpm に渡されるスクリプト パスは /var/www/chroot/public/index.php です。 php-fpm は chroot 環境にあるため、実際にアクセスしようとするパスは /var/www/chroot + /var/www/chroot/public/index.php になりますが、もちろんこれは存在しません。
そこで、ソフト接続を使用して chroot 環境の /var/www/chroot をルート ディレクトリにリンクすると、スクリプトに正常にアクセスできるようになります。
もちろん、SCRIPT_FILENAME を /public$fastcgi_script_name に設定することもできます。ただし、このようなハードコーディングは構成の移行には役に立たず、chroot 環境でのみ使用できます。非 chroot 環境に戻す場合は、構成を変更する必要があります。したがって、これを行うことはお勧めできません。 (ちなみに、$document_root を使用せず、ルート ディレクトリを直接ハードコーディングする古いチュートリアルがたくさんありますが、これはもちろんお勧めできません)
注 2: chroot 環境は 100% 安全ではありません。 chroot 環境での php-fpm の実行権限は www-data であるため、不要なアクセス権限を減らすために、必須でないディレクトリの所有者を root に設定することをお勧めします。 chroot はセキュリティと同等ではありません。chroot のベスト プラクティスにリストされているいくつかの原則を参照してください。より安全な観点から、bin、lib、sbin およびその他のディレクトリの読み取りおよび書き込み権限を削除し、実行可能権限のみを残すのが最善ですが、大きな違いはありません...
注 3: cp -a は、ファイルの内容をコピーするだけでなく、ファイルのアクセス許可、モード、その他の情報もコピーします。これを使用すると、0、urandom、null の 3 つの主要なデバイス ファイルを直接コピーできます。 mknod の方が信頼性の高い方法のようですが、cp -a を使用しても問題ないようです。
注 4: chmod --reference=XXX は、後続の権限を設定するために XXX の権限を参照します。 tmp については触れません。重要なのは、次の var/lib/php5/sessions が PHP がセッション ファイルを保存するディレクトリであり、www-data には読み取りおよび書き込み権限が必要であるということです。設定後に見てみることをお勧めします。もちろんこの後テストもあります。
2.PHP-FPM構成
新しい php-fpm 実行プールを作成して chroot 環境を構築します。 php-fpm.conf を直接変更することはお勧めできません。これは、複数の PHP サイトが存在する場合、chroot 環境を共有することになるためです。
実際、多くの php-fpm チュートリアルは php-fpm プールの設定を無視しています。そのため、多くの人がサーバー上のすべてのサイトの設定セット、特に php.ini 設定セットを共有することになりますが、これは実際には不合理です。の。プールはサイトのニーズに応じて個別に作成し、その中でパラメーターを調整する必要があります。
/etc/php5/fpm/pool.d/ の下に新しい chroot.conf を作成します (php-fpm.conf によって呼び出されるように、.conf で終わる必要があることに注意してください)。 リーリー
前のパラメータはすべておなじみのものです。 chroot を有効にするには、構成された環境のルート ディレクトリに chroot を設定するだけです。 php5-fpm -t を実行してテストした後、service php5-fpm reload を使用して新しいプールを有効にします。もちろん、バックエンドは Apache/nginx の対応する構成でセットアップする必要があります。最後の数行について言及します。最後から 4 行目では、display_errors をオンにして、後で chroot で PHP の機能をテストできるようにします。テスト後に必ずコメントアウトしてください。
session.gc_probability を設定して、PHP プロセスがセッションを独自に削除してリサイクルできるようにします。通常、セッションはPHPが追加したcronタスクによってクリーンアップされますが、chroot環境ではPHPが自動的にセッションをクリーンアップしてくれないようです。もちろん、自動的に実行されるスクリプトを cron.d に追加して自分でクリーンアップすることもできるため、このオプションをオンにする必要はありません。
3. Chroot環境でのPHPの各種機能を修復します
/var/www/chroot/public に新しい test.php を作成し、次の内容を記述します:
コードをコピーします コードは次のとおりです:
php
b41514798f15c18d234516bfbaf46c4f (0x00007fff779fe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f165620f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f16567fc000)
第一条那个只列了个文件名,=>后面也没有文件的基本上都是不用管的。剩下的库文件基本的原则是如果列出的是/lib64,就拷贝到chroot环境下的/lib64,如果列出的是/lib,虽然有很多发行版,大部分库文件包括libc.so是在/lib/x86_64-linux-gnu/目录下的,也直接拷贝到chroot环境的/lib目录下即可,是可以正常找到的。
但是!
前面那句 “必须存在/bin/sh,一个基本的shell” 其实并不是真的,对于mail()只要有一个能接受-c参数调用后面的命令的程序就可以了。所以Kienzl写了这样一个程序:
c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define MAXARG 64 int main( int argc, char* const argv[] ) { char* args[ MAXARG ] = {}; if( argc < 3 || strcmp( argv[1], "-c" ) != 0 ) { fprintf( stderr, "Usage: %s -c <cmd>\n", argv[0] ); return 1; } { char* token; int i = 0; char* argStr = strdup( argv[2] ); while( ( token = strsep( &argStr, " " ) ) != NULL ) { if( token && strlen( token ) ) args[ i++ ] = token; if( i >= MAXARG ) return 2; } } return execvp( args[0], args ); }
保存成sh.c执行: gcc sh.c -o sh -static 然后把sh拷贝到chroot环境的/bin目录下即可。
这样一个不完全的shell从一定程度上也算是增强了chroot环境的安全性了。
方法1:使用mini_sendmail
mini_sendmail似乎专为chroot环境而生。调用mini_sendmail后,它会转而访问本机的25端口,通过本机的邮件服务来发送邮件。所以如果主环境有安装postfix/exim4等邮件服务的话可以使用mini_sendmail来在chroot环境中发送邮件,这是最简单的方法。
mini_sendmail的安装很简单:
复制代码 代码如下:
bash
wget http://www.acme.com/software/mini_sendmail/mini_sendmail-1.3.8.tar.gz
tar zxf mini_sendmail-1.3.8.tar.gz
cd mini_sendmail-1.3.8
make
cp mini_sendmail /var/www/chroot/usr/sbin/sendmail
最后一行自行修改chroot环境的目录。切记要拷贝到chroot环境的/usr/sbin目录下并且命名为sendmail。否则的话要在pool里自行设置ini参数的sendmail_path来指导php找到sendmail程序。
由于mini_sendmail默认就是静态链接,所以也无需拷贝其它的库文件了。
方法2:使用ssmtp/msmtp
对于本机没有安装邮件服务的情况,就不能使用mini_sendmail了。ssmtp和msmtp都支持把接收到的邮件发送请求转而通过其它SMTP服务器来发送。需要注意的是由于ssl支持需要更多更复杂的库文件和配置,所以不建议为两者编译ssl支持……下面以ssmtp为例介绍一下。
bash wget ftp://ftp.debian.org/debian/pool/main/s/ssmtp/ssmtp_2.64.orig.tar.bz2 tar jxf ssmtp_2.64.orig.tar.bz2 cd ssmtp_2.64 ./configure --prefix=/ #别忘了prefix make #千万别手抖make install cp ssmtp /var/www/chroot/usr/sbin mkdir -p /var/www/chroot/etc/ssmtp cp ssmtp.conf revaliases /var/www/chroot/etc/ssmtp #配置文件 cd /var/www/chroot/usr/sbin ln -s ssmtp sendmail
同样记得ldd然后把对应的库文件拷贝过去。另外ssmtp需要/etc/passwd和/etc/group,如果上面没有使用nscd需要拷贝/伪造这两个文件。
ssmtp需要配置。ssmtp.conf文件配置如下:
bash root=admin@example.com #其实这行好像可以乱写 mailhub=smtp.example.com #smtp服务器地址 hostname=myexample.com #此处的hostname似乎会用于产生默认的“root@myexample.com”形式的发件人地址 AuthUser=admin@example.com #此处使用真实的登录用户名 AuthPass=password #密码 FromLineOverride=YES #允许改写发件人
revaliases里配置每个用户在使用ssmtp时使用的“发件人”地址和smtp服务器地址。可以不配置,但是文件要有。具体格式是:
复制代码 代码如下:
bash
# 本地用户名:发件人地址:smtp服务器[:端口(默认25)]
root:admin@example.com:smtp.example.com
www-data:noreply@example.com:smtp.example.com
可以使用chroot(指真正的chroot命令)做个测试:
复制代码 代码如下:
bash
chroot /var/www/chroot /bin/sh #此时/bin/sh一定要是真正的shell
echo "Subject: test"|sendmail -v username@server.com #替换邮件地址为自己的
此时php的mail()函数应该就可用了。
4.其它问题
配置完chroot环境后记得将php的pool设置里display_error关闭。
MySQL的连接可能会遇到问题 ,因为如果填写localhost的话php会试图寻找MySQL的unix socket来访问mysqld。填写127.0.0.1通过TCP连接就没有问题了
完成后的目录结构,以我为例给大家参考一下:
/var/www/chroot/ ├── bin │ └── sh ├── dev │ ├── null │ ├── urandom │ └── zero ├── etc │ └── ssmtp │ ├── revaliases │ └── ssmtp.conf ├── lib │ └── libc.so.6 ├── lib64 │ └── ld-linux-x86-64.so.2 ├── public ├── tmp ├── usr │ ├── sbin │ │ ├── sendmail -> ssmtp | │ └── ssmtp │ └── share │ └── zoneinfo │ ├── 大量时区的目录结构 │ └── zone.tab └── var ├── lib │ └── php5 │ └── sessions ├── run │ └── nscd │ ├── nscd.pid │ └── socket └── www └── chroot -> ../..
以上就是本文的全部内容,希望大家喜欢。