{"id":11424,"date":"2020-07-27T06:00:12","date_gmt":"2020-07-27T10:00:12","guid":{"rendered":"https:\/\/blog.litespeedtech.com\/?p=11424"},"modified":"2020-07-27T06:00:12","modified_gmt":"2020-07-27T10:00:12","slug":"bubblewrap-in-litespeed-web-server","status":"publish","type":"post","link":"https:\/\/lswp.store\/index.php\/2020\/07\/27\/bubblewrap-in-litespeed-web-server\/","title":{"rendered":"Integrated Bubblewrap Support in LiteSpeed Web Servers"},"content":{"rendered":"<p><img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter size-full wp-image-11428\" src=\"https:\/\/lswp.store\/wp-content\/uploads\/2020\/07\/bubblewrap.jpg\" alt=\"Bubblewrap in LiteSpeed Web Server\" width=\"1000\" height=\"500\" srcset=\"https:\/\/lswp.store\/wp-content\/uploads\/2020\/07\/bubblewrap.jpg 1000w, https:\/\/lswp.store\/wp-content\/uploads\/2020\/07\/bubblewrap-300x150.jpg 300w, https:\/\/lswp.store\/wp-content\/uploads\/2020\/07\/bubblewrap-768x384.jpg 768w, https:\/\/lswp.store\/wp-content\/uploads\/2020\/07\/bubblewrap-600x300.jpg 600w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<p>The LiteSpeed family of high performance web servers offers a number of ways to isolate requests, thereby providing protection against attack. In upcoming releases of LiteSpeed Enterprise (6.0) and OpenLiteSpeed (1.6.15), we have added integrated support for bubblewrap by Flatpak, providing even greater isolation and protection against attack.<\/p>\n<h2>What\u2019s so great about bubblewrap?<\/h2>\n<p>Bubblewrap is a lightweight sandbox application written by Flatpak, and is described in their wiki <a href=\"https:\/\/wiki.archlinux.org\/index.php\/Bubblewrap\">here<\/a>. What it does is implement <a href=\"https:\/\/man7.org\/linux\/man-pages\/man7\/namespaces.7.html\">Linux namespaces<\/a>, which basically gives the application (LiteSpeed in this case) a full sandbox, which includes operating-system-supported isolated mounts, user\/group IDs, interprocess communications, users, cgroups, host names and more.<\/p>\n<p>For example, with isolated mount namespaces: each request can only see the file system designated for that request and can even be denied write access to any files within any directories you specify.<\/p>\n<p>With isolated users and groups, the user will only be able to see their own user ID, group ID and capabilities. The default even creates independent <code>\/etc\/passwd<\/code> and <code>\/etc\/group<\/code> files with the contents you specify.<\/p>\n<p>With isolated interprocess communications each process can only see the named pipes, or Unix Domain Sockets you specify, which limits the applications that a process can contact. It&#8217;s impossible to communicate with applications without specified file system access.<\/p>\n<p>Similar to, but perhaps less comprehensive than, CloudLinux CageFS, a bubblewrap\u2019d process is utterly independent. Thus significantly reducing the opportunities for an attack.<\/p>\n<h2>Why integrate it?<\/h2>\n<p>Use of bubblewrap may be configured into previous versions of LiteSpeed (or other web servers), however, it requires complex reconfiguration of your server in order to call the <code>bwrap<\/code> program directly, and call your program from it. By integrating it into LiteSpeed, bubblewrap works for a large number of application types and requires a very simple configuration change.<\/p>\n<p>Integration allows it to operate on CGI applications as well as FCGI applications, which would not be possible without integration.<\/p>\n<h2>How to bubblewrap in LiteSpeed Web Server<\/h2>\n<p>In most cases you can enable bubblewrap in your existing LiteSpeed configuration by setting <strong>Bubblewrap Container<\/strong> to <strong>On<\/strong> in your security configuration. Details for OpenLiteSpeed are <a href=\"https:\/\/openlitespeed.org\/kb\/bubblewrap-in-openlitespeed\/\">here<\/a>.<\/p>\n<p>If you do not customize a <strong>Bubblewrap Command<\/strong> (and most users will not) it will use the default of:<\/p>\n<pre>\/bin\/bwrap --ro-bind \/usr \/usr --ro-bind \/lib \/lib --ro-bind-try \/lib64 \/lib64 --ro-bind \/bin \/bin --ro-bind \/sbin \/sbin --dir \/var --dir \/tmp --proc \/proc --symlink..\/tmp var\/tmp --dev \/dev --ro-bind-try \/etc\/localtime \/etc\/localtime --ro-bind-try \/etc\/ld.so.cache \/etc\/ld.so.cache --ro-bind-try \/etc\/resolv.conf \/etc\/resolv.conf --ro-bind-try \/etc\/ssl \/etc\/ssl --ro-bind-try \/etc\/pki \/etc\/pki --ro-bind-try \/etc\/man_db.conf \/etc\/man_db.conf --ro-bind-try \/home\/$USER \/home\/$USER --bind-try \/var\/lib\/mysql\/mysql.sock \/var\/lib\/mysql\/mysql.sock --bind-try \/home\/mysql\/mysql.sock \/home\/mysql\/mysql.sock --bind-try \/tmp\/mysql.sock \/tmp\/mysql.sock  --unshare-all --share-net --die-with-parent --dir \/run\/user\/$UID '$PASSWD 65534' '$GROUP 65534'\n<\/pre>\n<p>The key to the isolation is the bubblewrap parameters <code>--unshare-all<\/code> and <code>--share-net<\/code>.<\/p>\n<ul>\n<li><code>--unshare-all<\/code> specifies all of the isolation mentioned above.<\/li>\n<li><code>--share-net<\/code> is required to allow your application access to networking.<\/li>\n<\/ul>\n<p>Let\u2019s see the isolation this gives you. The first parameter is simply the location of the bubblewrap program. The rest of the parameters will:<\/p>\n<ul>\n<li>Mount the following directories (and their subdirectories) as read-only:\n<ul>\n<li><code>\/usr<\/code><\/li>\n<li><code>\/lib<\/code><\/li>\n<li><code>\/lib64<\/code> (if it exists)<\/li>\n<li><code>\/bin<\/code><\/li>\n<li><code>\/sbin<\/code><\/li>\n<li><code>\/etc\/ssl<\/code> (if it exists)<\/li>\n<li><code>\/etc\/pki<\/code> (if it exists)<\/li>\n<li><code>\/home\/<\/code>(your user\u2019s directory) (if it exists)<\/li>\n<\/ul>\n<\/li>\n<li>Mount the following files as read-only:\n<ul>\n<li><code>\/etc\/localtime<\/code> (if it exists)<\/li>\n<li><code>\/etc\/ld.so.cache<\/code> (if it exists)<\/li>\n<li><code>\/etc\/resolv.conf<\/code> (if it exists)<\/li>\n<li><code>\/etc\/man_db.conf<\/code> (if it exists)<\/li>\n<\/ul>\n<\/li>\n<li>Mount the following files as read-write:\n<ul>\n<li><code>\/var\/lib\/mysql\/mysql.sock<\/code> (if it exists)<\/li>\n<li><code>\/home\/mysql\/mysql.sock<\/code> (if it exists)<\/li>\n<li><code>\/tmp\/mysql.sock<\/code> (if it exists).<\/li>\n<\/ul>\n<\/li>\n<li>Create the following empty directories:\n<ul>\n<li><code>\/var<\/code><\/li>\n<li><code>\/tmp<\/code><\/li>\n<li><code>\/run\/user\/<\/code>(your user\u2019s ID)<\/li>\n<\/ul>\n<\/li>\n<li>Create symbolic links:\n<ul>\n<li>from <code>..\/tmp<\/code> to <code>var\/tmp<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Provide minimal access to:\n<ul>\n<li><code>\/proc<\/code><\/li>\n<li><code>\/dev<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Terminate when LiteSpeed terminates<\/li>\n<li>Create custom:\n<ul>\n<li><code>\/etc\/passwd<\/code> file with only your user\u2019s entry and <code>65534<\/code> (<code>nobody<\/code>)<\/li>\n<li><code>\/etc\/group<\/code> file with only your group\u2019s entry and <code>65534<\/code> (<code>nogroup<\/code>)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Most programs will be able to run with these defaults and the result is great protection with minimum configuration.<\/p>\n<p>If your program is not in one of the mounted directories, uses a file not in the list of files or directories, or needs write access to a file not in the writable list, your program won\u2019t be able to access what it needs and will fail. In that case you will need to create a customized command line.<\/p>\n<h2>How to customize it<\/h2>\n<p>The customization is all in the <strong>Bubblewrap Command<\/strong> command line. Basically it uses the <a href=\"https:\/\/wiki.archlinux.org\/index.php\/Bubblewrap\">bubblewrap parameters<\/a> from your version of bubblewrap with some additional tokens which LiteSpeed adds to provide better customization:<\/p>\n<ul>\n<li><code>$USER<\/code> is replaced with the actual user name of your user.<\/li>\n<li><code>$UID<\/code> is replaced with the user ID of your user.<\/li>\n<li><code>$GID<\/code> is replaced with the group ID of your group.<\/li>\n<li><code>$PASSWD<\/code> is replaced with the creation of a custom <code>\/etc\/passwd<\/code> file with a single user line in it, for the user you\u2019re running as. If you enclose this option in single quotes you can add space-separated additional users. The default is <code>\u2019$PASSWD 65535\u2019<\/code> which creates a 2 line <code>\/etc\/hosts<\/code> file, with your user and the nobody user.<\/li>\n<li><code>$GROUP<\/code> is just like <code>$PASSWD<\/code> but creates a custom <code>\/etc\/group<\/code>.<\/li>\n<\/ul>\n<p>Note that most users will be able to use the default <strong>Bubblewrap Command<\/strong> by leaving it blank.<\/p>\n<h3>A simple example<\/h3>\n<p>The simplest example is the worst because it gives your application no additional protections. Set <strong>Bubblewrap Container<\/strong> to <code>On<\/code> and <strong>Bubblewrap Command<\/strong> to:<\/p>\n<pre>\/bin\/bwrap --dev-bind \/ \/<\/pre>\n<h3>A better example<\/h3>\n<p>This is a much better example of a <strong>Bubblewrap Command<\/strong> as it mounts even fewer files and directories than the default. It includes no <code>\/var<\/code>, no <code>\/etc\/man_db.conf<\/code>, no database sockets, and only your user in <code>\/etc\/passwd<\/code> and your group in <code>\/etc\/group<\/code>:<\/p>\n<pre>bin\/bwrap --ro-bind \/usr \/usr --ro-bind \/lib \/lib --ro-bind-try \/lib64 \/lib64 --ro-bind \/bin \/bin --ro-bind \/sbin \/sbin --dir \/tmp --proc \/proc --dev \/dev --ro-bind-try \/etc\/localtime \/etc\/localtime --ro-bind-try \/etc\/resolv.conf \/etc\/resolv.conf --ro-bind-try \/etc\/ssl \/etc\/ssl --ro-bind-try \/etc\/pki \/etc\/pki --ro-bind-try \/home\/$USER \/home\/$USER --unshare-all --share-net --die-with-parent --dir \/run\/user\/$UID $PASSWD $GROUP<\/pre>\n<h2>Give it a try!<\/h2>\n<p>To try it, upgrade to a version of LiteSpeed Enterprise or OpenLiteSpeed that supports bubblewrap, and turn it on for an application. This will show you the power of an integrated sandbox like bubblewrap inside of a powerful web server like LiteSpeed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Integrated support for bubblewrap by Flatpak will be added to forthcoming versions of LiteSpeed Web Server and OpenLiteSpeed.<\/p>\n","protected":false},"author":1,"featured_media":11428,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[27,29],"tags":[51],"class_list":["post-11424","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-server","category-openlitespeed","tag-bubblewrap"],"jetpack_featured_media_url":"https:\/\/lswp.store\/wp-content\/uploads\/2020\/07\/bubblewrap.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts\/11424","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/comments?post=11424"}],"version-history":[{"count":0,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/posts\/11424\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/media\/11428"}],"wp:attachment":[{"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/media?parent=11424"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/categories?post=11424"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lswp.store\/index.php\/wp-json\/wp\/v2\/tags?post=11424"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}