Jump to content

Shellbox

From mediawiki.org
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 is available at Manual:BoxedCommand .

Server setup

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 internal 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 work directory for Shellbox:
 install -o shellbox -g shellbox -d /var/tmp/shellbox
  • Create the Shellbox configuration file referencing that temporary work directory /srv/shellbox/config/config.json:
 {
 	"url": "http://shellbox.internal/shellbox",
 	"tempDir": "/var/tmp/shellbox"
 }
  • Generate a secret key; it is strongly recommended to use a 128-bit minimal strength, so here we use 16 random bytes formatted into an hexadecimal string:
php -r 'print bin2hex(fread(fopen("/dev/urandom","r"),16))."\n";'
  • Create the Apache configuration /etc/apache2/sites-available/shellbox.internal.conf, and paste the secret key inside :
<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 Apache configuration file against unprivileged reads of the secret key and unprivileged modifications, by any other system user or group than those configured to run Apache itself on the server:
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. When configured in this way, Shellbox does not have permission to connect to the PHP-FPM socket:
[shellbox]
user = shellbox
group = shellbox
listen = /run/php/shellbox.sock
listen.owner = www-data
listen.group = www-data
pm = static
pm.max_children = 1

MediaWiki configuration

$wgShellboxUrls = [
	'default' => 'http://shellbox.internal/shellbox'
];
$wgShellboxSecretKey = '... your secret key ...';

Pre-built containers

Wikimedia has pre-built containers that contain Shellbox, its dependencies, and PHP-FPM:

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

Routes

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

Notes

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