# OpenSSH 성능 최적화: 접속 제한 설정 (MaxSessions, MaxStartups)

#### MaxSessions

`MaxSessions` 설정은 하나의 SSH 연결에서 허용되는 최대 세션 수를 정의하는 옵션이다. 기본적으로 SSH는 하나의 TCP 연결에서 여러 개의 세션을 열 수 있으며, 이는 특히 포트 포워딩과 같은 기능을 사용할 때 유용하다. 그러나 너무 많은 세션을 허용하면 서버 리소스가 과도하게 사용될 수 있으므로 적절한 제한을 설정하는 것이 중요하다.

`MaxSessions`의 기본값은 10이며, 이 값을 조정하면 각 사용자가 설정된 값만큼의 세션을 동시에 열 수 있다. 만약 이 값을 1로 설정한다면, 사용자당 하나의 세션만 허용되므로 보다 엄격한 보안 정책을 유지할 수 있다.

다음은 설정 파일 `sshd_config`에서 `MaxSessions` 값을 설정하는 예시이다:

```bash
MaxSessions 5
```

위 예시는 한 명의 사용자가 SSH 연결을 통해 동시에 최대 5개의 세션을 사용할 수 있음을 의미한다.

#### MaxStartups

`MaxStartups`는 SSH 데몬이 동시에 허용할 수 있는 최대 병렬 연결 수를 제어한다. 특히 새로운 연결 요청이 많이 들어올 때, 서버가 과부하되는 것을 방지하기 위해 설정된다. `MaxStartups`는 세 가지 매개변수로 구성되며, 각 매개변수는 쉼표(,)로 구분된다:

* 첫 번째 매개변수: 제한 없이 허용할 초기 연결 수
* 두 번째 매개변수: 허용된 초기 연결 수 이후의 연결 중에서 무작위로 거부될 확률 (0에서 100 사이의 값)
* 세 번째 매개변수: 거부될 확률이 100%가 되는 최대 연결 수

예를 들어, 다음과 같은 설정을 보겠다:

```bash
MaxStartups 10:30:60
```

이 설정은 다음과 같은 의미를 갖는다:

* 10개의 초기 연결은 제한 없이 허용된다.
* 그 이후의 연결 요청 중 30%는 무작위로 거부된다.
* 동시에 60개의 연결 요청이 들어오면, 모든 추가 연결 요청은 거부된다.

따라서 서버에 대한 과부하를 줄이고 성능을 최적화하는 데 있어 중요한 역할을 한다. 이 값을 최적화하려면 서버의 네트워크 트래픽과 사용 패턴을 분석하여 적절한 설정을 선택해야 한다.

#### 접속 제한 수식

접속 제한과 관련된 수식을 고려할 때, 서버가 허용하는 최대 연결 수와 세션 수는 리소스 사용량과 직결된다. 이를 수학적으로 표현하면 다음과 같다.

먼저, 서버가 동시에 처리할 수 있는 총 연결 수를 $C$, 각 연결에서 허용되는 세션 수를 $S$라고 할 때, 서버가 처리할 수 있는 최대 세션 수 $T$는 다음과 같이 계산된다:

$$
T = C \times S
$$

여기서:

* $C$는 `MaxStartups` 설정에 의해 제한되는 최대 연결 수
* $S$는 `MaxSessions` 설정에 의해 제한되는 세션 수

만약 `MaxStartups`를 $C = 60$, `MaxSessions`를 $S = 5$로 설정한 경우, 서버가 동시에 처리할 수 있는 최대 세션 수 $T$는 다음과 같다:

$$
T = 60 \times 5 = 300
$$

즉, 서버는 최대 300개의 세션을 동시에 처리할 수 있다.

#### MaxSessions와 MaxStartups의 상호 작용

`MaxSessions`와 `MaxStartups`의 상호작용은 서버 성능 최적화와 직결된다. 서버의 총 자원(메모리, CPU, 네트워크 대역폭)은 제한되어 있기 때문에, 많은 세션과 연결을 허용할 경우 자원 고갈로 인해 성능이 저하될 수 있다. 따라서 적절한 값을 설정하여 서버의 안정성과 성능을 보장하는 것이 중요하다.

이를 이해하기 위해, SSH 서버에서 각 연결이 자원에 미치는 영향을 모델링할 수 있다. 서버에서 각 연결은 CPU와 메모리 자원을 사용하며, 세션의 수가 증가할수록 자원의 소비도 선형적으로 증가하게 된다.

**자원 사용 모델링**

서버가 처리할 수 있는 최대 자원(CPU나 메모리)을 $R\_{\text{max}}$, 각 연결이 사용하는 자원을 $r\_c$, 각 세션이 추가적으로 사용하는 자원을 $r\_s$라고 정의하겠다. 총 연결 수를 $C$, 각 연결의 세션 수를 $S$로 정의하면, 전체 자원 사용량 $R$은 다음과 같은 수식으로 표현할 수 있다:

$$
R = C \cdot r\_c + (C \cdot S) \cdot r\_s
$$

여기서:

* $C \cdot r\_c$는 연결당 자원 사용량의 총합
* $(C \cdot S) \cdot r\_s$는 세션당 자원 사용량의 총합

만약 총 자원 사용량 $R$이 서버의 최대 자원 $R\_{\text{max}}$를 초과하면 서버 성능이 저하되거나 서비스가 중단될 수 있다. 따라서 자원 사용량을 최적화하려면 $R \leq R\_{\text{max}}$ 조건을 만족하는 $C$와 $S$ 값을 설정해야 한다.

예를 들어, 각 연결이 $r\_c = 5$MB의 메모리를 사용하고, 각 세션이 $r\_s = 1$MB의 메모리를 추가적으로 사용하는 서버를 가정해 봅시다. 서버의 총 메모리 자원이 $R\_{\text{max}} = 1,000$MB일 때, `MaxStartups`와 `MaxSessions` 값을 설정할 수 있다.

1. `MaxStartups` $C = 10$
2. `MaxSessions` $S = 5$

이 설정에서, 총 자원 사용량 $R$은 다음과 같이 계산된다:

$$
R = 10 \cdot 5 , \text{MB} + (10 \cdot 5) \cdot 1 , \text{MB} = 50 , \text{MB} + 50 , \text{MB} = 100 , \text{MB}
$$

따라서 이 경우, 서버는 메모리 자원 한도 $R\_{\text{max}} = 1,000$MB 내에서 충분히 많은 연결과 세션을 처리할 수 있다.

**접속 제한 최적화**

성능 최적화를 위해서는 서버의 사용 패턴을 고려한 접속 제한 설정이 필요하다. 사용자가 SSH를 주로 어떻게 사용하는지에 따라, `MaxSessions`와 `MaxStartups` 값을 조정해야 한다.

만약 사용자가 주로 파일 전송(SCP, SFTP) 또는 포트 포워딩을 많이 사용한다면, 각 세션에서 사용하는 자원이 클 수 있으므로 `MaxSessions` 값을 더 작게 설정해야 할 수 있다. 반면, 단순한 명령어 실행만 사용하는 경우에는 `MaxSessions` 값을 조금 더 높여도 문제가 없을 수 있다.

예를 들어, 서버가 CPU와 메모리 양쪽에서 자원을 관리해야 하는 경우, 각 세션에서 발생하는 CPU 부하를 $r\_{\text{CPU}}$, 메모리 부하를 $r\_{\text{MEM}}$로 나누어 계산할 수 있다:

$$
R\_{\text{CPU}} = C \cdot r\_{\text{CPU}} + (C \cdot S) \cdot r\_{\text{CPU,sess}}
$$

$$
R\_{\text{MEM}} = C \cdot r\_{\text{MEM}} + (C \cdot S) \cdot r\_{\text{MEM,sess}}
$$

이를 통해 자원 사용량을 균형 있게 조정하면서 서버 성능을 극대화할 수 있다.

#### MaxStartups의 확률적 거부 모델

`MaxStartups` 설정에서 두 번째 매개변수는 새로 들어오는 연결을 무작위로 거부할 확률을 설정한다. 이는 서버가 너무 많은 연결 요청을 동시에 처리하지 못하게 하여 리소스 고갈을 방지하는 데 유용하다. 거부 확률을 수학적으로 모델링하여 어떻게 작동하는지 설명하겠다.

**확률적 거부**

`MaxStartups` 설정의 두 번째 매개변수는 $p$로 정의되며, $0 \leq p \leq 100$ 범위의 값을 갖는다. 이때 $p %$ 확률로 새로운 연결을 거부하게 된다. 예를 들어, `MaxStartups` 설정이 `10:30:60`으로 되어 있다면, 10개의 연결은 확실히 허용되며, 이후에 들어오는 연결은 $30%$ 확률로 거부된다.

이를 수학적으로 설명하면, 서버가 추가적인 연결 요청을 받았을 때 각 연결이 성공할 확률 $P\_{\text{success}}$는 다음과 같이 표현된다:

$$
P\_{\text{success}} = 1 - \frac{p}{100}
$$

이 확률은 $p = 30$일 때 $P\_{\text{success}} = 1 - \frac{30}{100} = 0.7$, 즉 $70%$의 확률로 연결이 허용된다는 의미이다.

**확률적 거부의 누적 효과**

서버가 $n$개의 추가적인 연결 요청을 받을 때, 모든 요청이 성공할 확률은 각각의 요청이 성공할 확률을 곱한 값으로 표현된다. 이를 확률론적으로 모델링하면, $n$개의 연결 요청이 모두 성공할 확률 $P\_{\text{all\_success}}$는 다음과 같이 표현된다:

$$
P\_{\text{all\_success}} = \left( 1 - \frac{p}{100} \right)^n
$$

만약 $p = 30$이고, 3개의 연결 요청이 들어온다면, 모든 연결이 성공할 확률은 다음과 같이 계산된다:

$$
P\_{\text{all\_success}} = \left( 1 - \frac{30}{100} \right)^3 = 0.7^3 = 0.343
$$

즉, 3개의 연결이 모두 성공할 확률은 약 $34.3%$이다. 이는 새로운 연결이 많이 들어올수록 각 연결이 성공할 확률이 급격히 감소함을 보여준다.

#### MaxStartups의 최대 제한

`MaxStartups`의 세 번째 매개변수는 $C\_{\text{max}}$로 표현되며, 서버가 허용할 수 있는 최대 연결 수를 나타낸다. 이 값에 도달하면 새로운 연결 요청은 무조건 거부된다. 예를 들어, `MaxStartups 10:30:60` 설정에서 $C\_{\text{max}} = 60$일 경우, 60개의 연결 요청이 들어오면 그 이후의 모든 요청은 확률에 관계없이 거부된다.

이를 수학적으로 표현하면, 서버가 $C\_{\text{max}}$에 도달한 후 추가적인 연결 요청이 성공할 확률 $P\_{\text{success}}$는 다음과 같이 0으로 정의된다:

$$
P\_{\text{success}} = 0 \quad \text{if} \quad C \geq C\_{\text{max}}
$$

이 설정은 서버의 과도한 연결을 방지하고 자원 소모를 줄이기 위한 마지막 방어선으로 작용한다.

**예제**

다음은 `MaxStartups` 설정이 적용된 실제 예제이다. 서버의 `sshd_config` 파일에서 다음과 같이 설정되어 있다고 가정한다:

```bash
MaxStartups 10:50:100
```

* 처음 10개의 연결은 제한 없이 허용된다.
* 10개를 초과하는 연결은 50% 확률로 거부된다.
* 연결 수가 100개를 초과하면 모든 추가 연결이 거부된다.

이 설정을 통해 서버는 최대 100개의 연결까지만 처리할 수 있으며, 10개 이상의 연결에서는 절반 정도의 요청만 허용된다. 이를 통해 서버의 안정성을 유지하면서도 너무 많은 연결 요청이 들어왔을 때 자원을 절약할 수 있다.
