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

use DynamicUser=yes for all cockpit components #16811

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/systemd/Makefile.am
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ dist_systemdunit_DATA = \
src/systemd/cockpit-wsinstance-http.socket \
src/systemd/cockpit-wsinstance-https-factory.socket \
src/systemd/cockpit-wsinstance-https@.socket \
src/systemd/cockpit-wsinstance-socket-user.service \
$(NULL)

# -----------------
4 changes: 2 additions & 2 deletions src/systemd/cockpit-wsinstance-http.service.in
Original file line number Diff line number Diff line change
@@ -7,6 +7,6 @@ After=cockpit-session.socket cockpit-session-socket-user.service

[Service]
ExecStart=@libexecdir@/cockpit-ws --no-tls --port=0
User=cockpit-wsinstance
Group=cockpit-wsinstance
User=cockpit-wsinstance-socket
Group=cockpit-wsinstance-socket
SupplementaryGroups=cockpit-session-socket
9 changes: 5 additions & 4 deletions src/systemd/cockpit-wsinstance-http.socket
Original file line number Diff line number Diff line change
@@ -3,11 +3,12 @@ Description=Socket for Cockpit Web Service http instance
Documentation=man:cockpit-ws(8)
BindsTo=cockpit.service
# ensure our DynamicUser exists
Requires=cockpit-ws-user.service
After=cockpit-ws-user.service
Requires=cockpit-ws-user.service cockpit-wsinstance-socket-user.service
After=cockpit-ws-user.service cockpit-wsinstance-socket-user.service

[Socket]
ListenStream=/run/cockpit/wsinstance/http.sock
SocketUser=cockpit-ws
SocketMode=0600
SocketUser=root
SocketGroup=cockpit-wsinstance-socket
SocketMode=0660
RemoveOnStop=yes
9 changes: 5 additions & 4 deletions src/systemd/cockpit-wsinstance-https-factory.socket
Original file line number Diff line number Diff line change
@@ -3,12 +3,13 @@ Description=Socket for Cockpit Web Service https instance factory
Documentation=man:cockpit-ws(8)
BindsTo=cockpit.service
# ensure our DynamicUser exists
Requires=cockpit-ws-user.service
After=cockpit-ws-user.service
Requires=cockpit-ws-user.service cockpit-wsinstance-socket-user.service
After=cockpit-ws-user.service cockpit-wsinstance-socket-user.service

[Socket]
ListenStream=/run/cockpit/wsinstance/https-factory.sock
Accept=yes
SocketUser=cockpit-ws
SocketMode=0600
SocketUser=root
SocketGroup=cockpit-wsinstance-socket
SocketMode=0660
RemoveOnStop=yes
4 changes: 2 additions & 2 deletions src/systemd/cockpit-wsinstance-https@.service.in
Original file line number Diff line number Diff line change
@@ -8,6 +8,6 @@ After=cockpit-session.socket cockpit-session-socket-user.service
[Service]
Slice=system-cockpithttps.slice
ExecStart=@libexecdir@/cockpit-ws --for-tls-proxy --port=0
User=cockpit-wsinstance
Group=cockpit-wsinstance
User=cockpit-wsinstance-socket
Group=cockpit-wsinstance-socket
SupplementaryGroups=cockpit-session-socket
9 changes: 5 additions & 4 deletions src/systemd/cockpit-wsinstance-https@.socket
Original file line number Diff line number Diff line change
@@ -7,11 +7,12 @@ BindsTo=cockpit.service
# the services are resource-limited by system-cockpithttps.slice
BindsTo=cockpit-wsinstance-https@%i.service
# ensure our DynamicUser exists
Requires=cockpit-ws-user.service
After=cockpit-ws-user.service
Requires=cockpit-ws-user.service cockpit-wsinstance-socket-user.service
After=cockpit-ws-user.service cockpit-wsinstance-socket-user.service

[Socket]
ListenStream=/run/cockpit/wsinstance/https@%i.sock
SocketUser=cockpit-ws
SocketMode=0600
SocketUser=root
SocketGroup=cockpit-wsinstance-socket
SocketMode=0660
RemoveOnStop=yes
11 changes: 11 additions & 0 deletions src/systemd/cockpit-wsinstance-socket-user.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=Dynamic user for /run/cockpit/wsinstance/ sockets
BindsTo=cockpit.service

[Service]
DynamicUser=yes
User=cockpit-wsinstance-socket
Group=cockpit-wsinstance-socket
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
5 changes: 3 additions & 2 deletions src/systemd/cockpit.service.in
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@ Documentation=man:cockpit-ws(8)
Requires=cockpit.socket
Requires=cockpit-wsinstance-http.socket cockpit-wsinstance-https-factory.socket
# ensure our DynamicUser exists
Requires=cockpit-ws-user.service
After=cockpit-ws-user.service
Requires=cockpit-ws-user.service cockpit-wsinstance-socket-user.service
Copy link
Member Author

Choose a reason for hiding this comment

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

Reading this, even as someone who understands how this pile of software works, is confusing.

We've used cockpit-ws for cockpit-tls and cockpit-wsinstance for cockpit-ws for a while now for reasons that are no longer relevant. I think we should take the time to change these usernames: cockpit-tls for cockpit-tls and cockpit-ws for cockpit-ws.

Copy link
Member

Choose a reason for hiding this comment

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

We need to be careful about "cockpit-ws", as we used to have that static user, and /etc/cockpit/ws-certs.d/* may still be owned by it on old systems. In general, +1 for cleaning up the user names, though!

Copy link
Member

Choose a reason for hiding this comment

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

For that reason I added postinst scripts which remove the cockpit-wsinstance user on upgrade, but not for cockpit-ws. I don't want to get into the business of randomly chowning files in /etc. You can just too easily screw up shared certificates, backups, break Ansible scripts, etc.

After=cockpit-ws-user.service cockpit-wsinstance-socket-user.service
# we need to start after the sockets so that we can instantly forward incoming requests
After=cockpit-wsinstance-http.socket cockpit-wsinstance-https-factory.socket

@@ -17,6 +17,7 @@ ExecStartPre=+@libexecdir@/cockpit-certificate-ensure --for-cockpit-tls
ExecStart=@libexecdir@/cockpit-tls
User=cockpit-ws
Group=cockpit-ws
SupplementaryGroups=cockpit-wsinstance-socket
Copy link
Member Author

Choose a reason for hiding this comment

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

And ditto. We should have cockpit-ws-socket and cockpit-session-socket.

NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
4 changes: 2 additions & 2 deletions src/tls/README.md
Original file line number Diff line number Diff line change
@@ -73,8 +73,8 @@ use of systemd features.
reads the fingerprint from stdin, and asks systemd to start a new
[cockpit-wsinstance-https@fingerprint.socket](../src/ws/cockpit-wsinstance-https@.socket.in)
and .service pair.
* Each instance runs in its own systemd cgroup, as another unprivileged system
user `cockpit-wsinstance`.
* Each instance runs in its own systemd cgroup, as another unprivileged
dynamic system user `cockpit-wsinstance-socket`.
* cockpit-tls exports the client certificates to `/run/cockpit/tls/<fingerprint>`
while there is at least one open connection with that certificate, i. e. as
long as there is an active Cockpit session.
2 changes: 1 addition & 1 deletion test/verify/check-connection
Original file line number Diff line number Diff line change
@@ -332,7 +332,7 @@ class TestConnection(testlib.MachineCase):
# number of https instances is bounded (DoS prevention)
# with MaxTasks=200 und 2 threads per ws instance we should have a
# rough limit of 100 instances, so at some point curl should start failing
m.execute("runuser -u cockpit-ws -- sh -ec 'RC=1; for i in `seq 120`; do "
m.execute("runuser -u cockpit-wsinstance-socket -- sh -ec 'RC=1; for i in `seq 120`; do "
Copy link
Member Author

Choose a reason for hiding this comment

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

It occurs to me that if we ran this as cockpit-ws (ie: the account running cockpit-tls) it wouldn't work because the supplementary group isn't on that account, but rather comes in via an additional option in the unit. Can we move the supplementary group to the unit that dynamically creates the user? That might make things a bit easier to understand, and would allow us to drop this patch fragment...

" echo -n $i | nc %s -U /run/cockpit/wsinstance/https-factory.sock;"
" curl --silent --head --max-time 5 --unix-socket /run/cockpit/wsinstance/https@$i.sock http://dummy > /dev/null || RC=0; "
"done; exit $RC'" % n_opt)
1 change: 1 addition & 0 deletions tools/cockpit.spec
Original file line number Diff line number Diff line change
@@ -387,6 +387,7 @@ authentication via sssd/FreeIPA.
%{_unitdir}/cockpit-wsinstance-https-factory@.service
%{_unitdir}/cockpit-wsinstance-https@.socket
%{_unitdir}/cockpit-wsinstance-https@.service
%{_unitdir}/cockpit-wsinstance-socket-user.service
%{_unitdir}/system-cockpithttps.slice
%{_prefix}/%{__lib}/tmpfiles.d/cockpit-ws.conf
%{_sysusersdir}/cockpit-wsinstance.conf
1 change: 1 addition & 0 deletions tools/debian/cockpit-ws.install
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ ${env:deb_systemdsystemunitdir}/cockpit-wsinstance-https-factory@.service
${env:deb_systemdsystemunitdir}/cockpit-wsinstance-https-factory.socket
${env:deb_systemdsystemunitdir}/cockpit-wsinstance-https@.service
${env:deb_systemdsystemunitdir}/cockpit-wsinstance-https@.socket
${env:deb_systemdsystemunitdir}/cockpit-wsinstance-socket-user.service
${env:deb_systemdsystemunitdir}/system-cockpithttps.slice
${env:deb_pamlibdir}/security/pam_ssh_add.so
${env:deb_pamlibdir}/security/pam_cockpit_cert.so