Firejail: Need better way of managing order of options vis-a-vis implicitly-loaded profiles

Created on 18 Oct 2018  路  9Comments  路  Source: netblue30/firejail

As I understand it, Firejail processes command-line options and profile-file directives in the order that they appear on the command line (with profiles based on the name of the program implicitly appearing at the end). The order is significant in many cases, with the correct jail behavior resulting only if the directives are ordered correctly.

An example of this ordering is the hostname directive. Say that you want to run a program named hello, with a Firejail profile /etc/firejail/hello.profile. This profile contains a hostname hello-machine line.

If I run firejail hello, then the program sees a hostname of hello-machine, as expected.

If I run firejail --hostname=goodbye-machine hello, then the program still sees a hostname of hello-machine. The hello.profile file is loaded after the --hostname option is processed, and the hostname hello-machine directive effectively "overwrites" the value previously set on the command line.

Now, if I run firejail --profile=/etc/firejail/hello.profile --hostname=goodbye-machine hello, then and only then does the program get goodbye-machine. Because the --hostname option now comes after the directive in the profile.

But in order to get that desired behavior, I have to give up the implicit profile load, and instead load the profile explicitly. Wouldn't it be nice if I could specify that I want --hostname (or whatever other option) to be processed after the profile, but without having to change how the profiles are specified?

For example, an invocation like firejail --after-profile --hostname=goodbye-machine hello, in which a special option (--after-profile) indicates that all subsequent options should be processed after the profile is loaded.

After discovering through experimentation the importance of the order in which Firejail options are processed, I'd want something like this to help make it easier to get that right.

enhancement

Most helpful comment

That's fair; just remember that the original issue was not that certain setups are impossible, only that the config model is awkward in some cases (due to ordering) and could stand some improvement. If one doesn't mind e.g. writing a profile for every possible permutation of options needed, then this won't be an issue, but I'd like to see more flexibility to the end result of conciseness and reduced redundancy in the configuration. (Which tends to be a net positive for security, too.)

All 9 comments

firejail --hostname=goodbye-machine --ignore=hostname hello should do what you want therefore I don't think --after-profile is much improvement and worth additional complexity. After brief look I didn't find any other option affected by ordering.

I only chose hostname as a simple example to demonstrate ordering of directives. There are more complex scenarios, like interactions between noblacklist, whitelist and read-only for a given directory, where the ignore directive does little to help.

Can you give example commands which doesn't work as expected?

One example is --read-only versus --read-write. If you want to make everything under ~/.config/ read-only except for one directory ~/.config/foo/, then Firejail needs to see

read-only ~/.config
read-write ~/.config/foo

in that order, as the reverse will not work (the foo directory remains read-only). So if, say, the default profile has a read-only directive for a given directory, and you want to make a subdirectory writable, then you run into this problem.

An alternative course of action might be to treat ordering dependencies like this as a bug (outside of perhaps noblacklist, ignore, and a few other directives that are usually meant to come first) and ensure the same result regardless of order, but I don't know if that might have negative security implications. (In the above example, it could be advisable to print a warning like Making ~/.config read-only, but ~/.config/foo was previously made read-write)

In above passing firejail --read-only=~/.config --read-write=~/.config/foo should be enough as duplicate --read-only ~/.config from profile won't take effect after that.

Maybe others have any ideas if this syntax can be somewhat improved.

Having to put in redundant directives isn't a great approach. And if you're using the same options for different programs, which might have different profiles, then you get a read-only ~/.config whether or not the profile marks it as such.

A second read-only on the same directory is a no-op, then? That sounds like a partial fulfillment of making the profile directives independent of order...

I just wanted to point out that if someone is looking for a working solution then it exists. Setting it through .local profiles may be also less burdensome.

That's fair; just remember that the original issue was not that certain setups are impossible, only that the config model is awkward in some cases (due to ordering) and could stand some improvement. If one doesn't mind e.g. writing a profile for every possible permutation of options needed, then this won't be an issue, but I'd like to see more flexibility to the end result of conciseness and reduced redundancy in the configuration. (Which tends to be a net positive for security, too.)

I'd like to double what was said above about the configuration order. I don't think the entire current backwards system makes much sense compared to the far more prevalent last-set-wins. Firejail's awkward backwardness can be seen best in global profiles that need to load local ones _before_ their own settings, expecting local configuration to possibly ignore changes that follow. Presumably that's why the command line arguments are run _before_ the profile options, too, which prompted @iskunk to report the problem here. The backwardness makes for rather peculiar if not outright impossible situations where occasionally you'll need to ignore a later ignore... Not to mention configuration files are often loaded backwards and inwards as overrides need to appear _prior_ to defaults. Looking at a random profile, makepkg.profile, for example, shows how makepkg.local is loaded before globals.local, yet both are loaded before options in makepkg.profile itself. That's very confusing.

While there are a large number of existing profiles, I'd say it's worth simplifying the configuration semantics early. Usability improvements, even if they introduce temporary inconvenience, are worth in the long term. I'd suggest following what the majority of other configuration languages do, and that's reading configuration files top to bottom, with any new directive overwriting previously set values. One defaults.profile could be loaded at the top to provide a shared baseline. Local overrides would be loaded at the end of the file. The ignore pragma could be removed entirely. So could any warnings about reconfiguring previously set values, as honoring the latest setting would be the way to tweak global profiles. The same should apply to command line arguments, removing the need for the rather silly firejail --hostname=goodbye-machine --ignore=hostname hello workaround.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

dandelionred picture dandelionred  路  3Comments

reinerh picture reinerh  路  3Comments

Fincer picture Fincer  路  4Comments

fl-chris picture fl-chris  路  4Comments