Debian 및 Ubuntu에서는 sshd가 /var/log/auth.log에 기록됩니다. RHEL, Rocky, Alma 및 CentOS Stream에서는 /var/log/secure에 기록됩니다. 파일이 없으면 시스템 로그는 시스템 저널에만 기록됩니다. 그런 다음 Debian 기반 시스템에서는 journalctl -u ssh, Red Hat 계열, Fedora 및 Arch에서는 journalctl -u sshd를 사용하세요.
SSH는 거의 모든 Linux 서버의 정문과 같으며, 그래서 그 로그가 거의 모든 Linux 조사에 나타납니다. Prime Core에는 이러한 Linux 인증 로그에서 작동하는 11,632개의 시그마 규칙이 있으며, 이는 643개의 MITRE ATT&CK 기법과 매핑되어 있습니다. 그 중에는 brute force (T1110), 도난된 자격 증명을 사용한 로그인(T1078), SSH를 통한 횡적 이동(T1021.004)이 있습니다. 아래는 sshd 로그를 찾고, 내보내고, 정리하고, 무료로 LogTotal에서 조사하는 방법입니다.
요약
| 배포판 계열 | 로그 파일 | 저널 명령 |
|---|---|---|
| Debian, Ubuntu | /var/log/auth.log | journalctl -u ssh |
| RHEL, Rocky, Alma, CentOS Stream | /var/log/secure | journalctl -u sshd |
| Fedora, Arch, rsyslog 없는 최소 설치 버전 | 기본적으로 없음 | journalctl -u sshd |
시작하기 전에: 로그를 실제로 읽을 수 있나요?
인증 로그는 의도적으로 잠겨 있으므로 일반 계정은 보통 아무것도 얻지 못합니다.
- Debian 및 Ubuntu의 /var/log/auth.log는 루트 및 adm 그룹에서 읽을 수 있습니다.
- Red Hat 계열의 /var/log/secure는 루트 전용입니다.
- 시스템 저널은 루트와 systemd-journal, adm 및 wheel 멤버에게 열려 있습니다. 다른 사람은 자신의 사용자 저널만 볼 수 있습니다. 일반 사용자로 journalctl -u ssh를 실행하면 빈 결과와 다른 사용자의 메시지를 보지 못하고 있다는 힌트를 받게 됩니다. 이는 권한 때문이지 조용한 서버 때문이 아닙니다.
간단한 해결책은 sudo입니다. 로그 수집 전용 계정을 설정하고 있다면 루트를 제공하지 말고 adm 또는 systemd-journal에 추가하세요. 당사의 [Linux 로그 권한 가이드]에서 자세한 내용을 다룹니다.
서버에서 무언가를 복사하기 전에 알아야 할 점: auth 로그에는 사용자 이름, 소스 IP 및 호스트명이 포함되어 있습니다. LogTotal은 업로드 시 정리를 하지만, 먼저 데이터 처리 정책을 확인하세요.
1단계: 파일, 저널, 둘 다?
위의 표는 기본값을 보여줍니다. 기본값은 클라우드 이미지와 강화 스크립트에서 변경하는 것을 좋아합니다. 10초 정도만 확인해 보세요:
ls -l /var/log/auth.log /var/log/secure 2>/dev/null
systemctl is-active rsyslog
파일이 나타나고 rsyslog가 활성 상태이면 두 가지를 모두 사용할 수 있습니다: rsyslog는 메시지를 저널에서 가져와 일반 텍스트 파일로 복사합니다. 어떤 소스든 작동하며 파일이 복사하기 더 쉽습니다.
파일이 없으면 rsyslog가 그냥 설치되지 않은 것입니다. 현재는 기본입니다: Debian 12부터 rsyslog는 기본 설치에 포함되지 않으며, 새로운 Debian 상자에는 auth.log가 전혀 없습니다. Fedora와 Arch는 오랫동안 이런 방식으로 작동해 왔습니다. 2b 단계로 이동합니다.
여기 있는 동안, 저널이 재부팅 후에도 지속되는지 확인하세요:
ls -d /var/log/journal
디렉토리가 존재하지 않으면 journald는 /run/log/journal 아래에 메모리 로그를 보관하며, 재부팅 시 삭제됩니다. 조사 중인 컴퓨터에서는 누군가 ‘그냥 다시 시작’하기로 결정하기 전에 이를 아는 것이 중요합니다.
사고 작업을 위한 또 다른 점: 상자가 손상되었을 가능성이 있는 경우, 로컬 로그도 마찬가지일 수 있습니다. auth.log 삭제 또는 편집은 전형적인 정리 단계입니다. 서버가 SIEM으로 로그를 전달하는 경우, 거기서도 내보내고 비교합니다. 당사의 [Splunk 내보내기 가이드]가 방법을 보여줍니다.
2a 단계: auth.log 또는 secure에서 내보내기
현재 파일은 최근 며칠 동안의 내용만 포함합니다. 오래된 항목은 회전된 파일에 있습니다. Debian 및 Ubuntu에서는 auth.log.1, auth.log.2.gz와 같은 모양입니다. Red Hat 계열에서는 날짜가 포함되어 있습니다, 예를 들어 secure-20261012. 사고가 지난주에 시작되었다면 그것들도 필요합니다.
이 명령은 현재 및 회전된 파일에서 sshd 라인을 가져와 가장 오래된 것부터 하나의 파일에 넣습니다:
# Debian / Ubuntu
sudo zgrep -h ‘sshd’ $(ls -tr /var/log/auth.log*) > web-03_sshd.log
# RHEL / Rocky / Alma
sudo zgrep -h ‘sshd’ $(ls -tr /var/log/secure*) > web-03_sshd.log
zgrep은 일반 파일과 gzipped 파일을 모두 읽습니다, 그래서 아무것도 풀어야하지 않습니다. ls -tr은 수정 시간을 기준으로 정렬하여 가장 오래된 파일이 먼저 나가고 출력이 대략적으로 연대순으로 유지됩니다. sshd 패턴은 또한 sshd-session도 일치하며 이는 최신 시스템에서 중요합니다 (2b 단계 참조).
왜 필터링하는가? 잡음을 줄이는 것 외에도, auth.log는 sudo도 기록합니다, 그리고 sudo 라인은 전체 명령 라인을 포함합니다. 사람들이 그 안에 때때로 암호를 입력합니다. sshd로 필터링하여 파일에서 제외됩니다. 공격자가 한 일을 조사하고 있는 경우 예외입니다 로그인 후에 sudo 라인도 필요합니다: 전체 파일을 가져오고 LogTotal의 정리 단계가 이를 수행하게 합니다.
업로드 전 빠른 확인:
wc -l web-03_sshd.log
head -3 web-03_sshd.log; tail -3 web-03_sshd.log
타임스탬프를 확인하세요. rsyslog 구성에 따라, 이는 고전적인 syslog (Oct 19 10:15:01, 연도 없음, 시간대 없음) 또는 전체 ISO 8601일 수 있습니다. 고전적이라면 서버의 시간대(timedatectl)를 기록해 두세요. 이러한 이벤트를 다른 것들과 정렬하려고 할 때 필요합니다.
2b 단계: systemd 저널에서 내보내기
저널 전용 시스템에서, 이것이 전체 작업입니다:
sudo journalctl -u ssh -u sshd
–since “2026-10-19 00:00” –until “2026-10-20 00:00”
–no-pager -o short-iso > web-03_sshd.log
여기에서 몇 가지 선택은 의도적입니다.
두 개의 유닛 이름. Debian 및 Ubuntu에서는 서비스가 ssh로 불리고 거의 모든 곳에서는 sshd로 불립니다. journalctl은 반복된 -u 플래그를 OR로 결합하므로 두 계열 모두에서 동일한 명령이 작동합니다.
태그가 아닌 유닛으로 필터링하세요. 많은 이전 가이드는 journalctl -t sshd를 사용합니다. OpenSSH 9.8 이후, 서버는 두 개의 바이너리로 분리되었고, 연결당 메시지, 로그인 포함, sshd로 태그되었던 sshd-session으로 태그됩니다. 태그로 필터링하면 정말로 필요한 라인을 놓치게 됩니다. 이는 2024년에 9.8이 도입되었을 때 많은 fail2ban과 sshguard 설정을 망가뜨렸습니다. RHEL 10 및 기타 최신 릴리스는 OpenSSH 9.8 이상을 제공합니다. 유닛별로 필터링하면 서비스에 속한 모든 프로세스가 잡힙니다.
-o short-iso. 이는 연도 및 시간대가 포함된 전체 ISO 8601 타임스탬프와 함께 syslog 스타일의 라인을 제공하므로 추측할 필요가 없습니다. [증명: LogTotal이 short-iso를 분석하는지 확인; 그렇지 않으면 기본 설정 -o short 사용]. 모든 저널 필드를 유지하려면 (PID, 부팅 ID, 호스트 이름 등) -o json을 사용하세요, 이 경우 각 라인을 하나의 JSON 객체로 기록합니다. 파일이 커지지만 아무 것도 손실되지 않습니다.
시간 필터는 상대값도 사용합니다: –since “2 hours ago” 또는 –since yesterday. 영구적인 저널에서는 -b -1이 출력을 이전 부팅으로 제한하여, 사고 이후 서버가 재부팅된 경우에 도움이 됩니다.
/var/log/journal에서 바이너리 .journal 파일을 복사하고 업로드하지 마세요. LogTotal은 텍스트와 JSON을 읽으며, 저널 파일은 그 어떤 것이 아닙니다.
파일을 가지고 나면 무엇을 봐야 할까
대부분의 sshd 라인은 소수의 패턴으로 나뉩니다:
| 라인 시작 | 무엇을 의미하는가 |
|---|---|
| Failed password for <user> from <ip> | 존재하는 계정의 잘못된 암호 |
| Invalid user <user> from <ip> | 사용자 이름이 존재하지 않음; admin, test, oracle을 순환하는 스캐너의 특징 |
| Accepted password for / Accepted publickey for | 성공적 로그인; publickey 라인은 또한 키의 SHA256 지문을 포함 |
| Disconnecting authenticating user … Too many authentication failures | 클라이언트가 MaxAuthTries에 도달 |
| Connection closed by <ip> … [preauth] | 인증 전 차단, 대개 스캐너 및 배너 그랩버 |
| pam_unix(sshd:session): session opened for user | 세션이 실제로 시작됨 |
주의해야 할 시퀀스: 한 IP에서 여러 번의 Failed 또는 Invalid 사용자 라인에 이어 동일한 IP에서 성공적인 Accepted 라인. 이는 성공한 무차별 대입 공격입니다. 뒤따르는 것: 아무도 알지 못하는 주소에서 서비스 계정의 Accepted, 아무도 일하지 않는 시간에.
OpenSSH 9.8 및 이후 버전에서 페널티에 대한 메시지를 볼 수도 있습니다: sshd는 인증에 계속 실패하는 주소를 일시적으로 거부합니다. 이를 증상으로 취급하세요. 이는 누군가가 포트를 계속 밀고 있었음을 나타내며, 그저 누군가가 들어왔다는 것과는 다릅니다.
LogTotal에 업로드하여 정리하고 검토
수백 줄을 눈으로 읽는 것은 괜찮습니다. 하지만 40,000 줄을 읽기에는 괴롭습니다. LogTotal은 설정 없이 로그 파일에 대해 탐지 로직을 실행하는 SOC Prime의 무료 서비스입니다. 업로드한 내용을 정리하고 파일을 보관하지 않습니다.
- 업로드. Open logtotal.com 에 접속하여 web-03_sshd.log를 드롭하세요. [증명: 업로드 화면, 크기 제한]
- 정리. [PROOF: what gets masked in an sshd log: usernames, source IPs, hostnames]. Look over the result before you go on. You know which of those names are sensitive in your environment.
- 검토. [PROOF: what the results screen shows and how findings map to rules and ATT&CK techniques]
실제 데이터에서의 모습. 우리는 일회용 테스트 VM에서 sshd 로그를 생성했습니다: [증명: 몇 가지 일반 사용자 이름에 대한 SSH 암호 스프레이 공격 실행, 성공적인 로그인 하나로 끝나는]. 파일은 [증명: N 줄, X KB]로 나왔습니다. LogTotal은 [증명: 실제 발견 사항, 일치한 규칙, ATT&CK 기술]을 플래그했습니다.
자신의 서버를 만지기 전에 시도해 보시겠습니까? [증명: 샘플 파일 링크]는 위에서 사용한 동일한 파일입니다.
문제가 발생했을 때
| 증상 | 가능한 원인 | Fix |
|---|---|---|
| auth.log에 대해 No such file or directory | rsyslog가 설치되지 않았음 (Debian 12부터 기본) | journalctl 사용, 2b 단계 |
| 로그 파일에 대해 Permission denied | auth.log는 adm 전용, secure는 root 전용 | sudo 사용, 또는 계정 adm에 추가 |
| journalctl -u ssh는 아무것도 반환하지 않으며 다른 사용자에 대한 힌트를 제공 | systemd-journal, adm 또는 wheel의 일원이 아님 | sudo 사용, 또는 계정을 systemd-journal에 추가 |
| journalctl -u ssh는 root로 아무것도 반환하지 않습니다 | 이 배포판에 대한 잘못된 유닛 이름 | -u ssh -u sshd 사용 |
| 로그아웃은 있지만 Accepted 라인이 없음 | OpenSSH 9.8+에서 태그로 필터링 (-t sshd) | 대신 유닛으로 필터링 |
| 마지막 재부팅 이전의 것은 없음 | 휘발성 저널; /var/log/journal 없음 | 오래된 로그가 사라졌음; SIEM 또는 로그 포워더 확인 |
| 파일은 몇 일만 커버합니다 | 회전된 파일이 포함되지 않음 | auth.log* 또는 secure*와 함께 zgrep 명령어 사용 |
| 타임스탬프가 다른 소스와 맞지 않음 | 클래식 syslog 타임스탬프에는 시간대가 없음 | 서버의 시간대를 기록하거나 -o short-iso로 내보내기 |
FAQ
Ubuntu에서 SSH 로그는 어디에 있나요?
표준 Ubuntu 설치의 경우, /var/log/auth.log에 있으며, 저널(journalctl -u ssh)에도 있습니다. 최소 클라우드 이미지는 rsyslog를 생략하기도 합니다. 파일이 없다면 저널을 사용하세요.
SSH 로그인 실패만 보려면 어떻게 하나요?
저널 시스템에서는 sudo journalctl -u ssh -u sshd | grep -E ‘Failed|Invalid user’, 파일이 있는 경우에는 sudo zgrep -hE ‘Failed|Invalid user’ /var/log/auth.log*를 실행하세요. 빠른 확인을 넘어서면 전체 sshd 로그를 업로드하세요. 실패는 성공 옆에서만 의미가 있습니다.
마지막과 lastb는 어떻게?
이들은 /var/log/wtmp 및 /var/log/btmp에 있는 이진 로그인 기록을 읽습니다. 누가 로그인했는지를 빠르게 보기 위해 유용하지만, sshd 자체의 로그보다 세부 내용이 적고 침입자가 이를 조작하기도 쉽습니다.
여러 서버에서 한 번에 sshd 로그를 수집하려면 어떻게 하나요?
일회성에는 반복문이 도움이 됩니다: for h in web-01 web-02 web-03; do ssh “$h” “sudo journalctl -u ssh -u sshd –since yesterday -o short-iso –no-pager” > “${h}_sshd.log” done 이는 원격 측에서 비밀번호 프롬프트 없이 작동하려면 sudo가 필요합니다. 그렇지 않으면 ssh에 -t를 추가하고 매번 입력하면 됩니다. 이 작업을 분기별로 여러 번 하는 경우, 로그를 SIEM으로 전달하세요.
sshd 로그를 온라인 도구에 업로드해도 안전한가요?
LogTotal은 분석 전에 업로드를 정리하며 파일을 보관하지 않습니다; 당사의 [정리 가이드]는 마스킹되는 내용을 보여줍니다. 귀하 조직의 데이터 처리 규칙이 여전히 우선입니다.
다음 단계
파일을 가지고 있나요? LogTotal에 업로드하세요 그리고 11,632개의 시그마 규칙이 그것을 어떻게 처리하는지 확인하세요. 동일한 탐지 로직을 모든 Linux 서버에서 파일 하나씩이 아닌 실행하고 싶다면.
참조
- Debian 12 릴리스 노트: 시스템 로깅 변경
- OpenSSH 9.8 릴리스 노트: sshd / sshd-session 분할 및 변경된 로그 태그
- journalctl(1): 유닛 필터, 출력 형식, 저널 액세스 그룹
- journald.conf(5): 영구 저장대와 휘발성 저장대