tatu/files/user-cloud-config
Pino de Candia 8ba9919b5a Detailed documentation of sudo_pam option and pam-ussh module
Also, configure pam-ussh module directly in /etc/pam.d/sudo and leave
/etc/pam.d/system-auth unchanged.

Change-Id: Ie86daf7f51c99915d20d0a7da9020584d807f9c8
Signed-off-by: Pino de Candia <giuseppe.decandia@gmail.com>
2018-03-13 05:55:35 +00:00

161 lines
7.2 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#cloud-config
mounts:
- [ /dev/disk/by-label/config-2, /mnt/config ]
write_files:
- path: /root/tatu-setup-ssh.sh
permissions: '0700'
owner: root:root
content: |
#!/bin/bash
# Name: tatu-setup-ssh.sh
#
# Purpose: Fetch a SSH host cert from Tatu and configure SSH to use certs.
metadata=$(cat /mnt/config/openstack/latest/meta_data.json)
auth_id=$(echo $metadata | grep -Po 'project_id": "\K[^"]*')
if [ -z $auth_id ]; then
echo Failed to extract the project ID from metadata
exit 1
fi
echo auth_id=$auth_id
host_id=$(echo $metadata | grep -Po 'uuid": "\K[^"]*')
echo host_id=$host_id
vendordata=$(cat /mnt/config/openstack/latest/vendor_data2.json)
pam_sudo=$(echo $vendordata | grep -Po '"pam_sudo": \K[^,]*' | tr '[:upper:]' '[:lower:]')
pam_sudo=${pam_sudo:-false}
echo pam_sudo=$pam_sudo
token=$(echo $vendordata | grep -Po '"token": "\K[^"]*')
if [ -z $token ]; then
echo Failed to extract the Tatu token ID from vendordata
exit 1
fi
echo token=$token
ca_user=$(echo $vendordata | grep -Po '"auth_pub_key_user": "\K[^"]*')
echo ca_user=$ca_user
echo $ca_user > /etc/ssh/ca_user.pub
#root_principals=$(echo $vendordata | grep -Po '"root_principals": "\K[^"]*')
#echo root_principals=$root_principals
users=$(echo $vendordata | grep -Po '"users": "\K[^"]*')
echo users=$users
sudoers=$(echo $vendordata | grep -Po '"sudoers": "\K[^"]*')
echo sudoers=$sudoers
ssh_port=$(echo $vendordata | grep -Po '"ssh_port": \K[^,]*')
echo ssh_port=$ssh_port
host_pub_key=$(cat /etc/ssh/ssh_host_rsa_key.pub)
echo host public key is $host_pub_key
data=$(echo {\"token_id\": \"$token\", \"host_id\": \"$host_id\", \"pub_key\": \"$host_pub_key\"})
echo $data > /tmp/tatu_cert_request.json
api=$(echo $vendordata | grep -Po '"api_endpoint": "\K[^"]*')
url=$api/noauth/hostcerts
echo Posting Host Certificate request to Tatu API at $url
response=$(curl -s -w "%{http_code}" -d "@/tmp/tatu_cert_request.json" -X POST $url)
code=${response##*\}}
if [ "$code" != "200" ]; then
echo Curl to Tatu API failed with code $code
exit 1
fi
echo Tatu response is $response
cert=$(echo $response | grep -Po 'cert": "\K[^"]*')
cert=${cert%%\\n} # TODO: fix the trailing \n on the server side.
echo $cert > /etc/ssh/ssh_host_rsa_key-cert.pub
mkdir -p /etc/ssh/auth_principals
#root_principals_file=/etc/ssh/auth_principals/root
#> $root_principals_file
#for i in ${root_principals//,/ }
#do
# echo $i >> $root_principals_file
#done
for i in ${users//,/ }; do
id -u $i > /dev/null 2>&1
if [ $? == 1 ]; then
#adduser --disabled-password --gecos '' $i
adduser $i
fi
done
x=0
for i in ${sudoers//,/ }; do
prefix=$((130 + x++))
if [ "$pam_sudo" = true ]; then
echo $i ALL= ALL > /etc/sudoers.d/$prefix-$i
echo Defaults:$i timestamp_timeout=1 >> /etc/sudoers.d/$prefix-$i
else
echo $i ALL= NOPASSWD: ALL > /etc/sudoers.d/$prefix-$i
fi
done
if [ "$pam_sudo" = true ]; then
(crontab -l; echo "* * * * * /root/tatu-setup-pam.sh >> /var/log/tatu-setup-pam.log") | crontab -
fi
sed -i -e '$aTrustedUserCAKeys /etc/ssh/ca_user.pub' /etc/ssh/sshd_config
# man sshd_config, under AuthorizedPrincipalsFile: The default is none, i.e. not to use a principals file
# in this case, the username of the user must appear in a certificate's principals list for it to be accepted.
#sed -i -e '$aAuthorizedPrincipalsFile /etc/ssh/auth_principals/%u' /etc/ssh/sshd_config
sed -i -e '$aHostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub' /etc/ssh/sshd_config
sed -i -e '/^PasswordAuthentication /d' /etc/ssh/sshd_config
sed -i -e '$aPasswordAuthentication no' /etc/ssh/sshd_config
> /etc/ssh/revoked-keys
sed -i -e '$aRevokedKeys /etc/ssh/revoked-keys' /etc/ssh/sshd_config
sed -i -e '$aPort '"$ssh_port" /etc/ssh/sshd_config
sed -i -e '$aPort 22' /etc/ssh/sshd_config
setenforce permissive
systemctl restart sshd
echo Completed!
- path: /root/tatu-setup-pam.sh
permissions: '0700'
owner: root:root
content: |
#!/bin/bash
# Name: tatu-setup-pam.sh
#
# Purpose: Install uber/pam-ussh so that every sudo call authenticates the user's certificate in the background.
# If the user's certificate expires or is revoked, sudo authentication will fail. They lose sudo privileges even if
# they are still logged in.
crontab -l | grep -v 'tatu-setup-pam' | crontab -
cd /root
rm -rf /root/pam-ussh
inst=`which dnf`
inst=${inst:-`which yum`}
inst=${inst:-`which apt-get`}
$inst install -y pam-devel golang git
git clone https://github.com/pinodeca/pam-ussh
cd pam-ussh
git checkout -b krl origin/krl
export GOPATH=/root/pam-ussh/.go
go get golang.org/x/crypto/ssh
go get github.com/stretchr/testify/require
go get github.com/stripe/krl
make
mv pam_ussh.so /lib64/security/
vendordata=$(cat /mnt/config/openstack/latest/vendor_data2.json)
sudoers=$(echo $vendordata | grep -Po '"sudoers": "\K[^"]*')
echo setting up pam-ussh sudo authentication for $sudoers
sed -i -e '/auth.*include.*system-auth/i \
auth sufficient /lib64/security/pam_ussh.so ca_file=/etc/ssh/ca_user.pub authorized_principals='"$sudoers"' revoked_keys_file=/etc/ssh/revoked-keys' /etc/pam.d/sudo
- path: /root/tatu-manage-revoked-keys.sh
permissions: '0700'
owner: root:root
content: |
#!/bin/bash
# Name: tatu-manage-revoked-keys.sh
#
# Purpose: Fetch the revoked keys data from Tatu and write it to /etc/ssh
# !/usr/bin/env python
metadata=$(cat /mnt/config/openstack/latest/meta_data.json)
auth_id=$(echo $metadata | grep -Po 'project_id": "\K[^"]*')
echo auth_id=$auth_id
vendordata=$(cat /mnt/config/openstack/latest/vendor_data2.json)
api=$(echo $vendordata | grep -Po '"api_endpoint": "\K[^"]*')
url=$api/noauth/revokeduserkeys/$auth_id
echo Fetching revoked user keys from Tatu API at $url
response=$(curl -s -w "%{http_code}" $url)
code=${response##*\}}
if [ "$code" != "200" ]; then
echo Curl to Tatu API failed with code $code
exit 1
fi
echo Tatu response is $response
b64revoked=$(echo $response | grep -Po 'revoked_keys_data": "\K[^"]*')
echo $b64revoked | base64 -d > /etc/ssh/revoked-keys
runcmd:
- /root/tatu-setup-ssh.sh > /var/log/tatu-setup-ssh.log 2>&1
- /root/tatu-manage-revoked-keys.sh > /var/log/tatu-revoked-keys.log
- crontab -l | { cat; echo "* * * * * /root/tatu-manage-revoked-keys.sh >> /var/log/tatu-revoked-keys.log"; } | crontab -