# 디버깅 모드 사용

#### 디버깅 모드 개요

OpenSSH의 디버깅 모드는 SSH 클라이언트 및 서버에서 발생하는 문제를 해결하는 데 중요한 도구이다. `ssh` 또는 `sshd` 명령어에 특정 플래그를 추가하여 디버깅 출력을 활성화할 수 있으며, 이를 통해 문제를 보다 명확하게 파악할 수 있다. 디버깅 모드는 다양한 레벨로 설정할 수 있으며, 각 레벨은 로그의 상세도에 영향을 미친다.

#### 클라이언트 디버깅 활성화

클라이언트 측에서 디버깅 모드를 활성화하기 위해서는 `ssh` 명령어에 `-v`, `-vv`, `-vvv` 플래그를 사용한다. `-v` 플래그 하나만 사용하면 기본적인 디버깅 정보가 출력되며, `-vv`는 추가적인 정보, `-vvv`는 매우 상세한 디버깅 정보를 출력한다.

```bash
ssh -v user@host
```

* `-v`: 기본적인 정보 (핸드쉐이크, 키 교환, 인증 등)
* `-vv`: 추가 정보 (네트워크 트래픽 분석, 세부 인증 정보 등)
* `-vvv`: 가장 상세한 디버깅 정보 (모든 데이터의 흐름을 추적)

#### 서버 디버깅 활성화

서버 측에서 디버깅 모드를 활성화하려면 `sshd` 데몬을 직접 실행할 때 `-d`, `-dd`, `-ddd` 플래그를 사용한다. 이때 SSH 서버는 백그라운드에서 실행되지 않으며, 터미널에서 직접 실행된다. 이는 새로운 SSH 연결을 처리하기 위한 디버깅에 유용하다.

```bash
sudo /usr/sbin/sshd -d
```

* `-d`: 기본적인 서버 디버깅 정보 (클라이언트 접속, 키 교환, 인증 등)
* `-dd`: 추가적인 정보
* `-ddd`: 매우 상세한 디버깅 정보

서버 디버깅 모드는 특히 인증 문제, 연결 끊김, 비정상적인 네트워크 트래픽 문제를 진단하는 데 유용하다.

#### 디버깅 출력을 분석하는 방법

디버깅 모드가 활성화되면, SSH 클라이언트와 서버는 각각 터미널에 디버깅 정보를 출력한다. 이러한 로그는 여러 단계에서 발생하는 문제를 분석할 수 있게 해 준다. 디버깅 모드에서 주의깊게 봐야 할 로그 정보는 다음과 같다.

* **Key exchange**: SSH 세션이 시작될 때 클라이언트와 서버 간의 키 교환 과정이 정상적으로 이루어지는지 확인한다. 이 과정에서 발생하는 오류는 `diffie-hellman` 알고리즘의 문제일 가능성이 높다.
* **Authentication**: 클라이언트가 서버로부터 인증을 받을 때 발생하는 문제를 추적한다. 특히, 공개키 인증에서 문제가 발생하면 이 로그를 확인해야 한다.
* **Session setup**: 세션이 설정되는 과정에서 발생하는 문제를 로그에서 확인할 수 있다. 서버에서 세션 생성이 실패하거나 터미널이 정상적으로 할당되지 않는 경우도 이 부분에서 확인할 수 있다.

#### Key exchange 과정의 디버깅

SSH는 보안을 유지하기 위해 세션 시작 시 **Key exchange** 과정을 거친다. 이 과정에서는 클라이언트와 서버가 암호화 알고리즘과 공개키를 사용하여 보안을 설정한다. 이 과정에서 발생할 수 있는 오류는 주로 다음과 같은 문제를 포함한다:

* **암호화 알고리즘의 불일치**: 클라이언트와 서버가 지원하는 암호화 알고리즘이 서로 다를 때 발생할 수 있다. 이 경우 로그에 "no matching key exchange method found" 또는 "couldn't agree on a key exchange algorithm" 등의 오류 메시지가 나타난다.
* **Diffie-Hellman 그룹 문제**: SSH는 기본적으로 **Diffie-Hellman** 알고리즘을 사용하여 세션 키를 교환한다. 이 과정에서 사용되는 그룹(모듈로 나눈 수치)에 문제가 발생할 수 있다. 이는 주로 클라이언트나 서버가 오래된 소프트웨어 버전을 사용할 때 발생하며, 로그에서 "bad server DH group" 또는 "DH group mismatch"와 같은 메시지를 볼 수 있다.

**Key exchange** 과정에서 일반적으로 추적해야 하는 로그 항목은 다음과 같다:

1. `debug1: kex: initiate`
2. `debug1: kex: algorithm`
3. `debug1: kex: server->client cipher`
4. `debug1: kex: client->server cipher`

로그에서 클라이언트와 서버가 사용하는 알고리즘 및 암호화 방식을 확인하고, 호환되지 않는 경우 이에 맞는 설정을 변경해야 한다.

#### Authentication 과정의 디버깅

SSH 세션에서 클라이언트가 서버에 접속하려면 인증 과정이 필요하다. 공개키 인증, 비밀번호 인증, GSSAPI, Kerberos 등의 여러 인증 방법이 있다. 이 과정에서 발생할 수 있는 문제들은 다음과 같다:

* **공개키 인증 실패**: 클라이언트가 잘못된 공개키를 사용하거나, 서버의 `authorized_keys` 파일에 잘못된 권한이 설정되어 있을 때 발생할 수 있다. 디버깅 로그에서는 "Authentication refused: bad ownership or modes for directory" 또는 "Permission denied (publickey)"와 같은 메시지를 확인할 수 있다.
* **비밀번호 인증 실패**: 비밀번호 인증이 실패할 경우, 서버 설정에서 비밀번호 인증이 비활성화되어 있거나, 잘못된 비밀번호가 입력되었을 가능성이 있다. 이 경우 로그에서 "Permission denied, please try again" 메시지를 볼 수 있다.
* **GSSAPI/Kerberos 문제**: 이러한 인증 방법은 네트워크 환경이나 클라이언트 설정에 의존하는 경우가 많다. 이 과정에서 로그에 "GSSAPI authentication failed"와 같은 메시지를 확인할 수 있다.

Authentication 단계에서 확인해야 할 로그 항목은 다음과 같다:

1. `debug1: userauth-request`
2. `debug1: Offering public key`
3. `debug1: Server accepts key`
4. `debug1: Authentication succeeded (publickey)` 또는 `debug1: Authentication failed`

#### 포트 포워딩의 디버깅

SSH의 고급 기능 중 하나인 **포트 포워딩**은 디버깅이 필요한 경우가 종종 있다. 특히, **로컬 포트 포워딩** 및 **원격 포트 포워딩** 설정이 제대로 작동하지 않으면 클라이언트와 서버 간의 연결 문제를 확인해야 한다.

* **로컬 포트 포워딩 오류**: 클라이언트에서 서버로 데이터를 포워딩할 때, 해당 포트가 이미 사용 중일 경우 문제가 발생할 수 있다. 로그에서 "bind: Address already in use" 메시지를 확인하면 이 문제를 알 수 있다.
* **원격 포트 포워딩 오류**: 서버에서 클라이언트로의 포워딩에 실패하면, 클라이언트 또는 서버의 방화벽 설정이 원인이 될 수 있다. 로그에서 "remote port forwarding failed"와 같은 메시지를 볼 수 있다.

포트 포워딩 디버깅 시 확인해야 할 로그 항목은 다음과 같다:

1. `debug1: Local forwarding`
2. `debug1: Remote forwarding`
3. `debug1: Forwarded connection`

포트 포워딩 관련 문제는 SSH 서버와 클라이언트 설정 모두에서 발생할 수 있으며, 방화벽, 네트워크 라우팅 설정도 고려해야 한다.

#### Session setup 과정의 디버깅

SSH 세션이 설정되는 과정에서 여러 단계가 포함되며, 이 과정에서 발생하는 오류는 세션이 성공적으로 설정되지 않거나 비정상적으로 종료되는 원인이 된다. **Session setup** 과정에서 중요한 단계는 다음과 같다:

1. **터미널 할당**: SSH 세션에서 사용자가 상호작용할 수 있는 터미널을 설정하는 과정이다. 이 과정에서 발생하는 문제는 주로 서버에서 터미널을 할당할 수 없는 경우이다. 로그에서 "PTY allocation request failed"와 같은 메시지가 나타날 수 있다. 이 경우 서버의 `sshd_config` 파일에서 `PermitTTY` 설정이 올바르게 되어 있는지 확인해야 한다.
2. **X11 포워딩**: SSH를 통해 X11 세션을 포워딩할 수 있다. 그러나 X11 포워딩을 사용하려면 클라이언트와 서버 양쪽에서 X11 관련 설정이 올바르게 되어 있어야 한다. 설정 오류가 있을 경우, "X11 forwarding request failed" 메시지가 로그에 나타난다.
3. **세션 복구**: SSH 연결이 끊겼다가 다시 연결될 때, 세션을 복구하는 과정이 문제가 될 수 있다. `KeepAlive` 설정이 비활성화되어 있거나 네트워크 문제로 인해 세션이 정상적으로 복구되지 않는 경우가 있다. 이 경우 로그에서 "Connection reset by peer" 메시지를 확인할 수 있다.

**Session setup** 과정에서 주요 로그 항목은 다음과 같다:

* `debug1: Allocating pty`
* `debug1: X11 forwarding request accepted`
* `debug1: Channel established`
* `debug1: Session established`

#### 디버깅 모드에서 사용하는 유용한 옵션

디버깅 모드에서 문제를 보다 효과적으로 분석하기 위해 사용할 수 있는 몇 가지 유용한 옵션이 있다.

1. **-p 옵션**: 기본 SSH 포트가 아닌 다른 포트로 연결할 때 유용한 옵션이다. 서버가 22번 포트 이외의 포트에서 SSH 요청을 수락하도록 설정된 경우, 이 옵션을 사용하여 적절한 포트로 연결해야 한다.

   ```bash
   ssh -p 2222 user@host
   ```
2. **-L 옵션**: 로컬 포트 포워딩을 설정하는 데 사용된다. 클라이언트에서 특정 포트로 들어오는 트래픽을 SSH 터널을 통해 서버로 포워딩할 수 있다. 이는 보안이 필요한 로컬 네트워크에서 외부로 연결할 때 유용하다.

   ```bash
   ssh -L 8080:localhost:80 user@host
   ```
3. **-R 옵션**: 원격 포트 포워딩을 설정하는 데 사용된다. 서버에서 특정 포트로 들어오는 트래픽을 클라이언트로 포워딩할 수 있으며, 이는 외부에서 서버로의 접속을 클라이언트 측에서 처리할 때 유용하다.

   ```bash
   ssh -R 8080:localhost:80 user@host
   ```
4. **-D 옵션**: 동적 포트 포워딩을 설정하는 데 사용된다. SOCKS 프록시 서버를 설정하여 클라이언트와 서버 간의 다양한 네트워크 트래픽을 안전하게 터널링할 수 있다.

   ```bash
   ssh -D 8080 user@host
   ```

#### 디버깅 모드의 출력 이해

디버깅 모드에서 나오는 로그는 많은 정보를 제공하지만, 문제 해결에 직접적으로 도움이 되는 핵심 로그 항목을 빠르게 파악하는 것이 중요하다. 아래는 로그에서 자주 보게 되는 항목들이다.

* `debug1: Connecting to host [ip] port [port]`: SSH 연결이 시작될 때, 클라이언트가 서버의 IP 주소와 포트에 연결하는 과정을 나타낸다.
* `debug1: key_load_public`: 공개키를 로드하는 과정에서 발생하는 문제를 나타낸다. 공개키 파일이 손상되었거나 권한 설정이 잘못되었을 때 이 항목을 확인해야 한다.
* `debug1: Authentication succeeded`: 인증이 성공했음을 나타낸다. 공개키 또는 비밀번호 인증이 성공적으로 완료되었을 때 나타나는 로그이다.
* `debug1: Authentication failed`: 인증 실패를 나타낸다. 비밀번호나 키가 올바르지 않거나, 클라이언트 또는 서버의 설정에 문제가 있을 때 발생한다.

이러한 로그 메시지는 SSH 연결에서 문제가 발생했을 때 가장 먼저 확인해야 하는 항목들이다. 각각의 로그는 문제가 발생한 지점을 정확히 파악하고 문제를 해결하는 데 유용한 단서를 제공한다.
