반응형

VMware 에서 설치한 CentOS 6.4 네트워크 오류

OS 2013.09.02 11:22

VMware 에서 설치한 CentOS 6.4 를 이미지를 복제한 뒤에, 네트워크를 설정하다보면 다음과 같은 오류가 발생합니다.

 

$ service network restart
Shutting down loopback interface:                          [  OK  ]
Bringing up loopback interface:                            [  OK  ]
Bringing up interface eth0:  Device eth0 does not seem to be present, delaying initialization.
                                                           [FAILED]

이는 가상화 이미지를 복제할 때 ethernet adapter 의 MAC 주소가 바뀌기 때문에 발생하는 것입니다.

CentOS 에서는 이 때 ethernet adapter 를 새로 한개 더 추가해서 eth0 가 아닌 eth1 로 잡습니다.

이는 다음과 같이 확인해 볼 수 있습니다.

$ ls /sys/classs/net
eth1     lo

불필요한 ethernet adapter 를 삭제해주기 위해서, 장치 관리자가 자동으로 생성한 규칙 파일을 편집합니다.

해당 파일은 /etc/udev/rules.d/70-persistent-net.rules 입니다.

$ vi /etc/udev/rules.d/70-persistent-net.rules

# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

# PCI device 0x8086:0x100f (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:2c:ff:a7", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

# PCI device 0x8086:0x100f (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:da:06:f2", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

실제로 가상화 이미지의 ethernet adapter 의 MAC 주소를 확인해보면 00:0c:29:da:06:f2 확인될 것입니다.

위의 파일 내용에서 NAME="eth0" 항목을 삭제하고, NAME="eth1" 의 이름을 "eth0" 으로 바꿉니다.

# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

# PCI device 0x8086:0x100f (e1000)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:da:06:f2", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

/etc/sysconfig/network-scripts/ifcfg-eth0 를 수정합니다.

여기에 MAC 주소가 이전의 것으로 지정되어 있으므로, 새로운 MAC 주소로 설정합니다.

참고: http://netmaid.tistory.com/91

 

그리고 시스템을 리부팅합니다.

 

참고:

 

출처: <http://netmaid.tistory.com/94>

반응형
반응형

여기에 VirtualBox를 설치하였고,

VirtualBox 에 리눅스(Fedora)를 설치하였습니다.

 

한줄요약 : 윈도우에서 VirtualBox를 이용해 리눅스를 돌리고 있음.

위와같이 리눅스를 설치하고 윈도우에서 putty 를 이용해 리눅스에 ssh로 접속하여 작업합니다.

 

쉬운 브리지 어댑터 먼저 썰을 풉니다~

 

1. 브리지 어댑터 (Bridge Adapter)

Virtualbox 에서 Fedora를 실행하기 전에 아래와 같이 네트워크에서 브리지 어댑터를 선택합니다.

(아래 이미지는 리눅스를 실행한 후에 캡쳐를 한 것인데 실행 전에 선택해야합니다.)

 

 

 

이 경우, PC가 공유기로부터 IP를 받는 경우,

리눅스 또한 공유기로부터 IP를 받습니다.

 

윈도우의 IP가 192.168.10.xx 라면, 리눅스의 IP 또한 192.168.10.xx 가 됩니다.

 

브리지 어댑터로 설정하면 아래와 같은 구조라고 생각하면 됩니다.

 

 

문제점 :

위에 언급했듯이 전 윈도우에서 putty 를 이용해 리눅스에 접속하는 걸 선호합니다.

브리지 네트워크로 설정할 경우, 공유기가 없다면? 리눅스가 IP를 할당받지 못해

윈도우에서 리눅스로 접속할 방법이 없더군요.

공유기를 함께 챙기면 되겠지만 그러지 못한 상황이라면...

 

NAT 설정을 통해 이를 극복할 수 있습니다.

 

2. NAT

NAT의 개념은 저도 정확히 이거다 말하기가 애매한데요. 그냥, 경험을 통해 아~ 이렇구나 했습니다.

아니면 댓글로 알려주세요~

 

NAT 설정은 저 위에 Virtualbox 네트워크 설정에서 브리지 어댑터 대신 NAT를 선택하면 됩니다.

 

Virtualbox 를 설치하면 dos 에서 VirtualBox Host-Only Network 를 확인할 수 있습니다.

C:\> ipconfig

 

결론부터 얘기하면, 윈도우에서 리눅스로 접속하고 싶을 때,

위 주소 192.168.56.1 로 접속하여 리눅스로 접속할 수 있습니다.

 

(이 개념 찾는게 제일 힘들었네요. 전 계속 리눅스의 10.0.2.15로 접속하려고 시도했거든요.

그런데 막상 검색해도 쉽게 안나오던 정보였습니다.)

 

이에 몇가지 설정이 필요합니다.

 

VirtualBox 에서 NAT 로 설정한 후, 리눅스를 설치하고 ifconfig 하면

아래와 같이 10.0.x.15 주소를 확인할 수 있습니다.

 

 

 

이 주소는 NAT 설정 후 나타나는 주소입니다.

 

저 위에 윈도우에서 리눅스로 접속하기 위해 192.168.56.1 IP 를 사용한다고 했는데요.

이 192.168.56.1 이 리눅스의 10.0.2.15 IP와 연결되게 됩니다.

 

그러므로 윈도우에서 10.0.2.15 192.168.56.1 로 접속을 시도하면 리눅스로 연결되게 됩니다.

 

이제 NAT 설정 시, 그림을 다시 그려보면 아래와 같이 됩니다.

(이 개념은 지극히 개인적인... 고로 틀렸을지도 모릅니다. ㅜ.ㅠ )

 

브리지 어댑터의 경우, linux 가 바로 공유기에 연결된 개념이었는데

NAT의 경우, 위와 같은 구조이기에 공유기랑 상관없는 구조입니다.

공유기가 없는 환경에서 리눅스에 접속할 필요가 있을 경우, NAT를 사용하면 되겠지요~

 

이제 마지막 과정입니다.

192.168.56.1 과 10.0.2.15 사이에 포트포워딩을 해 주어야 합니다.

 

아래와 같이 포트포워딩을 선택합니다.

 

 

 

그러면 아래와 같은 그림이 나옵니다.

아래 제가 설정한 경우입니다.

 

이미지 오른쪽의 + 버튼을 클릭하여 규칙을 추가하시면 됩니다.

 

 

 

전 putty 를 이용해 리눅스에 접속하여 작업하기에 22번 포트를 포워딩했습니다.

그리고 리눅스에서 인터넷을 사용하기 위해 80번 포트를 포워딩했습니다.

 

기타 환경에 맞게 추가하여 주시면 됩니다.

 

위와 같이 설정한 후에 putty에서 192.168.56.1 로 접속시도하면 리눅스로 연결됩니다.

 

출처: <http://web3.c2.cyworld.com/myhompy/board/retrieveBoard.php?home_id=a1099643&lmenuSeq=194400&smenuSeq=152571&postSeq=7341859&referrer=http%3A%2F%2Fsearch.naver.com%2Fsearch.naver%3Fwhere%3Dnexearch%26query%3Dvirtualbox%2Bnat%2B%25EC%2584%25A4%25EC%25A0%2595%26sm%3Dtop_hty%26fbm%3D1%26ie%3Dutf8>

 

반응형

'오픈소스 활용하기' 카테고리의 다른 글

대표적인 개인 서버 전용 웹 스토리지 비교  (2) 2023.11.27
KVM 설치 가이드  (1) 2023.11.13
가상 머신과 Docker  (2) 2023.11.13
Docker란 무엇인가?  (1) 2023.11.13
Zabbix server config 파라메터  (1) 2023.11.09
반응형

본 설치 가이드는 공개SW 역량프라자에서 클라우드 컴퓨팅 기반 기술 중 가상화(Virtualization)에 대한 테스트 결과 보고서 외에 테스트 환경에 대한 이해를 돕고자 작성되었습니다.

모든 테스트 환경 구성에 대한 내용을 포함되어 있지 않으며, 주의가 필요하거나 참고해야 할 내용을 기반으로 작성되었습니다.

1. 설치환경

□ KVM 환경

모듈 Version
KVM 2.6.32 (Linux Kernel)
qemu-kvm 0.12.1
Virt-Manager 0.9.0.7

□ Stack 환경

구성 Host OS Guest OS
A Stack Ubuntu 10.04 Desktop LTS (64bit) CentOS 6.2 Windows 7
B Stack CentOS 6.2 (64bit) Ubuntu 12.04 Windows 7

□ HW 환경

제조사 모델명 CPU MEM Disk NIC
IBM X3850M2 Intel Xeon(R)CPU 2.40GHz * 4 8GB 320G Gigabit 1Port

 

2. CentOS 기반 KVM 설치

□ CentOS 설치 및 환경

o 패키지 선택

CentOS 설치 과정 중 아래의 그림과 같이 서버 용도에 맞는 패키지를 선택할 수 있는데 이번 테스트의 경우 가상화 관리 도구(Virt-Manager)이 GUI(Graphic User Interface)로 구성되어 Desktop을 선택하여 설치하였으며, 나머지 진행은 기본 설정을 기준으로 진행하였음

 

□ CentOS 설정

o SELinux 해제

vi /etc/selinux/config

# This file controls the state of SELinux on the system.

# SELINUX= can take one of these three values:

#     enforcing - SELinux security policy is enforced.

#     permissive - SELinux prints warnings instead of enforcing.

#     disabled - No SELinux policy is loaded.

#SELINUX=enforcing

# 아래의 내용으로 변경함

SELINUX=disabled

# SELINUXTYPE= can take one of these two values:

#     targeted - Targeted processes are protected,

#     mls - Multi Level Security protection.

SELINUXTYPE=targeted


reboot;

□ 가상화 지원 여부 확인

최근에 출시하는 Intel(VT-x), AMD(AMD-v) 계열의 프로세서는 대부분 하드웨어 가상화를 지원하며, 지원되지 않은 CPU일 경우 가상화를 원활히 사용할 수 없음

# intel cpu : vmx(Intel-VT), AMD cpu : svm(AMD-V)

egrep '(vmx|svm)' --color=always /proc/cpuinfo

o 아래 결과 중 빨간색(vmx)로 표시되면, CPU가 가상화 지원

 

□ KVM 환경 구성

o 참고사항

CentOS 6.2 버전의 경우 커널에 KVM이 기본적으로 포함되어 배포되어 별도의 설치가 필요 없이 사용 가능함

# KVM 설치 여부 확인

lsmod | grep kvm

#아래와 같이 표시되면 KVM이 설치되어 있음

kvm_intel      50380 0

kvm            305081 1 kvm_intel

o KVM 관련 패키지 설치

yum groupinstall "Virtualization*"

o KVM 관련 패키지 설치

- qemu-kvm

- qemu-img

- libvirt Library

- virt-manager

o 설치 확인

- 프로그램->시스템도구->가상 머신 관리자 선택

 

o 설치 확인

- 가상 머신 관리자(Virt-Manager) 구동 확인

※ 실제 처음 설치할 경우 등록된 가상 머신은 없음

 

3. Ubuntu 기반 KVM 설치

□ Ubuntu 설치

가상화 관리 도구(Virt-Manager)를 활용하기 위하여, Ubuntu 10.04 Desktop LTS 버전을 설치하였으며, 기본 설치 과정을 준수하여 설치하였음

 

□ 가상화 지원 여부 확인

최근에 출시하는 Intel(VT-x), AMD(AMD-v) 계열의 프로세서는 대부분 하드웨어 가상화를 지원하며, 지원되지 않은 CPU일 경우 가상화를 원활히 사용할 수 없음

# intel cpu : vmx(Intel-VT), AMD cpu : svm(AMD-V)

egrep '(vmx|svm)' --color=always /proc/cpuinfo

o 아래 결과 중 빨간색(vmx)로 표시되면, CPU가 가상화 지원

 

□ KVM 환경 구성

o KVM관련 패키지를 설치

$ sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils

o KVM관련 패키지를 설치

$ virsh -c qemu:///system list

# 아래와 같이 나타나면 정상적으로 설치됨

Id Name                 State

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

- 위와 같이 나오지 않고 아래의 내용과 같이 에러가 발생할 경우

$ virsh -c qemu:///system list

libvir: Remote error : Permission denied

error: failed to connect to the hypervisor

$

/var/run/libvirt/libvirt-sock 파일의 접근 권한 확인 필요

o 가상화 관리 도구(virt-manager) 설치

$ sudo apt-get install virt-manager

o 설치 확인

- Search 입력창에 virtual machine manager 입력

- 가상 머신 관리자(Virt-Manager) 구동 확인

※ 실제 처음 설치할 경우 등록된 가상 머신은 없음

 

원본 위치 <http://www.oss.kr/index.php?comment_srl=7728&mid=oss_repository9&order_type=desc&sort_index=readed_count&listStyle=gallery&page=4&document_srl=98713>

반응형
반응형


가상 머신과 Docker#

Docker는 지금까지 사용해왔던 VMware, Microsoft Hyper-V(Virtual PC), Xen 등의 같은 가상 머신과 비슷합니다.

가상 머신에 리눅스를 설치한 뒤 각종 서버와 DB를 설치하고, 개발한 어플리케이션이나 웹사이트를 실행했습니다. 이렇게 세팅한 가상 머신 이미지를 여러 서버에 복사해서 실행하면 이미지 하나로 서버를 계속 만들어낼 수 있었습니다.

보통 가상 머신 서버를 독자적으로 운영하거나, 서비스 형태로 제공되는 AWS, Microsoft Azure를 사용하기도 합니다.


가상 머신#

 

출처: http://www.docker.com/whatisdocker/

가상 머신은 편하긴 하지만 성능이 좋지 못한 것이 단점이었습니다. 지금까지 CPU에 가상화를 위한 기능들이 많이 추가되었지만 아직도 가상 머신은 리얼 머신에 비해 속도가 느립니다.

느린 속도를 개선하기 위해 반가상화(Paravirtualization) 방식이 개발되었고, 현재 널리 쓰이고 있습니다.

그림에서 보는 것과 같이 가상 머신이기 때문에 항상 Guest OS를 설치해야 합니다. 그래서 이미지안에 OS가 포함되기 때문에 이미지 용량이 커집니다.

아무리 네트워크와 인터넷 속도가 빨라졌다 하더라도 가상화 이미지를 주고받는 것은 꽤 부담스럽습니다.

가상 머신은 OS를 가상화하는데 초점이 맞춰져 있습니다. 그래서 이미지를 생성하는 기능만 가지고 있을 뿐 배포와 관리 기능이 부족합니다(VMware의 비싼 제품을 사용해도 되지만…).


Docker#

 

 

출처: http://www.docker.com/whatisdocker/

Docker는 반가상화보다 좀더 경량화된 방식입니다. 그림에서 보는 것과 같이 Geust OS를 설치하지 않습니다. Docker 이미지에 서버 운영에 필요한 프로그램과 라이브러리만 격리해서 설치할 수 있고, OS 자원은 호스트와 공유합니다. 이렇게 되면서 이미지 용량이 크게 줄어들었습니다. 그리고 가상화 레이어가 없기 때문에 파일시스템, 네트워크 속도도 가상 머신에 비해 월등히 빠릅니다(호스트와 거의 동일한 속도).

최근까지 Docker lxc(Linux Container) 드라이버 기반으로 동작했지만 0.9x 버전부터는 libcontainer를 사용합니다.

Docker는 가상 머신과는 달리 이미지 생성과 배포에 특화된 기능을 제공합니다.

Git에서 소스를 관리하는 것처럼 이미지 버전 관리 기능을 제공합니다. 그리고 중앙 관리를 위해 저장소에 이미지를 올리고, 받을 수 있습니다(Push/Pull). 게다가 GitHub처럼 Docker 이미지를 공유할 수 있는 Docker Hub도 제공합니다(GitHub처럼 개인 저장소도 제공합니다).

다양한 API를 제공하기 때문에 원하는 만큼 자동화를 할 수 있어 개발과 서버 운영에 매우 유용합니다.


리눅스 컨테이너#

리눅스는 운영체제 레벨에서 가상화를 제공했습니다. OS를 통째로 가상화하는 것이 아닌 리눅스 커널 레벨에서 제공하는 일종의 격리(Isolate)된 가상 공간입니다.

OS가 설치되지 않기 때문에 가상 머신이라고 하지 않고, 컨테이너라고 부릅니다.

리눅스 컨테이너는 격리된 공간만 제공할 뿐 개발 및 서버 운영에 필요한 부가기능이 부족했습니다. Docker는 리눅스 컨테이너를 기반으로 하여 편리하게 이미지를 관리하고 배포할 수 있도록 해줍니다.


Docker 이미지와 컨테이너#

Docker는 이미지와 컨테이너라는 개념이 있습니다.

이미지는 필요한 프로그램과 라이브러리, 소스를 설치한 뒤 파일로 만든 것입니다. 이 이미지를 저장소에 올리고, 받을 수 있습니다.

컨테이너는 이미지를 실행한 상태입니다. 이미지로 여러개의 컨테이너를 만들 수 있습니다. 운영체제로 보면 이미지는 실행파일이고 컨테이너는 프로세스입니다.

Docker는 특정 실행파일 또는 스크립트를 위한 실행 환경이라 보면 됩니다. 리눅스/유닉스 계열은 파일 실행에 필요한 모든 구성요소가 잘게 쪼개어져 있습니다. 시스템 구조가 단순해지고 명확해지는 장점이 있지만 의존성 관계를 해결하기가 어려워지는 단점이 있습니다. 그래서 리눅스 배포판 별로 미리 컴파일된 패키지(rpm, deb )라는 시스템이 나왔습니다. 하지만 서버를 실행할 때마다 일일이 소스를 컴파일하거나 패키지를 설치하고, 설정하려면 상당히 귀찮습니다.

서버가 한 두대라면 큰 어려움이 없겠지만 클라우드 환경에서는 서버를 몇 십, 몇 백개를 생성해야 합니다. 서버 구성을 미리 해놓은 Docker 이미지를 사용하면 실행할 서버가 몇개가 되든 손쉽게 해결할 수 있습니다.


설치하기#

이제 Docker를 설치해보겠습니다. Docker는 소스를 컴파일해서 설치하려면 준비해야할 것이 많습니다. 따라서 이 문서에서는 자동 설치 스크립트와 각 리눅스 배포판의 패키지로 설치하는 방법을 설명하겠습니다.


리눅스#

자동 설치 스크립트#

Docker는 리눅스 배포판 종류를 자동으로 인식하여 패키지를 설치해주는 스크립트를 제공합니다.

$ sudo wget -qO- https://get.docker.com/ | sh

get.docker.com 스크립트로 Docker를 설치하면 hello-world 이미지도 자동으로 설치됩니다.

hello-world 이미지는 사용하지 않을 것이므로 모두 삭제합니다.

$ sudo docker rm `sudo docker ps -aq`

$ sudo docker rmi hello-world

우분투#

자동 설치 스크립트를 사용하지 않고 우분투에서 패키지로 직접 설치하는 방법입니다.

우분투 14.04 LTS 64비트를 기준으로 하겠습니다.

$ sudo apt-get update

$ sudo apt-get install docker.io

$ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker

/usr/bin/docker.io 실행파일을 /usr/local/bin/docker로 링크해서 사용합니다.

RedHat Enterprise Linux, CentOS#

자동 설치 스크립트를 사용하지 않고, 레드햇 엔터프라이즈 리눅스(RHEL) CentOS에서 패키지로 직접 설치하는 방법입니다. RHEL CentOS 패키지 저장소에는 docker-io가 없으므로 EPEL(Fedora Extra Packages For Enterprise Linux) 저장소를 사용할 수 있도록 설정합니다.

CentOS 6

$ sudo yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

$ sudo yum install docker-io  

AWS EC2에 설치되는 Amazon Linux(CentOS 기반) EPEL 저장소를 바로 사용할 수 있으므로 epel-release-6-8.noarch.rpm은 설치하지 않아도 됩니다.

CentOS 7에서는 docker 패키지를 설치하면 됩니다.

CentOS 7

$ sudo yum install docker

Docker 서비스 실행

$ sudo service docker start

부팅했을 때 자동으로 실행하기

$ sudo chkconfig docker on


Mac OS X#

맥에서는 Boot2Docker를 이용하여 Docker를 사용할 수 있습니다.

https://github.com/boot2docker/osx-installer/releases에서 Boot2Docker-1.x.x.pkg를 받은 뒤 설치합니다.

설치는 특별한 것이 없으므로 따로 설명하지 않겠습니다(내부적으로 VirtualBox가 함께 설치됩니다).

설치가 끝난 뒤에 응용 프로그램(Applications)에서 boot2docker를 실행합니다.

잠시 기다리면 자동으로 boot2docker.iso를 이용하여 가상 머신이 생성되고, 가상 머신에 접속됩니다.


윈도우#

윈도우에서는 Boot2Docker를 이용하여 Docker를 사용할 수 있습니다.

https://github.com/boot2docker/windows-installer/releases에서 docker-install.exe를 받은 뒤 설치합니다.

  • VirtualBox를 설치하지 않았다면 VirtualBox에 체크합니다.
  • 윈도우용 Git을 설치하지 않았다면 MSYS-git UNIX tools에 체크합니다.

설치가 끝난 뒤에 바탕 화면에 생성된 Boot2Docker Start 을 실행합니다. 만약 실행 파일 선택 창이 뜨면 Git Bashsh.exe를 선택합니다.

잠시 기다리면 자동으로 boot2docker.iso를 이용하여 가상 머신이 생성되고, 가상 머신에 접속됩니다.


사용하기#

Docker의 명령은 docker rundocker push와 같이 docker <명령> 형식입니다. 그리고 항상 root 권한으로 실행해야 합니다.

먼저 Docker의 기본적인 사용법을 알아보기 위해 Docker Hub에서 제공하는 이미지를 받아서 실행해보겠습니다.


search#

Docker Docker Hub를 통해 이미지를 공유하는 생태계가 구축되어 있습니다search 명령으로 Docker Hub에서 이미지를 검색할 수 있습니다.

$ sudo docker search ubuntu

NAME                          DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED

ubuntu                        Official Ubuntu base image                      383

stackbrew/ubuntu              Official Ubuntu base image                      40

crashsystems/gitlab-docker    A trusted, regularly updated build of GitL...   19                   [OK]

dockerfile/ubuntu             Trusted Ubuntu (http://www.ubuntu.com/) Bu...   15                   [OK]

ubuntu-upstart                Upstart is an event-based replacement for ...   7

cmfatih/phantomjs             PhantomJS [ phantomjs 1.9.7, casperjs 1.1....   5                    [OK]

dockerfile/ubuntu-desktop     Trusted Ubuntu Desktop (LXDE) (http://lxde...   5                    [OK]

lukasz/docker-scala           Dockerfile for installing Scala 2.10.3, Ja...   5                    [OK]

litaio/ruby                   Ubuntu 14.04 with Ruby 2.1.2 compiled from...   5                    [OK]

엄청나게 많은 이미지가 검색될 것입니다. 보통 ubuntu, centos, redis OS나 프로그램 이름을 가진 이미지가 공식 이미지입니다. 나머지는 사용자들이 만들어 공개한 이미지입니다.

Docker Hub에서 이미지를 검색한 뒤 해당 이미지의 Tags 탭을 보면 현재 사용할 수 있는 이미지의 버전을 볼 수 있습니다.

Official Ubuntu base image Tags


pull#

우분투 이미지를 받아보겠습니다.

$ sudo docker pull ubuntu:latest

docker pull <이미지 이름>:<태그> 형식입니다. latest를 설정하면 최신 버전을 받습니다ubuntu:14.04,ubuntu:12.10처럼 태그를 지정해 줄 수도 있습니다.

이미지 이름에서 pyrasis/ubuntu처럼 / 앞에 사용자명을 지정하면 Docker Hub에서 해당 사용자가 올린 이미지를 받습니다. 공식 이미지는 사용자명이 붙지 않습니다.

 참고

호스트에 설치된 리눅스 배포판과 Docker 이미지의 배포판의 종류가 달라도 됩니다. CentOS 위에서 우분투 컨테이너를 실행할 수 있습니다.


images#

이제 받은 이미지의 목록을 출력해보겠습니다.

$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED                  VIRTUAL SIZE

ubuntu              latest              e54ca5efa2e9        Less than a second ago   276.1 MB

docker images는 모든 이미지 목록을 출력합니다docker images ubuntu처럼 이미지 이름을 설정하면 이름은 같지만태그가 다른 이미지가 출력됩니다.


run#

이미지를 컨테이너로 생성한 뒤 Bash Shell을 실행해보겠습니다.

$ sudo docker run -i -t --name hello ubuntu /bin/bash

docker run <옵션> <이미지 이름> <실행할 파일> 형식입니다. 여기서는 ubunbu 이미지를 컨테이너로 생성한 뒤 ubuntu 이미지 안의 /bin/bash를 실행합니다. 이미지 이름 대신 이미지 ID를 사용해도 됩니다.

-i(interactive), -t(Pseudo-tty) 옵션을 사용하면 실행된 Bash Shell에 입력 및 출력을 할 수 있습니다. 그리고 --name옵션으로 컨테이너의 이름을 지정할 수 있습니다. 이름을 지정하지 않으면 Docker가 자동으로 이름을 생성하여 지정합니다.

이제 호스트 OS와 완전히 격리된 공간이 생성되었습니다cdls 명령으로 컨테이너 내부를 한번 둘러봅니다. 호스트 OS와는 다르다는 것을 알 수 있습니다exit를 입력하여 Bash Shell에서 빠져나옵니다. 우분투 이미지에서 /bin/bash 실행 파일을 직접 실행했기 때문에 여기서 빠져나오면 컨테이너가 정지(stop)됩니다.

 참고

CentOS에서 아래와 같은 에러가 발생하면

unable to remount sys readonly: unable to mount sys as readonly max retries reached

/etc/sysconfig/docker 파일에서 아래와 같이 --exec-driver=lxc를 추가합니다.

/etc/sysconfig/docker

# /etc/sysconfig/docker

#

# Other arguments to pass to the docker daemon process

# These will be parsed by the sysv initscript and appended

# to the arguments list passed to docker -d

 

other_args="--selinux-enabled --exec-driver=lxc"

Docker 서비스를 재시작합니다.

$ sudo service docker restart


ps#

아래 명령을 입력하여 모든 컨테이너 목록을 출력합니다.

$ sudo docker ps -a

CONTAINER ID  IMAGE          COMMAND    CREATED        STATUS                             PORTS  NAMES

6338ce52d07c  ubuntu:latest  /bin/bash  4 seconds ago  Exited (0) Less than a second ago         hello

docker ps 형식입니다-a 옵션을 사용하면 정지된 컨테이너까지 모두 출력하고, 옵션을 사용하지 않으면 실행되고 있는 컨테이너만 출력합니다.

우리는 앞에서 컨테이너를 생성할 때 이름을 hello로 지정했으므로 컨테이너 목록에서도 hello로 표시됩니다.


start#

방금 정지한 컨테이너를 다시금 시작해보겠습니다.

$ sudo docker start hello

docker start <컨테이너 이름> 형식입니다. 컨테이너 이름 대신 컨테이너 ID를 사용해도 됩니다.

아래 명령을 입력하여 실행된 컨테이너 목록을 출력합니다.

$ sudo docker ps

CONTAINER ID  IMAGE          COMMAND    CREATED         STATUS                        PORTS  NAMES

6338ce52d07c  ubuntu:latest  /bin/bash  15 minutes ago  Up 3 seconds                         hello

hello 컨테이너가 시작되었습니다.


restart#

OS 재부팅처럼 컨테이너를 재시작해보겠습니다.

$ sudo docker restart hello

docker restart <컨테이너 이름> 형식입니다. 컨테이너 이름 대신 컨테이너 ID를 사용해도 됩니다.


attach#

이제 시작한 컨테이너에 접속해보겠습니다. 아래 명령을 실행한 뒤 엔터를 한번 더 입력하면 Bash Shell이 표시됩니다.

$ sudo docker attach hello

root@6338ce52d07c:/#

docker attach <컨테이너 이름> 형식입니다. 컨테이너 이름 대신 컨테이너 ID를 사용해도 됩니다.

우리는 /bin/bash를 실행했기 때문에 명령을 자유롭게 입력할 수 있지만, DB나 서버 어플리케이션을 실행하면 입력은 할 수 없고 출력만 보게 됩니다.

Bash Shell에서 exit 또는 Ctrl+D를 입력하면 컨테이너가 정지됩니다. 여기서는 Ctrl+PCtrl+Q를 차례대로 입력하여 컨테이너를 정지하지 않고, 컨테이너에서 빠져나옵니다.


exec#

현재 컨테이너가 /bin/bash로 실행된 상태입니다. 이번에는 /bin/bash를 통하지 않고 외부에서 컨테이너 안의 명령을 실행해보겠습니다.

$ docker exec hello echo "Hello World"

Hello World

docker exec <컨테이너 이름> <명령> <매개 변수> 형식입니다. 컨테이너 이름 대신 컨테이너 ID를 사용해도 됩니다. 컨테이너가 실행되고 있는 상태에서만 사용할 수 있으며 정지된 상태에서는 사용할 수 없습니다.

컨테이너 안의 echo 명령을 실행하고 매개 변수로 “Hello World”를 지정했기 때문에 Hello World가 출력됩니다.docker exec 명령은 이미 실행된 컨테이너에 apt-getyum 명령으로 패키지를 설치하거나, 각종 데몬을 실행할 때 활용할 수 있습니다.


stop#

이번에는 컨테이너를 정지해보겠습니다. 먼저 실행된 컨테이너 목록을 출력합니다.

$ sudo docker ps

CONTAINER ID  IMAGE         COMMAND    CREATED         STATUS                       PORTS  NAMES

6338ce52d07c  ubuntu:latest /bin/bash  51 minutes ago  Up 2 minutes                        hello

아래 명령으로 컨테이너를 정지합니다.

$ sudo docker stop hello

docker stop <컨테이너 이름> 형식입니다. 컨테이너 이름 대신 컨테이너 ID를 사용해도 됩니다.

실행된 컨테이너 목록을 출력합니다.

$ sudo docker ps

CONTAINER ID  IMAGE         COMMAND    CREATED         STATUS                       PORTS  NAMES

hello 컨테이너를 정지했기 때문에 아무것도 안나옵니다.


rm#

생성된 컨테이너를 삭제해보겠습니다.

$ sudo docker rm hello

docker rm <컨테이너 이름> 형식입니다. 컨테이너 이름 대신 컨테이너 ID를 사용해도 됩니다.

모든 컨테이너 목록을 출력합니다.

$ sudo docker ps -a

CONTAINER ID  IMAGE         COMMAND    CREATED         STATUS                       PORTS  NAMES

hello 컨테이너를 삭제했기 때문에 아무것도 안 나옵니다.


rmi#

이번에는 이미지를 삭제해보겠습니다.

$ sudo docker rmi ubuntu:latest

docker rmi <이미지 이름>:<태그> 형식입니다. 이미지 이름 대신 이미지 ID를 사용해도 됩니다docker rmi ubuntu처럼 이미지 이름만 지정하면 태그는 다르지만 ubuntu 이름을 가진 모든 이미지가 삭제됩니다.

이미지 목록을 출력합니다.

$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED                  VIRTUAL SIZE

ubuntu 이미지를 삭제했기 때문에 아무것도 안 나옵니다.


이미지 생성하기#

기본적인 이미지와 컨테이너 사용 방법을 알아보았으니 이번에는 이미지를 생성해보겠습니다.


Dockerfile#

Dockerfile Docker 이미지 설정 파일입니다. Dockerfile에 설정된 내용대로 이미지를 생성합니다.

먼저 example 디렉터리를 생성한 뒤 example 디렉터리로 이동합니다.

~$ mkdir example

~$ cd example

아래 내용을 Dockerfile로 저장합니다.

example/Dockerfile

FROM ubuntu:14.04

MAINTAINER Foo Bar <foo@bar.com>

 

RUN apt-get update

RUN apt-get install -y nginx

RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

RUN chown -R www-data:www-data /var/lib/nginx

 

VOLUME ["/data", "/etc/nginx/site-enabled", "/var/log/nginx"]

 

WORKDIR /etc/nginx

 

CMD ["nginx"]

 

EXPOSE 80

EXPOSE 443

우분투 14.04를 기반으로 nginx 서버를 설치한 Docker 이미지를 생성하는 예제입니다.

  • FROM: 어떤 이미지를 기반으로 할지 설정합니다. Docker 이미지는 기존에 만들어진 이미지를 기반으로 생성합니다<이미지 이름>:<태그> 형식으로 설정합니다.
  • MAINTAINER: 메인테이너 정보입니다.
  • RUN: Shell 스크립트 혹은 명령을 실행합니다.
  • VOLUME: 호스트와 공유할 디렉터리 목록입니다docker run 명령에서 -v 옵션으로 설정할 수 있습니다. )-v /root/data:/data 호스트의 /root/data 디렉터리를 Docker 컨테이너의 /data 디렉터리에 연결합니다.
  • CMD: 컨테이너가 시작되었을 때 실행할 실행 파일 또는 스크립트입니다.
  • WORKDIR: CMD에서 설정한 실행 파일이 실행될 디렉터리입니다.
  • EXPOSE: 호스트와 연결할 포트 번호입니다.


build#

Dockerfile을 작성하였으면 이미지를 생성합니다. Dockerfile이 저장된 example 디렉터리에서 아래 명령을 실행합니다.

$ sudo docker build --tag hello:0.1 .

docker build <옵션> <Dockerfile 경로> 형식입니다--tag 옵션으로 이미지 이름과 태그를 설정할 수 있습니다. 이미지 이름만 설정하면 태그는 latest로 설정됩니다.

잠시 기다리면 이미지 파일이 생성됩니다. 이미지 목록을 출력합니다.

$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED                  VIRTUAL SIZE

ubuntu              14.04               e54ca5efa2e9        Less than a second ago   276.1 MB

ubuntu              latest              e54ca5efa2e9        Less than a second ago   276.1 MB

hello               0.1                 2031ee0736e8        9 minutes ago            298.4 MB

hello:0.1 이미지가 생성되었습니다. 이제 실행을 해봅니다.

$ sudo docker run --name hello-nginx -d -p 80:80 -v /root/data:/data hello:0.1

-d 옵션은 컨테이너를 백그라운드로 실행합니다.

-p 80:80 옵션으로 호스트의 80번 포트 컨테이너의 80번 포트를 연결하고 외부에 노출합니다. 이렇게 설정한 뒤http://<호스트 IP>:80에 접속하면 컨테이너의 80번 포트로 접속됩니다.

-v /root/data:/data 옵션으로 호스트의 /root/data 디렉터리를 컨테이너의 /data 디렉터리에 연결합니다. /root/data 디렉터리에 파일을 넣으면 컨테이너에서 해당 파일을 읽을 수 있습니다.

실행된 컨테이너 목록을 출력합니다.

$ sudo docker ps

CONTAINER ID  IMAGE      COMMAND  CREATED         STATUS         PORTS                        NAMES

3c06a0bebab6  hello:0.1  nginx    10 minutes ago  Up 10 minutes  443/tcp, 0.0.0.0:80->80/tcp  hello-nginx

hello-nginx 컨테이너가 실행되었습니다.

웹 브라우저를 실행하고http://<호스트 IP>:80으로 접속합니다Welcome to nginx! 페이지가 표시될 것입니다.

 Mac OS X, Windows에서 Boot2Docker를 사용한다면?

Boot2Docker는 가상 머신 안에 도커를 실행한 상태이기 때문에 호스트 IP로는 nginx에 접속할 수 없습니다. 따라서 다음 명령을 실행하여 Boot2Docker의 가상 머신 IP를 알아냅니다(Windows에서는 Git Bash를 실행한 뒤 명령을 실행합니다).

$ boot2docker ip

The VM's Host only interface IP address is: 192.168.59.103

웹 브라우저를 실행하고http://<Boot2Docker VM IP>:80으로 접속합니다Welcome to nginx! 페이지가 표시될 것입니다.


기타 명령#


history#

앞에서 생성한 hello:0.1 이미지의 히스토리를 조회해보겠습니다.

$ sudo docker history hello:0.1

IMAGE               CREATED                  CREATED BY                                      SIZE

e54ca5efa2e9        Less than a second ago   /bin/sh -c apt-get update && apt-get install    8 B

6c37f792ddac        Less than a second ago   /bin/sh -c apt-get update && apt-get install    83.43 MB

83ff768040a0        Less than a second ago   /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.903 kB

2f4b4d6a4a06        Less than a second ago   /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB

d7ac5e4f1812        Less than a second ago   /bin/sh -c #(nop) ADD file:adc47d03da6bb2418e   192.5 MB

2031ee0736e8        21 minutes ago           /bin/sh -c #(nop) EXPOSE map[443/tcp:{}]        0 B

aa7183744747        21 minutes ago           /bin/sh -c #(nop) EXPOSE map[80/tcp:{}]         0 B

747f1cc74b12        21 minutes ago           /bin/sh -c #(nop) CMD [nginx]                   0 B

6103d971baec        21 minutes ago           /bin/sh -c #(nop) WORKDIR /etc/nginx            0 B

ba6879ea73b0        21 minutes ago           /bin/sh -c #(nop) VOLUME ["/data", "/etc/ngin   0 B

9bed2a790c60        21 minutes ago           /bin/sh -c chown -R www-data:www-data /var/li   7 B

d51d99711779        21 minutes ago           /bin/sh -c echo "\ndaemon off;" >> /etc/nginx   1.621 kB

39c72a05ccf4        21 minutes ago           /bin/sh -c apt-get install -y nginx             18.07 MB

c7bc6a6c45a2        25 minutes ago           /bin/sh -c apt-get update                       4.206 MB

23f17c89799a        25 minutes ago           /bin/sh -c #(nop) MAINTAINER Foo Bar <foo@bar   0 B

511136ea3c5a        11 months ago                                                            0 B

docker history <이미지 이름>:<태그> 형식입니다. 이미지 이름 대신 이미지 ID를 사용해도 됩니다.

이렇게 Dockefile에 설정한 대로 히스토리가 생성됩니다.


cp#

hello-nginx 컨테이너에서 파일을 꺼내보겠습니다.

$ sudo docker cp hello-nginx:/etc/nginx/nginx.conf ./

docker cp <컨테이너 이름>:<경로> <호스트 경로> 형식입니다.

현재 디렉터리에 nginx.conf 파일이 복사되었습니다.


commit#

docker commit 명령은 컨테이너의 변경 사항을 이미지 파일로 생성합니다.

hello-nginx 컨테이너 안의 파일 내용이 바뀌었다고 치고, 컨테이너를 이미지 파일로 생성해보겠습니다.

$ sudo docker commit -a "Foo Bar <foo@bar.com>" -m "add hello.txt" hello-nginx hello:0.2

docker commit <옵션> <컨테이너 이름> <이미지 이름>:<태그> 형식입니다. 컨테이너 이름 대신 컨테이너 ID를 사용해도 됩니다.

-a "Foo Bar <foo@bar.com>" -m "add hello.txt" 옵션으로 커밋한 사용자와 로그 메시지를 설정합니다hello-nginx 컨테이너를 hello:0.2 이미지로 생성합니다.

이미지 목록을 출력합니다.

$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED                  VIRTUAL SIZE

ubuntu              14.04               e54ca5efa2e9        Less than a second ago   276.1 MB

ubuntu              latest              e54ca5efa2e9        Less than a second ago   276.1 MB

hello               0.2                 d2e8c352b303        About a minute ago       298.4 MB

hello               0.1                 2031ee0736e8        44 minutes ago           298.4 MB

hello:0.2 이미지가 생성되었습니다.


diff#

docker diff 명령은 컨테이너가 실행되면서 변경된 파일 목록을 출력합니다. 비교 기준은 컨테이너를 생성한 이미지 내용입니다.

$ sudo docker diff hello-nginx

A /data

C /run

A /run/nginx.pid

C /var/lib/nginx

A /var/lib/nginx/body

A /var/lib/nginx/fastcgi

A /var/lib/nginx/proxy

A /var/lib/nginx/scgi

A /var/lib/nginx/uwsgi

C /etc/nginx

A /etc/nginx/site-enabled

C /dev

C /dev/kmsg

docker diff <컨테이너 이름> 형식입니다. 컨테이너 이름 대신 컨테이너 ID를 사용해도 됩니다.

A는 추가된 파일C는 변경된 파일D는 삭제된 파일입니다.


inspect#

docker inspect 명령은 이미지와 컨테이너의 세부 정보를 출력합니다.

$ sudo docker inspect hello-nginx

[{

    "Args": [],

    "Config": {

        "AttachStderr": false,

        "AttachStdin": false,

        "AttachStdout": false,

        "Cmd": [

            "nginx"

        ],

        "CpuShares": 0,

        "Cpuset": "",

        "Domainname": "",

        "Entrypoint": null,

        "Env": [

            "HOME=/",

            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

        ],

        "ExposedPorts": {

            "443/tcp": {},

            "80/tcp": {}

        },

        "Hostname": "d4369f661b0a",

        "Image": "hello:0.1",

        ... 생략 ...

    },

    "Name": "/hello-nginx",

        "NetworkSettings": {

        "Bridge": "docker0",

        "Gateway": "172.17.42.1",

        "IPAddress": "172.17.0.40",

        "IPPrefixLen": 16,

        "PortMapping": null,

        "Ports": {

            "443/tcp": null,

            "80/tcp": [

                {

                    "HostIp": "0.0.0.0",

                    "HostPort": "80"

                }

            ]

        }

    },

    "Path": "nginx",

    "ProcessLabel": "",

    "ResolvConfPath": "/etc/resolv.conf",

    "State": {

        "ExitCode": 0,

        "FinishedAt": "0001-01-01T00:00:00Z",

        "Paused": false,

        "Pid": 19804,

        "Running": true,

        "StartedAt": "2014-06-03T22:25:42.838118718Z"

    },

    ... 생략 ...

}]

docker inspect <이미지 또는 컨테이너 이름> 형식입니다. 이미지, 컨테이너 이름 대신 이미지 ID, 컨테이너 ID를 사용해도 됩니다.


컨테이너 연결하기#

웹 서버 컨테이너와 DB 컨테이너가 있을 때 웹 서버 컨테이너에서 DB 컨테이너에 접근할 수 있어야 합니다. 이 때에는docker run 명령에서 --link 옵션을 사용하여 컨테이너를 연결합니다.

먼저 DB 이미지를 컨테이너로 실행합니다. 이번에는 MongoDB를 사용해보겠습니다.

$ sudo docker run --name db -d mongo

DB 컨테이너 이름은 db로 설정하였습니다.

이제 web 컨테이너를 생성하면서 db 컨테이너와 연결합니다. 웹 서버로 사용할 컨테이너는 nginx 이미지로 생성하겠습니다.

$ sudo docker run --name web -d -p 80:80 --link db:db nginx

--link <컨테이너 이름>:<별칭> 형식입니다.

컨테이너 목록을 출력합니다.

$ sudo docker ps

CONTAINER ID  IMAGE         COMMAND               CREATED      STATUS        PORTS               NAMES

3971618834cd  nginx:latest  nginx                 About a min  Up About a m  0.0.0.0:80->80/tcp  web

8d4031106c57  mongo:2.6     /usr/src/mongo/docke  4 minutes a  Up 4 minutes  27017/tcp           db,web/db

db 컨테이너와 web 컨테이너가 연결되었습니다web/db라고 표시되는데 web 컨테이너에서 db 컨테이너에 접속할 수 있다는 것입니다.

이제 web 컨테이너 안에서 db:27017 주소로 db 컨테이너의 MongoDB에 접속할 수 있습니다.

mongodb://db:27017/exampledb

<별칭>:<포트 번호> 형식입니다.

 참고

다음과 같이 docker inspect 명령으로 web 컨테이너의 세부 정보에서 hosts 파일 경로를 구한 뒤 cat 명령으로 내용을 살펴봅니다(`는 탭키 위에 있는 문자입니다).

$ cat `docker inspect -f {{ .HostsPath }}" web`

172.17.0.13     aa1982fed33e

127.0.0.1       localhost

::1     localhost ip6-localhost ip6-loopback

fe00::0 ip6-localnet

ff00::0 ip6-mcastprefix

ff02::1 ip6-allnodes

ff02::2 ip6-allrouters

172.17.0.12     db

db --link db:db에서 설정한 별칭이고172.17.0.12 db 컨테이너의 IP 주소입니다.

컨테이너를 연결하면 이렇게 hosts 파일에 IP 주소가 자동으로 설정되기 때문에 별칭을 통해 연결한 컨테이너에 접속할 수 있습니다.


개인 저장소 구축하기#

Docker 저장소 서버는 Docker 레지스트리 서버라고 부릅니다. 레지스트리 서버에 이미지를 올리거나 받을 수 있습니다.

먼저 --insecure-registry 옵션을 사용하여 Docker 데몬을 실행합니다.

$ sudo docker -d --insecure-registry localhost:5000

보통 Docker 데몬을 직접 실행하지 않고 서비스 형태로 실행합니다. 이때는 /etc/init.d/docker 파일의 DOCKER_OPTS 부분을 다음과 같이 설정합니다(이 파일은 root 권한으로 수정해야 합니다).

/etc/init.d/docker

DOCKER_OPTS=--insecure-registry localhost:5000

/etc/init.d/docker 파일을 수정했으면 Docker 서비스를 재시작합니다.

$ sudo service docker restart


로컬에 이미지 데이터 저장#

Docker 레지스트리 서버도 Docker Hub를 통해 Docker 이미지로 제공됩니다. Docker 레지스트리 이미지를 받습니다.

$ sudo docker pull registry:latest

registry:latest 이미지를 컨테이너로 실행합니다.

$ sudo docker run -d -p 5000:5000 --name hello-registry \

    -v /tmp/registry:/tmp/registry \

    registry

이렇게 실행하면 이미지 파일은 호스트의 /tmp/registry 디렉터리에 저장됩니다.

push#

앞에서 만든 hello:0.1 이미지를 개인 저장소에 올려보겠습니다.

$ sudo docker tag hello:0.1 localhost:5000/hello:0.1

$ sudo docker push localhost:5000/hello:0.1

docker tag <이미지 이름>:<태그> <Docker 레지스트리 URL>/<이미지 이름>:<태그> 형식입니다.

docker push <Docker 레지스트리 URL>/<이미지 이름>:<태그> 형식입니다.

먼저 docker tag 명령으로 hello:0.1 이미지를 localhost:5000/hello:0.1 태그로 생성합니다. 그리고 docker push 명령으로 localhost:5000/hello:0.1 이미지를 개인 저장소에 올립니다(태그를 생성했으므로 실제로는 hello:0.1 이미지가 올라갑니다).

이제 다른 서버에서 개인 저장소(Docker 레지스트리 서버)에 접속하여 이미지를 받아올 수 있습니다. 개인 저장소 서버 IP 주소가 192.168.0.39라면 아래와 같이 명령을 실행합니다.

$ sudo docker pull 192.168.0.39:5000/hello:0.1

이미지 목록을 출력합니다.

$ sudo docker images

REPOSITORY                TAG                 IMAGE ID            CREATED             VIRTUAL SIZE

centos                    latest              0c752394b855        4 weeks ago         124.1 MB

192.168.0.39:5000/hello   0.1                 2031ee0736e8        4 weeks ago         298.4 MB

개인 저장소에서 192.168.0.39:5000/hello 이미지를 받았습니다.

이미지를 삭제할 때에는 아래와 같이 실행합니다.

$ sudo docker rmi 192.168.0.39:5000/hello:0.1


Amazon S3에 이미지 데이터 저장#

이번에는 AWS S3에 이미지 데이터를 저장하는 방법입니다.

Docker 레지스트리 이미지를 받습니다.

$ sudo docker pull registry:latest

registry:latest 이미지를 컨테이너로 실행합니다.

$ sudo docker run -d -p 5000:5000 --name s3-registry \

   -e SETTINGS_FLAVOR=s3 \

   -e AWS_BUCKET=examplebucket10 \

   -e STORAGE_PATH=/registry \

   -e AWS_KEY=AKIABCDEFGHIJKLMNOPQ \

   -e AWS_SECRET=sF4321ABCDEFGHIJKLMNOPqrstuvwxyz21345Afc \

   registry

  • SETTINGS_FLAVOR: s3을 설정합니다.
  • AWS_BUCKET: 이미지 데이터를 저장할 S3 버킷 이름을 설정합니다.
  • STORAGE_PATH: 이미지 데이터 저장 경로입니다/registry를 설정합니다.
  • AWS_KEY: AWS 액세스 키를 설정합니다.
  • AWS_SECRET: AWS 시크릿 키를 설정합니다.

이제 s3-retistry 저장소에 Docker 이미지를 push하면 S3 버킷에 저장됩니다.


기본 인증 사용하기#

Docker 레지스트리에는 로그인 기능이 없습니다. 따라서 Nginx의 기본 인증(Basic Authentication) 기능을 사용해야 합니다. 또한, HTTP 프로토콜에서는 인증을 지원하지 않으므로 반드시 HTTPS 프로토콜을 사용해야 합니다.

먼저 /etc/hosts 파일을 편집하여 테스트용 도메인을 추가합니다. 이 파일은 root 권한으로 수정해야 합니다. 도메인을 구입하지 않았을 때는 이 부분을 반드시 설정해주어야 하며, 도메인 구입하여 DNS를 설정하였다면 이 부분은 건너뛰어도 됩니다.

/etc/hosts

127.0.0.1       localhost

127.0.1.1       ubuntu

<레지스트리 서버 IP 주소>    registry.example.com

 

# The following lines are desirable for IPv6 capable hosts

::1     localhost ip6-localhost ip6-loopback

ff02::1 ip6-allnodes

ff02::2 ip6-allrouters

여러분의 레지스트리 서버 IP 주소를 registry.example.com으로 설정합니다. 이 문서에서는 registry.example.com을 기준으로 설명하겠습니다.

이제 SSL 사설 인증서(Self Signed)를 생성하겠습니다. SSL 공인 인증서를 구입하였다면 이 부분은 건너뛰어도 됩니다.

다음 명령을 입력하여 개인 키 파일을 생성합니다.

$ openssl genrsa -out server.key 2048

인증서 서명 요청(Certificate signing request) 파일을 생성합니다.

  • Country Name: 국가 코드입니다. KO를 입력합니다.
  • State or Province Name: 주 또는 도입니다. 자신의 상황에 맞게 입력합니다.
  • Locality Name: 도시입니다. 자신의 상황에 맞게 입력합니다.
  • Organization Name: 회사 이름을 입력합니다.
  • Organizational Unit Name: 조직 이름을 입력합니다.
  • Common Name: Docker 레지스트리를 실행하는 서버의 도메인입니다. 이 부분을 정확하게 입력하지 않으면 인증서를 사용해도 로그인할 때 에러가 발생합니다/etc/hosts 파일에 설정한대로 registry.example.com를 입력합니다.
  • Email Address: 이메일 주소입니다.

$ openssl req -new -key server.key -out server.csr

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [AU]:KO

State or Province Name (full name) [Some-State]:

Locality Name (eg, city) []:Seoul

Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Company

Organizational Unit Name (eg, section) []:Example Company

Common Name (e.g. server FQDN or YOUR name) []:registry.example.com

Email Address []:exampleuser@example.com

 

Please enter the following 'extra' attributes

to be sent with your certificate request

A challenge password []:<아무것도 입력하지 않음>

An optional company name []:<아무것도 입력하지 않음>

서버 인증서 파일을 생성합니다.

$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

이제 server.crt 인증서 파일을 시스템에 설치를 해주어야 합니다(인증서 파일을 설치하지 않으려면 –insecure-registry 옵션을 사용해야 합니다. 이 부분은 뒤에 따로 설명하겠습니다).

우분투

$ sudo cp server.crt /usr/share/ca-certificates/

$ echo "server.crt" | sudo tee -a /etc/ca-certificates.conf

$ sudo update-ca-certificates

CentOS

$ sudo cp server.crt /etc/pki/ca-trust/source/anchors/

$ sudo update-ca-trust enable

$ sudo update-ca-trust extract

/etc/hosts에 도메인을 추가하고, 인증서 파일을 설치했으면 Docker 서비스를 재시작합니다. Docker 서비스를 재시작해야 추가된 도메인과 설치된 인증서가 적용됩니다.

$ sudo service docker restart

Docker 레지스트리에 접속할 다른 시스템에도 server.crt 인증서 파일을 복사하여 같은 방식으로 설치를 하고 Docker 서비스를 재시작합니다. 그리고 도메인을 구입하지 않았다면 /etc/hosts에 레지스트리 서버(registry.example.com) IP 주소를 설정합니다.

 --insecure-registry 옵션

server.crt 인증서 파일을 시스템에 설치하지 않으려면 Docker 데몬을 실행할 때 --insecure-registry 옵션을 사용해야 합니다.

$ sudo docker -d --insecure-registry registry.example.com

  • --insecure-registry 옵션에 Docker 레지스트리의 도메인을 설정합니다. 도메인 여러 개를 설정하려면 --insecure-registry 옵션을 여러 번 사용하면 됩니다.

보통 Docker 데몬을 직접 실행하지 않고 서비스 형태로 실행합니다. 이때는 /etc/init.d/docker 파일의 DOCKER_OPTS 부분을 다음과 같이 설정합니다(이 파일은 root 권한으로 수정해야 합니다).

/etc/init.d/docker

DOCKER_OPTS=--insecure-registry registry.example.com

/etc/init.d/docker 파일을 수정했으면 Docker 서비스를 재시작합니다.

$ sudo service docker restart

Docker 레지스트리에 접속할 다른 시스템에도 같은 방식으로 --insecure-registry 옵션을 사용하여 Docker 데몬을 실행합니다.

이제 사용자 계정과 비밀번호를 저장할 .htpasswd 파일을 생성해야 합니다. 먼저 다음 패키지를 설치합니다.

우분투

$ sudo apt-get install apache2-utils

CentOS

$ sudo yum install httpd-tools

htpasswd 명령으로 .htpasswd 파일을 생성하고 hellouser라는 예제 사용자를 추가합니다. 비밀번호 입력 부분에는 사용할 비빌번호를 입력합니다.

$ htpasswd -c .htpasswd hellouser

New password:<비밀번호 입력>

Re-type new password:<비밀번호 입력>

Adding password for user hellouser

이번에는 Nginx 이미지를 따로 생성하지 않고 공식 이미지를 그대로 사용하겠습니다. 다음 내용을 nginx.conf 파일로 저장합니다.

nginx.conf

worker_processes  1;

 

events {

    worker_connections  1024;

}

 

http {

    server {

        listen       443;

        server_name  registry.example.com;

 

        ssl on;

        ssl_certificate /etc/server.crt;

        ssl_certificate_key /etc/server.key;

 

        proxy_set_header Host           $http_host;

        proxy_set_header X-Real-IP      $remote_addr;

        proxy_set_header Authorization  "";

 

        client_max_body_size 0;

 

        chunked_transfer_encoding on;

 

        location / {

            proxy_pass          http://docker-registry:5000;

            proxy_set_header    Host  $host;

            proxy_read_timeout  900;

 

            auth_basic            "Restricted";

            auth_basic_user_file  .htpasswd;

        }

    }

}

  • server_name: Docker 레지스트리 서버의 도메인을 설정합니다. 여기서는 registry.example.com을 설정합니다.
  • ssl_certificate, ssl_certificate_key: /etc/server.crt/etc/server.key를 설정합니다.
  • proxy_pass: 리버스 프록시 설정입니다. Docker 레지스트리 컨테이너와 포트인 docker-registry:5000을 설정합니다.
  • auth_basic: 인증 설정입니다"Restricted"를 설정하여 기본 인증을 사용합니다.
  • auth_basic_user_file: 사용자 정보가 저장된 .htpasswd 파일을 설정합니다.

 daemon off; 옵션

Nginx 공식 이미지 1.7.5 버전부터는 다음과 같이 Nginx 실행 파일을 실행할 때 옵션에 직접 daemon off;를 설정해줍니다. 따라서 nginx.conf 파일에는 daemon off; 옵션을 넣지 않아도 됩니다.

CMD ["nginx", "-g", "daemon off;"]

다음 명령을 실행하여 Docker 레지스트리 컨테이너를 먼저 생성합니다. 컨테이너의 이름은 nginx.conf 파일에서 설정한 대로 docker-registry로 지정합니다.

$ sudo docker run -d --name docker-registry \

   -v /tmp/registry:/tmp/registry \

   registry:0.8.1

  • Nginx를 통해서 사용자 인증을 하고 이미지를 주고 받을 것이기 때문에 Docker 레지스트리는 5000번 포트를 외부에 노출하지 않습니다.

Nginx 공식 이미지 1.7.5 버전으로 컨테이너를 생성하고 docker-registry 컨테이너와 연결합니다.

$ sudo docker run -d --name nginx-registry \

   -v ~/nginx.conf:/etc/nginx/nginx.conf \

   -v ~/.htpasswd:/etc/nginx/.htpasswd \

   -v ~/server.key:/etc/server.key \

   -v ~/server.crt:/etc/server.crt \

   --link docker-registry:docker-registry \

   -p 443:443 \

   nginx:1.7.5

  • -v 옵션으로 nginx.conf 파일은 컨테이너의 /etc/nginx/nginx.conf로 연결합니다. 마찬가지로 .htpasswd 파일도 /etc/nginx/.htpasswd로 연결합니다server.keyserver.crt 파일은 앞에서 설정한 것처럼 /etc 디렉터리 아래에 연결합니다.
  • --link docker-registry:docker-registry 옵션으로 앞에서 생성한 docker-registry 컨테이너를 docker-registry 별칭으로 연결합니다. 이렇게하면 nginx.conf proxy_pass 설정으로 Docker 레지스트리에 트래픽을 보낼 수 있습니다.
  • -p 443:443 옵션으로 443번 포트를 외부에 노출합니다.

docker login 명령으로 https://registry.example.com 로그인합니다. Username Password에는 htpasswd 명령으로 생성한 사용자와 비밀번호를 입력합니다. 이메일은 입력하지 않아도 됩니다.

$ docker login https://registry.example.com

Username: hellouser

Password: <비밀번호 입력>

Email:

Login Succeeded

docker login <Docker 레지스트리 URL> 형식입니다.

 주의

도메인 설정이 귀찮다고 그냥 건너뛰고 IP 주소만 사용하면 로그인이 안됩니다. 인증서에 설정한 도메인과 docker login 명령에 입력한 도메인이 반드시 일치해야 합니다. HTTPS 프로토콜은 IP 주소 접속을 허용하지 않으므로 구입하지 않은 도메인은 /etc/hosts 파일에 등록하여 사용합니다.

이제 앞에서 만든 hello:0.1 이미지를 개인 저장소에 올려보겠습니다.

$ sudo docker tag hello:0.1 registry.example.com/hello:0.1

$ sudo docker push registry.example.com/hello:0.1

The push refers to a repository [registry.example.com/hello] (len: 1)

Sending image list

Pushing repository registry.example.com/hello (1 tags)

511136ea3c5a: Image successfully pushed

bfb8b5a2ad34: Image successfully pushed

c1f3bdbd8355: Image successfully pushed

897578f527ae: Image successfully pushed

9387bcc9826e: Image successfully pushed

809ed259f845: Image successfully pushed

96864a7d2df3: Image successfully pushed

ba3b051655b4: Image successfully pushed

11ae3a0f7f28: Image successfully pushed

e75f421fc19c: Image successfully pushed

507149de4094: Image successfully pushed

ce11bd8322f9: Image successfully pushed

bb5b14a7e9b8: Image successfully pushed

548b98b8a152: Image successfully pushed

e376f7a8e74c: Image successfully pushed

e2626c81818f: Image successfully pushed

7a06b68da607: Image successfully pushed

Pushing tag for rev [7a06b68da607] on {https://registry.example.com/v1/repositories/hello/tags/0.1}

이미지의 태그는 <Docker 레지스트리 URL>/<이미지 이름>:<태그> 형식으로 생성합니다. 우리는 registry.example.com으로 설정했으므로 registry.example.com/hello:0.1이 됩니다.

다른 서버에서는 다음 명령을 실행하여 registry.example.com에 저장된 이미지를 받을 수 있습니다.

$ sudo docker pull registry.example.com/hello:0.1

 

반응형
반응형

개념 잡기
Docker는 Linux 기반의 Container RunTime 오픈소스이다. 처음 개념을 잡기가 조금 어려운데, Virtual Machine과 상당히 유사한 기능을 가지면서, Virtual Machine보다 훨씬 가벼운 형태로 배포가 가능하다. 정확한 이해를 돕기 위해서, VM 과 Docker Container의 차이를 살펴보자.
아래는 VM 에 대한 컨셉이다. Host OS가 깔리고, 그 위에 Hypervisor (VMWare,KVM,Xen etc)가 깔린 후에, 그위에, Virtual Machine이 만들어진다. Virtual Machine은 일종의 x86 하드웨어를 가상화 한 것이라고 보면된다. 그래서 VM위에 다양한 종류의 Linux나, Windows등의 OS를 설치할 수 있다.
 


 
 
Docker의Container 컨셉은 비슷하지만 약간 다르다. Docker도 VM 처럼 Docker Engine이 Host위에서 수행된다. 그리고, Container는 Linux 기반의 OS만 수행이 가능하다.
Docker는 VM처럼 Hardware를 가상화 해주는 것이 아니라, Guest OS (Container)를 Isolation해준다.무슨 말인가 하면, Container의 OS는 기본적으로 Linux OS만 지원하는데, Container 자체에는 Kernel등의 OS 이미지가 들어가 있지 않다. Kernel은 Host OS를 그대로 사용하되, Host OS와 Container의 OS의 다른 부분만 Container 내에 같이 Packing된다. 예를 들어 Host OS가 Ubuntu version X이고, Container의 OS가CentOS version Y라고 했을때, Container에는 CentOS version Y의 full image가 들어가 있는 것이 아니라, Ubuntu version X와 CentOS version Y의 차이가 되는 부분만 패키징이 된다. Container 내에서 명령어를 수행하면 실제로는 Host OS에서 그 명령어가 수행된다. 즉 Host OS의 Process 공간을 공유한다.
 


 
실제로 Container에서 App을 수행하고 ps –ef 를 이용하여 process를 보면, “lxc”라는 이름으로 해당 App이 수행됨을 확인할 수 있다. 아래는docker를 이용해서 container에서 bash 를 수행했을때는 ps 정보이다. lxc 프로세스로 bash 명령어가 수행되었음을 확인할 수 있다.
root      4641   954  0 15:07 pts/1    00:00:00 lxc-start -n 161c56b9284ffbad0477bd04875c4277be976e2032f3ffa35395950ea05f9bd6 -f /var/lib/docker/containers/161c56b9284ffbad0477bd04875c4277be976e2032f3ffa35395950ea05f9bd6/config.lxc -- /.dockerinit -g 172.17.42.1 -e TERM=xterm -e HOME=/ -e PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -e container=lxc -e HOSTNAME=161c56b9284f -- /bin/bash
LXC는 (LinuX Container)로, 자세한 정보는 http://linuxcontainers.org/ 에서 얻을 수 있다.
lxc는 container를 실행시켜주는 runtime으로, 앞에서 설명한것과 같이 VM과 비슷한 기능을 제공하지만, 실제 수행에 있어서, guest os (container)를 마치 VM처럼 isolate해서 수행해주는 기능을 제공한다.
이와 같이 Docker는 LXC라는 Linux에 특화된 feature를 사용하기 때문에, 제약 사항을 가지고 있는데, 현재까지 Docker는 Ubuntu 12.04 이상(Host OS)에서만 사용이 가능하다.
Performance에 대해서는 당연히 Host OS에서 직접 application 을 돌리는 것보다 performance 감소가 있는데, 아래 표와 같이 performance 감소가 매우 적은 것을 볼 수 있다.
 


 
 
출처: http://www.slideshare.net/modestjude/dockerat-deview-2013
Repository 연계
다음으로 Docker의 특징중의 하나는 repository 연계이다.Container Image를 중앙의 Repository에 저장했다가, 다른 환경에서 가져다가 사용할 수 있다. 마치 git와 같은 VCS (Version Control System)과 같은 개념인데, 이를 통해서 Application들을 Container로 패키징해서 다른 환경으로 쉽게 옮길 수 있다는 이야기다.
 


 
예를 들어 local pc에서 mysql, apache, tomcat등을 각 컨테이너에 넣어서 개발을 한 후에, 테스트 환경등으로 옮길때, Container를 repository에 저장했다가 테스트환경에서 pulling(당겨서) 똑같은 테스트환경을 꾸밀 수 있다는 것이다. Container에는 모든 application과 설치 파일, 환경 설정 정보 등이 들어 있기 때문에, 손쉽게 패키징 및 설치가 가능하다는 장점을 가지고 있다.
여기서 고려해야할점은 Docker는 아쉽게도 아직까지 개발중이고, 정식 릴리즈 버전이 아니다. 그래서, 아직까지는 production(운영환경)에 배포를 권장하고 있지 않다. 단 개발환경에서는 모든 개발자가 동일한 개발환경을 사용할 수 있게 할 수 있고, 또한 VM 보다 가볍기 때문에, 개발환경을 세팅하는데 적절하다고 볼 수 있다.
Base Image vs Dockerfile
Docker의 Container Image를 packing하기 위해서, Docker는 Base Image와 Docker file이라는 두가지 컨셉을 이용한다. 쉽게 설명하면, Base Image는 기본적인 인스톨 이미지, Docker file은 기본적인 인스톨 이미지와 그 위에 추가로 설치되는 스크립트를 정의한다.
예를 들어 Base Image가 Ubuntu OS 이미지라면, Docker File은 Ubuntu OS + Apache, MySQL을 인스톨하는 스크립트라고 보면 된다. 일반적으로 Docker Base Image는 기본 OS 인스톨 이미지라고 보면 된다. 만약에 직접 Base Image를 만들고 싶으면  http://docs.docker.io/en/latest/use/baseimages/ 를 참고하면 된다. docker에서는 미리 prebuilt in image들을 제공하는데,https://index.docker.io/ 를 보면 public repository를 통해서 제공되는 이미지들을 확인할 수 있다. 아직까지는 Ubuntu 많이 공식적으로 제공되고, 일반 contributor들이 배포한 centos 등의 이미지들을 검색할 수 있다. (2013.10.22 현재 redhat 등의 이미지는 없다.)
아래는 docker file 샘플이다. (출처 : http://docs.docker.io/en/latest/use/builder/)
# Nginx
#
# VERSION               0.0.1
 
FROM      ubuntu
MAINTAINER Guillaume J. Charmes <guillaume@dotcloud.com>
 
# make sure the package repository is up to date
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
 
RUN apt-get install -y inotify-tools nginx apache2 openssh-server
위의 이미지는 Ubuntu OS 베이스 이미지에 apt-get을 이용해서, inotify-tools nginx apache2 openssh-serverf 를 인스톨하는 스크립트이다.
Docker 실행해보기
그럼 간단하게 docker를 테스트해보자, 윈도우즈 환경을 가정한다. 앞서 말한바와 같이 Docker는 Unbuntu 위에서만 작동한다. (참고 :http://docs.docker.io/en/latest/installation/windows/)
그래서, 윈도우즈 위에서 Ubuntu VM을 설치한후, Ubuntu VM에서 Docker를 실행할 것이다. 이를 위해서 VM을 수행하기 위한 환경을 설치한다.
  Hypervisor인 Virtual Box를 설치한다. https://www.virtualbox.org 
  VM을 실행하기 위한 vagrant를 설치한다. http://www.vagrantup.com 
  Docker 코드를 다운받기 위해서 git 클라이언트를 설치한다. http://git-scm.com/downloads 
여기까지 설치했으면, docker를 실행하기 위한 준비가 되었다.
다음 명령어를 수행해서, docker 코드를 git hub에서 다운로드 받은 후에, vagrant를 이용해서 Ubuntu host os를 구동한다.

git clone https://github.com/dotcloud/docker.git
cd docker
vagrant up
Virtual Box를 확인해보면, Docker의 Host OS가 될 Ubuntu OS가 기동되었음을 확인할 수 있다.
 


 
그러면, 기동된 Ubuntu OS로 SSH를 이용해서 log in을 해보자. Putty를 이용해서 127.0.0.1:2222 포트로, SSH를 통해서 로그인한다. (기본id,passwd는 vagrant/vagrant 이다.)
이제 Docker를 이용해서, public repository에서 “busybox”라는 Ubuntu OS를 Container로 설치하고, 그 Container에서 “echo hello world” 명령어를 수행해보자
sudo su
docker run busybox echo hello world
Docker가 public repository에서 busybox image를 다운로드 받아서 설치하고, 아래와 같이 명령어를 수행했음을 확인할 수 있다.
 


 
※ 참고 : 현재 docker에 설치된 이미지 리스트 docker images, 설치된 이미지를 삭제할려면 docker rmi {image id}. {image id}는 docker images에서 hexa로 나온 id를 사용하면 된다.

반응형

'오픈소스 활용하기' 카테고리의 다른 글

KVM 설치 가이드  (1) 2023.11.13
가상 머신과 Docker  (2) 2023.11.13
Zabbix server config 파라메터  (1) 2023.11.09
Zabbix value cache working in low memory mode  (0) 2023.11.09
Zabbix 한글깨짐 관련  (0) 2023.11.09
반응형
HTTP에서 HTTPS로 전환하기 위한 완벽 가이드
HTTPS 설정은 경험이 부족한 사용자에게는 어려울 수 있다. 여러 단계를 거쳐야 하고 암호화와 서버 구성에 관한 지식이 필요하기 때문에 복잡한 작업으로 여겨진다.
여기서는 HTTPS 설정에 필요한 구성 요소와 단계에 대해 설명한다. 호스팅 공급 업체가 HTTPS 인증서를 제공하는 경우는 설정이 더 쉽다(제어판에서 모든 작업을 쉽고 빠르게 수행할 수 있다). 리눅스와 유닉스 아파치 HTTP 서버와 엔진엑스Nginx뿐만 아니라 윈도우 IISInternet Information Server의 관리자나 cPanel 사용자를 위한 지침도 소개한다. 기본적인 내용부터 시작해보자.
 
HTTP, HTTPS, HTTP/2, SSL, TLS – 도대체 뭐가 뭔지?
클라이언트와 서버 간 통신 과정을 설명하는 데 사용되는 약어가 많다. 이러한 약어의 개념을 모르는 사람은 혼동해서 사용하기 쉽다.
HTTPHypertext Transfer Protocol는 클라이언트와 서버 양쪽에서 통신할 수 있도록 구현해야 하는 기본 통신 프로토콜로, 요청과 응답, 세션, 캐싱, 인증 등을 다룬다. 프로토콜과 HTML 관련 작업은 CERN에서 팀 버너스 리Tim Berners-Lee와 그 팀이 1989년에 시작했다. 첫 번째 공식 프로토콜 버전(HTTP 1.0)은 1996년에 발표됐고, 곧이어 1997년에 현재 널리 사용되는 버전(HTTP 1.1)이 나왔다.
HTTP는 브라우저와 서버 사이에서 정보를 평문으로 전송하므로 정보가 전달되는 네트워크에서 전송되는 정보를 엿볼 수 있다. 이런 보안 문제로 인해 클라이언트와 서버가 먼저 암호화 통신 채널을 설정한 다음 평문 HTTP 메시지를 전송함으로써 정보 유출을 막는 HTTPSHTTP Secure가 소개되었다.
암호화 채널은 이전에 SSLSecure Socket Layer이라고 불렸던 TLSTransport Layer Security 프로토콜을 사용해서 만든다. 흔히 SSL과 TLS를 혼용했으나 SSL 3.0은 TLS 1.0으로 대체되었다. SSL은 넷스케이프가 개발한 프로토콜인 반면 TLS는 IETF 표준이다. 현재 SSL(1.0, 2.0, 3.0)의 모든 버전은 여러 가지 보안 문제로 사용되지 않고 대부분의 브라우저에서 경고를 표시한다. 현재 TLS 버전(1.0, 1.1, 1.2)을 사용하고 있으며 1.3 버전은 초안이다.
1996년과 1997년에 현재의 안정적인 인터넷 버전(HTTP 1.1, SSL과 TLS는 선택)이 등장했으며 현재 대부분의 웹사이트가 이 버전에서 운영되고 있다. HTTP는 민감하지 않은 트래픽(예: 뉴스 기사)에 이용되고 HTTPS는 민감한 트래픽(예: 인증, 전자상거래)에 이용된다. 하지만 프라이버시에 관심이 높아지면서 구글 크롬과 같은 웹 브라우저는 이제 HTTP 웹사이트를 ‘안전하지 않음’으로 표시하고 HTTP의 앞날에 경고를 보내고 있다.
HTTP 프로토콜의 다음 업그레이드 버전인 HTTP/2는 점점 많은 웹사이트에 적용되고 있으며 지연을 줄이고 성능과 보안 향상을 위해 새 기능(압축, 멀티플렉싱, 우선순위 지정)을 추가했다.
HTTP 버전 1.1에서는 보안 연결이 선택이지만(HTTP와 HTTPS는 서로 독립적) HTTP/2에서는 사실상 필수다. 표준으로는 HTTP/2에서 TLS를 선택적으로 정의했지만 대부분의 브라우저 공급 업체는 HTTP/2와 TLS만 지원한다고 명시했다.
HTTPS에서 제공하는 것
HTTPS로 전환을 고민하는 이유부터 살펴보자. HTTPS는 다음 세 가지 주요 이유 때문에 사용한다.
• 기밀성 HTTPS는 인터넷과 같은 공공 매체에서 두 참여자 간의 통신을 보호한다. 예를 들어, HTTPS가 없다면 와이파이Wi-Fi 액세스 포인트Access Point를 운영하는 사람은 액세스 포인트를 사용하는 사람이 온라인에서 무언가를 구입할 때 신용카드와 같은 개인정보를 볼 수도 있다.
• 무결성 HTTPS는 변조되지 않은 정보로 목적지에 도달하게 한다. 예를 들어, 와이파이가 웹사이트에 광고를 추가하거나, 대역폭을 절약하고자 이미지 품질을 저하시키거나, 읽는 기사의 내용을 변조할 수 있지만 HTTPS는 웹사이트를 변조할 수 없도록 한다.
• 인증 HTTPS를 통해 웹사이트의 진위 여부를 확인할 수 있다. 예를 들어, 와이파이 액세스 포인트을 운영하는 사람이 가짜 웹사이트를 브라우저에 보낼 수도 있다. HTTPS는 example.com이라는 웹사이트가 실제로 example.com인지 확인한다. 일부 인증서는 yourbank.com이 YourBank.Inc라는 걸 알리기 위해 해당 웹사이트의 법적 신원을 검사하기도 한다.
암호 기술의 핵심
기밀성, 무결성, 인증이 HTTPS에만 한정된 것은 아니다. 이러한 특징은 암호 기술의 핵심 개념이다. 이제부터는 각 특징에 대해서 들여다보자.
기밀성
기밀성Confidentiality은 프라이버시다. 즉, 기밀성은 인증되지 않은 제3자가 정보를 읽지 못하도록 보호한다. 그 과정은 보통 평문plaintext이라고 하는 읽을 수 있는(들을 수 있거나 볼 수 있는) 정보 형식을 암호문ciphertext이라고 하는 뒤죽박죽 된 읽을 수 없는 정보 형식으로 변환하는 작업을 거친다. 이 과정을 암호화encryption라고 한다. 반대의 과정(암호문을 다시 읽을 수 있는 평문으로 전환)을 복호화decryption라고 한다. 정보를 암호화하고 복호화하는 방법(암호 함수cipher functions 또는 알고리즘)은 많다.
두 명의 당사자가 통신하려면 다음 두 가지에 동의해야 한다.
1. 통신에 사용할 알고리즘(암호 함수)
2. 선택한 방법으로 사용할 매개변수 또는 암호, 규칙(예: 시크릿secret)
암호화에는 두 가지 주요 방법이 있다.
• 대칭 양쪽 당사자가 공통 비밀 키를 공유한다.
• 비대칭 당사자 중 한쪽이 비밀 키와 공개 키의 쌍, 공개 키 인프라(PKI) 기반을 갖는다.
대칭형 방식은 양쪽 당사자가 공유한 시크릿에 의존하는데, 전송자는 정보를 암호화하는 데 사용하고 수신자는 동일한 방식과 키를 사용해 복호화한다(‘대칭 키 암호화’ 그림 참조). 이 방법의 문제는 양쪽 당사자가 서로 물리적인 만남 없이 시크릿을 협상(교환)하는 방법이라서 일종의 보안 통신 채널이 필요하다.
 
 


대칭 키 암호화 (이미지 확대)
공개 키와 개인 키의 개념을 기반으로 하는 비대칭 방식은 대칭 방식의 문제를 해결한다. 두 가지 키 중 하나로 평문을 암호화하면 다른 보완 키를 사용해야만 복호화할 수 있다. 이를테면 서로 안전하게 통신하고 싶은 두 당사자 앨리스와 밥이 있다고 가정하자(앨리스와 밥은 모든 튜토리얼과 보안 매뉴얼에 항상 등장하는 허구의 인물이므로 여기서는 그러한 전통을 따랐다). 앨리스와 밥은 공개 키와 개인 키의 쌍을 가졌다. 개인 키는 각 소유자만 알고 있으며 공개 키는 누구든 사용할 수 있다.
앨리스가 밥에게 메시지를 보내고 싶다면, 앨리스는 밥의 공개 키를 얻어 평문을 암호화하고 암호문을 밥에게 보낸다. 밥은 자신의 개인 키를 사용해 암호문을 복호화한다.
밥이 앨리스에게 회신하고 싶다면, 앨리스의 공개 키를 얻어서 평문을 암호화해 암호문을 보낸다. 엘리스는 자신의 개인 키를 사용해 그 암호문을 복호화한다.
 
 


비대칭 암호화 (이미지 확대)
언제 대칭 암호화를 사용하고, 언제 비대칭 암호화를 사용할까? 비대칭 암호화는 클라이언트와 서버 간 시크릿을 교환할 때 사용한다. 실생활에서는 양방향 비대칭 통신이 필요하지 않다. 당사자 중 한쪽이(서버라고 하자) 일련의 키를 가지고 있으므로 암호화된 메시지를 받을 수 있다는 것만으로 충분하다. 이는 공개 키로 암호화한 정보는 개인키를 사용해야만 복호화되기 때문에 클라이언트에서 서버로 향하는 단방향으로만 정보를 보호한다. 그러므로 서버에서만 그 정보를 복호화할 수 있다. 반대 방향은 보호되지 않는다. 서버의 개인 키로 암호화된 정보는 공개 키를 가진 누구든지 복호화할 수 있다. 상대편(클라이언트라고 하자)은 서버의 공개 키를 사용해 무작위로 생성된 세션 시크릿을 암호화해 통신을 시작한다. 그 다음 암호문을 다시 서버로 보내고, 서버는 다시 자신의 개인 키로 복호화하면 그 시크릿을 갖게 된다.
대칭 암호화는 비대칭 암호화보다 훨씬 빠르기 때문에 전송 중인 실제 데이터를 보호하는 데 사용된다. 앞서 교환한 시크릿으로 정보를 가진 두 당사자(클라이언트와 서버)만 해당 정보를 암호화하고 복호화할 수 있다.
이 때문에 핸드셰이크handshake의 첫 비대칭 부분이 키 교환이라고 불리며, 실제 암호화된 통신은 사이퍼 메서드cipher methods라는 알고리즘을 사용한다.
무결성
HTTPS로 해결하는 또 다른 문제는 데이터 무결성integrity이다. 즉, (1)전체 정보가 잘 도착했으며, (2)전송 중에 누가 변조하지 않았음을 보장한다. 정보가 잘 전송되었음을 보장하기 위해 메시지 다이제스트message digest 알고리즘을 사용한다. 교환된 각 메시지의 메시지 인증 코드message authentication codes, MAC 계산은 암호화 해싱 프로세스다. 예를 들어 MAC(태그라고도 한다) 획득은 실질적으로 다음의 작업이 불가능(보통 사용하는 용어는 ‘실행 불가능infeasible’)하게 하는 방식이다.
• 태그에 영향을 끼치지 않고 메시지 변경하기
• 두 개의 다른 메시지에 동일한 태그 생성하기
• 프로세스를 거꾸로 돌려 태그에서 원래 메시지 획득하기
인증
인증authentication은 어떨까? 공개 키 인프라의 실제 애플리케이션이 갖는 문제는 양쪽 당사자가 (물리적으로 떨어져 있는) 상대편이 실제로 누구인지 알 방법이 없다는 것이다. 그래서 상대편의 신원을 보증하기 위해 상호 신뢰할 수 있는 제3자, 즉 인증 기관certificate authority, CA이 필수다. 인증 기관은 example.com이라는 도메인 이름(고유한 식별자)이 공개 키 XXX와 연결되어 있음을 기술한 인증서를 발행한다. 경우에 따라서는(조금 뒤 설명하는 EV와 OV 인증서) 인증 기관은 그 도메인을 특정 회사가 통제하는지도 확인한다. 이 정보는 인증 기관 X(인증서 발행)에서 보증하고, 이 보증은 날짜 Y(시작일)와 날짜 Z(만료일)사이에서 유효하다. 이 모든 정보는 HTTPS 인증서라는 문서 하나에 들어간다. 이해를 돕기 위해 나라에서 국민에게 발행하는 ID나 여권을 예로 들면, 해당 정부를 신뢰하는 모든 신뢰 당사자는 ID를 가진 사람의 신원 또한 수용한다(가짜 ID인 경우는 이 예의 범위 밖이다).
인증 기관은 인증서를 서명하기 위해 신뢰된 조직이다. 윈도우와 맥OS, iOS, 안드로이드 등의 운영체제뿐만 아니라 파이어폭스 브라우저는 신뢰된 인증서 목록을 갖고 있다. 사용하는 브라우저에서 신뢰하는 인증 기관을 확인할 수 있다.
• 파이어폭스 설정 → 개인 정보 및 보안 → 인증서 → 인증서 보기 → 인증 기관
• 윈도우 제어판 → 인터넷 옵션 → 내용 → 인증서 → 신뢰할 수 있는 인증 기관/중간 인증 기관
• 맥 응용 프로그램 → 유틸리티 → 키체인 접근 → 카테고리 내 인증서

신뢰 사슬Chain of trust (이미지 확대)
목록에 없는 다른 인증 기관도 추가할 수 있는데, 이는 자체 서명된 인증서와 같은 사설 인증서를 사용할 때 유용하다(뒤에서 다룬다).
대개 일반적인 상황에서 서버 쪽에서만 클라이언트에 신원을 증명한다. 예를 들어, 전자상거래 웹사이트와 고객의 관계에서 해당 웹사이트만 인증서가 필요하다. 전자 정부와 같은 경우는 서비스를 요청하는 서버와 클라이언트 모두 자신의 신원을 증명해야 한다. 이는 양쪽 당사자 모두 다른 당사자를 인증하는 데 인증서를 사용해야 한다는 뜻이다(이 설정 또한 이 글의 범위 밖이다).
HTTPS 인증서 유형
HTTPS 인증서에는 여러 유형이 있으며 다음과 같이 나눌 수 있다.
1. 신원 검증
1. DVDomain validated 가장 일반적인 유형의 인증서인 DV 인증서는 도메인이 특정 공개 키와 일치하는지 확인한다. 브라우저는 서버와 보안 연결을 수립하고 닫힌 자물쇠를 표시한다. 이 표시를 클릭하면 ‘현재 웹사이트는 소유자 정보를 제공하지 않고 있습니다’를 보여준다. 도메인 외의 다른 특별한 요구 사항은 없다. DV 인증서는 해당 도메인에 대한 알맞은 공개 키인지를 간단히 확인하며, 브라우저에서는 법적 신원을 보여주지는 않는다. DV 인증서는 무료이거나 저렴(10달러/년)하다(아래 Let’s Encrypt와 Cloudflare 부분 참고).
2. EVExtended validation EV 인증서는 웹사이트의 법적 신분을 검증한다. EV 인증서는 가장 신뢰할 수 있는 유형의 인증서다. 인증 기관에서 도메인을 관리하는 이의  법적 신원을 확인한 후 얻을 수 있다. 법적 신원은 다음의 조합으로 확인한다.
• 도메인 관리(예: DV 인증서)
• 회사가 등록되었고 현재 유지 상태인지 확인할 수 있는 공인된 사업 기록
• D&B(Dunn and Bradstreet), 세일즈포스 connect.data.com, 전화번호부 등에 등재된 자영업 정보
• 확인 전화
• 인증서의 모든 도메인 이름 검사(와일드카드는 EV 인증서에서 명시적으로 금지). 닫힌 자물쇠 표시뿐만 아니라 EV HTTPS 인증서는 URL 앞에 검증된 법적 신원의 이름(등록된 회사)을 표시한다. iOS 사파리와 같은 일부 기기는 검증된 법적 신원만 표시하고 전체 URL은 무시한다. 해당 표시를 클릭하면 이름과 주소 같은 조직에 대한 자세한 정보를 보여준다. 비용은 연간 150달러에서 300달러 정도다.
3. OVOrganization validated EV처럼 OV 인증서는 웹사이트의 법적 신분을 검증한다. 하지만 EV 인증서와 달리 OV HTTPS 인증서는 UI에서 확인된 법적 이름을 표시하지는 않는다. 결과적으로 OV 인증서는 높은 검증 요구 사항 대비 사용자에게 보여주는 이점이 없기 때문에 인기가 덜하다. 가격은 연 40달러에서 100달러 정도다.
2. 다루는 도메인 수
이전 HTTPS 인증서는 일반적으로 CN 필드에서 하나의 도메인을 다뤘다. 나중에 ‘주체 대체 이름Subject Alternative Name, SAN’ 필드가 추가되어 하나의 인증서에서 추가적인 도메인을 다루도록 허용했다. 요즘 만드는 모든 HTTPS 인증서는 동일하다. 단일 도메인 인증서에도 해당 단일 도메인에 대한 SAN(그리고 그 도메인의 www 버전에 대한 두 번째 SAN)이 있다. 하지만 많은 인증서 공급 업체는 여전히 과거의 관행을 이유로 단일 도메인과 다중 도메인 HTTPS 인증서를 팔고 있다.
1. 단일 도메인 가장 흔한 인증서 유형으로 example.com과 http://www.example.com와 같은 도메인 이름에 유효하다.
2. 다중 도메인(UCC/SAN) UCCUnified Communications Certificate 또는 SAN 인증서로 알려진 인증서 유형으로 도메인의 목록을 다룰 수 있다(지정된 제한까지). 단일 도메인에 대한 제한은 없으며 다른 도메인과 하위 도메인을 혼합할 수 있다. 가격은 보통 정해진 도메인의 수(3~5개)에 추가 비용을 지불하면 더 많이(최대 한도까지) 포함할 수 있는 옵션을 제공한다. 웹사이트의 인증서를 검사하는 클라이언트는 주 도메인뿐만 아니라 모든 추가 도메인을 확인하기 때문에 웹사이트와 관련된 도메인 사용을 권장한다.
3. 와일드카드 이 유형의 인증서는 주 도메인뿐만 아니라 하위 도메인(*.example.com)의 수를 제한 없이 다룬다(예: example.com, http://www.example.com, mail.example.com, ftp.example.com 등). 제한 사항은 주 도메인의 하위 도메인만 다룬다는 점이다.
다음 표에서 사용 가능한 다양한 HTTPS 인증서를 정리했다.
인증서 유형 DV OV EV
(Domain validated) (Organization validated) (Extended validation)
HTTPS HTTPS에서 법적 소유자 검증 HTTPS 검증 법적 소유자 정보가 브라우저에 표시
단일 도메인 example.com, http://www.example.com
다중 도메인 mail.example.com, example.net, example.org 등. 사전 정의된 목록, 지정된 최대 제한까지 (보통100)
와일드카드 *.example.com는 example.com의 모든 하위 도메인을 뜻한다. N/A. 모든 이름은 인증서에 명시적으로 포함해야 하고 CA에서 검사해야 한다.
구성
요약하면 HTTPS의 네 가지 구성 요소는 다음의 암호화를 필요로 한다.
1. 초기 키 교환 비대칭(개인 키와 공개 키) 알고리즘을 사용한다.
2. 신원 인증서(인증 기관에서 발행한 HTTPS 인증서) 이 인증서는 비대칭(개인 키와 공개 키) 알고리즘을 사용한다.
3. 실제 메시지 암호화 대칭(미리 공유한 시크릿) 알고리즘을 사용한다.
4. 메시지 다이제스트 암호 해싱 알고리즘을 사용한다.
이들 각 구성 요소는 서로 다른 키 크기를 사용하는 일련의 알고리즘(이들 알고리즘 중 일부는 사용하지 않음)이 있다. 일부 핸드셰이크의 경우 클라이언트와 서버가 사용할 방식의 조합(수십 개의 공개 키(키 교환) 알고리즘 중 하나, 수십 개의 대칭 키(암호) 알고리즘 가운데 하나와 3개의 메시지 다이제스트(해싱) 알고리즘(2개는 사용 안 함) 가운데 하나를 선택해 수백 가지 조합)에 대한 동의를 요구한다.
예를 들어 ECDHE-RSA-AES256-GCM-SHA384 설정은 해당 키를 ECDHEElliptic Curve Diffie-Hellman Ephemeral 키 교환 알고리즘을 사용해 교환한다는 뜻이다. 인증 기관은 RSARivest-Shamir-Adleman 알고리즘을 사용해 인증서를 서명한다. 대칭 메시지 암호화는 256비트 키와 GCM 운영 모드를 갖는 AESAdvanced Encryption Standard 암호를 사용한다. 메시지 무결성은 384비트 다이제스트를 사용하는 SHA 보안 해싱 알고리즘을 사용해 검증한다(포괄적인 알고리즘 조합 목록을 사용할 수 있다.) 따라서 몇 가지 구성을 선택할 수 있다.
암호화 스위트
사용할 암호화 스위트cipher suite를 결정하는 일은 호환성과 보안 사이의 균형이다.
• 이전 브라우저와 호환성은 이전 암호화 스위트를 지원하는 서버가 필요하다.
• 하지만 대다수의 이전 암호화 스위트는 더 이상 안전하지 않다.
OpenSSL은 암호 강도가 가장 안전한 것에서 가장 약한 것 순서로 위에서 아래로 지원 조합을 나열한다. 클라이언트와 서버 간의 초기 핸드셰이크 동안 양쪽 당사자가 지원하는 조합과 일치하는 것을 발견할 때까지 협상하기 때문에 이런 방식으로 설계했다. 가장 보안이 좋은 조합을 먼저 시도하고 다른 방법이 없다면 점차 더 약한 조합을 쓴다.
서버에서 사용할 암호화 방법을 조언할 때 매우 유용하고 권장하는 자료는 뒤에서 실제 서버 구성에 다룰 모질라 SSL 구성 생성기다.
키 유형
ECCElliptic Curve Cryptography 인증서는 RSA 인증서보다 더 빠르고 CPU를 덜 쓰는데, 특히 모바일 클라이언트에는 이런 점이 중요하다. 하지만 아마존의 클라우드프론트CloudFront나 헤로쿠Heroku와 같은 일부 서비스는 이 글을 쓰는 시점에 아직 ECC 인증서를 지원하지 않는다. 256 비트 ECC 키면 충분하다.
RSARivest Shamir Adleman 인증서는 더 느리지만 오래된 다양한 서버와 호환된다. RSA 키는 더 크므로 2048비트 RSA 키가 최소한이다. 4096비트 이상의 RSA 키는 성능에 좋지 않다. 이 인증서는 2048비트 중간 인증 기관에서 서명할 수도 있어 추가적인 보안에 상당한 손상을 준다.
앞서 기술한 내용이 가변적이라는 점과 키 크기의 제약 사항을 주목했을 것이다. 한 서버에서 과부하를 주는 요인이 다른 서버에서는 그렇지 않을 수 있기 때문이다. 성능에 미치는 영향을 확인하는 최선의 방법은 실제 웹사이트와 실제 방문자로 서버의 부하를 모니터링하는 것이다. 시간의 흐름에 따라 성능이 바뀔 것이다.
절차
HTTPS 인증서를 얻으려면 다음 단계를 거쳐야 한다.
1. 개인 키와 공개 키 쌍을 만들고 조직과 공개 키에 관한 정보를 포함하는 CSRCertificate Signing Request을 준비한다.
2. 인증 기관에 연결해 CSR 기반 HTTPS 인증서를 요청한다.
3. 서명된 HTTPS 인증서를 획득하고 웹 서버에 인증서를 설치한다.
개인 키와 공개 키, CSR과 서명된 HTTPS 인증서 등 공개 키 인프라(PKI)의 다른 구성 요소를 포함하는 일련의 파일이 존재한다. 복잡성을 더 높이는 방편으로 동일성 여부를 확인하는 데 다른 당사자는 다른 이름(그리고 파일 확장자)을 사용한다.
정보를 저장하기 위한 두 가지 인기 있는 형식에는 DER과 PEM이 있다. DER은 바이너리이며, PEM은 base64 인코딩된(텍스트) DER 파일이다. 기본적으로 윈도우는 DER 형식을 직접 사용하며, 오픈소스 진영(리눅스, 유닉스)은 PEM 형식을 사용한다. 두 가지 형식 서로 간에는 변환할 수 있는 도구(OpenSSL)가 있다.
설명 과정에서 예제로 사용할 파일은 다음과 같다.
• example.com.key 이 PEM 형식 파일은 개인 키를 포함한다. 확장자 .key는 표준이 아니므로 일부에서는 사용한다. 시스템 슈퍼 유저만이 보호하고 접근할 수 있다.
• example.com.pub 이 PEM 형식 파일은 공개 키를 포함한다. 이 파일은 개인 키에서 생성될 수 있기 때문에 실제로는 필요하지 않다. 여기서는 설명 목적으로 포함시켰다.
• example.com.csr 이 파일은 인증서 서명 요청이다. 조직 정보와 서버의 공개 키를 포함하는 PEM 형식 파일을 HTTPS 인증서를 발행하는 인증 기관에 보내야 한다.
• example.com.crt 이 HTTPS 인증서는 인증 기관이 서명한 것이다. 이 파일은 PEM 형식 파일이며 서버의 공개 키와 조직 정보, 인증 기관 서명, 유효기간, 만료 날짜 등이 들어 있다. 확장자 .crt는 표준이 아니다. 다른 일반적인 확장자는 .cert와 .cer을 포함한다.
파일 이름(그리고 확장자)는 표준이 아니다(원하는 어떤 것도 가능하다). 어떤 구성 요소가 무슨 기능을 하는지 분명하게 보여야 한다고 생각하기 때문에 이 명명 규칙을 선택했다. 명령과 서버 구성 파일에서 적합한 키 인증서를 참조한다면 프로세스 전체에서 어떤 명명 규칙이든 사용할 수 있다.
개인 키는 특정 길이(여기서는 2048비트 사용)의 문자열을 무작위로 생성한 것으로 다음과 같다.
—–BEGIN RSA PRIVATE KEY—–
MIIEowIBAAKCAQEAm+036O2PlUQbKbSSs2ik6O6TYy6+Zsas5oAk3GioGLl1RW9N
i8kagqdnD69Et29m1vl5OIPsBoW3OWb1aBW5e3J0x9prXI1W/fpvuP9NmrHBUN4E
S17VliRpfVH3aHfPC8rKpv3GvHYOcfOmMN+HfBZlUeKJKs6c5WmSVdnZB0R4UAWu
Q30aHEBVqtrhgHqYDBokVe0/H4wmwZEIQTINWniCOFR5UphJf5nP8ljGbmPxNTnf
b/iHS/chjcjF7TGMG36e7EBoQijZEUQs5IBCeVefOnFLK5jLx+BC//X+FNzByDil
Tt+l28I/3ZN1ujhak73YFbWjjLR2tjtp+LQgNQIDAQABAoIBAEAO2KVM02wTKsWb
dZlXKEi5mrtofLhkbqvTgVE7fbOKnW8FJuqCl+2NMH31F1n03l765p4dNF4JmRhv
/+ne4vCgOPHR/cFsH4z/0d5CpHMlC7JZQ5JjR4QDOYNOpUG51smVamPoZjkOlyih
XGk/q72CxeU6F/gKIdLt6Dx03wBosIq9IAE8LwdMnioeuj18qaVg195OMeIOriIn
tpWP4eFya5rTpIFfIdHdIxyXsd6hF/LrRc9BMWTY1/uOLrpYjTf7chbdNaxhwH7k
buvKxBvCvmXmd6v/AeQQAXbUkdSnbTKDaB9B7IlUTcDJyPBJXvFS1IzzjN6vV+06
XBwHx5ECgYEAyRZLzwnA3bw8Ep9mDw8JHDQoGuQkFEMLqRdRRoZ+hxnBD9V9M0T6
HRiUFOizEVoXxf6zPtHm/T7cRD8AFqB+pA/Nv0ug6KpwUjA4Aihf5ADp0gem0DNw
YlVkCA6Bu7c9IUlE0hwF7RLB7YrryJVJit9AymmUTUUHCQTWW2yBhC8CgYEAxoHS
HGXthin5owOTNPwLwPfU2o7SybkDBKyW69uTi0KxAl3610DjyA/cV2mxIcFlPv1y
HualGd9eNoeCMBy/AUtjzI0K77yeRpjj321rj6k8c8bYWPHH539SiBXLWTY/WQ0w
pxfT3d/Z4QMh5d6p+p5f3UIrXESYQd+fAaG5tNsCgYEAksTdTB4YUT9EsWr6eN9G
jPlclFQUKV3OMvq77bfYvg8EJORz32nnDDmWS7SUjoOtemwutBlMeWbaKk25aMp3
5JNMXuV6apeMJ9Dd8GU7qBUqlIvVK31/96XPvzmnYzWZPqRVwO2HPcRFG3YcJmkg
JmZQyexJvCQ3wFNxiYUm+y0CgYBXQSMhFnCUg4jWbbDcHlnwRT+LnjHrN2arPE3O
eKLfGL6DotmqmjxFaStaRPv2MXMWgAMUsB8sQzG/WEsSaOBQaloAxJJlFIyhzXyE
bi1UZXhMD8BzQDu1dxLI/IN4wE6SDykumVuocEfuDxlsWDZxEgJjWD2E/iXK9seG
yRa+9wKBgEydVz+C1ECLI/dOWb20UC9nGQ+2dMa+3dsmvFwSJJatQv9NGaDUdxmU
hRVzWgogZ8dZ9oH8IY3U0owNRfO65VGe0sN00sQtMoweEQi0SN0J6FePiVCnl7pf
lvYBaemLrW2YI2B7zk5fTm6ng9BW/B1KfrH9Vm5wLQBchAN8Pjbu
—–END RSA PRIVATE KEY—–
‘개인 키를 비공개로 유지하자.’ 이 말은 매우 제한된 권한(600)으로 보호하고 누구에게도 드러내지 말라는 의미다.
여기에 대응하는 공개 키는 다음과 같다.
—–BEGIN PUBLIC KEY—–
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm+036O2PlUQbKbSSs2ik
6O6TYy6+Zsas5oAk3GioGLl1RW9Ni8kagqdnD69Et29m1vl5OIPsBoW3OWb1aBW5
e3J0x9prXI1W/fpvuP9NmrHBUN4ES17VliRpfVH3aHfPC8rKpv3GvHYOcfOmMN+H
fBZlUeKJKs6c5WmSVdnZB0R4UAWuQ30aHEBVqtrhgHqYDBokVe0/H4wmwZEIQTIN
WniCOFR5UphJf5nP8ljGbmPxNTnfb/iHS/chjcjF7TGMG36e7EBoQijZEUQs5IBC
eVefOnFLK5jLx+BC//X+FNzByDilTt+l28I/3ZN1ujhak73YFbWjjLR2tjtp+LQg
NQIDAQAB
—–END PUBLIC KEY—–
CSRCertificate Signing Request은 다음과 같다.
—–BEGIN CERTIFICATE REQUEST—–
MIICzjCCAbYCAQAwgYgxFDASBgNVBAMMC2V4YW1wbGUuY29tMQswCQYDVQQLDAJJ
VDEPMA0GA1UECAwGTG9uZG9uMRIwEAYDVQQKDAlBQ01FIEluYy4xIDAeBgkqhkiG
9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMQswCQYDVQQGEwJHQjEPMA0GA1UEBwwG
TG9uZG9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm+036O2PlUQb
KbSSs2ik6O6TYy6+Zsas5oAk3GioGLl1RW9Ni8kagqdnD69Et29m1vl5OIPsBoW3
OWb1aBW5e3J0x9prXI1W/fpvuP9NmrHBUN4ES17VliRpfVH3aHfPC8rKpv3GvHYO
cfOmMN+HfBZlUeKJKs6c5WmSVdnZB0R4UAWuQ30aHEBVqtrhgHqYDBokVe0/H4wm
wZEIQTINWniCOFR5UphJf5nP8ljGbmPxNTnfb/iHS/chjcjF7TGMG36e7EBoQijZ
EUQs5IBCeVefOnFLK5jLx+BC//X+FNzByDilTt+l28I/3ZN1ujhak73YFbWjjLR2
tjtp+LQgNQIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAGIQVhXfuWdINNfceNPm
CkAGv4yzpx88L34bhO1Dw4PYWnoS2f7ItuQA5zNk9EJhjkwK8gYspK7mPkvHDbFa
Um7lPSWsm3gjd3pU7dIaHxQ+0AW9lOw5ukiBlO4t3qgt+jTVZ3EhMbR0jDSyjTrY
kTgfuqQrGOQSmLb5XviEtCcN0rseWib3fKIl8DM69JiA2AALxyk7DCkS1BqLNChT
pnbgvtlUhc4yFXNCtwPGskXIvLsCn2LRy+qdsPM776kDLgD36hK0Wu14Lpsoa/p+
ZRuwKqTjdaV23o2aUMULyCRuITlghEEkRdJsaXadHXtNd5I5vDJOAAt46PIXcyEZ
aQY=
—–END CERTIFICATE REQUEST—–
이 특정 CSR은 서버의 공개 키와 영국 런던을 기반으로 하는 기업 ACME에 관한 자세한 정보, 도메인 이름 example.com를 포함한다.
마지막으로 서명된 HTTPS 인증서는 다음과 같다.
—–BEGIN CERTIFICATE—–
MIIDjjCCAnYCCQCJdR6v1+W5RzANBgkqhkiG9w0BAQUFADCBiDEUMBIGA1UEAwwL
ZXhhbXBsZS5jb20xCzAJBgNVBAsMAklUMQ8wDQYDVQQIDAZMb25kb24xEjAQBgNV
BAoMCUFDTUUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5jb20x
CzAJBgNVBAYTAkdCMQ8wDQYDVQQHDAZMb25kb24wHhcNMTYwNDE5MTAzMjI1WhcN
MTcwNDE5MTAzMjI1WjCBiDEUMBIGA1UEAwwLZXhhbXBsZS5jb20xCzAJBgNVBAsM
AklUMQ8wDQYDVQQIDAZMb25kb24xEjAQBgNVBAoMCUFDTUUgSW5jLjEgMB4GCSqG
SIb3DQEJARYRYWRtaW5AZXhhbXBsZS5jb20xCzAJBgNVBAYTAkdCMQ8wDQYDVQQH
DAZMb25kb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCb7Tfo7Y+V
RBsptJKzaKTo7pNjLr5mxqzmgCTcaKgYuXVFb02LyRqCp2cPr0S3b2bW+Xk4g+wG
hbc5ZvVoFbl7cnTH2mtcjVb9+m+4/02ascFQ3gRLXtWWJGl9Ufdod88Lysqm/ca8
dg5x86Yw34d8FmVR4okqzpzlaZJV2dkHRHhQBa5DfRocQFWq2uGAepgMGiRV7T8f
jCbBkQhBMg1aeII4VHlSmEl/mc/yWMZuY/E1Od9v+IdL9yGNyMXtMYwbfp7sQGhC
KNkRRCzkgEJ5V586cUsrmMvH4EL/9f4U3MHIOKVO36Xbwj/dk3W6OFqTvdgVtaOM
tHa2O2n4tCA1AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBABwwkE7wX5gmZMRYugSS
7peSx83Oac1ikLnUDMMOU8WmqxaLTTZQeuoq5W23xWQWgcTtfjP9vfV50jFzXwat
5Ch3OQUS53d06hX5EiVrmTyDgybPVlfbq5147MBEC0ePGxG6uV+Ed+oUYX4OM/bB
XiFa4z7eamG+Md2d/A1cB54R3LH6vECLuyJrF0+sCGJJAGumJGhjcOdpvUVt5gvD
FIgT9B04VJnaBatEgWbn9x50EP4j41PNFGx/A0CCLgbTs8kZCdhE4QFMxU9T+T9t
rXgaspIi7RA4xkSE7x7B8NbvSlgP79/qUe80Z7d8Oolva6dTZduByr0CejdfhLhi
mNU=
—–END CERTIFICATE—–
모든 부분은 연결되어 있으며 서로 일치해야 한다. 마지막 인증서는 설명 목적으로만 생성한 것이다. 공인된 인증 기관에서 서명하지 않았기 때문에 자체 서명 인증서라고 한다.
다음은 cPanel과 리눅스, FreeBSD, 윈도우에서 설정 단계를 설명한다. 이는 모든 종류의 인증서에 유효한 범용 절차다. 무료 DV 인증서를 얻고 싶다면 아래 나오는 Let’s Encrypt와 Cloudflare 부분에서 따라야 하는 절차에 대해 설명할 것이다.
1단계: 개인 키와 CSR 만들기
다음 예제에서 호환성을 위해 2048비트 RSA 인증서를 사용한다. 서버 공급 업체에서 이를 지원한다면(예: 헤로쿠나 AWS를 사용하지 않는 경우) ECC를 사용하는 편이 좋다.
CPANEL
1. 호스트의 cPanel에 로그인한다.
2. 아래로 스크롤해서 ‘Security’을 찾고 ‘SSL/TLS’를 클릭한다.

cPanel ‘Security’ 섹션 (이미지 확대)  
3. 이제 ‘SSL/TLS Manager’ 홈으로 넘어왔다. ‘Private Keys(KEY)’를 클릭해 새로운 개인 키를 만든다.

cPanel ‘SSL/TLS Manager’ (이미지 확대)  
4. 페이지를 ‘Generate, Paste or Upload a new Private Key’로 리디렉션한다. ‘Key Size’ 드롭다운 메뉴에서 ‘2048-bit’를 선택하고 ‘Generate’를 클릭한다.

cPanel ‘Private Key’ 관리 (이미지 확대)  
5. 새 개인 키가 생성되고 확인 화면이 나타난다.

cPanel 개인 키 확인 (이미지 확대)  
6. ‘Private Keys’ 홈으로 다시 돌아가면 새로운 키 목록을 보게 된다.

새로 생성된 키가 있는 cPanel ‘Private Keys’ (이미지 확대)  
7. ‘SSL/TLS Manager’ 홈으로 다시 돌아간다. ‘Certificate Signing Requests(CSR)’를 클릭해 새로운 인증서 요청을 만든다.

cPanel ‘SSL/TLS Manager’ (이미지 확대)  
8. 이제 ‘Generate New Certificate Signing Request’ 양식이 표시된다. 이전에 만든 개인 키를 선택하고 필드를 채운다. 모든 질문에 알맞은 답을 적고(서명된 인증서에 공개), HTTPS 인증서를 요청하는 도메인 이름과 정확히 일치해야 하는 ‘Domains’ 섹션에 특별히 주의한다. 최상위 수준 도메인만(example.com) 포함한다(CA는 보통 www 하위 도메인(예: http://www.example.com) 역시 추가한다). 작업을 마치고 나면 ‘Generate’ 버튼을 클릭한다.

cPanel ‘Generate New Certificate Signing Request’ 양식 (이미지 확대)  
9. 새로운 CSR이 생성되고 확인 화면이 표시된다.

cPanel CSR 확인 (이미지 확대)  
10. ‘Certificate Signing Request’ 홈으로 돌아가면 새로운 CSR 목록이 보인다.

생성된 새로운 CSR이 있는 cPanel ‘Certificate Signing Request’ (이미지 확대)  
리눅스, FREEBSD
OpenSSL이 설치되었는지 다음 명령을 사용해 확인한다.
openssl version
아직 설치되지 않았다면 명령줄을 열고 해당 플랫폼에 대한 OpenSSL을 설치한다.
• 데비안, 우분투 및 클론 sudo apt-get install openssl
•  레드햇, CentOS 및 클론 sudo yum install openssl
• FreeBSD make -C /usr/ports/security/openssl install clean
그 다음 다음 명령으로 개인 키와 CSR을 생성한다.
openssl req -newkey rsa:2048 -nodes -keyout example.com.key -out example.com.csr
개인 키가 생성되고 CSR에 대한 몇 가지 질문을 요청받는다.
Generating a 2048 bit RSA private key
……………………+++
……………………………………………………….+++
writing new private key to ‘example.com.key’
—–
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
모든 질문에 알맞은 답을 제공하고(서명된 인증서에 공개), HTTPS 인증서를 요청하는 도메인 이름과 정확히 일치해야 하는 ‘Common Name’ 섹션에 특별히 주의한다. 최상위 수준 도메인만(example.com) 포함한다. CA는 보통 www 하위 도메인(예: http://www.example.com) 역시 추가한다.
Country Name (2 letter code) [AU]:GB
State or Province Name (full name) [Some-State]:London
Locality Name (eg, city) []:London
Organization Name (eg, company) [Internet Widgits Pty Ltd]:ACME Inc.
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:admin@example.com
Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
 
윈도우의 IIS(INTERNET INFORMATION SERVER)
1. 시작 → 관리 도구 → IIS(인터넷 정보 서비스) 관리자를 실행하고 서버 이름을 클릭한다. 가운데 열에서 ‘Server Certificates’를 더블 클릭한다.

IIS 관리자에서 ‘Server Certificates’ 더블클릭 (이미지 확대)
2. 오른쪽 열에서 ‘Create Certificate Request’를 클릭한다.

오른쪽 열에서 ‘Create Certificate Request’ 클릭 (이미지 확대)
3. 도메인 이름과 일치해야 하는 ‘Common Name’에 주의하면서 조직의 세부 내용을 입력하고 ‘Next’를 클릭한다.

조직의 세부 내용 입력 창 (이미지 확대)
4. ‘Cryptographic Service Provider’에서는 기본값을 사용하고, ‘Bit length’를 2048로 설정한다.

‘Bit length’를 2048로 설정 (이미지 확대)
5. 생성된 CSR을 저장할 위치를 지정하고 ‘Finish’를 클릭한다.

생성된 CSR을 저장할 위치 지정 후 ‘Finish’ 클릭 (이미지 확대)
2단계: HTTPS 인증서 얻기
웹사이트 인증서를 얻기 위해 먼저 HTTPS 인증서 공급 업체로부터 HTTPS 인증서 크레딧(DV, OV, EV, 단일 사이트, 멀티 사이트, 와일드 카드)을 구매한다. 인증서 크레딧 구매 뒤 선택한 도메인에 구매한 크레딧을 쓸 인증서 서명 요청을 해야 한다. BEGIN CERTIFICATE REQUEST와 END CERTIFICATE REQUEST를 포함해 전체 CSR 텍스트 제공(필드에 붙여 넣기 하거나 업로드)을 요청받는다. EV나 OV 인증서를 받고 싶다면 인증서 요청자의 법적 신원을 제공해야 한다. 또한 확인을 위해 회사와 관련된 추가 문서를 제출해야 한다. 인증서 등록 기관은 요청(그리고 모든 지원 문서)을 검증한 다음 서명된 HTTPS 인증서를 발행한다.
HTTPS 인증서 얻기
호스팅 공급 업체나 HTTPS 등록 기관에 따라 제품과 등록 절차가 다를 수 있으나 일반적으로 비슷한 방식이다.
1. HTTPS 인증서 공급 업체를 찾는다.
2. 인증서 유형(DV, OV, EV, 단일 사이트, 멀티 사이트, 와일드 카드)을 선택하고 ‘Add to cart’를 클릭한다. 선호하는 지급 방법을 지정하고 지불을 완료한다.
3. 도메인에 새로운 HTTPS 인증서를 활성화한다. 인증서 서명 요청을 붙여 넣거나 업로드할 수 있다. 시스템은 CSR에서 인증서 세부 사항을 뽑아낸다.
4. ‘Domain Control Validation’이라는 방식을 선택하라는 요청을 받는다. 이메일이나 HTML 파일(HTTP 기반) 업로드, 도메인 영역 파일(DNS 기반)에 TXT 레코드를 추가를 통해 수행한다.
5. 검증이 완료되고 HTTPS 인증서가 발행될 때까지 잠깐 기다린다. 서명된 HTTPS 인증서를 다운로드한다.
자체 서명 인증서
인증 기관을 통하지 않고 스스로 인증서를 서명할 수도 있다. 이 인증서는 다른 인증서만큼이나 암호화 방법으로 우수하기 때문에 테스트 목적으로는 좋으나, 브라우저에서는 신뢰하지 않으므로 보안 경고를 표시한다. 어떤 것이라도 클레임이 포함할 수 있지만 제 3의 당사자의 검증은 통과하지 못한다. 사용자가 해당 웹사이트를 신뢰한다면 인증서를 저장하고 향후 방문에서 신뢰하도록 브라우저에서 예외를 추가할 수 있다.
앞의 예제 인증서는 자체 서명된 인증서다. example.com 도메인용으로 사용할 수 있으며 유효기간 내에서 잘 동작한다.
OpenSSL을 사용할 수 있는 모든 플랫폼에서 자체 서명 인증서를 만들 수 있다.
openssl x509 -signkey example.com.key -in example.com.csr -req -days 365 -out example.com.crt
자체 서명 인증서를 사용할 수 있다면 서버에 이 인증서를 설치해야 한다. 같은 공급 업체의 호스팅과 HTTPS 등록 서비스를 사용하고 있다면(많은 호스팅 공급 업체가 HTTPS 인증서를 판매한다), 웹사이트용으로 새로 구매한 HTTPS 인증서를 설치하고 활성화하는 자동화된 절차가 있을 것이다. 다른 곳에서 호스팅 중 이라면 인증서를 다운로드하고 인증서를 사용할 수 있도록 서버를 구성해야 한다.
3단계: 웹사이트에 HTTPS 인증서 설치하기
CPANEL
1. ‘SSL/TLS Manager’ 홈으로 다시 돌아간다. ‘Certificates(CRT)’를 클릭해서 새로운 인증서를 가져온다.

cPanel ‘SSL/TLS Manager’ (이미지 확대)
2. HTTPS 등록 기관에서 받은 인증서 파일의 내용을 붙여 넣기 하거나 ‘Browse’ 버튼을 사용해 인증서를 업로드한다.

cPanel의 새로운 HTTPS 인증서 가져오기 (이미지 확대)
3. HTTPS 인증서 내용을 붙여 넣을 때 내용이 분석되며, 확인을 위한 평문 값이 표시된다. 내용을 검토하고 ‘Save Certificate’ 버튼을 클릭한다.

cPanel의 HTTPS 인증서 검토와 확인 (이미지 확대)
4. 새로운 HTTPS 인증서를 저장하면 다음과 같은 확인 화면이 나타난다.

cPanel HTTPS 인증서 확인 (이미지 확대)
5. ‘Certificates(CRT)’ 홈으로 다시 돌아가면, 새로운 HTTPS 인증서 목록이 표시된다.

새로운 HTTPS 인증서 목록이 있는 cPanel (이미지 확대)
6. ‘SSL/TLS Manager’ 홈으로 돌아간다. ‘Install and Manage SSL for your website(HTTPS)’를 클릭해 기존 웹사이트에 새로운 인증서를 할당한다.

cPanel ‘SSL/TLS Manager’ (이미지 확대)
7. ‘Install an SSL Website’ 양식이 표시된다. ‘Browse Certificates’ 버튼을 클릭하고 HTTPS 인증서를 선택한다. 드롭다운 메뉴에서 웹사이트 도메인을 선택하고 ‘Certificate’와 ‘Private Key’ 필드가 채워졌는지 확인한다.

cPanel ‘Install an SSL Website’ (이미지 확대)
https://www.example.com으로 액세스할 수 있는지 확인한다. 웹사이트가 잘 동작하면 영구적으로 HTTP 트래픽을 HTTPS로 리디렉션하고 싶을 것이다. 그렇게 하려면 웹사이트 루트 폴더의 .htaccess 파일(아파치 웹 서버의 경우)에 몇 줄의 코드를 넣어야 한다.
RewriteEngine On
 
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
.htaccess 파일이 이미 존재한다면 기존 RewriteEngine On 지시문 바로 다음 RewriteCond와 RewriteRule 줄만 붙여 넣는다.
리눅스, FREEBSD
생성한 개인 키(example.com.key)와 인증서 서명 요청(example.com.csr), 유효한 HTTPS 인증서(example.com.crt)를 적절한 위치에 넣는다.
• 데비안, 우분투 및 클론, FreeBSD cp example.com.crt /etc/ssl/certs/cp example.com.key /etc/ssl/private/cp example.com.csr /etc/ssl/private/
• 레드햇, CentOS 및 클론 cp example.com.crt /etc/pki/tls/certs/cp example.com.key /etc/pki/tls/private/cp example.com.csr /etc/pki/tls/private/restorecon -RvF /etc/pki0
파일은 루트가 소유해야 하며 600이라는 퍼미션 설정으로 보호해야 한다.
• 데비안, 우분투 및 클론 chown -R root. /etc/ssl/certs /etc/ssl/privatechmod -R 0600 /etc/ssl/certs /etc/ssl/private
• 레드햇, CentOS 및 클론 chown -R root. /etc/pki/tls/certs /etc/pki/tls/privatechmod -R 0600 /etc/pki/tls/certs /etc/pki/tls/private
• FreeBSD chown -R root:wheel /etc/ssl/certs /etc/ssl/privatechmod -R 0600 /etc/ssl/certs /etc/ssl/private
아파치
웹사이트의 HTTPS 버전을 활성화하는 절차는 다음과 같다.
• mod_ssl이 서버에 설치되었는지 확인한다.
• 획득한 HTTPS 인증서(.crt) 파일을 서버로 업로드한다.
• 아파치 서버 구성 파일을 편집한다.
mod_ssl을 확인하는 것으로 시작한다. 운영체제에 따라 다음 구문 중 하나가 동작해야 한다.
apache2 -M | grep ssl
or
httpd -M | grep ssl
mod_ssl이 설치됐으면 다음과 같은 결과가 표시된다.
ssl_module (shared)
Syntax OK
약간 다른 유사한 결과가 나올 수도 있다.
mod_ssl이 없거나 활성화되지 않는 경우 운영체제에 따라 다음 작업을 시도해본다.
• 데비안, 우분투 및 클론 sudo a2enmod sslsudo service apache2 restart
• 레드햇, CentOS 및 클론 sudo yum install mod_sslsudo service httpd restart
• FreeBSD (SSL 옵션 선택) make -C /usr/ports/www/apache24 config install cleanapachectl restart
아파치 구성 파일을 편집한다(httpd.conf).
• 데비안, 우분투 /etc/apache2/apache2.conf
• 레드햇, CentOS /etc/httpd/conf/httpd.conf
• FreeBSD /usr/local/etc/apache2x/httpd.conf
Listen          80
Listen          443
 
<VirtualHost *:80>
ServerName example.com
ServerAlias http://www.example.com
Redirect 301 / https://www.example.com/
</VirtualHost>
 
<VirtualHost *:443>
ServerName example.com
Redirect 301 / https://www.example.com/
</VirtualHost>
 
<VirtualHost *:443>
ServerName http://www.example.com

SSLEngine on
SSLCertificateFile/path/to/signed_certificate_followed_by_intermediate_certs
SSLCertificateKeyFile /path/to/private/key
 
    
반응형
반응형

Squid 프록시 서버

 

Squid 프록시 서버 LInux

2005/09/12 13:23

http://blog.naver.com/darkstorm001/40017472839

Squid 프록시 서버

 

프록시(Proxy)란 보통 대리인을 뜻하는 영어 단어이다. 일반적으로 브라우저로 웹서핑을 하면 브라우저를 실행하고 있는 컴퓨터와 서버 컴퓨터간의 1 1 직접 연결이 이뤄진다. 프록시는 우선 그러한 1 1 접속이 이뤄질 수 없는 환경에서 또는 1 1 접속을 허용해서는 안되는 환경에서 유용하게 쓰인다. 주로 방화벽 장비에 프록시 서버를 설치하고, 방화벽 뒤에 있는 PC가 프록시를 경유해 웹서핑 또는 FTP 다운로드를 받는다. 여기서 프록시는 그야말로 대리인이다. PC의 브라우저가 보내는 요청을 받아 서버에게 전달하고, 서버에서 받는 내용을 다시 브라우저에도 보내준다.

 

현재 대두분의 회사나 관공서의 경우 대역폭의 절감과 보안강화 그리고 웹서핑 속도를 높이기 위한 노력을 끊임없이 하고 있다. 이런 기능이 구현된 몇몇 프록시 서버 프로그램이 시장에 선보였는데 이 프로그램들은 몇 가지 문제점을 가지고 있었다. 첫 번째는 오픈소스가 아니라는 점이고 두 번째는 ICP를 지원하지 않는다는 것이다. ICP는 이웃하는 캐시에 특정요청 정보가 존재하는지 정보를 교환하는데 사용되며 인접해 있는 다른 캐시서버에 먼저 저장돼 있는 캐시정보를 전송받아 사용할 수 있도록 하는 것이다.

 

그러나 이러한 것을 Squid는 두 가지 모두를 충족해주고 오히려 그 이상의 효과를 기대할 수 있게 해주었다. 또한 프록시의 부가적인 이익이로는 대역폭을 경제적으로 사용할 수 있게 해 준다는 것이다. 프록시는 최근 사람들이 공통적으로 방문한 사이트를 디렉토리에 저장해 두었다가 같은 URL에 대한 요청이 들어오면 서버에 연결하지 않고도 디렉토리에서 읽어 즉시 브라우저에게 보내준다.

여기서는 웹서버 성능의 최적화를 위해 두 가지 다른 방법으로 Squid 서버를 설치하고 설정하는 방법에 대해 알아본다.

첫 번째 웹서버 성능을 극대화하고 httpd 가속서버로 구성하는 것이다. Squid가 가속서버로 동작할 때 상당한 효과를 얻을 수 있다.

두 번째는 일반적인 프록시 캐싱서버로 구성하는 것이다. 이렇게 구성함으로써 회사 또는 조직내의 모든 사용자들로 하여금 Squid를 통해서만 인터넷에 접근하도록 할 수 있다. 이것은 상당한 보안효과와 시스템 자체의 속도를 향상 시킬 수 있다. 또한 Suqid 자체 설정을 통해 인터넷의 접속제한 여부를 설정할 수도 있다. 이렇게 구성함으로써 유해사이트도 간단히 접근제어할 수 있는 것이다.

 

Squie 사이트http://www.squid-cache.org

 

Squid 컴파일, 최적화 및 설치

 

Squid 사이트에서 소스를 다운로드한 후 적절한 디렉토리에 복사한다. 그 다음 필요한 디렉토리에 옮겨 압축을 해제한다.

 

#cp squid-2.5.STABLE1.tar.gz /usr/local/src#cd /usr/local/src#tar xvzf squid-2.5.STABLE1.tar.gz

 

압축을 풀어 Squid 디렉토리로 이동한 후 컴파일한다. Squid 자체를 컴파일하기 전에 아래와 같은 컴파일 옵션을 사용해 최적화한다.

 

#./configure --prefix=/usr/local/squid --libexecdir=/usr/lib/squid --localstatedir=/var --sysconfdir=/etc/squid --enable-auth-modules="PAM" --enable-linux-netfilter#make#make install

 

이러한 것처럼 Squid의 컴파일 및 설치는 매우 간단하다. 일단 프록시 서버의 설정 및 컴파일이 끝난 후에는 더 이상 관련 프로그램들이 필요없으므로 삭제하도록 한다.

 

#rm -rf squid-2.5.STABLE1rm -f squid-2.5.STABLE1.tar.gz

 

Squid 보안과 최적화

 

Squid에서의 보안과 최적화는 일단 다른 응용프로그램의 더 이상 추가가 필요없다는 점이다. 기본 설치된 프로그램만으로도 효율적으로 보안을 강화시킬 수 있고 Squid 자체의 최적화도 가능하다.

 

1. Squid 캐시 디렉토리 마운트 제어

Squid의 캐시정보가 기록되는 디렉토리를 설정함으로써 한층 강화된 보안성능을 구현할 수 있다. 시스템 내에서 어떠한 바이너리도 실행할 수 없고, 문자나 특별한 블록장치를 인식하지 않기 위해서 다음과 같이 설정한다. 여기서는 /var/spool 이라는 파티션이 기존에 정의되있는 것으로 가정하였다.

 

#vi /etc/fstab/var/spool /var/spool ext2 defaults,noexec,nodev 1 2#mount /var/spool -oremount

 

위와 같이 변경한 내용을 적용시키면 된다.

보안적인 측면을 더욱 강화하기 위해서 Squid의 설정 파일을 불변설정한다. 아래와 같이 한다면 관리자가 직접 해제하지 않는 이상 파일의 수정, 추가가 불가능하다.

 

#chattr +i /etc/squid/squid.conf

 

만약 수정, 추가가 필요할때는 -i 옵션을 사용하면 된다.

 

Squid의 성능을 강화하고 최적화하는 방법으로 가장 중요한 부분이 메모리이다. Squid 자체는 CPU보다는 메모리 자원에 의존한다. 그러므로 가능한 충분한 메모리를 확보하도록 한다. 또한 Squid가 사용하는 캐시의 읽고 쓰는 속도를 향상하기 위해 IDE보다는 스카시 하드디스크를 사용하는 것이 좋다.

 

다음 단계는 Squid 서버를 용도에 맞게 설정하는 일이다. Squid의 설정 파일은 /etc/squid/squid.conf에 위치하게 된다. squid.conf 파일을 어느 정도 용도에 맞게 설정하느냐에 따라 성능향상의 폭을 높일 수 있다. 처음으로 웹 가속모드를 설정하고 그 다음은 프로시 캐싱모드로 작동하도록 설정하겠다.

먼저 squid.conf는 앞서 언급한 Squid의 주 설정 파일이다. 파일의 내용을 자세히 보면 알겠지만 상당히 많은 옵션이 제공되고 있으나 실제로는 주요 몇 개의 옵션만 수정하면 된다. 또한 자세한 설명으로 별로 어렵지 않게 응용할 수도 있다. squid.conf 파일의 주요 내용은 다음과 같다.

 

http_port 80

icp_port 0

cache_mem 8 MB

cache_dir ufs /var/spool 100 16 256

emulate_httpd_log on

acl all src 0.0.0.0/0.0.0.0

http_access allow localhost

httpd_accel_host 201.111.132.32

httpd_accel_port 80

buffered_logs on

 

옵션별로 자세히 설명을 하자면,

 

http_port 80

'http_port' 80 옵션은 HTTP 클라이언트가 요청했을 경우 Squid가 응답할 소켓 주소이다. 디폴트 포트는 3128이고 만약 가속모드로 동작하는 Squid의 경우는 80번 포트를 사용해야 한다.

 

icp_port 0

'icp_port' Squid ICP 쿼리를 인접하는 캐시로부터 주고 받을 포트를 정의한다. 디폴트는 3103이며 사용하지 않을 경우는 0으로 설정한다Squid 웹 가속모드로 사용할 경우에는 0으로 해 사용하지 않는 상태로 설정한다. 이유는 Squid가 웹 가속모드로 작동할 경우 ICP를 사용하면 그 만큼 Squid에 불필요한 자원을 낭비하기 때문이다.

 

cache_mem 8 MB

'cache_mem'옵션은 In-Transit objects, hot Objects, Negative-Cached objects을 캐싱하기 위해 지원되는 메모리를 지정하는 옵션이다. 기본은 8MB이다.

 

cache_dir ufs /var/spool 100 16 256

'cache_dir ufs /var/spool/squid 100 16 256' Squid가 사용할 캐시 디렉토리 정의와 디스크용량, 디렉토리 수를 정의한다. 기본적으로 /var/spool 디렉토리를 사용하지만 디스크 용량이 여의치 않다면 특정 디렉토리로 변경 사용할 수 있다. 그 다음에 열거되는 수는 첫 번째, 앞에서 정의한 디렉토리의 용량을 설정한다. 따라서 /var/spool 디렉토리가 사용할 디스크용량은 100MB이다. 16 256은 각각 캐시 디렉토리에서 생성할 하위 디렉토리 수 16과 첫 번째 하위 디렉토리에서 생성될 두 번째 하위 디렉토리 수 256이다.

 

emulate_httpd_log on

'emulate_httpd_log on'옵션은 Squid 자체가 많은 'httpd' 프로그램이 사용하는 로그포맷에 따라 로그를 남기도록 하는 설정이다. 따라서 Squid 자체도 별도의 웹로그 분석 툴로 로그 분석 보고서를 만들 수 있다.

 

acl all src 0.0.0.0/0.0.0.0

http_access allow

위의 두 옵션은 Squid 서버에 접근제어 설정에 사용하는 옵션이다. 현재는 웹 가속모드로 설정하기 때문에 따른 접근제한을 두지 않았다. 물론 다른 목적으로 Squid 서버를 구성할 때에는 이옵션을 적절히 제한해야만 한다.

 

httpd_accel_host 201.111.132.32

httpd_accel_port 80

'httpd_accel_host'는 실제 웹서버의 가속을 위하여 사용된다. 201.111.132.32 Squid 서버가 웹가속 해주게 된다. 'httpd_accel_port 80'은 설명할 필요 없이 해당 포트를 정의한 것이다.

 

buffered_logs on

실제로 중요한 작동을 하는 옵션은 아니다. 로그 기록시 사용되는 시스템 자원을 절약함으로써 약간의 속도 향상을 기대할 수 있는 옵션이다.

 

프록시 캐싱모드로 Squid 설정

 

프록시 캐싱모드는 앞서 말한 웹 가속모드와는 완전히 다른 개념이다. Squid를 프록시 캐싱모드로 사용한다면 해당 네트워크의 모든 가입자가 Squid를 통해야만 인터넷 및 다른 네트워크로 접근할 수 있는 것이다. 또한 별도의 설정으로 내부 사용자들의 사이트 방문지나 연결시간 등을 제어할 수 있다.

앞서 설정한 웹 가속모드와 비슷하게 squid.conf를 수정하면 된다. 다만 접근제어 옵션부분만 자신의 네트워크 상황에 맞게 수정하면 된다. 프록시 캐싱모드에서는 접근제어목록(ACL)을 사용한다. 이 옵션으로 원본주소, 목적지주소, 원본도메인, 목적지도메인, 시간등을 제한 설정할 수 있고 자세한 내용은 squid.conf의 내용을 참조바란다.

접근제어 목록에 대해 간단히 살펴보면 다음과 같다.

 

acl aclname acltype string1 .....acl aclname acltype "file' .....

 

예를 들자면,

 

acl localhost src 172.19.210.0/255.255.255.0

 

사설 IP 172.19.210.0 내부 사용자에 대해 Squid에 접근 가능토록 설정한 것이다. 물론 목적지 기반으로 dst를 사용 목적지 IP를 가진 네트워크에 대해서는 접근을 제어할 수 있다. 그럼 다음 접근제어목록을 보면서 이해 바란다.

 

acl localhost src 127.0.0.1/255.255.255.255acl localhost src 172.19.210.0/255.255.255.0

acl Safe_ports port 80 443acl CONNECT method CONNECTacl all src 0.0.0.0/0.0.0.0http_access allow localhosthttp_access allow localnethttp_access deny !Safe_portshttp_access deny CONNECThttp_access deny all

 

acl 설정으로 로컬 및 사설 IP 172.19.210.0을 사용하는 내부에게만 프록시 서버를 접근할 수 있도록 한 것이다. 또한 내부 포트 80, 443만 사용하도록 했고 명시되지 않은 어떠한 네트워크와 포트를 제한했다.

이와 같이 프록시 캐싱모드로 Squid를 활용한다면 적절한 설정으로 네트워크 및 포트등을 통제할 수 있다. 따라서 부적절한 사이트에 대해 근본적으로 차단할 수 있다. 이런 효과를 바탕으로 더 많은 부분에 대해서 활용될 수 있는 것도 Squid의 장점이다.

출처Tong - ggypsy님의 배우자! 이것통

 

출처: <http://snsdjess.blogspot.kr/2009/08/squid-1.html>

반응형
반응형

Creating an HTTP Proxy Using Squid on CentOS 6.4

Updated Monday, March 3rd, 2014 by Alex Fornuto

Squid is a proxy/cache application with a variety of configurations and uses. This guide will cover using Squid as an HTTP proxy. Please note that unless you follow the last section of the guideAnonymizing Traffic, this will not anonymize your traffic to the outside world, as your originating IP address will still be sent in the X-Forwarded-For header. Additionally, the traffic is not encrypted and will still be visible on your local network. If you are looking for a solution that offers greater security, you may want to look at our guide to Setting up an SSH Tunnel or Deploy VPN Services with OpenVPN.

This guide is written for a non-root user. Commands that require elevated privileges are prefixed with sudo. If you’re not familiar with the sudo command, you can check our Users and Groups guide.

Installing Squid

  1. Squid is available in the CentOS repositories. To ensure your system is up-to-date and install Squid run the following commands:
1
2
sudo yum update
sudo yum install squid
  1. Copy the original configuration file to keep as a backup:
1 sudo cp /etc/squid/squid.conf /etc/squid/squid.conf.default

Configuring Squid as an HTTP proxy

Squid Proxy can be used as an HTTP proxy to bypass local network restrictions, or mask your true location to the world.

Basic Setup

This section covers the easiest way to use Squid as an HTTP proxy, using only the client IP address for authentication.

  1. Edit the Squid configuration file and add the following lines:
    /etc/squid/squid.conf
1 acl client src 12.34.56.78 # Home IP http\_access allow client

Be sure to replace client with a name identifying the connecting computer, and 12.34.56.78 with your local IP address. The comment # Home IP isn’t required, but comments can be used to help identify clients.

  1. Once youve saved and exited the file, start Squid:
1 sudo service squid restart
  1. At this point you can configure your local browser or operating systems network settings to use your Linode as an HTTP proxy. How to do this will depend on your choice of OS and browser. Once youve made the change to your settings, test the connection by pointing your browser at a website that tells you your IP address, such as ifconfigWhat is my IP, or by Googling What is my ip.
  2. Additional clients can be defined by adding new acl lines to /etc/squid/squid.conf. Access to the proxy is granted by adding the name defined by each acl to the http_access allow line.

Advanced Authentication

The following configuration allows for authenticated access to the Squid proxy service using usernames and passwords.

  1. You will need the htpasswd utility. If you’ve installed Apache on your Linode, you will already have it. Otherwise run:
1 sudo yum install httpd-tools
  1. Create a file to store Squid users and passwords, and change ownership:
1
2
sudo touch /etc/squid/squid_passwd
sudo chown squid /etc/squid/squid_passwd
  1. Create a username password pair:
1 sudo htpasswd /etc/squid/squid_passwd user1

Replace user1 with a username. You will be prompted to create a password for this user:

1
2
3
New password:
Re-type new password:
Adding password for user user1

You can repeat this step at any time to create new users.

  1. Edit the Squid configuration file and add the following lines:
    /etc/squid/squid.conf
1
2
3
auth_param basic program /usr/lib64/squid/ncsa_auth /etc/squid/squid_passwd
acl ncsa_users proxy_auth REQUIRED
http_access allow ncsa_users
  1. Once youve saved and exited the file, restart Squid:
1 sudo service squid restart
  1. At this point, you can configure your local browser or operating systems network settings to use your Linode as an HTTP proxy. You will need to specify that the server requires authentication, and provide the username and password. How to do this will depend on your choice of OS and browser. Once youve made the settings change, test the connection by pointing your browser at a website that tells you your IP address, such as ifconfigWhat is my IP, or by Googling What is my ip.
  2. To remove a users access to the proxy, you must delete their entry in the squid_passwd file. Each user is represented in the file on a single line in the format of user:passwordhash :
    /etc/squid/squid_passwd
1 user1:gh48gfno user2:9b83v5hd

If you are using Nano, the command Control+k will remove the entire line where the cursor rests. Once you’ve saved and exited the file, restart Squid:

1 sudo service squid restart

Anonymizing Traffic

In order to mask your IP address from servers you connect to, you will need to add the following lines to the Squid configuration file.

/etc/squid/squid.conf

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
forwarded_for off
request_header_access Allow allow all
request_header_access Authorization allow all
request_header_access WWW-Authenticate allow all
request_header_access Proxy-Authorization allow all
request_header_access Proxy-Authenticate allow all
request_header_access Cache-Control allow all
request_header_access Content-Encoding allow all
request_header_access Content-Length allow all
request_header_access Content-Type allow all
request_header_access Date allow all
request_header_access Expires allow all
request_header_access Host allow all
request_header_access If-Modified-Since allow all
request_header_access Last-Modified allow all
request_header_access Location allow all
request_header_access Pragma allow all
request_header_access Accept allow all
request_header_access Accept-Charset allow all
request_header_access Accept-Encoding allow all
request_header_access Accept-Language allow all
request_header_access Content-Language allow all
request_header_access Mime-Version allow all
request_header_access Retry-After allow all
request_header_access Title allow all
request_header_access Connection allow all
request_header_access Proxy-Connection allow all
request_header_access User-Agent allow all
request_header_access Cookie allow all
request_header_access All deny all

Once youve saved and exited the file, restart Squid:

1 sudo service squid restart

More Information

You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

 

원본 위치 <https://www.linode.com/docs/networking/squid/squid-http-proxy-centos-6-4>

 

반응형

+ Recent posts