Network related interfaces don't permit to execute netplan

Hi there,
I need to permit to a snap of configure the network : for example setting vlan etc.
I would like to use netplan framework to accomplish this feature.
I am using a private store where the reviewing process is on my hand.
I connect the following interface:

  • network-setup-control
  • network-setup-observe

This interface permit to read and write file on netplan configuration folder, but don’t permit to run netplan executable present in the core snap.
The result is that I can only change network setting by rebooting the board.

For overcoming the problem I try to staging the netplan package in my snap, but I have a further problem:
the netplan apply command need to use /lib/netplan/geerate - it seems hardcoded but i don’t check it- but not the my snap version.
The error is:

Jun 22 07:45:05 localhost kernel: [53496.504016] audit: type=1400 audit(1498117505.312:3913): apparmor="DENIED" operation="exec" profile="snap.netplan-poc.daemon-netplan" name="/lib/netplan/generate" pid=29828 comm="netplan" requested_mask="x" denied_mask="x" fsuid=0 ouid=0

I check the code of snapd for a interface that permit to run netplan executable but I didn’t find it: maybe am I wrong?

If my check is good, then I think that the only way for accomplish my task is connecting the network-control interface and using iproute2 utilities for setting up the network without reboot the board.
is it correct and the good way for implement dinamic network setting on ubuntu core powered board?

Cheers,
Nicolino

Not allowing /lib/netplan/generate is simply a bug in the interfaces code and just needs to be added somewhere. Looking at /lib/netplan/generate --help it seems like the only thing it does is “Generate backend network configuration from netplan YAML definition” and so I think that adding this to network-setup-control makes sense:

/lib/netplan/generate ixr,

@NCuralli, can you add the above line to /var/lib/snapd/apparmor/profiles/snap.netplan-poc.daemon-netplan (before the trailing ‘}’, then run:

$ sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/snap.netplan-poc.daemon-netplan

and report back either way if it works? If it does, I can prepare a PR to get this fixed up (though there might be some discussion on if this should be in network-setup-control vs network-control, but we can discuss that in the PR if it comes up).

thanks @jdstrand.
the new apparmor rule fix the prevoius problem but it hits several one.

I obtain with the new rule in place the following log row:

Jun 22 13:19:38 localhost kernel: [  469.116245] audit: type=1400 audit(1498137578.294:124): apparmor="DENIED" operation="open" profile="snap.netplan-poc.daemon-netplan" name="/run/systemd/network/" pid=4864 comm="generate" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
Jun 22 13:19:38 localhost kernel: [  469.116542] audit: type=1400 audit(1498137578.294:125): apparmor="DENIED" operation="unlink" profile="snap.netplan-poc.daemon-netplan" name="/run/NetworkManager/conf.d/netplan.conf" pid=4864 comm="generate" requested_mask="d" denied_mask="d" fsuid=0 ouid=0
Jun 22 13:19:38 localhost kernel: [  469.117248] audit: type=1400 audit(1498137578.294:126): apparmor="DENIED" operation="mknod" profile="snap.netplan-poc.daemon-netplan" name="/run/systemd/network/10-netplan-eth0.network.USKD2Y" pid=4864 comm="generate" requested_mask="c" denied_mask="c" fsuid=0 ouid=0

Perhaps it make sense whitelisting the “/usr/sbin/netplan” executable when the network-control interface is connected.
/usr/sbin/netplan and /lib/netplan/generate are strongly related.

Cheers,
Nicolino

It’s still not clear to me if this should be in network-control or not, but that’s ok. Let’s get the full ruleset going and then decide. Can you make sure network-control is not plugged, then add to your profile:

/lib/netplan/generate ixr,
/usr/sbin/netplan ixr,
/run/systemd/network/ r,
/run/systemd/network/*-netplan-* rw,
/run/NetworkManager/conf.d/*.conf rw,

then try again? Feel free to continue adding rules until you have something that works (use ‘ixr’ for executables, ‘r’ for read and ‘w’ for write and ‘rw’ for both).

@jdstrand I am also not able to use netplan generate and netplan apply from with in the snap. Do we still have to do all these manual work to get it working ? Like the OP, I am connecting my snap to network-manager, network-setup-control and network-control interfaces.

I would have to see the logged denials from journalctl (I didn’t hear back on my last question in nthis topic, so this didn’t move forward appreciably).

Here are the logs for your reference.

INFO: $ sudo journalctl --output=short --follow --all | sudo snappy-debug.security scanlog
kernel.printk_ratelimit = 0
= AppArmor =
Time: Feb 28 02:01:30
Log: apparmor="DENIED" operation="exec" profile="snap.mysnap.myser" name="/usr/sbin/netplan" 
pid=22628 comm="sh" requested_mask="x" denied_mask="x" fsuid=0 ouid=0
File: /usr/sbin/netplan (exec)
Suggestions:
* adjust snap to ship 'netplan'
* adjust program to use relative paths if the snap already ships 'netplan'

= AppArmor =
Time: Feb 28 02:01:30
Log: apparmor="DENIED" operation="exec" profile="snap.mysnap.myser" name="/usr/sbin/netplan" 
pid=22629 comm="sh" requested_mask="x" denied_mask="x" fsuid=0 ouid=0
File: /usr/sbin/netplan (exec)
Suggestions:
* adjust snap to ship 'netplan'
* adjust program to use relative paths if the snap already ships 'netplan'

@jdstrand any updates/suggestions on this ?

Sorry I missed your reply from last week. I may have not been clear in my request for more information on Network related interfaces don't permit to execute netplan.

Please add this to /var/lib/snapd/apparmor/profiles/snap.mysnap.myser:

/lib/netplan/generate ixr,
/usr/sbin/netplan ixr,
/run/systemd/network/ r,
/run/systemd/network/*-netplan-* rw,
/run/NetworkManager/conf.d/*.conf rw,

then load the policy into the kernel with sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/snap.mysnap.myser and try again. Then feel free to continue adding rules until you have something that works (use ‘ixr’ for executables, ‘r’ for read and ‘w’ for write and ‘rw’ for both). When it works or you get stuck, please report the rules you added and any lingering denials.

Thanks!

Updated Rules

/lib/netplan/generate ixr,
/usr/sbin/netplan ixr,
/run/systemd/network/ r,
/run/systemd/network/*-netplan-* rw,
/run/NetworkManager/conf.d/*.conf.* rw,
/run/NetworkManager/conf.d/*.conf rw,
/run/netplan/* rw,
/run/systemd/system/multi-user.target.wants/* r,

Here are the logs after updating the rules

INFO: following '/var/log/syslog'. If have dropped messages, use:
INFO: $ sudo journalctl --output=short --follow --all | sudo snappy-debug.security scanlog
kernel.printk_ratelimit = 0
WARN: could not find log mark, is syslog enabled?
= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/usr/sbin/" pid=13649 

comm=“netplan” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
File: /usr/sbin/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON,
$SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/run/netplan/" pid=13653 comm="generate" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /run/netplan/ (read)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" 
name="/run/systemd/system/multi-user.target.wants/" pid=13653 comm="generate" 
requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /run/systemd/system/multi-user.target.wants/ (read)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="connect" profile="snap.mysnap.myser" name="/run/udev/control" pid=13654 comm="udevadm" requested_mask="wr" denied_mask="wr" fsuid=0 ouid=0
File: /run/udev/control (write)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/usr/sbin/" pid=13655 
comm="netplan" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /usr/sbin/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, 
$SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/run/netplan/" 
pid=13656 comm="generate" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /run/netplan/ (read)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" 
name="/run/systemd/system/multi-user.target.wants/" pid=13656 comm="generate" 
requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /run/systemd/system/multi-user.target.wants/ (read)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="connect" profile="snap.mysnap.myser" name="/run/udev/control" 
pid=13657 comm="udevadm" requested_mask="wr" denied_mask="wr" fsuid=0 ouid=0
File: /run/udev/control (write)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="exec" profile="snap.mysnap.myser" name="/bin/systemctl" 
pid=13658 comm="netplan" requested_mask="x" denied_mask="x" fsuid=0 ouid=0
File: /bin/systemctl (exec)
Suggestions:
* adjust snap to ship 'systemctl'
* adjust program to use relative paths if the snap already ships 'systemctl'admin@FT8TB02:~$ sudo 
snappy-debug.security scanlog mysnap
INFO: following '/var/log/syslog'. If have dropped messages, use:
INFO: $ sudo journalctl --output=short --follow --all | sudo snappy-debug.security scanlog
kernel.printk_ratelimit = 0
WARN: could not find log mark, is syslog enabled?
= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/usr/sbin/" pid=13649 
comm="netplan" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /usr/sbin/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, 
$SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/run/netplan/" 
pid=13653 comm="generate" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /run/netplan/ (read)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/run/systemd/system/multi-user.target.wants/" pid=13653 comm="generate" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /run/systemd/system/multi-user.target.wants/ (read)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="connect" profile="snap.mysnap.myser" name="/run/udev/control" pid=13654 comm="udevadm" requested_mask="wr" denied_mask="wr" fsuid=0 ouid=0
File: /run/udev/control (write)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/usr/sbin/" pid=13655 comm="netplan" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /usr/sbin/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/run/netplan/" pid=13656 comm="generate" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /run/netplan/ (read)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="open" profile="snap.mysnap.myser" name="/run/systemd/system/multi-user.target.wants/" pid=13656 comm="generate" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /run/systemd/system/multi-user.target.wants/ (read)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="connect" profile="snap.mysnap.myser" name="/run/udev/control" pid=13657 comm="udevadm" requested_mask="wr" denied_mask="wr" fsuid=0 ouid=0
File: /run/udev/control (write)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  6 22:20:27
Log: apparmor="DENIED" operation="exec" profile="snap.mysnap.myser" name="/bin/systemctl" pid=13658 comm="netplan" requested_mask="x" denied_mask="x" fsuid=0 ouid=0
File: /bin/systemctl (exec)
Suggestions:
* adjust snap to ship 'systemctl'
* adjust program to use relative paths if the snap already ships 'systemctl'

It looks like the netplan script is trying to access the systemctl command when trying to apply the rules, which is the reason why netplan fails when running from with in a snap.

"Traceback (most recent call last):; File "/usr/sbin/netplan", line 387, in <module>; eval('command_' + args.command.replace('-', '_'))(); File "/usr/sbin/netplan", line 276, in command_apply; subprocess.check_call(['systemctl', 'stop', '--no-block', 'systemd-networkd.service', 'netplan-wpa@*.service']); File "/usr/lib/python3.5/subprocess.py", line 576, in check_call; retcode = call(*popenargs, **kwargs); File "/usr/lib/python3.5/subprocess.py", line 557, in call; with Popen(*popenargs, **kwargs) as p:; File "/usr/lib/python3.5/subprocess.py", line 947, in __init__; restore_signals, start_new_session); File "/usr/lib/python3.5/subprocess.py", line 1551, in _execute_child; raise child_exception_type(errno_num, err_msg); PermissionError: [Errno 13] Permission denied; ", Exception Keyword Arguments={}

Please add:

/usr/sbin/ r,
/run/netplan/ r,
/run/systemd/system/multi-user.target.wants/ r,
/run/udev/control rw,
/bin/systemctl Ux,

and try again. However, that last rule was what I was worried would happen. netplan having to start/stop daemons directly via systemd is very problematic because systemd isn’t designed for application isolation and attempting to use fine-grained rules for starting and stopping of specific daemons doesn’t work and results in a bunch of policy that in reality gives device ownership to the snap (this is why I used a Ux rule here).

Please continue with your policy investigation though (if you don’t mind)-- if this is the only thing, perhaps netplan could be modified to do something else, perhaps with the help of some new functionality within snapd. It would be interesting to known what netplan is using systemctl for (I’m guessing for interacting with NetworkManager and/or systemd-networkd).

It is basically trying to start/stop systemd-networkd.service and netplan-wpa as per the traceback. I will add the new rules and update the findings. Thanks.

After adding additional rules , here are the new set of denials

= AppArmor =
Time: Mar  7 14:27:10
Log: apparmor="DENIED" operation="mkdir" profile="snap.mysnap.myser" name="/run/netplan/" pid=2705 comm="generate" requested_mask="c" denied_mask="c" fsuid=0 ouid=0
File: /run/netplan/ (write)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  7 14:27:11
Log: apparmor="DENIED" operation="mkdir" profile="snap.mysnap.myser" name="/run/netplan/" pid=2707 comm="generate" requested_mask="c" denied_mask="c" fsuid=0 ouid=0
File: /run/netplan/ (write)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

I tried adding mask rw, cix, Cx, cux to /run/netplan and /run/netplan/* and also to /run/ but could not get rid of the error, I manually created the directory /run/netplan and then a different set of error started popping up

= AppArmor =
Time: Mar  7 14:36:13
Log: apparmor="DENIED" operation="mkdir" profile="snap.mysnap.myser" name="/run/systemd/system/multi-user.target.wants/" pid=2799 comm="generate" requested_mask="c" denied_mask="c" fsuid=0 ouid=0
File: /run/systemd/system/multi-user.target.wants/ (write)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

= AppArmor =
Time: Mar  7 14:36:14
Log: apparmor="DENIED" operation="mkdir" profile="snap.mysnap.myser" name="/run/systemd/system/multi-user.target.wants/" pid=2801 comm="generate" requested_mask="c" denied_mask="c" fsuid=0 ouid=0
File: /run/systemd/system/multi-user.target.wants/ (write)
Suggestions:
* adjust program to use $SNAP_DATA
* adjust program to use run/shm/snap.$SNAP_NAME.*

Note that the denial ends with ‘/’, which applies to the directory, so you need to make sure that the apparmor rule has it. Eg:

/run/netplan/ rw,
/run/systemd/system/multi-user.target.wants/ rw,

This is the final set of rules I had to add to get the netplan working from with in the snap. I am yet to test if these changes persist across reboot . But at-least for now apparmor does not throw any errors .

/lib/netplan/generate ixr,
/usr/sbin/netplan ixr,
/run/systemd/network/ r,
/run/systemd/network/*-netplan-* rw,
/run/NetworkManager/conf.d/*.conf.* rw,
/run/NetworkManager/conf.d/*.conf rw,
/run/netplan/* rw,
/run/systemd/system/multi-user.target.wants/* r,
/usr/sbin/ r,
/run/netplan/ r,
/run/systemd/** rw,
/run/systemd/** cix,
/run/udev/control rw,
/bin/systemctl Ux,
/root/build/** r,
/home/admin/build/** r,
/run/netplan/ rw,
/run/systemd/system/multi-user.target.wants/ rw,
/run/NetworkManager/conf.d/ rw,
/etc/systemd/network/ r,
/sys/bus/sdio/drivers/** rw,

I will run some more tests and on an another device to confirm if these rules really work or not. Many thanks for the hints.

Such manual changes to apparmor snap command profiles do not persist across reboot. AIUI, this was an exercise to determine a set of rules that can work for ‘netplan apply’, not an approach for persistently and manually changing apparmor profiles, which would not be OK for security reasons. See netplan-apply-inside-snaps for the plans for enabling netplan apply from a snap.