当chrooted shell没有时,为什么chrooted PHP(FPM)存在DNS问题? [关闭]

What I want to do:

Get Nginx to serve PHP files through FastCGI (FPM) from within a chroot jail created using debootstrap.

The problem:

Every function that resolves hostnames to IP addresses fails with php_network_getaddresses: getaddrinfo failed: Name or service not known. What's so odd about this is that there's no problem resolving hostnames from a chrooted shell.

What I did so far:

  • I disabled the firewall outside the jail.

  • I copied /etc/resolv.conf, /etc/nsswitch.conf and some other files (which I found here) into the jail. (All of which were already there thanks to Debootstrap, but I replaced them anyways!)

  • I added nameserver 8.8.8.8 and nameserver 8.8.4.4 to /etc/resolv.conf. (I haven't done this before, because the nameservers were properly provided by the DHCP server!)

  • I added domain localhost1 to /etc/resolv.conf and 127.0.0.1 localhost1 to /etc/hosts.

  • I installed a nameserver inside the jail.

  • I installed a nameserver outside the jail (oops).

  • I mounted /proc inside the jail.

Needless to say that nothing actually fixed the problem, so please help me.

All the steps needed to reproduce this:

  1. Install Debian Wheezy from debian-7.4.0-amd64-netinst.iso and use the default settings for everything except for Software selection, leave only Standard system checked there.

  2. Realize that not picking a less distant mirror was a mistake.

    vi /etc/apt/sources.list and made the file look like this:

    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. Make sure everything is up to date prior to installing Debootstrap, Nginx and PHP-FPM.

    aptitude update && aptitude -y full-upgrade

    aptitude -y install debootstrap nginx php5-fpm

  4. Use Debootstrap to create the chroot jail for the website.

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

  5. Create a directory called www with a test file inside the previously created jail and make www-data the owner.

    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. Configure and enable the site.

    vi /etc/nginx/sites-available/localhost1 and made the file look like this1:

    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. Make slight adjustments to the FastCGI parameters provided by Nginx.

    vi /etc/nginx/fastcgi_params and made the file look like this:

    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. Create a PHP-FPM pool(?) for the site.

    vi /etc/php5/fpm/pool.d/localhost.conf1 and made the file look like this1:

    [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. Remove Nginx and PHP-FPM configuration examples.

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

  10. Restart the PHP-FPM and the Nginx service.

    service php5-fpm restart && service nginx restart

  11. Inspect the output.

    wget -qO- http://localhost1 prints:

    <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 into the jail, just to see that there's no problem with resolving hostnames

    chroot /srv/localhost/1

    ping -c1 ftp.de.debian.org prints:

    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 All occurrences of my actual domain have been replaced with localhost and those of my actual IP address with 127.0.0.1.

2 I've exported the Oracle® VirtualBox appliance and uploaded it on Mega.co.nz (root password is password) for everyone who's really, really eager to help me here.

1个回答



我不知道为什么会这样,但你可能会发现使用strace。 要安装strace,你需要做 apt-get install strace </ code>。 然后用 ps ax |得到nginx的PID grep nginx </ code>。 那么对于实际的支撑:
</ p>

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

然后启动 wget -qO- http:// localhost </ code>,停止nginx(或kill strace),然后查看/tmp/trace.out以及它的位置 抛出错误。 可能你的chroot中缺少一些库。

编辑:</ strong>

你写完你所做的事的方式你没有在chroot中实际执行测试 。 应该是:
</ p>

  chroot / srv / localhost / bin / ping -c1 ftp.de.debian.org 
</ code> </ pre> \ n

你可以实际上对那个ping进行分析,然后从nginx中包含更少的东西。 这将要求ping命令也在chroot中(无论如何都需要测试它),包括它依赖库等。</ p>
</ div>

展开原文

原文

I don't know why that happens, but you could probably find out by using strace. To install strace you'd do a apt-get install strace. Then you get the PID of nginx with ps ax | grep nginx. Then for the actual stracing:

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

Then you fire up that wget -qO- http://localhost, stop nginx (or kill strace), and then look through /tmp/trace.out and where it's throwing the error. Probably there's some library missing in your chroot.
EDIT:
The way you have written what you've done you haven't actually performed the test-ping within the chroot. That shoul be:

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

You can actually strace that ping then, which would then include less stuff form nginx. This would require the ping command to be in the chroot as well (which would be needed anyway to test this), including it's depending libraries etc.

dpvr49226
dpvr49226 仅使用gethostbyname来测试脚本@ knzl.de/setting-up-a-chroot-for-php在Alpine Linux / nginx chroot中为我解决了dns问题。
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问