Skip to content

Instantly share code, notes, and snippets.

@nothub
Created January 27, 2021 22:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nothub/dd6596a193264a7a88a9dbfaff29eba4 to your computer and use it in GitHub Desktop.
Save nothub/dd6596a193264a7a88a9dbfaff29eba4 to your computer and use it in GitHub Desktop.
ubuntu focal standalone initial setup
#!/usr/bin/env bash
# MANDATORY options
SETUP_HOSTNAME="" # full domain that is pointed to this box
SETUP_USERNAME="" # admin user
SETUP_SSH_PUBKEY="" # admin users ssh public key
SETUP_FORWARD_EMAIL="" # root and user mails gonna be forwarded to this
# OPTIONAL options
SETUP_DISABLE_IPV6=true
SETUP_HARDEN_NETWORK=true
SETUP_INSTALL_DOCKER=true
SETUP_INSTALL_NETDATA=true
set -e
if [ "$EUID" -ne 0 ]; then
echo >&2 "run as root!"
exit
fi
if ! grep -q DISTRIB_CODENAME=focal /etc/lsb-release; then
echo >&2 "wrong os!"
exit
fi
if [ -z "$SETUP_HOSTNAME" ]; then
echo >&2 "no hostname specified!"
exit
fi
if [ -z "$SETUP_USERNAME" ]; then
echo >&2 "no username specified!"
exit
fi
if [ -z "$SETUP_FORWARD_EMAIL" ]; then
echo >&2 "email address specified!"
exit
fi
if [ -z "$SETUP_SSH_PUBKEY" ]; then
echo >&2 "no ssh key specified!"
exit
fi
# set hostname
hostnamectl set-hostname $SETUP_HOSTNAME
# disable ipv6
SETUP_REQUIRES_REBOOT=false
if [ "$SETUP_DISABLE_IPV6" = true ]; then
# disable ipv6
echo "Disabling IPv6"
{
echo ""
echo "#disable ipv6"
echo "net.ipv6.conf.all.disable_ipv6=1"
echo "net.ipv6.conf.default.disable_ipv6=1"
echo "net.ipv6.conf.lo.disable_ipv6=1"
} >>/etc/sysctl.conf
sysctl -p
SETUP_REQUIRES_REBOOT=true
fi
# harden network
if [ "$SETUP_HARDEN_NETWORK" = true ]; then
# set hardened network settings
echo "Hardening network settings"
{
echo ""
echo "#harden network"
echo "net.ipv4.conf.default.rp_filter=1"
echo "net.ipv4.conf.all.rp_filter=1"
echo "net.ipv4.tcp_syncookies=1"
echo "net.ipv4.conf.all.accept_redirects=0"
echo "net.ipv4.conf.all.send_redirects=0"
echo "net.ipv4.conf.all.accept_source_route=0"
echo "net.ipv4.conf.all.log_martians=1"
if [ "$SETUP_DISABLE_IPV6" = false ]; then
echo "net.ipv6.conf.all.accept_redirects=0"
echo "net.ipv6.conf.all.accept_source_route=0"
fi
} >>/etc/sysctl.conf
sysctl -p
fi
# disable motd ads
echo "Disabling motd ads"
if [ -f /etc/default/motd-news ]; then
sed -i 's/ENABLED=1/ENABLED=0/g' /etc/default/motd-news
fi
systemctl disable --now motd-news.timer
# use default apt archive servers
echo "Configuring default apt server"
{
echo "deb http://archive.ubuntu.com/ubuntu focal main restricted universe multiverse"
echo "deb http://archive.ubuntu.com/ubuntu focal-updates main restricted universe multiverse"
echo "deb http://archive.ubuntu.com/ubuntu focal-security main restricted universe multiverse"
echo "deb http://archive.ubuntu.com/ubuntu focal-backports main restricted universe multiverse"
} >/etc/apt/sources.list
# set up locales
export DEBIAN_FRONTEND=noninteractive
apt-get -qy update
echo "Configuring locales"
apt-get -qy install language-pack-en-base language-pack-en
localectl set-locale LANG=en_US.UTF-8
echo "Configuring timezone"
timedatectl set-timezone Europe/Berlin
# remove bloat
echo "Removing bloat"
apt-get -qy purge \
apport \
apport-symptoms \
cloud-guest-utils \
cloud-init \
cloud-initramfs-copymods \
cloud-initramfs-dyn-netconf \
landscape-common \
pastebinit \
popularity-contest \
snapd \
telnet
# reloading systemd daemon
systemctl daemon-reload
# clean up cloud-init
rm -rf /etc/cloud/
rm -rf /var/lib/cloud/
# clean up snapd
rm -rf /root/snap
rm -rf /var/cache/snapd/
# full-update apt packages
apt-get -qy full-upgrade
# install additional apt packages
apt-get -qy install \
apt-transport-https \
apt-utils \
bash-completion \
ca-certificates \
curl \
debconf-utils \
fail2ban \
git \
htop \
iftop \
man \
nano \
netcat \
openssh-server \
openssl \
rsync \
screen \
shellcheck \
software-properties-common \
tldr \
tree \
ufw \
unattended-upgrades \
unzip \
vim \
wget
# configure firewall
echo "Setting up firewall"
if [ "$SETUP_DISABLE_IPV6" = true ]; then
{
echo ""
echo "IPV6=no"
} >>/etc/ufw/ufw.conf
systemctl restart ufw
fi
ufw logging on
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh/tcp
ufw --force enable
# install netdata
if [ "$SETUP_INSTALL_NETDATA" = true ]; then
curl https://my-netdata.io/kickstart.sh -o netdata-install.sh
chmod +x netdata-install.sh
./netdata-install.sh --non-interactive
rm netdata-install.sh
fi
# install docker
if [ "$SETUP_INSTALL_DOCKER" = true ]; then
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
apt-get -qy update
apt-get -qy install docker-ce docker-ce-cli containerd.io
systemctl enable docker
# enable memory limit and swap accounting
sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"/g' /etc/default/grub
update-grub
SETUP_REQUIRES_REBOOT=true
# install docker-compose
curl -L "https://github.com/docker/compose/releases/download/1.28.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
fi
# add user
SETUP_PRINT_PASSWORD=false
if id "$SETUP_USERNAME"; then
echo "User $SETUP_USERNAME already exists"
else
# add admin user
echo "Adding user $SETUP_USERNAME"
adduser --quiet --disabled-password --gecos "" "$SETUP_USERNAME"
gpasswd -a "$SETUP_USERNAME" sudo
SETUP_PASS="$(openssl rand -base64 14)"
echo "$SETUP_USERNAME:$SETUP_PASS" | chpasswd
SETUP_PRINT_PASSWORD=true
fi
# install mail utils
# shellcheck disable=SC2154
debconf-set-selections <<<"postfix postfix/mailname string $myhostname"
debconf-set-selections <<<"postfix postfix/main_mailer_type select Internet Site"
debconf-set-selections <<<"postfix postfix/protocols select ipv4"
apt-get -qy install mailutils postfix
if grep -Eq '\smyorigin|^myorigin' /etc/postfix/main.cf; then
# shellcheck disable=SC2016
sed -i '/myorigin/s/= .*/= $myhostname/' /etc/postfix/main.cf
else
echo "myorigin = \$myhostname" >>/etc/postfix/main.cf
fi
if grep -Eq '\smydestination|^mydestination' /etc/postfix/main.cf; then
# shellcheck disable=SC2016
sed -i '/mydestination/s/= .*/= localhost.$mydomain, localhost, $myhostname/' /etc/postfix/main.cf
else
echo "mydestination = localhost.\$mydomain, localhost, \$myhostname" >>/etc/postfix/main.cf
fi
if grep -Eq '\sinet_interfaces|^inet_interfaces' /etc/postfix/main.cf; then
sed -i '/inet_interfaces/s/= .*/= loopback-only/' /etc/postfix/main.cf
else
echo "inet_interfaces = loopback-only" >>/etc/postfix/main.cf
fi
systemctl restart postfix
echo "root: $SETUP_FORWARD_EMAIL" >>/etc/aliases
echo "$SETUP_USERNAME: $SETUP_FORWARD_EMAIL" >>/etc/aliases
echo "testing mail transfer agent by sending a mail to root" | mail -s "beep boop" root
echo "testing mail transfer agent by sending a mail to $SETUP_USERNAME" | mail -s "beep boop" $SETUP_USERNAME
# clean up packages
echo "Cleaning up packages"
apt-get -qy autoremove
apt-get -qy clean
# ssh config
echo "Configuring ssh"
{
echo "HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256"
echo "KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256"
echo "MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com"
echo "Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr"
echo "HashKnownHosts yes"
} >/etc/ssh/ssh_config
# sshd config
echo "Configuring sshd"
{
echo "HostKey /etc/ssh/ssh_host_ed25519_key"
echo "HostKey /etc/ssh/ssh_host_rsa_key"
echo "KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256"
echo "MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com"
echo "Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com"
echo "LogLevel VERBOSE"
echo "Subsystem sftp internal-sftp"
echo "PermitRootLogin No"
echo "LoginGraceTime 1m"
echo "UseDNS no"
echo "AllowTcpForwarding no"
echo "X11Forwarding no"
echo "AuthenticationMethods publickey"
echo "UsePAM yes"
echo "PasswordAuthentication no"
echo "PermitEmptyPasswords no"
echo "ChallengeResponseAuthentication no"
echo "KerberosAuthentication no"
echo "GSSAPIAuthentication no"
echo "Match User $SETUP_USERNAME"
echo " AllowTcpForwarding yes"
} >/etc/ssh/sshd_config
# sshd auth config
if [[ -n "$SETUP_SSH_PUBKEY" ]]; then
echo "Authorizing ssh key"
cd /home/"$SETUP_USERNAME"
mkdir -p .ssh
touch .ssh/authorized_keys .ssh/known_hosts
echo "$SETUP_SSH_PUBKEY" >.ssh/authorized_keys
chmod 700 .ssh
chmod 600 .ssh/authorized_keys
chown -R "$SETUP_USERNAME":"$SETUP_USERNAME" .ssh
else
echo "Enabling ssh password auth for $SETUP_USERNAME"
{
echo " AuthenticationMethods publickey password"
echo " PasswordAuthentication yes"
} >>/etc/ssh/sshd_config
fi
# generate server keys
echo "Deleting old ssh server keys"
cd /etc/ssh
shred -u ssh_host_*key*
echo "Generating ed25519 ssh server key"
ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N ""
echo "Generating rsa ssh server key"
ssh-keygen -t rsa -b 8192 -f ssh_host_rsa_key -N ""
# restart sshd
echo "Restarting sshd"
systemctl restart sshd
# done
echo "########"
if [ "$SETUP_PRINT_PASSWORD" = true ]; then
echo "Password for $SETUP_USERNAME is: $SETUP_PASS"
fi
if [ "$SETUP_INSTALL_NETDATA" = true ]; then
echo "Netdata was installed, establish a connection via ssh tunnel like this: ssh -L 19999:localhost:19999 $SETUP_HOSTNAME@$SETUP_USERNAME and visit http://127.0.0.1:19999/ in your browser. read the guide at: check the guide at https://github.com/netdata/netdata/blob/master/docs/quickstart/single-node.md"
fi
if [ "$SETUP_REQUIRES_REBOOT" = true ]; then
echo "Please reboot the machine for certain changes to take effect!"
fi
echo "Setup finished!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment