• 对于注定会优秀的人来说,他所需要的,只是时间!
  • 手懒得,必受贫穷,手勤的,必得富足----《圣经》
  • 帮助别人,成就自己。愿君在本站能真正有所收获!
  • 如果你在本站中发现任何问题,欢迎留言指正!
  • 宝剑锋从磨砺出,梅花香自苦寒来!

PHP项目chroot相关内容

网站服务 eryajf 2周前 (10-09) 53°C 已收录 0个评论
本文预计阅读时间 18 分钟

1,PHP的chroot配置

有时候开启了chroot的项目,偶尔请求外部域名,会有报错,反馈77的code,一般就是里边依赖库的问题,重新执行一波下边的操作即可。

一些目录的创建

mkdir -p /data/www
mkdir /data/www/usr/
mkdir /data/www/usr/local/
mkdir /data/www/etc/
mkdir /data/www/usr/share/zoneinfo/Asia/

rsync -al /dev/null /data/www/dev/
rsync -al /dev/random /data/www/dev/
rsync -al /dev/urandom /data/www/dev/
rsync -al /dev/zero /data/www/dev/
rsync -al /lib /data/www/
rsync -al /lib64 /data/www/
rsync -al /usr/lib /data/www/usr/
rsync -al /usr/lib64 /data/www/usr/
rsync -al /usr/local/lib /data/www/usr/local/
rsync -al /usr/local/lib64 /data/www/usr/local/
rsync -al /etc/pki /data/www/etc/
rsync -al /etc/ssl /data/www/etc/
rsync -al /etc/resolv.conf /data/www/etc/
rsync -al /usr/share/zoneinfo/Asia/Shanghai /data/www/usr/share/zoneinfo/Asia/

mkdir /data/www/tmp
chmod 1777 /data/www/tmp

另外一种方式可通过本机挂载来设置:

原来:
rsync -al /dev/null /data/www/dev/
rsync -al /dev/random /data/www/dev/
rsync -al /dev/urandom /data/www/dev/
rsync -al /dev/zero /data/www/dev/
rsync -al /lib /data/www/
rsync -al /lib64 /data/www/
rsync -al /usr/lib /data/www/usr/
rsync -al /usr/lib64 /data/www/usr/
rsync -al /usr/local/lib /data/www/usr/local/
rsync -al /usr/local/lib64 /data/www/usr/local/
rsync -al /etc/pki /data/www/etc/
rsync -al /etc/ssl /data/www/etc/
rsync -al /etc/resolv.conf /data/www/etc/
rsync -al /usr/share/zoneinfo/Asia/Shanghai /data/www/usr/share/zoneinfo/Asia/


现在:
mkdir -p /data/www/dev
mkdir -p /data/www/lib
mkdir -p /data/www/lib64
mkdir -p /data/www/usr/lib
mkdir -p /data/www/usr/lib64
mkdir -p /data/www/etc
mkdir -p /data/www/usr/share/zoneinfo/Asia

mount --bind -o ro /dev /data/www/dev/
mount --bind -o ro /lib /data/www/lib
mount --bind -o ro /lib64 /data/www/lib64
mount --bind -o ro /usr/lib /data/www/usr/lib
mount --bind -o ro /usr/lib64 /data/www/usr/lib64
mount --bind -o ro /etc /data/www/etc
mount --bind -o ro /usr/share/zoneinfo/Asia /data/www/usr/share/zoneinfo/Asia

然后是PHP的配置文件更改/usr/local/php/etc/php-fpm.d/www.conf

[chroot]
listen = 127.0.0.1:9000
user = www
group = www
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 100
request_terminate_timeout = 120
request_slowlog_timeout = 2
slowlog = /var/log/php-fpm/chroot-slow.log
chroot = /data/www
php_admin_value[error_log] = /var/log/php-fpm/chroot-error.log
php_admin_flag[log_errors] = on
php_value[session.save_path]    = /var/lib/php/session

此时PHP配置完成之后,可以创建一个PHP文件进行验证。

当我进行验证的时候发现,死活不能得到想要的结果,一直会报一个 "File not found"内容,看NGINX的错误日志内容如下:

2019/08/02 15:59:18 [error] 19008#0: *341 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 115.238.43.130, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "115.159.112.87", referrer: "http://115.159.112.87/"

2,NGINX配置。

这个时候我的NGINX配置为:

server {
    listen 80;
    server_name localhost;
    index index.html index.htm index.php default.html default.htm default.php;
    root  /data/www/typecho;

location ~ .*\.php(\/.*)*$ {
    root  /data/www/typecho;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
   include fastcgi.conf;
   include pathinfo.conf;
    }

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
    expires      30d;
    }

location ~ .*\.(js|css)?$ {
    expires      12h;
    }
}

如上配置在PHP不开启chroot的情况下,访问是没有问题的,只要一开启,就会报刚刚的错误。

后来查资料,了解到,当我设置了chroot,就相当于把配置的目录定义为了根目录,于是,在NGINX层面,就不能再像原来那样配置了。

也就是chroot目录定义为了 /data/www,那么在php解析的时候,就需要将真实的项目目录定义为根目录才行,因此使用如下配置即可解决:

server {
    listen 80;
    server_name localhost;
    index index.html index.htm index.php default.html default.htm default.php;
    root  /data/www/typecho;

location ~ .*\.php(\/.*)*$ {
    root  /data/www/typecho;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME /typecho$fastcgi_script_name;
    include fastcgi_params;
    }

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
    expires      30d;
    }

location ~ .*\.(js|css)?$ {
    expires      12h;
    }
}

其中 fastcgi_param SCRIPT_FILENAME /typecho$fastcgi_script_name;/typecho就是当前项目的根目录,然后再去访问,就没有问题了。

网上有说把配置定义为 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;也可以,但经过我的测试,发现并不行。

3,通过mount挂载扩展

这是一个有意思的尝试方案,仅作为扩展眼界,不太推荐生产使用。

我们可以通过mount –bind命令来将两个目录连接起来,mount –bind命令是将前一个目录挂载到后一个目录上,所有对后一个目录的访问其实都是对前一个目录的访问,如下所示:

# 将test1挂载到test2
mount --bind test1 test2

当mount –bind命令执行后,Linux将会把被挂载目录的目录项(也就是该目录文件的block,记录了下级目录的信息)屏蔽,即test2的下级路径被隐藏起来了(注意,只是隐藏不是删除,数据都没有改变,只是访问不到了)。同时,内核将挂载目录(test1)的目录项记录在内存里的一个s_root对象里,在mount命令执行时,VFS会创建一个vfsmount对象,这个对象里包含了整个文件系统所有的mount信息,其中也会包括本次mount中的信息,这个对象是一个HASH值对应表(HASH值通过对路径字符串的计算得来),表里就有 /test1 到 /test2 两个目录的HASH值对应关系。

命令执行完后,当访问 /test2下的文件时,系统会告知 /test2 的目录项被屏蔽掉了,自动转到内存里找VFS,通过vfsmount了解到 /test2 和 /test1 的对应关系,从而读取到 /test1 的inode,这样在 /test2 下读到的全是 /test1 目录下的文件。

  1. mount –bind连接的两个目录的inode号码并不一样,只是被挂载目录的block被屏蔽掉,inode被重定向到挂载目录的inode(被挂载目录的inode和block依然没变)。
  2. 两个目录的对应关系存在于内存里,一旦重启挂载关系就不存在了。

在固件开发过程中常常遇到这样的情况:为测试某个新功能,必需修改某个系统文件。而这个文件在只读文件系统上(总不能为一个小小的测试就重刷固件吧),或者是虽然文件可写,但是自己对这个改动没有把握,不愿意直接修改。这时候mount –bind就是你的好帮手。
假设我们要改的文件是/etc/hosts,可按下面的步骤操作:

  1. 把新的hosts文件放在/tmp下。当然也可放在硬盘或U盘上。
  2. mount –bind /tmp/hosts /etc/hosts 此时的/etc目录是可写的,所做修改不会应用到原来的/etc目录,可以放心测试。测试完成了执行 umount /etc/hosts 断开绑定。

解决重启挂载失效的问题:

当然是写入到自动挂载咯,写法如下:

$ cat /etc/fstab

/etc /data/www/etc none    bind        0 0
/dev /data/www/dev/ none    bind        0 0
/lib /data/www/lib none    bind        0 0
/lib64 /data/www/lib64 none    bind        0 0
/usr/lib /data/www/usr/lib none    bind        0 0
/usr/lib64 /data/www/usr/lib64 none    bind        0 0
/usr/share/zoneinfo/Asia /data/www/usr/share/zoneinfo/Asia none    bind        0 0

或者使用另外一种方案,将这波挂载集成为一个服务,并把服务做成开机自启,并记得PHP的启动在此服务之后即可。

创建启动文件:

$ cat /etc/init.d/chroot_mount

#!/bin/sh

### BEGIN INIT INFO
# Provides:          php7-fpm-chroot-setup
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Bind-mounts needed running before php-fpm.service
### END INIT INFO

CHROOT=/data/www
DIRS="/dev /lib /lib64 /usr/lib /usr/lib64 /etc /usr/share/zoneinfo/Asia"

case "$1" in
  start)
        $0 stop 2>/dev/null
        for d in $DIRS; do
                mkdir -p "${CHROOT}${d}"
                mount --bind -o ro "${d}" "${CHROOT}${d}"
        done
        ;;
  stop)
        for d in $DIRS; do
                umount "${CHROOT}${d}"
        done
        ;;
  *)
        echo "Usage: $N {start|stop}" >&2
        exit 1
        ;;
esac

exit 0

添加为系统服务并启动,启动之前保证 /data/www将要挂载的几个目录干净。

chmod +x chroot_mount
chkconfig --add chroot_mount
systemctl start chroot_mount
systemctl enable chroot_mount

然后调整一下php的启动文件:

$ vim php-fpm.service

[Unit]
Description=The PHP FastCGI Process Manager
After=network.target chroot_mount

[Service]
Type=simple
PIDFile=/var/run/php-fpm.pid
ExecStart=/usr/local/php/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php/etc/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target

weinxin
扫码订阅本站,第一时间获得更新
微信扫描二维码,订阅我们网站的动态,另外不定时发送WordPress小技巧,你可以随时退订,欢迎订阅哦~

二丫讲梵 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明PHP项目chroot相关内容
喜欢 (0)
[如果想支持本站,可支付宝赞助]
分享 (0)
eryajf
关于作者:
学无止境,我愿意无止境学。书山有路,我愿意举身投火,淬炼成金!永远不要忘记,激情的奋进,就是美好的未来!

您必须 登录 才能发表评论!