Debian Jessie, Nginx, PHP, UWSGI quick start

Hello,
I had to host a potential unsecure PHP web application. So I though
about
writing a small c programm which creates a network, filesystem, pid,
uts, and ipc namespace and run php-fpm inside it. I needd from the PHP
web application access to a mysql database, mailserver and ftp server of
the localhost. I stumbled across uwsgi and thought less programming for
me, but it took me several hours to get it finally running so I write up
this quickstart guide for others who will face the same problem. I would
also like feedback from others who are doing the same. Maybe you can add
this quickstart guide to the uwsgi website after reviewing it.

  • First it is necessary to setup a debootstrap of the distribution you
    want to use. For me it was Debian Jessie amd64. And add the php5-mysql
    package and any other php5 extensions you might need. I also searched
    for any user writable directories, deleted them and symlinked them to
    /tmp

/usr/sbin/debootstrap --arch amd64 jessie /distro/jessie
cd /distro/jessie
chroot .
mount -t proc none /proc
apt-get --no-install-recommends install php5-mysql
find . -type d -perm -o+w -exec ls -adl {} ;
rm ./var/lib/php5/sessions
ln -s /tmp ./var/lib/php5/sessions

exit

  • Than I installed on the host the uwsgi-emperor and uwsgi-plugin-php

apt-get install uwsgi-emperor uwsgi-plugin-php

  • Next is the configuration. I tried to create a root from the existing
    system without using debootstrap which always failed at the chroot
    step for me. So at one point I decided to go with debootstrap. I
    changed one other challenge: I needed to be able to reach the socket
    of uwsgi-plugin-php and have communication to mysql, postfix, and the
    ftp server. As soon as I enabled network namespaces that communication
    was gone. The options are: Don’t do network namespaces (not an option
    for me), use unix sockets (not an option for ftp and mail) or use
    veth, macvlan or the uwsgi TunTap Router (I did not want to go the
    network communication through userland). So I used veth. Note that the
    new network namespace does not get a default route. For the network
    configuration I used a /30 but I probably should have used
    pointopoint.
    One problem I faces is reaching the socket of uwsgi after enable
    network namespaces. Is there a way to let the emperor listen and
    forward the communication channel to the vassals using two
    filedescriptors so that I don’t need shared filesystem for the unix
    socket or an ip address to communicate from the host to the vassal?

(infra) [~] cat /etc/uwsgi-emperor/emperor.ini
[uwsgi]
emperor = /etc/uwsgi-emperor/vassals
emperor-use-clone = ipc,uts,pid,net
master = true

exec-as-emperor = ip link del veth0
exec-as-emperor = ip link add veth0 type veth peer name veth1
exec-as-emperor = ifconfig veth0 10.12.13.1 netmask 255.255.255.252 up
exec-as-emperor = ip link set veth1 netns $UWSGI_VASSAL_PID

(infra) [~] cat /etc/uwsgi-emperor/vassals/shell.ini
[uwsgi]
socket = 10.12.13.2:12345

uid = www-data
gid = 33
unshare = fs
hook-post-jail = mount:none /distro/jessie /ns bind,ro
pivot_root = /ns /ns/.old
hook-as-root = mount:proc none /proc nodev hidepid=2
hook-as-root = mount:tmpfs none /tmp
hook-as-root = mount:none /.old/srv/www/shell /srv/www/shell bind
hook-as-root = mount:none /.old/dev/pts /dev/pts bind
hook-as-root = umount:/.old rec,detach

wait-for-interface = veth1
exec-as-root = hostname vassal001
exec-as-root = ifconfig lo up
exec-as-root = ifconfig veth1 10.12.13.2 netmask 255.255.255.252 up

plugin = 0:php
php-allowed-ext = .php
php-docroot = /srv/www/shell
php-index = index.php
php-set = extension=mysql.so

processes = 10
cheaper = 2

(infra) [~] cat /etc/nginx/nginx.conf

server {
listen 1.2.3.4:443;

    server_name shell.glanzmann.de; # the host is gone . :-)

    root /srv/www/shell;

    disable_symlinks on;
    autoindex off;

    index index.php;

    location ~ \.php$ {
            include /etc/nginx/uwsgi_params;
            uwsgi_pass 10.12.13.2:12345;
    }

}

Here are some useful sources that I used during the process:

http://lists.unbit.it/pipermail/uwsgi/2013-September/006405.html

I appreciate any tips to improve the above configuration, errors that I
might did and also if there is another tool which is probably easier
than uwsgi to configure which can do the same thing. I like uwsgi, but
it took me yesterday several hours to get it running and I found the
documentation to be very confusing.

Cheers,
Thomas

Am 02.01.2016 um 08:37 schrieb Thomas G. [email protected]:

Hello,
I had to host a potential unsecure PHP web application. So I though about
writing a small c programm which creates a network, filesystem, pid,
uts, and ipc namespace and run php-fpm inside it.

Excuse me if I’m blunt, but: can’t you just use php-fpm’s chroot
feature?
What’s the advantage of using uwsgi for php, apart from some tricks you
really cannot do with php-fpm (running multiple PHPs at the same time).

I’ve chrooted all my php-fpm instances (under FreeBSD) and it works very
well.

Of course, you can’t talk to any socket directly anymore. But that’s a
minor issue IMO.