Several issues found while setting up mandos on Ubuntu
Chris Vigelius
me at cv.gd
Wed Jul 15 15:42:08 CEST 2026
Hello,
I have recently deployed mandos on some servers and encountered some
bugs and issues:
1. server not working on Ubuntu 26.04 / Python 3.14
On 26.04, there is an AttributeError/PickleError as soon as the first
check is successful and mandos tries to pickle the result:
AttributeError: module '__main__' has no attribute 'ClientDBusAlternate'
...
_pickle.PicklingError: Can't pickle <class
'__main__.ClientDBusAlternate'>: it's not found as
__main__.ClientDBusAlternate
(see also attached log mandos_pickle_error.txt)
This problem does not appear on 24.04 / Python 3.12 with 1.8.19.
2. monitor broken on Ubuntu 26.04 / Python 3.14
Starting mandos-monitor results in ModuleNotFoundError:
Traceback (most recent call last):
File "/usr/sbin/mandos-monitor", line 41, in <module>
import urwid.curses_display
ModuleNotFoundError: No module named 'urwid.curses_display'
Note: urwid.curses_display IS installed and while "import
urwid.curses_display" does not work, "from urwid import curses_display"
does. I have no idea why.
This problem does not appear on 24.04 / Python 3.12 with 1.8.19.
3. mandos (server) package should depend on fping
The checker uses fping by default and fails if this package is not
installed, marking the hosts as disabled.
4. mandos-monitor shows deprecation warnings (minor)
datetime.utcnow() is deprecated as of Python 3.12, which causes python
to show warnings (breaking the urwid display). Replacing it with
datetime.now(timezone.utc) should solve this
5. Docs could have a "Getting started" section (minor)
Even though the docs and manpages have good reference documentation, it
is difficult for new users to figure out what to do to get started.
Something like
"Install mandos-client on the client you want to automatically unlock,
and install mandos on another server. Now run mandos-keygen --password
on the client, enter the necessary password and copy the resulting
config into /etc/mandos/clients.conf on the server"
would help a lot to get on the right track. The front page or the intro
man page would be a good place for that IMHO.
best regards,
Chris
-------------- next part --------------
root@[redacted]:/etc/mandos# mandos --debug
2026-07-15 13:15:12,322 mandos [1380449]: DEBUG: Did setuid/setgid to 132:136
2026-07-15 13:15:12,406 mandos [1380449]: WARNING: Could not load persistent state: No such file or directory
2026-07-15 13:15:12,407 mandos [1380449]: DEBUG: Creating client '...'
2026-07-15 13:15:12,407 mandos [1380449]: DEBUG: Key ID: BA...FE
2026-07-15 13:15:12,407 mandos [1380449]: DEBUG: Fingerprint: 5E...7D
2026-07-15 13:15:12,411 mandos [1380449]: INFO: Now listening on address '::', port 57155, flowinfo 0, scope_id 0
2026-07-15 13:15:12,412 mandos [1380449]: DEBUG: Avahi server state change: 2
2026-07-15 13:15:12,413 mandos [1380449]: DEBUG: Adding Zeroconf service 'Mandos' of type '_mandos._tcp' ...
2026-07-15 13:15:12,413 mandos [1380449]: DEBUG: Starting main loop
2026-07-15 13:15:12,414 mandos [1380449]: DEBUG: Avahi entry group state change: 1
2026-07-15 13:15:13,374 mandos [1380449]: DEBUG: Avahi entry group state change: 2
2026-07-15 13:15:13,374 mandos [1380449]: DEBUG: Zeroconf service established.
----------------------------------------
Exception occurred during processing of request from ('fd00:...:6fd2', 59090, 0, 0)
AttributeError: module '__main__' has no attribute 'ClientDBusAlternate'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.14/socketserver.py", line 318, in _handle_request_noblock
self.process_request(request, client_address)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/sbin/mandos", line 2614, in process_request
proc = MultiprocessingMixIn.process_request(self, request,
client_address)
File "/usr/sbin/mandos", line 2600, in process_request
proc.start()
~~~~~~~~~~^^
File "/usr/lib/python3.14/multiprocessing/process.py", line 121, in start
self._popen = self._Popen(self)
~~~~~~~~~~~^^^^^^
File "/usr/lib/python3.14/multiprocessing/context.py", line 230, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
File "/usr/lib/python3.14/multiprocessing/context.py", line 306, in _Popen
return Popen(process_obj)
File "/usr/lib/python3.14/multiprocessing/popen_forkserver.py", line 35, in __init__
super().__init__(process_obj)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
File "/usr/lib/python3.14/multiprocessing/popen_fork.py", line 20, in __init__
self._launch(process_obj)
~~~~~~~~~~~~^^^^^^^^^^^^^
File "/usr/lib/python3.14/multiprocessing/popen_forkserver.py", line 47, in _launch
reduction.dump(process_obj, buf)
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.14/multiprocessing/reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
_pickle.PicklingError: Can't pickle <class '__main__.ClientDBusAlternate'>: it's not found as __main__.ClientDBusAlternate
when serializing ClientDBusAlternate class
when serializing ClientDBusAlternate object
when serializing dict item 'odin'
when serializing dict item 'clients'
when serializing MandosServer state
when serializing MandosServer object
when serializing tuple item 0
when serializing method reconstructor arguments
when serializing method object
when serializing dict item '_target'
when serializing multiprocessing.context.Process state
when serializing multiprocessing.context.Process object
----------------------------------------
More information about the Mandos-Dev
mailing list