본문으로 바로가기

[Linux] 리눅스 ssh 동작 방식, 설치 및 사용법

category OS/Linux 2021. 10. 6. 16:23

목차

    1. SSH

    SSH

    • SSH 이란 Secure Shell Protocol의 약자로, FTP / Telnet에 비해 보안에 초점을 맞춘 Protocol입니다.
    • 네트워크 상의 다른 컴퓨터에 로그인하거나 원격 시스템에서 명령을 실행하고 다른 시스템으로 파일을 복사할 수 있도록 해 주는 프로토콜 혹은 프로그램
    • 암호화 방식을 지원해서 중간에 암호를 해킹을 당해도 암호화된 문자로 보여 원본을 알 수 없고 강력한 인증 방식을 지원하기 때문에 보안적으로 우수한 프로토콜입니다.
    • SSH 접속을 위해서는 기본적으로 서버에 SSH 서버(데몬)가 설치되어 있어야 하고, 클라이언트에는 SSH 클라이언트가 설치되어 있어야 합니다.
    • 기본 포트는 22번 포트입니다.

    1.1. SSH 프로토콜의 주요 기능

    1. 보안 접속을 통한 rsh, rcp, rlogin, rexec, telnet, ftp 등을 제공합니다. (인증(Authentication), 암호화(Encryption))
    2. IP spoofing (IP스푸핑, 아이피 위/변조 기법 중 하나)을 방지하기 위한 기능을 제공합니다. (무결성(Integrity))
    3. X11 패킷 포워딩 및 일반적인 TCP/IP 패킷 포워딩을 제공합니다.

    1.2. SSH 프로토콜의 스택 구조

    SSH 스택

    SSH 전송 프로토콜 (SSH Transport Layer Protocol, SSH TLP)

    : 서버 인증, 기밀성, 무결성, 압축(옵션) 제공

    : 키 교환 방식, 공개 키 방식, 대칭 키 방식, 메시지 인증 방식, 해시 알고리즘 등이 클라이언트, 서버 간에 협상

    • SSH 인증 프로토콜 (SSH User Authentication Protocol)

    : 해당 서버에 대한 사용자 인증(User Authentication) 제공

    • SSH 연결 프로토콜 (SSH Connection Protocol)

    : 암호화된 터널들 각각에 다수 논리 채널들을 다중화 (1:N) 가능

    • SSH 응용 프로토콜

    : TELNET, RLOGIN, SMTP 

     


    2. SSH 설치

    2.1. SSH 설치 확인

    • "rpm -qa" 또는 "yum list installed"를 이용해 ssh 설치가 되어있는지 확인해 봅니다.
    • 일반적으로 Linux를 설치하면서 기본적으로 설치되어있기도 합니다. (필자는 CentOS7에서 설치 확인했습니다.)
    # rpm -qa | grep ssh
    openssh-server-7.4p1-21.el7.x86_64
    openssh-clients-7.4p1-21.el7.x86_64
    openssh-7.4p1-21.el7.x86_64
    libssh2-1.8.0-4.el7.x86_64
    
    또는 
    
    # yum list installed | grep ssh
    libssh2.x86_64                              1.8.0-4.el7                @anaconda
    openssh.x86_64                              7.4p1-21.el7               @anaconda
    openssh-clients.x86_64                      7.4p1-21.el7               @anaconda
    openssh-server.x86_64                       7.4p1-21.el7               @anaconda

    2.2. SSH 설치

    • SSH가 설치되어 있지 않은 경우 yum을 이용해 설치합니다.
    • 설치 후 systemctl 명령어를 이용해 실행시켜 줍니다.
    • ssh 서버 실행 파일(데몬): /usr/sbin/sshd
    • ssh 클라이언트 실행 파일: /etc/bin/ssh
    [ssh 설치]
    # yum install openssh-server
    
    [서비스 시작]
    # systemctl start sshd 
    
    [서비스 중지]
    # systemctl stop sshd
    
    [재부팅 후 자동실행]
    # systemctl enable sshd
    
    [재부팅 후 자동실행 X]
    # systemctl disable sshd
    
    [서비스 상태 확인]
    # systemctl status sshd
    ● sshd.service - OpenSSH server daemon
       Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
       Active: active (running) since 수 2020-11-25 15:29:10 KST; 10 months 9 days ago
         Docs: man:sshd(8)
               man:sshd_config(5)
    ( ... ) 생략
    
    [프로세스 상태 확인]
    # ps -ef | grep sshd | grep -v grep
    root      1341     1  0  2020 ?        00:33:56 /usr/sbin/sshd -D
    root     19261  1341  0 12:44 ?        00:00:00 sshd: root@pts/1
    root     19265  1341  0 12:44 ?        00:00:00 sshd: root@notty
    root     24444  1341  0 14:02 ?        00:00:00 sshd: root@pts/2
    root     24461  1341  0 14:02 ?        00:00:00 sshd: root@notty
    
    [데몬이 특정포트에 잘 떠 있는지 확인]
    # netstat -ntap | grep LISTEN | grep sshd
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1341/sshd
    tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      19261/sshd: root@pt
    tcp        0      0 127.0.0.1:6011          0.0.0.0:*               LISTEN      24444/sshd: root@pt
    tcp6       0      0 :::22                   :::*                    LISTEN      1341/sshd
    tcp6       0      0 ::1:6010                :::*                    LISTEN      19261/sshd: root@pt
    tcp6       0      0 ::1:6011                :::*                    LISTEN      24444/sshd: root@pt
    
    [클라이언트 / 서버 실행 파일]
    # which ssh
    /usr/bin/ssh
    
    # which sshd
    /usr/sbin/sshd

    2.3. 방화벽 설정

    • ssh(22 port) 포트를 열어 줍니다.
    //firewall을 사용하는 경우
    # firewall-cmd --zone=public --permanent --add-port=22/tcp
    # firewall-cmd --reload
    # firewall-cmd --zone=public --list-all
    
    //iptables를 사용하는 경우
    # iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    # service iptables save
    # service iptables restart
    # iptables -nL

     

     


    3. SSH 설정

    • 설정 파일은 /etc/ssh/sshd_config입니다.
    • 설정 파일을 변경 후 적용을 위해서는 sshd를 재시작해야 합니다.
    # systemctl restart sshd

    3.1. 접속 포트 변경

    • /etc/ssh/sshd_config 17번 라인에 "Port 22" 주석을 해제한 후 원하는 포트로 수정해 줍니다.
    • 접속 포트를 변경 할 경우 방화벽 설정도 해야 합니다. 

    3.2. 접속 IP 지정

    • /etc/ssh/sshd_config 19번 라인에 "ListenAddress" 주석을 해제한 후 특정 ip로 수정해줍니다.
    • 설정한 특정 IP로만 접속이 허용되게 됩니다.

    3.3. root 계정 접속 거부

    • root 계정으로의 ssh 접속을 거부하려면 /etc/ssh/sshd_config 38번 라인에 "PermitRootLogin yes" 주석을 해제 후 yes를 no로 변경합니다.
    • root 접속 허용은 보안상 권장하지 않습니다.

    3.4. 공개키 인증 방식 사용 여부

    • 공개키 인증 방식을 사용하지 않으려면 /etc/ssh/sshd_config 43번 라인에 "PubkeyAuthentication yes" 주석을 해제 후 yes를 no로 변경합니다.
    • 공개키 인증에 사용할 서버의 공개키 경로는 /etc/ssh/sshd_config 47번 라인에 "AuthorizedKeysFile %h/.ssh/authorized_keys" 의 경로를 수정해 줍니다. (%h는 사용자 홈 디렉터리)
    • 공개키 인증은 클라이언트에서 키(공개키, 개인키)를 생성 후 생성한 공개키를 서버에 저장해서 인증하는 방식입니다.

    3.5. 패스워드 인증 방식 

    • 패스워드 인증 방식을 사용하지 않으려면 /etc/ssh/sshd_config 65번 라인에 "PasswordAuthentication yes" 주석을 해제 후 yes를 no로 변경합니다.


    4. SSH 접속 동작 방식

    • SSH 원격 접속 시 서버 인증을 하고 클라이언트 인증(비밀번호 또는 키 페어 인증)을 통해 접속합니다.
    • 클라이언트와 서버가 서로가 올바른 상태인지 인증(검증)을 하는 과정에서는 비대칭키 방식을 활용합니다.
    • 비대칭키 방식을 이용해 인증 후 데이터를 주고받는 과정(데이터 통신)에서는 대칭키 방식을 활용합니다.

    4.1. 서버 인증, 세션 키 생성

    • 접속하려는 서버가 올바른 서버인지 검증하고 이후의 데이터 통신을 안전하게 진행하기 위한 세션 키를 생성하는 과정
    • 서버에서 생성된 서버의 공개키를 클라이언트 시스템에 저장한 후 다음 접속에서 클라이언트에 저장되어 있는 서버의 공개키와 접속한 서버의 공개키가 동일한지를 확인하는 방식
    • 서버에서 공개키, 개인키를 생성합니다.

    SSH 서버인증

    1. 클라이언트가 서버에 처음 접속을 시도하면 공개키를 받을지 메시지가 나오고 클라이언트의 사용자가 "Yes"를 입력하면 공개키를 받아서 클라이언트의 .ssh/known_hosts 파일에 저장합니다.
    2. 클라이언트는 난수 값을 만들고 난수 값에 대해 해시 값을 생성 후 저장합니다.
    3. 난수 값을 공개키로 암호화하여 서버에 전달합니다.
    4. 서버에서는 클라이언트에서 보내준 암호화된 데이터를 개인키로 복호화해서 난수 값을 구한 후. 이 난수 값을 해시값으로 만들어 클라이언트에 전달합니다. 
    5. 클라이언트에서는 저장한 해시값과 서버에서 받은 해시값을 비교해 서버가 정상인 서버인지 확인합니다.

    [사용자가 확인할 수 있는 커맨드 창 내용]

    # ssh root@hostIP -p 31242
    The authenticity of host '[hostIP]:31242 ([0.0.0.0]:31242)' can't be established.
    ECDSA key fingerprint is SHA256: ( ... ).
    ECDSA key fingerprint is MD5: ( ... ).
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '[hostIP]:31242,[0.0.0.0]:31242' (ECDSA) to the list of known hosts.

    4.2. 클라이언트 인증

    • 클라이언트가 해당 서버에 대한 올바른 접근 권한을 가지고 있는지 검증하는 과정
    • 비밀번호 인증키 페어 인증 방식이 있습니다.

    4.2.1. 비밀번호 인증

    • 사용자가 입력한 비밀번호를 서버 인증 과정에서 생성한 세션 키로 암호화하여 서버에게 보내고, 서버가 이를 검증하면 끝입니다.
    • 보안상 권장하지 않는 방식입니다.

    4.2.2. SSH 키 페어(공개키, 개인키) 인증

    • 클라이언트에서 공개키(Public Key), 개인키(Private Key)를 생성합니다.
    • 서버에 접속할 때 비밀번호 대신 key를 제출하는 방식
    • 비밀번호보다 높은 수준의 보안

    SSH 키 인증

    1. 클라이언트에서 비대칭키(공개키, 개인키)를 생성합니다.
    2. 클라이언트에 생성된 공개키를 복사해 서버의 .ssh/authorized_keys 파일에 직접 붙여 넣습니다.
    3. 서버에서 난수 값을 생성 후 해시값을 만들어 저장합니다. 
    4. 서버에서 난수 값을 공개키로 암호화해 클라이언트에 전달합니다.
    5. 클라이언트에서 암호화된 데이터를 개인키로 복호화 후, 복호화 한 데이터로 해시값을 생성해 다시 서버로 전달합니다.
    6. 서버에 저장된 해시 값과 클라이언트로부터 받은 해시 값을 비교해 같을 경우 정상적인 사용자로 인증되어 데이터 통신이 가능해집니다. 

     

     


    5. SSH 접속

    5.1. SSH 명령어

    # ssh [options] [사용자 계정]@[원격지 ip 또는 주소]

    [options]

    • 주요 몇몇 옵션입니다. 더 많은 옵션은 "man ssh"를 이용해 확인해주세요.
    옵션 설명
    -1 SSH Protocol v1을 사용합니다.
    -2 SSH Protocol v2을 사용합니다.
    -4 IPv4를 사용합니다.
    -6 IPv6를 사용합니다.
    -i 공개키 인증 시 사용하며 공개키 인증시 사용 할 개인키 파일을 선택합니다.
    -p 원격 호스트에 연결할 포트를 지정합니다.
    -x X11 전송을 불가능하게 합니다.
    -l 원격 접속할 계정을 설정합니다.
    -v 디버깅 모드를 활성화 합니다.
    -g, -G 장비 관련 옵션
    -L 원격 호스트와 포트에 전송할 로컬 포트를 설정합니다.
    -R 로컬 호스트와 지정된 포트로 전송될 원격 포트를 설정합니다.
    -e 세션에 대해 이스케이프 문자를 설정합니다.
    -C 모든 데이터에 압축을 요청합니다.

     

    [명령어 사용 예시]

    // 기본 포트로 접속하기 (22 포트)
    # ssh root@1.1.1.1 
    # ssh root@HostAddress
    
    // -l 옵션 이용해서 접속하기
    # ssh HostAddress -l root
    
    // 다른 포트로 접속하기 (22022 포트)
    # ssh root@1.1.1.1 -p 22022
    
    // 원격 접속 후 명령문 실행
    # ssh root@1.1.1.1 netstat -ntap
    
    // 공개키 인증을 통해 원격 접속하기(개인키 지정)
    # ssh -i ssh_key root@1.1.1.1

    5.2. 비밀번호 인증 접속

    • 클라이언트가 서버에 처음 접속을 시도하면 공개키를 받을지 메시지가 나오고 클라이언트의 사용자가 "Yes"를 입력하면 공개키를 받아서 클라이언트의 .ssh/known_hosts 파일에 저장합니다.
    # ssh root@hostIP -p 31242
    The authenticity of host '[hostIP]:31242 ([0.0.0.0]:31242)' can't be established.
    ECDSA key fingerprint is SHA256: ( ... ).
    ECDSA key fingerprint is MD5: ( ... ).
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '[hostIP]:31242,[0.0.0.0]:31242' (ECDSA) to the list of known hosts.
    • 비밀번호를 이용해 서버에 접속합니다. 
    • 보안상 권장하지 않는 방식입니다.
    # ssh root@HostIP -p 22022
    root@HostIP's password:
    
    Last login: Tue Oct  5 17:36:12 2021 from

    5.3. SSH 키 페어(공개키, 개인키) 인증 접속

    • 클라이언트에서 공개키(Public Key), 개인키(Private Key)를 생성합니다.
    • 클라이언트는 개인키를 가지고 있고, 서버에 공개키를 가지고 있도록 하여 접속하는 방식입니다.

    1. ssh-kegen으로 공개키/개인키 한 쌍을 생성

    • "ssh-keygen -t rsa" 명령어를 이용해 키(공개키, 개인키를 생성합니다. (RSA 암호화 방식으로 키 생성)
    • 키 비밀번호는 생략 가능합니다. 보안 홀이 생길 수 있지만 자동 로그인을 원한다면 생략해야 합니다.
    • 개인키는 절대로 타인에게 노출이 되면 안 됩니다. (파일 권한 설정 필수)
    // 키 이름, 키 비밀번호, 키 비밀번호확인 을 입력해줍니다.
    // 자동 로그인을 원한다면 비밀번호는 생략 해줍니다. 
    # ssh-keygen -t rsa
    
    Generating public/private rsa key pair.
    Enter file in which to save the key (/root/.ssh/id_rsa): ssh_key
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in ssh_key.
    Your public key has been saved in ssh_key.pub.
    The key fingerprint is:
    SHA256:XWNxETm/HROiCCIRT91JvMR8m+qwm0QroKSHyFTK0YA root@localhost.localdomain
    The key's randomart image is:
    +---[RSA 2048]----+
    |.. oo.. *.. . ++ |
    |E o.o. o B . +o. |
    | . o... o + B .o.|
    |. +      + * . o.|
    | = .   .S o     =|
    |*.. . ....     ..|
    |+o.  . o+        |
    | .    o...       |
    |       o.        |
    +----[SHA256]-----+
    
    // ssh_key(개인키), ssh_key.pub(공개키)
    # ls
    known_hosts  ssh_key  ssh_key.pub

    2. 공개키를 접속할 서버의 ~/.ssh/authorized_keys 파일에 키값을 저장

    • 클라이언트에서 생성 한 공개키를 복사해서 서버의 "~/.ssh/authorized_keys" 파일에 저장합니다.

    [클라이언트]

    # ls
    config  known_hosts  ssh_key  ssh_key.pub
    
    // 출력한 공개키 내용을 복사합니다.
    # cat ssh_key.pub
    ssh-rsa AAAAB3NzaC1yc2asdasdadsBAQDYmS/zdWAmBazJhasdaksdmdkasdrvRbRpdQHdh+MCbiA0ZGd6q9hrasd

    [서버]

    // 복사한 내용을 저장합니다.
    # vi ~/.ssh/authorized_keys
    
    # cat authorized_keys
    ssh-rsa AAAAB3NzaC1yc2asdasdadsBAQDYmS/zdWAmBazJhasdaksdmdkasdrvRbRpdQHdh+MCbiA0ZGd6q9hrasd

    3. 공개키 인증 접속(ssh -i 개인키 root@1.1.1.1)

    • 다음 명령어를 이용해 클라이언트에서 생성한 개인키를 이용해 원격 접속합니다.
    • 키 생성 시 비밀번호를 생략했을 경우 바로 접속이 됩니다. 
    //키 비밀번호를 입력합니다. 
    # ssh -i 개인키경로 root@HostAddress
    Enter passphrase for key 'ssh_key':
    
    Last login: Wed Oct  6 14:47:10 2021 from

    4. 비밀번호 인증 방식 접속 차단(선택)

    • 키를 이용한 원격 접속을 원할 경우에 설정합니다.
    • /etc/ssh/sshd_config 65번 라인에 "PasswordAuthentication yes"를 no로 변경해줍니다.

    5.4. ssh 관련 파일 권한 설정

    • ~/.ssh 디렉토리는 매우 중요한 보안 정보가 담긴 디렉토리 이므로 아래와 같이 권한 설정을 해주는 것을 권장합니다.
    //서버, 클라이언트 공통
    # chmod 700 ~/.ssh
    
    //클라이언트 
    # chmod 600 ~/.ssh/개인키
    # chmod 644 ~/.ssh/공개키
    # chmod 644 ~/.ssh/known_hosts
    
    //서버
    # chmod 644 ~/.ssh/authorized_keys

    5.5. config 파일 생성(편하게 SSH 이용하기)

    • 긴 명령어 입력 필요 없이 config 파일에 정보를 저장해서 간단하게 접속 가능한 방법입니다.
    • "ssh 접속명" 이런 식으로 간단하게 접속이 가능합니다.
    1. 클라이언트 ~/.ssh 경로에 config 파일을 생성해줍니다. 
    2. 아래의 내용을 config 파일에 입력해 줍니다.
    3. 비밀번호 인증 접속을 이용할 경우 개인키 관련 내용은 생략해줍니다.

    [config 파일 내용]

    Host 접속이름
        HostName [IP or Address]
        User [Username]
        Port [Port Number]
        IdentityFile ~/.ssh/[private key]
    # cd ~/.ssh/
    
    //config 파일이 없으면 생성해줍니다.
    # touch config
    
    //편집기를 이용해 ssh 접속에 필요한 내용을 저장해줍니다.
    # vi config
    
    Host test
        HostName test.co.kr
        User root
        Port 22022
        IdentityFile ~/.ssh/ssh_key
        
    //다음과 같이 접속을 시도합니다.
    # ssh test
    Enter passphrase for key '/root/.ssh/ssh_key':
    
    Last login: Wed Oct  6 14:52:45 2021 from

     

    이 게시물의 일부분은 다음 게시물을 참고했습니다.

     

    SSH 암호화 원리 및 AWS SSH 접속 실습

    SSH 암호화 방식에 대한 설명

    medium.com