Shellbox

From mediawiki.org
Jump to navigation Jump to search
Shellbox safely sandboxes unsafe command execution.
For information about Wikimedia's Shellbox deployment, see: wikitech:Shellbox.

Shellbox is a library for command execution, and also a server and client for remote command execution. It was primarily implemented to sandbox lilypond (used by the Score extension) and provide a way for MediaWiki to utilize external binaries without needing to run them in the same container. It was designed and approved via RFC: PHP microservice for containerized shell execution. Shellbox is usable starting with MediaWiki 1.36.

Information about using Shellbox in MediaWiki may some day appear in Manual:Shell framework.

Server setup[edit]

It is recommended that you set up Shellbox to run as an unprivileged user inside an isolated container with no external network access. Wikimedia uses Kubernetes for this purpose and has a Helm chart that may be reusable.

The following packages should be installed inside the container: Apache2 (httpd), PHP-FPM, and whatever commands you need to shell out to (e.g. lilypond, imagemagick, etc.).

In the following examples we use shellbox.internal as the container hostname.

Get the Shellbox source and its dependencies:

cd /srv
git clone https://gerrit.wikimedia.org/r/mediawiki/libs/Shellbox shellbox
cd shellbox
composer install --no-dev

Create an unprivileged user for Shellbox:

useradd -r shellbox

Create a temporary directory:

install -o shellbox -g shellbox -d /var/tmp/shellbox

Create the Shellbox configuration file /srv/shellbox/config/config.json:

{
	"url": "http://shellbox.internal/shellbox",
	"tempDir": "/var/tmp/shellbox"
}

Generate a secret key:

php -r 'print bin2hex(fread(fopen("/dev/urandom","r"),16))."\n";'

Create the Apache configuration /etc/apache2/sites-available/shellbox.internal.conf

<VirtualHost *:80>
	ServerName shellbox.internal
	DocumentRoot /srv/shellbox/public_html
	Alias /shellbox /srv/shellbox/shellbox.php
	SetEnv SHELLBOX_SECRET_KEY "...YOUR SECRET KEY HERE..."
	<Directory /srv/shellbox/public_html>
		Order deny,allow
		Satisfy Any
	</Directory>
	<FilesMatch ".+\.php$">
		SetHandler "proxy:unix:/run/php/shellbox.sock|fcgi://localhost"
	</FilesMatch>

	RewriteEngine On
	RewriteCond %{HTTP:Authorization} ^(.*)
	RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

</VirtualHost>

Protect the secret key against unprivileged reads:

chown root:root /etc/apache2/sites-available/shellbox.internal.conf
chmod 600 /etc/apache2/sites-available/shellbox.internal.conf

Create the PHP-FPM pool configuration:

[shellbox]
user = shellbox
group = shellbox
listen = /run/php/shellbox.sock
listen.owner = www-data
listen.group = www-data
pm = static
pm.max_children = 1

When configured in this way, Shellbox does not have permission to connect to the PHP-FPM socket.

MediaWiki configuration[edit]

$wgShellboxUrl = 'http://shellbox.internal/shellbox';
$wgShellboxSecretKey = '... your secret key ...';

Pre-built containers[edit]

Wikimedia has pre-built containers that contain Shellbox, it's dependencies, and PHP-FPM: https://docker-registry.wikimedia.org/wikimedia/mediawiki-libs-shellbox/tags/

These images currently have no stability guarantee/versioning (help wanted on figuring this out).

Routes[edit]

Shellbox exposes a /healthz route for manual and automated health checks. It also has a PHP-RPC interface for executing sandboxed PHP code.

Notes[edit]

Shellbox does not support cross-platform requests, so if you run MediaWiki on Windows, it's necessary to run Shellbox on Windows as well.

External links[edit]