I would like to manually set my ssh keys from a bash script provided in user data and disable the first time login password change request when logging with my ssh keys. Is this possible?
Here’s what I’m doing so far:
#!/bin/bash
root_ssh_key="ssh-rss ..."
ssh_port=22
sshd_config="/etc/ssh/sshd_config"
sudo_user="dev"
sudo_user_home="/home/${sudo_user}"
sudo_user_ssh_key="ssh-rss ..."
# ########################
# updates
setup_updates() {
echo "Running updates..."
# get updates and install
sudo apt-get update
sudo apt-get dist-upgrade -y
}
# ########################
# user account
setup_account() {
echo "Configuring user account..."
# add the specified '$sudo_user'
sudo adduser $sudo_user --disabled-password --gecos ""
# add '$sudo_user' to the sudo group
sudo gpasswd -a $sudo_user sudo
# add sudo permissions
echo "$sudo_user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
#
# ssh access
#
ssh_folder=${sudo_user_home}/.ssh
# create .ssh folder restrict permissions
sudo mkdir -p -v $ssh_folder
sudo chmod 700 $ssh_folder
authorized_keys_file=${ssh_folder}/authorized_keys
# create an authorized_keys's file
sudo touch $authorized_keys_file
# write the ssh keys to the user's authorized_keys file and restrict permissions
echo $sudo_user_ssh_key > $authorized_keys_file
sudo chmod 600 $authorized_keys_file
# set $sudo_user as the owner of the folder
sudo chown -R ${sudo_user}:sudo $ssh_folder
# set port and disable authentication with passwords
sudo sed -i -e "/^Port/s/^.*$/Port ${ssh_port}/" $sshd_config
sudo sed -i -e '/^PasswordAuthentication/s/^.*$/PasswordAuthentication no/' $sshd_config
sudo sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin without-password/' $sshd_config
# allow root and $sudo_user to connect
sudo echo -e "\nAllowUsers root $sudo_user" >> $sshd_config
# restart
sudo service ssh restart
# set root ssh keys
echo $root_ssh_key > "/root/.ssh/authorized_keys"
}
# ########################
# setup firewall
#
setup_firewall() {
echo "Setting up ufw..."
# defaults
sudo ufw default deny incoming
sudo ufw default allow outgoing
# exceptions
sudo ufw allow ${ssh_port}/tcp
sudo ufw allow http
sudo ufw allow https
# start on boot
sed -i -e '/^ENABLED/s/^.*$/ENABLED=yes/' /etc/ufw/ufw.conf
# enable
sudo ufw enable
}
# ########################
# main
#
main() {
echo "Initializing droplet as $USER..."
# check if user is root
if [ "$UID" -ne 0 ] ; then
echo "Must be root to run this script."
exit 1
fi
# setup_updates
setup_account
setup_firewall
echo "Droplet initialized."
echo "Rebooting..."
sudo shutdown -r now
}
main
I’m able to immediately login with my dev account. But I would like to prevent that first time password change request for the root. How can I do this without providing my root ssh key outside of this script?
These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.
Click below to sign up and get $100 of credit to try our products over 60 days!
@nmdias
From what I’m reading, you can change passwords for users, but
root
isn’t one of them, at least not in the way you’re wanting. This could be done on DigitalOceans end if they modified one of the modules, though I don’t see a way for this to be done user-side using just Cloud Init and without the modification.That being said, I know you’re waiting to keep your public key within the script, though it’d be better to simply provide that public key to DigitalOcean that way you don’t have to worry about password authentication for the
root
user.Public Keys can be made public. There’s really no security concern as without the Private Key, there’s no way to authenticate using the Public Key. If you’re truly concerned about security, use a passcode on the Private Key and make sure the Private Key is at least 4096 bits. Alternatively, use Elliptic Curve instead of RSA (noted as some feel that 4096 bit keys are pointless – I use and prefer them or EC).