Skip to content

Sudo Multi Machine Overhaul

Martin Pitt edited this page Jan 14, 2020 · 23 revisions

Use cases / requirements

As a user using Cockpit for a single machine at a time (with or without a bastion host in the middle) ...

  • I want to log into Cockpit with my personal wheel account and immediately be able to do superuser tasks. [sudo-immediate]

    My personal account is in the "wheel" group (or equivalent) and I can run things like "sudo su" on the command line. Sudo might ask for the password of my personal account, or it might not. Cockpit should remember my password from the login screen and give it to sudo during login.

  • I want to log into Cockpit with my personal wheel account but Cockpit should not be able to do superuser tasks. [sudo-prevent]

    My personal account is in the "wheel" group (or equivalent) and I can run things like "sudo su" on the command line. Sudo might ask for the password of my personal account, or it might not. Cockpit should not remember my password from the login screen and should not give it to sudo. Even if sudo wont ask for a password, Cockpit should not give the session superuser powers.

  • I want to take away from Cockpit the ability to do superuser tasks in a session. [sudo-stop]

    After gaining superuser powers as with "sudo-immediate" or "sudo-start", I want Cockpit to kill the sudo that it has started. From that point on, Cockpit should behave as if I had logged in with "sudo-prevent".

  • I want to give to Cockpit the ability to do superuser tasks in a session. [sudo-start]

    While not having superuser powers as after "sudo-prevent" or "sudo-stop", I want Cockpit to gain these powers.

    My personal account is in the "wheel" group (or equivalent) and I can run things like "sudo su" on the command line. Sudo might ask for the password of my personal account, or it might not. Cockpit should ask me for my password if necessaey and only if necessary.

  • I want Cockpit to remember whether the last session had superuser powers for the next session. [sudo-sticky]

    After logging out, I want Cockpit to either behave like "sudo-immediate" or "sudo-prevent" by default on the next login.

    This should also work if the next login doesn't actually involve a login page where I could change this setting, such as with a automatic Kerberos or OAuth login.

    pitti: The login page currently stores that in a cookie (or localstorage?), so it's per browser profile instead of really by user; the latter also does not really work consistently across machines. I think it's fine to bind a browser profile to a "role" of the user. I just want to explicitly spell it out.

  • I want the login to succeed even if my personal account can't run sudo. [sudo-failure-is-fine]

    If my personal account can't run things like "sudo su", maybe because it is not in the "wheel" group, and I ask for superuser powers during login (or the previous session did have superuser powers), I want the login to still succeed but of course without superuser powers in the session.

As a user using Cockpit for a multiple machines (with or without a bastion host in the middle to get to the primary machine) ...

  • I want to access a secondary machine via SSH from a primary machine. [ssh]

    I can access the secondary machine with "ssh HOST" or "ssh USER@HOST" on the command line and Cockpit should use that ability to start a session on that machine. If a password or passphrase is necessary, Cockpit should ask for it.

  • I want to use a specific account for a secondary session. [ssh-user]

    Cockpit should not assume that the account of the primary session is the correct one for secondary sessions. Using a different one should not give the impression that it's a workaround for a configuration problem.

  • I want to use a specific SSH identity for a secondary session. [ssh-identity]

    pitti: I think this choice should be persistent (see ssh-history and sticky-ssh). But I don't yet have a solid opinion where to persist this choice. ~/.ssh/config would be ideal, but I am rather afraid of programmatically changing it -- not just because it's very sensitive and error prone, but also because this could be considered intrusive by users. So machines.d/ JSON would be the logical alternative, and given that it already overrides other settings from ssh config (at least the port), it would not be too bad to add the identity there as well? In many cases the identity would already be part of ~/.ssh/config, and we should certainly use it if it's there (ssh-config).

  • I want to use a specific port for a secondary session. [ssh-port]

    Cockpit should assume that port 22 is the SSH port on the secondary machine, but it should allow the specification of a different one, without confusing people who don't know anything about ports.

  • I want Cockpit to use my ~/.ssh/config for a secondary session. [ssh-config]

  • I want Cockpit to have my private keys ready for use during the primary session. [ssh-agent]

    If accessing secondary machines requires the unlocking of passphrase protected keys, I only want to specify and unlock each key once, even if it is used multiple times.

  • I want Cockpit to drop one of the keys that it holds ready. [ssh-agent-remove]

  • I want Cockpit to automatically unlock keys with my password on login to the primary session. [ssh-auto-agent]

    If a SSH key is protected by a passphrase that is equal to my password, I want that key to be unlocked during login and automatically be used afterwards.

    This should be attempted for all keys that SSH tries by default, and for all keys that were held ready in the previous primary session.

    pitti: This is apparently what Cockpit does right now, but it feels rather opportunistic/inconsistent to me. gnome-keyring does that more explicitly: It offers to remember your gpg/ssh passphrases and stores that in its keyring. I most certainly don't want Cockpit to maintain its own keyring. I'm not sure whether we should encourage users to use the same passphrase for account and SSH keys -- is that considered best practice?

  • I want to close a session on a secondary machine without completely logging out of Cockpit. [ssh-close]

  • I want Cockpit to remember recently closed secondary sessions for easy reconnecting. [ssh-history]

    When opening a secondary session, I would like to be able to just pick from the most recent 10 sessions or so. This should bring back the host for that session (obviously), but also account, ssh port, and ssh identity, etc.

    pitti: If you remove a host from the dashboard, it just gets marked as invisible in machines JSON. That's a good place to remember previous sessions. Adding a host could offer typeahead search, too.

  • I want Cockpit to remember the secondary sessions from one primary session to the next. [sticky-ssh]

    When logging into a primary session, I want all the secondary sessions from the last time to still be there so that I don't need to set then up explicitly again.

    An actual connection to a secondary machine should only be opened on demand. At that point, Cockpit should ask for necessary passwords and passphrases.

  • I want to manage superuser powers for the secondary sessions just like for the primary one. [ssh-sudo]

    For each session (primary and secondary), I want to control whether or not that session has superuser powers. The current state should be remembered for the next time.

  • I want to clearly see the state of sessions. [session-state]

    I want to see which is my primary session, and which are the secondary sessions. I want to see which account is used in a given session and whether or not it currently has superuser powers.

  • I want to setup public key authentication for SSH. [ssh-setup]

    I want password-less access to secondary machines, but I need help creating and copying SSH keys.


Omitted

  • I want to have arbitrarily nested SSH sessions. [ssh-inception]

    Everything about secondary sessions should hold for "tertiary" sessions that are accessed via SSH from a secondary session. And so on and on ...

  • I want to give to Cockpit the ability to do a single superuser task in a session. [one-shot-sudo]

    If a task requires superuser powers, Cockpit should perform it with sudo and ask me for a password if necessary. The password should not be used for anything else.

    This is not well-defined. E. g. technically, launching cockpit-bridge is one action, but conceptually it is not. Likewise, setting up a D-Bus signal listener might feel like a continuous thing. It seems better to explicitly get or drop privileges, as above. So big +1 for not doing this.


UX

Login screen:

  • No "[ ] Reuse my password" checkbox. Cockpit will remember from the last session for this user whether or not it had superuser powers. The way change that is to drop/gain those powers in the session, and that will stick to the next session.

Shell navigation:

  • Secondary machines are marked up as clearly secondary and contribute to the top row. The top row would continue showing the branding, OS, and user menu for the primary session, but new elements would appear that show the user menu for the current secondary session. Maybe the elements for the primary session will be replaced by the secondary ones.

...


Discussion

  • Because of "sudo-sticky" we might not need a "reuse my password" checkbox on the login page at all. Win!

  • The browser will remember a whole lot from one session to the next, including the list of secondary sessions and all their params. This replaces /etc/cockpit/machines.d/. The dashboard would still manage machines.d (for backward compat), but the shell would not. Details to be figured out.

  • Cockpit will no longer use a stored password to log into secondary machines. The way to get prompt-less access is to set up key auth for SSH, maybe using the login password as the passphrase. Cockpit can explain this at length and help with generating the keys and copying them over to the secondary machine.

    I would consider removing the user synch feature. I think it's too easy to cause chaos with it.

  • Because of the above, Cockpit doesn't need to remember the login password after login is complete. It still needs to give it out to sudo and right now sudo is started only on-demand but maybe making it "one-time-use" would work. It's not super critical to delete the password form cockpit-ws, I think, but it would be cleaner.

  • Instead of

    cockpit-session -> cockpit-bridge -> sudo cockpit-bridge --privileged

    we could have

    cockpit-session -> sudo cockpit-bridge

    for superuser sessions? The "superuser" option to channels wouldn't try to start anything on demand.

    In order to implement dropping/gaining privileges inside the session, cockpit-bridge would need to re-exec itself in some tricky way. Also, this would probably make it harder to change privilege levels without a full reload of the pages. So...

  • "No "[ ] Reuse my password" checkbox. Cockpit will remember from the last session for this user whether or not it had superuser powers." What is the behavior on the very first login ever? - Andreas

  • I don't quite understand the shell navigation UX part. Would need some examples I think. - Andreas

Clone this wiki locally