位置: 编程技术 - 正文

PHP-FPM之Chroot执行环境详解(php root)

编辑:rootadmin

推荐整理分享PHP-FPM之Chroot执行环境详解(php root),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:php root,php root,php cgi,php php-fpm,php-fpm cgi,php chroot,php chroot,php fpm cli,内容如对您有帮助,希望把文章链接给更多的朋友!

在PHP-FPM中设立chroot,有很好的隔离作用,提高系统安全性,但是要想建立一个合理的PHP-FPM Chroot环境难度有点大,比用debootstrap等工具建立还要麻烦,下面通过参考相关资料,把PHP-FPM之Chroot执行环境整理出来,分享给大家。

本文以Ubuntu ..2为例,php-fpm使用的是 ppa:ondrej/php5-5.6 提供的PHP5.6版本,跟系统自带以及Debian系统的php-fpm和系统目录结构应该是一致的。CentOS请自行调整。

php-fpm的chroot环境配置和所使用的服务器前端没有关联,也不强求Apache/Nginx进行chroot。当然那样更安全——也更复杂。

1.建立目录结构

chroot的目录选择为 /var/www/chroot ,其中页面文件放置在 /var/www/chroot/public 。

执行下面的命令建立基本的目录结构:

下面是此时目录结构,之后还会添加一些新的东西:

注1:这个软连接用于解决Apache/nginx传给php-fpm的 SCRIPT_FILENAME 在进入chroot后找不到文件(访问php页面返回"File not found")的问题。

以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环境并不是%安全的。由于php-fpm在chroot环境中的执行权限是www-data,仍然建议把非必要的目录的拥有者设置为root来减少不必要的访问权限。chroot不等于安全,参考 chroot最佳实践 中列出的一些原则。从更安全的角度上讲之后最好也将bin、lib、sbin等目录的读写权限去掉,只留可执行权限,不过也没大差别了……

注3:cp -a除了拷贝文件内容外也会复制文件的权限、模式等信息,可以很方便的直接拿来拷贝zero、urandom和null这三个关键的设备文件。mknod似乎是更为稳妥的方式,不过cp -a我使用起来似乎也没问题。

注4:chmod --reference=XXX会参考XXX的权限设置后面的权限。tmp就不提了,关键是后面的 var/lib/php5/sessions 是php存放session文件的目录,需要让www-data有读写的权限。建议设置完之后再看一眼。当然后面会有测试。

2.PHP-FPM的配置

建立一个新的php-fpm的执行pool来搭建chroot环境。并不建议直接修改php-fpm.conf,因为这样是全局生效的,如果有多个php站点的话会共用一套chroot环境。

其实很多php-fpm的教程都忽略了php-fpm的pool的配置,导致很多人一台服务器上所有站点都共用一套配置,尤其是共用一套php.ini的配置,实际上是不合理的。应当根据站点的需求单独建立pool并在其中调整参数。

在 /etc/php5/fpm/pool.d/ 下新建 chroot.conf (注意必须以.conf结尾,才能被php-fpm.conf调用):

前面的参数都比较熟悉了。只需要简单的设置chroot为配置好的环境根目录就可以开启chroot了。通过执行 php5-fpm -t 测试一下之后,用 service php5-fpm reload 即可启用新的pool。当然Apache/nginx对应的配置中要设置好后端。

提一下最后几行。倒数第四行打开了 display_errors ,以便之后对chroot下的php的功能进行测试,测试完了记得注释掉。

设置 session.gc_probability 允许php进程自行对session进行删除回收。正常情况下session是由php添加的cron任务清理的,但是似乎php不会自动清理chroot环境下的session。当然也可以自己在cron.d下添加自动执行的脚本来清理,就不用开启这个选项了。

3.修复Chroot环境下PHP的各项功能

在/var/www/chroot/public下新建一个test.php,写入以下内容:

这里主要测试的功能是:session、DNS解析、时间和日期、邮件mail()函数。

访问上面的测试页面,提示No such directory or file或者Permission denied说明session配置不正确。 gethostbyname 返回的不是.0.0.1或者::1,则说明DNS解析没有生效。提示 timezone database is corrupt 之类的,说明时间和日期有错误。mail()也会有各种错误提示。

session就不提了,设置好目录权限就没有问题。主要处理一下后面三个问题,也是php的chroot环境主要需要处理的内容。

3.1 域名解析/时区等问题

mail()的解决方法大同小异,放后面谈。前面的域名解析等问题这里我介绍两种解决方法。方法1是参考Kienzl的简便方法,方法2是大部分教程采用的方法。

方法1:使用nscd

nscd是(e)glibc的“Name Service Caching Daemon”。除了处理gethostbyname()这样的函数外,也处理getpwnam()等需要访问/etc/passwd的函数。(e)glibc访问nscd的unix socket, /var/run/nscd/socket 来通过nscd获取这些内容,如果不能连接到nscd则转而自行进行解析。

也就是说,只要装好nscd,并且让chroot环境里的程序能够访问到socket连接上nscd,就可以把chroot环境内的解析请求转由chroot外顺利进行了。由于/var/run一般是tmpfs,硬链接无法跨文件系统使用,所以可以使用 mount -bind 来把/var/run/nscd目录mount到chroot环境中同样的位置去即可。

同样的道理,用 mount -bind 把/usr/share/zoneinfo目录mount到chroot环境里,配合在php-fpm的pool里设置date.timezone就可以非常直接而暴力的解决时区问题。

先执行 apt-get install nscd 安装nscd,然后为了能够让 mount -bind 自动执行,把下面的脚本存为 /etc/init.d/php-chroot

执行 update-rc.d php-chroot defaults 来让脚本在启动时执行。如果有多个chroot环境以及多个目录需要bind-mount,可以自行添加一个循环改写。

PHP-FPM之Chroot执行环境详解(php root)

这个方法的好处是简单易行,不需要拷贝大量etc下的配置文件和库文件到chroot环境中。使用nscd在解决域名访问的问题过程中也顺道解决了/etc/passwd和/etc/group。但是bind-mount和nscd的安全性尚没有确切的说法,只能说so far so good。另外 mount -bind 会消耗一定的系统资源,有评论称大约一个mount 大概会消耗k内存,所以对于大量的chroot环境(几百个)不见得适合。

方法2:拷贝/etc配置文件和库文件

这是最传统而常用的方法,也相对比较复杂。到底拷贝哪些配置、哪些库文件因发行版和软件版本而异,很难有定论也不好调试。而且一旦系统升级,对应的库文件也需要进行更新,工作量很大。我没有采用这个方法,但是简要的介绍一些比较靠谱的方法分享一下。

域名解析。需要拷贝/etc/resolv.conf,/etc/hosts,/etc/nsswitch.conf到chroot环境下的etc目录下。还需要拷贝一系列的库文件,主要是libnss_*.so,libresolv.so,libsoftokn3.so。具体libnss_*.so拷贝哪些,可以打开nsswitch.conf看列出了哪些。

时区配置。拷贝/etc/localtime,/usr/share/zoneinfo/zone.tab,和/usr/share/zoneinfo目录下所使用时区的文件。

其它常用配置。/etc/passwd和/etc/group有时也是需要的,但是内容 似乎可以伪造 ,至少可以选择性的填写不用完全拷贝主系统里的。

如果使用的时候仍然出现问题,可以使用strace来查看php进行了哪些调用使用了哪些库文件。先执行:

查看pool的进程pid(可以在pool设置里先把子进程数目限制到1个方便调试)。然后执行:

bashstrace -p 进程pid -o chroot1.txt& #有多个子进程就修改pid执行多次,输出改为chroot2/3.txt存到不同文件里此时在页面里执行各种函数,然后查看输出文件里记录了哪些库文件,对应拷贝到chroot环境里即可。

这个方法很麻烦,尤其是第一次安装设置和后续系统更新时。当然身为运维人员写写shell脚本简化工作肯定是基本功了。这种方法没有额外的内存消耗,可以部署大量chroot环境,当然硬盘消耗会高一点,而且安全性也经历了长久的考验

3.2 修复mail()

如果是使用WordPress,也可以利用MailChimp等插件不使用系统自身的邮件服务。事实上因为垃圾邮件的标准日益严格,和VPS主机商的限制,我现在更倾向于干脆不在系统里部署邮件服务了,所以php的mail()函数算是被废掉了……当然如果需要的话也可以很简单的设置好的。

php的mail()函数是使用system()调用sendmail进行邮件发送操作,所以需要chroot环境里有能够调用的sendmail程序即可。常见的替代品是mini_sendmail,这里多介绍ssmtp,msmtp也类似。

前提:处理/bin/sh

system()调用产生的命令行是 /bin/sh -c command 。在chroot环境中调用外部程序必须存在/bin/sh,一个基本的shell。通常选择拷贝dash:

注意运行 ldd /bin/dash 观察需要拷贝哪些库文件。我这里的回显是:

第一条那个只列了个文件名,=>后面也没有文件的基本上都是不用管的。剩下的库文件基本的原则是如果列出的是/lib,就拷贝到chroot环境下的/lib,如果列出的是/lib,虽然有很多发行版,大部分库文件包括libc.so是在/lib/x_-linux-gnu/目录下的,也直接拷贝到chroot环境的/lib目录下即可,是可以正常找到的。

但是!

前面那句 “必须存在/bin/sh,一个基本的shell” 其实并不是真的,对于mail()只要有一个能接受-c参数调用后面的命令的程序就可以了。所以Kienzl写了这样一个程序:

保存成sh.c执行: gcc sh.c -o sh -static 然后把sh拷贝到chroot环境的/bin目录下即可。

这样一个不完全的shell从一定程度上也算是增强了chroot环境的安全性了。

方法1:使用mini_sendmail

mini_sendmail似乎专为chroot环境而生。调用mini_sendmail后,它会转而访问本机的端口,通过本机的邮件服务来发送邮件。所以如果主环境有安装postfix/exim4等邮件服务的话可以使用mini_sendmail来在chroot环境中发送邮件,这是最简单的方法。

mini_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为例介绍一下。

同样记得ldd然后把对应的库文件拷贝过去。另外ssmtp需要/etc/passwd和/etc/group,如果上面没有使用nscd需要拷贝/伪造这两个文件。

ssmtp需要配置。ssmtp.conf文件配置如下:

revaliases里配置每个用户在使用ssmtp时使用的“发件人”地址和smtp服务器地址。可以不配置,但是文件要有。具体格式是:

可以使用chroot(指真正的chroot命令)做个测试:

此时php的mail()函数应该就可用了。

4.其它问题

配置完chroot环境后记得将php的pool设置里display_error关闭。MySQL的连接可能会遇到问题 ,因为如果填写localhost的话php会试图寻找MySQL的unix socket来访问mysqld。填写.0.0.1通过TCP连接就没有问题了完成后的目录结构,以我为例给大家参考一下:

标签: php root

本文链接地址:https://www.jiuchutong.com/biancheng/284483.html 转载请保留说明!

上一篇:wampserver改变默认网站目录的办法(wamp设置)

下一篇:使用Thinkphp框架开发移动端接口(thinkphp框架流程原理)

  • 土地 税
  • 企业所得税和增值税重复收税了吗
  • 纳税申报期限是纳税期限期满后的时间
  • 完工产品成本计入什么科目
  • 核定征收的计算方法有哪些
  • 个体户核定征收需要做账吗
  • 进口消费税应该记到什么科目
  • 从事小额零星经营业务的个人是指
  • 误餐补助缴个税怎么申报
  • 公司注销投资款退回给股东,附言写什么
  • 医院纯收入
  • 制造费用的借方和贷方各表示什么
  • 留抵税额抵税怎么做分录
  • 实际发生坏账后要把计提的坏账冲回吗?
  • 长期股权投资收益会计处理
  • 单位定期存款如遇利率调整,不论调高调低
  • 餐馆的前期投资预算
  • 一般纳税人销售自己使用过的物品
  • 金税盘费用如何抵扣
  • 刷银行卡消费安全吗
  • 通用申报表个人所得税应税项怎么填
  • 发票丢失可以抵扣吗
  • 通用机打发票属于什么发票
  • 递延所得税收益计算公式
  • 个体虚开普通发票罪立案标准
  • 接受政府无偿划拨固定资产税务处理
  • 财务计提个人缴纳社保部分怎么记账?
  • 出口退税服务
  • 电脑温度过高会怎么样
  • 负债的情况
  • 先入费用后来发票怎么做账
  • Uncaught TypeError: XXX is not a function问题解决方法
  • PHP:xml_get_error_code()的用法_XML解析器函数
  • code ide
  • 公司报销之后钱发到哪
  • 个体工商户减免个人所得税政策
  • vscodehtml快捷键
  • 支付个人赔偿款入账
  • 抵债资产怎么入账
  • wordpress 批量添加标签
  • 设备调试费是什么税
  • 有下列情形之一的,当事人可以解除
  • 施工企业期间费用 企业管理费会计分录
  • 劳动报酬收入包含什么
  • 雇佣临时工需要交个人所得税吗
  • 计提工会经费会计分录怎么写
  • 购买电脑一次性计入费用吗合理吗
  • 房租季度付款是几个月
  • 现金短缺与溢余解析
  • 买车抵扣增值税超销项怎么算
  • 企业技术服务费有税前列支限额吗
  • 硕士研究生个税专项扣除
  • 股东出资转为借款
  • 收到其他公司往来款怎么做账
  • 润滑油开具增值税专用发票
  • 转账支票需要知道开户行吗
  • 企业大额融资需要什么资料
  • 对公账户提取备用金怎么做账
  • 对子公司的投资损失可以税前扣除吗
  • 加盟店直营店什么意思
  • 传统与现代的结合英文
  • win7不能运行应用程序的方法
  • jQuery扩展+xml实现表单验证功能的方法
  • node js php
  • unity3d改变物体坐标系
  • js 在线调试
  • bootstraprow布局
  • jQuery prototype冲突的2种解决方法(附demo示例下载)
  • node.js怎么用
  • Unity3D游戏开发(第2版)pdf
  • windows捕获文件夹
  • unity网络通信框架
  • jquery选项卡
  • python gensim
  • Binary XML file line #7: Error inflating class fragment
  • 关联企业业务往来税收调整
  • 涉嫌虚开增值税专用发票罪
  • 常州车辆过户手续办理
  • 合并方为进行企业合并发生的佣金和手续费怎么处理?
  • 江苏税务实名认证怎么更改
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设