Identity: users from a domain, and their roles¶
Who may log in to the box, and as what: local users, or the users of a domain (FreeIPA or Red Hat IdM, or Active Directory), whose groups give them their role. The domain is reached through SSSD on the host: one place for Cockpit, the standalone UI, SSH and sudo alike.
Config¶
# stronghold.yaml
identity:
type: ipa # ipa (FreeIPA, Red Hat IdM) or ad (Active Directory)
domain: ipa.example.com # the DNS domain; the Kerberos realm is its upper case
server: ipa1.ipa.example.com # optional: default, found in DNS
api:
admin-groups: [stronghold-admins] # default [wheel]; root is always an admin
operator-groups: [netops]
viewer-groups: [helpdesk]
Joining takes a credential once, on each box, so it is an action rather
than config: stronghold identity join -u admin (a user who may add
hosts, its password asked for), or --otp with a one-time password
(FreeIPA's host enrollment password: ipa host-add --random; AD's
pre-created computer account's). Each box of an HA pair joins on its own,
with its own host name. stronghold identity leave leaves; with -u the
box's host entry in the domain goes too.
How¶
- realmd and SSSD, as Cockpit does.
realm join(FreeIPA throughipa-client-install, AD throughadcli) configures SSSD, Kerberos and the system's PAM and NSS (authselect's sssd profile). Cockpit's own "Join domain" (its Overview page) does the same through realmd's D-Bus API, so a box joined from either shows as joined in both, and Cockpit stays as it is: its logins are PAM's, its administrative access sudo. - A member has its FQDN as its name: joining renames the box from
gw1togw1.<domain>first (its short name stays). FreeIPA wants it; AD takes the computer account's DNS name from it, and a computer may only give itself names under that one (single sign-on'sHTTP/). - The box must resolve the domain: its servers' names, and for
discovery the SRV records. With the box's own resolver, a forward zone
for the domain to its DNS servers (
dns.yaml), as in the lab. - Logins: the standalone UI's password logins go through PAM's
strongholdservice (password-auth, so SSSD once joined); the role comes from the user's groups as NSS gives them (api.admin-groups,operator-groups,viewer-groups), the highest one wins. AD names users and groups with their domain (jo@ad.example.com,netops@ad.example.com): the groups are written so too. - Only the role groups log in at all: once the box is a member,
strongholdd makes realmd's permitted groups the role groups (admin,
operator and viewer:
realm deny --all, thenrealm permit --groups, only when they differ), so a domain user without a role can't log in to SSH, the console or Cockpit either: by default realmd lets every user of the domain in, and on a gateway that's too many. It is realmd's own setting (SSSD's simple access provider), shown as such in Cockpit andrealm list. The box's own users (wheel) are unaffected. - Admins get sudo: a sudoers drop-in
(
/etc/sudoers.d/50-stronghold-admins, checked withvisudobefore it is put in place) for the admin groups other than wheel, which Fedora's sudoers has. So a domain admin has administrative access in Cockpit too, and the Cockpit plugin (which needs it) works for them. FreeIPA's own sudo rules (SSSD's sudo provider) work as well, for those who manage sudo there. - Status:
stronghold identity,GET /v1/identity(joined, SSSD online or offline, the domains realmd knows), the System tab's "Identity and roles" card (the domain, joining and leaving, the role groups). - Removing
identityfrom the config doesn't leave the domain (that would lock out its users without a word): leave first.
Single sign-on¶
A domain's users whose browsers have a Kerberos ticket log in to Cockpit
and to the standalone UI without typing a password (Negotiate, as on a
Windows domain's intranet): Cockpit does it itself once the box has a key
for HTTP/<its name>; strongholdd checks the same tickets with the same
key.
- The key is made on the box when it joins with a user (
stronghold identity join -u admin), or afterwards withstronghold identity sso(the System tab's "Set up single sign-on",POST /v1/identity/sso): - FreeIPA: the box's
HTTP/service (ipa service-add) and its key in Cockpit's own keytab,/etc/cockpit/krb5.keytab(ipa-getkeytab), as Cockpit's "Join domain" makes it. It takes a user who may add services: a box joined with a one-time password gets it withsso -u. - Active Directory: the HTTP name on the box's own computer account
(
adcli update --add-service-principal), by the box's own key: no user needed, done at every join. Its keys are in the box's keytab,/etc/krb5.keytab, which SSSD renews with the account's password. AD lets a computer name itself only under its account's DNS name: a box joined with a short hostname (by hand, or before 0.4) has to leave and join again. - Checked, not assumed: the box then asks the domain for a ticket
to its HTTP name (as the box, or as the user in FreeIPA) and opens it
with the keytab (
kvno -k); adcli only warns when AD refuses a name. - Cockpit checks tickets with its own keytab if there is one, else the box's; strongholdd picks the same.
- The name is the box's (
gw1.ipa.example.com; a short hostname gets the domain): the browsers must use it, never an address, for a ticket. Each box of a pair has its own. - The standalone UI asks for a ticket by itself when the login page
opens (
GET /v1/session/kerberos: 401Negotiate, then the session), once: after logging out it doesn't, and its "Log in with Kerberos" button tries again. A browser without a ticket just sees the page. - The same rules as a password: the ticket's user (krb5's mapping,
SSSD's:
alice@IPA.EXAMPLE.COMisalice, an AD useralice@ad.example.com) needs a role group, and PAM's account stack must let it in (the realm's permitted groups), as for SSH and Cockpit. Failures count towards the login throttle. - Browsers: Firefox takes the domain in
network.negotiate-auth.trusted-uris; Chrome and Edge a policy (AuthServerAllowlist); a domain's Windows computers do it by themselves for the intranet zone. curl:curl --negotiate -u :. - Status:
stronghold identity(sso:the principal and keytab),GET /v1/identity'ssso, the System tab. - Built with the
gssapitag (MIT krb5's GSSAPI,krb5-devel) and PAM; not on a podman host's controller (SSSD is the host's).
The web proxy's logins¶
The web proxy's clients can log in with the domain's Kerberos, without a
prompt (proxy.md, "Logins"): its key comes from an account of the
proxy's name of its own (stronghold proxy join), and checking the
clients' tickets needs no membership of the box's.
Packages¶
realmd, sssd, sssd-tools, freeipa-client, adcli,
oddjob-mkhomedir, krb5-workstation, all in Fedora, in the host image.
Identity is the host's (PAM, NSS, sudo for the whole box): not a
container.
In the lab¶
stronghold-ipa (FreeIPA, ipa.lab.home.arpa, lab.md); the pair's
resolver forwards that domain to it (dns.yaml's domain-overrides).
gw1 joined with stronghold identity join -u admin (renamed to
gw1.ipa.lab.home.arpa first), gw2 with a one-time password from
ipa host-add gw2.ipa.lab.home.arpa --random; SSSD online on both.
Admins wheel, stronghold-admins, operators netops, viewers
helpdesk:
- The standalone UI: alice (stronghold-admins) admin, bob (netops) operator, carol (helpdesk) viewer, dave (no role group) refused.
- Cockpit, as it comes: alice, bob and carol log in, dave is refused (403, the permitted groups); Cockpit's Overview shows the domain; alice turns on administrative access with her own password (sudo, the drop-in) and the Stronghold plugin shows the config.
sudo -l: alice may run everything, bob nothing.- Found on the way: realmd, already running (any
realmcommand, or Cockpit, starts it), kept the old host name and refused the join as "not fully qualified": restarted after the rename; sudoers takes a group with a space escaped, not quoted; and realmd lets the whole domain log in, so the permitted groups are set right after the join.
In the lab: single sign-on¶
The package-mode VM (stronghold-proxy) joined to the lab's Samba AD DC
(LAB.EXAMPLE, a container on its LAN, 192.168.74.10), jo in
stronghold-admins@lab.example, dave in no role group; a client beside
it (kinit, curl --negotiate -u :), 0.4.0:
stronghold identity join -u Administrator: realmd, SSSD and adcli installed by PackageKit first (a box from packages had none), the box renamedstronghold-proxy.lab.example, joined, andHTTP/stronghold-proxy.lab.exampleon its account, checked with a ticket of the domain's.- jo, with a ticket and no password: the standalone UI's session as an
admin (
GET /v1/session/kerberos, with the box's answer token), usable as any session; Cockpit's/cockpit/login, a session cookie. dave (no role group): refused by both (403); no ticket: 401Negotiate. No SELinux denials; the replay cache in/var/lib/stronghold/krb5. - In a browser (headless Chromium in the client,
AuthServerAllowlistfor*.lab.example, driven over its DevTools protocol): the page logged jo in by itself; after Log out it stayed on the login page; Log in with Kerberos logged in again. Without a ticket: the login page, no prompt, and the button says how to get one. - FreeIPA (its server's container,
IPA.LAB.EXAMPLE, 192.168.74.11): the same box left AD and joined with-u admin: renamedstronghold-proxy.ipa.lab.example, itsHTTP/service made and its key in/etc/cockpit/krb5.keytab, checked with the admin's ticket. alice (stronghold-admins): an admin in the standalone UI (asalice) and in Cockpit; dave: refused by both.
Found on the way:
- The box joined with its short hostname got an account with a short DNS
name, and AD refuses a computer a name not under it (spn validation
failed), which adcli update only warns about: the HTTP key was in
the keytab, the domain gave no tickets for it, and the status said
ready. A join now renames an AD member to its FQDN too, and making the
key asks the domain for a ticket to check it.
- rpm -q (is a join's package there?) couldn't run as strongholdd, so
every join asked PackageKit for all of them: allowed now.
- ipa, as strongholdd, was refused FreeIPA's client state in
/var/lib/ipa-client (it went on without): allowed to read it now.
- The login page's button showed the box's bare "no Kerberos ticket"
rather than how to get one.
Not yet¶
- FreeIPA's HBAC rules instead of the permitted groups, for those who manage access there (SSSD's ipa access provider; the permitted groups replace it).