[GH-ISSUE #1620] Enforcing directory structure with permissive parts for web virtual hosts with SSH access #1086

Open
opened 2026-05-05 07:26:04 -06:00 by gitea-mirror · 5 comments
Owner

Originally created by @tomsseisums on GitHub (Oct 26, 2017).
Original GitHub issue: https://github.com/netblue30/firejail/issues/1620

I am on Ubuntu 16.04 LTS, therefore using the LTS version of firejail 0.9.38.10.

I am looking for a way to enforce a specific/strict structure for web virtual hosts on a somewhat shared hosting server.

My idea is to serve from each users home, where each user acts as a single vhost/domain. This is necessary because the virtual hosts also require SSH access, but I don't want to give them too much freedom to roam around. Otherwise I could, for example, set up sftp-chroot's through openssh.

So, with directory structure like this:

  • /home/<user>
    • /home/<user>/web
      • /home/<user>/web/log
      • /home/<user>/web/www
        • /home/<user>/web/www/public

Is it possible to configure permissions such that:

  • /home/<user> — remains as homes are by default, though, I may restrict it even more in future.
    • /home/<user>/web — isn't deletable/writable/editable, including contents.
      • /home/<user>/web/log — isn't deletable/writable/editable, but contents have to be up to date from actual system.
      • /home/<user>/web/www — isn't itself deletable/editable, but contents can be freely created/edited/deleted.
        • /home/<user>/web/www/public — isn't itself deletable/editable (being more restrictive than parent directory), but contents can be freely created/edited/deleted.

Web server daemons (nginx, php-fpm) in return has to be able to:

  • write to /home/<user>/web/log
  • if user has provided appropriate scripts, write to /home/<user>/web/www and /home/<user>/web/www/public - and the user has to be able to see the changes
  • also has to be able to read from those directories.

I've got this far (virtual-webhost.profile):

# Allow access to mysql socket.
noblacklist /var/run/mysqld/mysqld.sock

# Allow known history files.
noblacklist ${HOME}/.bash_history
noblacklist ${HOME}/.mysql_history

# Default web settings.
whitelist ${HOME}/web/www
whitelist ${HOME}/web/log
read-only ${HOME}/web/log

# Extend upon generic profile.
include /etc/firejail/generic.profile

But this is not a good starting point, because whole of ${HOME} is hidden only the obvious whitelisted parts are available. Though, I need those .bash_history and .mysql_history files and will need others after I will be settled with ~/web struture.

Is this possible with firejail? (if it is, but only above LTS release, I could switch this package out to a more recent one)

P.S. I'm not a system administrator, nor a Linux specialist. I'm a web developer tasked to set up our in-house server, though, I am looking for a more refined setup - want some more security/isolation.

Originally created by @tomsseisums on GitHub (Oct 26, 2017). Original GitHub issue: https://github.com/netblue30/firejail/issues/1620 I am on Ubuntu 16.04 LTS, therefore using the LTS version of firejail 0.9.38.10. I am looking for a way to enforce a specific/strict structure for web virtual hosts on a somewhat shared hosting server. My idea is to serve from each users home, where each user acts as a single vhost/domain. This is necessary because the virtual hosts also require SSH access, but I don't want to give them too much freedom to roam around. Otherwise I could, for example, set up sftp-chroot's through openssh. So, with directory structure like this: - `/home/<user>` - `/home/<user>/web` - `/home/<user>/web/log` - `/home/<user>/web/www` - `/home/<user>/web/www/public` Is it possible to configure permissions such that: - `/home/<user>` — remains as homes are by default, though, I may restrict it even more in future. - `/home/<user>/web` — isn't deletable/writable/editable, including contents. - `/home/<user>/web/log` — isn't deletable/writable/editable, but contents have to be up to date from actual system. - `/home/<user>/web/www` — isn't itself deletable/editable, but contents can be freely created/edited/deleted. - `/home/<user>/web/www/public` — isn't itself deletable/editable (being more restrictive than parent directory), but contents can be freely created/edited/deleted. Web server daemons (nginx, php-fpm) in return has to be able to: - write to `/home/<user>/web/log` - if user has provided appropriate scripts, write to `/home/<user>/web/www` and `/home/<user>/web/www/public` - and the user has to be able to see the changes - also has to be able to read from those directories. I've got this far (`virtual-webhost.profile`): ``` # Allow access to mysql socket. noblacklist /var/run/mysqld/mysqld.sock # Allow known history files. noblacklist ${HOME}/.bash_history noblacklist ${HOME}/.mysql_history # Default web settings. whitelist ${HOME}/web/www whitelist ${HOME}/web/log read-only ${HOME}/web/log # Extend upon generic profile. include /etc/firejail/generic.profile ``` But this is not a good starting point, because whole of `${HOME}` is hidden only the obvious whitelisted parts are available. Though, I need those `.bash_history` and `.mysql_history` files and will need others after I will be settled with `~/web` struture. Is this possible with firejail? (if it is, but only above LTS release, I could switch this package out to a more recent one) P.S. I'm not a system administrator, nor a Linux specialist. I'm a web developer tasked to set up our in-house server, though, I am looking for a more refined setup - want some more security/isolation.
gitea-mirror added the
question_old
label 2026-05-05 07:26:04 -06:00
Author
Owner

@netblue30 commented on GitHub (Oct 29, 2017):

You can definitely build something like this. Let's say this is the directory structure:

  • /home/<user>
    • /home/<user>/web
      • /home/<user>/web/log
      • /home/<user>/web/www

As root, you start the server:

firejail --profile=somefile.profile --bind=/home/<user>web/www,/var/www /etc/init.d/nginx start

For somefile.profile use server.profile as a starting point. You will also have to use --net and --ip on the command line or in the profile to give him a network namespace, so all users have a webserver on the regular 80 tcp port.

The only thing missing in this moment is /home/<user>/web/log handling. Currently /var/log goes in a tmpfs accessible only from inside the sandbox. We can add support to have it as a mount-bin in user home directory.

As for the user, you can sandbox him when he logs in over ssh, look at man firejail-login.

<!-- gh-comment-id:340262197 --> @netblue30 commented on GitHub (Oct 29, 2017): You can definitely build something like this. Let's say this is the directory structure: - `/home/<user>` - `/home/<user>/web` - `/home/<user>/web/log` - `/home/<user>/web/www` As root, you start the server: ````` firejail --profile=somefile.profile --bind=/home/<user>web/www,/var/www /etc/init.d/nginx start ````` For somefile.profile use server.profile as a starting point. You will also have to use --net and --ip on the command line or in the profile to give him a network namespace, so all users have a webserver on the regular 80 tcp port. The only thing missing in this moment is `/home/<user>/web/log` handling. Currently /var/log goes in a tmpfs accessible only from inside the sandbox. We can add support to have it as a mount-bin in user home directory. As for the user, you can sandbox him when he logs in over ssh, look at man firejail-login.
Author
Owner

@tomsseisums commented on GitHub (Oct 29, 2017):

I'm not looking to sandbox nginx, was pointing the necessities for nginx so that the settings for SSH sandboxing do not clash with the underlying system.

I guess, I overshot a little with the question details.

My main concern is to enforce the structure for the SSH session.

<!-- gh-comment-id:340262511 --> @tomsseisums commented on GitHub (Oct 29, 2017): I'm not looking to sandbox nginx, was pointing the necessities for nginx so that the settings for SSH sandboxing do not clash with the underlying system. I guess, I overshot a little with the question details. My main concern is to enforce the structure for the SSH session.
Author
Owner

@netblue30 commented on GitHub (Oct 29, 2017):

You keep a single SSH server running on the system without any sandboxing, and sandbox strictly the user session at login time. In /etc/firejail/login.users you can add any firejail command line options, including a --profile command. By default it picks up default.profile.

Parts of user home directory are shared between the sandboxed SSH login session and the sandboxed web server - if I understand your question.

<!-- gh-comment-id:340263111 --> @netblue30 commented on GitHub (Oct 29, 2017): You keep a single SSH server running on the system without any sandboxing, and sandbox strictly the user session at login time. In /etc/firejail/login.users you can add any firejail command line options, including a --profile command. By default it picks up default.profile. Parts of user home directory are shared between the sandboxed SSH login session and the sandboxed web server - if I understand your question.
Author
Owner

@tomsseisums commented on GitHub (Oct 29, 2017):

But how do I prevent some of the parts of the home directory to be modified by the sandboxed user?

Like, to enforce these "laws":

  • /home/<user>/web — isn't deletable/writable/editable, including contents.
    • /home/<user>/web/log — isn't deletable/writable/editable, but contents have to be up to date from actual system.
    • /home/<user>/web/www — isn't itself deletable/editable, but contents can be freely created/edited/deleted.
      • /home/<user>/web/www/public — isn't itself deletable/editable, but contents can be freely created/edited/deleted.
<!-- gh-comment-id:340263603 --> @tomsseisums commented on GitHub (Oct 29, 2017): But how do I prevent some of the parts of the home directory to be modified by the sandboxed user? Like, to enforce these "laws": - `/home/<user>/web` — isn't deletable/writable/editable, including contents. - `/home/<user>/web/log` — isn't deletable/writable/editable, but contents have to be up to date from actual system. - `/home/<user>/web/www` — isn't itself deletable/editable, but contents can be freely created/edited/deleted. - `/home/<user>/web/www/public` — isn't itself deletable/editable, but contents can be freely created/edited/deleted.
Author
Owner

@netblue30 commented on GitHub (Oct 29, 2017):

/home/<user>/web/log will owned actually by root, so the user cannot write to it.

/home/<user>/web/www — isn't itself deletable/editable, but contents can be freely

This is a little bit difficult. You can make /home/<user>/web/www owned by root, and a directory /home/<user>/web/www/html owned by the user. The user won't be able to delete /home/<user>/web/www/html or add new files in /home/<user>/web/www, but he will be able to add or modify anything inside /home/<user>/web/www/html.

<!-- gh-comment-id:340265392 --> @netblue30 commented on GitHub (Oct 29, 2017): `/home/<user>/web/log` will owned actually by root, so the user cannot write to it. > `/home/<user>/web/www` — isn't itself deletable/editable, but contents can be freely This is a little bit difficult. You can make `/home/<user>/web/www` owned by root, and a directory `/home/<user>/web/www/html` owned by the user. The user won't be able to delete `/home/<user>/web/www/html` or add new files in `/home/<user>/web/www`, but he will be able to add or modify anything inside `/home/<user>/web/www/html`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#1086
No description provided.