[[cert-authentication]]= Certificate/smart card authenticationCockpit can use TLS client certificates for authenticating users.Commonly these are provided by a smart card, but it's equally possibleto import certificates directly into the web browser.This requires the host to be in an Identity Management domain likehttps://www.freeipa.org[FreeIPA] orhttps://en.wikipedia.org/wiki/Active_Directory[Active Directory], whichcan associate certificates to users.To authenticate users from a Identity Management domain, the server thatCockpit is running on must be joined to that domain. See thexref:sso.adoc#sso-server[SSO server requirements] for details.[[certauth-server-cert-generation]]== User certificate generationGenerating the certificates for users is usually done with a certificatemanagement system like https://pagure.io/certmonger[certmonger] orhttps://www.freeipa.org/page/PKI[FreeIPA], which are not documentedhere. This command generates a simple key and certificate request forthe "alice" user:....openssl req -new -newkey rsa:2048 -days 365 \-keyout alice.key -out alice.csr -subj "/CN=alice"....Now get this certificate request signed by the Certificate Authority ofyour Identity Management domain, to get a PEM certificate. Browsers andsmart cart utilities accept PKCS#12 format for importing/transfer, soconvert the certificate/key pair; it will ask for and protect it with atransfer password:....openssl pkcs12 -export -in alice.pem -inkey alice.key -out alice.p12....Don't forget to clean up the key file when you do not need it any more:....shred -u alice.key....You can now import `+alice.p12+` directly into your browser, with givingthe transfer password set above. Orhttps://linux.die.net/man/1/pkcs15-init[put the certificate onto a smartcard]:....pkcs15-init --store-private-key alice.p12 --format pkcs12 --auth-id 01....[[certauth-server-ipa]]== Certificate mapping with FreeIPAThe recommended method to sign a user certificate request and associateit to a user is `+ipa cert-request+`:....ipa cert-request alice.csr --principal=alice --certificate-out=alice.pem....Alternatively, if you are using a different CA, you can use`+ipa user-add-cert+` to associate the signed certificate to the user.This expects PEM format, but without the `+-----BEGIN+`/`+-----END+`markers:....ipa user-add-cert alice --certificate="$(grep -v ^---- alice.pem)"....See thehttps://www.freeipa.org/page/V4/User_Certificates#Feature_Management[FreeIPAUser Certificates documentation] for details.[[certauth-server-ms-ad]]== Certificate mapping with Microsoft Active DirectoryThe domain user certificates get imported into the`+userCertificate;binary+` LDAP attribute. The following commandsconvert the PEM certificate into binary DER form, create anhttps://ldap.com/ldif-the-ldap-data-interchange-format/[LDIF] file andapply it to the LDAP server running on the domain controller"dc.example.com":....openssl x509 -outform der -in alice.pem -out alice.dercat <<EOF > alice.ldifversion: 1dn: cn=alice,ou=users,ou=YOUR_NETBIOS_NAME,dc=example,dc=comchangetype: modifyadd: userCertificate;binaryuserCertificate;binary:< file://$(pwd)/alice.derEOFldapmodify -H ldap://dc.example.com -f alice.ldif....[[certauth-server-samba-ad]]== Certificate mapping with Samba Active DirectoryAt least some versions of https://www.samba.org/[Samba] do not supportthe `+userCertificate;binary+` LDAP attribute, so the import has tohappen in base64 PEM form into the textual `+userCertificate+` attributeinstead. Also, Samba uses a slightly different user hierarchy:....cat <<EOF > alice.ldifversion: 1dn: cn=alice,cn=users,dc=example,dc=comchangetype: modifyadd: userCertificateuserCertificate: $(grep -v ^---- alice.pem | tr -d '\n')EOFldapmodify -H ldap://dc.example.com -f alice.ldif....As `+userCertificate+` is a text instead of binary field, you need toset up ahttps://www.mankier.com/5/sssd.conf#Certificate_Mapping_Section[certificatemapping rule] in `+sssd.conf(5)+` in a `+[certmap/domain/rulename]+`section, for example:....[certmap/example.com/adcerts]# we match full certificates, so it is not important to check anything herematchrule = <KU>digitalSignaturemaprule = LDAP:(userCertificate={cert!base64})....[[certauth-server-cockpitconf]]== Cockpit web server configurationSet the trusted Certificate Authority of your user certificates in`+sssd+`, either by copying the CA PEM file to`+/etc/sssd/pki/sssd_auth_ca_db.pem+` or setting thehttps://www.mankier.com/5/sssd.conf#Services_Sections-PAM_configuration_options[`+pam_cert_db_path+`]configuration option to the path of the CA. If you use FreeIPA and itsCA:....cp /etc/ipa/ca.crt /etc/sssd/pki/sssd_auth_ca_db.pem....Certificate authentication needs to be enabled inman:cockpit.conf[5] explicitly:....[WebService]ClientCertAuthentication = yes....When enabling this mode,https://github.com/cockpit-project/cockpit/blob/main/doc/authentication.md[otherauthentication types] commonly get disabled, so that _only_ clientcertificate authentication will be accepted. By default, after a failedcertificate authentication attempt, Cockpit's normal login page willappear and permit other login types such as `+basic+` (passwords) or`+negotiate+` (Kerberos). For example, password authentication getsdisabled with:....[basic]action = none....[[certauth-server-resourcelimits]]== Cockpit web server resource limitsWhen using certificate authentication, all requests with a particularcertificate will be handled by a separate and isolated instance of theman:cockpit-ws[8] web server. This protects againstpossible vulnerabilities in the web server and prevents an attacker fromimpersonating another user. However, this introduces a potential Denialof Service: Some remote attacker could create a large number ofcertificates and send a large number of http requests to Cockpit withthese.To mitigate that, all `+cockpit-ws+` instances run in a`+system-cockpithttps.slice+`https://www.freedesktop.org/software/systemd/man/systemd.slice.html[systemdslice unit] whichhttps://www.freedesktop.org/software/systemd/man/systemd.resource-control.html[limitsthe collective resources] of these web server instances: by default,this slice sets a limit of 200 threads (roughly 100 instances of`+cockpit-ws+` -- in other words, a maximum of 100 parallel usersessions with different certificates) and a 75% (soft)/90% (hard) memorylimit.You are welcome to adjust these limits to your need through ahttps://www.freedesktop.org/software/systemd/man/systemd.unit.html[drop-in].For example:....# systemctl edit system-cockpithttps.slice[Slice]# change existing valueTasksMax=100# add new restrictionCPUQuota=30%....[[certauth-forwarding]]== Authentication to other services like sudo and sshOnce you logged into Cockpit with a certificate, you likely need toswitch to administrative mode (root privileges through sudo), or connectto remote machines through SSH. If your user account has a password,that can be used for authenticating to sudo or ssh as usual._Supported with FreeIPA only:_ As an alternative to passwordauthentication, you can also declare the initial Cockpit certificateauthentication as trusted for authenticating to SSH, sudo, or otherservices. For that purpose, Cockpit automatically creates anhttps://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/bde93b0e-f3c9-4ddf-9f44-e1453be7af5a[S4U2ProxyKerberos ticket] in the user session:....$ klistTicket cache: FILE:/run/user/1894000001/cockpit-session-3692.ccacheDefault principal: user@EXAMPLE.COMValid starting Expires Service principal07/30/21 09:19:06 07/31/21 09:19:06 HTTP/myhost.example.com@EXAMPLE.COM07/30/21 09:19:06 07/31/21 09:19:06 krbtgt/EXAMPLE.COM@EXAMPLE.COMfor client HTTP/myhost.example.com@EXAMPLE.COM....You can set uphttps://www.freeipa.org/page/V4/Service_Constraint_Delegation[constraineddelegation rules] to enumerate which hosts (including its own) thatticket is trusted to access. For example, if the cockpit session runs onhost `+myhost.example.com+` and should be trusted to access its own host(through sudo) and another host `+remote.example.com+` (through ssh),create a delegation like this:....# a list of target machines which can be accessed by a particular ruleipa servicedelegationtarget-add cockpit-targetipa servicedelegationtarget-add-member cockpit-target \--principals=host/myhost.example.com@EXAMPLE.COM \--principals=host/remote.example.com@EXAMPLE.COM# allow cockpit sessions (HTTP/ principal) to access that host listipa servicedelegationrule-add cockpit-delegationipa servicedelegationrule-add-member cockpit-delegation \--principals=HTTP/myhost.example.com@EXAMPLE.COMipa servicedelegationrule-add-target cockpit-delegation \--servicedelegationtargets=cockpit-target....In addition, you need to enable GSS (Kerberos) authentication in thecorresponding services.* For SSH, enable `+GSSAPIAuthentication yes+` inhttps://linux.die.net/man/5/sshd_config[/etc/ssh/sshd_config].* For sudo, enable `+pam_sss_gss+` as described in thehttps://www.mankier.com/8/pam_sss_gss[manpage]: In`+/etc/sssd/sssd.conf+`: Add an entry for your domain:+....[domain/example.com]pam_gssapi_services = sudo, sudo-i....+In `+/etc/pam.d/sudo+`, enable the module in the first line:+....auth sufficient pam_sss_gss.so...._Caveat:_ The delegated S4U ticket is not yet forwarded to remote SSHhosts when connecting to them from Cockpit, so authenticating to sudo onthe remote host with that ticket does not work. This will be provided ina future version.