본문 바로가기

Linux

SSL서비스 구축 및 OpenSSL

출처 : http://www.tunelinux.pe.kr/gboard/bbs/tb.php/tip/125

OpenSSL 

문태준 

    * OpenSSL 개략 
    * 문서변경내용 
    * 참고자료 
          o openssl 
          o openssl 과 서비스연동 
    * 인증서 작업 개요 
          o 공인인증을 이용할 경우 
          o 자체인증을 이용할 경우 
          o 공인인증을 이용할 경우 초간단 사용법 
    * openssl 사용법 
          o openssl 설정 및 rootCA 구축하기 
          o 인증서 생성시 주의사항 
          o 제공스크립트 이용하기 
          o 보안설정 
    * openssl 주요명령어 설명 
          o 주요 명령어 
          o genrsa 
          o req 
          o ca 
    * 인증서 서비스에 활용 
          o 자체사인한 ssl 인증서 생성 스크립트 
          o apache 에서 ldap인증을 사용할 경우 
          o 주소록 
          o ldapadmin 프로그램 
    * CSR 인증요청서 만들어서 처리하기 
    * apache ssl 세팅하기 
    * 참고사항 
          o 개인키의 비밀번호 암호화 없애기 
          o 한개의 인증서에 여러개의 도메인 설정하기 

OpenSSL 개략 

openssl을 이용하여 인증서 만들고 서명하는 방법 
참고자료에서 openssl 에 대한 내용을 먼저 알고 있어야 이해할 수 있음. 
문서변경내용 

    * 2007.6.14 openssl 사용법 자세한 설명 및 웹서비스 연동 상세히 추가 

참고자료 
openssl 

    * http://wiki.kldp.org/wiki.php/DocbookSgml/SSL-Certificates-HOWTO SSL 인증서 HOWTO. ssl 전반에 대한 소개 
    * http://wiki.kldp.org/wiki.php/LinuxdocSgml/OpenSSL-KLDP 다른 부분은 위의 자료를 참고하는데 jdk 에서 사용하는 keytool 에 대한 간략한 소개가 있음 

openssl 과 서비스연동 

    * http://wiki.kldp.org/wiki.php/DocbookSgml/SSL-RedHat-HOWTO Building a Secure RedHat Apache Server HOWTO 레드햇 사용자가 apache 에 ssl을 사용할 경우에 대한 문서. 간략하게 필요한 부분만 나와있음 
    * http://manual.anycert.co.kr/entry/Apache-2X-CSR-%EC%83%9D%EC%84%B1-%EA%B0%80%EC%9D%B4%EB%93%9C Apache 2.0.xx CSR 생성 가이드 
    * http://manual.anycert.co.kr/entry/Apache-%EC%9B%B9%EC%84%9C%EB%B2%84-20xx-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EC%84%A4%EC%B9%98 Apache 웹서버 2.0.xx 인증서 설치 
    * KISA에서 나온 보안서버구축가이드. SSL 구축방법 및 여러가지 이슈 및 프로그래밍 방법등이 다양하게 정리가 잘 되어있다. 

인증서 작업 개요 
공인인증을 이용할 경우 

    * 공인인증을 이용할 경우에는 스크립트나 명령을 이용하여 키를 생성하고 인증요청서를 생성한다. 여기서 생성한 CSR을 해당 기관에 보내 인증을 받은 공개키를 받고 CA의 공개키도 함께 받아 설치한다. 이 경우에는 자체 인증을 하는것이 아니므로 rootCA 는 만들지 않아도 된다. 
    * rootCA를 이용하지 않고 공인인증기관을 이용할 경우 /usr/share/ssl/certs 의 Makefile을 이용하는 것이 편리하다. 

자체인증을 이용할 경우 

    * 공인인증이 필요없는 경우에는 직접 rootCA를 구축한다. rootCA를 구축할 경우에도 일반인증서를 만드는 것과 차이점은 거의 없으며 x509 옵션을 이용하여 자체 셀프사인한 것만 다르다. 
    * 인 증서 관리를 편리하게 하기 위해서는 자체 인증이 필요한 경우 인증서버를 한대두고 그 서버에서 자체 인증할 csr을 만들고 인증하는 것이 편리하다. 굳이 각 해당 도메인별로 rootCA를 따로 만들면 관리가 불편하고 생성한 key, csr도 한군데에서 관리하는것이 편리할 것이다. 
    * openssl 명령에 익숙해지면 openssl 등에서 제공하는 스크립트를 이용하는 것보다는 직접 스크립트를 짜서 사용하는 것이 편리하다. 키파일 이름, 디렉토리가 제각각이기 때문이다. 
    * rootCA를 구축할 경우 /usr/share/ssl/misc/CA 스크립트를 이용하는 것이 편리하다. 

공인인증을 이용할 경우 초간단 사용법 

    * 아래에서 키파일은 server.key 이며 로컬서버에 저장을 한다. 
    * server.csr은 인증요청서이며 공인인증기관에 보내서 인증을 받아야 한다. 
    * 인증을 받은 파일은 server.crt로 저장을 하고 server.csr은 필요없다. 
    * 키 를 만들때 -nodes 옵션을 주어서 개인키를 암호화하지 않은 경우이다. 유효기간은 365일로 하였다. subj 는 해당 인증서에 대한 정보로 여기서 도메인 sds.co.kr 을 사용하고자 하는 도메인 또는 이메일주소로 바꾸면 된다. 
    * server.key , server.crt, 인증기관에서 받은 rootCA 인증키를 해당 응용프로그램에 따라 설정하면 된다. 

      /usr/bin/openssl  req -new -nodes -keyout server.key -days 365 -out server.csr -subj "/C=KR/ST=Seoul/L=Guro/O=Samjung Data Service Co./OU=service/CN=sds.co.kr" 

openssl 사용법 
openssl 설정 및 rootCA 구축하기 

공인인증을 받을 필요가 없을 경우에는 자체서명된 root CA를 구축한다. 
공인인증을 받는 경우에는 인증요청서 (CSR) 를 만들어서 공인인증기관에 보내 사인을 받은 후 사용하면 된다. 

    * openssl 기본설정 
      openssl 기본설정은 /usr/share/ssl/openssl.cnf 파일에 있다. 
      아래 기본값을 바꾸어놓은 파일 openssl.cnf 여기서 common name 만 바꾸어서 사용하면 된다. 

기본값중에서 인증서의 유효기간을 지정하는 옵션인 default_days 은 365일에서 더 늘려놓는 것이 관리상 편리할 것이다. 
DN 입력하는 기본값을 넣어주면 편리하다. (openssl 명령행에서도 가능함) 
인증서 생성시 옵션을 명령행에서 주지 않으면 일일이 나오는 질문에 답변을 해야하는데 작업을 자주 하는 경우는 매우 불편한 부분이다. 

# diff openssl.cnf openssl.cnf.orig 
63c63 
< default_days  = 1825                  # how long to certify for 
--- 
> default_days  = 365                  # how long to certify for 
120c120 
< countryName_default          = KR 
--- 
> countryName_default          = GB 
125c125 
< stateOrProvinceName_default  = Seoul 
--- 
> stateOrProvinceName_default  = Berkshire 
128c128 
< localityName_default          = guro 
--- 
> localityName_default          = Newbury 
131c131 
< 0.organizationName_default    = Samjung Data Service Co. 
--- 
> 0.organizationName_default    = My Company Ltd 
138c138 
< organizationalUnitName_default        = service 
--- 
> #organizationalUnitName_default      = 
141d140 
< commonName_default            = sds.co.kr 
145d143 
< emailAddress_default          = joon@sds.co.kr 

    * root CA 생성 
      /usr/share/ssl/misc/CA 스크립트를 이용한다. CA 프로그램은 openssl을 편리하게 사용하기 위한 스크립트이다. 
      일반인증서를 만들 경우에는 /usr/share/ssl/certs/Makefile 을 이용하는 것이 낫지만 root CA 생성시는 이 스크립트를 이용하는 것이 필요한 디렉토리까지 같이 생성해주므로 편리하다. 

rootCA 관련한 작업은 기준디렉토리가 /usr/share/ssl/misc 이므로 이 디렉토리로 이동하여 모든 작업을 하면 된다. 다른 디렉토리에 있으면 디렉토리정보때문에 에러가 생긴다. 

root CA 생성은 아래 디렉토리 사용함. 
/usr/share/ssl/misc/demoCA 

root CA 생성은 아래와 같다. 

이전에 만들어놓은 rootca를 삭제하려면 먼저 아래와 같이 실행을 한다. 
cd /usr/share/ssl/misc/ 
rm -rfv demoCA/ 

ca를 신규로 생성한다. 
./CA -newca 
( openssl req -new -x509  -keyout /usr/share/ssl/misc/demoCA/private/cakey.pem \ 
-out /usr/share/ssl/misc/demoCA/cacert.pem -days 365 ) 

CA 스크립트에서 demoCA 디렉토리를 생성하고 ca를 위한 개인키, 공개키를 생성한다. 
인증서의 유효기간은 쉘스크립트에서 DAYS를 이용해 지정하므로 이 부분을 필요에 따라 늘려놓으면 편리하다. 

디렉토리 구조는 아래와 같다. 

# tree /usr/share/ssl/misc/demoCA/ 
/usr/share/ssl/misc/demoCA/ 
|-- cacert.pem -> 공개키 
|-- certs 
|-- crl 
|-- index.txt 
|-- index.txt.old 
|-- newcerts 
|  `-- 01.pem 
|-- private 
|  `-- cakey.pem -> 개인키 
|-- serial 
`-- serial.old 

    * 자체 서명 인증서 만들기 
      자체 서명한 인증서는 -x509 옵션을 이용하여 만든다. 위에서 만든 root CA도 자체서명한 인증서이다. 
      자체 서명하는 인증서는 별도로 공인인증을 받지 않고 사용할 경우 이용하면 된다. 위와 동일한 스크립트이지만 key 파일이름과 경로, 공개키파일의 이름과 경로만 다르다. 

      ./CA -newcert 
      또는 
      /usr/bin/openssl req -new  -keyout newreq.pem  -x509 -days 1825 -out newreq.pem 
      또는 
      cd  /usr/share/ssl/certs/Makefile/ 
      make server.crt  -> 여기서 앞의 파일명은 임의로 만들어도 된다. 

      CA 스크립트나 make 파일을 이용해도 되고 openssl 명령을 이용해도 된다. 

    * 인증요구서 만들기 
      자체적으로 구축한 root CA를 이용하여 사인을 하려하거나 공인인증을 받으려고 하는 경우에는 인증요구서를 만들어야 한다. 

      ./CA -newreq 
      또는 
      (openssl req -new -keyout newreq.pem -out newreq.pem -days 365) 

    * 키확인하기 
      해당 키가 server.key 일 경우 아래와 같이 생성한 키를 확인할 수 있다. 

      # openssl rsa -noout -text -in server.key 

    * 인증요구서 확인하기 
      csr 이 server.csr 일 경우 아래와 같이 확인한다. 

      #openssl req -noout -text -in server.csr 

아래 예제를 본다. 

/usr/bin/openssl req -new -nodes -key /etc/httpd/conf/ssl.key/server.key -days 1825 \ 
-out /etc/httpd/conf/ssl.csr/server.csr 

여기서는 개인키를 이미 만들어둔경우여서 -key 옵션을 사용하였다. 
-nodes 옵션을 개인키를 만들때 암호화하지 않는 것이다. 키를 생성할 경우 비밀번호를 물어보는데 이렇게 하면 아파치 등 대몬 프로그램을 내리고 올릴때 비밀번호를 넣어주어야한다. 보안상 문제가 될 수 있지만 관리측면에서는 불편한 부분이므로 넣어서 사용하는 것이 좋을 듯하다. 

-out 에 지정한 파일에 인증요구서가 만들어지고 ca 옵션을 이용하여 root CA로 사인을 하였다. 

openssl ca -out /etc/httpd/conf/ssl.crt/server.crt -infiles /etc/httpd/conf/ssl.csr/server.csr 

    * crt 인증서 확인하기 

      # openssl x509 -in /etc/httpd/conf/ssl.crt/server.crt -noout -text 

    * rootCA 인증한 인증서 철회하기 
      rootCA 인증을 받은 server.crt를 철회할 경우는 아래와 같이 하면 된다. index.txt에 인증서에 정보가 있다. 
      R는 철회된 인증서, V는 유효한 인증서, E는 유효기간이 만료된 인증서를 뜻한다. 
      아래에서 인증서를 철회하면서 V가 R로 바뀐 것을 확인할 수 있다. 

다음으로 인증철회목록(Certificate Revoked List, CRL)을 업데이트한다. 

# pwd 
/usr/share/ssl/misc 

# cat /usr/share/ssl/misc/demoCA/index.txt 
V      080612041333Z          01      unknown /C=KR/ST=Seoul/O=Samjung Data Service Co./OU=service/CN=sds.co.kr 

# openssl ca -revoke /etc/httpd/conf/ssl.crt/server.crt 

# cat /usr/share/ssl/misc/demoCA/index.txt 
R      080612041333Z  070614005917Z  01      unknown /C=KR/ST=Seoul/O=Samjung Data Service Co./OU=service/CN=sds.co.kr 

# openssl ca -gencrl  -out demoCA/crl/sopac-ca.crl 
Using configuration from /usr/share/ssl/openssl.cnf 
Enter pass phrase for ./demoCA/private/cakey.pem: 

인증서 생성시 주의사항 

참고자료 : http://manual.anycert.co.kr/entry/Apache-2X-CSR-%EC%83%9D%EC%84%B1-%EA%B0%80%EC%9D%B4%EB%93%9C 에서 인용 

    * Organization(영문회사명)에는 < > ~ ! @ # $ % ^ * / \ ( ) ? 등의 특수 문자를 넣을 수 없습니다. 사업자 등록증에 기재된 회사명과 일치하는 영문회사명을 넣어 주시기 바랍니다. (예: 사업자 등록증에 '닷네임 코리아'이면 dotname korea 으로 넣어주셔야 합니다. dotname만 넣으시면 않됩니다.) 
      또한, 인증서를 설치할 Common Name(인증 받을 도메인 주소)에 해당하는 도메인의 등록정보를 반드시 참조하셔서 해당 등록정보에 기재된 회사명을 참고 하실 수 있겠습니다. 
      영문 회사명은 소유하고 계신 도메인이 com/net/org인 경우에는 Network Solutions에서, kr인 경우에는 KRNIC에서 확인할 수 있습니다. 
    * Common Name(인증 받을 도메인 주소)에는 IP 주소, 포트번호, 경로명, http:// 등을 포함할 수 없습니다. 
    * 정 보입력 과정에서 마지막에 나오는 Extra Attributes, 즉 A challenge password와 An optional company name은 입력하지 마시고 Enter키만 눌러주셔야 합니다. 두 항목에 내용을 입력하실 경우 잘못된 CSR이 생성될 수 있습니다. 

입력예는 아래 참조 

Country Name (국가코드) : KR 
State or Province Name (시/도) : Seoul 
Locality Name (구/군) : Songpa 
Organization Name (회사명) : Dotname Korea 
Organizational Unit Name (부서명) : Digital Certificate Team 
Common Name (인증 받을 도메인 주소) : www.anycert.co.kr 
Email Address : 
Please enter the following 'extra' attributes 
to be sent with your certificate request 
A challenge password : 
An optional company name : 

제공스크립트 이용하기 

public/private key 쌍을 만들거나 (pem 으로 저장), SSL 인증 사인 요청서 (CSR), 자체 사인한 테스트 인증서 작성등에 사용할 수 있으며 apache ssl 연동에도 사용할 수 있다. 
스크립트 예제를 보면 된다. 해당 스크립트에서 일부 옵션을 조정하여 사용하면 되는데 -days 등의 옵션이 여기에 해당할 것이다. 

일반적인 경우라면 위의 스크립트로 충분하다. csr을 만들때 nodes 옵션정도를 조정하면 편리할 것이다. 

    * /usr/share/ssl/certs/Makefile 스크립트 이용하기 

      .PHONY: usage 
      .SUFFIXES: .key .csr .crt .pem 
      .PRECIOUS: %.key %.csr %.crt %.pem 

      usage: 
              @echo "This makefile allows you to create:" 
              @echo "  o public/private key pairs" 
              @echo "  o SSL certificate signing requests (CSRs)" 
              @echo "  o self-signed SSL test certificates" 
              @echo 
              @echo "To create a key pair, run \"make SOMETHING.key\"." 
              @echo "To create a CSR, run \"make SOMETHING.csr\"." 
              @echo "To create a test certificate, run \"make SOMETHING.crt\"." 
              @echo "To create a key and a test certificate in one file, run \"make SOMETHING.pem\"." 
              @echo 
              @echo "To create a key for use with Apache, run \"make genkey\"." 
              @echo "To create a CSR for use with Apache, run \"make certreq\"." 
              @echo "To create a test certificate for use with Apache, run \"make testcert\"." 
              @echo 
              @echo Examples: 
              @echo "  make server.key" 
              @echo "  make server.csr" 
              @echo "  make server.crt" 
              @echo "  make stunnel.pem" 
              @echo "  make genkey" 
              @echo "  make certreq" 
              @echo "  make testcert" 

      %.pem: 
              umask 77 ; \ 
              PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \ 
              PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \ 
              /usr/bin/openssl req -newkey rsa:1024 -keyout $$PEM1 -nodes -x509 -days 365 -out $$PEM2 ; \ 
              cat $$PEM1 >  $@ ; \ 
              echo ""    >> $@ ; \ 
              cat $$PEM2 >> $@ ; \ 
              $(RM) $$PEM1 $$PEM2 

      %.key: 
              umask 77 ; \ 
              /usr/bin/openssl genrsa -des3 1024 > $@ 

      %.csr: %.key 
              umask 77 ; \ 
              /usr/bin/openssl req -new -key $^ -out $@ 

      %.crt: %.key 
              umask 77 ; \ 
              /usr/bin/openssl req -new -key $^ -x509 -days 365 -out $@ 

      KEY=/etc/httpd/conf/ssl.key/server.key 
      CSR=/etc/httpd/conf/ssl.csr/server.csr 
      CRT=/etc/httpd/conf/ssl.crt/server.crt 

      genkey: $(KEY) 
      certreq: $(CSR) 
      testcert: $(CRT) 

      $(CSR): $(KEY) 
              umask 77 ; \ 
              /usr/bin/openssl req -new -key $(KEY) -out $(CSR) 

      $(CRT): $(KEY) 
              umask 77 ; \ 
              /usr/bin/openssl req -new -key $(KEY) -x509 -days 365 -out $(CRT) 

apache 와 연동하는 경우 키파일은 다음과 같다. 
KEY=/etc/httpd/conf/ssl.key/server.key 
CSR=/etc/httpd/conf/ssl.csr/server.csr 
CRT=/etc/httpd/conf/ssl.crt/server.crt 

기존 파일을 지우려면 다음과 같이 한다. 

rm -fv /etc/httpd/conf/ssl.crt/server.crt /etc/httpd/conf/ssl.csr/server.csr /etc/httpd/conf/ssl.key/server.key 

Makefile 에서 편리하게 생성을 해주고 자동으로 파일을 복사해준다. 
make genkey : 키생성 . 키는 따로 생성하지 않아도 아래 명령어에서 자동으로 생성해줌 
make certreq : CSR 생성. root CA 로 사인하거나 공인인증을 받으려고 하는 경우 필요 
make testcert : 자체 사인한 인증서 생성 

key(키), csr(CSR), crt(자체사인한 인증서), pem (키와 인증서를 파일 하나로 만듬) 등 확장자에 따라 자동으로 생성해주므로 편리하다. 

csr이나 crt 파일을 만들면 key파일은 자동으로 Makefile에서 만들어준다. 
처음 아파치를 rpm으로 설치하고 새롭게 인증서파일을 만들 경우에는 기존의 파일을 먼저 지워준다. 
CSR은 공인인증을 받을경우 이용하면 되고 자체사인한 인증서를 사용하려면 CRT를 이용하면 된다. 
참고로 위 스크립트에서 보듯이 기본 유효기간이 365일이므로 더 늘려서 사용하는것이 운영상 편리할 것이다. 
보안설정 

개인키는 위험에 노출되지 않도록 안전한 곳에 보관을 한다. 

# ll /usr/share/ssl/misc/demoCA/private/ 
total 4 
-rw-------  1 root root 963 Dec 28 13:55 cakey.pem 
# ll /etc/httpd/conf/ssl.key/ 
total 4 
-rw-------  1 root root 963 Dec 28 14:01 server.key 

openssl 주요명령어 설명 
주요 명령어 

openssl 상세한 사용법은 해당 man page 를 봐야한다. 

    * genrsa : RSA 개인키생성 
    * rsa : RSA 키 처리 프로그램. 개인키의 암호화를 없앨 경우 사용할 수 있음 
    * req : X.509 Certificate Signing Request (CSR) Management (man openssl) . 인증서 생성시 사용 
    * ca : Certificate Authority (CA) Management (man openssl) . ca에서 사용 
    * req 에 대한 상세설명은 man req 을 참고한다. 

genrsa 

    * -des3 : 개인키 암호화. 이 옵션을 빼면 개인키를 암호화하지 않아서 비밀번호를 물어보지 않는다. 

req 

    * -new : 인증 요청서 생성 
      this option generates a new certificate request. It will prompt the user for the relevant field values. The actual fields prompted for and their maximum and minimum sizes are specified in the configuration file and any requested extensions. If the -key option is not used it will generate a new RSA private key using information specified in the configuration file 
    * -key : 읽어들일 개인키 지정. 개인키를 미리 생성하여 사용할 경우에 필요함 
      This specifies the file to read the private key from. It also accepts PKCS#8 format private keys for PEM format files. 
    * -keyout : 새로 생성할 개인키 파일명 지정 
      this gives the filename to write the newly created private key to. If this option is not specified then the filename present in the configura-tion file is used. 
    * -out : 공개키 파일 명 지정 
      This specifies the output filename to write to or standard output by default. 
    * -days : 인증서 유효기간. 기본값은 30일임 
      when the -x509 option is being used this specifies the number of days to certify the certificate for. The default is 30 days. 
    * -x509 : 인증요청서를 만드는 대신에 자체 사인한 인증서를 만듬. 보통 테스팅용 인증서를 만들거나 root CA를 만들 경우에 필요함. 
      this option outputs a self signed certificate instead of a certificate request. This is typically used to generate a test certificate or a self signed root CA. The extensions added to the certificate (if any) are specified in the configuration file. Unless specified using the set_serial option 0 will be used for the serial number. 
    * -subj : DN 내용을 미리 입력할 수 있음. 
      sets subject name for new request or supersedes the subject name when processing a request. The arg must be formatted as /type0=value0/type1=value1/type2=..., characters may be escaped by \ (backslash), no spaces are skipped. 
      예제 : /usr/bin/openssl req -new -subj '/CN=sds.co.kr/O=samjung/C=KO/ST=gurogu/L=seoul' -keyout newreq.pem -x509 -days 1825 -out newreq.pem 
    * -nodes : 개인키 암호화를 하지 않는다. 대몬프로그램을 올리고 내릴때 편리하다. 
      if this option is specified then if a private key is created it will not be encrypted. 

ca 

    * -infiles : 인증요청서(csr) 파일명 
      if present this should be the last option, all subsequent arguments are assumed to the the names of files containing certificate requests. 
    * -out : 생성할 인증서 파일 
    * -revoke : 인증을 철회할 파일명 
    * -gencrl : this option generates a CRL based on information in the index file. 

인증서 서비스에 활용 
자체사인한 ssl 인증서 생성 스크립트 

self 사인한 ssl 인증서를 생성하는 스크립트이다. 자체생성하여 만든 개인키는 /usr/local/direct/ssl 에 보관하고 CA에서 받은 인증서파일은 cacerts 하위 디렉토리에 보관한다. 
이것을 가지고 apache, ldap 등에서 연동하여 사용한다. 
openldap 에서는 /usr/local/direct/ssl/cacerts/ 디렉토리를 /etc/openldap/cacerts/ 디렉토리로 심볼릭 링크하여 사용한다. 

#!/bin/bash 
# joon 
# 자체 사인한 인증서를 생성하며 만료기간은 1825일(5년)으로 해 두었다. 
# 프라이비트키는 root로 두어야하지만 ldap 사용자가 읽어야 하기에 ldap 사용자 계정으로 바꾸어주었다. 
KEY_NAME='wiki.sds.co.kr' 
KEY_DIRECTORY=/usr/local/direct/ssl 
CA_DIRECTORY=$KEY_DIRECTORY/cacerts 
PUBLIC_KEY=$CA_DIRECTORY/$KEY_NAME.crt 
PRIVATE_KEY=$KEY_DIRECTORY/$KEY_NAME.key 
DAYS="1825" 

[ -f $PUBLIC_KEY ] && mv -fv $PUBLIC_KEY $PUBLIC_KEY.orig 
[ -f $PRIVATE_KEY ] && mv -fv $PRIVATE_KEY $PRIVATE_KEY.orig 

[ ! -d $KEY_DIRECTORY ] && mkdir -p $KEY_DIRECTORY 
[ ! -d $CA_DIRECTORY ] && mkdir -p $CA_DIRECTORY 

ln -s $CA_DIRECTORY /etc/openldap/cacerts 

SUBJ='/C=KR/ST=gurogu/L=seoul/O=samjung/OU=itservice/CN='$KEY_NAME 

/usr/bin/openssl req -new -nodes -keyout $PRIVATE_KEY -x509 -days $DAYS -out $PUBLIC_KEY -subj $SUBJ 

/bin/chmod 644 $PUBLIC_KEY* 
/bin/chown ldap.ldap $PRIVATE_KEY 
/bin/chmod 400 $PRIVATE_KEY* 

/etc/init.d/ldap restart 
/etc/init.d/httpd stop && /etc/init.d/httpd startssl 
/usr/sbin/cacertdir_rehash $CA_DIRECTORY 

위와 같은 작업을 한후 /etc/openldap/slapd.conf 에서 다음과 같이 설정한다. 

TLSCipherSuite HIGH:MEDIUM:+SSLv2 
TLSCACertificateFile /usr/local/direct/ssl/cacerts/wiki.sds.co.kr.crt 
TLSCertificateFile /usr/local/direct/ssl/cacerts/wiki.sds.co.kr.crt 
TLSCertificateKeyFile /usr/local/direct/ssl/wiki.sds.co.kr.key 

사용자 인증으로 ldap 을 사용할 경우 /etc/ldap.conf 에서 tls_cacertdir 이 /etc/openldap/cacerts 로 지정되어 있는 경우 cacertdir_rehash 명령을 실행해주어야 한다. 

/usr/sbin/cacertdir_rehash /etc/openldap/cacerts/ 

웹서버설정에서는 아래과 같이 지정한다. 
/etc/httpd/conf.d/ssl.conf 

SSLCertificateFile /usr/local/direct/ssl/cacerts/wiki.sds.co.kr.crt 
SSLCertificateKeyFile /usr/local/direct/ssl/wiki.sds.co.kr.key 
SSLCACertificateFile /usr/local/direct/ssl/cacerts/wiki.sds.co.kr.crt 

여기에서 wiki.sds.co.kr.crt 파일은 공인인증을 받지 않았으므로 윈도우에서 crt 파일을 클릭한 경우 인증서가져오기(확장자를 .crt로 하면 됨)를 실행하여 인증서를 저장하면 된다. 
그러면 웹브라우즈에서도 인증서 설치한 이후에는 편리하게 사용할 수 있다. 

위에서 만약 사설인증이 아니라 공인인증을 이용했을 경우 ldap 에서 TLSCACertificateFile, 아파치에서 SSLCACertificateFile 파일만 달라질 것이다. 

아래는 아파치에서 자체적으로 만든 rootCA를 이용하여 별도로 crt 파일을 만든 경우이며 공인인증을 이용했을 경우에는 csr을 보내 인증받을 인증서를 SSLCertificateFile 에 넣고 SSLCACertificateFile 만 공인인증기관의 것을 이용하면 된다. 

SSLCertificateFile /tmp/test/crt/sds.co.kr.crt 
SSLCertificateKeyFile /tmp/test/key/sds.co.kr.key 
SSLCACertificateFile /usr/share/ssl/misc/demoCA/cacert.pem 

여기에서 mirror.crt 파일은 공인인증을 받지 않았으므로 윈도우에서 crt 파일을 클릭한 경우 인증서가져오기(확장자를 .crt로 하면 됨)를 실행하여 인증서를 저장하면 된다. 
그러면 웹브라우즈에서도 인증서 설치한 이후에는 편리하게 사용할 수 있다. 
apache 에서 ldap인증을 사용할 경우 

apache 에서 ldap 인증을 사용하는 경우에는 아래 내용이 httpd.conf에 있어야한다. 
CA키만 적절한 것으로 바꾸어주면 된다. 

LDAPTrustedCA /usr/share/ssl/misc/demoCA/cacert.pem 
LDAPTrustedCAType BASE64_FILE 

이제 htaccess 파일에서 아래와 같이 지정을 하면 된다. 

# cat .htaccess 
AuthType Basic 
AuthName "Samjung Staff Only" 
AuthLDAPBindDN cn=readonly,ou=admingroup,dc=samjung,dc=com 
AuthLDAPBindPassword readonly 
AuthLDAPURL ldaps://xxxx.direct.co.kr/ou=people,dc=samjung,dc=com?uid?sub?(objectClass=*) 
require valid-user 

주소록 

아웃룩등의 주소록에서는 기타 설정에서 SSL사용을 체크해주면 된다. 
ldapadmin 프로그램 

자체서명해서 사용하면 ldapadmin 에서는 셀프사인한 root 인증서라는 주의사항이 나온다. 이것은 불편해서 그냥 사용을 해야 할 듯하다. 
CSR 인증요청서 만들어서 처리하기 

아래는 CSR (인증요청서)를 만드는 스크립트이다. 
해당 도메인에 대하여 dns에 등록되어있는지 확인을 한다. 
만약 키파일이나 CSR파일이 있는 경우는 백업하고 진행하거나 중지하거나 백업하지 않고 새로운 파일을 만들 수 있도록 한다. 
키, csr 파일 생성시 nodes 옵션을 이용하여 개인키 비밀번호를 설정하지 않았다. 

#!/bin/bash 
# joon 
# CSR 생성요청 스크립트 

if [ $# -lt 1 ] 
then 
echo "CSR을 생성할 도메인명을 입력하십시요" 
echo "사용방법 : $0 domain" 
exit 
fi 

# 신청할 도메인명 
KEY_NAME=$1 

# 키보관 디렉토리. 개인키는 key, 인증요구서는 csr,인증받은 인증서는 crt, CA 인증서는 cacerts 디렉토리에 넣어둠 
SSL_KEY_STORE=/usr/local/direct/SSL_KEY_STORE 
KEY_DIRECTORY=$SSL_KEY_STORE/key 
CSR_DIRECTORY=$SSL_KEY_STORE/csr 
CRT_DIRECTORY=$SSL_KEY_STORE/crt 
CA_DIRECTORY=$SSL_KEY_STORE/cacerts 

CSR_FILE=$CSR_DIRECTORY/$KEY_NAME.csr 
KEY_FILE=$KEY_DIRECTORY/$KEY_NAME.key 

# 인증서 유효기간 
DAYS="365" 

# 이전 인증파일을 현재 년월일-시분초기준으로 백업함 
# %F    same as %Y-%m-%d 
# %T    time, 24-hour (hh:mm:ss) 
NOW=`date +%F-%T` 

# 등록되어 있는 도메인인지 확인을 합니다 
/usr/bin/host $KEY_NAME | grep "not found" && echo "경고 : $KEY_NAME 도메인은 dns에 등록되어 있지 않습니다. 정상적인 사용을 위해서는 도메인 등록을 해야합니다" 

if [ -f $KEY_FILE ] 
then 
echo "기존에 키파일이 존재합니다. 백업을 하고 새로 생성을 하려면 y를 누르세요. n를 누르면 더이상 진행하지 않습니다. 그냥 엔터를 치면 백업을 하지 않고 새로운 키를 생성합니다." 

read remove_key 
case "$remove_key" in 
Y|y) mv -fv $KEY_FILE $KEY_FILE.$NOW ; 
    echo "기존 $KEY_FILE 을 $KEY_FILE.$NOW 로 백업하였습니다" ;; 
N|n) echo "실행을 멈춥니다"; 
    exit;; 
# *) echo "$KEY_NAME 에 대한 새로운 key 파일을 생성합니다." ;; 
esac 
fi 

#[ -f $KEY_FILE ] && mv -fv $KEY_FILE $KEY_FILE.$NOW 
#[ -f $CSR_FILE ] && mv -fv $CSR_FILE $CSR_FILE.$NOW 

if [ -f $CSR_FILE ] 
then 
echo "기존에 CSR파일이 존재합니다. 백업을 하고 새로 생성을 하려면 y를 누르세요. n를 누르면 더이상 진행하지 않습니다. 그냥 엔터를 치면 백업을 하지 않고 새로운 키를 생성합니다." 

read remove_key 
case "$remove_key" in 
Y|y) mv -fv $CSR_FILE $CSR_FILE.$NOW ; 
    echo "기존 $CSR_FILE 을 $CSR_FILE.$NOW 로 백업하였습니다" ;; 
N|n) echo "실행을 멈춥니다"; 
    exit;; 
# *) echo "$KEY_NAME 에 대한 새로운 CSR 파일을 생성합니다.";; 
esac 
fi 

[ ! -d $KEY_DIRECTORY ] && mkdir -p $KEY_DIRECTORY 
[ ! -d $CSR_DIRECTORY ] && mkdir -p $CSR_DIRECTORY 
[ ! -d $CRT_DIRECTORY ] && mkdir -p $CRT_DIRECTORY 
[ ! -d $CA_DIRECTORY ] && mkdir -p $CA_DIRECTORY 

# 생성할 인증서에 대한 정보 
SUBJ="/C=KR/ST=Seoul/L=Guro/O=Samjung Data Service Co./OU=service/CN=$KEY_NAME" 
#SUBJ="/C=KR/ST=Seoul/L=Guro/O=SamjungDataServiceCo/OU=service/CN=$KEY_NAME" 

# openssl 프로그램 경로 
OPENSSL_CMD="/usr/bin/openssl" 

# 인증서 생성 
$OPENSSL_CMD req -new -nodes -keyout $KEY_FILE -days $DAYS -out $CSR_FILE -subj "$SUBJ" || exit 

# 파일퍼미션 조정 
/bin/chmod 400 $KEY_FILE 
/bin/chmod 644 $CSR_FILE 

echo "===================================================================================================" 
echo "$KEY_NAME 에 대한 인증요청서를 정상적으로 생성하였습니다!" 
echo "$KEY_DIRECTORY 에 key, csr, crt, CA 인증서등을 보관하면 편리합니다." 
echo "KEY(개인키)는 $KEY_FILE 입니다." 
echo "비밀번호를 생성하여 개인키를 만들었을 경우 비밀번호를 반드시 기억해두셔야 하며 안전한 곳에 보관하시기 바랍니다. 또한 일반사용자가 읽지못하도록 해야 합니다." 
echo "" 
echo "CSR(인증요청서)는 $CSR_FILE 입니다. 원하는 인증기관에 보내서 인증을 받아야 합니다" 

apache ssl 세팅하기 

    * openssl 확인 
      openssl은 rpm으로 설치확인을 한다. 

    * apache mod_ssl 확인 
      Apache 웹서버는 두가지 방식의 모듈 설치를 지원하므로 statically linking module, DSO(Dynamic Shared Objects) module 로 설치된 모듈을 확인할 수 있습니다. 
      $HTTPD 변수는 아파치 설치 디렉토리를 가르킵니다. 

    * 
          o statically linking module 로 설치된 mod_ssl 모듈확인 

            # /usr/local/apache/bin/httpd -l | grep mod_ssl 
              mod_ssl.c 

    * 
          o DSO module 로 설치된 mod_ssl 모듈확인 

            # /usr/local/apache/bin/httpd -l | grep mod_so 
              mod_so.c 

            # ll /usr/local/apache/modules/ | grep ssl 
            -rwxr-xr-x  1 root root  155624 Aug 13  2006 mod_ssl.so 

            웹서버에 설치된 mod_so.c 를 확인하고 dso 모듈로 설치된 mod_ssl.so를 확인하면 됩니다. 

    * CSR 생성 및 인증받기 
      위의 내용 참고 

    * 네트워크 확인사항 
      SSL을 적용하면 기본 443 포트를 사용한다. 그러므로 방화벽에서 443 포트에 대한 접근을 허용해야한다. 
      추가로 한대의 서버에서 여러개의 SSL 웹서비스를 하는 경우는 각 SSL 서비스별로 별도 포트를 지정해야한다. 

    * 인증받은후 인증서 설치하기 
      인증받은 인증서는 보통 도메인명.crt 형태이다. 또한 공인인증기관의 rootCA 인증서가 같이 온다. 
      해당 crt 파일을 윈도우에서 더블클릭하여 열어보면 내용을 확인할 수 있다. 

아파치의 conf/ssl.conf 에서 ssl 설정을 한다. 

SSL Virtual Host Context 부분이 ssl 가상호스팅 설정을 하는 부분이다. 

중요한 부분은 아래의 세줄이다. 
SSLCertificateFile 은 인증받은 도메인이름으로 된 인증서(crt 파일), 
SSLCertificateKeyFile 은 CSR 파일생성할때 먼저 생성한 개인키파일 
SSLCACertificateFile 은 인증받은 기관에서 받은 인증서를 넣으면 된다. 

SSLCertificateFile /usr/local/direct/SSL_KEY_STORE/crt/sds.co.kr.crt 
SSLCertificateKeyFile /usr/local/direct/SSL_KEY_STORE/key/sds.co.kr.nodes.key 
SSLCACertificateFile /usr/share/ssl/misc/demoCA/cacert.pem 

실제 설정예 

<VirtualHost sds.co.kr:443> 
DocumentRoot "/usr/local/apache/htdocs" 
ServerName sds.co.kr:443 
ServerAdmin you@example.com 
#ErrorLog /usr/local/apache/logs/error_log 
#TransferLog /usr/local/apache/logs/access_log 

SSLCertificateFile /usr/local/direct/SSL_KEY_STORE/crt/sds.co.kr.crt 
SSLCertificateKeyFile /usr/local/direct/SSL_KEY_STORE/key/sds.co.kr.nodes.key 
SSLCACertificateFile /usr/share/ssl/misc/demoCA/cacert.pem 

SSLEngine on 
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL 
</VirtualHost> 

이제 아파치 프로그램을 시작하여 확인해보면 된다. 

bin/apachectl startssl 
또는 
bin/apachectl -D -SSL -k start 

log/error_log 파일을 확인해서 문제가 있는지 확인을 한다. 

    * 프로세서 확인 

      # ps auxw | grep http 
      root    12681  0.0  1.0  7540 2636 ?        Ss  13:58  0:00 /usr/local/apache/bin/httpd -k start -DSSL 
      nobody  12682  0.0  0.9  7888 2464 ?        S    13:58  0:00 /usr/local/apache/bin/httpd -k start -DSSL 
      nobody  12683  0.0  0.9  7888 2460 ?        S    13:58  0:00 /usr/local/apache/bin/httpd -k start -DSSL 

      # netstat -atn | egrep ":80|:443" 
      tcp        0      0 :::80                      :::*                        LISTEN 
      tcp        0      0 :::443                      :::*                        LISTEN 

    * 여러개의 서버 가상호스팅하는 경우 
      이경우에는 각 호스트별로 포트를 다르게 해야한다. 
      아래 설정을 참고한다. 
      원래의 파일에서 일부 순서를 조정하였다. 
      FilesMatch, Directory, SetEnvIf, CustomLog 부분은 원래 가상호스팅설정에 있는 부분인데 공동으로 써도 되는 내용이며 빼놓아도 잘 작동한다. 

# grep -v "^#" ssl.conf 
SSLRandomSeed startup builtin 
SSLRandomSeed connect builtin 
<IfDefine SSL> 
Listen 443 
Listen 444 

AddType application/x-x509-ca-cert .crt 
AddType application/x-pkcs7-crl    .crl 

SSLPassPhraseDialog  builtin 

SSLSessionCache        dbm:/usr/local/apache/logs/ssl_scache 
SSLSessionCacheTimeout  300 

SSLMutex  file:/usr/local/apache/logs/ssl_mutex 

<FilesMatch "\.(cgi|shtml|phtml|php3?)$"> 
    SSLOptions +StdEnvVars 
</FilesMatch> 
<Directory "/usr/local/apache/cgi-bin"> 
    SSLOptions +StdEnvVars 
</Directory> 

SetEnvIf User-Agent ".*MSIE.*" \ 
        nokeepalive ssl-unclean-shutdown \ 
        downgrade-1.0 force-response-1.0 

CustomLog /usr/local/apache/logs/ssl_request_log \ 
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" 

<VirtualHost sds.co.kr:444> 
DocumentRoot "/usr/local/apache/htdocs" 
ServerName sds.co.kr:444 
ServerAdmin you@example.com 

SSLCertificateFile /usr/local/direct/SSL_KEY_STORE/crt/sds.co.kr.crt 
SSLCertificateKeyFile /usr/local/direct/SSL_KEY_STORE/key/sds.co.kr.nodes.key 
SSLCACertificateFile /usr/share/ssl/misc/demoCA/cacert.pem 

SSLEngine on 
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL 
</VirtualHost> 

<VirtualHost ssl.sds.co.kr:443> 
DocumentRoot "/usr/local/apache/cent4" 
ServerName ssl.sds.co.kr:443 
ServerAdmin you@example.com 

SSLCertificateFile /tmp/test/crt/ssl.sds.co.kr.crt 
SSLCertificateKeyFile /tmp/test/key/ssl.sds.co.kr.key 
SSLCACertificateFile /usr/share/ssl/misc/demoCA/cacert.pem 

SSLEngine on 
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL 
</VirtualHost> 

</IfDefine> 

참고사항 
개인키의 비밀번호 암호화 없애기 

csr 생성시 nodes 옵션을 이용하거나 이미 생성된 개인키에서 비밀번호를 없앨 수 있다. 
그래야 부팅시에 웹서버(또는 ldap 등 다른서버)가 패스워드 입력없이 정상적으로 동작한다. 
개인키 파일 또는 개인키가 포함된 server.eky 파일을 가지고 다음의 명령을 통해 비밀문구를 제거할 수 있다. 
같은 키파일에 nodes라는 것을 추가하여 알아보기 쉽도록 추가하였다. 

openssl rsa -in server.key -out server-nodes.key 

위 작업을 거치면 비밀문구가 제거된 server-nodes.key 이름의 개인키 파일이 생길 것이다. 
이 파일에는 비밀문구가 빠졌기 때문에 보안상 대단히 위험하다. 때문에 이에 대한 조치를 취해야 한다. 
예를 들어 파일 권한을 변경해서 관리자만 볼 수 있게 한다든지 등의 조치가 필요하다. 
만약 이 파일이 누출된다면 여러분의 사이트는 망가지게 될 것이다. 
한개의 인증서에 여러개의 도메인 설정하기 

CSR 생성시 cn 이름을 여러개 넣어도 작동은 한다. 
공인인증기관에서 해주는지는 모르겠으며 이런 방식을 이용하여 서비스를 하는곳도 있다. 
이에 대해서는 KISA에서 나온 보안서버구축가이드를 참고한다. 

openssl req -new -nodes -keyout cent34.key -days 365 -out cent34.csr \ 
-subj '/C=KR/ST=Seoul/L=Guro/O=Samjung Data Service Co./OU=service/CN=sds.co.kr/CN=ssl.sds.co.kr'
 

'Linux' 카테고리의 다른 글

synergy linux build  (0) 2011.05.25
VIM 펑션키 맵핑  (0) 2011.04.24
VI 사용 간략 정리  (0) 2011.04.12
objdump  (0) 2011.02.16
xargs  (0) 2011.01.20