Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add systemd service files #121

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

eddsalkield
Copy link

Adds systemd service files for IMAP, SMTP, and CardDAV that limits the permissions of hydroxide for security.
Runs the program as user hydroxide, group hydroxide.
Expects $HOME to be at /var/lib/hydroxide

Resolves #120.

Feedback welcome on how best to ensure that this user and directory is automatically generated when a package is installed. We also might want to consider how we could make the setup process more seamless so that users don't have to create the hydroxide user and group, and then run hydroxide auth as that user, before running the service.

@eddsalkield
Copy link
Author

In response to @proletarius101, here:

Since you make 3 services seperately, would be great if there is a hydroxide-serve.service (or simply [email protected]? what do you think?)

I think that's a good idea, and I'll create a new service for this purpose.

Another thing is it sounds not quite ideal to set $HOME to be at /var/lib/hydroxide. At least it's not the standard freedesktop.org arrangement.

Would you elaborate on what you mean by "it's not the standard freedesktop.org arrangement"?
According to the relevant part of the Linux Filesystem Hierarchy Standard, /var/lib/ is for:

state information pertaining to an application or the system. State information is data that programs modify while they run, and that pertains to one specific host.

So indeed programs are supposed to keep their runtime data here.

it's unsafe to store credentials to a directory outside $HOME (many ppl only encrypts $HOME).

This isn't true, on two counts:
Firstly, whether or not a block device is encrypted or not is an irrelevance when it's already mounted to the filesystem (as in the case with an encrypted $HOME directory). Even if your $HOME is encrypted, the only thing preventing a user from getting the information out of your sensitive files are the file permissions, when the system is running. The only time it makes a difference is when the disk is unmounted: if somebody is trying to secure their machine against an offline attacker, they ought to be doing full disk encryption anyway.

Secondly, it's actually much more safe to store the sensitive credentials in /var/lib/hydroxide (with owner hydroxide:hydroxide and permissions 750 of course), because we can set this to be the hydroxide user's home directory. By running hydroxide (the program) only under user hydroxide with the restrictions in place by the systemd unit file, we sandbox hydroxide off from the rest of the system: it could be entirely compromised, yet the rest of the system remains safe.

This is the approach taken by nearly every other server of this kind: for example, see jellyfin, knot, etc.

The remaining question is how we get the rpm to automatically create this user and the /var/lib/hydroxide directory at installation.

One further thing: I've realised how it's strange that hydroxide runs a service that's accessible system-wide, but it expects data files to be in the $HOME of the running user. Really, it should be putting its configuration files (auth.json) in /etc/hydroxide, and its data files (*.db) in /var/lib/hydroxide. Changing this behaviour will require a patch.

Thanks for your feedback - I look forward to seeing this working nicely on Fedora when we're all done!

@proletarius101
Copy link
Contributor

So indeed programs are supposed to keep their runtime data here.

It's true for "runtime data".

The spec says

State information is data that programs modify while they run, and that pertains to one specific host.

So actually the point is, for host information (used for that computer), data should be preserved in /var/lib or /etc/, while data for a specific linux user, it should be stored in $HOME and comply with XDG standard.

whether or not a block device is encrypted or not is an irrelevance when it's already mounted to the filesystem (as in the case with an encrypted $HOME directory).

Well, I totally agree with what you state after this sentence. However, what I'm concerning about is when it's not mounted (with physical access, e.g. administrator or when your computer is stolen). But I only focus on PC than server, because it's on which that I believe most people use protonmail.

@eddsalkield
Copy link
Author

I completely agree with you regarding the different directory locations: that host-wide services should use /var/lib and /etc, and that user-based programs should comply with the XDG Base Directory Specification.

The question is whether hydroxide is supposed to be host-wide in scope, or user-wide. I suspect that most people that want to use hydroxide, say on their PC, will not have multiple unprivileged users who each want their own instance. For them, as well as for people running servers, the host-wide directories work best.

However, for people that are running protonmail as an unprivileged user on a shared instance, and still trust the sysadmin enough not to peek at their secrets, the user-based directories seem to be the better option.

Although we can create user unit files with systemd, as in the latter case, packaging these up doesn't make sense: firstly, the user unit file must contain the user name, and secondly we'd have to install these service files to all users on the system. That's a no-go. We can instead provide documentation on how to set up unit files for these users.

However, we can accommodate both kinds of user in the directory layout by:

  • First checking the XDG user-wide locations
  • Then checking the system-wide locations

And maybe we can go wild and support a manual override of config and data locations as command-line arguments, for people that consider themselves to be special edge cases.

@proletarius101
Copy link
Contributor

proletarius101 commented Oct 1, 2020

Sorry for the late reply!

firstly, the user unit file must contain the user name, 

That's not quite true. If it's a user unit, it inherits that user's namespace. That is, since hydroxide by far officially store secrets in $XDG_CONFIG_HOME/hydroxide, simply ExecStart=/usr/bin/hydroxide serve works. For instance, we'll have

#$HOME/.config/systemd/user/[email protected]
[Unit]
Description=A third-party, open-source ProtonMail CardDAV, IMAP and SMTP bridge
ConditionPathExistsGlob=%E/hydroxide/*.db

[Service]
ExecStart=/usr/bin/hydroxide %i
ProtectHome=true
ProtectSystem=full

# Note that some security hardening using cgroups may not have enough priviledge to work. 

[Install]
WantedBy=default.target

and secondly we'd have to install these service files to all users on the system.

Not really make a difference either. For system-wide service, we need sudo systemctl enable --now hydroxide@serve, whereas for the corresponding user unit we need systemctl --user enable --now hydroxide@serve, both of which create a symlink from the package-provided service template in /usr to the directory of active units.

However, we can accommodate both kinds of user in the directory layout by:

Agreed. We can provide both which is similar to the solution applied in https://src.fedoraproject.org/rpms/clash/tree/master

@emersion
Copy link
Owner

I'd prefer the systemd service files to be located in a contrib/systemd directory, because I'm not willing to maintain them. That would make them entirely community-maintained.

We should probably change the config/state files location defaults, but let's discuss this in #122.

@emersion
Copy link
Owner

Another note: I'm not sure it's a good idea to have separate service files for SMTP, IMAP and WebDAV. Event processing won't work correctly IIRC if multiple services are run at the same time.

What's the plan for letting users run hydroxide auth? Use su?

@mrvik
Copy link
Contributor

mrvik commented Nov 21, 2020

The remaining question is how we get the rpm to automatically create this user and the /var/lib/hydroxide directory at installation.

Use sysusers.d(5) to create users and their homes automatically.
See the sddm.conf file:

u sddm - "Simple Desktop Display Manager" /var/lib/sddm
m sddm video

So it's pretty simple to adapt it to this thing.

On the user/system wide install, I'm also going for the per-user services (it's my current setup) and as of systemd.unit(5), user services are read from /usr/lib/systemd/user/*, but this is somehow distro-specific (some distros use lib64 instead), so the package building scripts should address this and put the units on the needed directory.

@LeSnake04
Copy link

What's the plan for letting users run hydroxide auth? Use su?

I think it would make sense to make a user service instead an root service.

@eddsalkield
Copy link
Author

Revisiting this, I agree with the sentiment to provide a user service alongside a root service. I didn't originally consider a user service file stored in a system-wide location as an option!

However I'm afraid to say that I'm now moving away from ProtonMail, and so I don't have particular motivation to complete this PR - I only have so much time in the day 😢. If somebody would like to fork my changes and modify the user service file, they can feel free to do so. Certainly hydroxide would be improved for this work being done, but I think I'm not the person to do it.

@emersion
Copy link
Owner

No problem, thanks for this initial work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add systemd service files
5 participants