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

Debian/Ubuntu: use non-root evcc user #4901

Merged
merged 6 commits into from
Feb 6, 2023
Merged

Debian/Ubuntu: use non-root evcc user #4901

merged 6 commits into from
Feb 6, 2023

Conversation

pauxus
Copy link
Contributor

@pauxus pauxus commented Oct 22, 2022

  • include preinstall script that stops the service (with flag) and
    copies over the database
  • postinstall also recognizes restart flag in above case
  • unit file uses evcc user

Fixes #4900

Refs #4878

@andig
Copy link
Member

andig commented Oct 23, 2022

Ich halte das für eine gute Idee, kann aber nicht beurteilen, ob der PR korrekt ist. Können wir einen unabhängigen Review dafür bekommen?

@andig andig added the infrastructure Basic functionality label Oct 23, 2022
@andig andig changed the title Use distinct user for evcc on debian/ubuntu Debian/Ubuntu: use non-root evcc user Oct 23, 2022
@andig
Copy link
Member

andig commented Oct 23, 2022

@goebelmeier ist so nett und wird das für mich testen.

@pauxus
Copy link
Contributor Author

pauxus commented Oct 23, 2022

Bitte die korrigierte Fassung, mein Fix (copy/paste error) war unsinnig, hab es korrigiert.

Copy link
Contributor

@goebelmeier goebelmeier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adduser should not be called with --no-create-home from my point of view.

packaging/scripts/preinstall.sh Outdated Show resolved Hide resolved
packaging/scripts/preinstall.sh Outdated Show resolved Hide resolved
packaging/scripts/preinstall.sh Outdated Show resolved Hide resolved
packaging/scripts/preinstall.sh Outdated Show resolved Hide resolved
@pauxus
Copy link
Contributor Author

pauxus commented Oct 31, 2022

@goebelmeier Thanks for testing, I fixed the home dir creation - this might still leave open some very special cornercases (/var/lib/evcc exists but belongs to another user), but I think we are safe to assume someone in that scenario being able to resolve that manually.

@andig
Copy link
Member

andig commented Nov 3, 2022

Fehlt hier noch was? Sonst wäre jetzt nach Release der richtige Zeitpunkt zum mergen.

/cc @premultiply @VolkerK62

@goebelmeier
Copy link
Contributor

Gegentesten könnte ich das noch, weiß aber nicht ob ich das morgen unter kriege

@pauxus
Copy link
Contributor Author

pauxus commented Dec 22, 2022

Wie schaut es aus? Fehlt noch was?

@andig
Copy link
Member

andig commented Dec 29, 2022

@pauxus Zeit das fertig zu machen ;)

Aktuell liegt die db ja unter ~/.evcc/evcc.db. Passt das dann immer noch? Du verschiebst sie doch nach ~/evcc- da würde sie ja dann nicht mehr gefunden, oder funktioniert das bei Dir?

Also wäre die Fragen, wie wir dann wieder an die richtige Location kommen.

@pauxus
Copy link
Contributor Author

pauxus commented Jan 2, 2023

@andig Ich verschiebe sie nach /var/lib/evcc (also ~evcc statt ~evcc/.evcc), und natürlich habe ich aus irgendeinem Grund vergessen, die angepasste Config mit zu commiten. Argh. Neues Jahr, neues Glück. Ich rebase dann auch gleich nochmal auf den letzten Release.

pauxus added 4 commits January 2, 2023 07:20
- include preinstall script that stops the service (with flag) and
  copies  over the database
- postinstall also recognizes restart flag in above case
- unit file uses evcc user

Fixes #4900
@pauxus
Copy link
Contributor Author

pauxus commented Jan 2, 2023

So, nochmal alles durchgetestet. Funktioniert auch soweit alles, Service läuft mit dem richtigen Nutzer, DB ist kopiert.

Einen Cornercase gibt es, über den ich bei meinem letzten Test gestolpert bin: ich hatte manuell bei mir einen anderen Nutzer über evcc.service.d/ konfiguriert. Das beachtet das Skript natürlich nicht. Theoretisch könnten wir hier noch einen Schritt weitergehen und den Nutzer, unter dem evcc aktuell läuft bestimmen.

@pauxus
Copy link
Contributor Author

pauxus commented Jan 2, 2023

Allerdings ist da ein Gedankenfehler drin, muss ich gleich noch korrigieren

Don't change the default location, we only want this for the systemd service
@pauxus
Copy link
Contributor Author

pauxus commented Jan 2, 2023

Macht natürlich keinen Sinn, den Pfad zur DB global zu überschreiben, sondern nur für die Systemd Unit, ich habe es jetzt explizit im Unitfile gesetzt. Ich werde noch einen Sanity Check was geänderte Nutzer oder doppelte DBs angeht einbauen

@andig
Copy link
Member

andig commented Jan 2, 2023

Das beachtet das Skript natürlich nicht.

Das wär mir egal. Wer das kann kann auch die DB wieder finden.

- Copy database even if run as non root
- check if database already exists before copying, if so fail
- Fail if existing homedir could not be moved instead of warn only
- Warn if there are systemd overrides, in that case, service is not restarted
@pauxus
Copy link
Contributor Author

pauxus commented Jan 2, 2023

Hab jetzt noch ein paar Sanity checks dazugepackt, ich denke damit sind alle Szenarien erschlagen

@andig
Copy link
Member

andig commented Jan 3, 2023

@goebelmeier könntest Du nochmal einen Blick drauf werden? Soweit ok? Rein damit?

/cc @premultiply ?

Comment on lines +17 to +18
User=evcc
Group=evcc
Copy link
Contributor

@mweinelt mweinelt Jan 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using a statically allocated user, let systemd manage the user dynamically. That should simplify the install script somewhat.

Suggested change
User=evcc
Group=evcc
DynamicUser=true
User=evcc

Then let systemd create the state directory at /var/lib/evcc and change the working directory using

StateDirectory=evcc
WorkingDirectory=/var/lib/evcc

From what I remember systemd also manages the StateDirectory migration from/to DynamicUser=, so if /var/lib/evcc already exists it should migrate that data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - this would simply the script. I will give it a spin tomorrow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea what you‘re talking about. Staying tuned :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did again look into it (was almost tomorrow...) and would rather not use DynamicUser. The directories would be created inside /var/lib/private/evcc and symlinked to /var/lib/evcc which introduces unnecessary complexity. Also it would no make the script much simpler. We still would need to create the directory, we still need to copy the database and we would still need to chown (systemd only chowns the containing files if the owner of the directory is wrong, so this might lead to effects, if the user/directory already exists).

The only thing we could do would be to set StateDirectory and use the STATE_DIRECTORY env variable in the call, but I don't think this would help very much.

Copy link
Contributor

@mweinelt mweinelt Jan 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, if you have state to migrate in post-install that gets hairy fast. Most of the issues you describe seem to originate from a migration story, but I think they are easily solvable.

if the user/directory already exists

You would need to delete the persistent user.

we would still need to chown (systemd only chowns the containing files if the owner of the directory is wrong

After removing the persistent user the owner/group would certainly mismatch.

The directories would be created inside /var/lib/private/evcc and symlinked to /var/lib/evcc which introduces unnecessary complexity.

I think the complexity you see is that it only gets created, when the unit is first started. But as you noticed you can create it yourself and I think that is reasonable given that you want to migrate old state.

I think systemd is a very neat tool to manage a service's lifetime. Find below my personal systemd unit running on NixOS. It goes beyond the scope of this PR, especially by including hardening options, but maybe you'll find it interesting or even useful.

# /etc/systemd/system/evcc.service
[Unit]
After=network-online.target mosquitto.target mosquitto.service

[Service]
Environment="HOME=/var/lib/evcc"
Environment="LOCALE_ARCHIVE=/nix/store/wqzfxm6fni76h5w9m17q7zkl7h7isk96-glibc-locales-2.35-163/lib/locale/locale-archive"
Environment="PATH=/nix/store/57xv61c5zi8pphjbcwxxjlgc34p61ic9-glibc-2.35-163-bin/bin:/nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1/bin:/nix/store/mydc6f4k2z73xlcz7ilif3v2lcaiqv>
Environment="TZDIR=/nix/store/i16lgq16av602nfyws3ps8dd9yj36dwh-tzdata-2022f/share/zoneinfo"

CapabilityBoundingSet=
DeviceAllow=char-ttyUSB
DevicePolicy=closed
DynamicUser=true
ExecStart=/nix/store/qc0vs3by55v0daf7ii854d56kz3nwsf0-evcc-0.109.2/bin/evcc --config /nix/store/fzbldlqmx5ambi3hmf3jhagb3nvc33qp-evcc.yml 
LockPersonality=true
MemoryDenyWriteExecute=true
PrivateTmp=true
PrivateUsers=true
ProcSubset=pid
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=invisible
RestrictAddressFamilies=AF_INET
RestrictAddressFamilies=AF_INET6
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=true
RestrictRealtime=true
StateDirectory=evcc
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallFilter=~@privileged
UMask=0077
User=evcc
WorkingDirectory=/var/lib/evcc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would need to delete the persistent user.

Since DynamicUser CAN work with preexisting users, this can get fishy rather. If you have a user (log reader or similar) that is part of the group evcc and that group is deleted, you will have unexpected consequences. I would suggest sticking with fixed users. You can always use your really strict (in a positive way, you are correct, I find it one of the most hardened unit files that I have seen so far) unit configuration in an override file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andig @mweinelt Wie sieht es aus? ich würde es so lassen...

@andig
Copy link
Member

andig commented Feb 6, 2023

@goebelmeier @premultiply @mweinelt last call- habt ihr noch Anmerkungen? Mir erscheint das sonst vollständig und hoffentlich auch frei von Nebenwirkungen und ich würde es ins Nightly mergen?

@premultiply
Copy link
Member

LGTM

@goebelmeier
Copy link
Contributor

Es sieht mir gut aus, ich hab relativ viel Fuzzy Testing gemacht und es ist nicht zerbrochen. Also könnte man IMHO reinnehmen

@andig
Copy link
Member

andig commented Feb 6, 2023

Dann Mut zur Lücke. Danke fürs Feedback!

@VolkerK62 im apt Package wandert die SQlite Datenbank jetzt nach https://github.com/evcc-io/evcc/pull/4901/files#diff-fc00ac250b8d002d87e12d46f86302b54999b140a3048acb82f91de09df794e7R13

@andig andig merged commit 5fef68d into evcc-io:master Feb 6, 2023
@andig
Copy link
Member

andig commented Feb 6, 2023

Und natürlich Dank an @pauxus

@VolkerK62
Copy link
Contributor

@VolkerK62 im apt Package wandert die SQlite Datenbank jetzt nach https://github.com/evcc-io/evcc/pull/4901/files#diff-fc00ac250b8d002d87e12d46f86302b54999b140a3048acb82f91de09df794e7R13

Ich habe die Kommentierungen gelesen und nix verstanden.
Muss man bzgl. des Umzugs der DB als normaler Nutzer irgendwie tätig werden?
In der Doku habe ich keinen Verweis auf die DB gefunden, da ist also nix zu tun.

@andig
Copy link
Member

andig commented Feb 6, 2023

Ne, die sollte per Skript umziehen, liegt aber danach am neuen Ort. Im Logfile sagt evcc, welche verwendet wird

@VolkerK62
Copy link
Contributor

VolkerK62 commented Feb 6, 2023

Sollte dieser PR in dem Nightly von vorhin (wegen freeze) enthalten sein?

pi@raspberrypi:~ $ evcc dump
[main  ] INFO 2023/02/06 20:10:23 evcc 0.112.4 (7faa8bb8)
[main  ] INFO 2023/02/06 20:10:23 using config file: /etc/evcc.yaml
[db    ] INFO 2023/02/06 20:10:30 using sqlite database: /home/pi/.evcc/evcc.db

andig added a commit that referenced this pull request Feb 6, 2023
andig added a commit that referenced this pull request Feb 6, 2023
@andig
Copy link
Member

andig commented Feb 8, 2023

This error has just popped up in the wild:

hatte grade von 0.111.? auf 0.112.5 aktualisiert.
hab jetzt diese Fehler:

Feb  8 09:50:26 homeserver evcc[16875]: [lp-1  ] INFO 2023/02/08 09:50:26 start charging ->
Feb  8 09:50:26 homeserver evcc[16875]: [db    ] ERROR 2023/02/08 09:50:26 persist: attempt to write a readonly database (8)
Feb  8 10:28:05 homeserver evcc[16875]: [lp-1  ] INFO 2023/02/08 10:28:05 stop charging <-
Feb  8 10:28:05 homeserver evcc[16875]: [db    ] ERROR 2023/02/08 10:28:05 persist: attempt to write a readonly database (8)
Feb  8 10:28:20 homeserver evcc[16875]: [lp-3  ] INFO 2023/02/08 10:28:20 start charging ->
Feb  8 10:28:20 homeserver evcc[16875]: [db    ] ERROR 2023/02/08 10:28:20 persist: attempt to write a readonly database (8)
Feb  8 10:28:30 homeserver evcc[16875]: [db    ] ERROR 2023/02/08 10:28:30 persist: attempt to write a readonly database (8)
Feb  8 10:28:30 homeserver evcc[16875]: [main  ] ERROR 2023/02/08 10:28:30 cannot save settings: attempt to write a readonly database (1544)
Feb  8 10:28:30 homeserver evcc[16875]: [db    ] ERROR 2023/02/08 10:28:30 persist: attempt to write a readonly database (1544)

nach dem ändern "chown evcc:evcc /bla/bla" vom Verzeichnis in dem die SQlite db ist und die db file - läuft alles wieder rund.

-> is that something we need to fix in the packaging?

@pauxus
Copy link
Contributor Author

pauxus commented Feb 8, 2023

The change was not part of 112.5. You reverted beforehand and revert-reverted afterwards. Need more details:

  • which user was used (before/after)?
  • Where is bla/bla?
  • is this actually a Debian/Ubuntu system

@Chris591
Copy link
Contributor

Chris591 commented Feb 8, 2023

I guess it was root
at least the folder and file was owned by root
bla/bla was the default location /var/lib/evcc/evcc.db
OS:

PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

@Chris591
Copy link
Contributor

Chris591 commented Feb 8, 2023

This was the error or warning I saw during the update.

Vorbereitung zum Entpacken von .../evcc_0.112.5+1675824468_armhf.deb ...
adduser: Warnung: Das Home-Verzeichnis ?/var/lib/evcc? geh?rt nicht dem Benutzer, den Sie gerade anlegen.
Entpacken von evcc (0.112.5+1675824468) ?ber (0.111.1+1675414714) ...
evcc (0.112.5+1675824468) wird eingerichtet ...

@pauxus
Copy link
Contributor Author

pauxus commented Feb 8, 2023

Ok, this is a corner case. We could add a chown after the creation of the user, but I don't know whether this is really necessary.

I assume you created the folder manually? Or do you have any overrides in your systemd module (like stateDirectory)?

@Chris591
Copy link
Contributor

Chris591 commented Feb 8, 2023

No didn't created it but using the nightly and added it to the config file a while ago. Not sure why I had to do it but was related to not saving the chargelogs persistent as I remember correctly.

@Chris591
Copy link
Contributor

Chris591 commented Feb 9, 2023

This is the error on todays update:

Vorbereitung zum Entpacken von .../evcc_0.112.5+1675930264_armhf.deb ...
Warning: evcc's home directory is incorrect (116)
but can't be changed because another process (31452) is using it.
Stop offending process(es), then restart installation
dpkg: Fehler beim Bearbeiten des Archivs /var/cache/apt/archives/evcc_0.112.5+1675930264_armhf.deb (--unpack):
 ?neues evcc-Skript des Paketes pre-installation?-Unterprozess gab den Fehlerwert 1 zur?ck
Fehler traten auf beim Bearbeiten von:
 /var/cache/apt/archives/evcc_0.112.5+1675930264_armhf.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

process (31452) was the previous EVCC running process.

@andig
Copy link
Member

andig commented Feb 9, 2023

Let's continue in #6162, seems this is more serious.

@DerAndereAndi
Copy link
Contributor

There is another issue caused by this, which needs to be addressed: #6140 (comment)

/dev/tty... devices can not be accessed by the evcc user.

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

Successfully merging this pull request may close these issues.

Debian / Ubuntu Service: Separater Nutzer
8 participants