Created
January 27, 2021 22:50
-
-
Save nothub/dd6596a193264a7a88a9dbfaff29eba4 to your computer and use it in GitHub Desktop.
ubuntu focal standalone initial setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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