8ba9919b5a
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>
161 lines
7.2 KiB
Plaintext
161 lines
7.2 KiB
Plaintext
#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 -
|