LabHub
배우기 러닝패스 코스

SSH and File Transfer

The Order and Verification of sshd Hardening

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

sshd 설정을 바꿀 때 가장 중요한 것은 어떤 값을 넣느냐가 아니라 어떤 순서로 확인하느냐다. 잘못하면 자기 자신을 잠근다.

Concept map: 어떤 값을 넣느냐가 아니라 어떤 순서로 확인하느냐 · 타고 있는 나뭇가지를 자르는 일 · 현재 세션을 유지한 채 · 문법을 검사한다

왜 이게 필요했나

원격 서버의 sshd 설정을 고치는 것은 타고 있는 나뭇가지를 자르는 일과 같다. 설정이 틀리면 sshd 가 안 뜨고, 안 뜨면 들어갈 방법이 없다. 콘솔 접근이 없는 클라우드 인스턴스라면 인스턴스를 통째로 재생성해야 할 수도 있다.

그래서 절차가 있다.

  1. 현재 세션을 유지한 채 새 터미널을 하나 더 열어 둔다
  2. 설정 파일을 수정한다
  3. sshd -t문법을 검사한다
  4. 서비스를 재적재한다
  5. 기존 세션을 닫지 말고 새 터미널에서 접속을 확인한다
  6. 확인이 끝난 뒤에만 기존 세션을 닫는다

3번과 5번을 건너뛰는 사람이 정말 많다. 그리고 그중 일부가 새벽에 데이터센터로 간다.

어떻게 동작하나

검사 명령이 두 개다.

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 는 문법만 본다. -T최종적으로 적용되는 값을 전부 보여 준다. 이 차이가 중요한 이유는 요즘 배포판이 설정을 조각내기 때문이다.

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

같은 키가 여러 번 나오면 sshd 는 첫 번째 값을 쓴다. 그래서 Include 가 파일 앞쪽에 있으면 조각 파일이 이기고, 뒤쪽에 있으면 본문이 이긴다. "분명히 고쳤는데 안 먹는다" 의 절반이 여기서 나온다. -T 로 확인하는 습관이 이 문제를 원천 차단한다.

권장 설정과 각 값의 의미.

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

Match 블록으로 예외를 만든다.

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

Match 는 조건이 맞으면 다음 Match 나 파일 끝까지의 설정을 덮어쓴다. 같은 키워드가 여러 Match 에서 만족되면 첫 번째 것만 적용된다. 순서가 결과를 바꾸므로 sshd -T -C ... 로 반드시 검증한다.

현장에서 만나는 모습

접속이 안 될 때의 계층별 진단. 세 메시지의 구분이 진단의 절반이다.

그리고 ssh -vvv 를 읽는 요령. debug1: Connecting to 까지 못 가면 네트워크 문제고, Offering public key 다음에 Authentications that can continue 가 반복되면 서버가 그 키를 거부한 것이다.

잠그다가 스스로를 잠그지 않는 법

sshd 설정을 죄는 작업은 자기 자신을 밖으로 밀어낼 수 있는 몇 안 되는 작업이다. 순서를 지키면 그 위험이 사라진다.

지금 세션을 절대 끊지 않는다. sshd 를 재시작해도 이미 맺어진 연결은 유지된다. 그러니 그 세션을 살려 둔 채 새 창으로 접속을 시험한다. 되면 그때 원래 세션을 닫고, 안 되면 원래 세션에서 되돌린다.

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

설정 파일 두 곳을 함께 본다. 요즘 배포판은 /etc/ssh/sshd_config.d/*.conf 를 읽고, 먼저 나온 값이 이긴다. 본 파일을 고쳤는데 안 먹으면 드롭인이 앞에서 정하고 있는 것이다.

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

sshd -T실제로 적용될 값을 보여 준다. 파일을 읽는 것보다 이쪽이 정확하다.

한 번에 다 죄지 않는다. 비밀번호 인증을 끄기 전에 모든 사람이 키로 들어올 수 있는지 먼저 확인한다. 확인하지 않고 끄면, 그 순간부터 못 들어오는 사람이 생기고 그 사실을 그 사람이 필요할 때 알게 된다.

포트를 바꾸는 것은 보안이 아니라 소음 감소다. 자동 스캔 로그는 줄지만 실제 공격을 막지는 못한다. 대신 방화벽으로 접속 가능한 출발지를 제한하거나 fail2ban 으로 반복 실패를 차단하는 것이 실효가 있다.

진짜로 값이 큰 세 가지는 이것이다.

설정 효과
PasswordAuthentication no 무차별 대입이 통하지 않는다
PermitRootLogin no 계정 이름을 하나 더 알아내야 한다
AllowGroups ssh-users 새 계정이 자동으로 접속 권한을 얻지 않는다

콘솔 접근을 확보해 둔다. 클라우드의 직렬 콘솔이나 IPMI 로 들어갈 수 있는지 미리 확인한다. ssh 로만 닿는 서버에서 sshd 설정을 죄는 것은 되돌릴 길이 없는 작업이 된다.

다음 실습에서 할 것

drop-in 설정 파일로 sshd 를 하드닝하고, sshd -tsshd -T 로 검증한다. Match 블록을 만들어 조건부 적용까지 확인하고, 마지막에 키 접속은 여전히 되고 비밀번호 인증은 거부되는지 실제로 시험한다.