PermissionError: Unable to create paho python mqtt client instance in snap

I’m trying to create a snap of my python application but getting PermissionError: [Errno 13] Permission denied error.

In my application, I have a module config_mqtt.py where I’m trying to create the instance of paho pathon mqtt client as follows:

import paho.mqtt.client as mqtt


def init():

    print(mqtt)

    client = mqtt.Client()

    print(client)

This is working without snap.
But after installing the snap when I run it, I’m getting following error:

sudo config-mqtt
[sudo] password for yahya: 
<module 'paho.mqtt.client' from '/snap/config-mqtt/x1/lib/python3.6/site-packages/paho/mqtt/client.py'>
Traceback (most recent call last):
  File "/snap/config-mqtt/x1/bin/config-mqtt", line 11, in <module>
    load_entry_point('config-mqtt==0.1.dev0', 'console_scripts', 'config-mqtt')()
  File "/snap/config-mqtt/x1/lib/python3.6/site-packages/config_mqtt/config_mqtt.py", line 9, in init
    client = mqtt.Client()
  File "/snap/config-mqtt/x1/lib/python3.6/site-packages/paho/mqtt/client.py", line 566, in __init__
    self._sockpairR, self._sockpairW = _socketpair_compat()
  File "/snap/config-mqtt/x1/lib/python3.6/site-packages/paho/mqtt/client.py", line 270, in _socketpair_compat
    socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_IP)
  File "/snap/config-mqtt/x1/usr/lib/python3.6/socket.py", line 144, in __init__
    _socket.socket.__init__(self, family, type, proto, fileno)
PermissionError: [Errno 13] Permission denied

any help to fix this error?
many thanks

Check the syslog for DENIED messages from apparmor. You can also use snappy-debug from the store to get helpful hints as to interfaces that are required; just install and then run at the same time you run your app to see what it detects is being denied and any potential mitigations.

I suspect you’re missing either network or network-bind interface plug.

thank you very much.
I could get the following error message from armor:

= AppArmor =
Time: Feb 18 16:38:46
Log: apparmor="DENIED" operation="file_inherit" profile="/snap/core/8592/usr/lib/snapd/snap-confine" pid=9606 comm="snap-confine" family="unix" sock_type="seqpacket" protocol=0 requested_mask="send receive" denied_mask="send receive" addr=none peer_addr=none

= AppArmor =
Time: Feb 18 16:38:46
Log: apparmor="DENIED" operation="file_inherit" profile="/snap/core/8592/usr/lib/snapd/snap-confine" pid=9606 comm="snap-confine" family="unix" sock_type="stream" protocol=0 requested_mask="send receive" denied_mask="send receive" addr=none peer_addr=none

= AppArmor =
Time: Feb 18 16:38:46
Log: apparmor="DENIED" operation="file_inherit" profile="snap-update-ns.config-mqtt" name="/dev/pts/2" pid=9629 comm="7" requested_mask="wr" denied_mask="wr" fsuid=0 ouid=1000
File: /dev/pts/2 (write)

= AppArmor =
Time: Feb 18 16:38:46
Log: apparmor="DENIED" operation="file_inherit" profile="snap-update-ns.config-mqtt" name="/apparmor/.null" pid=9629 comm="7" requested_mask="wr" denied_mask="wr" fsuid=0 ouid=0
File: /apparmor/.null (write)
Suggestion:
* adjust program to write to $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

I’m not sure which option I should pick because I’m not writing anything.

I have added network interface to .yaml file below the command line as:

    plugs:
      - network

but still getting the error:

<module 'paho.mqtt.client' from '/snap/config-mqtt/x1/lib/python3.6/site-packages/paho/mqtt/client.py'>
Traceback (most recent call last):
  File "/snap/config-mqtt/x1/bin/config-mqtt", line 11, in <module>
    load_entry_point('config-mqtt==0.1.dev0', 'console_scripts', 'config-mqtt')()
  File "/snap/config-mqtt/x1/lib/python3.6/site-packages/config_mqtt/config_mqtt.py", line 9, in init
    client = mqtt.Client()
  File "/snap/config-mqtt/x1/lib/python3.6/site-packages/paho/mqtt/client.py", line 566, in __init__
    self._sockpairR, self._sockpairW = _socketpair_compat()
  File "/snap/config-mqtt/x1/lib/python3.6/site-packages/paho/mqtt/client.py", line 273, in _socketpair_compat
    listensock.listen(1)
PermissionError: [Errno 1] Operation not permitted

and in the apparmor:

= AppArmor =
Time: Feb 19 09:06:40
Log: apparmor="DENIED" operation="file_inherit" profile="snap.config-mqtt.config-mqtt" name="/snap/code/25/usr/share/code/chrome_100_percent.pak" pid=8873 comm="snap-exec" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /snap/code/25/usr/share/code/chrome_100_percent.pak (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

plugs: [network] also has the same error.
@ogra
any thoughts to fix this please?

thanks

add network-bind as well, like @lucyllewy suggested above …

Thank you very much for your reply.
I have updated yaml file as:

plugs: [network, network-bind, ssh-keys, home]

But still getting the error.
In my python module, I’m trying to read a .crt file as follows:

client.tls_set('ca-certificates.crt')

from the apparmor:

= AppArmor =
Time: Feb 19 10:58:42
Log: apparmor="DENIED" operation="open" profile="snap.olibox-core.olibox-core" name="/home/yahya/Documents/GitHub/olibox_core/ca-certificates.crt" pid=31499 comm="python3" requested_mask="r" denied_mask="r" fsuid=0 ouid=1000
File: /home/yahya/Documents/GitHub/olibox_core/ca-certificates.crt (read)
Suggestion:
* add 'home' to 'plugs'

from the console:

Traceback (most recent call last):
  File "/snap/olibox-core/x1/lib/python3.6/site-packages/olibox_core/olibox_core/olibox_core.py", line 63, in main
    connect_mqtt()
  File "/snap/olibox-core/x1/lib/python3.6/site-packages/olibox_core/olibox_core/olibox_core.py", line 45, in connect_mqtt
    client = pkg.config_mqtt()
  File "/snap/olibox-core/x1/lib/python3.6/site-packages/olibox_core/olibox_core/olibox_pkg/oli_mqtt.py", line 82, in config_mqtt
    client.tls_set('ca-certificates.crt')
  File "/snap/olibox-core/x1/lib/python3.6/site-packages/paho/mqtt/client.py", line 827, in tls_set
    context.load_verify_locations(ca_certs)
PermissionError: [Errno 13] Permission denied

I have already added home to plugs.
The .crt file and the python module are in the same directory.
I also place the .crt file in project home directory as well (just to avoid path issues).

I’m not sure if I have to move .crt file to $SNAP_USER_DATA.
any guidance please? thanks

@ogra
I have update my script to copy the .crt file from project root directory to $SNAP_USER_DATA as:

cp ./ca-certificates.crt $SNAP_USER_DATA/ca-certificates.crt

when I run the snap I get error to copy the file:

cp: cannot open './ca-certificates.crt' for reading: Permission denied

that ultimately leads to file not found error.
I’m missing any other permission interface to copy certificate files?

well, is the filew actually readable by your user ? what are the file permissions ?

Its a cerficate file that works fine without snap.
In normal app this file is working fine and being used.
I didn’t set any permission and I’m not sure about it.

from the apparmor:

= AppArmor =
Time: Feb 19 11:42:12
Log: apparmor="DENIED" operation="open" profile="snap.olibox-core.olibox-core" name="/proc/6399/mounts" pid=6399 comm="python3" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
File: /proc/6399/mounts (read)
Suggestions:
* adjust program to not access '@{PROC}/@{pid}/mounts'
* add one of 'mount-observe, network-control' to 'plugs'

I have already added mount-observe and network-control.
can you please help me out to adjust program to not access '@{PROC}/@{pid}/mounts', how can I do this? thanks

did you also connect the interfaces after installing your snap not all of them auto-connect …

check with snap connections olibox-core (and connect the unconnected ones)

I can see the following interfaces:

Interface      Plug                       Slot           Notes
home           olibox-core:home           :home          -
mount-observe  olibox-core:mount-observe  -              -
network        olibox-core:network        :network       -
network-bind   olibox-core:network-bind   :network-bind  -
ssh-keys       olibox-core:ssh-keys       -              -

I’m not using auto-connect option, hut using them as plugs: [network, network-bind, ssh-keys, home, mount-observe].

I’m not sure, do I need to set some permissions on .crt file like sudo chmod 644 ca-certificates.crt?

It looks like you’re trying to copy a file from outside the snap into $SNAP_USER_DATA. How do you plan to guarantee that this file will exist on users’ systems and will exist in the location you expect it to?

Your code above copies from ./ which means the current working directory. This will be whatever directory that the user is within when launching the application, and cannot be guaranteed unless you first do a cd /known/path/location first.

The current file permission are :

-rw-r--r-- 1 yahya yahya 235192 Jan 15 17:18 ca-certificates.crt

Yes, I already have the file there.

In my bash script, I included the command that will copy the file when we run the application.

is that not possible to copy the file from home directory to $SNAP_USER_DATA? or do I need to place the file to some other location?

mount-observe is not connected, you need to manually connect it …

can you please be kind enough to guide me how can I do this manually?

see:

snap connect --help

Its now connected:

Interface      Plug                       Slot            Notes
home           olibox-core:home           :home           -
mount-observe  olibox-core:mount-observe  :mount-observe  manual
network        olibox-core:network        :network        -
network-bind   olibox-core:network-bind   :network-bind   -
ssh-keys       olibox-core:ssh-keys       -               -

but still there is same error.

you mean it still complains about /proc/*/mounts ?
you are jumping back and forth between topics here, this is very hard to follow … could you work on one thing at a time ?