--- title: Authenticate to Cockpit from anywhere subtitle: author: Martin Pitt <> email: mpitt@redhat.com date: DevConv.CZ 2020 theme: Singapore header-includes: - \setbeameroption{show notes} ... # Cockpit what? - Interactive Server admin web interface - Easy setup and troubleshooting for one or a few machines - Included in all major distros :::notes - Conceptually: Linux session running in a web browser; technically very similar to ssh/VT/GNOME login - Tool for experimenting, learning, troubleshooting, and doing infrequent tasks ::: # Extending LVM ```sh pvcreate /dev/sdb2 vgextend vg0 /dev/sdb2 lvresize --extents '+100%FREE' vg0/data1 resize2fs /dev/vg0/data1 ``` :::notes - for example, adding a new PV to an LV and resizing the file system you can spend some time coming up with these commands - lots of possibilities for screwing up - you can do it simply and safely with Cockpit like this → go to local browser - Storage page, vg0 in Devices (top right), + in Physical Volumes, add sdb2 - expand data1 table line, click grow ::: # Accessible from any browser - Windows/Edge - Mobile devices - Simple install - Zero configuration :::notes - being web based makes this server UI available to places that you traditionally don't reach with ssh - Switch to Windows virt-viewer, open Edge, show Cockpit - Quit virt-viewer - Move to local browser, enable mobile mode (Ctrl+Shift+M) - Zero configuration so far, other than possibly installing cockpit pkg and enabling cockpit.socket - But wait, you say -- want to admin that server over there, but not allowed to open new port and system service? - In larger environments it's impractical to install cockpit server on hundreds of machines and using the login web page; better solution: piggyback on ssh - Glimpse of how to customize how cockpit runs and how to authenticate to it ::: # Anatomy: cockpit-ws ![ws-session](ws-session.pdf)\ - TCP http+WebSocket $\leftrightarrow$ JSON pipe - collect credentials :::notes - for configuring, extending, and embedding Cockpit you need to coarsely understand the components of it - this: simplest structure, what I just showed you and what you will most probably see the first time you try it - browser only speaks HTTP and WebSocket, so you always need a web server, cockpit-ws - all components in cockpit communicate to each other via a JSON protocol on standard pipes, usually stdio - this provides a lot of flexibility and extensibility, as we'll see shortly - ws roles: communicate with the browser for getting credentials: login page, krb negotiation, client cert - ws: deliver HTML/js content, connects JSON protocol on the WebSocket to pipes to the other components; runs as unprivileged system user ::: # Anatomy: cockpit-session ![ws-session](ws-session.pdf)\ - ws credentials → PAM session - forward JSON pipe to session leader :::notes - need some root helper to actually start session: use creds from ws to start PAM login session, connect pipe to it - standard is cockpit-session: very small, auditable - but doesn't have to be, that's the flexible part ::: # Anatomy: cockpit-bridge ![ws-session](ws-session.pdf)\ - session leader, cockpit's "bash" - JSON on stdio $\leftrightarrow$ system APIs :::notes - bridge: session leader, moral equivalent of what bash is in ssh session - JSON protocol on stdio to system APIs: exec programs, call D-Bus, work with files or sockets - runs as target user in login session; complex, but no special privileges ::: # SSH sessions ![ssh-session](ssh-session.pdf)\ nothing Cockpit specific running outside of the user session :::notes - ws and the login session don't need to run on the same machine - cockpit-session is meant to be customizable for your purposes - most obvious replacement is to let ssh start a session; that already does the PAM bits and forward its initial stdio to the session lead; it would just launch cockpit-bridge instead of bash - browser: go to Dashboard, add cockpit.dev:2201 - interesting property: nothing Cockpit specific running in the system, no ws, no extra open port; only bit is bridge, but that's uninteresting from security POV ::: # Bastion host ![bastion-host](bastion-host.pdf)\ Enforce using ssh in cockpit.conf(5): ```ini [WebService] RequireHost=true ``` :::notes - further illustrated by a mode that we call "bastion host" - disable cockpit-session and local logins, only use ssh - can run in container - no ws on critical machines, don't trust cockpit-session - switch to browser; log out, use "connect to" for cockpit.dev:2201 - finish the demo script, press Enter ::: # Other authentication setups - SSO/Kerberos in Identity Management domains - smart card/client certificate authentication - OAuth (external embedding) - Foreman: included cockpit-ws with dynamic configuration TODO: foreman screenshot :::notes - Cockpit supports common authentication systems out of the box - IdM is very common; if you have a krb ticket, you get a session immediately without the login page - browsers can ask for TLS client certificates, commonly with smart cards, and present them to the web server; latest Cockpit versions supports that - Foreman has a "Web Console" button; interesting case for seamless transition between Foreman and Cockpit - already has ssh to all maintained machines - runs a single cockpit-ws process on its server, and dynamically configures it for selected target machine - custom cockpit session helper to do OAuth between Foreman session and cockpit-ws, and wrap cockpit-ssh session starter - not enough time to demo and explain all of this; just keep in mind that it's possible ::: # Embedding into existing session ![local-session-unsafe](local-session-unsafe.pdf){height=60%}\ \footnotesize \verb!cockpit-ws -p 9999 --no-tls --local-session=/usr/bin/cockpit-bridge! `firefox http://localhost:9999` :::notes - what I do want to show: opposite direction; "replace cockpit-session" can also mean "by nothing" - due to common JSON protocol, we can connect ws directly to a cockpit-bridge - take a step back: if I want to admin this very machine, it's in a running Linux session, it knows who I am - put the whole auth structure inside out and instead run cockpit-ws as my user inside my session - open localhost:9999 in firefox - alarm bells: exposes my session to a TCP port without any auth ::: # Embedding into existing session: once more with safety! ![local-session-unsafe](local-session.pdf){height=60%}\ \footnotesize \verb! ! `/usr/libexec/cockpit-desktop [page]` :::notes - need to hide that port; put browser and cockpit-ws into network namespace, then they live in a completely isolated world - do some work to hide browser chrome, use webkit if available - cockpit-desktop / - wants to run priv bridge, can accept or decline - decline, R/O view - can show an individual iframe, "page" - suddenly you end up with a halfway decent desktop app - just the storage page, replacement for gnome-disks - cockpit-desktop podman ::: # Conclusion - Authentication is very flexible - Works with zero configuration - Can be arbitrarily embedded :::notes - Cockpit provides a set of standard auth protocols that are being used in today's modern deployments - Once you know about the structure, you can combine ssh, web servers, reverse proxies, and custom auth helpers to embed Cockpit anywhere you want ::: # Q & A Contact: - `#cockpit` on Freenode - https://cockpit-project.org Useful links: * [Authentication configuration](https://cockpit-project.org/guide/latest/authentication.html) * [Authentication protocol](https://github.com/cockpit-project/cockpit/blob/master/doc/authentication.md) :::notes - Home page leads to mailing lists, documentation - thanks for your attention; Q+A :::