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분에 인증서를 갱신하고 아파치를 재기동 할 수 있다.


현상

eclipse에서 변경파일을 커밋하려고 하는데 locked 관련 오류가 나면서 커밋이 안된다.


원인

이전에 커밋할려다 시간이 오래걸려서 eclipse를 강제로 재시작한 경우가 있다. 이때 커밋대상 파일에 대해 lock이 걸렸을 것으로 추정함


해결

1. 프로젝트 우클릭 > team > cleanup

=> 실패 : 아무런 반응 없음


2. 대상 파일 삭제후 서버에서 다시 업데이트 받음

=> 실패 : lock이 걸려서 파일 삭제 불가


3. sqlite 클라이언트 다운로드

http://sqlitebrowser.org/ : 다운로드 속도가 안될 경우 아래 주소에서 다운로드

https://sourceforge.net/projects/sqlitedbrowser/ : 위 주소보다 버전은 낮지만 작업하는데 문제는 없다.


- 로컬 PC에 설치(압축해제)한 후 프로그램 실행

- File > Open Database > 대상 프로젝트 루트 경로의 .svn 폴더 아래에 있는 wc.db 파일을 선택

- Execute SQL 탭을 선택 후 아래 SQL 실행


DELETE FROM WORK_QUEUE;


=> 실패 : 대상 자료가 없음


4. 아래 SQL 실행


DELETE FROM WC_LOCK;


=> 성공 : 1개 데이타 삭제함


※ 혹시 그래도 안되면 4번까지 실행 후 1번 재실행




지난번 [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 코드 나오도록 수정함



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




Exception Handling in Spring MVC


http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc


시간날때 적용 해봐야겠다.

빠른 HTML과 CSS 작성을 위해 필요한 플러그인이다.


기존의 CSS 셀렉터 기술만 알고 있으면 되며 더 배워야 할 건 거의 없다.


1. 이클립스 업데이트 URL을 통해 zen-conding 설치

http://zen-coding.ru/eclipse/updates/


[사용법]

빈 문서를 하나 열어서 

div#header


라고 입력한 후 Ctrl + E !!


결과는

<div id="header"></div>


뭐하는 놈인지 대충 알겠죠?


자세한 사용법은 아래 치트시트 문서 참조 !!


2. 치트시트 PDF 문서 다운로드

http://www.aether.ru/files/zencoding.pdf

java 태스크

<target name="run" depends="compile">       

    <java classname="com.some.package.path.BootStrap" 

          classpathref="classpath" 

          fork="true" 

          failonerror="true">

        <jvmarg value="-Dcom.sun.management.jmxremote=true"/>

        <jvmarg value="-Dcom.sun.management.jmxremote.port=9999"/>

        <jvmarg value="-Dcom.sun.management.jmxremote.authenticate=false"/>

        <jvmarg value="-Dcom.sun.management.jmxremote.ssl=false"/>

        <classpath>

            <pathelement path="${dist.dir}/classes"/>

        </classpath>

    </java>

</target>


jar 태스크

<target name="jar" depends="compile">

    <delete>

        <fileset dir="${dist.dir}" includes="output-jar-name.jar"/>

    </delete>

    <jar jarfile="${dist.dir}/output-jar-name.jar">

        <fileset dir="${classes.dir}">

            <include name="com/some/package/path/**/*.class" />

            <include name="com/some/package/path/**/*.xml" />

            <include name="resources/**/*.*" />

        </fileset>

        <manifest>

            <attribute name="Built-By" value="owner"/>

            <attribute name="Main-Class" value="com.some.package.path.BootStrap"/>

            <attribute name="Class-Path" value="

                ../lib/aopalliance-1.0.jar

                ../lib/commons-beanutils-1.6.jar

                ../lib/commons-collections-3.2.jar

                ../lib/commons-configuration-1.8.jar

                ../lib/commons-dbcp-1.2.2.jar

                ../lib/commons-lang-2.6.jar

                ../lib/commons-logging-1.1.1.jar

                ../lib/commons-pool-1.3.jar

                ../lib/ibatis-sqlmap-2.3.4.726.jar

                ../lib/java-gearman-service-0.6.3.jar

                ../lib/log4j-1.2.16.jar

                ../lib/mysql-connector-java-5.1.19.jar

                ../lib/org.springframework.aop-3.1.1.RELEASE.jar

                ../lib/org.springframework.asm-3.1.1.RELEASE.jar

                ../lib/org.springframework.beans-3.1.1.RELEASE.jar

                ../lib/org.springframework.context.support-3.1.1.RELEASE.jar

                ../lib/org.springframework.context-3.1.1.RELEASE.jar

                ../lib/org.springframework.core-3.1.1.RELEASE.jar

                ../lib/org.springframework.expression-3.1.1.RELEASE.jar

                ../lib/org.springframework.jdbc-3.1.1.RELEASE.jar

                ../lib/org.springframework.orm-3.1.1.RELEASE.jar

                ../lib/org.springframework.transaction-3.1.1.RELEASE.jar

                ../lib/slf4j-api-1.6.4.jar

                ../lib/slf4j-log4j12-1.6.5.jar"/>

        </manifest>

    </jar>

</target>


J2EE Servlet 명세에서 인코딩된(content type : application/x-www-form-urlencoded) HTTP PUT 메소드는 지원하지 않기 때문에 폼에 값을 담은 후 PUT으로 서버에 전송할 경우 Command Object 바인딩이 자동으로 되지 않는다.


해결책은 아래와 같다. 


자료 찾느라 열라 고생함 ㅠㅠ 

(아직 spring 기반의 RESTful 서비스가 많지 않아서 그런가? 아님 너무 당연해서 나만 몰랐던 건가?)


출처 : http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html

16.3.3.11 Working with "application/x-www-form-urlencoded" data

The previous sections covered use of @ModelAttribute to support form submission requests from browser clients. The same annotation is recommended for use with requests from non-browser clients as well. However there is one notable difference when it comes to working with HTTP PUT requests. Browsers can submit form data via HTTP GET or HTTP POST. Non-browser clients can also submit forms viaHTTP PUT. This presents a challenge because the Servlet specification requires the ServletRequest.getParameter*() family of methods to support form field access only for HTTP POST, not for HTTP PUT.

To support HTTP PUT requests, the spring-web module provides the filter HttpPutFormContentFilter, which can be configured in web.xml:

<filter>
  <filter-name>httpPutFormFilter</filter-name>
  <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>httpPutFormFilter</filter-name>
  <servlet-name>dispatcherServlet</servlet-name>
</filter-mapping>

<servlet>
  <servlet-name>dispatcherServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>

The above filter intercepts HTTP PUT requests with content type application/x-www-form-urlencoded, reads the form data from the body of the request, and wraps the ServletRequest in order to make the form data available through the ServletRequest.getParameter*() family of methods.


참고 : http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/filter/HttpPutFormContentFilter.html




+ Recent posts