Execute commands as another user in the X Server on both OpenBSD and Linux.
OpenBSD 6.4 introduced the unveil(2) system call to restrict file system access of the calling process. Along with it the chromium port started accepting the
--enable-unveil parameter, which limits the file system access of Chromium to the Downloads directory in your $HOME. Besides Chromium, work is in progress to start using unveil on other programs, both on base and from ports.
On the Linux side, Firejail is able to restrict the running environment of untrusted applications using kernel features.
Both mechanisms supersede the need for the
- This script is about to be rewritten entirely in Perl, now that Perl is already used to close the input/output handlers and to detach from the running terminal.
- Some programs may not work without a tty.
- The X authorization file is currently generated for "trusted" clients, giving them access to tamper with other X clients. But otherwise it wouldn't be possible to share the clipboard with xodoed windows, and that's a bummer.
Download and install this script:
$ ftp https://raw.githubusercontent.com/garotosopa/xodo/master/xodo.sh $ chmod +x xodo.sh $ doas mv -i xodo.sh /usr/local/bin/xodo
If you don't have
doas privilege to move the script to
root and move the file accordingly.
Setup a different user for running Firefox:
$ doas xodo --setup firefox
If you don't have
doas privilege for this initial setup, become
root and setup
xodo with the
--for option as described in the Examples section, further below.
Once everything is set, run Firefox as a different user:
$ xodo firefox
xodo <command> [--as <user>] [--] [args...] xodo --setup <command> [--as <user>] [--for <user>] xodo --help
xodo utility authorizes another user to connect to the active X display, then executes the given command as this other user. It's been developed to ease the steps of running desktop programs with different privileges than your own, so that a vulnerability couldn't compromise all your files directly.
xodo does is to run
doas on OpenBSD, or
sudo on Linux. It can also configure new users automatically with the
xodo for executing a program as a different user, this other user must already exist, preferably for the sole purpose of running said program. It can be created manually or using xodo's
--setup option. Also, the main user that's going to use
xodo must be allowed to
sudo as the other user. This is already taken care of by
xodo --setup. Unless told otherwise, the other username defaults to
The command parameter can either be an absolute or relative path, or even just the command basename. In this latter case, the command is assumed to be in the current
xodo to launch programs, any argument other than
--as or arguments after
-- are passed to the command being executed.
When specified, this is the user as which the command is going to be executed, or the user that's going to be created when invoked with the
When ommitted, the convention assumes
$USER-<command>. During setup, the username part can be overriden with the
When specified, this is the user that will be allowed to execute the command as another user. This option is only used with
When ommitted, the current username in the
USER environment variable is used.
Display basic usage syntax.
Adds a user and authorizes another to execute the given command in its behalf. The main user is also added to the new user's own group, in order to facilitate the access to its files and to be able to create the necessary .Xauthority file.
This option must be used as
root, as it calls
usermod, and writes to
/etc/doas.conf on OpenBSD and
/etc/sudoers.d/xodo on Linux.
--as overrides the username being created, and option
--for overrides the username that will be allowed to execute the given command via
Configure a separate user for Mike to execute Firefox:
mike$ doas xodo --setup firefox
This assumes that Mike is permitted in
doas.conf to execute
root. If that's not so,
root should be used directly for setting this up for Mike:
mike$ su - root# xodo --setup firefox --for mike
Either way, Mike can now execute Firefox as the user mike-firefox, so that ideally any vulnerability in Firefox couldn't compromise Mike's files directly:
mike$ xodo firefox
To create a user different than the
<user>-<command> convention, use the
--as option during setup:
mike$ su - root# xodo --setup firefox --for mike --as webuser
Then specify this different user when executing
mike$ xodo firefox --as webuser