OpenSSH 에서 SSH 강화

HydraBeginner
지금 연습하기

소개

이 랩에서는 키 인증 및 설정 강화 (configuration hardening) 를 통해 OpenSSH 에서 SSH 보안을 향상시키는 필수 기술을 배우게 됩니다. 비밀번호 인증을 안전한 키 쌍으로 대체하고, root 로그인을 비활성화하며, 무차별 대입 공격 (brute-force attacks) 을 완화하기 위해 기본 포트를 수정하는 연습을 할 것입니다.

실습을 통해 암호화 키를 생성하고, 적절한 파일 권한을 구성하며, 안전한 SSH 설정을 테스트하는 방법을 안내합니다. 또한 SSH 서비스를 관리하고 보안 구성을 확인하기 위한 주요 명령어도 배우게 됩니다.

OpenSSH 설치

이 단계에서는 LabEx VM 에 OpenSSH 서버 패키지를 설치합니다. OpenSSH (Open Secure Shell) 는 SSH 프로토콜의 무료 오픈 소스 구현으로, 안전하지 않은 네트워크를 통해 신뢰할 수 없는 두 호스트 간에 안전하게 암호화된 통신을 제공합니다. 원격 서버 관리 및 안전한 파일 전송을 위한 표준 도구입니다.

시작하기 전에 SSH 가 클라이언트 - 서버 모델로 작동한다는 것을 이해하는 것이 중요합니다. 서버 (현재 설치 중) 는 들어오는 연결을 수신 대기하고, 클라이언트 (로컬 머신의 터미널과 같은) 는 서버에 연결합니다. 모든 통신은 암호화되어 자격 증명과 데이터를 보호합니다.

LabEx VM 은 systemctl을 사용할 수 없는 Docker 컨테이너를 사용하므로 (Docker 컨테이너는 일반적으로 전체 운영 체제 대신 단일 프로세스를 실행합니다), SSH 데몬을 관리하기 위해 service 명령을 사용합니다. 이는 컨테이너 환경에서 잘 작동하는 systemctl의 더 간단한 대안입니다.

OpenSSH 를 설치하려면 다음 단계를 따르세요.

  1. 먼저, 최신 버전을 얻기 위해 패키지 목록을 업데이트합니다. 이렇게 하면 Ubuntu 의 저장소에서 최신 패키지 정보를 가져옵니다.

    sudo apt update
    
  2. OpenSSH 서버 패키지를 설치합니다. -y 플래그는 설치 중 모든 프롬프트를 자동으로 확인합니다.

    sudo apt install -y openssh-server
    
  3. 설치 후 SSH 서비스가 실행 중인지 확인합니다. status 명령은 서비스가 활성 상태이고 연결을 수신 대기하는지 여부를 보여줍니다.

    service ssh status
    

    서비스가 활성 상태 (실행 중) 임을 나타내는 출력을 확인해야 합니다. 실행 중이 아니면 다음 단계에서 시작합니다.

  4. 서비스가 실행 중이 아닌 경우 (상태 출력에 "inactive"로 표시됨), 수동으로 시작합니다.

    service ssh start
    
  5. SSH 가 기본 포트 (22) 에서 수신 대기하는지 확인합니다. netstat 명령은 네트워크 연결 및 수신 대기 포트를 표시하고, grep은 SSH 관련 항목을 필터링합니다.

    sudo netstat -tulnp | grep sshd
    

    다음과 유사한 출력을 확인해야 합니다. SSH 가 포트 22 에서 모든 네트워크 인터페이스 (0.0.0.0) 에서 수신 대기하고 있음을 보여줍니다.

    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
    

키 인증 설정

이 단계에서는 기존의 비밀번호 인증보다 강력한 보안을 제공하는 SSH 키 기반 인증을 구성합니다. 추측하거나 무차별 대입 (brute-force) 공격을 받을 수 있는 비밀번호와 달리, 키 인증은 암호화 키 쌍을 사용합니다. 하나는 개인 키 (비밀 유지) 이고 다른 하나는 공개 키 (서버와 공유) 입니다.

SSH 서버에 연결하면 수학적 알고리즘을 사용하여 파일에 있는 공개 키와 일치하는 개인 키를 소유하고 있는지 확인합니다. 이 방법은 설정되면 더 안전하고 편리합니다.

이러한 키를 단계별로 생성하고 구성해 보겠습니다.

  1. 먼저, 새로운 SSH 키 쌍을 생성합니다. 이 명령은 ~/.ssh 디렉토리에 두 개의 파일을 생성합니다.

    ssh-keygen -t rsa -b 4096 -f ~/.ssh/labex_key -N ""
    
    • -t rsa는 키 유형 (RSA 알고리즘) 을 지정합니다.
    • -b 4096은 강력한 4096 비트 키를 만듭니다.
    • -f는 키 쌍의 파일 이름을 설정합니다.
    • -N ""는 암호 구문 (랩의 단순성을 위해) 을 사용하지 않음을 의미합니다.

    이제 다음을 갖게 됩니다.

    • 개인 키: ~/.ssh/labex_key (절대 공유하지 마세요!)
    • 공개 키: ~/.ssh/labex_key.pub (이것은 서버와 공유됩니다)
  2. 적절한 파일 권한은 SSH 보안에 매우 중요합니다. 다음 명령은 본인만 키에 액세스할 수 있도록 합니다.

    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/labex_key
    chmod 644 ~/.ssh/labex_key.pub
    
  3. 이제 SSH 가 확인하는 특수 파일인 authorized_keys 파일에 공개 키를 추가하여 키를 인증합니다.

    cat ~/.ssh/labex_key.pub >> ~/.ssh/authorized_keys
    chmod 600 ~/.ssh/authorized_keys
    
  4. 다음으로, SSH 서버 자체를 구성합니다. 주 구성 파일을 편집합니다.

    sudo nano /etc/ssh/sshd_config
    

    다음과 같은 중요한 설정을 찾아 수정합니다.

    PubkeyAuthentication yes
    PasswordAuthentication no
    

    이것은 SSH 에게 다음을 지시합니다.

    • 키 인증 허용 (기본적으로 활성화되어 있지만 확인하는 것이 좋습니다)
    • 비밀번호 로그인을 비활성화 (키 기반 액세스만 강제)
  5. 구성을 변경한 후에는 항상 SSH 서비스를 다시 시작합니다.

    service ssh restart
    
  6. 마지막으로, 모든 것이 제대로 작동하는지 확인해 보겠습니다. 새 키를 사용하여 자신의 머신 (localhost) 에 연결해 봅니다.

    ssh -i ~/.ssh/labex_key localhost
    

    -i 플래그는 사용할 개인 키를 지정합니다. 성공하면 비밀번호 프롬프트 없이 즉시 로그인됩니다. 이는 키 인증이 올바르게 작동하고 있음을 확인합니다.

Root 로그인 비활성화

이 단계에서는 SSH 를 통한 직접적인 root 로그인을 비활성화합니다. root 계정은 전체 시스템 권한을 가지고 있어 해커의 주요 표적이 되기 때문에 중요합니다. root 로그인을 비활성화하면 공격자는 사용자 이름과 비밀번호를 모두 추측해야 하므로 무차별 대입 (brute-force) 공격이 훨씬 더 어려워집니다.

이 변경 후 root 권한이 필요한 경우, 먼저 일반 사용자 계정으로 로그인한 다음 관리 작업에 sudo를 사용합니다. 이는 공격자가 두 개의 계정을 손상시켜야 하므로 추가적인 보안 계층을 생성합니다.

SSH 구성을 수정해 보겠습니다.

  1. 먼저, 텍스트 편집기로 주 SSH 구성 파일을 엽니다. 여기서는 nano 를 사용하지만, 편안하게 사용할 수 있는 편집기를 사용할 수 있습니다.

    sudo nano /etc/ssh/sshd_config
    
  2. PermitRootLogin이라는 줄을 찾습니다 (일반적으로 32 번째 줄 근처). 찾을 수 없으면 추가해야 합니다. 이 줄을 다음과 같이 변경하거나 추가합니다.

    PermitRootLogin no
    
  3. 이 파일을 편집하는 동안, 이 변경 사항과 잘 작동하는 몇 가지 추가 보안 매개변수를 설정해 보겠습니다.

    StrictModes yes
    MaxAuthTries 3
    LoginGraceTime 60
    
    • StrictModes는 보안을 위해 파일 권한을 확인합니다.
    • MaxAuthTries는 로그인 시도 실패 횟수를 제한합니다.
    • LoginGraceTime은 로그인이 걸릴 수 있는 시간을 설정합니다.
  4. nano 에서 변경 사항을 저장하려면 다음을 누릅니다.

    • Ctrl+O 를 눌러 쓰기
    • Enter 를 눌러 확인
    • Ctrl+X 를 눌러 종료
  5. 변경 사항을 적용하려면 SSH 서비스를 다시 시작합니다.

    service ssh restart
    
  6. root 로 SSH 를 시도하여 변경 사항이 작동하는지 테스트해 보겠습니다 (실패해야 합니다).

    ssh root@localhost
    

    "Permission denied (publickey)"와 같은 오류가 표시되어야 합니다. 이는 보안 조치가 올바르게 작동하고 있음을 의미합니다. 이제부터는 일반 사용자 계정을 사용하여 로그인해야 합니다.

기본 포트 변경

이 단계에서는 기본 SSH 포트를 22 에서 사용자 지정 포트 (예: 2222) 로 수정합니다. 이는 많은 자동화된 봇과 공격자가 표준 포트 22 에서 SSH 서버를 스캔하기 때문에 중요한 보안 조치입니다. 표준이 아닌 포트로 변경하면 이러한 자동화된 스캔에 서버가 덜 노출됩니다.

변경하기 전에 먼저 현재 SSH 포트 구성을 확인해 보겠습니다. 이를 통해 기존 설정을 이해할 수 있습니다.

sudo grep -i port /etc/ssh/sshd_config

일반적으로 출력에 #Port 22가 표시됩니다. # 기호는 이 줄이 주석 처리되었음을 의미하므로 SSH 는 현재 기본 포트 22 를 사용하고 있습니다.

이제 SSH 구성 파일을 편집합니다. 초보자에게 친숙한 nano 텍스트 편집기를 사용합니다.

sudo nano /etc/ssh/sshd_config

파일 내부에서 #Port 22가 포함된 줄을 찾습니다. 여기에서 두 가지 변경을 해야 합니다.

  1. #을 제거하여 줄의 주석 처리를 해제합니다 (이것은 설정을 활성화합니다).
  2. 포트 번호를 22 에서 2222 로 변경합니다.

수정된 줄은 다음과 같아야 합니다.

Port 2222

이 변경을 한 후 nano 에서 다음을 눌러 파일을 저장합니다.

  1. Ctrl+O (파일 쓰기)
  2. Enter (파일 이름 확인)
  3. Ctrl+X (편집기 종료)

변경 사항을 적용하려면 SSH 서비스를 다시 시작해야 합니다.

service ssh restart

이제 SSH 가 기본 포트 대신 새 포트 (2222) 에서 수신 대기하는지 확인해 보겠습니다.

sudo netstat -tulnp | grep ssh

출력에 SSH 가 포트 2222 에서 수신 대기하는 것으로 표시되어야 합니다. 여전히 포트 22 가 표시되면 구성 파일 변경 사항을 다시 확인하십시오.

마지막으로, 사용자 지정 포트를 사용하여 SSH 에 연결하여 새 구성을 테스트합니다. 이제 -p 플래그로 포트를 지정해야 합니다.

ssh -p 2222 -i ~/.ssh/labex_key localhost

성공적으로 연결한 후 Ctrl+D 를 눌러 SSH 세션을 종료할 수 있습니다. 이제부터 SSH 서버에 연결할 때마다 이 사용자 지정 포트를 항상 지정해야 합니다.

강화된 설정 테스트

이 마지막 단계에서는 구현한 모든 보안 강화 조치를 확인합니다. SSH 서버가 올바르게 구성되고 안전하게 설정되었는지 확인하려면 테스트가 중요합니다. 서버 측 설정과 클라이언트 측 연결 시도를 모두 검사합니다.

먼저 서버에서 현재 SSH 구성을 확인하여 시작해 보겠습니다. 이렇게 하면 이전에 수행한 변경 사항이 활성화되었는지 확인할 수 있습니다.

  1. 먼저, 현재 모든 SSH 설정을 확인합니다.

    sudo sshd -T | grep -E 'port|permitrootlogin|passwordauthentication|pubkeyauthentication'
    

    sshd -T 명령은 실제 런타임 구성을 표시합니다. 주요 보안 매개변수를 필터링하고 있습니다. 다음을 확인해야 합니다.

    port 2222
    permitrootlogin no
    passwordauthentication no
    pubkeyauthentication yes
    

    이 출력은 SSH 가 포트 2222 에서 실행 중이고, root 로그인이 비활성화되어 있으며, 비밀번호 인증이 꺼져 있고, 공개 키 인증이 활성화되어 있음을 확인합니다.

이제 클라이언트 관점에서 연결을 테스트해 보겠습니다.

  1. 키 인증으로 성공적인 연결 테스트:

    ssh -p 2222 -i ~/.ssh/labex_key localhost "echo 'Key auth successful'"
    

    이것은 개인 키를 사용하여 연결을 시도합니다 (-i 플래그는 키 파일을 지정합니다). 이 명령은 성공하면 서버에서 간단한 echo 를 실행합니다. 다음을 확인해야 합니다.

    Key auth successful
    
  2. root 로그인 시도 실패 테스트:

    ssh -p 2222 root@localhost 2>&1 | grep -i "permission denied"
    

    이것은 root 로 로그인하려고 시도하며, root 로그인을 비활성화했으므로 실패해야 합니다. 이 명령은 예상되는 오류 메시지를 필터링합니다.

  3. 비밀번호 인증 시도 실패 테스트:

    ssh -p 2222 -o PreferredAuthentications=password -o PubkeyAuthentication=no localhost 2>&1 | grep -i "permission denied"
    

    여기서는 비밀번호 인증 (구성에서 비활성화됨) 을 강제로 실행하여 제대로 차단되었는지 확인합니다. 옵션은 공개 키 인증을 명시적으로 비활성화합니다.

마지막으로, 서버의 네트워크 상태를 확인해 보겠습니다.

  1. 활성 SSH 연결 확인:

    sudo netstat -tulnp | grep 2222
    

    이것은 사용자 지정 SSH 포트 (2222) 에 대해 필터링된 모든 수신 대기 포트를 표시합니다. 이 포트에서 수신 대기하는 것으로 sshd가 나열되어야 합니다.

  2. SSH 서비스 상태 확인:

    service ssh status
    

    SSH 서비스가 제대로 실행되고 있는지 확인합니다. 출력은 서비스가 활성 상태임을 나타내야 합니다.

요약

이 Lab 에서 실용적인 구성을 통해 OpenSSH 의 SSH 보안을 강화하는 방법을 배웠습니다. 연습에서는 OpenSSH 서버 설치, 상태 확인, 적절한 권한 설정을 사용한 키 기반 인증 구현을 다루었습니다.

또한 root 로그인 비활성화 및 기본 SSH 포트 변경을 포함한 중요한 보안 강화 기술을 탐구했습니다. 이러한 조치는 시스템 기능을 유지하면서 무차별 대입 공격 및 자동화된 스캔에 대한 취약성을 효과적으로 줄입니다.