로그인

Language :
제목MySQL 과 Tomcat 을 SSL 로 연결
글쓴이이지섭작성일2018-11-16수정일2024-01-14조회수5271

  MySQL 과 Tomcat 을 SSL 로 연결하기 위해서는 OPENSSL 프로그램이 설치되어 있어야 한다.

  Openssl 프로그램은 MySQL 에서 사용되고, Java 의 keytool 프로그램은 톰캣 쪽에서 사용된다.

 

1) 아래 2) 번을 참조하여 인증서를 생성합니다. 쉘에서 아래 명령을 실행한다.

  uid 옵션이 없으면 인증서가 인식되지 않으므로 mysql 계정으로 생성되도록 한다.

mysql_ssl_rsa_setup --uid=mysql

 

2) 인증서 생성시 만들어지는 파일들은 다음과 같으며, (폴더 위치 : /var/lib/mysql/ )

  새로 생성할 경우에는 private_key.pem, public_key.pem 두 파일을 제외한 .pem 파일들을 삭제한 후 생성한다.

  이때 다음의 private_key.pem, public_key.pem 두 파일은 삭제되지 않고 그대로 남아 있어야 한다.

ca.pem, ca-key.pem, 
client-cert.pem, client-key.pem,
server-cert.pem, server-key.pem,
private_key.pem, public_key.pem

 

3) 인증서의 유효기간 등을 확인할 때는 다음과 같은 명령어를 사용한다.

  (2) 번은 유효기간에 대한 정보만 간략하게 보는 것이다.

(1)
sudo openssl x509 -in /var/lib/mysql/server-cert.pem -noout -text

(2)
sudo openssl x509 -in /var/lib/mysql/server-cert.pem -noout -dates

 

4) MySQL 설정 파일에 아래의 내용을 입력한 후 재기동 한다.

  이때 인증서를 다른 디렉토리로 복사해 이동된 것을 사용하면 안된다. 원본 인증서를 그대로 사용한다.

[mysqld]

ssl-ca=/var/lib/mysql/ca.pem
ssl-cert=/var/lib/mysql/server-cert.pem
ssl-key=/var/lib/mysql/server-key.pem

 

5) 재기동 후 show variables like '%ssl%'; 명령으로 SSL 연결이 YES 로 나오는지 확인한다.

  YES 로 나올 때만 SSL 연결이 가능하다.

mysql> show variables like '%ssl%';
+--------------------+--------------------------------+
| Variable_name      | Value                          |
+--------------------+--------------------------------+
| have_openssl       | YES                            |
| have_ssl           | YES                            |
| mysqlx_ssl_ca      |                                |
| mysqlx_ssl_capath  |                                |
| mysqlx_ssl_cert    |                                |
| mysqlx_ssl_cipher  |                                |
| mysqlx_ssl_crl     |                                |
| mysqlx_ssl_crlpath |                                |
| mysqlx_ssl_key     |                                |
| ssl_ca             | /var/lib/mysql/ca.pem          |
| ssl_capath         |                                |
| ssl_cert           | /var/lib/mysql/server-cert.pem |
| ssl_cipher         |                                |
| ssl_crl            |                                |
| ssl_crlpath        |                                |
| ssl_fips_mode      | OFF                            |
| ssl_key            | /var/lib/mysql/server-key.pem  |
+--------------------+--------------------------------+
17 rows in set (0.06 sec)

mysql>

 

6) 아래 (1) 명령으로 username1 계정이 SSL 로만 연결되도록 한다.

  테스트 할 때 SSL 연결을 안해도 되도록 하려면, 아래 (2) 와 같이 한다.

(1) 
mysql> alter user 'username1'@'%' require ssl; (2)
mysql> alter user 'username1'@'%' require none;

 

7) MySQL 클라이언트 툴에서 SSL 연결을 설정할 때는, ca.pem, client-cert.pem, client-key.pem 파일을 사용한다.

 

8) 자동 생성된 인증서를 사용하지 않고, 별도의 인증서를 사용하고자 할 경우에는

  인증서를 /var/lib/mysql 디렉토리에 복사해 넣도록 하고,

  복사한 인증서의 소유주를 mysql 로 한다.

chown mysql:mysql *.pem

 

9) 톰캣에서 MySQL 을 연동할 때 사용할 인증서를 아래와 같은 명령으로 등록하고 생성하며 비밀번호를 설정한다.

  java 와 openssl 프로그램이 설치되어 있어야 한다. 각 과정에서 비밀번호를 입력한다.

  생성되는 파일은 truststore 와 mysql-client-keystore.p12 와 keystore 파일이다.

  이 중에서 truststore 파일과 keystore 파일을 사용한다.

(1)
sudo keytool -importcert -alias MySQLCACert -file ./ca.pem -keystore truststore
(2) sudo openssl pkcs12 -export -in /var/lib/mysql/client-cert.pem -inkey /var/lib/mysql/client-key.pem -name "mysqlclient" -out mysql-client-keystore.p12
(3) sudo keytool -importkeystore -srckeystore mysql-client-keystore.p12 -srcstoretype pkcs12 -destkeystore keystore -deststoretype JKS

  (1), (3) 번은 톰캣이 있는 서버에서 작업하고, (2) 번은 MySQL 이 있는 서버에서 작업한다.

 

10) 위 (2)번에서 openssl 프로그램으로 인증서를 생성할 때,

  /var/lib/mysql/ 경로를 지정하여 참조할 인증서를 표시해 주어야 한다.

  java 의 keytool 프로그램을 사용하여 인증서를 import 할 때는 인증서를 복사해 와서 해도 되지만,

  openssl 프로그램으로 인증서를 생성할 때는 복사한 인증서를 사용하면 안되고 원본 인증서를 그대로 사용한다.

 

11) 톰캣의 catalina.sh 파일에 아래의 구문을 입력하여 톰캣에서 인증서를 참조하도록 한다.

  yourPassword 는 9)번 과정에서 입력한 비밀번호를 사용한다.

JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=/home/ubuntu/mysql_certs/truststore"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=yourPassword"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStore=/home/ubuntu/mysql_certs/keystore"
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStorePassword=yourPassword"

 

그런데 위와 같이 하면 어플리케이션 전체에 인증서가 적용이 되어서,

HttpConnection 을 맺으려고 할 때 연결이 실패하는 경우가 발생한다.

그래서 jdbc 연결에서만 인증서를 사용하도록 하는 방식으로 바뀌어야 한다.

 

jdbc:mysql://127.0.0.1:3306/rg?autoReconnect=true
&verifyServerCertificate=true
&useSSL=true
&requireSSL=true
&trustCertificateKeyStoreUrl=file:///home/ubuntu/mysql_certs/truststore
&trustCertificateKeyStorePassword=yourPassword
&clientCertificateKeyStoreUrl=file:///home/ubuntu/mysql_certs/keystore
&clientCertificateKeyStorePassword=yourPassword

 

jdbc connection URL 을 위와 같이 하여 DB 와 연결을 하면,

어플리케이션에는 영향을 주지 않고, DB 연결에만 해당 인증서를 사용할 수 있다.

 

12) 톰캣 연결할 때의 옵션은 다음과 같다.

  %TOMCAT_HOME%/conf/context.xml 파일에 작업한다. DataSource 설정이다.

  MySQL 은 SSL 연결할 때 3306 포트를 기본으로 사용한다.

<Context>

<!-- Uncomment this to disable session persistence across Tomcat restarts --> <Manager pathname="" /> <Resource name="jdbc/MySQLDB" auth="Container" type="javax.sql.DataSource" factory="org.apache.commons.dbcp2.BasicDataSourceFactory" username="username1" password="password1" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/dbName?autoReconnect=true&amp;verifyServerCertificate=true&amp;useSSL=true&amp;requireSSL=true" url="jdbc:mysql://127.0.0.1:3306/dbName?autoReconnect=true&amp;verifyServerCertificate=true&amp;useSSL=true&amp;requireSSL=true&amp;trustCertificateKeyStoreUrl=file:///home/ubuntu/mysql_certs/truststore&amp;trustCertificateKeyStorePassword=yourPassword&amp;clientCertificateKeyStoreUrl=file:///home/ubuntu/mysql_certs/keystore&amp;clientCertificateKeyStorePassword=yourPassword" maxTotal="8" maxIdle="4" validationQuery="select 1" connectionProperties="useUnicode=yes;characterEncoding=utf8;" /> </Context>

  필요한 라이브러리 (버전은 크게 중요하지 않음, %Tomcat_Home%/lib 에 둠.) : 

    mysql-connector-java-8.0.11.jar, commons-pool2-2.6.0.jar, commons-dbcp2-2.2.0.jar, 

    commons-logging-1.2.jar

 

13) 톰캣을 재기동하여 MySQL 과 연결되는 것을 확인한다.

  간단하게 JSP 파일로 테스트 할 때는 다음과 같이 한다.

<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>

<%@ page import="java.sql.Connection" %>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.sql.DataSource" %>

<%
Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/MySQLDB");
Connection conn = ds.getConnection();
out.println("----------------------------------------<br />"); out.println(conn); out.println("<br />"); out.println("----------------------------------------<br />"); %>

 

[참조한 웹 페이지]

  https://dev.mysql.com/doc/refman/8.0/en/creating-ssl-files-using-openssl.html

  https://dev.mysql.com/doc/refman/8.0/en/mysql-ssl-rsa-setup.html

  https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-using-ssl.html

  http://stove99.tistory.com/153

  https://www.snoopybox.co.kr/1736

  https://docs.wavemaker.com/learn/how-tos/mysql-connection-using-ssl/

 

댓글

이름               비밀번호 
내용
비밀번호를 확인합니다.

댓글 등록시 입력한 비밀번호를 입력해주시기 바랍니다.