아래의 글은 TechNote.kr@https://technote.kr/213 에서 정리된 글을 가저온것 입니다. 감사합니다.


가상 네트워크를 설정하기 위해서는 다음의 것들을 정해야 한다. 


-. 어떤 하드웨어를 통해 가상화할 것인가. 

: PC에 설치된 Ethernet 카드 중 어떤 카드를 통해 가상화하여 네트워크를 사용할 것인지 정한다.


-. 어떤 가상화 모드로 설정할 것인가. 

: 설정가능한 6개의 가상화 모드 중 어떤 것을 사용할 것인지 정한다. 기본으로는 NAT가 설정되어 있다.


(참고로 VirtualBox의 네트워크라는 표현을 사용하기는 하였지만 정확히 말하면 virtualbox manual에서 볼 수 있듯이 virtual networking, 즉  virtualbox의 가상 네트워킹이다.)


    • 연결되지 않음

    • NAT

    • NAT 네트워크

    • 브리지 어댑터

    • 내부 네트워크

    • 호스트 전용 어댑터

    • 일반 드라이버


NAT (Network Address Translation)


  • 가상머신 내부 네트워크 -> Host PC 외부 네트워크 단방향 통신 가능
  • Host PC 내의 가상 머신 간의 통신 불가능

해당 모드는 기본 선택사항으로 가상 머신 내에서 단순히 인터넷 사용이나 파일 다운로드와 같은 용도로만 사용할 경우 설정이 가능하다. 가상 머신 내에서는 자체 사설 IP 주소를 사용하지만 실제 외부로 나갈 때는 Host PC가 가진 IP 주소를 바꿔 달고 나가게 된다. Host PC의 외부 네트워크에서는 내부의 가상 머신에 접근 불가능하다. (일반적으로 통용되는 NAT의 개념을 적용한 부분이라 자세한 설명은 넘어간다.) 


즉, 아래 그림과 같이 NAT 모드일 경우 192.168.0.1의 주소를 사용하는 가상 머신은 외부 네트워크와 통신할 때 123.123.123.x 주소를 달고 외부와 통신하게 된다. 반면 192.168.0.x 의 주소를 가진 다른 가상 머신들과는 통신이 불가능하다.






NAT Network


  • 가상머신 내부 네트워크 -> Host PC 외부 네트워크 단방향 통신 가능
  • Host PC 내의 가상 머신 간의 통신 가능

해당 모드는 NAT와 거의 동일하지만 Host PC 내의 가상 머신끼리 통신이 가능하다는 점이 다르다. 가상 머신 간에 상호 통신이 필요한 작업이 있다면 해당 모드를 사용해야 한다. 


NAT Network의 경우는 아래 그림과 같이 NAT 와 다 동일하지만 192.168.0.x 의 주소를 가진 다른 가상 머신들과도 통신이 가능하다는 점이 다르다. 




브리지 어댑터 (Bridged Adapter)


  • Host PC와 동등한 수준의 네트워크 구성
  • 추가의 IP 할당이 필요함

해당 모드는 가상 머신의 네트워크를 Host PC 와 동등 수준으로 구성할 수 있게 해준다. 즉, 예를 들어 Host PC의 네트워크가 192.168.0.2로 설정이 되어 있다면 가상 머신의 네트워크 또한 192.168.0.4 정도로 같은 네트워크로 설정할 수 있는 것이다. 근데 잘 생각해 보면 실제 물리적인 네트워크 인터페이스는 Host PC의 Ethernet 카드 하나밖에 없다. 그렇다면 어떻게 Host PC와 가상 머신의 네트워크를 구분해 내는 것일까. VirtualBox 의 Manual에 따르면 소위 "net filter"라 불리는 Host PC의 network device driver를 사용하여 구분해 낸다고 한다. 해당 net filter를 통해 가상 머신은 자신의 data를 Host PC의 네트워크 카드로 부터 분리해내고 삽입하기도 한다. 


브리지 어댑터의 경우 아래 그림과 같이 물리적으로는 Host PC 내에 존재하지만 Host PC의 주소와 동등한 수준의 별도의 주소를 가지고 외부와 통신한다. 




내부 네트워크 (Internal Network)


  • Host PC와 독립적인 내부 네트워크
  • 같은 Host PC 내의 가상 머신 간 연결이 가능

해당 모드는 브리지 어댑터와 많은 부분에서 유사하지만 가장 큰 차이점으로 외부와 통신이 되지 않는다는 점이 있다. 즉, Host PC의 네트워크와 분리되어 있고, Host PC 내 가상 머신 간에만 상호 연결하여 통신이 가능하다. Host PC의 물리적인 네트워크 인터페이스와 연결되어 있지 않다. 


아래 그림과 같이 내부 네트워크는 Host PC 네트워크와 분리되어 있고, 가상 머신 간에만 통신이 가능하다.




호스트 전용 어댑터 (Host-only Adapter)


  • Host PC를 포함한 내부 네트워크 (외부 네트워크와는 단절)
  • 같은 Host PC 내의 가상 머신 간 연결이 가능

해당 모드는 "브리지 어댑터"모드와 같이 Host PC와 내부 가상 머신들과 통신이 가능하고, "내부 네트워크"모드와 같이 외부 네트워크와는 통신이 불가능하다. Host PC의 물리 네트워크 어댑터외에 별도의 Loopback 어댑터를 생성하여 해당 어댑터를 통해 통신한다.


호스트 전용 어댑터의 경우는 아래 그림과 같이 외부 네트워크가 단절되어 있다. 




일반 드라이버 (Generic Driver)


  • 거의 사용되지 않는 모드
  • UDP Tunnel networking과 VDE(Virtual Distributed Ethernet) 지원






Posted by Steven J.S Min

댓글을 달아 주세요

초기 CentOS8을 VirtualBox에 설치후, 기본적으로 필요한 설정 내용을 정리함.


  • Guest Editions 설치에 필요한 패키지 설치

>> sudo dnf install -y elfutils-libelf-devel

>> Devices > Insert Guest Additions CD Image… —> 필요에따라서 VBoxGuestAddtion.iso 파일을 다운받아 마운

:: 작업을 위해서는 처음 Linux 설치시 devel-tool 추가 선택해서 설치해줘야한다.



  • VirtualBox Network 설정

>> Bridged Adapter 설정 : 해당 모드는 가상 머신의 네트워크를 Host PC  동등 수준으로 구성할 있게 해준다

            :: 예를 들어 Host PC 네트워크가 192.168.0.2 설정이 되어 있다면 가상 머신의 네트워크 또한 192.168.0.4 정도로 설정됨.



  • SSH 접속 허용 가능하도록 설정

>> firewall-cmd --permanent --zone=public --add-port=22/tcp



  • /etc/profile.d/에 커스텀 Shell파일 생성 --> PS1 프롬프트 변경/기본 Global Var설정

export export PS1='\h \[\e[32m\u\] \[\e[36m\W\] \[\e[33m\]\[\e[1m\]$ \[\e[0m\]'


export JAVA_HOME="/app/java/jdk"

export JRE_HOME="/app/java/jdk/jre"


export PATH=$PATH:/app/oc:$JAVA_HOME/bin


alias vi=vim


** 위의 내용은 나 개인의 어플리케이션에 종속된 설정입니다.



  • EPEL 리포지토리 설치

Configuration 패키지 설치

>> dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm


패키지가 설치되었는지 확인

>> rpm -ql epel-release


EPEL Repository Enable되었는지 확인

>> dnf repolist -v


EPEL Repository 포함된 패키지 체크

>> dnf repository-packages epel list



  • Hostname 변경

>> hostnamectl set-hostname workstation

>> /etc/hosts Host Alias이름 추가



  • Host Guest 공유폴더 설정 

- Virtualbox에서 지정된 Guest서버에서설정 —> 공유폴더에서  공유폴더 설정 ==> SharedFolder

- 게스트확장 설치 —> 위에서 “sudo dnf install -y elfutils-libelf-devel” 통해서 이미 마운트 되어 있을수 있다.

- 게스트에서 다음 명령 실행

>> mount /dev/cdrom /media (readonly 에러는 무시)

- 게스트 에디션 설치

>> yum update kernel*

>> yum install gcc kernel-devel kernel-headers dkms make bzip2 perl

>> /media/VBoxLinuxAdditions.run



/media 폴더에서 나온 umount /media



>> mount -t vboxsf SharedFolder /SharedFolder



- 재부팅 자동 적용 되도록 명령어 추가

       >> vi /etc/fstab (파일 열어서 수정)

       >> 아래 다음행 추가 “SharedFolder /SharedFolder  vboxsf   nodev,noexec,nosuid 0 0”



  • 접속하려는 서버에 SSH Public 키 복사 

>> ssh-copy-id -i ~/.ssh/id_rsa.pub mins1@192.168.0.218    —> 또는 steven.pub 

>> ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.218       —> 또는 steven.pub 



  • .ssh/config 파일 생성 

# STEVEN Virtual Box ==============================================
Host workstation
HostName 192.168.0.50
User root
Port 22
IdentityFile ~/.ssh/id_rsa

Host server1
HostName 192.168.0.83
User root
Port 22
IdentityFile ~/.ssh/id_rsa

Host server2
HostName 192.168.0.20
User root
Port 22
IdentityFile ~/.ssh/id_rsa


Host centos8
HostName 192.168.0.218
User root
Port 22
IdentityFile ~/.ssh/id_rsa

# COMMON ==========================================================
Host git-codecommit.*.amazonaws.com
User {AWS IAM KEY}
IdentityFile ~/.ssh/id_rsa

Host github.com
HostName github.com
IdentityFile ~/.ssh/id_rsa
User stevenjsmin

Host gitlab.com
HostName gitlab.com
IdentityFile ~/.ssh/id_rsa User stevenjsmin



  • 파이선2/3 설치 그리고 기본 Python 설정

>> sudo dnf install python3

>> sudo dnf install python2

>> sudo alternatives --set python /usr/bin/python3


  • Ansible 설치 그리고 Python 설정

>> sudo dnf install ansible


그리고 명시적으로 Ansible이  Python3를 사용하도록 하기위해서는 ansible.cfg 파일에 다음 항목 설정

ansible_python_interpreter=/usr/bin/python3

참조 :: https://docs.ansible.com/ansible/latest/reference_appendices/python_3_support.html

  • 일반사용자 Sudo User만들기

>> usermod -aG wheel username



  • 일반사용자(Ansible remote_user)를 Sudo사용시 비빌번호 없이 수행하도록  Escalation 설정

>> usermod -aG wheel username

>> 아래의 두가지 방법 중 하나 선택

1. /etc/sudoers파일에서 

   %wheel         ALL=(ALL)       NOPASSWD: ALL             

와 같이 설정해서 모든 wheel 그룹의 사용자가 비밀번호 없이 sudo 사용하도록 설정

또는

적절한 지시문이있는 파일을 /etc/sudoers.d/파일에 아래와 같이 생성

   ## password-less sudo for Ansible user                       

   username     ALL=(ALL)       NOPASSWD: ALL              



  • VirtualBox 포트 Forwarding 설정

>> firewall-cmd --zone=public --add-port=9999/tcp --permanent

>> firewall-cmd --zone=public --add-service=http --permanent

>> firewall-cmd --reload


그리고 VirtualBox의 Gust OS Networ설정에서 포트를 80 --> 9999로 설정하면 "http://127.0.0.1:80"으로 요청하면 Guest의 9999포트로 연결된다.

*** Guest IP로 연결하면 안된다.



  • 추가 Applicaiton 및 소프트웨어 구성

/app 에 모두 설치


centos8 root /app $ ll

total 0

lrwxrwxrwx. 1 root root   20 Nov 26 16:06 apache-tomcat -> apache-tomcat-9.0.22

drwxr-xr-x. 9  root root 235 Nov 27 09:41 apache-tomcat-9.0.22

drwxr-xr-x. 3  root root   37 Nov 27 09:15 java

drwxr-xr-x. 7  root root 147 Mar 21 15:48 jenkins_2.176.2

drwxr-xr-x. 2  root root   63 Nov 14 16:46 oc



  • GIT 클라이언트 설치 및 설정

>> dnf install git

>> git config --global user.name "Steven Min"

>> git config --global user.email "steven.jsmin@gmail.com"

>> git config --list


** Git서버에 Public key 등록 "Settings --> SSH and GPG Keys --> New SSH Key"



  • VM Start with "Headless" mode as default

>> VBoxManage modifyvm "<<VM Name>>" --defaultfrontend headless



Posted by Steven J.S Min

댓글을 달아 주세요

1. 자신의 PC에 공개키와 비밀키 쌍을 생성

$ ssh-keygen


2. [k-name]과 [k-name].pub 이라는 키 쌍이 생성된다

    • steven
    • steven.pub

3. 이 공개키(steven.pub)를 서버에 등록하여야 한다.   

$ scp steven.pub jenkins@52.78.151.36:/tmp/

또는 아래 설명된 ssh-copy-id 명령 사용


4. 이 공개키를 인증할 때 사용하기 위해 키의 내용을 ~/.ssh/authorized_keys 라는 파일에 추가하여야 한다.

$ ssh jenkins@52.78.151.36

$ cat /tmp/steven.pub >> ~/.ssh/authorized_keys



5. .ssh 디렉토리 내의 모든 파일을 읽고 쓸 수 없도록 권한을 설정 (600)



6. 하나의 키에 대해서 특정 명령어만 실행할 수 있게 설정도 가능   

    • ~/.ssh/authorized_keys 파일을 연 후
    • 아래와 같이 해당 공개키 앞에 특정 명령어열을 추가해주면 된다.
    • command="scp -f /var/log/access.log" ssh-rsa AAA...  

설정하면 해당 비밀키로는 /var/log/access.log 파일을 scp 명령어로 복사해오는 것 밖에 하지 못하게 된다.




---------------------


SSH key 동작방식

SSH 서버는 여러가지 방법으로 클라이언트를 인증할 수 있다. 그 중 가장 기본적인 방법은 패스워드를 사용하는 것으로 사용하기 쉽지만 가장 안전한 인증방법은 아니다.
비록 패스워드는 암호화되어 서버로 보내지지만 꾸준하고 반복적인 해커의 공격에 안전할만큼 복잡하거나 길지 않은 경우가 거의 대부분이다. 컴퓨팅 파워가 비약적으로 발전했기 때문에 자동화 된 스크립트를 사용한 brute-force 공격에 취약할 수 밖에 없다. 다른 추가적인 보안박식들도 있지만 SSH key가 가장 안정적이고 안전한 검증된 인증방식이다.

SSH 키 페어는 두개의 암호키로 SSH 서버가 클라이언트를 인증하는데 사용될 수 있다. 각 키 페어는 public 키와 private 키로 이루어진다.

Private 키는 클라이언트가 가지고 있고, 이 키는 절대적인 비밀(누구에게도 복사해 주거나 공개하면 안됨)로 해야만 한다. 어떤 식으로건 private 키가 알려지는 순간 공격자는 그 쌍이 되는 public 키로 설정된 서버에 아무 추가적인 인증 없이 로그인이 가능해진다. 추가적인 예방조치로 private 키를 passphrase로 암호화 해서 디스크에 저장할 수 있다.

쌍이 되는 public 키는 아무 걱정 없이 자유롭게 누구에게든 공유할 수 있다. Public 키로 메시지를 암호화 할 수 있는데, 그 암호화 된 메시지는 그 쌍이 되는 private 키로만 해석할 수 있다. (암호화에 사용한 public 키로도 암호화 된 메시지를 해석할 수 없다) 이런 특성이 키 페어를 사용한 인증방식에 사용된다.

Public 키는 SSH로 로그인하길 원하는 원격 서버에 업로드된다. 이 키는 사용자 어카운트의 ~/.ssh/authorized_keys 라는 특별한 파일에 추가된다.

클라이언트가 SSH key를 사용해 인증하려고 시도하면, 서버는 클라이언트가 private 키를 가지고 있는지 여부를 테스트 할 수 있다. 클라이언트가 private 키를 가지고 있는걸 증명하면 쉘 세션이 생성되거나 요구된 명령을 실행한다.
이 전체적인 흐름은 다음과 같다.


1. 클라이언트가 서버에 SSH 연결을 요청한다.
2. 서버는 랜덤 챌린지(랜덤 데이터 스트링)를 생성해 클라이언트에게 보낸다.
3. 클라이언트는 서버로 부터 받은 챌린지(C)를 자신이 가지고 있는 private 키로 암호화해서 암호화 된 메시지를 서버로 보낸다.
4. 서버는 클라이언트에서 받은 암호화 된 메시지를 public 키로 해석한 후 그 결과를 2단계에서 자신이 클라이언트에게 보낸 랜덤 챌린지와 일치하는지 확인한다. (public 키로 해석할 수 있는 메시지는 그 쌍이 되는 private 키를 가진 사람만이 만들 수 있기 때문) 일치하면 클라이언트가 인증된 것이다.

SSH 키 만들기

서버가 SSH 키 인증을 사용하도록 설정하려면 가장 먼저 해야 하는 일은 클라이언트에서 키 페어를 만드는 것이다.
키 페어를 만들려면 OpenSSH에 포함되어 있는 ssh-keygen 유틸리티를 사용한다. 디폴트로 2048-bit RSA 키 페어를 만들게 되어 있는데, 대부분의 사용자에게 이 정도면 충분하다.

클라이언트에서 ssh-keygen을 실행해 SSH 키 페어를 만든다.

$ ssh-keygen

Generating public/private rsa key pair.
Enter file in which to save the key (/home/test/.ssh/id_rsa):

프로그램이 생성될 키를 저장할 위치를 선택하도록 물어본다. 디폴트로 ~/.ssh 디렉토리에 저장하게 되어 있다. Private 키는 id_rsa라는 이름이고 public 키는 id_rsa.pub라는 이름을 사용한다. 일반적으로 디폴트를 그대로 사용하는게 좋다. 별도 디렉토리를 사용하려면 원하는 위치를 입력하고, 그냥 디폴트를 사용하려면 엔터를 누르면 된다.

만일 이전에 만들어 놓은 SSH 키가 있다면 다음과 같은 내용을 보게 될 것이다.

/home/test/.ssh/id_rsa already exists.
Overwrite (y/n)?

덮어쓰기를 선택하면 이전 키를 사용하는 인증은 더 이상 사용할 수 없게 된다. 이 단계는 되돌릴 수 없으므로 yes를 선택하려면 매우 주의해야 한다.

Created directory '/home/test/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

다음으로 키에 대한 passphrase를 물어본다. Passphrase는 옵션으로 private 키를 디스크에 저장할 때 암호화 하는데 사용된다.
어짜피 passphrase를 입력해야 한다면 SSH 키를 사용하는 장점이 무엇인가 궁금할 수 있을 것이다. 몇가지 장점을 나열하자면...

* Private SSH키(passphrase로 보호되는 부분)는 네트웍 상에 절대로 노출되지 않는다. Passphrase는 로컬머신상에서 private 키를 해석하는데만 사용된다. 그러므로 passphrase에 대한 네트웍 기반의 brute-force 공격이 불가능해 진다.
* Private 키는 제한된 디렉토리내에서만 보관된다. SSH 클라이언트는 제한된 디렉토리에 보관되지 않는 private 키는 인식하지 않는다. 또한 키 자체는 제한된 퍼미션을 가져야만 한다. (owner만 rw가 가능) 즉 시스템의 다른 사용자가 볼 수 없다는걸 의미한다.
* Private SSH 키의 passphrase를 탈취하려는 해커는 이미 시스템을 억세스 할 수 있어야 한다. 즉 해커가 이미 시스템의 사용자 어카운트나 루트 어카운트에 억세스 할 수 있다는걸 의미한다. 이 경우 passphrase를 사용하면 해커가 즉각 다른 서버에 로그인 하는걸 막아줄 수 있다. 즉 새로운 SSH key 쌍을 만들고 이미 탈취당한 키는 삭제할 수 있는 시간을 벌어줄 수 있다.

Private 키는 절대 네트웍에 노출되지 않고 파일 퍼미션으로 보호되기 때문에 당신(과 루트유저) 이외에는 이 파일에 접근할 수 없다.
Passphrase는 옵션이기 때문에 입력해주면 이후에는 (SSH agent를 사용하지 않는 한) 이 키를 사용할 때 마다 passphrase를 입력해 줘야 한다. Passphrase를 사용하는걸 권장하지만, 원하지 않는다면 그냥 엔터를 눌러주면 된다.

Your identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is:
a9:49:2e:2a:5e:33:3e:a9:de:4e:77:11:58:b6:90:26 username@remote_host
The key's randomart image is:
+--[ RSA 2048]----+
|     ..o         |
|   E o= .        |
|    o. o         |
|        ..       |
|      ..S        |
|     o o.        |
|   =o.+.         |
|. =++..          |
|o=++.            |
+-----------------+  


이제 인증에 사용할 수 있는 private 키와 public 키 쌍을 만들었다. 다음 단계는 public키를 서버에 넣어줘 SSH key를 인증에 사용할 수 있게 해 주는 것이다.


서버에 public 키를 카피하기 :: SSH-Copy-ID

서버에 public키를 복사하는 가장 쉬운 방법은 ssh-copy-id 라는 유틸리티를 사용하는 것이다. 간단하기 때문에 가능하다면 가장 권장하는 방법이다. ssh-copy-id는 OpenSSH 패키지에 들어있기 때문에 로컬 시스템에 이미 설치되어 있을 가능성이 크다. 이 방식을 사용하려면 먼저 서버에 패스워드로 ssh 억세스가 가능해야만 한다.
이 유틸리티를 사용하려면 연결하려는 원격 호스트 이름과 유저 어카운트를 지정해 주면 된다. 

$ ssh-copy-id test@foo.bar.com

명령을 입력하면 다음과 같은 메시지가 출력된다. 

The authenticity of host 'foo.bar.com (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

메시지의 내용은 로컬 컴퓨터가 원격 컴퓨터를 식별할 수 없다는 의미이다. 새 호스트에 처음으로 접속하는 경우 발생한다. 'yes'와 엔터를 눌러 계속 진행한다.
유틸리티가 로컬 어카운트의 기존에 만들어 놓은 id_rsa.pub 키를 찾는다. 키를 찾으면 원격 컴퓨터의 유저 어카운트 패스워드를 묻는다. (예에서는 foo.bar.com 서버의 test 어카운트의 암호)

/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
test@foo.bar.com's password:

암호를 입력하고 엔터를 누르면 유틸리티는 입력한 암호를 사용해 원격 호스트의 어카운트에 연결한다. 그리고 로컬 어카운트에 있는 ~/.ssh/id_rsa.pub 키파일의 내용을 원격 호스트 어카운트의 ~/.ssh 디렉토리에 있는 authorized_keys 에 복사한다.

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'test@foo.bar.com'"
and check to make sure that only the key(s) you wanted were added.

이제 자신의 id_rsa.pub 파일이 서버에 업로드 된 것이다.

- 수동으로 복사

로컬 머신 어카운트의 id_rsa.pub 키 파일 내용을 SSH로 로그인하길 원하는 서버 어카운트의 ~/.ssh/authorized_keys 파일에 복사해 넣어주면 된다.

먼저 id_rsa.pub 키 파일 내용을 화면에 출력한다.

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqql6MzstZYh1TmWWv11q5O3pISj2ZFl9HgH1JLknLLx44+tXfJ7mIrKNxOOwxIxvcBF8PXSYvobFYEZjGIVCEAjrUzLiIxbyCoxVyle7Q+bqgZ8SeeM8wzytsY+dVGcBxF6N4JS+zVk5eMcV385gG3Y6ON3EG112n6d+SMXY0OEBIcO6x+PnUSGHrSgpBgX7Ks1r7xqFa7heJLLt2wWwkARptX7udSq05paBhcpB0pHtA1Rfz3K2B+ZVIpSDfki9UVKzT8JUmwW6NNzSgxUfQHGwnW7kj4jp4AT0VZk3ADw497M2G/12N0PPB5CnhHf7ovgy6nL1ikrygTKRFmNZISvAcywB9GVqNAVE+ZHDSCuURNsAInVzgYo9xgJDW8wUw2o8U77+xiFxgI5QSZX3Iq7YLMgeksaO4rBJEa54k8m5wEiEE1nUhLuJ0X/vh2xPff6SQ1BL/zkOhvJCACK6Vb15mDOeCSq54Cr7kvS46itMosi/uS66+PujOO+xt/2FWYepz6ZlN70bRly57Q06J+ZJoc9FfBCbCyYH7U/ASsmY095ywPsBo1XQ9PqhnN1/YOorJ068foQDNVpm146mUpILVxmq41Cj55YKHEazXGsdBIbXWhcrRf4G2fJLRcGUr9q8/lERo9oxRm5JFX6TCmj6kmiFqv+Ow9gI0x8GvaQ== test@localhost

원격 호스트에 로그인 한 다음 먼저 홈 디렉토리에 .ssh 디렉토리가 만들어 져 있는가 확인한다. 만일 없다면 다음 명령으로 만들어준다.

mkdir ~/.ssh

이제 .ssh 디렉토리 안에 authorized_key 파일이 없으면 만들고, 이미 존재하면 파일 내용에 추가해주면 된다.

echo [public_key_string] >> ~/.ssh/authorized_keys

위의 명령에서 빨간색 [public_key_string] 부분은 위의 cat 명령에서 출력된 결과로 바꿔줘야 한다.  (위에서 노란색으로 칠해진 부분)

SSH 키를 사용해 서버에 로그인하기

서버에 public 키를 카피해 놓았다면 원격 호스트에 로그인 할 어카운트의 암호 없이 로그인이 가능하다. 로그인 절차는 완전 동일하다.

ssh test@foo.bar.com

만일 이 호스트에 SSH로 첫번째 접속하는 것이면 다음과 같은 메시지를 보게 될 것이다.

The authenticity of host 'foo.bar.com (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
  
메시지의 내용은 로컬 컴퓨터가 원격 컴퓨터를 식별할 수 없다는 의미이다. 새 호스트에 처음으로 접속하는 경우 발생한다. 'yes'와 엔터를 눌러 계속 진행한다.

Private 키에 passphrase를 지정해 주지 않았다면 곧바로 로그인이 된다. 만일 키 쌍을 만들 때 private 키에 passphrase를 지정해 주었다면 passphrase를 물어본다. 인증이 성공되면 쉘 세션이 열리게 된다.







Posted by Steven J.S Min

댓글을 달아 주세요

SRC:  정광섭, https://www.lesstif.com/pages/viewpage.action?pageId=12451848

증 상

Java 에서 HTTPS 로 remote 사이트에 연결시 다음과 같은 Exception 이 발생

error log

Caused by: javax.naming.CommunicationException: simple bind failed: <server-name>

[Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target\]


원 인

다음과 같이 여러 가지 원인이 있을 수 있다.

  • 연결하려는 remote site의 인증서가 신뢰하는 인증기관 인증서 목록(keystore)에 없음

  • 서버/클라이언트간 사용하려는 SSL/TLS 버전이 맞지 않음(Ex:TLS 1.0 만 지원하는 서버에 1.2로 hand shaking 요청등)

  • SSL/TLS 통신에 사용하려는 cipher suite 가 오래되거나 지원하지 않음. (Ex: JDK 1.8 부터는 RC4 를 사용하려고 하면 에러 발생)

  • 웹 브라우저의 경우 인증서 경로 설정을 참고하여 웹 서버에 Intermediate CA certificate 를 설치한다.

무료 SSL 인증서를 발급해 주는 Let's encrypt 의 CA 인증서는 Java VM 에 포함되어 있지 않으므로 Let's encrypt 에서 발급 받은 SSL 인증서를 Java 에서 사용할 경우에도 위와 같은 에러가 발생한다.


해 결

1번 원인일 경우 현재 구동되는 JDK 의 keystore에 상대방 인증서를 넣어줘야 함



1. gist 에서 InstallCert.Java 를 다운로드

    2. 컴파일


    3. InstallCert 구동

    # localhost 에 SSL 인증서를 받아올 호스트명을 입력

    java -cp ./ InstallCert  git.nbnco.net.au


    4. 다음과 같은 화면이 나오면 1을 눌러서 인증서 저장

    ssl import

    Caused by: java.lang.UnsupportedOperationException
    at InstallCert$SavingTrustManager.getAcceptedIssuers(InstallCert.java:183)
    at sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(SSLContextImpl.java:926)
    at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:872)
    at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:814)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
    ... 2 more

    Server sent 2 certificate(s):

    1 Subject CN=wiki.modernpug.org
    Issuer CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
    sha1 47 0a 15 c4 5d ed 62 0a 4b 18 d5 d8 58 14 42 5d 36 e0 d5 8f 
    md5 3a 0d ab ce 27 be dd bd e5 c1 d5 e8 b6 25 aa eb

    2 Subject CN=Let's Encrypt Authority X3, O=Let's Encrypt, C=US
    Issuer CN=DST Root CA X3, O=Digital Signature Trust Co.
    sha1 e6 a3 b4 5b 06 2d 50 9b 33 82 28 2d 19 6e fe 97 d5 95 6c cb 
    md5 b1 54 09 27 4f 54 ad 8f 02 3d 3b 85 a5 ec ec 5d

    Enter certificate to add to trusted keystore or 'q' to quit: [1]
    2

    서버가 2 개의 인증서를 전송했는데 2번째가 Let's Encrypt 의 CA 인증서이므로 2번을 선택해서 저장해야 한다.


    5. 다음과 같은 메시지가 나오고 저장됨. keystore 명과 alias 명을 기억

    Added certificate to keystore 'jssecacerts' using alias 'letsencrypt'

    6. keytool 로 keystore에서 인증서 추출 (KeyStore의 암호는 changeit 이라 가정!)

    ## alias 옵션뒤에 위의 alias명 입력

    keytool -exportcert -keystore jssecacerts -storepass changeit -file output.cert -alias letsencrypt

    -alias 옵션 뒤에 파라미터는 5번에서 저장된 alias(letsencrypt) 를 입력


    7. 현재 JDK 의 keystore에 cert import

    ## JAVA_HOME=/usr/java/jdk1.7.0_25

    keytool -importcert -keystore ${JAVA_HOME}/jre/lib/security/cacerts -storepass changeit -file output.cert -alias letsencrypt

    이미 존재할 경우 다음 명령어로 삭제

    keytool -delete -alias letsencrypt -keystore ${JAVA_HOME}/jre/lib/security/cacerts -storepass changeit



같이 보기



Posted by Steven J.S Min

댓글을 달아 주세요