소개
이 실습에서는 원격 Linux 시스템 관리에 필수적인 기술인 SSH(Secure Shell) 연결 구성 및 보안 설정 방법을 직접 실습합니다. 먼저 SSH를 사용하여 원격 시스템에 접속하는 방법을 배우고, 클라이언트-서버 아키텍처와 기본적인 연결 명령어를 이해합니다. 여기에는 SSH 클라이언트 설치 확인, 원격 호스트 연결, 호스트 인증 프롬프트 처리, 원격 시스템 로그인 및 로그아웃 과정이 포함됩니다.
이 기초를 바탕으로 비밀번호 없는 인증을 위한 SSH 키 쌍 생성 및 활용, ssh-agent를 이용한 효율적인 키 관리, 일반적인 SSH 연결 문제 해결과 같은 고급 주제를 다룹니다. 마지막으로, 효율성을 높이기 위해 SSH 클라이언트 구성을 사용자 지정하고, 루트 로그인 및 비밀번호 인증을 비활성화하여 OpenSSH 서버의 보안을 강화함으로써 강력하고 안전한 원격 액세스를 보장하는 방법을 배웁니다.
SSH를 통한 원격 시스템 접속
이 단계에서는 SSH(Secure Shell)를 사용하여 원격 시스템에 접속하는 방법을 배웁니다. SSH는 보안되지 않은 네트워크에서 네트워크 서비스를 안전하게 운영하기 위한 암호화 네트워크 프로토콜입니다. SSH 클라이언트와 SSH 서버를 연결하는 클라이언트-서버 아키텍처를 사용하여 보안되지 않은 네트워크를 통해 안전한 채널을 제공합니다.
참고: 이 실습 환경에서는 보안상의 이유로 루트 로그인 제한과 같은 일부 보안 기능이 이미 구성되어 있을 수 있습니다. 이는 일반적인 상황이며 모범 사례를 보여줍니다.
원격 시스템에 연결하기 전에 OpenSSH 클라이언트 및 서버 패키지를 설치하고 SSH 서비스를 시작하여 실습 환경을 준비합니다. SSH는 클라이언트-서버 아키텍처를 사용합니다. 클라이언트(ssh)가 연결을 시작하고 서버(sshd)가 이를 수락합니다. 또한 나중에 SSH 구성 파일을 편집하는 데 사용할 nano도 설치합니다.
다음 명령을 실행하여 필요한 패키지를 설치합니다. -y 플래그는 패키지 설치 프롬프트를 자동으로 확인합니다.
sudo dnf install -y openssh-clients openssh-server nano
SSH 서비스를 시작하고 부팅 시 자동으로 시작되도록 구성합니다.
sudo systemctl start sshd
sudo systemctl enable sshd
SSH 서비스가 실행 중인지 확인합니다.
sudo systemctl status sshd
출력에서 Active: active (running)을 확인할 수 있어야 합니다. q를 눌러 상태 보기에서 나옵니다.
먼저 SSH를 사용하여 로컬 시스템에 연결합니다. 이는 동일한 머신에 연결할 때도 SSH 클라이언트-서버 아키텍처가 작동함을 보여줍니다. ssh 명령을 사용하여 localhost에 연결합니다.
ssh의 기본 구문은 다음과 같습니다.
ssh [username]@[hostname_or_IP]
사용자 이름을 지정하지 않으면 SSH는 현재 로컬 사용자 이름으로 로그인을 시도합니다. 이 경우 로컬 사용자 이름은 labex입니다.
현재 사용자 이름을 사용하여 localhost에 연결해 보겠습니다.
ssh localhost
처음 연결할 때 SSH는 호스트의 신뢰성을 확인하라는 메시지를 표시합니다. 이는 중간자 공격(man-in-the-middle attack)을 방지하기 위한 보안 조치입니다. yes를 입력하고 Enter를 누릅니다.
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ED25519 key fingerprint is SHA256:h5k1mmPFylpxUCsKx+Mf8rN4wOrk9TmyRfzTvGWRm7A.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ED25519) to the list of known hosts.
labex@localhost's password:
labex 사용자의 비밀번호를 묻는 메시지가 나타납니다. labex를 입력하고 Enter를 누릅니다.
labex@localhost's password:
Last login: Mon Jun 9 01:34:39 2025 from 47.251.66.143
[labex@host ~]$
이제 SSH를 통해 localhost에 로그인되었습니다. 프롬프트가 [labex@localhost ~]$로 표시되어 SSH를 통해 연결되었음을 나타냅니다.
SSH 세션에서 로그아웃하려면 exit 명령을 사용합니다.
exit
logout
Connection to localhost closed.
[labex@host ~]$
이제 root 사용자로 localhost에 연결해 보겠습니다. 이 환경에서는 보안상의 이유로 루트 로그인이 기본적으로 비활성화되어 있을 수 있습니다.
ssh root@localhost
루트 비밀번호를 묻는 메시지가 나타납니다. 하지만 루트 로그인이 비활성화된 경우 "Permission denied" 메시지가 표시될 수 있습니다.
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
루트 로그인이 비활성화된 경우 이는 예상된 동작이며 보안 모범 사례를 보여줍니다. Ctrl+C를 눌러 연결 시도를 취소할 수 있습니다.
SSH는 대화형 셸을 열지 않고 원격 시스템에서 단일 명령을 실행하는 데 사용할 수도 있습니다. 이는 빠른 확인이나 자동화에 유용합니다.
labex 사용자로 localhost에서 hostname 명령을 실행해 보겠습니다.
ssh labex@localhost hostname
labex 사용자의 비밀번호를 묻는 메시지가 나타납니다. labex를 입력하고 Enter를 누릅니다.
labex@localhost's password:
6846375f1c0e35fea6cb03e6
[labex@host ~]$
hostname 명령이 SSH를 통해 실행되었고 그 결과가 로컬 터미널에 표시되었습니다. 대화형 셸로 진입하지 않았습니다.
마지막으로 SSH가 알려진 호스트(known hosts)를 관리하는 방법을 살펴보겠습니다. 새로운 SSH 서버에 연결하면 해당 서버의 공개 키 지문이 ~/.ssh/known_hosts 파일에 추가됩니다. 이 파일은 SSH 클라이언트가 향후 연결에서 서버의 신원을 확인하는 데 도움을 줍니다.
~/.ssh/known_hosts 파일의 내용을 볼 수 있습니다.
cat ~/.ssh/known_hosts
localhost ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHvl7dcZkvMNOr3cjKjlR2/JgFbGpURThT/bHnLZN6gG
localhost ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCynhy3601o9ZSGZoY0KB/QSonk5ykod2Tb7sCAqVn4ZgTCwd96BhPjJLPNQ6ldNASo1e7EzfT4BUjG5T0ZDRhgaI65qmDwITWipTWUfmYT5XoScyf6NDhcRxYiJwztFEkOvLcPhelS6UXj5Z7HdmYH4Nc5wiF00Wah3Jc0/2CfQsFZCXTn/7Kp8KKbBbPqPzr2R3WIULEacOxx9HKVv+2TvYg/OHZz40hTsr1c68DD7h5PMBNe21YB3HLRRk2LQEC7v7BFD+DCek9GNR66JBjbLDljtwWCaPCY0UntBjjvJ3W2LhX5RDZQHV/iaUSj2tEXnvPt9KSqGfBS91D12dBXyOmWVnTpvvI17BdDkEeefas2Uz4d7Bv/PDxZR6IKkaIGQ/ZnRhSEhBNvfqlBGqkOhRr6jQJK+rQMnsZCT6OEgW7osWzkw5Bs1wY/RNToeQqrRMclqffO9plFI688N2iT86+nxrvBVZg4yMMm2J1lleaBvinXCB8jE6lrtwoAdgk=
localhost ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKYWY8Ty6TrbQS/0fUljBWuUpkyPCS/5P6ZwxhSYsqjRBIprMANI/JQotZqHYq2w3b2X/n8O+J3/WuIB6XMl1f4=
이 항목들은 클라이언트가 localhost에 대해 여러 공개 키(ED25519, RSA, ECDSA)를 기록했음을 확인해 줍니다. SSH 서버는 호환성을 위해 여러 키 유형을 지원할 수 있습니다. 이러한 서버 키 중 하나라도 예기치 않게 변경되면 SSH가 경고를 보내는데, 이는 중요한 보안 기능입니다.
비밀번호 없는 인증을 위한 SSH 키 쌍 생성 및 사용
이 단계에서는 SSH 키 쌍을 생성하고 이를 비밀번호 없는 인증에 사용하는 방법을 배웁니다. SSH 키 기반 인증은 비밀번호 인증보다 더 안전하고 편리한 대안입니다. 연결할 때마다 비밀번호를 입력하는 대신 암호화 키 쌍을 사용합니다. 개인 키(로컬 머신에 비밀로 보관)와 공개 키(원격 서버에 배치)가 필요합니다.
먼저 SSH 키 쌍을 생성해야 합니다. 이를 위해 ssh-keygen 명령을 사용합니다. 기본적으로 ssh-keygen은 RSA 키 쌍을 생성하고 개인 키를 ~/.ssh/id_rsa에, 공개 키를 ~/.ssh/id_rsa.pub에 저장합니다.
ssh-keygen 명령을 실행합니다.
ssh-keygen
몇 가지 옵션을 묻는 메시지가 나타납니다.
Generating public/private rsa key pair.
Enter file in which to save the key (/home/labex/.ssh/id_rsa):
Enter를 눌러 기본 파일 경로(/home/labex/.ssh/id_rsa)를 수락합니다.
Enter passphrase (empty for no passphrase):
이 실습에서는 Enter를 두 번 눌러 암호(passphrase)를 비워둡니다. 실제 환경에서는 보안 계층을 추가하기 위해 암호를 사용하는 것이 권장되지만, 여기서는 단순함을 위해 생략하고 비밀번호 없는 인증을 직접 시연합니다.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/labex/.ssh/id_rsa
Your public key has been saved in /home/labex/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:QoV7pNBFu1kafGP3VJhpZuIdr1zc+qamJ1C2YAadgNY labex@6846375f1c0e35fea6cb03e6
The key's randomart image is:
+---[RSA 3072]----+
| . *=o . +.|
| . =oE.o . O. |
| o.++.=..*.+.|
| .o .O+o+o. =|
| ..So + o.+ |
| . . . + |
| . . |
| . o o|
| .=.o |
+----[SHA256]-----+
이제 ~/.ssh/ 디렉토리에 키 파일이 생성되었는지 확인합니다.
ls -l ~/.ssh/
total 16
-rw------- 1 labex labex 2622 Jun 9 01:37 id_rsa
-rw-r--r-- 1 labex labex 584 Jun 9 01:37 id_rsa.pub
-rw------- 1 labex labex 825 Jun 9 01:35 known_hosts
-rw-r--r-- 1 labex labex 91 Jun 9 01:35 known_hosts.old
id_rsa(개인 키)와 id_rsa.pub(공개 키)가 보여야 합니다. 권한을 확인하세요. id_rsa는 rw-------(소유자만 읽기/쓰기 가능) 권한을 가지며, 이는 보안상 매우 중요합니다. 이전 known_hosts 파일의 백업인 known_hosts.old도 보일 수 있습니다.
다음으로, 비밀번호 없는 인증을 활성화하려면 공개 키를 복사해야 합니다. ssh-copy-id 명령이 이 목적을 위해 설계되었습니다. 이 명령은 공개 키를 ~/.ssh/authorized_keys 파일에 추가하여 비밀번호 없이 로그인할 수 있게 합니다.
사용자와 호스트 이름을 지정하여 ssh-copy-id 명령을 실행합니다.
ssh-copy-id labex@localhost
labex 사용자의 비밀번호를 묻는 메시지가 나타납니다. labex를 입력하고 Enter를 누릅니다.
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/labex/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
labex@localhost's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'labex@localhost'"
and check to make sure that only the key(s) you wanted were added.
명령 출력은 키 하나가 추가되었음을 확인해 줍니다. 이제 비밀번호를 입력하지 않고 labex로 localhost에 로그인을 시도해 봅니다.
ssh labex@localhost
모든 것이 올바르게 구성되었다면 비밀번호를 묻는 메시지 없이 SSH를 통해 로그인되어야 합니다.
Last login: Mon Jun 9 01:37:39 2025 from 47.251.66.143
[labex@host ~]$
키 쌍을 사용하여 비밀번호 없는 SSH 인증을 성공적으로 구성했습니다!
원격 세션을 종료하려면 exit를 입력합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
ssh-agent를 사용한 SSH 키 관리
이 단계에서는 ssh-agent를 사용하여 SSH 키를 관리하는 방법을 배웁니다. ssh-agent는 백그라운드에서 실행되며 메모리에 개인 키를 보관하는 프로그램입니다. 이는 개인 키가 암호(passphrase)로 보호될 때 특히 유용합니다. 키를 사용할 때마다 암호를 입력하는 대신, ssh-agent에 키를 추가할 때 한 번만 입력하면 세션이 유지되는 동안 에이전트가 인증을 처리합니다.
이전 단계에서 암호 없이 키를 생성했지만, 이제 ssh-agent의 유용성을 시연하기 위해 암호가 있는 새 키를 생성하겠습니다.
먼저 암호가 있는 새 SSH 키 쌍을 생성합니다. 기본 id_rsa 키와 구분하기 위해 이 키의 이름을 id_rsa_passphrase로 지정합니다.
ssh-keygen -f ~/.ssh/id_rsa_passphrase
암호를 입력하라는 메시지가 나타납니다. 이 실습에서는 mypassphrase를 암호로 사용합니다.
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): mypassphrase
Enter same passphrase again: mypassphrase
Your identification has been saved in /home/labex/.ssh/id_rsa_passphrase
Your public key has been saved in /home/labex/.ssh/id_rsa_passphrase.pub
The key fingerprint is:
SHA256:BuSxVlJb1lsiUFi2I5DAvyL01fJ5d480LT86dgtcHEg labex@6846375f1c0e35fea6cb03e6
The key's randomart image is:
+---[RSA 3072]----+
| ...=o+=*. E |
| .o.*.=..+ o |
| .=.o o. = . |
| . .+... .. . .|
| . . . +S. + |
| . o ..o . o * .|
| . . . . = * |
| oooo|
| ..+.o|
+----[SHA256]-----+
참고: 실수로 암호를 입력하지 않고 Enter를 누르면 암호 없이 키가 생성됩니다. 이 경우 파일을 삭제하고 명령을 다시 실행하여 메시지가 나타날 때 mypassphrase를 입력하십시오.
이제 이 새 공개 키를 localhost에 복사하여 인증에 사용할 수 있도록 합니다.
ssh-copy-id -i ~/.ssh/id_rsa_passphrase.pub labex@localhost
이미 기본 키로 비밀번호 없는 인증이 설정되어 있으므로, 명령이 비밀번호를 묻지 않고 기존 인증을 사용할 수 있습니다.
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/labex/.ssh/id_rsa_passphrase.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'labex@localhost'"
and check to make sure that only the key(s) you wanted were added.
이제 이 새 키를 사용하여 localhost에 연결해 봅니다. -i 옵션을 사용하여 개인 키 파일을 지정해야 합니다.
ssh -i ~/.ssh/id_rsa_passphrase labex@localhost
키에 암호를 설정했다면 암호를 묻는 메시지가 나타납니다. 하지만 실수로 암호 없이 키를 생성했다면(예제 출력과 같이) 바로 로그인됩니다.
Last login: Mon Jun 9 01:39:25 2025 from 47.251.66.143
[labex@host ~]$
로그인되었습니다. 이제 세션을 종료합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
참고: 키에 암호가 없더라도 ssh-agent가 암호를 묻지는 않지만, 작동 방식을 이해하기 위해 ssh-agent 시연을 계속할 수 있습니다.
먼저 현재 셸 세션에서 ssh-agent를 시작합니다. eval 명령은 ssh-agent가 출력하는 환경 변수를 올바르게 설정하는 데 사용됩니다.
eval "$(ssh-agent)"
Agent pid 1024
출력에는 ssh-agent의 프로세스 ID(PID)가 표시됩니다.
다음으로 개인 키(id_rsa_passphrase)를 ssh-agent에 추가합니다.
ssh-add ~/.ssh/id_rsa_passphrase
키에 암호가 있다면 암호를 묻는 메시지가 나타납니다. 없다면 키가 바로 추가됩니다.
Identity added: /home/labex/.ssh/id_rsa_passphrase (labex@6846375f1c0e35fea6cb03e6)
이제 키가 ssh-agent에 추가되었으므로 같은 키를 사용하여 localhost에 다시 연결해 봅니다.
ssh -i ~/.ssh/id_rsa_passphrase labex@localhost
이제 에이전트가 관리하므로 암호를 묻는 메시지 없이 연결할 수 있어야 합니다(키에 암호가 있든 없든 상관없습니다).
Last login: Mon Jun 9 01:39:49 2025 from 127.0.0.1
[labex@host ~]$
ssh-agent를 사용하여 SSH 키를 성공적으로 관리했습니다.
중요 참고: ssh-agent 환경 변수는 이를 시작한 셸 세션에서만 사용할 수 있습니다. SSH 세션 내에 있다면 ssh-add 명령을 사용하기 위해 로컬 셸로 다시 나가야 합니다.
먼저 SSH 세션을 종료합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
이제 ssh-agent에 현재 로드된 키를 보려면 ssh-add -l을 사용합니다.
ssh-add -l
에이전트가 실행 중이고 키가 로드되어 있다면 다음과 같은 출력이 보입니다.
3072 SHA256:BuSxVlJb1lsiUFi2I5DAvyL01fJ5d480LT86dgtcHEg /home/labex/.ssh/id_rsa_passphrase (RSA)
하지만 "Could not open a connection to your authentication agent"와 같은 오류 메시지가 보인다면, 현재 세션에 에이전트 환경 변수가 설정되지 않았음을 의미합니다.
ssh-agent에서 모든 ID를 제거하려면 ssh-add -D를 사용합니다.
ssh-add -D
에이전트에 액세스할 수 있다면 다음이 표시됩니다.
All identities removed.
하지만 "Could not open a connection to your authentication agent"가 보인다면 현재 세션에서 에이전트 환경을 사용할 수 없음을 의미합니다.
이제 다시 연결을 시도할 때 키에 암호가 있다면, 키가 에이전트에서 제거되었으므로 암호를 묻는 메시지가 나타납니다.
ssh -i ~/.ssh/id_rsa_passphrase labex@localhost
키에 암호가 있다면 다음이 표시됩니다.
Enter passphrase for key '/home/labex/.ssh/id_rsa_passphrase':
키에 암호가 없더라도 직접 연결할 수 있습니다. 암호를 묻는 메시지가 나타나면 Ctrl+C를 눌러 연결 시도를 취소하십시오.
마지막으로 ssh-agent 프로세스를 중지하려면 ssh-agent -k를 사용할 수 있습니다.
ssh-agent -k
SSH_AGENT_PID 환경 변수가 설정되지 않았다면 다음이 표시될 수 있습니다.
SSH_AGENT_PID not set, cannot kill agent
이는 에이전트가 다른 셸 세션에서 시작되었거나 환경 변수가 제대로 내보내지지 않은 경우 정상적인 현상입니다.
SSH 연결 문제 해결
이 단계에서는 일반적인 SSH 연결 문제를 해결하는 방법을 배웁니다. SSH 연결이 실패하면 정확한 문제를 파악하기 어려울 수 있습니다. ssh 명령은 연결 과정에 대한 자세한 정보를 보여줌으로써 문제를 진단하는 데 도움이 되는 상세 출력(verbose output) 옵션을 제공합니다.
ssh 명령은 -v, -vv, -vvv의 세 가지 상세 수준을 제공합니다. v가 추가될 때마다 표시되는 디버깅 정보의 양이 늘어납니다.
연결 실패를 시연하고 디버깅 출력을 확인하기 위해 localhost의 존재하지 않는 포트에 연결을 시도하는 것부터 시작하겠습니다.
먼저 -v(verbose)를 사용하여 포트 2222(실행 중이지 않아야 함)에 연결해 봅니다.
ssh -v -p 2222 labex@localhost
연결이 거부되었음을 나타내는 다음과 유사한 출력이 표시됩니다.
OpenSSH_8.7p1, OpenSSL 3.0.1 14 Dec 2021
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Reading configuration data /etc/ssh/ssh_config.d/01-training.conf
debug1: /etc/ssh/ssh_config.d/01-training.conf line 1: Applying options for *
debug1: Reading configuration data /etc/ssh/ssh_config.d/50-redhat.conf
debug1: /etc/ssh/ssh_config.d/50-redhat.conf line 3: Applying options for *
debug1: Connecting to localhost [127.0.0.1] port 2222.
ssh: connect to host localhost port 2222: Connection refused
이제 -vv(더 상세함)를 사용하여 시도해 봅니다.
ssh -vv -p 2222 labex@localhost
출력이 더 자세해지며 추가 디버깅 메시지가 제공됩니다.
OpenSSH_8.7p1, OpenSSL 3.0.1 14 Dec 2021
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Reading configuration data /etc/ssh/ssh_config.d/01-training.conf
debug1: /etc/ssh/ssh_config.d/01-training.conf line 1: Applying options for *
debug1: Reading configuration data /etc/ssh/ssh_config.d/50-redhat.conf
debug1: /etc/ssh/ssh_config.d/50-redhat.conf line 3: Applying options for *
debug2: resolving "localhost" port 2222
debug2: ssh_connect_direct: entering
debug1: Connecting to localhost [127.0.0.1] port 2222.
debug1: connect to address 127.0.0.1 port 2222: Connection refused
ssh: connect to host localhost port 2222: Connection refused
마지막으로 -vvv(가장 상세함)를 사용하여 시도해 봅니다.
ssh -vvv -p 2222 labex@localhost
이 수준은 최대 디버깅 정보를 제공하며, 복잡한 문제에 매우 유용합니다.
OpenSSH_8.7p1, OpenSSL 3.0.1 14 Dec 2021
debug3: ssh_connect_internal: entering
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Reading configuration data /etc/ssh/ssh_config.d/01-training.conf
debug1: /etc/ssh/ssh_config.d/01-training.conf line 1: Applying options for *
debug1: Reading configuration data /etc/ssh/ssh_config.d/50-redhat.conf
debug1: /etc/ssh/ssh_config.d/50-redhat.conf line 3: Applying options for *
debug2: resolving "localhost" port 2222
debug2: ssh_connect_direct: entering
debug1: Connecting to localhost [127.0.0.1] port 2222.
debug1: connect to address 127.0.0.1 port 2222: Connection refused
ssh: connect to host localhost port 2222: Connection refused
이 경우 Connection refused 오류는 포트 2222에서 실행 중인 SSH 서버가 없음을 명확하게 나타냅니다.
이제 일반적인 문제인 '변경된 호스트 키'를 시뮬레이션해 보겠습니다. 첫 번째 단계에서 localhost에 연결했고, 해당 공개 키가 ~/.ssh/known_hosts 파일에 추가되었습니다. SSH 서버 키가 변경되면(예: 서버 재구축 또는 악의적인 공격으로 인해) SSH 클라이언트는 이 불일치를 감지하고 연결을 거부합니다.
이를 시뮬레이션하기 위해 localhost에 대한 known_hosts 항목을 의도적으로 수정하여 유효하지 않게 만들겠습니다.
먼저 nano를 사용하여 ~/.ssh/known_hosts 파일을 엽니다.
nano ~/.ssh/known_hosts
다른 키 유형을 가진 여러 줄이 보입니다.
localhost ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHvl7dcZkvMNOr3cjKjlR2/JgFbGpURThT/bHnLZN6gG
localhost ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCynhy3601o9ZSGZoY0KB/QSonk5ykod2Tb7sCAqVn4ZgTCwd96BhPjJLPNQ6ldNASo1e7EzfT4BUjG5T0ZDRhgaI65qmDwITWipTWUfmYT5XoScyf6NDhcRxYiJwztFEkOvLcPhelS6UXj5Z7HdmYH4Nc5wiF00Wah3Jc0/2CfQsFZCXTn/7Kp8KKbBbPqPzr2R3WIULEacOxx9HKVv+2TvYg/OHZz40hTsr1c68DD7h5PMBNe21YB3HLRRk2LQEC7v7BFD+DCek9GNR66JBjbLDljtwWCaPCY0UntBjjvJ3W2LhX5RDZQHV/iaUSj2tEXnvPt9KSqGfBS91D12dBXyOmWVnTpvvI17BdDkEeefas2Uz4d7Bv/PDxZR6IKkaIGQ/ZnRhSEhBNvfqlBGqkOhRr6jQJK+rQMnsZCT6OEgW7osWzkw5Bs1wY/RNToeQqrRMclqffO9plFI688N2iT86+nxrvBVZg4yMMm2J1lleaBvinXCB8jE6lrtwoAdgk=
localhost ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKYWY8Ty6TrbQS/0fUljBWuUpkyPCS/5P6ZwxhSYsqjRBIprMANI/JQotZqHYq2w3b2X/n8O+J3/WuIB6XMl1f4=
수정할 줄을 하나 선택합니다. 이 예제에서는 ED25519 키(첫 번째 줄)를 수정해 보겠습니다. 긴 키 문자열에서 몇 개의 문자를 수정합니다(예: 마지막 문자를 G에서 A로 변경). 전체 줄이나 파일의 다른 부분을 삭제하지 않도록 주의하십시오.
예를 들어:
...ZN6gG를
...ZN6gA로 변경합니다.
Ctrl+X를 누른 다음 Y를 눌러 저장 확인, Enter를 눌러 파일 이름 확인을 통해 파일을 저장합니다.
이제 localhost에 다시 연결해 봅니다.
ssh labex@localhost
변경된 호스트 키에 대한 경고가 표시됩니다.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:h5k1mmPFylpxUCsKx+Mf8rN4wOrk9TmyRfzTvGWRm7A.
Please contact your system administrator.
Add correct host key in /home/labex/.ssh/known_hosts to get rid of this message.
Offending key in /home/labex/.ssh/known_hosts:1
ED25519 host key for localhost has changed and you have requested strict checking.
Host key verification failed.
이는 심각한 보안 경고입니다. 실제 환경에서 이 메시지가 나타나면 호스트 키가 변경된 이유를 조사해야 합니다. 정당한 변경(예: 서버 재설치)이라면 known_hosts에서 이전 항목을 제거해야 합니다.
이를 해결하려면 ~/.ssh/known_hosts를 수동으로 편집하여 문제가 되는 줄을 제거하거나, ssh-keygen -R을 사용하여 localhost 항목을 제거할 수 있습니다.
ssh-keygen -R을 사용하여 잘못된 항목을 제거해 보겠습니다.
ssh-keygen -R localhost
## Host localhost found: line 1
## Host localhost found: line 2
## Host localhost found: line 3
/home/labex/.ssh/known_hosts updated.
Original contents retained as /home/labex/.ssh/known_hosts.old
이제 localhost에 다시 연결해 봅니다. 처음 연결했을 때와 마찬가지로 호스트의 신뢰성을 확인하라는 메시지가 나타납니다.
ssh labex@localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ED25519 key fingerprint is SHA256:h5k1mmPFylpxUCsKx+Mf8rN4wOrk9TmyRfzTvGWRm7A.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ED25519) to the list of known hosts.
Last login: Mon Jun 9 01:40:03 2025 from 127.0.0.1
[labex@host ~]$
이제 키 기반 인증을 사용하여 다시 성공적으로 연결되었습니다.
세션을 종료합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
SSH 클라이언트 구성 사용자 지정
이 단계에서는 ~/.ssh/config 파일을 사용하여 SSH 클라이언트 구성을 사용자 지정하는 방법을 배웁니다. 이 파일을 사용하면 다양한 원격 호스트에 대한 별칭(alias)과 특정 연결 매개변수를 정의하여 SSH 명령을 단순화하고 일관성을 높일 수 있습니다.
~/.ssh/config 파일은 SSH 연결을 관리하는 강력한 도구입니다. 사용자 이름, 사용할 개인 키 파일, 포트 번호, 프록시 명령과 같은 고급 설정 등 다양한 옵션을 지정할 수 있습니다.
먼저 ~/.ssh/config 파일을 생성하거나 엽니다. 파일이 없으면 nano가 생성합니다.
nano ~/.ssh/config
파일에 다음 구성을 추가합니다. 이 구성은 labex 사용자로 localhost에 연결하기 위한 별칭 localhost_labex와 root 사용자로 연결하기 위한 별칭 localhost_root를 정의합니다. 또한 labex 사용자가 이전 단계에서 생성한 id_rsa 키를 사용하도록 IdentityFile을 명시적으로 지정합니다.
Host localhost_labex
HostName localhost
User labex
IdentityFile ~/.ssh/id_rsa
Host localhost_root
HostName localhost
User root
Ctrl+X를 누른 다음 Y를 눌러 저장 확인, Enter를 눌러 파일 이름 확인을 통해 파일을 저장합니다.
이제 이 새 별칭을 사용하여 localhost에 연결해 봅니다.
localhost_labex 별칭을 사용하여 labex로 연결합니다.
ssh localhost_labex
IdentityFile ~/.ssh/id_rsa를 구성했고 id_rsa에 암호가 없으므로 비밀번호를 묻는 메시지 없이 로그인되어야 합니다.
Last login: Mon Jun 9 01:54:16 2025 from 47.251.66.143
[labex@host ~]$
세션을 종료합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
이제 localhost_root 별칭을 사용하여 root로 연결합니다.
ssh localhost_root
root 사용자의 비밀번호를 묻는 메시지가 나타납니다. 하지만 이 환경에서는 루트 로그인이 비활성화되어 있으므로 "Permission denied" 메시지가 표시됩니다.
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Ctrl+C를 눌러 연결 시도를 취소합니다.
^C
이는 SSH 구성 별칭은 작동하지만 루트 로그인을 비활성화하는 보안 정책으로 인해 연결이 실패함을 보여줍니다.
보시다시피 ~/.ssh/config 파일을 사용하면 일반적인 연결 매개변수를 미리 구성하여 SSH 명령을 단순화할 수 있습니다.
다른 포트를 지정하는 방법을 보여주기 위해 항목을 하나 더 추가해 보겠습니다. localhost는 기본 SSH 포트(22)를 사용하지만, 이 예제는 포트가 다를 경우 어떻게 구성하는지 보여줍니다.
~/.ssh/config 파일을 다시 엽니다.
nano ~/.ssh/config
다음 항목을 추가합니다. 이는 포트를 2222로 명시적으로 설정하는 별칭 localhost_port_example을 생성합니다. (참고: localhost는 실제로 포트 2222에서 수신 대기하지 않으므로 이 연결은 실패하지만 구성을 시연합니다.)
Host localhost_labex
HostName localhost
User labex
IdentityFile ~/.ssh/id_rsa
Host localhost_root
HostName localhost
User root
Host localhost_port_example
HostName localhost
Port 2222
User labex
파일을 저장합니다.
이제 localhost_port_example 별칭을 사용하여 연결해 봅니다.
ssh localhost_port_example
localhost가 포트 2222에서 수신 대기하지 않으므로 이 연결은 실패하지만, SSH 구성에서 사용자 지정 포트를 지정하는 방법을 보여줍니다.
ssh: connect to host localhost port 2222: Cannot assign requested address
You can find some explanations for typical errors at this link:
https://red.ht/support_rhel_ssh
현재 SSH 구성을 확인하여 정의된 모든 호스트를 볼 수 있습니다.
cat ~/.ssh/config
Host localhost_labex
HostName localhost
User labex
IdentityFile ~/.ssh/id_rsa
Host localhost_root
HostName localhost
User root
Host localhost_port_example
HostName localhost
Port 2222
User labex
마지막으로 localhost_port_example 항목을 제거하여 ~/.ssh/config 파일을 정리하겠습니다.
~/.ssh/config 파일을 엽니다.
nano ~/.ssh/config
Host localhost_port_example 블록을 삭제합니다. 파일은 다음과 같아야 합니다.
Host localhost_labex
HostName localhost
User labex
IdentityFile ~/.ssh/id_rsa
Host localhost_root
HostName localhost
User root
파일을 저장합니다.
OpenSSH 서버 보안 구성 이해
이 단계에서는 현재 보안 구성을 검토하여 OpenSSH 서버 보안 모범 사례에 대해 배웁니다. 루트 로그인 제한 및 비밀번호 인증 설정이 어떻게 작동하여 무단 액세스로부터 서버를 보호하는지 이해합니다.
참고: 이 실습 환경에서는 현재 SSH 보안 구성을 검토하고 다양한 보안 설정을 이해합니다. 이 단계는 이러한 보안 조치를 이해하고 SSH 서버 구성 모범 사례를 배우는 데 중점을 둡니다.
루트 로그인 보안 이해
SSH를 통한 직접적인 루트 로그인을 허용하는 것은 일반적으로 권장되지 않습니다. 루트 계정은 전체 관리 권한을 가지기 때문입니다. 공격자가 루트 계정에 액세스하면 시스템을 완전히 제어할 수 있습니다. 일반 사용자로 로그인한 다음 sudo를 사용하여 관리 작업을 수행하는 것이 더 안전합니다.
현재 루트 로그인 구성을 검토하고 그 효과를 테스트해 보겠습니다.
먼저 labex 사용자로 SSH를 통해 로그인합니다.
ssh labex@localhost
이전 단계의 SSH 키 설정이 올바르다면 비밀번호 없이 로그인되어야 합니다.
Last login: Mon Jun 9 01:57:27 2025 from 47.251.66.143
[labex@host ~]$
이제 SSH 서버 구성 파일을 검토하여 현재 보안 설정을 이해합니다.
sudo cat /etc/ssh/sshd_config | grep -E "^PermitRootLogin|^#PermitRootLogin"
이 명령은 현재 PermitRootLogin 설정을 보여줍니다. 다음과 같은 내용이 보여야 합니다.
PermitRootLogin no
이 설정은 SSH를 통한 직접적인 루트 로그인이 비활성화되었음을 의미하며, 이는 보안 모범 사례입니다.
루트 로그인이 실제로 차단되는지 테스트해 보겠습니다. 먼저 현재 SSH 세션을 종료합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
이제 root로 localhost에 로그인을 시도합니다.
ssh root@localhost
"Permission denied" 메시지가 표시되어 직접적인 루트 로그인이 허용되지 않음을 나타냅니다(이 환경에서는 이미 구성되어 있을 수 있음).
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
이는 이 환경에서 루트 로그인이 비활성화되었음을 확인해 주며, 이는 바람직한 보안 구성입니다. "Permission denied" 메시지는 보안 조치가 효과적으로 작동하고 있음을 보여줍니다.
비밀번호 인증 보안 이해
비밀번호 인증을 비활성화하면 사용자는 SSH 키 기반 인증과 같은 더 안전한 방법을 사용해야 합니다. 이는 서버에 대한 무차별 대입 공격(brute-force attack)의 위험을 크게 줄입니다.
현재 비밀번호 인증 설정을 검토하고 작동 방식을 이해해 보겠습니다.
labex 사용자로 SSH를 통해 로그인합니다(SSH 키 사용).
ssh labex@localhost
Last login: Mon Jun 9 01:57:32 2025 from 127.0.0.1
[labex@host ~]$
먼저 현재 PasswordAuthentication 설정을 확인합니다.
sudo cat /etc/ssh/sshd_config | grep PasswordAuthentication
PasswordAuthentication yes
## PasswordAuthentication. Depending on your PAM configuration,
## PAM authentication, then enable this but set PasswordAuthentication
보시다시피 PasswordAuthentication yes가 현재 구성되어 있으며, 이는 비밀번호 인증이 활성화되었음을 의미합니다. 사용자가 비밀번호로 인증할 수 있게 하지만, 서버를 무차별 대입 비밀번호 공격에 취약하게 만들기 때문에 보안 위험이 있습니다.
출력은 다음을 보여줍니다.
PasswordAuthentication yes- 비밀번호 인증을 활성화하는 활성 설정- 주석 처리된 줄은 PAM 구성에 대한 추가 컨텍스트를 제공
이 구성은 사용자가 비밀번호와 SSH 키를 모두 사용하여 인증할 수 있음을 의미합니다. 보안 강화를 위해 비밀번호 인증을 비활성화하고 SSH 키 기반 인증에만 의존하는 것이 좋습니다.
현재 SSH 세션을 종료합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
이제 비밀번호 인증이 활성화된 상태에서 SSH 키 기반 인증이 제대로 작동하는지 확인해 보겠습니다.
ssh labex@localhost
이 작업은 SSH 키를 사용하여 비밀번호 프롬프트 없이 성공해야 합니다.
Last login: Mon Jun 9 02:00:22 2025 from 127.0.0.1
[labex@host ~]$
이는 몇 가지 중요한 보안 개념을 보여줍니다.
- 비밀번호 인증이 활성화됨 (
PasswordAuthentication yes) - 사용자는 비밀번호와 SSH 키 모두로 로그인할 수 있습니다. - SSH 키 기반 인증이 제대로 작동함 - 더 안전한 인증 방법을 사용할 수 있습니다.
- 서버가 두 인증 방법을 모두 허용함 - 편리하지만 무차별 대입 공격으로 인한 보안 위험이 있을 수 있습니다.
- 루트 로그인이 비활성화됨 - 관리자 액세스에는 적절한 사용자 권한 상승이 필요합니다.
보안 권장 사항: 프로덕션 환경에서는 사용자가 SSH 키 기반 인증만 사용하도록 강제하여 보안을 강화하기 위해 PasswordAuthentication no 설정을 고려하십시오.
세션을 종료합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
OpenSSH 서버 보안 구성을 성공적으로 검토하고 이해했습니다. 서버는 현재 루트 로그인이 비활성화되어 있고(보안 모범 사례 준수) 비밀번호 인증이 활성화되어 있습니다(유연성을 제공하지만 프로덕션 환경에서는 추가 보안 고려 사항이 필요할 수 있음). 또한 더 안전한 인증 방법으로서 SSH 키 기반 인증이 제대로 작동하는지 확인했습니다.
요약
이 실습에서 참가자들은 SSH를 사용하여 시스템에 액세스하는 방법을 배웠으며, openssh-clients 설치 확인 및 SSH를 통한 localhost 연결부터 시작했습니다. 비밀번호로 인증하는 방법을 연습하고 초기 호스트 신뢰성 확인 과정을 이해했습니다.
또한 비밀번호 없는 인증을 위한 SSH 키 쌍 생성 및 활용, ssh-agent를 통한 키 관리, 일반적인 SSH 연결 문제 해결 방법을 안내받았습니다. 마지막으로 참가자들은 SSH 클라이언트 구성을 사용자 지정하고 루트 로그인 및 비밀번호 인증을 비활성화하여 OpenSSH 서버를 보호하는 방법을 배웠으며, 이를 통해 안전한 원격 액세스 관행에 대한 이해를 높였습니다.



