Considering Ubuntu (22.02 LTS), what setup and hardening guide do you follow?
And if not using Ubuntu, or using a different version, please describe what you use and why (and if being so generous, also what guide you follow).
TIA!
They take a while to come for the latest version of a OS and none is out for Ubuntu later than 20.04 yet, but it is a very good starting point for a checklist even if you do not run a DoD system (a lot of the points might be specific for these but easily skipped) and depending on changes between versions, some parts might still apply. For a recently released OS you usually have to rely on the system documentation from the system creator (Canonical in this case) but most of my experience is from the Red Hat world so not sure how good it is for other distros.
If you start with the best practices for your OS/distro and then dig into a hardening guide (like STIG) you should probably have a pretty good understanding and base documentation for your specific use-case. As always, if you use a specific service/software on top of that (a web-server, mail-server, etc) you will need to dig into the documentation of that specific product and after that check for hardening guides.
The general principle of removing/disabling/blocking everything that you do not use is usually a good one. Knowing what you actually use and the exceptions is what makes it hard :-)
It is my experience that most guides you will find for Linux hardening are either outdated, too opinionated or are written with shock value to induce paranoia [0].
I harden ssh (no root login, no passwords), setup fail2ban for it and leave it at that.
Only thing I remember to do is not to mess with security configurations e.g disabling selinux to make something work. Keeping number of software installed to an absolute minimum. And last but not least I setup automatic updates via unattended-upgrades.
[0] https://madaidans-insecurities.github.io/guides/linux-harden...
I use to download the Cookbooks for CIS benchmark from Chef’s repos.
An important detail is that these frameworks will typically word a control as "Disable X, unless it is required by the application or not used”. Don’t beat yourself up for removing controls that are not applicable to your situation.
Once your application is installed and configured, with configuration management of course, set AppArmor or SELinux into permissive but logging mode. After profiling the application in use for a period, write a policy to allow those events for your application and enable enforcing mode.
Systemd offers some very simple to use controls as well. You can update your application unit to do sandboxing things like block access to system directories, block system capabilities, and even limit network access. These additions are very easy with significant rewards.
If you can bake it all into a machine image, glorious. If you need last mile configuration or personalization, use cloud-init to make those changes on first boot. If you need to save state, externalize it with an additional volume or network storage. Log to an external system, and disable remote access. Enforce a maximum life for a server to a couple of days and replace. Of course, many applications can’t survive as cattle and need to live longer or have difficult replacement procedures.
Stick with Ubuntu LTS, unless you are willing to pay for RHEL. Do NOT use Fedora or any Arch based distro, those have way too aggressive releases to be considered for any type of server (they are fine desktop or lab distros but I would never consider them for legit servers).
Ideally have a firewall (or security group if in AWS, etc) that sits in front of your server. Make sure only the absolute necessary ports are open (white list by ip if you can). Extra credit have Wire Guard server that you connect to and only allow ssh through that.
If you are the only person accessing a shell on the machine then make sure shh allows keys only, and make sure you private key has a pass phrase on it. Extra credit, use jump cloud (free if you have under 5 users), and it’s super easy to enforce 2FA with ssh.
If you have several people that need to ssh then use a short lived certificate solution like Teleport.
My only tip I haven't seen mentioned here is be very careful using docker with ufw, as by default docker will effectively override ufw port restrictions if it is told to expose a port.
It applies to basically every distribution and has useful links at the bottom for even more tips.
* Check open/listening ports and reconfigure or disable unnecessary services to limit attack surface. Do you really need an NTP server, or just a client? What about SNMP, you going to use that or do you use telegraf/metricbeat/whatever?
* Harden configs for any remaining services. SNMPv3 only. SSH key/cert based auth only. Disable insecure ciphers or protocols.
* Keep the distro PATCHED. So easy to pwn old ass sudo binaries, openssl versions, or kernels. Patch your shit. Can't overstate this.
* send audit logs to a central log store, for post-intrusion forensics
I also run endlessh on TCP port 22, and a fake HTTP server as a community service.
You can get a rough feel for the enthusiasm of your distro's desire to do 'hardened things' by checking its kernel config. Heres one such script that has consolidated some hardening guides; https://github.com/a13xp0p0v/kconfig-hardened-check and also spot check with http://kernsec.org/wiki/index.php/Kernel_Self_Protection_Pro...
Then can also see if the distro is doing things to harden the binaries (relro, nx, canaries, aslr, pie, etc) ; https://www.trapkit.de/tools/checksec/ Also! you may be surprised to find which distros are comfortable with allowing unprivileged user namespaces (kernel.unprivileged_userns_clone=1)
Maybe wouldn't set up a pubnix on them without some tweaking, but for most use cases the defaults are sane. Maybe disable password login on SSH and if you're worried.
Set up a honeypot if you don't believe me.
Be aware and focus specifically on which ports/services are available from the internet.
If you absolutely need SSH, ensure you use something like fail2ban and use complex credentials. If possible, use obscurity to change from the default port of 22.
If you're running an internet-facing service, like nginx, ensure that it's always up to date.
Using SELinux and AppArmour and GRSecurity are usually way overkill and cumbersome to manage.
I HTTPS all the things except the Tasmota UIs. I use a SmallStep CA with ACME on my internal network to get certs for my internal stuff; to be safe, the root cert is NameConstrain'ed to `.lan`. Obviously everything is in my local DNS. If someone steals that approach: Make sure to put DHCP-assigned DNS names into something like `.dhcp.lan` ;-)
As you can see, this is already quite opinionated. Generally: Be minimal with what you expose, make sure to quickly update, setup SELinux, setup proper firewalls/VLANs for multi-host deployments. SSH only with keys, not with passwords. Compartmentalize, so that one breach doesn't pwn your machine(s). For that you need either more physical machines, or you can put stuff in containers (I prefer root-less podman over docker) or VMs (e.g. libvirt/qemu or ESXi).
Also, don't rely on some Ubuntu LTS to get all updates you need for "a long time". E.g. Tomcat is a community package and the 18.04 LTS was missing many (security) updates last time I've checked. I've also seen docker containers not being timely updated by their maintainers. Do some external port scans to not be surprised that you e.g. accidentially left your SQL open for the world. Because mistakes happen, and a `nmap -T5 -p1-65535 $host` doesn't hurt you.
Instead, if you'd like to improve your security, I'd recommend 3 things:
- Learn basics of threat modelling. There are many posts about it, but in short it's asking: who can do what and what are the options to prevent that.
- Learn what's running in your system. What services you're running, what apps. What untrusted data hits any software.
- Go to the higher quality sources for what you actually care about. For example, you find out you're running samba - read the security sections of their docs https://www.samba.org/samba/docs/using_samba/ch09.html and system administration guides. Read about firewall configuration for your system.
Seriously though: Lynis when setting things up and then for work CIS.
But, that's just checking boxes. I do use apparmor to lockdown my browser and VMM but that's as far as I go and I have accepted that security on Linux is a dangerous illusion because there will always that one man page, that one setting everyone appsrently knows, that one permission you are expected to know by implication of having an understanding of some Linux subsystem where that is really all anyone targeting you needs to get in or move laterally. Logging more than you should and forwarding centrally (auditd and security logs) seems about all you can do (detection focused not prevention) that said, checking boxes is much better than defaults. Security is a reponsibility left to the user/admin by default and to be fair, Linux is hardlh alone in that regard,it just so happens to change a lot making it harder to keep up.
- I put all my servers on a private network (e.g., db server, web server, monitoring server)
- The only server exposed to the internet is my load balancer (usually nginx) and a bastion server
- The bastion server only runs SSH. It's hardened (how good? I don't know; I just try to follow "best practices") and nothing else runs on it
- I access my internal servers via the bastion server
Not sure how secure my setup is, but I am not a "sec" guy, and the above setup is already above my average knowledge of software engineering (which is what I usually do). I know I could go for a VPN, or pay a saas to have better security, or use SELinux or what not...
There's no perfect guide. You should collect things that make sense to you, put them in git and apply to your servers via Ansible/SaltStack
You can disable and remove services you don't use and turn on auto-update and that will be good enough for day to day use in my opinion.
Do you want which of the two?
* performance
* security
* older hardware
You can also do it the easy way, instead of installing Ubuntu, which is based on Debian, install and Arch spin such as Arco Linux https://arcolinux.com/ and during the installation choose the 'hardened kernel' option instead of the default or zen kernel.