Whonix AppArmor Profiles Development Discussion

No more denied messages.

Only issue I am experiencing is, when I run “sudo service sdwdate restart” with the sdwdate profile enabled, I don’t see the timesync gui anymore. Maybe I see the gui but the progress meter doesn’t move. Or the progress meter moves, but it doesn’t close when it reached 100%. This doesn’t happen when the sdwdate profile is disabled. Without any denied messages, any idea how to fix it?

Some new denied messages with ‘timesync --verbose’. The profile was updated.

I am still trying to find out why the gui is not showing with “sudo service sdwdate restart” when it is enforced. So far, I had not exactly the same symptoms as you have.

I installed gnome-keyring, now I am getting this.

And this.

Normally, all the pam_xxx.so files are in /lib/i386-linux-gnu/security/. Added ‘/lib/security/* mr,’ in sdwdate, time sync and whonixcheck, for safety.

Edit. With a typo i am correcting now…

Correction done.

Only issue I am experiencing is, when I run "sudo service sdwdate restart" with the sdwdate profile enabled, I don't see the timesync gui anymore. Maybe I see the gui but the progress meter doesn't move. Or the progress meter moves, but it doesn't close when it reached 100%. This doesn't happen when the sdwdate profile is disabled. Without any denied messages, any idea how to fix it?

It seems that the normal behavior when running “sudo service sdwdate restart” is that it does not show the timsesync progress window. There is no reference to timesync in the sdwdate scripts in /etc/init.d/ or /usr/bin/, and sdwdate on its own does not display anything.

From the test I have done, when you start or reboot the workstation, the gui will show after “sudo service sdwdate restart” only during the first sleeping period. After that, the gui is no longer displayed, regardless of the apparmor mode (enforce or disable). Just a guess, but it could have something to do with sdwdate running as a daemon and timesync on its own, in parallel. Aren’t both basically achieving the same thing?

sdwdate also needs read access to /var/lib/sdw_error.

It seems that the normal behavior when running "sudo service sdwdate restart" is that it does not show the timsesync progress window.

You can test on a fresh Whonix-Workstation 8 without any AppArmor profiles, if you run “sudo service sdwdate” restart you always get a progress bar window and the progress bar moves.

There is no reference to timesync in the sdwdate scripts in /etc/init.d/ or /usr/bin/, and sdwdate on its own does not display anything.

/etc/init.d/sdwdate and /usr/bin/sdwdate indeed do not include any GUI specific code. This is on purpose. The GUI code is implemented in /etc/sdwdate.d/31_timesync_plugin.

sdwdate evaluates the contents of $DISPATCH_PRE, which is for example “/usr/lib/whonix/timesync_pre --autostart --mode startup”.

From the test I have done, when you start or reboot the workstation, the gui will show after "sudo service sdwdate restart" only during the first sleeping period.
This is on purpose. This has to do with --mode startup vs. --mode daemon. When sdwdate starts after reboot or after sdwdate was upgraded by apt-get, $SDW_MODE will be startup. After the first run, next $SDW_MODE will be daemon. This because the user is advised to wait until sdwdate succeeded after the first boot of Whonix for better anonymity. When exactly subsequent runs of sdwdate are executed and how long they take is not so important. It only tries to avoid clock skews and long time likeability. For subsequent runs, sdwdate would only show if sdwdate failed. You can test that on a separate Whonix-Workstation without any AppArmor profiles, when no Whonix-Gateway is available for this Whonix-Workstation, the daemon sdwdate will fail and it's timesync plugin will launch a popup notification.

Another way to test sdwdate error handling is to run “sudo touch /var/lib/sdw_error”, after end of current sleep and in the next loop the the daemon an error will be provoked. In the log you will see.

6b170e95-07ee-47fe-b1d0-375e99f705fc: dispatching post_error (SDW_MODE: startup): /usr/lib/whonix/timesync_post_error "$error_message" & disown

And also a popup will be shown. (This command /usr/lib/whonix/timesync_post_error “$error_message” can also be used standalone for testing purposes.)

Aren't both basically achieving the same thing?
No. In essence, for one there is sdwdate, a standalone daemon which has been extended with a timesync plugin. From sdwdate perspective, the sdwdate plugin is used to inform terminal and X users about important events that would otherwise go unnoticed in syslog.

When timesync is started, it watches sdwdate’s log and runs “sudo service sdwdate restart”, keeps the user informed about sdwdate’s progress and status independently from sdwdate. (Manually run timesync would be able to diagnose sdwdate failures and bugs.)

I’ve written a sdwdate_simulator.

[code]#!/bin/bash

set -x
set -o pipefail

declare -g SDWDATE_POOL_NEUTRAL
declare -A -g SDWDATE_CURL_DISPATCH_PRE
declare -A -g SDWDATE_CURL_DISPATCH_POST

for i in /etc/sdwdate.d/*; do
if [ -f “$i” ]; then
## If the last character is a ~, ignore that file, because it was created
## by some editor, which creates backup files.
if [ “${i: -1}” = “~” ]; then
continue
fi
## Skipping files such as .dpkg-old and .dpkg-dist.
if ( echo “$i” | grep -q “.dpkg-” ); then
true "skip $i"
continue
fi
source "$i"
fi
done

SDW_MODE=“startup”

while true; do

#SDW_MODE=“daemon”

SDWDATE_CURRENT_POOL=“neutral”

Opens progress bar in X, informs

eval $DISPATCH_PRE

Checks if Tor has finished bootstrapping yet

#eval $DISPATCH_PREREQUISITE

sleep 5

Moves progress bar running curl for that pool.

true "Will run: eval ${SDWDATE_CURL_DISPATCH_PRE[SDWDATE_POOL_NEUTRAL]}"
eval ${SDWDATE_CURL_DISPATCH_PRE[SDWDATE_POOL_NEUTRAL]}

sleep 5

In case any tool exits an unexpected non-zero exit code while running sdwdate.

#eval $DISPATCH_POST_ERROR

Moves progress bar running curl after that pool.

true "Will run: eval ${SDWDATE_CURL_DISPATCH_POST[SDWDATE_POOL_NEUTRAL]}"
eval ${SDWDATE_CURL_DISPATCH_POST[SDWDATE_POOL_NEUTRAL]}

sleep 5

In case sdwdate succeeded.

eval $DISPATCH_POST_SUCCESS

In case sdwdate did not succeed, for example one pool was unreachable.

#eval $DISPATCH_POST_FAILURE

SDW_MODE=“daemon”

sleep 15

done
[/code]

This is what sdwdate basically does while leaving out the actual time synchronization code. You can use this for testing. Either to just look it at it as a reference how it’s working, or to write a profile for /usr/bin/sdwdate_simulator (just to find out what’s missing in the actual sdwdate profile), or use this code to temporarily replace the actual /usr/bin/sdwdate to make debugging the AppArmor profile easier.

I think it would be best if sdwdate was allowed to exec all /usr/lib/whonix/timesync_… scripts unconstrained by AppArmor profiles while also preserving the environment variables. I don’t think these scripts have potential to be exploited. I think what they need is unconstrained execute mode (ux) but I don’t know enough about AppArmor. This is because the /usr/lib/whonix/timesync_… scripts need lots of permissions for themselves for notification stuff which may not be allowed by the current sdwdate AppArmor profile.

I think it would be best if sdwdate was allowed to exec all /usr/lib/whonix/timesync_... scripts unconstrained by AppArmor profiles while also preserving the environment variables. I don't think these scripts have potential to be exploited. I think what they need is unconstrained execute mode (ux) but I don't know enough about AppArmor. This is because the /usr/lib/whonix/timesync_... scripts need lots of permissions for themselves for notification stuff which may not be allowed by the current sdwdate AppArmor profile.

I have authorized all /usr/lib/whonix/timesync_… scripts, including the ones not required by apparmor plus msgcollector and msgprogress, to run unconfined.

/usr/lib/whonix/timesync_pre rwUx,
/usr/lib/whonix/timesync_post_error rwUx,
/usr/lib/whonix/timesync_prerequisite rwUx,
/usr/lib/whonix/timesync_post_success rwUx,
/usr/lib/whonix/usr/timesync_init_d rwUx,
/usr/lib/whonix/usr/timesync_post_failure rwUx,
/usr/lib/whonix/msgcollector rUx,
/usr/lib/whonix/msgprogress rUx,

To no avail. I had actually started in that direction.

In order to make a fresh start, all the profiles were moved in a tmp directory. Run “sudo service apparmor teardown” for good measure.

Here a digest of my tests.

Reboot the workstation.
- timesync notification OK

Run “service sdwdate restart” several times.
- timesync GUI, progress bar
- timesync notification OK

Wait after first sleep period. Run “sudo service sdwdate restart”
[@error]
- no timesync GUI
- timesync success notification

Run timesync.
[@OK]
- timesync GUI, progress bar
- timesync notification OK

Run “sudo service sdwdate restart” several times.[@OK]

Run sdwdate_simulator once (ctrl-c during the 15s sleep period) [@OK]

Run “sudo service sdwdate restart” several times.[@OK]

Let sdwdate_simulator run twice. [@error]

Run “sudo service sdwdate restart” . [@error]

Run timesync. [@OK]. And so on…

I have authorized all /usr/lib/whonix/timesync_... scripts, including the ones not required by apparmor plus msgcollector and msgprogress, to run unconfined. [code] /usr/lib/whonix/timesync_pre rwUx, ....[/code]

Tried “rwux” too. Same result.

Updated usr.bin.sdwdate. A new message (/usr/lib/whonix/curl_exit_codes denied) and some minor changes and reorganization after the last tests.

By the way no worries about double posts by the way. In fact, when you edit a post, I don’t get a new e-mail notification. As long as it’s useful, and all of your postings certainly are, no issue with that. Just wanted to mention it.

I will test the new profile. Works well after a quick test.

[code] Wait after first sleep period. Run “sudo service sdwdate restart”
[@error]

  • no timesync GUI
  • timesync success notification [/code]
    Strange error. I can’t reproduce this on my Whonix-Workstation without any AppArmor profiles loaded. I thought quite a lot about what could cause this to no avail.

I noticed, that once when running “sudo service sdwdate restart” the progress bar was opened, reached 100% but didn’t automatically close. So the implementation is indeed not 100% bug free.

Can you check please, if you have a file

/home/user/.whonix/msgdispatcher-error.log

on your workstation? If so, check the contents and post them here if they don’t contain anything private.

It might be futile, because the msgcollector error log isn’t terribly useful in Whonix 8.*. I had one error myself but couldn’t make head or tail of it.

If you like, you can get the

/usr/ lib/whonix/msgcollector

with improved error long from https://github.com/Whonix/Whonix/blob/master/whonix_shared/usr/lib/whonix/msgcollector. Then we might get better insights why it is failing for you.

The content of /home/user/.whonix/msgdispatcher-error.log

I have intalled the new msgcollector from github. Same and only message after reboot and after a couple ot sdwdate restarts.

A new denied message from sdwdate (/proc/tty/drivers). The profile is updated.

Got a new denied messages.

apparmor="DENIED" operation="file_mmap" parent=16382 profile="/usr/bin/whonixcheck" name="/lib/security/pam_gnome_keyring.so" pid=16450 comm="sudo" requested_mask="m" denied_mask="m" fsuid=0 ouid=0

Mar 20 13:12:16 host kernel: [ 197.811151] type=1400 audit(1395321136.076:86): apparmor="DENIED" operation="mkdir" parent=7795 profile="/home/user/tor-browser_en-US/Browser/firefox" name="/home/user/tor-browser_en-US/.gnome2/" pid=7807 comm="firefox" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 Mar 20 13:12:16 host kernel: [ 197.811205] type=1400 audit(1395321136.076:87): apparmor="DENIED" operation="mkdir" parent=7795 profile="/home/user/tor-browser_en-US/Browser/firefox" name="/home/user/tor-browser_en-US/.gnome2/" pid=7807 comm="firefox" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 Mar 20 13:13:02 host kernel: [ 243.769019] type=1400 audit(1395321182.036:88): apparmor="DENIED" operation="mkdir" parent=7925 profile="/home/user/tor-browser_en-US/Browser/firefox" name="/home/user/tor-browser_en-US/.gnome2/" pid=7937 comm="firefox" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 Mar 20 13:13:02 host kernel: [ 243.769075] type=1400 audit(1395321182.036:89): apparmor="DENIED" operation="mkdir" parent=7925 profile="/home/user/tor-browser_en-US/Browser/firefox" name="/home/user/tor-browser_en-US/.gnome2/" pid=7937 comm="firefox" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 Mar 20 13:13:21 host kernel: [ 263.020016] type=1400 audit(1395321201.284:90): apparmor="DENIED" operation="mkdir" parent=7990 profile="/home/user/tor-browser_en-US/Browser/firefox" name="/home/user/tor-browser_en-US/.gnome2_private/" pid=8002 comm="firefox" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000 Mar 20 13:13:44 host kernel: [ 286.276128] type=1400 audit(1395321224.544:91): apparmor="DENIED" operation="mkdir" parent=8063 profile="/home/user/tor-browser_en-US/Browser/firefox" name="/home/user/tor-browser_en-US/.gnome2/accels/" pid=8075 comm="firefox" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000

The ‘d’ mask does not exist in the AppArmor documentation. I have met it a couple of times, and I don’t remember exactly how I fixed it. For the moment, changed from rix to rwk. Can you test it? I will have to ask the folks at Ubuntu.

The progress with Qubes is slow, and for reasons I don’t want to develop here, I’m not sure it is the right track to follow for a replacement of VirtualBox.

The work on KVM has resumed, and it will probably be more rewarding. By the way, welcome back HulaHoop. I have followed the thread in the old forum, without being able to participate, but…

Instead of Qubes, have you ever considered booting Xen in Debian and installing the Whonix VMs on top of it? I just had a quick read in the Deian Xen wiki, it sounds nice in one line. There certainly are some issues that I overlook there, but do you think it might be worth digging a little?

For the moment, I carry on with AppArmor. I have done the “abstractions/Whonix”, I am testing the modified profiles and I will put them in the wiki soon. Next in the list would be XChat, and whatever you might think of. A PDF reader and and cupsd maybe, although I have not looked at how to install a wireless or even a USB printer in the workstation. As I’m using Whonix most of the time now, It would be nice to have.

I am testing the profile.

Instead of Qubes, have you ever considered booting Xen in Debian and installing the Whonix VMs on top of it?
Just superficial.
I just had a quick read in the Deian Xen wiki, it sounds nice in one line. There certainly are some issues that I overlook there, but do you think it might be worth digging a little?
I don't know and I am not going to discourage you. I think QubesOS actually is Xen + usability improvements such as secure file transfer between VMs and GUI. Would be worth getting a list of actual differences.
Next in the list would be XChat, and whatever you might think of. A PDF reader and and cupsd maybe, although I have not looked at how to install a wireless or even a USB printer in the workstation.
Sounds good.

Do you think it would be worth having a profile for curl? Since sdwdate and whonixcheck are using curl, which connects to the internet, I think it would be important to have it confined. Or do the sdwdate / whonixcheck profiles already confine curl?

I have added abstractions/whonix in the wiki and modified the TBB, Icedove and Pidgin profiles accordingly. A new entry in whonixchek too, when it’s run manually.

At first glance, curl (or scurl for instance) is not confined in the profiles. I’ll have a look.