linux - ssh(secure shell)와 ssh-keygen 그리고 scp(secure copy)에 대하여

양승현·2023년 9월 25일
1

linux

목록 보기
19/20
post-thumbnail

SSH

SSH란?

  • SSH(Secure Shell)는 암호화 및 인증 매커니즘을 사용하여 보안 액세스 및 파일 전송과 같은 서비스를 구현하는 네트워크 보안 프로토콜이다.
  • Telnet 및 FTP와 같은 기존 원격 로그인 및 파일 전송 방법은 안전하지 않은 일반 텍스트로 데이터를 전송하며, 보안이 중요함에 따라 이러한 방법은 점점 덜 수용되고 있다.
  • SSH는 네트워크 데이터를 암호화하고 인증하여 불안전한 네트워크 환경에서 안전한 네트워크 서비스를 제공한다.
  • Telnet 및 기타 여러 안전하지 않은 원격 셸 프로토콜에 대한 안전한 대안 솔루션인 SSH 프로토콜은 전 세계적으로 널리 사용되며 대부분 장치들은 SSH를 지원한다.
20(FTP), 21(FTP, FTPS), 23(TELNET), 25(SMTP), 53(DNS), 80(HTTP), 123(NTP), 443(HTTPS), 3389(RDP), 5900(VNC) 

SSH가 필요한 이유

  • 기존 인터넷 통신에서는 데이터가 일반 텍스트로 전송된다.
  • 이때, 데이터를 가로채면 완전히 노출되므로 보안 이슈가 발생하여 안전하지 않다.
  • 하지만, SSH는 클라이언트-서버 모델을 사용하여 두 당사자를 인증하고 두 당사자 간의 데이터를 암호화하여 보안이 적용되지 않은 네트워크를 통해 네트워크 서비스를 안전하게 운영하기 위한 보안 전송 채널을 제공한다.
  • SSH를 적용하는 가장 일반적인 시나리오는 원격 로그인 및 파일 전송인데, SSH가 등장하기 전에 Telnet은 원격 로그인 시나리오에서 널리 사용되어 네트워크 장치의 원격 관리를 용이하게 했다.
  • FTP는 작동하기 쉽고 높은 전송 효율성을 제공하는 일반적인 파일 전송 프로토콜인데, Telnet과 FTP에는 모두 동일한 문제가 존재한다.
  • 데이터가 일반 텍스트로 전송되므로 보안 위험이 발생하게 된다.
  • Telnet 및 FTP 애플리케이션의 보안 문제를 해결하기 위해 SSH는 암호화된 데이터 전송 및 인증 강도 향상과 같은 방법을 사용하여 안전한 원격 로그인 및 파일 전송 서비스를 구현한다.

SSH 작동 방식

  • SSH는 클라이언트-서버 모델을 사용하는데, 보안 SSH 채널을 설정하려면 두 당사자가 TCP 연결을 설정하고, 사용할 버전 번호와 알고리즘을 협상하고, 후속 대칭 암호화를 위해 동일한 세션 키를 생성해야한다.
  • 사용자 인증이 완료되면 두 당사자는 데이터 교환을 위한 세션을 설정할 수 있다.
  • SSH 작업 프로세스는 아래 단계로 구성된다.

1. 연결 설정(Connection establishment)

  • SSH는 토신을 위해 포트를 사용하는데, SSH 연결이 설정되기 전에 SSH 서버는 지정된 포트에서 연결 요청을 수신한다.
  • SSH 클라이언트가 SSH 서버의 지정된 포트로 연결 요청을 보내면 SSH 클라이언트와 SSH 서버 사이에 TCP 연결이 설정되고 이 포트를 통해 서로 통신한다.
  • 기본적으로 SSH 서버는 포트 22번을 default로 사용하며, SSH를 NETCONF에 적용하는 경우 기본 포트 번호 22 혹은 830을 지정할 수 있다.
  • SSH에서 사용하는 포트 번호는 장치에서 사용 가능한 다른 포트로 변경될수 있으며, 변경 후에는 현재 모든 연결이 끊어지고 SSH 서버가 새 포트를 수신하기 시작한다.
  • default SSH 포트 번호로 22를 사용하며 키 보안 전송 중에 SSH 포트 번호를 변경하는 것이 좋다.

2. 버전 협상(Version Negotiation)

  • SSH에는 SSH1.X(SSH2.0 이전 버전)와 SSH2.0 두 가지 버전이 있다.
  • SSH1.X와 비교할때 SSH2.0은 확장된 구조를 가지며 더 많은 인증 방법과 키 교환 방법을 지원하고 서비스 기능을 향상시킨다.
  • SSH 서버와 클라이언트는 아래 프로세스에 사용할 SSH 버전을 결정하기 위해 협상한다.
    1. SSH 서버는 설정된 연결을 통해 지원되는 SSH 버전 정보를 SSH 클라이언트로 보낸다.
    1. SSH 클라이언트는 버전 정보를 받은 후 자신이 지원하는 SSH 버전을 기준으로 사용할 버전을 결정하고 해당 버전을 SSH 서버로 보낸다.
    2. SSH 서버는 클라이언트가 결정한 버전을 지원하는지 확인하고, 맞다면 버전 협상에 성공한 것이다.

3. 알고리즘 협상(Algorithm Negotiation)

  • SSH는 세션 키 생성을 위한 키 교환 알고리즘, 데이터 암호화를 위한 대칭 암호화 알고리즘, 디지털 서명 및 인증을 위한 공개 키 알고리즘, 데이터 무결성 보호를 위한 HMAC 알고리즘 등 다양한 우형의 알고리즘을 사용한다.
  • SSH 서버와 클라이언트는 각 유형의 여러 알고리즘을 지원하므로 각 유형에 사용할 알고리즘을 협상하고 결해야하는데, 프로세스는 아래와 같다.
    1. SSH 서버와 클라이언트는 지원되는 알고리즘을 서로에게 보낸다.
    1. SSH 서버와 클라이언트는 각 유형에 사용할 알고리즘을 협상하게 되는데, 각 유형의 알고리즘을 협상하는 동안 SSH 서버와 클라이언트는 최종 알고리즘을 사용하기 위해 둘 다 지원하는 알고리즘으로 일치시키며, 각 유형에 대한 알고리즘이 성공적으로 일치하면 알고리즘 협상이 완료된다. 만약 유형에 대해 일치하는 알고리즘이 없다면 이 유형의 알고리즘 협상은 실패하게 되고 SSH 서버와 클라이언트 간의 SSH 연결은 끊어지게 된다.

4. 키 교환(Key Exchange)

  • SSH 서버와 클라이언트는 키 교환 알고리즘을 사용하여 암호화된 채널을 설정하기 위한 공유 세션 키와 세션 ID를 동적으로 생성한다.
  • 세션 키는 전송을 위해 후속 데이터를 암호화하는데 사용되며, 세션 ID는 인증 중에 관련 SSH 연결을 식별하는데 사용된다.
  • SSH 서버와 클라이언트는 후속 대칭 암호화를 위해 동일 세션 키를 보유해야 하는데, 키 교환의 보안을 보장하기 위해 SSH는 보안 방법을 사용하여 세션 키를 생성한다.
  • SSH 서버와 클라이언트는 공동으로 세션 키를 생성한다.(수학적 이론을 바탕으로 직접적인 키 전송 없이 키 교환을 구현하므로 안전하지 않은 채널을 통해 키를 전송할 필요가 없다.)
  • 아래 그림 참고

5.1 사용자 인증(User Authentication)

  • SSH 클라이언트는 SSH 서버에 인증 요청을 보낸 다음 SSH 클라이언트를 인증하는데, 아래 인증 모드를 지원한다.
  1. 비밀번호 인증(strong password authentication) : 클라이언트는 암호화된 사용자 이름과 비밀번호를 서버로 보낸다. 서버는 사용자 이름과 비밀번호를 해독하고 이를 로컬에 저장된 사용자 이름 및 비밀번호와 비교한 후 인증 성공 또는 실패 메세지를 클라이언트에 반환한다.
  2. 공개 키 인증(public key authentication) : 클라이언트는 사용자 이름, 공개 키, 공개 키 알고리즘을 사용하여 인증을 위해 서버와 데이터를 교환한다.
  3. 비밀번호 + 공개 키 인증 : 클라이언트는 비밀번호 인증과 공개키 인증을 모두 사용하여 서버의 인증을 받은 후에만 시스템에 로그인 할 수 있다.
  • 비밀번호 인증과 공개 키 인증 방법 두가지는 기본 SSH 사용자 인증 방법이며, 비밀번호 인증 모드는 간단하므로 사용자는 로그인할 때마다 사용자 이름과 비밀번호만 입력하면 되고, 키 인증 방법은 널리 사용되고 있으며, 보안성이 높은 비밀번호 없이 로그인을 구현할 수 있으므로 권장된다.

5.2 비밀번호 인증(Password Authentication)

  • 비밀번호 인증의 기본 원칙으로 SSH 클라이언트는 서버 공개 키를 사용하여 비밀번호를 암호화하고, SSH 서버는 개인 키를 사용하여 비밀번호를 해독하고 비밀번호 유효성을 확인한다.
  • 과정은 아래와 같다.
  1. SSH 클라이언트가 SSH 서버에 로그인 요청을 보낸다.
  2. SSH 서버는 공개 키를 SSH 클라이언트로 보낸다.
  3. SSH 클라이언트에 비밀번호를 입력한 후, 서버 공개 키를 이용하여 비밀번호를 암호화하고, 암호화된 비밀번호를 SSH 서버로 전송한다.
  4. SSH 서버는 암호문을 수신하고 개인 키를 사용하여 이를 해독해 비밀번호를 얻는다. 그런 다음 SSH 서버는 비밀번호가 올바른지 확인하고 맞다면 인증에 성공한다.
  • 이 인증 모드의 단점은 중간자(MITM) 공격의 위험이 있다는 것인데, 누군가 SSH 클라이언트의 로그인 요청을 가로채 SSH 서버인것처럼 가장하고 위조된 공개 키를 SSh 클라이언트에게 보내면 사용자의 로그인 비밀번호를 알아낼 수 있다.
  • 따라서 SSH 서버에 처음 로그인하게 되면 SSH 클라이언트는 공개키 지문을 표시하고 로그인 확인 여부를 묻는데, 확인 후 공개 키는 저장되고 신뢰할 수 있게된다.
  • 이후 다음 접속 시 SSH 클라이언트는 SSH 서버에서 보낸 공개 키가 로컬에 저장된 공개 키와 동일 한지 확인하는 작업을 거치게 된다. 이 방법은 공개키 지문을 공개한 SSH 서버와 올바른 SSH 서버에 로그인한 SSH 클라이언트에 적용 가능하다.

5.3 키 인증(Key Authentication)

  • 중간자(MITM) 공격을 방지하려면 보다 안전한 키 인증을 사용할 수 있어야한다.
  • 키 인증의 기본 원칙은 SSH 서버가 클라이언트 공개 키를 사용하여 임의의 콘텐츠를 암호화하고, SSH 클아이언트는 개인 키를 사용하여 콘텐츠를 해독하고 신원 확인을 위해 해독한 콘텐츠를 서버에 보낸다.
  • 아래 그림은 해당 내용의 자세한 과정을 나타낸다.
  1. SSH 연결을 설정하기 전에 SSH 클라이언트는 자체 공개-개인 키 쌍을 생성하고 공개 키를 SSH 서버에 저장해야 한다.
  2. SSH 클라이언트는 SSH 서버에 로그인 요청을 보낸다.
  3. SSH 서버는 요청에 포함된 사용자 이름 등의 정보를 기반으로 하여 클라이언트 공개 키를 검색하고, 공개 키를 사용해 난수를 암호화한 후에 암호화된 난수를 클라이언트에게 보낸다.
  4. SSH 클라이언트는 수신 시 자체 개인 키를 사용하여 반환된 정보를 해독한 후 해독된 정보를 SSH 서버로 보낸다.
  5. SSH 서버는 SSH 클라이언트가 보낸 복호화된 정보가 올바른지 확인하게 되고, 정보가 정확하면 인증에 성공한 것이다.

6. 세션 요청(Session Request)

  • 인증이 성공하면 SSH 클라이언트는 서버에 세션 요청을 보내 서버에 특정 유형의 서비스를 제공하도록 요청하는데 즉, SSH 클라이언트는 서버와의 세션 설정을 요청하고 서버는 클라이언트의 요청에 응답한다.

7. 세션 상호작용(Session Interaction)

  • 세션이 설정된 후 SSH 서버와 클라이언트는 세션을 통해 데이터를 교환한다. SSH 서버와 클라이언트가 보낸 데이터는 세션 키를 사용하여 암호화되고 해독된다.

원격 호스트 인증을 위한 SSH 키 생성 및 사용

ssh 접속 규칙 정의

  • /etc/hosts 설정
$ cat /etc/hosts
192.168.100.200 yangmaster1
192.168.100.201 yangworker1
192.168.100.202 yangworker2
or
$ sudo bash -c 'cat >> /etc/hosts << EOF
192.168.100.200 yangmaster1
192.168.100.201 yangworker1
192.168.100.202 yangworker2
EOF'
  • /etc/ssh/sshd_config 설정 및 확인
$ vi /etc/ssh/sshd_config

# Port 22 
-> ssh 기본 접속 port는 22번 이며, 임의의 port를 지정하여 사용하고 싶다면, port 번호를 변경 후 주석을 해제시킨다.

# ListenAddress 0.0.0.0 
-> 기본 default 값은 주석으로 처리되어 정책이 동작하지 않지만 주석을 해제하고 특정 ip를 지정하게 되면 해당 ip에서만 접속이 허용된다.

HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
-> ssh 접속을 할 경우 필요한 암호화 키가 저장되는 default 경로로 ECDSA_KEY 암호화 방식을 사용한다.

#PermitRootLogin no
-> root 계정으로 원격 접속 시 허용 여부를 정의한다. 허용하고 싶다면 주석을 해제하고 no에서 yes로 변경하면 root로 접속이 허용되지만, 보안상 이슈가 발생할 수 있어 권장하지 않는다.
  • sshd.service 재 시작하기
# /etc/ssh/sshd_config의 값을 변경 했다면 재시작하여 변경 내용을 적용해주자
$ systemctl restart sshd

방화벽 설정하기

  • 방화벽(firewalld)와 iptables를 운영 중이라면 ssh default port인 22번 port를 허용해주자
# CentOS 7 버전 이상에서 사용
$ firewall-cmd --zone=public --add-port=22/tcp --permanent
or
$ firewall-cmd --permanent --zone=public --add-port=22/tcp

# 방화벽 재시작
$ firewall-cmd --reload

# iptables 설정 
$ iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

# ssh port 확인하기(현재 네트워크가 어떻게 열려있고 통신하고 있는지 확인 가능)
$ sudo netstat -antp

1. SSH key 생성(ssh-keygen)

  • ssh key 생성하기
# 키 쌍 만들기
$ ssh-keygen
or
$ ssh-keygen -t rsa
or
$ ssh-keygen -t rsa -m pem
Generating public/private rsa key pair.
Enter file in which to save the key (/home/jsmith/.ssh/id_rsa):[Enter key]
Enter passphrase (empty for no passphrase): [Press enter key]
Enter same passphrase again: [Pess enter key]
Your identification has been saved in /home/jsmith/.ssh/id_rsa.
Your public key has been saved in /home/jsmith/.ssh/id_rsa.pub.
The key fingerprint is:
33:b3:fe:af:95:95:18:11:31:d5:de:96:2f:f2:35:f9 yang@yangmaster
  • 위 명령어를 실행하게 되면 ~/.ssh/ 경로에 public key(id_rsa.pub)와 Private key(id_rsa) 키가 생성된다.
  • 키를 생성 했다면 public key(id_rsa.pub)를 remote server들에게 scp 명령어을 통해 전달하면 접속할 수 있다.

2.1 Password를 통한 접속

# ssh [user name]@[Server Name or Server IP]
$ ssh yang@master
yang@master`s password : 입력


$ ssh yang@192.168.100.200
yang@192.168.100.200`s password : 입력

2.2 SSH key를 통한 접속

  • remote server의 authorized_keys 파일에, 생성한 자신의 공개키를 등록해야 하기 때문에 scp 명령을 통해 키를 전송해야 한다.
# 퍼블릭 키를 authorized_key로 copy 
$ cp id_rsa.pub authorized_keys

# scp 명령어로 yangserver1과 yangserver2에 public key(authorized_keys) 전송하기
# 해당 방법 사용시 password를 입력해야 전송한다.
$ scp ~/.ssh/* yang@yangserver1
$ scp ~/.ssh/* yang@yangserver1

# yangserver1과 yangserver2에 public key(authorized_keys)를 복사하기
$ cat ~/.ssh/id_rsa.pub
ssh-rsa dasdsadadawdadawdsadwasdadw 생략
# 출력된 키 값을 복사하여 remote server에 접속하여 ~/.ssh/authorized_keys에 붙여넣기
$ cat <<EOF > ~/.ssh/authorized_keys
ssh-rsa dasdsadadawdadawdsadwasdadw
EOF

# ssh key를 통해 접속하기
$ ssh yang@yangserver1
$ ssh yang@yangserver2

# ssh key 경로가 다른 경우
$ ssh -i KEY_PATH/id_rsa.pem yang@yangserver1
$ ssh -i KEY_PATH/id_rsa yang@yangserver2
# 정상 접속이 안된다면 -v | -vv | -vvv 옵션 중 하나를 맨뒤에 붙여 자세한 내용을 확인하자

2.3 ssh-keygen 및 ssh-copy-id를 사용하여 비밀번호 없이 SSH 로그인을 수행

  • ssh-keygen은 공개 키와 개인 키를 생성한다.
  • ssh-copy-id는 로컬 호스트의 공개 키를 원격 호스트의 Authorized_keys 파일에 복사하며, remote host의 ~/.ssh/authorized_keys에 적절한 권한을 할당한다.
    1. 먼저 1번 내용을 통해 ssh-keygen하여 키 쌍을 생성한다.
$ ssh-keygen
    1. ssh-copy-id를 사용하여 공개 키를 remote host에 복사한다.
# ssh-copy-id -i ~/.ssh/id_rsa.pub [hostname or IP of remote host]
$ ssh-copy-id -i ~/.ssh/id_rsa.pub yangworker1
yang@yangworker1's password: [yangworker1의 password 입력]
Now try logging into the machine, with "ssh 'yangworker1'", and check in: 

.ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

$ ssh-copy-id -i ~/.ssh/id_rsa.pub yangworker2
yang@yangworker2's password: [yangworker2의 password 입력]
Now try logging into the machine, with "ssh 'yangworker2'", and check in: 

.ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

# 해당 작업을 완료하게 되면 비밀번호를 입력하지 않고 remote host(yangworker1 & yangworker2)에 로그인 할 수 있다.
    1. password 없이 remote host에 로그인
$ ssh yang@[yangworker1
or
$ ssh yang@yangworker2
Authorized_keys의 중복
  • 로컬 호스트에서 ssh-copy-id를 여러 번 실행하면 중복을 확인하지 않고 원격 호스트의 Authorized_keys 파일에 동일한 키를 계속 추가하기 때문에 해당 정보가 중복되어 저장된다.
  • 항목이 중복되어도 문제가 되지 않지만 불피요한 정보가 계속 저장될 수 있다.
know_hosts
  • 한번 원격 접속이 이루어지고 나면 사용자 홈 디레터리 ~/.ssh/know_hosts 파일에 원격지 접속에 필요한 키 값이 생성된다.
  • hostname 혹은 ip로 같은 remote host에 원격 접속할 경우 출동이 발생할 수 있다.(이 경우 둘 중 하나는 주석(#) 처리)

보안 FTP

  • sftp & scp 프로토콜을 통해 SSH를 파일 전송에 사용할 수 있다.
  • OS에서 SSH를 사용하도록 설정한 경우 sftp & scp로도 연결할 수 있다.

sftp(secure ftp)

usage: sftp [-46aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]
         [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit]
         [-o ssh_option] [-P port] [-R num_requests] [-S program]
         [-s subsystem | sftp_server] destination

scp(secure copy)

usage: scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
          [-l limit] [-o ssh_option] [-P port] [-S program] source ... target

출처
What Is SSH?
3 Steps to Perform SSH Login Without Password Using ssh-keygen & ssh-copy-id
원격 호스트 인증을 위한 SSH 키 생성 및 사용
리눅스 ssh 명령어 사용법

0개의 댓글