TT Lab
Get started
Learn Learning paths Courses

SSH and File Transfer

The Order and Verification of sshd Hardening

Continue in TT Lab

In one line

When you change the sshd configuration, the most important thing is not what value you put in but in what order you check. If you get it wrong, you lock yourself out.

Why this exists

Editing the sshd configuration on a remote server is like cutting the branch you are sitting on. If the configuration is wrong, sshd does not start, and if it does not start, there is no way in. On a cloud instance with no console access, you may have to recreate the whole instance.

That is why there is a procedure.

  1. Keeping the current session, open one more new terminal
  2. Edit the configuration file
  3. Check the syntax with sshd -t
  4. Reload the service
  5. Without closing the existing session, confirm the connection in the new terminal
  6. Close the existing session only after the confirmation is done

A great many people skip steps 3 and 5. And some of them end up going to the data center at dawn.

How it works

There are two check commands.

sshd -t                      # 문법만 검사
sshd -T | sort | head -40    # 실제 적용될 유효 설정 전체 출력
sshd -T -C user=deploy,host=10.0.3.14,addr=10.0.3.14 | grep -i 'passwordauth\|pubkey'

-t looks only at the syntax. -T shows all the values that are finally applied. The reason this difference matters is that recent distributions split the configuration into fragments.

Include /etc/ssh/sshd_config.d/*.conf

If the same key appears several times, sshd uses the first value. So if the Include is at the front of the file, the fragment files win, and if it is at the back, the main body wins. Half of "I definitely fixed it but it has no effect" comes from here. The habit of checking with -T blocks this problem at the source.

Recommended settings and the meaning of each value.

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
AllowGroups sshusers
X11Forwarding no
PermitEmptyPasswords no
LogLevel VERBOSE

You create exceptions with a Match block.

Match Group sftponly
  ChrootDirectory /srv/sftp/%u
  ForceCommand internal-sftp
  AllowTcpForwarding no

When its condition matches, Match overrides the settings up to the next Match or the end of the file. If the same keyword is satisfied in several Match blocks, only the first one applies. Because order changes the result, always verify with sshd -T -C ....

What it looks like in the field

Layered diagnosis when you cannot connect. Telling the three messages apart is half of the diagnosis.

And a tip for reading ssh -vvv. If it does not get as far as debug1: Connecting to, it is a network problem, and if Authentications that can continue repeats after Offering public key, the server rejected that key.

How not to lock yourself out while locking things down

Tightening the sshd configuration is one of the few jobs that can push you out of the machine yourself. If you keep to the order, that risk disappears.

Never cut the current session. Even if you restart sshd, connections already established are maintained. So keep that session alive and test the connection in a new window. If it works, then close the original session, and if it does not, revert from the original session.

sshd -t                       # 문법 검사. 통과해야 재시작한다
systemctl reload sshd
ssh -o BatchMode=yes user@host true   # 다른 창에서

Look at both configuration locations. Recent distributions read /etc/ssh/sshd_config.d/*.conf and the value that comes first wins. If you edited the main file and it has no effect, a drop-in is deciding earlier.

sshd -T | grep -iE 'permitrootlogin|passwordauth|pubkeyauth|port'

sshd -T shows the values that will actually apply. It is more accurate than reading the files.

Do not tighten everything at once. Before you turn off password authentication, first check that everyone can get in with keys. If you turn it off without checking, from that moment some people cannot get in, and they learn of it when they need to.

Changing the port is noise reduction, not security. The automatic scan logs shrink but it does not stop real attacks. Instead, restricting the allowed source addresses with a firewall or blocking repeated failures with fail2ban is what is effective.

The three things that are really valuable are these.

Setting Effect
PasswordAuthentication no Brute force does not work
PermitRootLogin no You have to discover one more account name
AllowGroups ssh-users A new account does not automatically gain access

Secure console access. Check in advance whether you can get in through the cloud's serial console or IPMI. Tightening the sshd configuration on a server reachable only by ssh becomes a job with no way back.

What you will do in the next lab

You harden sshd with a drop-in configuration file and verify with sshd -t and sshd -T. You create a Match block and even check conditional application, and at the end you actually test whether key access still works and password authentication is rejected.