[Из песочницы] Safe-enough quick linux server base install
release: 2005, Ubuntu + CentOS (supposed to work with Amazon Linux, Fedora, Debian, RHEL as well)
updated: 2020 APR 27
by: @timurxyz
org: secdev.eu, defdev.eu
You fire up a professionally prepared Linux image at a cloud platform provider (Amazon, DO, Google, Azure, etc.) and it will run a kind of production level service moderately exposed to hacking attacks (non-targeted, non-advanced threats).
Disclaimers:
- It’s not at all a guide for Docker containers or for a seriously hardened production server.
- The author is not a certified unix admin or a devsecops guru.
What would be the standard settings to have configured before you install the meat? A subjective advise, Ubuntu-first approach:
- You are already experienced in Linux administration.
- As an admin you work on a trusted machine (desktop, laptop or tablet), properly hardened, continuously patched, with security not weared off by years of usage or being shared.
- There is a handy facility to generate and store passwords available on the above admin client.
- Your SSH keys or other credentials to admin the instance are handled securely on your admin machine. (An issue in itself how to satisfy this requirement. Like should your keys be enclosed in password or token protected key stores or drives?!)
- Your access to the cloud platform provider is secure enough, and your user/account there is handled with security in mind.
- You manage the cloud platform provider’s web UI in a browser which you use solely for admin tasks.
- To sum the above: The security context of your installation (instance cooking) work is on a higher level of assurance than the level you would expect from the instance you configure.
- You use a Linux image provided by a party whose security competence is assumed (like the image baked by the cloud platform provider themselves or the Linux distro builder).
- You login to the instance via a trusted and clean terminal app or within admin browser via the native web-CLI.
The best approach is to adhere to cyber hygiene practices from the zero moment and not rely on an idea that security can be hardened in a bonus step afterwards.
Our advice would be to use — a corporate managed — iPad as a trusted admin client at a remote location or a managed desktop at the enterprise internal network. In case you/the company are/is subject for targeted attacks then laptops are a weaker choice for paranoids. But that’s an other story to which I will dedicate an article or a post later.
Have a matching firewall protection enabled
I mean which serves as the internet facing firewall behind which your instance is running. Amazon calls it the security group, in DO that’s the firewalls feature of a project. This filters ports internet connections can hit on your instance. Plan which external firewall preset will match the open ports of the instance you are installing. SSH + the ports of services. The external firewall may allow more ports as the preset may serve several types of instances. The good old approach to minimize the open ports is still valid.
You may have different firewall presets ready for different stages of your installations. Like in the beginning port 22 is the one you start off, but when a non standard SSH port is configured you may switch to a preset with 22 closed forever and the corresponding internet noise will not hit your instance.
Choosing the initial connect/login method
- In case you have your working practice to connect to the cloud platform resources, connect as you deem it safe. Otherwise:
- If the cloud platform allows I would choose the option with connecting to ssh with a random root password generated by the platform (DO offers this). See the explanation of my pro-passwords (long random passwords) point of view in a below section.
Don’t let a fresh instance run as is in the wild
Be paranoid, don’t let a fresh instance to run unpatched while exposed to internets. When fired up log in within minutes to start patching.
Login
… and
sudo -s
Unless otherwise indicated all below commands you issue as root .
Make sure the bare system is up-to-date
# Ubuntu
apt update
apt ugrade
# CentOS
dnf update
dnf upgrade
# + both optionally:
shutdown -r now
Restarting is technically not necessary, but it won’t harm.
Basic steps
- Enable the local firewall and allow some ports. (It’s indeed useless to enable the firewall if you already enabled a frontfacing firewall on the provider’s host, but still.)
- Set the timezone.
Ubuntu:
ufw enable
ufw allow 22, <*your custom ssh, eg 52112*>
# see the SSHd setup below
ufw status
# make your time meaningful, change the location:
timedatectl set-timezone Europe/Berlin
CentOS:
# may firewalld not present:
dnf install firewalld
systemctl enable firewalld --now
# then
firewall-cmd --state
# should be '*running*'
firewall-cmd --list-all
# should be telling something like:
# *public (active)*
# *services: cockpit dhcpv6-client ssh*
firewall-cmd --list-all-zones | more
firewall-cmd --get-default-zone
# public
# add a custom ssh port, see the SSHd setup below
firewall-cmd --permanent --zone=public --add-port=<*your custom ssh, eg 52112*>/tcp
# success
firewall-cmd --complete-reload
firewall-cmd --list-all
# now should also contain your custom ssh port
# make your time meaningful, change the location:
timedatectl set-timezone Europe/Berlin
SELinux, AppArmor
Check the AppArmor or SELinux status:
# Ubuntu:
apparmor_status
# CentOS:
sestatus
It’s not that you should bother with it, but it’s still more secure to utilize an Linux distro preconfigured with LSM in enforcing mode active, so try to make it an aspect when you choose your provider and select from the factory maintained images there. However based on other’s opinions and considering the «micro threat model» set out above I would not make it a prerequisite. In order for LSM to make real sense it should be tuned adequately to your services and the particular situation.
Comfort first
Make yourself comfortable and productive, like:
- zsh, fish or a similar advanced shell will help you a lot (tuning it is not discussed here).
- wget is used in this guide.
- Don’t hesitate to install the editor of choice as early as possible (I promote micro here, tho it’s a bit more complicated to install).
apt/dnf install zsh wget
which zsh
echo $0
# Ubuntu
snap install micro --classic
Yes I start with suppressing a security alert. Let’s be realistic. Let’s face it all systems are non-secure, even bash had horrible security flaws, everything has, maybe except ssh written by paranoid and methodic freaks.))
Alternatively install micro from:
https://github.com/zyedidia/micro/releases/
mkdir -p /tank/packagez
chown -R root:wheel /tank/packagez
mkdir /opt/bin
cd /tank/packagez
wget https://github.com/zyedidia/micro/releases/download/v2<...>/micro-2<...>-linux64.tar.gz
tar xf micro...
mv micro.../micro /opt/bin/
chown -R root:root /opt/bin
chmod -R 755 /opt/bin
export PATH="$PATH:/opt/bin"
micro /etc/profile.d/env.sh
# create or add
export PATH="$PATH:/opt/bin"
# * or to the PATH in /etc/environment if that one is in use by the os
Password quality
Mod the password quality settings:
# on Ubuntu you may need to install this first
apt install libpam-pwquality
# then
micro /etc/security/pwquality.conf
# enable:
minlen = 20
ocredit = -2
This will set the minimum password length to 20 and require 2 special characters in it. Why 20? Ok, let it be 25. See also my bellow comment regarding passwords vs key files. (I suggest using random passwords and SSH password authentication instead of key files, hence the length. See the explanation of my pov in a below section.)
Your personal user
For sshing your persistent instance imo a good practice would look like follows:
ssh -p 52112 lola@acme.web
- custom user, custom port
Create an admin user:
# Ubuntu
useradd --uid <*1111*> -N --home /home/.<*lola*> --shell /usr/bin/zsh -g admin -G users <*lola*>
# CentOS
useradd --uid <*1111*> -N --home /home/.<*lola*> --shell /bin/zsh -g wheel -G users <*lola*>
- mind to rewrite to your nick
UID does not matter actually
zsh may not be your choice
mind that home directory is hidden in the above example (yes I think obscurity adds to security a bit))