참고 : http://www.techstacks.com/howto/disable-http-methods-in-tomcat.html

참고 : http://tyboss.tistory.com/entry/Tomcat-Authorization-Authentication-webxml


Tomat 환경파일 또는 Application의 web.xml에 아래 코드 추가 후 Restart

// Sample Security Constraint
<security-constraint>
  <web-resource-collection>
      <web-resource-name>restricted methods</web-resource-name>
      <url-pattern>/*</url-pattern>
      <http-method>PUT</http-method>
      <http-method>POST</http-method>
      <http-method>DELETE</http-method>
      <http-method>OPTIONS</http-method>
      <http-method>TRACE</http-method>
  </web-resource-collection>
  <auth-constraint />
</security-constraint> 


http-method 에 선언한 method 는 접근이 제한된다.

HTTP Method 목록 : http://ko.wikipedia.org/wiki/HTTP

(OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT)


출처 : http://hmjkor.tistory.com/408

참고 : https://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html

apache tomcat 5.5 이후 버전에서의 Context 생성 방법입니다.


server.xml 파일을 열게 되면 xml Tag가 Service라는 태그의 속성명 name을 찾습니다.

일반적으로는  <Service name="Catalina"> 이렇게 되어 있습니다.


먼저 context를 만들기 위한 폴더를 생성합니다.

service 태그의 name값인 Catalina 폴더를 만들고 다시 그 안에 localhost 라는 폴더를 만듭니다.

최종적으로는 위에 내용대로라면 톰캣경로/conf/Catalina/localhost가 되겠네요


그럼 이제 이하위에 파일을 생성하시면 되는데 파일은 xml 형식입니다.

root Context는 ROOT.xml을 만드시면 되고 기타 context는 컨텍스트명.xml파일로 만드시면 됩니다.


파일이 생성이 되었으면 이제 관련 설정을 파일에 추가하면 됩니다.

test라는 컨텍스트를 만들게 되면 아래와 같은 형식이 되겠습니다.


server.xml

<?xml version='1.0' encoding='utf-8'?>
<Context path="/test"
         docBase="/home/test/web"
         debug="0"
         reloadable="true"
         crossContext="true">

<Valve className="org.apache.catalina.valves.AccessLogValve"
            directory="/home/test/logs/access"
            prefix="access."
            suffix=".log"
            pattern="common"
            fileDateFormat="yyyy-MM-dd"
            resolveHosts="false"/>
    <Resource name="jdbc/my" auth="Container"
                        type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver"
                        url="jdbc:mysql://[ip]:[port]/[db명]?zeroDateTimeBehavior=convertToNull"
                        username="[username]" password="[password]"
                        loginTimeout="10" maxActive="50"
                        maxIdle="10" maxWait="-1" />
</Context> 


<Resource name="jdbc/oracle" auth="Container" type="javax.sql.DataSource"
    driverClassName="oracle.jdbc.OracleDriver"
    url="jdbc:oracle:thin:@DB_IP:DB_PORT:DB_SID"
    username="아이디" password="비밀번호" maxTotal="20" maxIdle="10" />




Note that the resource name (here, jdbc/EmployeeDB) must match the value specified in the web application deployment descriptor.

This example assumes that you are using the HypersonicSQL database JDBC driver. Customize the driverClassName and driverName parameters to match your actual database's JDBC driver and connection URL.

The configuration properties for Tomcat's standard data source resource factory (org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory) are as follows:

  • driverClassName - Fully qualified Java class name of the JDBC driver to be used.
  • username - Database username to be passed to our JDBC driver.
  • password - Database password to be passed to our JDBC driver.
  • url - Connection URL to be passed to our JDBC driver. (For backwards compatibility, the property driverName is also recognized.)
  • initialSize - The initial number of connections that will be created in the pool during pool initialization. Default: 0
  • maxTotal - The maximum number of connections that can be allocated from this pool at the same time. Default: 8
  • minIdle - The minimum number of connections that will sit idle in this pool at the same time. Default: 0
  • maxIdle - The maximum number of connections that can sit idle in this pool at the same time. Default: 8
  • maxWaitMillis - The maximum number of milliseconds that the pool will wait (when there are no available connections) for a connection to be returned before throwing an exception. Default: -1 (infinite)

Some additional properties handle connection validation:

  • validationQuery - SQL query that can be used by the pool to validate connections before they are returned to the application. If specified, this query MUST be an SQL SELECT statement that returns at least one row.
  • validationQueryTimeout - Timeout in seconds for the validation query to return. Default: -1 (infinite)
  • testOnBorrow - true or false: whether a connection should be validated using the validation query each time it is borrowed from the pool. Default: true
  • testOnReturn - true or false: whether a connection should be validated using the validation query each time it is returned to the pool. Default: false

The optional evictor thread is responsible for shrinking the pool by removing any connections which are idle for a long time. The evictor does not respect minIdle. Note that you do not need to activate the evictor thread if you only want the pool to shrink according to the configured maxIdle property.

The evictor is disabled by default and can be configured using the following properties:

  • timeBetweenEvictionRunsMillis - The number of milliseconds between consecutive runs of the evictor. Default: -1 (disabled)
  • numTestsPerEvictionRun - The number of connections that will be checked for idleness by the evictor during each run of the evictor. Default: 3
  • minEvictableIdleTimeMillis - The idle time in milliseconds after which a connection can be removed from the pool by the evictor. Default: 30*60*1000 (30 minutes)
  • testWhileIdle - true or false: whether a connection should be validated by the evictor thread using the validation query while sitting idle in the pool. Default: false

Another optional feature is the removal of abandoned connections. A connection is called abandoned if the application does not return it to the pool for a long time. The pool can close such connections automatically and remove them from the pool. This is a workaround for applications leaking connections.

The abandoning feature is disabled by default and can be configured using the following properties:

  • removeAbandoned - true or false: whether to remove abandoned connections from the pool. Default: false
  • removeAbandonedTimeout - The number of seconds after which a borrowed connection is assumed to be abandoned. Default: 300
  • logAbandoned - true or false: whether to log stack traces for application code which abandoned a statement or connection. This adds serious overhead. Default: false

Finally there are various properties that allow further fine tuning of the pool behaviour:

  • defaultAutoCommit - true or false: default auto-commit state of the connections created by this pool. Default: true
  • defaultReadOnly - true or false: default read-only state of the connections created by this pool. Default: false
  • defaultTransactionIsolation - This sets the default transaction isolation level. Can be one of NONEREAD_COMMITTEDREAD_UNCOMMITTEDREPEATABLE_READSERIALIZABLE. Default: no default set
  • poolPreparedStatements - true or false: whether to pool PreparedStatements and CallableStatements. Default: false
  • maxOpenPreparedStatements - The maximum number of open statements that can be allocated from the statement pool at the same time. Default: -1 (unlimited)
  • defaultCatalog - The name of the default catalog. Default: not set
  • connectionInitSqls - A list of SQL statements run once after a Connection is created. Separate multiple statements by semicolons (;). Default: no statement
  • connectionProperties - A list of driver specific properties passed to the driver for creating connections. Each property is given as name=value, multiple properties are separated by semicolons (;). Default: no properties
  • accessToUnderlyingConnectionAllowed - true or false: whether accessing the underlying connections is allowed. Default: false

For more details, please refer to the commons-dbcp documentation.




만약 다른 도메인이나 서브 도메인이 생성되어야 한다면

server.xml에 신규 HOST를 추가한다.

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
    기존 도메인 내용이 있음
</Host>
<!-- 신규로 추가되는 서브 도메인 -->
<Host name="test.anaconda.pe.kr" appBase="webapps" unpackWARs="true" autoDeploy="true">
</Host>



그리고 /conf/Catalina/폴더 아래에 test.anaconda.pe.kr라는 폴더를 만든다.

/conf/Catalina/test.anaconda.pe.kr와 같은 폴더를 가진다.

그리고 그 아래에 ROOT.xml파일을 만들고 context 정보를 넣어주면 된다.



출처 : http://blog.nekrs.com/195


Tomcat 서버에서 로그인 페이지처럼 특정 페이지는 HTTPS를 이용하고, 나머지 페이지는 HTTP를 사용하려고 한다. 이때 HTTPS->HTTP로 이동하면서 세션은 공유되지 않는 문제가 있다. 다음은 이 문제를 해결하는 방법 중 하나이다.

RequestWrapper 클래스를 하나 만듭니다. 이 클래스는 HTTPS 요청일 경우 쿠키에 세션 정보를 조작하는 역할을 합니다.

 public class HttpsRequestWrapper extends HttpServletRequestWrapper{
 private HttpServletResponse response = null;
 public HttpsRequestWrapper (HttpServletRequest request) {
  super(request);
 }
 public void setResponse (HttpServletResponse response) {
  this.response = response;
 }
 public HttpSession getSession () {
  HttpSession session = super.getSession();
  processSessionCookie(session);
  return session;
 }
 public HttpSession getSession (boolean create) {
  HttpSession session = super.getSession(create);
  processSessionCookie(session);
  return session;
 }
 private void processSessionCookie (HttpSession session) {
  if (null == response || null == session)  return;

  Object cookieOverWritten = getAttribute("COOKIE_OVERWRITTEN_FLAG");
  if (null == cookieOverWritten && isSecure() && isRequestedSessionIdFromCookie() && session.isNew())  {
   Cookie cookie = new Cookie("JSESSIONID", session.getId());
   cookie.setMaxAge(-1);
   String contextPath = getContextPath();
   if ((contextPath != null) && (contextPath.length() > 0))   {
    cookie.setPath(contextPath);
   }   else   {
    cookie.setPath("/");
   }  
   response.addCookie(cookie);
   setAttribute("COOKIE_OVERWRITTEN_FLAG", "true");
  }
 }
}

그리고 Filter 클래스를 만듭니다. 이 필터는 기본 Request를 HttpsRequestWrapper로 변경하는 역할을 합니다. 그리고 이 필터는 다른 필터보다 우선 실행되어야 합니다.

public class HttpsFilter implements Filter{
 public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
   HttpsRequestWrapper httpsRequest = new HttpsRequestWrapper((HttpServletRequest)request);
   httpsRequest.setResponse((HttpServletResponse)response);
   chain.doFilter(httpsRequest, response);
 }




 


참고 : http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
       https://tomcat.apache.org/tomcat-7.0-doc/config/http.html
       https://access.redhat.com/solutions/1232233
      http://www.sysnet.pe.kr/Default.aspx?mode=2&sub=0&detail=1&pageno=0&wid=1132&rssMode=1&wtype=0
       https://www.comodossl.co.kr/Certificate/InstallGuide/Apache.htm
       http://minix.tistory.com/395
       http://charmpa.egloos.com/1535479
        https://www.comodossl.co.kr/certificate/ssl-installation-guides/Tomcat-csr-crt.aspx



무료 인증기관 : http://t.co/1nFgVLJd


1. keystore 파일 생성

jdk/bin 폴더로 이동
keytool -genkey -alias tomcat -keyalg RSA -keystore tomcat.keystore

키 저장소 비밀번호 입력:
새 비밀번호 다시 입력:
이름과 성을 입력하십시오.
 [Unknown]:  maruara
조직 단위 이름을 입력하십시오.
 [Unknown]:
조직 이름을 입력하십시오.
 [Unknown]:
구/군/시 이름을 입력하십시오?
 [Unknown]:
시/도 이름을 입력하십시오.
 [Unknown]:  seoul
이 조직의 두 자리 국가 코드를 입력하십시오.
 [Unknown]:  KR
N=maruara, OU=Unknown, O=Unknown, L=Unknown, ST=seoul, C=KR이(가) 맞습니까?
 [아니오]:  y

tomcat>에 대한 키 비밀번호를 입력하십시오.
       (키 저장소 비밀번호와 동일한 경우 Enter 키를 누름):


2. tomcat - server.xml 설정 추가

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystorePass="tomcat" keystoreFile="C:/Program Files/Java/jdk1.7.0_25/bin/tomcat.keystore"
                />


참고 : Jboss

<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true" enable-lookups="false">
    <ssl name="ombs-ssl" key-alias="Key Alias" password="비밀번호" certificate-key-file="/etc/pki/tls/private/ombs.keystore" protocol="TLSv1" verify-client="false" keystore-type="JKS" />
</connector>
<!-- ALL,SSLv2,SSLv3,TLSv1,TLSv1.1,TLSv1.2 --> 



3. 접속 테스트

https://localhost:8443/ 



===========================================================================================


# Tomcat 버젼 7.X 의 경우..
< -- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector port="8443"
   maxThreads="200"
   scheme="https" secure="true" SSLEnabled="true"
   keystoreFile="키스토어파일경로/hanbiro.key" keystorePass="(hanbiro.key 패스워드)" clientAuth="false" sslProtocol="TLS" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"

/>

# Tomcat 버젼 6.X 의 경우..
<!--Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector port="443"
   maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true"
   acceptCount="100" debug="0" scheme="https" secure="true" SSLEnabled="true"  clientAuth="false" sslProtocol="TLS"
   keystoreFile="키스토어파일경로/hanbiro.key" keystorePass="(hanbiro.key 패스워드)" 
/>

# Tomcat 버젼 5.X 의 경우..
<!--Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector port="443"
   maxThreads="150" minSpareThreads="25" maxSpareThreads="75"  enableLookups="false" disableUploadTimeout="true"
   acceptCount="100" debug="0" scheme="https" secure="true"  clientAuth="false" sslProtocol="TLS"
   keystoreFile="키스토어파일경로/hanbiro.key"  keystorePass="(hanbiro.key 패스워드)" 
/>

# Tomcat 버전 4.X 의 경우.
<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector" port="443" minProcessors="5" maxProcessors="75"
  enableLookups="true"  acceptCount="100" debug="0" scheme="https" secure="true"
  useURIValidationHack="false" disableUploadTimeout="true" />
<Factory className="org.apache.coyote.tomcat4.CoyoteServerSocketFactory"
  clientAuth="false" protocol="TLS"  keystoreFile="키스토어파일경로/hanbiro.key"  keystorePass="(hanbiro.key 패스워드)" 
/>


SSL, TLS 보안 관련 : http://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/SSL-on-an-instance.html

SSLProtocol -SSLv2 -SSLv3 +TLSv1 +TLSv1.1 +TLSv1.2



=====================================================================

출처 : http://firstboos.tistory.com/entry/SSL-cipher-suite-order-%EC%A1%B0%EC%A0%95


웹 브라우저로 https:// 주소로 접속할때, 클라이언트와 서버 간에 교환하는 보안 알고리즘 집합인 cipher suite 의 우선 순위를 조정할 필요가 생긴다. 주로 메시지 인증 알고리즘을 sha2 로 바꿔달라는 요구사항이 발생한다. (쇼핑몰, 특히 CC 인증 ㅠㅠ 요구사항인 경우가 많다.)


인증서 생성

- Tomcat : JKS 타입

# keytool -genkey -alias KeystoreAlias -keysize 2048 -keyalg RSA -keystore mykeystore -dname "CN=mycompany.com, OU=webteam, O=MyCompany, L=seoul, ST=seoul, C=kr"

-> 키 교환 알고리즘이 RSA, 키 사이즈는 2048 로 설정

※ keytool 은 keysize 2048 로 설정하면 서명 알고리즘이 sha256 으로 설정된다. 


- Tomcat : PKCS12  타입

1. openssl req -nodes -sha256 -newkey rsa:2048 -keyout server.key -out server.csr -subj "/C=kr/ST=seoul/L=seoul/O=MyCompany/OU=webteam/CN=mycompany.com"

-> 키 교환 알고리즘이 RSA, 키 사이즈는 2048 , 서명 알고리즘은 sha256 으로 설정.

-> server.key : 서버 개인키(private key), server.csr : 서버 인증 요구서.


2. openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt -sha256

-> -sha256 : 서명 알고리즘은 sha256  으로 설정. 만일 이 옵션이 없으면 sha1 으로 설정된다.

-> server.crt : self signed 인증서.


3. openssl pkcs12 -export -in server.crt -inkey server.key -out mykeystore

-> 1,2 번에서 생성한 파일들을 가지고 PKCS12 타입으로 키저장소(mykeystore) 파일 생성.


- Apache HTTPD

1. openssl req -nodes -sha256 -newkey rsa:2048 -keyout server.key -out server.csr -subj "/C=kr/ST=seoul/L=seoul/O=MyCompany/OU=webteam/CN=mycompany.com"

-> 키 교환 알고리즘이 RSA, 키 사이즈는 2048 , 서명 알고리즘은 sha256 으로 설정.

-> server.key : 서버 개인키(private key), server.csr : 서버 인증 요구서.


2. openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt -sha256

-> -sha256 : 서명 알고리즘은 sha256  으로 설정. 만일 이 옵션이 없으면 sha1 으로 설정된다.

-> server.crt : self signed 인증서.


3. openssl x509 -in server.crt -noout -text

-> 인증서 내용 확인

-> -noout : PEM 부분을 출력안하도록 설정.


Tomcat 설정

- server.xml 설정 : GCM 이 선택되도록 하기 위해서는 sslProtocol TLSv1.2 로 선택해야함.

        <Connector port="443" protocol="HTTP/1.1" URIEncoding="UTF-8" useBodyEncodingForURI="true"

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

                clientAuth="false" SSLEnabled="true" sslProtocol="TLSv1.2" sslEnabledProtocols="TLSv1.2"

                  ciphers="TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA"

                keystoreFile="${catalina.home}/conf/mykeystore" keyAlias="KeystoreAlias"

                keystoreType="JKS" keystorePass="키스토어패스워드" />


- server.xml 설정 2 : 어떤 환경에서는 sslProtocol 을 TLS 로 설정해야 연결되는 경우도 있다. 

<Connector port="443" protocol="HTTP/1.1" URIEncoding="UTF-8" useBodyEncodingForURI="true"

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

                clientAuth="false" SSLEnabled="true" sslProtocol="TLS"

          ciphers="TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA"

                keystoreFile="${catalina.home}/conf/mykeystore"                keyAlias="KeystoreAlias"

                keystoreType="JKS" keystorePass="키스토어패스워드" />


- server.xml 설정 3 : IE11 에서 "TLS_RSA_WITH_AES_256_CBC_SHA256" 먼저 선택되도록 하기 위한 설정.(크롬 브라우저에서는 TLS_RSA_WITH_AES_256_CBC_SHA 가 선택된다.)

<Connector port="443" protocol="HTTP/1.1" URIEncoding="UTF-8" useBodyEncodingForURI="true"

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

                clientAuth="false" SSLEnabled="true" sslProtocol="TLS"

                ciphers="TLS_ECDH_RSA_WITH_AES_256_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA"

                keystoreFile="${catalina.home}/conf/mykeystore" keyAlias="KeystoreAlias"

                keystoreType="JKS" keystorePass="키스토어패스워드" />



※ cipher : 공개키 알고리즘(RSA, Diffie-Hellman, ...) + 대칭키 알고리즘(RC4, DES, AES, ...) + 해쉬 알고리즘(MD5, SHA, ...)의 집합


Apache 설정

# yum install httpd

# yum install mod_ssl


httpd.conf 설정

<VirtualHost *:443>

    SSLEngine on

    SSLCertificateFile /etc/httpd/conf/server.crt

    SSLCertificateKeyFile /etc/httpd/conf/server.key

    SSLCertificateChainFile /etc/httpd/conf/server.csr

    SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

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

    DocumentRoot /var/www.html

    SSLProtocol             all

    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:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK

    SSLHonorCipherOrder     on

#    SSLCompression          off

</VirtualHost>


테스트

IE 11 브라우저에서는 https:// 로 접속시,  443 포트 패킷을 캡쳐해보면 SSL handshake 과정에서 "Server Hello" 가 "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256" 로 응답하는 것을 확인했다. 

그런데, 이해가 안되지만 크롬 최신버전(37.0.2062.120 m)에서는 동일한 인증서 파일인데도  "Server Hello" 가 "TLS_DHE_RSA_WITH_AES_128_GCM_SHA1" 으로 응답했다. 


- openssl 으로 접속 테스트

# openssl s_client -connect localhost:443

CONNECTED(00000003)

depth=0 C = kr, ST = seoul, L = seoul, O = MyCompany, OU = webteam, CN = mycompany.com

verify error:num=18:self signed certificate

verify return:1

depth=0 C = kr, ST = seoul, L = seoul, O = MyCompany, OU = webteam, CN = mycompany.com

verify return:1

...

...

...

---

SSL handshake has read 1463 bytes and written 477 bytes

---

New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384

Server public key is 2048 bit

Secure Renegotiation IS supported

Compression: NONE

Expansion: NONE

SSL-Session:

    Protocol  : TLSv1.2

    Cipher    : ECDHE-RSA-AES256-SHA384

    Session-ID: 541C0297D25D7219750A92F8D17EE82762D7505C79B96F58DECFBF2D420D5FBF

    Session-ID-ctx:

    Master-Key: C50822A4CA025BE58961E3427F8A6F9F04B5F954B9F1D6C1A091D12CF91DE4BF06BDF77F0CEEDB96FB0BC617E60E3EC2

    Key-Arg   : None

    Krb5 Principal: None

    PSK identity: None

    PSK identity hint: None

    Start Time: 1411121874

    Timeout   : 300 (sec)

    Verify return code: 18 (self signed certificate)



openssl version

CentOS 5.X 대는 기본 설치되어 있는 openssl(라이브러리가 아닌 실행 프로그램이다) 의 버전이 0.9.8e 이다. 접속하려고 하면 다음과 같은 오류가 날수 있다. openssl 의 버그일 가능성이 높다.

# openssl s_client -connect localhost:443

CONNECTED(00000003)

31789:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:583: 


무시하고 1.X 버전의 openssl 에서 테스트해보자. openssl 을 업데이트한다.(yum update openssl) 

# openssl s_client -connect localhost:443

CONNECTED(00000003)

depth=0 C = kr, ST = seoul, L = seoul, O = MyCompany, OU = webteam, CN = mycompany.com

verify error:num=18:self signed certificate

verify return:1

depth=0 C = kr, ST = seoul, L = seoul, O = MyCompany, OU = webteam, CN = mycompany.com

verify return:1

139902702569288:error:100AE081:elliptic curve routines:EC_GROUP_new_by_curve_name:unknown group:ec_curve.c:316:

139902702569288:error:1408D010:SSL routines:SSL3_GET_KEY_EXCHANGE:EC lib:s3_clnt.c:1641:


openssl 의 버전이 "openssl-1.0.1e-15.el6_5.15.x86_64" (rpm -qa | grep openssl) 이라면  아마 위의 마지막에 나오는 "error: elliptic curve" 이하의 오류를 볼 수 있을 것이다. 관련 내용을 찾아보면 openssl 버그라고 나온다.

이때에는 openssl 을 업데이트(yum update openssl)하면 오류 메시지가 안 나온다. openssl 의 버전도 확인해보면 중간의 15가 16으로 바뀔것이다.(관련 링크1관련 링크2 )


그외

* 인증서에서 pem 정보만 뽑아내는 스크립트

# echo -n | openssl s_client -connect localhost:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./site.pem



참고한 사이트 :

http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html

https://www.ssllabs.com/ssltest/analyze.html?d=github.com&s=192.30.252.131

http://mail-archives.apache.org/mod_mbox/tomcat-users/201405.mbox/%3CCALAJ+5Aa9_yBJbvJxUwpUM4ytDXSQ+7KHd29+fcvpKfYn6Sk1Q@mail.gmail.com%3E

https://wiki.kldp.org/wiki.php/DocbookSgml/SSL-Certificates-HOWTO

http://opentutorials.org/course/228/4894

http://coffeenix.net/board_view.php?bd_code=1661

https://www.openssl.org/docs/apps/ciphers.html#TLS_v1_2_cipher_suites

+ Recent posts