Chrome 브라우저 최신 버전으로 업데이트 이후 예전에 적용했던 WoSign SSL 인증서를 신뢰하지 않는 문제가 발생했다.



관련 내용은 아래 주소를 참고:


https://www.xetown.com/square/416332



그래서 이번에는 Apache2 서버에 Chrome이 후원하고 있는 Lets' Encrypt 무료 인증서를 적용해 보도록 한다.


우분투 Ubuntu 16.04.2 LTS 에서는 고맙게도 설치 프로그램을 제공하고 있다.

$ sudo apt-get install letsencrypt


설치가 정상적으로 완료되면 아래 명령어를 이용해 인증서를 서버에 설치한다.

$ sudo letsencrypt certonly --webroot --webroot-path=웹루트_풀경로명 -d 대상_도메인명

 - Congratulations! Your certificate and chain have been saved .... 이라는 메시지가 나오면 성공이다.

(도메인이 여러개일 경우 -d 옵션을 여러개 지정하면 된다.)


아래 명령어를 통해 인증서 파일 목록을 볼 수 있다.

$ sudo ls  -l /etc/letsencrypt/live/


아파치 서버에 적용해보자.

아래 구문을 대상 conf 파일에 넣어주자. (기존에 설정한 게 있다면 주석 처리한다.)

SSLEngine on

SSLProtocol all -SSLv2 -SSLv3

SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA


SSLHonorCipherOrder on


SSLCertificateFile "/etc/letsencrypt/live/도메인명/cert.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/도메인명/privkey.pem"
SSLCertificateChainFile "/etc/letsencrypt/live/도메인명/chain.pem"

아파치를 재기동하면 이제 정상적으로 인증서가 적용된 모습을 볼 수 있다.


Lets' Encrypt 인증서는 인증기간이 90일로 짧다. 따라서 주기적으로 인증서를 갱신해야 한다.

$ sudo crontab -e

----- 생 략 ----

# For more information see the manual pages of crontab(5) and cron(8)

# m h  dom mon dow   command

10 5 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log

15 5 * * 1 /usr/sbin/apache2ctl restart

이제 매주 월요일 5시 10분과 15분에 인증서를 갱신하고 아파치를 재기동 할 수 있다.


지난번 [Tomcat8 : SSL 인증서 적용하기 (WoSign 무료 인증서)] 글에 이어 이번에는 Apache2에 SSL 인증서를 적용하는 절차를 알아본다.


1. 개인키 파일 생성

# openssl genrsa -des3 -out private.key 2048


Generating RSA private key, 2048 bit long modulus

..................+++

................+++

e is 65537 (0x10001)

Enter pass phrase for private.key: (개인키 패스워드 입력)

Verifying - Enter pass phrase for private.key: (개인키 패스워드 입력)

2. CSR 생성

# openssl req -new -key private.key -out out.csr


Enter pass phrase for pri.kery: (개인키 패스워드 입력)

Loading 'screen' into random state - done 

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]:KR (국가코드 C)

State or Province Name (full name) [Some-State]:Seoul (시,도 ST)

Locality Name (eg, city) []:Gu-ro (구,군 L)

Organization Name (eg, company) [Internet Widgits Pty Ltd]:Finkle (기관명 O)

Organizational Unit Name (eg, section) []:RnD (조직명 OU)

Common Name (eg, YOUR name) []:mydomain.co.kr (도메인명 CN)

Email Address []:my@email.com (이메일)


Please enter the following 'extra' attributes 

to be sent with your certificate request 

A challenge password []: enter

An optional company name []: enter


3. https://buy.wosign.com/free/ 접속 후 위에서 생성한 CSR 파일 내용 붙여넣기


4. zip 파일 다운로드

mydomain.co.kr_sha256_en.zip


5. 압축 파일 내 [for Apache.zip] 파일의 내용 추출 후 적용대상 서버에 업로드

1_root_bundle.crt

2_mydomain.co.kr.crt


6. 아파치 설정파일 변경


<VirtualHost *:443>

    SSLEngine on

    SSLCertificateKeyFile  /my/path/ssl/private.key

    SSLCertificateFile       /my/path/ssl/2_mydomain.co.kr.crt

    SSLCACertificateFile   /my/path/ssl/1_root_bundle.crt

</VirtualHost>


7. 아파치 재기동


1개의 Tomcat에서 2개의 instance를 띄우고자 하는 시나리오를 가정한다. (Tomcat 8.0 기준)


1. Tomcat 설치 폴더 : 

/home/finkle/tomcat8


2. 인스탄스 1번 폴더 : 

/home/finkle/instance/svc01


3. 인스탄스 2번 폴더 : 

/home/finkle/instance/svc02



1. 톰캣 설치 폴더에서 1번 instance로 파일 복사

$ cd /home/finkle/instance/svc01

$ cp -R /home/finkle/tomcat8/* .

$ rm -rf bin lib LICENSE NOTICE RELEASE-NOTES RUNNING.txt

$ ls

conf logs temp webapps work


※ 2번 instance도 위와 같은 과정을 따라한다.


3. conf/server.xml 수정 : 서비스를 위한 포트번호가 중복되지 않도록 설정한다.


1번 instance의 server.xml


<Server port="8005" shutdown="SHUTDOWN">

....

    <Connector port="80" protocol="HTTP/1.1" Server="WAS-NAME"

               connectionTimeout="20000"

               redirectPort="443" URIEncoding="utf-8" />

....


2번 instance의 server.xml


<Server port="8015" shutdown="SHUTDOWN">

....

    <Connector port="8010" protocol="HTTP/1.1" Server="WAS-NAME"

               connectionTimeout="20000"

               redirectPort="8443" URIEncoding="utf-8" />

....


4. 1번 instance의 Tomcat 구동 스크립트 작성


$ cd /home/finkle/instance/svc01

$ mkdir bin

$ cd bin

$ touch startup.sh

$ touch shutdown.sh

$ chmod +x *.sh



startup.sh


#!/bin/sh


CATALINA_BASE=/home/finkle/instance/svc01

CATALINA_OPTS="-Denv.servername=svc01"

CATALINA_PID=/home/finkle/instance/svc01/svc01.pid

JAVA_OPTS="-Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -server -Xms512m -Xmx512m"


export CATALINA_BASE CATALINA_OPTS CATALINA_PID JAVA_OPTS


/bin/su -p -s /bin/sh finkle $CATALINA_HOME/bin/startup.sh



shutdown.sh


#!/bin/sh


CATALINA_BASE=/home/finkle/instance/svc01

CATALINA_PID=/home/finkle/instance/svc01/svc01.pid


export CATALINA_BASE CATALINA_PID


/bin/su -p -s /bin/sh finkle $CATALINA_HOME/bin/shutdown.sh


※ 2번 instance도 위와 같은 과정을 따라한다.



도움받은 곳 : 

http://linux.systemv.pe.kr/tomcat-multi-instance-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0/


https://beyondj2ee.wordpress.com/2012/07/03/%EB%A9%80%ED%8B%B0-%ED%86%B0%EC%BA%A3-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%EB%A1%9C-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0-multiple-tomcat-instances/


무료로 SSL 인증서를 배포하는 wosign(회원가입 필요)에서 인증서를 생성해 Tomcat 서버에 적용하는 과정에서 몇 번의 삽질 끝에 성공한 절차를 기록해본다.



1. 개인키 파일 생성

# keytool -genkey -keyalg RSA -sigalg SHA1withRSA -alias mySSL -keysize 2048 -keystore mySSL.jks


키 저장소 비밀번호 입력:  

새 비밀번호 다시 입력: 

이름과 성을 입력하십시오.

  [Unknown]:  Finkle

조직 단위 이름을 입력하십시오.

  [Unknown]:  Finkle

조직 이름을 입력하십시오.

  [Unknown]:  RND

구/군/시 이름을 입력하십시오?

  [Unknown]:  Seoul

시/도 이름을 입력하십시오.

  [Unknown]:  Seoul

이 조직의 두 자리 국가 코드를 입력하십시오.

  [Unknown]:  KR

CN=Finkle, OU=Finkle, O=RND, L=Seoul, ST=Seoul, C=KR이(가) 맞습니까?

  [아니오]:  y


<mySSL>에 대한 키 비밀번호를 입력하십시오.

(키 저장소 비밀번호와 동일한 경우 Enter 키를 누름):  

새 비밀번호 다시 입력:


2. 생성된 파일 확인

# keytool -list -keystore mySSL.jks 


3. CSR 생성

# keytool -certreq -alias mySSL -keyalg RSA -sigalg SHA1withRSA -file mySSL.csr -keystore mySSL.jks

키 저장소 비밀번호 입력: 


4. https://buy.wosign.com/free/ 접속 후 위에서 생성한 CSR 파일 내용 붙여넣기


5. zip 파일 다운로드

mydomain.co.kr_sha256_en.zip


6. 압축 파일 내 [for Other Server.zip] 파일의 내용 추출 후 적용대상 서버에 업로드

root.crt

1_cross_Intermediate.crt

2_issuer_Intermediate.crt

3_user_mydomain.co.kr.crt


7. Tomcat에 적용할 정보 키스토어 파일에 적용

# keytool -import -trustcacerts -alias WoSignROOT -file root.crt -keystore mySSL.jks

# keytool -import -trustcacerts -alias CrossINTER -file 1_cross_Intermediate.crt -keystore mySSL.jks

# keytool -import -trustcacerts -alias IssuerINTER -file 2_issuer_Intermediate.crt -keystore mySSL.jks

# keytool -import -alias mySSL-file 3_user_mydomain.co.kr.crt -keystore mySSL.jks



8. 내용 확인

# keytool -list -v -keystore mySSL.jks


9. 톰캣 설정 파일 변경

$ vi server.xml

<Connector port="443" protocol="HTTP/1.1"

       maxThreads="150" SSLEnabled="true" scheme="https" secure="true"

       clientAuth="false" sslProtocol="TLS" 

       keystoreFile="/home/path/tools/ssl/mySSL.jks" keystorePass="xxxx" />


10. 톰캣 재기동

503 에러는 사용자 폭주시 일시적으로 발생하는 에러라고 구글이 알려줌.


그러나 나에게 주어진 상황은 이와 달라 원인찾는데 애먹음.


현상 : 

특정 페이지를 방문한 후 다른 페이지를 방문할 시 503 에러가 발생함

다른 페이지에서 방문할 경우는 이상 없음


원인 :

해당 페이지 내  삽입된 이미지에서 404 에러 발생 후 타 페이지 이동시 발생하는 현상으로 파악됨


조치 :

이미지에서 200 코드 나오도록 수정함



※ 톰캣에서는 정상이나 제우스에서만 발생하는 현상이라 원인찾기 힘들었음. 아마 웹투비 쪽 설정상의 문제가 아닐까 추정함.




간단하게 서버 부하를 점검할 수 있는 무료 툴


http://openwebload.sourceforge.net


윈도용은 설치는 따로 필요없고 사용법도 간단함

톰캣 설정
context-1.xml
<Context crossContext="true" .... 생략

context-2.xml 
<Context crossContext="true" .... 생략

테스트
context-1.jsp 

<%

    ServletContext ctx = application.getContext("/context-1");

    Integer counter = (Integer)ctx.getAttribute("counter");

    if (counter == null) {

        counter = 0;

    }

    counter++;

    

    request.setAttribute("counter", counter);

    ctx.setAttribute("counter", counter);

%>


<h1>Context-1</h1>

<h1>현재 카운터는 ${counter}입니다.</h1>


context-2.jsp

<%

    ServletContext ctx = application.getContext("/context-1");

    Integer counter = (Integer)ctx.getAttribute("counter");

    if (counter == null) {

        counter = 0;

    }

    counter++;

    

    request.setAttribute("counter", counter);

    ctx.setAttribute("counter", counter);

%>


<h1>Context-1</h1>

<h1>현재 카운터는 ${counter}입니다.</h1>


출처 : http://jee-bpel-soa.blogspot.com/2009/06/session-sharing-in-apache-tomcat.html
 

 
Sitemesh 2.4.1 버전은 기존의 PageFilter가 SitemeshFilter로 바뀌었다.

이번 버전에서는 아래와 같은 에러가 데코레이션 되는 URL에서는 발생하지 않지만 데코레이션 되지 않는 URL에서는 여전히 발생한다.

ProtocolException : Didn't meet stated Content-Length

Sitemesh 이전 버전에서의 해결방법은 http://finkle.tistory.com/56 게시글 참조

Sitemesh 2.4.1 버전에서 해결방법은 아래와 같다.
com.opensymphony.sitemesh.webapp.decorator.NoDecorator 클래스를 아래와 같이 수정한다.

if (Container.get() != Container.WEBLOGIC) {
    response.setContentLength(content.originalLength());
}

또 하나, 보통 SpringMVC 3.0에서 Annotation을 통해 JSTL View를 지정하여 화면을 렌더링 하는데 Sitemesh 데코레이션 파일에 설정된 URL을 Weblogic에서는 제대로 인식하지 못한다.

아래 설정정보는 Tomcat에서 잘 작동하는 데코레이션 설정인데 Weblogic에서는 데코레이션 되지 않는다.

decoration.xml

<decorator name="xxxx_manage" page="xxxx/common/decorator/xxxx_manage.jsp">
    <pattern>/manage/**/xxxx_*.do</pattern>
</decorator>

해결방법은 아래와 같다.

<decorator name="xxxx_manage" page="manage/common/decorator/xxxx_manage.jsp">
    <pattern>/manage/**/xxxx_*.do</pattern>
    <pattern>/WEB-INF/view/manage/**/xxxx_*</pattern> <!-- For weblogic -->
</decorator>


Tomcat에서 정상 동작하던 것이 Weblogic 전환 시 문제가 발생한다.

Weblogic은 ....
1. include 되는 녀석의 contentType 중복을 허용하지 않음

버전 8,1의 경우에는 ....
2. JSTL 1.0만 지원함
[1.1 버젼] : <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
[1.0 버젼] : <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>


3. Sevlet 2.3만 지원함 (Sevlet 2.4 -> http://www.okjsp.pe.kr/seq/30536)
[2.4 버젼] : <!DOCTYPE web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
[2.3 버젼] : <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

Sitemesh와 통합했을 경우에는 ....
4. Didn't meet stated Content-Length 에러 발생
: response.setContentLength의 크기가 Sitemesh에 의해 변하는 것을 Weblogic은 허용하지 않고 에러를 발생시킨다.

com.opensymphony.module.sitemesh.filter.PageFilter 클래스 아래와 같이 변경함
    if (Container.get() != Container.WEBLOGIC) {
        response.setContentLength(page.getContentLength());
    }

※ 아울러 한글 Window OS에서 UTF-8 인코딩 설정 시 한글 문제 아직 미해결 함 (이것 역시 Sitemesh와의 문제인 듯 ....)

+ Recent posts