Skip to content

Instantly share code, notes, and snippets.

@MarkErik
Last active April 8, 2024 19:30
Show Gist options
  • Save MarkErik/5e5af1727d054a33cc28291a024bb5bc to your computer and use it in GitHub Desktop.
Save MarkErik/5e5af1727d054a33cc28291a024bb5bc to your computer and use it in GitHub Desktop.
Automated Script to Setup Rootless Docker and Fail2Ban for Digital Ocean VPS
#!/bin/bash
set -euo pipefail
########################
### ACKNOWLEDGEMENT ###
########################
# Adapted from: https://www.digitalocean.com/community/tutorials/automating-initial-server-setup-with-ubuntu-18-04
########################
### SCRIPT VARIABLES ###
########################
# Name of the user to create and grant sudo privileges
USERNAME=mark
# Should we tweet out the time?
TWEET=no
# Twitter API keys
TWITTERUSER=
CONSUMER_KEY=
CONSUMER_SECRET=
TOKEN=
SECRET=
####################
### SCRIPT LOGIC ###
####################
#save start of execution time
date '+%s' > /root/script-time.txt
#set timezone
timedatectl set-timezone America/Toronto
# Add sudo user and grant privileges
useradd --create-home --shell "/bin/bash" --groups sudo "${USERNAME}"
# Delete invalid password for user if using keys so that a new password
# can be set without providing a previous value
passwd --delete "${USERNAME}"
# Lock the root account to password-based access
passwd --lock root
# Create SSH directory for sudo user
home_directory="$(eval echo ~${USERNAME})"
mkdir --parents "${home_directory}/.ssh"
#create a keypair to do a local ssh session
ssh-keygen -t rsa -q -f "/root/.ssh/local_key" -N ""
cat /root/.ssh/local_key.pub >> /root/.ssh/authorized_keys
# Copy `authorized_keys` file from root
cp /root/.ssh/authorized_keys "${home_directory}/.ssh"
cp /root/.ssh/local_key "${home_directory}/.ssh"
# Adjust SSH configuration ownership and permissions
chmod 0700 "${home_directory}/.ssh"
chmod 0600 "${home_directory}/.ssh/authorized_keys"
chown --recursive "${USERNAME}":"${USERNAME}" "${home_directory}/.ssh"
# Disable root SSH login
sed --in-place 's/^PermitRootLogin.*/PermitRootLogin no/g' /etc/ssh/sshd_config
if sshd -t -q; then
systemctl restart sshd
fi
#update the system
apt-get update
apt-get -y upgrade
apt-get -y autoremove
#install the packages needed for docker, fail2ban
apt-get update
apt-get -y install uidmap tree fail2ban haveged
#have the haveged start at boot to generate more randomness
update-rc.d haveged defaults
#create directory for traefik logs
mkdir --parents "${home_directory}/logs/traefik"
chown --recursive "${USERNAME}":"${USERNAME}" "${home_directory}/logs/traefik"
sudo -u "${USERNAME}" -H sh -c "touch '${home_directory}/logs/traefik/access.log'"
#create files, jails, settings etc. for fail2ban
cat > /etc/fail2ban/jail.d/sshd.local <<EOL
[sshd]
enabled = true
maxretry = 2
findtime = 3m
bantime = 4w
port = ssh
EOL
cat > /etc/fail2ban/jail.d/traefik-auth.local <<EOL
[traefik-auth]
enabled = true
findtime = 3m
bantime = 4w
logpath = ${home_directory}/logs/traefik/access.log
EOL
#install docker
ssh -i /root/.ssh/local_key -o StrictHostKeyChecking=accept-new "${USERNAME}"@localhost "curl -fsSL https://get.docker.com/rootless | sh"
#set variables for docker
echo "export PATH=${home_directory}/bin:$PATH" >> ${home_directory}/.profile
echo "export DOCKER_HOST=unix:///run/user/1000/docker.sock" >> ${home_directory}/.profile
#grant rootless docker capabilities to access ports below 1024
setcap cap_net_bind_service=ep ${home_directory}/bin/rootlesskit
#install docker-compose
ssh -i /root/.ssh/local_key "${USERNAME}"@localhost "curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m) -o ${home_directory}/bin/docker-compose; chmod +x ${home_directory}/bin/docker-compose"
#save end of execution time
date '+%s' >> /root/script-time.txt
#calculate how long it took and save result
starttime=$(sed -n 1p /root/script-time.txt)
endtime=$(sed -n 2p /root/script-time.txt)
totaltime=$(($endtime-$starttime))
echo "Total time: " $totaltime >> /root/script-time.txt
if [ "${TWEET}" == "yes" ]; then
#log the start time for the stuff needed to do the tweet
date '+%s' > "${home_directory}"/twitter-time.txt
# Step 1: Create the file which contains the authorisation keys for twitter and set ownership on it
# using . to represent spaces so that no issues when uploading to github
cat > "${home_directory}"/.trc <<EOL
---
profiles:
..my_username:
...."${TWITTERUSER}":
......username: my_username
......consumer_key: "${CONSUMER_KEY}"
......consumer_secret: "${CONSUMER_SECRET}"
......token: "${TOKEN}"
......secret: "${SECRET}"
configuration:
..default_profile:
....-.my_username
....-."${TWITTERUSER}"
EOL
#change ownership to the user so that it can be passed to the docker container
chown "${USERNAME}":"${USERNAME}" "${home_directory}"/.trc
#replace the periods in the file to spaces
sed -i 's/\./ /g' "${home_directory}"/.trc
#ssh to the user's account and create the docker container to tweet out the time
ssh -i /root/.ssh/local_key "${USERNAME}"@localhost "export DOCKER_HOST=unix:///run/user/1000/docker.sock; ${home_directory}/bin/docker run --rm -v ${home_directory}/.trc:/root/.trc \$(${home_directory}/bin/docker build -q https://gist.githubusercontent.com/MarkErik/5e5af1727d054a33cc28291a024bb5bc/raw/61a6ff48a4d3474596f182b634e14e9a4cb8d982/Dockerfile) t update \"Howdy from a DigitalOcean droplet that took \$((\$("date '+%s'")-\$(cat ${home_directory}/twitter-time.txt))) seconds to create a Docker container to tweet this automatically.\"; ${home_directory}/bin/docker system prune -a -f"
fi
#remove created SSH keypairs and entry in authorized keys
rm /root/.ssh/local_key*
rm "${home_directory}"/.ssh/local_key*
sed -i '$ d' /root/.ssh/authorized_keys
sed -i '$ d' "${home_directory}"/.ssh/authorized_keys
# Expire the sudo user's password immediately to force a change on next login
chage --lastday 0 "${USERNAME}"
#restart the system since the apt-get upgrade required it
reboot
FROM debian:buster-slim
RUN apt-get update
RUN apt-get install -y ruby-dev build-essential
RUN gem install t
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment