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