为什么chrooted PHP(FPM)在DNS方面有问题,而chrooted shell却没有


Why does chrooted PHP (FPM) have problems with DNS when a chrooted shell does not?

我想做的事情:

让Nginx通过FastCGI(FPM)从使用debotstrap创建的chroot监狱中提供PHP文件。

问题是:

每个将主机名解析为IP地址的函数都会因php_network_getaddresses: getaddrinfo failed: Name or service not known而失败。奇怪的是,从chrooted shell中解析主机名没有问题。

到目前为止我做了什么:

  • 我禁用了监狱外的防火墙。

  • 我将/etc/resolv.conf/etc/nsswitch.conf和其他一些文件(我在这里找到的)复制到了监狱中(由于Debotstrap,所有这些都已经存在了,但我无论如何都替换了它们!)

  • 我将nameserver 8.8.8.8nameserver 8.8.4.4添加到/etc/resolv.conf(我以前没有这样做,因为DHCP服务器正确地提供了名称服务器!)

  • 我将domain localhost1添加到/etc/resolv.conf,并将127.0.0.1 localhost1添加到/etc/hosts。

  • 我在监狱里安装了一个名称服务器。

  • 我在监狱外安装了一个名称服务器(oops)

  • 我在监狱里安装了/proc

不用说,实际上没有什么能解决问题,所以请帮助我。

复制此内容所需的所有步骤:

  1. Debian-7.4.0-amd64-netinst.iso安装Debian Wheezy,并对除软件选择之外的所有内容使用默认设置,只在此处选中标准系统

  2. 要意识到,没有选择一个不那么遥远的镜子是一个错误。

    vi /etc/apt/sources.list,并使文件看起来像这样:

    deb http://ftp.de.debian.org/debian/ wheezy main contrib non-free
    deb-src http://ftp.de.debian.org/debian/ wheezy main contrib non-free
    deb http://security.debian.org/ wheezy/updates main
    deb-src http://security.debian.org/ wheezy/updates main
    deb http://ftp.de.debian.org/debian/ wheezy-updates main
    deb-src http://ftp.de.debian.org/debian/ wheezy-updates main
    
  3. 在安装Debotstrap、Nginx和PHP-FPM之前,确保一切都是最新的。

    aptitude update && aptitude -y full-upgrade

    aptitude -y install debootstrap nginx php5-fpm

  4. 使用Debootstrap为网站创建chroot监狱。

    debootstrap wheezy /srv/localhost http://ftp.de.debian.org/debian/1

  5. 在之前创建的监狱中创建一个名为www的目录,并将www数据作为所有者。

    mkdir /srv/localhost/srv/www1

    echo "<?php fsockopen('ftp.de.debian.org'); ?>" > /srv/localhost/srv/www/index.php1

    chown -R 33:33 /srv/localhost/srv/www1

  6. 配置并启用站点。

    vi /etc/nginx/sites-available/localhost1并使文件看起来像这样1:

    server {
      listen 127.0.0.1:80;
      server_name localhost;
      root /srv/localhost/srv/www;
      index index.html index.htm index.php;
      location ~ '.php$ {
        try_files     $uri =404;
        fastcgi_pass  unix:/var/run/localhost.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /www/$fastcgi_script_name;
        include       fastcgi_params;
      }
      location / {
        try_files $uri $uri/ /index.html;
      }
      location ~* '.(jpg|jpeg|gif|png|css|js|ico)$ {
        access_log off;
      }
      location = /favicon.ico {
        log_not_found off;
      }
      location ~ /'. {
        deny          all;
        access_log    off;
        log_not_found off;
      }
    }
    

    ln -s /etc/nginx/sites-available/localhost /etc/nginx/sites-enabled/1

  7. 对Nginx提供的FastCGI参数进行轻微调整。

    vi /etc/nginx/fastcgi_params,并使文件看起来像这样:

    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    fastcgi_param  HTTPS              $https if_not_empty;
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;
    # PHP only, required if PHP was built with --enable-force-cgi-redirect
    fastcgi_param  REDIRECT_STATUS    200;
    
  8. 为站点创建一个PHP-FPM池(?)。

    vi /etc/php5/fpm/pool.d/localhost.conf1并使文件看起来像这样1:

    [localhost]
    user  = www-data
    group = www-data
    listen                 = /var/run/localhost.sock
    listen.allowed_clients = 127.0.0.1
    pm                      = ondemand
    pm.max_children         = 5
    pm.process_idle_timeout = 300s
    pm.max_requests         = 500
    ;access.log    = log/$pool.access.log
    ;access.format = "%R - %u %t '"%m %r'" %s"
    chroot = /srv/localhost/srv
    chdir  = /
    ;catch_workers_output = yes
    ;security.limit_extensions = .php .php3 .php4 .php5
    php_flag[display_errors]           = on
    php_admin_flag[log_errors]         = on
    php_admin_value[error_log]         = /var/log/php.log
    php_admin_value[memory_limit]      = 32M
    php_admin_value[session.save_path] = /tmp
    
    env[HOSTNAME] = $HOSTNAME
    env[PATH]     = /usr/local/bin:/usr/bin:/bin
    env[TMP]      = /tmp
    env[TMPDIR]   = /tmp
    env[TEMP]     = /tmp
    
  9. 删除Nginx和PHP-FPM配置示例。

    rm /etc/nginx/sites-enabled/default /etc/php5/fpm/pool.d/wwww.conf

  10. 重新启动PHP-FPM和Nginx服务。

    service php5-fpm restart && service nginx restart

  11. 检查输出。

    wget -qO- http://localhost1打印:

    <br />
    <b>Warning</b>:  fsockopen(): php_network_getaddresses: getaddrinfo failed: Name or service not known in <b>/www/index.php</b> on line <b>1</b><br />
    <br />
    <b>Warning</b>:  fsockopen(): unable to connect to ftp.de.debian.org:80:-1 (php_network_getaddresses: getaddrinfo failed: Name or service not known) in <b>/www/index.php</b> on line <b>1</b><br />
    
  12. 走进监狱,只是为了看看解决主机名没有问题

    chroot /srv/localhost/1

    ping -c1 ftp.de.debian.org打印:

    PING ftp.de.debian.org (141.76.2.4) 56(84) bytes of data.
    64 bytes from ftp.de.debian.org (141.76.2.4): icmp_req=1 ttl=56 time=15.1 ms
    --- ftp.de.debian.org ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 15.137/15.137/15.137/0.000 ms
    

1我的实际域的所有出现都被替换为localhost,我的实际IP地址的出现都被127.0.0.1。

2我已经导出了Oracle®VirtualBox设备,并将其上传到Mega.co.nz上(根密码为密码),供所有非常非常渴望在这里帮助我的人使用。

我不知道为什么会发生这种情况,但您可能可以通过使用strace找到答案。要安装strace,您需要执行apt-get install strace。然后用ps ax | grep nginx得到nginx的PID。然后进行实际扫射:

strace -f -s 1024 -p PIDOFNGINX -o /tmp/trace.out

然后启动wget -qO- http://localhost,停止nginx(或杀死strace),然后查看/tmp/trace.out以及它抛出错误的位置。也许你的chroot里少了一些图书馆
编辑:
您编写所做内容的方式实际上并没有在chroot中执行测试ping。应该是:

chroot /srv/localhost /bin/ping -c1 ftp.de.debian.org

实际上,你可以对ping进行遍历,这样就可以减少nginx中的内容。这将需要ping命令也在chroot中(无论如何都需要它来测试这一点),包括它依赖的库等。