Debian Jessie, Nginx, PHP, UWSGI quick start

Thomas Glanzmann thomas at glanzmann.de
Sat Jan 2 07:37:36 UTC 2016


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:

https://github.com/gdamjan/uwsgi-php-in-a-namespace
http://lists.unbit.it/pipermail/uwsgi/2013-September/006405.html
http://superuser.com/questions/868602/owncloud-in-subdirectoy-on-arch-nginx-uwsgi
https://github.com/unbit/uwsgi-docs/blob/master/Changelog-1.9.15.rst
https://github.com/unbit/uwsgi-docs/blob/master/articles/MassiveHostingWithEmperorAndNamespaces.rst

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



More information about the nginx mailing list