Access config file from snap

A Trippy user has reported an issue reading the application config file from /home when installed via snap.

I tried adding the home interface to the snap (edge channel, revision 2643) and connected it manually (with the intention of asking here for it to be auto-connected after testing it) but alas it still fails with Permission denied (os error 13):

fuji@trippy-dev:~$ sudo trip 1.1.1.1 --config-file /home/fuji/trippy.toml
Error: config file not found: "/home/fuji/trippy.toml"

Caused by:
    Permission denied (os error 13)

Can you advise what the issue may be?

Aside: in this example Iā€™ve specified a non-hidden file, however if a config file is not explicitly specified then Trippy will look for either trippy.toml or .trippy.toml in the usual places and so I imagine personal-files will be needed?

snap-id:      MuyJc7aas4HVkKbWZclsIhu0R9WAjX50
tracking:     latest/edge
refresh-date: today at 13:00 UTC
channels:
  latest/stable:    0.9.0 2023-11-30 (1943) 3MB -
  latest/candidate: ā†‘
  latest/beta:      ā†‘
  latest/edge:      0.9.0 2024-03-21 (2643) 3MB -
installed:          0.9.0            (2643) 3MB -

Connections after manually connecting the home on the edge channel:

fuji@trippy-dev:~$ sudo snap connections trippy
Interface        Plug                    Slot              Notes
home             trippy:home             :home             -
network          trippy:network          :network          -
network-bind     trippy:network-bind     :network-bind     -
network-observe  trippy:network-observe  :network-observe  -

Plugs (see here):

    plugs:
      - network-bind
      - network
      - network-observe
      - home

Previous thread for other interface this application needs for background: Request auto-connect (network-observe) for Trippy

Thanks

Well sudo makes you root so your homedir changes to be /root indeed ā€¦ why is that user running the tool with sudo ?

Thanks for the reply and the hint @ogra.

If I place the config file in /root then it can be found by the tool when run under sudo. However that is likely not the behaviour users would want, they would expect to be able to have their own config file in their own /home rather than a shared config file owned by root.

Usually you would use sudo -H to ā€œRequest that the security policy set the HOME environment variable to the home directory specified by the target userā€™s password database entryā€ (to quote from man sudo). It seems that the home interface in snap does not work that way? Specifically the interface allows the target user (root) to access their /home but not the /home of the initial user.

So the question is, does snap provide a way of achieving the desired behaviour?

Aside: for completeness I also tried both the usual techniques of achieve this as a non-root user and neither seem to work when installed as a snap (I guess by design):

sudo chown root $(which trip) && sudo chmod +s $(which trip)
sudo setcap CAP_NET_RAW+p $(which trip)

For reference the tool (usually) requires certain privileges to run, notably CAP_NET_RAW and hence the various network interface plugs.

Thanks

The home interface has an attribute read: that you can set to all which should allow an app to access all non-hidden files and dirs in all homesā€¦ that said, Iā€™m not sure what qualifies a package to get permission granted to use this option (it will likely be deniedby default since it opens a security hole for the snap), that would be a question to the reviewersā€¦

I did see that and felt it was likely overly broad and likely not appropriate. Itā€™s actually more permissive than classic confinement I think?

Taking a slightly different approach, Iā€™m now wondering, and trying to remember, if network-observe (which trippy already has) means it can use raw sockets without sudo, in effect if it emulates what CAP_NET_RAW does?

If so I could perhaps add an option to the application to say ā€œeven if we are not being run as root and do not have CAP_NET_RAW, assume we donā€™t need them in this execution environment and try anywayā€. Far from ideal but Iā€™m struggling to think of better options.

Perhaps moving to classic confinement would be a better option?

Classic would not be any option i think, unless you can prove your app falls into one of the few supported categories (which i doubt for a network scanner) from:

Expanding the home interface makes the snap surely less safe, but you can not compare that to classic at all (which simply drops all confinement)

If you could make it work with just network-observe Iā€™d go with thatā€¦ have you ever checked your package with snappy-debug ? Perhaps that would have even other suggestionsā€¦

Either way, if the extension of the home interface would help, you should file a store-request and see what the reviewers think ( i dont think they read the snapcraft category regularly), asking is cheap after all :wink:

If you could make it work with just network-observe Iā€™d go with that

I added a flag to the application (--unsafe-assume-privileged) to bypass detection of whether the application is running with elevated privileges (i.e. CAP_NET_RAW on Linux) but alas that fails, it seems you need both network-observe and to run with elevated privileges to open raw sockets. This is revision 2655 for reference.

have you ever checked your package with snappy-debug ? Perhaps that would have even other suggestionsā€¦

I gave this a try running the original command (sudo trip 1.1.1.1 --config-file trippy.toml) to try and read the config file from the user /home and get the following output:

= AppArmor =
Time: 2024-03-23T10:3
Log: apparmor="DENIED" operation="capable" class="cap" profile="snap.trippy.trippy" pid=2714576 comm="trip" capability=2  capname="dac_read_search"
Capability: dac_read_search
Suggestions:
* adjust program to not require 'CAP_DAC_READ_SEARCH' (see 'man 7 capabilities')
* add one of 'microstack-support, system-backup' to 'plugs'
* do nothing if program otherwise works properly

Reading the docs, neither of the suggestions sound appropriate:

Taking a step back, Iā€™d have thought a snap that (i) requires elevated privileges and (ii) needs to read a user configuration file would be a very common scenario and so have a simple solution, I feel we must be missing something obvious here? So Iā€™m at a bit of a loss on how to proceed here, do you have a suggestion?

Thanks again for the help.

Well, as i said above this is why the read: all option was added to the home interface

Here is an example:

To correct myself, the documentation for the home interface says (emphasis mine) ā€œwhen set to ā€˜allā€™, also allows reading non-hidden files in the home directories of all users as traditional file permissions allow.ā€. That last bit was the critical part I had missed (I had thought it allowed essentially root level access to all /home which would be a very scary permission to grant which is why I wasnā€™t keen!).

Given that definition, home: read: all is what is needed (ignoring hidden files for nowā€¦).

I just added that to the snapcraft.yaml as follows:

    plugs:
      - network-bind
      - network
      - network-observe
      - home:
          read: all

After updating and re-connecting the home interface it now shows it as manual (which I think makes sense as I have not requested auto-connect for it yet):

fuji@trippy-dev:/home/fuji$ sudo snap connections trippy
Interface        Plug                    Slot              Notes
home             trippy:home             :home             manual
network          trippy:network          :network          -
network-bind     trippy:network-bind     :network-bind     -
network-observe  trippy:network-observe  :network-observe  -

(aside: I donā€™t see any way using the snap tool to show all interfaces for a snap including showing the attributes such as read, this would be useful to verify that the changes have taken effect)

However, it still does not work:

fuji@trippy-dev:/home/fuji$ sudo trip 1.1.1.1 --config-file /home/fuji/trippy.toml
Error: config file not found: "/home/fuji/trippy.toml"

Caused by:
    Permission denied (os error 13)

The output from snappy-debug is as before:

= AppArmor =
Time: 2024-03-23T15:5
Log: apparmor="DENIED" operation="capable" class="cap" profile="snap.trippy.trippy" pid=2719366 comm="trip" capability=2  capname="dac_read_search"
Capability: dac_read_search
Suggestions:
* adjust program to not require 'CAP_DAC_READ_SEARCH' (see 'man 7 capabilities')
* add one of 'microstack-support, system-backup' to 'plugs'
* do nothing if program otherwise works properly

The (lack of) interfaces remove permissions, but adding interfaces canā€™t grant them. Some more context of the attribute would be e.g that Ubuntu had from 2006 til like 2022 or so, set default permissions on user folders so that users can view other peoples files (but not change them). Originally that was intended for home users where you might look at the photo album on your kids account. The snap policy effectively goes ā€œWe donā€™t actually want that to be possibleā€ ignoring the distribution policy. Even though the policy on Ubuntu itself has now changed for new installations, older upgraded releases could still carry their original config, and the @OWNER restriction still has effect there.

However, thereā€™s never a situation where an interface gives you more access than youā€™d have otherwise have. e.g., for the raw network ports interface, these still need sudo because whilst the interface itself wouldnā€™t stop you, the regular OS permissions would.

1 Like

AFAIU the plug definitions is incorrect of trippy app are wrong. What you need is:

...

apps:
  trippy:
    command: bin/trip
    plugs:
      - network-bind
      - network
      - network-observe
      - home

...
# top level plugs is where you add attributes
plugs:
  home:
    read: all

Iā€™m not quite sure how snapcraft accepted that, looks a bug maybe?

2 Likes

Thank you @mborzecki1 !

Iā€™ve adjusted the config and build a new version (#2667). It seems the additional of read: all has triggered the need for a manual review (OpenID transaction in progress shows Manual review pending and I got an email). As soon as it is reviewed Iā€™ll try this out.

Assuming that will work then iā€™ll jump to the next challenge; is there an equivalent of read: all for the personal-files interface to be able to read from hidden files and directories? It seems to accept an array of specific file paths rather than the anywhere ā€œas traditional file permissions allow.ā€ approach of home. Is this the best option?

1 Like

If you simply want to try it out, you can install the snap locally with --dangerous and then connect the plug manually using snap connect.

Sorry, there is no blanket read-all for personal files. This would go against the promise of the sandbox isolating the untrusted software from your system (eg. snap grabbing your SSH keys from $HOME/.ssh). You could say request $HOME/.config but I donā€™t think the store reviewers would grant such reques as itā€™s too boardā€¦ However, I think itā€™s ok to suggest to the users to store their configs at say $HOME/.config/trippy and then set up personal files to read/write that location.

Thanks for the tip; I downloaded the .snap file build by snapcraft, installed it locally and connected the plugs. Testing it and it works as expected for non-hidden files. Nice. Hopefully it isnā€™t a false positive (i.e. some checks being omitted for a local install and/or using --dangerous) .

Iā€™ll open a new post to ask for home to be auto-connected and refer the reviewers to this thread.

The issue with that is the application will not look there automatically and so users would be forced to add the config file path as a command line argument each time which is very cumbersome.

For reference the application looks for a configuration file in these place:

# Trippy will attempt to locate a `trippy.toml` or `.trippy.toml` config file
# in one of the following locations:
#   the current directory
#   the user home directory
#   the XDG config directory (Unix only): `$XDG_CONFIG_HOME` or `~/.config`

So even if I added support to the application for looking in $XDG_CONFIG_HOME/trippy/ for the file and whitelisted that path in the snap personal-files config then it still wouldnā€™t cover all cases (i.e. the users home dir, current dir cases). And of course this also assumes the user hasnā€™t changed their standard $XDG_CONFIG_HOME.

So if there are no better options then I think, for snap installs, I would prefer to note that configuration in hidden files and directories is not supported.

Thanks again for the help.

Request for auto-connect: Request auto-connect (home interface) for Trippy