Initial Server Setup on CentOS 7
Every new CentOS 7 box I get shows up the same way: root only, password SSH login on, and whatever packages the image builder felt like including. I got tired of doing this from memory and forgetting a step, so now I run the same short checklist every time: a sudo user, locked-down SSH, firewalld, and a sane clock. About fifteen minutes, and it works on any provider or a local VM.
You need root over SSH (or the console) and an SSH client. On Windows I use PuTTY.
1. Update the system
Log in as root and bring everything up to date first, so the rest of the steps run against current packages.
yum update -y
yum install -y vim wget bind-utils net-tools
If the update pulled in a new kernel, reboot now rather than later:
reboot
2. Create a regular user with sudo
Working as root all day is a habit worth breaking. I've typed one wrong rm as root too many times. Create a normal account and add it to the wheel group, which is already allowed to use sudo on CentOS 7.
adduser deploy
passwd deploy
usermod -aG wheel deploy
Confirm that the wheel line in /etc/sudoers is not commented out. Use visudo rather than editing the file directly, because it checks the syntax before saving:
visudo
The line you want active is:
%wheel ALL=(ALL) ALL
Now open a second terminal and verify that you can log in as deploy and run sudo whoami before you touch the SSH configuration. Keep the root session open as a safety net.
3. Set up an SSH key for the new user
Generate a key on your workstation if you do not already have one:
ssh-keygen -t rsa -b 4096 -C "deploy@workstation"
Copy the public key to the server. ssh-copy-id does the directory creation and permissions for you:
ssh-copy-id deploy@203.0.113.10
If ssh-copy-id is not available, do it manually on the server:
mkdir -p /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
vim /home/deploy/.ssh/authorized_keys # paste the public key
chmod 600 /home/deploy/.ssh/authorized_keys
chown -R deploy:deploy /home/deploy/.ssh
4. Harden the SSH daemon
Edit /etc/ssh/sshd_config and change the following directives. Some are commented out by default; uncomment them.
PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
Check the file for syntax errors and reload:
sshd -t
systemctl reload sshd
Test from your workstation with ssh deploy@203.0.113.10 in a new window. Don't close the root session until key login works. Seriously.
5. Firewalld
CentOS 7 ships with firewalld, but on some cloud images it's disabled. Turn it on and allow only SSH for now.
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --permanent --add-service=ssh
firewall-cmd --reload
When you later install a web server, add the services the same way:
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
6. Hostname and time
Give the machine a proper name and keep the clock in sync. Bad clocks make logs useless when you're chasing something across two servers. CentOS 7 uses chrony by default.
hostnamectl set-hostname web01.example.com
timedatectl set-timezone Europe/Berlin
yum install -y chrony
systemctl enable chronyd
systemctl start chronyd
Did it work?
From the deploy account:
sudo -v # asks for your password, then succeeds
sudo firewall-cmd --list-all # shows ssh in services
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication'
chronyc tracking # shows a reference server and small offset
Also try ssh root@203.0.113.10 from your workstation; it should be refused with Permission denied (publickey).
Things that bit me
- Locked out after disabling passwords. If you see
Permission denied (publickey,gssapi-keyex,gssapi-with-mic), the key was not installed correctly. Use the provider's console to log in and check the ownership and permissions of~/.ssh(700) andauthorized_keys(600). SELinux can also block a freshly created directory; runrestorecon -Rv /home/deploy/.sshto fix the context. deploy is not in the sudoers file. This incident will be reported.The user was not added towheel, or the%wheelline is still commented out. Log in as root and rerunusermod -aG wheel deploy; the change takes effect on the next login.- firewalld blocks a service you just installed. Remember that
--permanentrules are not active untilfirewall-cmd --reload. Conversely, a rule added without--permanentdisappears on the next reload or reboot. sshd -treportsBad configuration option. Usually a typo in a directive name. sshd will refuse to reload with a broken config, which is exactly why you test first.
Next on my list is usually fail2ban, but honestly with key-only SSH it's more about log noise than safety.