load-module module-native-protocol-tcp listen=127.0.0.1 auth-ip-acl=127.0.0.1/8
In the past, I mentioned I like to run my web browser as an alternative user, so if the web browser is compromised, it will not gain direct access to my user files. When I was using ALSA with the dmix plugin, this choice had no audio-related drawbacks as long as the web browser user had permission to access the sound devices. However, I also recently mentioned I migrated to PulseAudio, using it as the default ALSA backend, which has a problem in this situation.
The PulseAudio daemon is running as my normal user and depends on the ALSA
devices being available. The web browser user will try to use PulseAudio first,
being the default ALSA backend. This will fail, because PulseAudio is not
running as that user, and it will fall back to the default system device if
configured so in
/etc/asound.conf or it will fail to produce sound. In
addition, if the web browser user grabs the audio device, my PulseAudio instance
will not be able to use it (in other words, trying to play a sound as my normal
user while a web video is paused will fail, like when using ALSA without the
The solution I adopted, as per the post title, is similar to using ALSA with dmix. Simply allow any local user to connect to PulseAudio. This “recipe” is available all over the web (I took it from another blog), but mentioning it one more time doesn’t hurt. It also avoids running PulseAudio in system mode, which is less well-supported upstream.
/etc/pulse/default.pa, make sure you load the
module with the following parameters:
This way, the PulseAudio daemon will load a module that will allow it to accept TCP connections from the loopback interface and the loopback interface only.
For every other user except the one running the PulseAudio daemon, you need to
configure PulseAudio so it won’t try to launch a new instance and will instead
communicate with the existing daemon over TCP by default. This is simply a
matter of editing
~/.config/pulse/client.conf and using the following line:
default-server = 127.0.0.1
Note the user running the PulseAudio daemon cannot have that client configuration option, or else PulseAudio will refuse to launch a new daemon and will instead try to connect to a non-running process at 127.0.0.1.
Caveats and problems
I tried to use UNIX sockets with module-native-protocol-unix and an authorised user group and it didn’t seem to work, for some reason. Any input on that is appreciated. If you have a working configuration with UNIX sockets let me know.
The web browser user will have unlimited access to your sound devices. It can output sound and it can also listen to your microphone, should you have one permanently attached. In my case, this is a desktop computer and it doesn’t have one connected normally. Make no mistakes: this is the same situation as with ALSA and dmix, with one minor variation: if the PulseAudio daemon has a vulnerability, the web browser user may be able to make it run code as your user, so PulseAudio needs to be kept secure.