sudo: Configure pam_ssh_agent_auth

I do not like how Fedora CoreOS configures `sudo` to allow the *core*
user to run privileged processes without authentication.  Rather than
assign the user a password, which would then have to be stored
somewhere, we'll install *pam_ssh_agent_auth* and configure `sudo` to
use it for authentication.  This way, only users with the private key
corresponding to one of the configured public keys can run `sudo`.

Naturally, *pam_ssh_agent_auth* has to be installed on the host system.
We achieve this by executing `rpm-ostree` via `nsenter` to escape the
container.  Once it is installed, we configure the PAM stack for
`sudo` to use it and populate the authorized keys database.  We also
need to configure `sudo` to keep the `SSH_AUTH_SOCK` environment
variable, so *pam_ssh_agent_auth* knows where to look for the private
keys.  Finally, we disable the default NOPASSWD rule for `sudo`, if
and only if the new configuration was installed.
master
Dustin 2024-01-28 12:33:57 -06:00
parent d6751af326
commit f886a1bd8a
21 changed files with 113 additions and 0 deletions

View File

@ -0,0 +1,6 @@
package schema
#Sudo: {
use_pam_ssh_agent: bool | *false
authorized_keys?: string
}

21
app/sudo/templates.cue Normal file
View File

@ -0,0 +1,21 @@
package sudo
import "du5t1n.me/cfg/base/schema/instructions"
templates: [...instructions.#RenderInstruction] & [
{
template: "sudo/sudo.pam.conf"
dest: "/etc/pam.d/sudo"
},
{
template: "sudo/authorized_keys"
dest: "/etc/security/sudo.authorized_keys"
},
{
template: "sudo/ssh-auth-sock.sudoers"
dest: "/etc/sudoers.d/ssh-auth-sock"
owner: "root"
group: "root"
mode: "u=rw,g=r,o="
},
]

13
env/prod/sudo.cue vendored Normal file
View File

@ -0,0 +1,13 @@
package prod
import (
"du5t1n.me/cfg/app/sudo/schema"
)
sudo: schema.#Sudo & {
use_pam_ssh_agent: true
authorized_keys: """
sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAINZCN2cxMDwedJ1Ke23Z3CZRcOYjqW8fFqsooRus7RK0AAAABHNzaDo= dustin@rosalina.pyrocufflink.blue
sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIAB6xTCSNz+AcQCWcyVKs84tThXN4wpLgCo2Lc48L6EsAAAABHNzaDo= dustin@luma.pyrocufflink.blue
"""
}

View File

@ -12,3 +12,5 @@ nut: monitor: prod.#nut_monitor & {
} }
collectd: prod.collectd collectd: prod.collectd
sudo: prod.sudo

View File

@ -0,0 +1 @@
. scripts/no-coreos-default-sudo.sh

View File

@ -0,0 +1,5 @@
#!/bin/sh
. scripts/pam-ssh-agent-auth.sh
install_packages

View File

@ -10,3 +10,5 @@ nut: monitor: schema.#NutMonitor
nut: monitor: prod.#nut_monitor & { nut: monitor: prod.#nut_monitor & {
#username: "nvr1" #username: "nvr1"
} }
sudo: prod.sudo

View File

@ -0,0 +1 @@
. scripts/no-coreos-default-sudo.sh

View File

@ -0,0 +1,5 @@
#!/bin/sh
. scripts/pam-ssh-agent-auth.sh
install_packages

View File

@ -1 +1,7 @@
package serial1 package serial1
import (
"du5t1n.me/cfg/env/prod"
)
sudo: prod.sudo

View File

@ -0,0 +1 @@
. scripts/no-coreos-default-sudo.sh

View File

@ -0,0 +1,5 @@
#!/bin/sh
. scripts/pam-ssh-agent-auth.sh
install_packages

View File

@ -5,6 +5,7 @@ import (
"du5t1n.me/cfg/app/collectd" "du5t1n.me/cfg/app/collectd"
"du5t1n.me/cfg/app/nut" "du5t1n.me/cfg/app/nut"
"du5t1n.me/cfg/app/sudo"
) )
render: list.Concat([ render: list.Concat([
@ -12,4 +13,5 @@ render: list.Concat([
nut.templates, nut.templates,
nut.monitor.templates, nut.monitor.templates,
nut.collectd.templates, nut.collectd.templates,
sudo.templates,
]) ])

View File

@ -4,9 +4,11 @@ import (
"list" "list"
"du5t1n.me/cfg/app/nut" "du5t1n.me/cfg/app/nut"
"du5t1n.me/cfg/app/sudo"
) )
render: list.Concat([ render: list.Concat([
nut.sysusers.templates, nut.sysusers.templates,
nut.monitor.templates, nut.monitor.templates,
sudo.templates,
]) ])

View File

@ -4,8 +4,10 @@ import (
"list" "list"
"du5t1n.me/cfg/app/collectd" "du5t1n.me/cfg/app/collectd"
"du5t1n.me/cfg/app/sudo"
) )
render: list.Concat([ render: list.Concat([
collectd.templates, collectd.templates,
sudo.templates,
]) ])

View File

@ -0,0 +1,6 @@
if [ -f /host/etc/sudoers.d/coreos-sudo-group ] &&
[ -s /host/etc/sudoers.d/ssh-auth-sock ] &&
[ -s /host/etc/security/sudo.authorized_keys ]
then
rm -f /host/etc/sudoers.d/coreos-sudo-group
fi

View File

@ -0,0 +1,3 @@
. scripts/rpm-ostree-install.sh
check_install /host/lib*/security/pam_ssh_agent_auth.so pam_ssh_agent_auth

View File

@ -0,0 +1,16 @@
INSTALL_PACKAGES=''
check_install() {
if [ ! -e "${1}" ]; then
INSTALL_PACKAGES="${INSTALL_PACKAGES} ${2}"
fi
}
install_packages() {
if [ ! -z "${INSTALL_PACKAGES}" ]; then
echo "Installing packages: ${INSTALL_PACKAGES}" >&2
nsenter -m -u -i -n -p -t 1 \
rpm-ostree install -y --allow-inactive --idempotent --apply-live \
${INSTALL_PACKAGES}
fi
}

View File

@ -0,0 +1 @@
{{ sudo.authorized_keys }}

View File

@ -0,0 +1,3 @@
{% if sudo.use_pam_ssh_agent -%}
Defaults env_keep += "SSH_AUTH_SOCK"
{% endif -%}

View File

@ -0,0 +1,10 @@
#%PAM-1.0
{% if sudo.use_pam_ssh_agent -%}
-auth sufficient pam_ssh_agent_auth.so file=/etc/security/sudo.authorized_keys
{% endif -%}
auth include system-auth
account include system-auth
password include system-auth
session optional pam_keyinit.so revoke
session required pam_limits.so
session include system-auth