몇 년 전에 했던 내용인데, 갑자기 생각이 안나서 정리 차원에서 포스팅.
자바에서는 JSSE를 통한 기본 TLS(SSL) 프로토콜 시스템 구현을 할 수 있게 도와준다.
(https://docs.oracle.com/cd/E19900-01/820-0849/6ncifjhm7/)
was단에서의 설정으로 하는 방법과 spring security 와 엮는 방법 2가지를 다룰 예정이다.
01. 설치된 자바 jdk/bin/keytool.exe 로 .keystore 를 생성
c:\program files\java\jdk1.8.0_111\bin\keytool.exe -genkey -alias tomcat -keyalg RSA
주의사항이 있다면, 리눅스라면 yes/no 로 물어보니 yes 로 응답하면 되는 데
한글 윈도우인지라 예/아니오 라고 물어보기 때문에 예라 눌러줘야한다.
(스샷의 빨간색 밑줄 친 부분의얘기임)
02. 발급받은 .keystore 를 확인하자.
보통
user_home/.keystore 에 저장이 된다.
ex) c:\users\jhun\.keystore
(여기서 jhun은 내 윈도우 user id, user_home이 c:/users/jhun 인 셈)
03. 설치된 톰캣의 설정 (conf/server.xml)
설치된 톰캣의 conf/server.xml 에 설정을 해주어야 한다. 아래의 구문을 삽입하자. (사실 defaults 설정이 주석으로 되어있다. 하지만 이를 쓸 일은 없으므로 무시하고 그냥 새로 삽입해주자)
<Connector SSLEnabled='true' keystoreFile='C:/Users/jhun/.keystore'
keystorePass='password' port='8443' scheme='https' secure='true'
sslProtocol='TLS' />
04. 내가 만든 웹 어플리케이션에서 설정 (web.xml)
<web-app></web-app>
안에서 아래 구문을 삽입해준다.
<security-constraint>
<web-resource-collection>
<web-resource-name>my-secure-app</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
여기서
<transport-guarantee ></ >
에 들어갈 옵션에 대한 이야기로
NONE : 아무것도 안함
INTEGRAL : 데이터를 볼수는 있으나 변조를 못하게 해줌. 무결성
CONFDENTIAL : 데이터를 훔쳐보지 못하게함 . 기밀성
당연히 우리는 https를 보안의 초강화이기 때문에 CONFDENTIAL 해주자.
(각 설정에 따라 퍼포먼스가 떨어진다. 당연히 CONFDENTIAL이 속도적인면에서 가장 구림)
참고:
http://hellowk1.blogspot.kr/2015/04/spring-tomcat-https.html
http://hamait.tistory.com/330
http://channelofchaos.tistory.com/89
http://zgundam.tistory.com/43
Spring에 SSL 적용
Spring Framework에 SSL을 적용하는 방식은 Spring Framework 구성에 따라 다양한 형태가 될 수 있습니다.
여기서는 가장 단순한 형태로 SSL을 적용하는 법을 살펴보도록 하겠습니다.
1. Key Store 생성
- 유효한 인증을 가진 private keystore를 생성해야 합니다.
keytool은 자바에서 제공하는 기본 keystore 생성 프로그램으로 $JAVA_HOME/bin 디렉토리에 위치하고 있습니다.
keytool -genkey -keyalg RSA -alias KeystoreAlias -keystore /home/laonbud/test.keystore
2. Tomcat Configuration 수정
- Tomcat에 SSL connector를 추가하기 위해서 server.xml의 내용을 수정해야 합니다. 먼저 아래와 같은 기본 코드를 찾아,
<Connector port='8443' protocol='HTTP/1.1' SSLEnabled='true'
maxThreads='150' scheme='https' secure='true'
clientAuth='false' sslProtocol='TLS' />
다음과 같이 수정해줍니다.
<Connector SSLEnabled='true' keystoreFile='/Users/Roger/tmp/roger.keystore' keystorePass='password' port='8443' scheme='https' secure='true' sslProtocol='TLS'/>
3. Application Configuration 수정
1, 2를 통해 현재 https 접근이 가능합니다. 하지만 여전히 http로도 접근이 가능합니다.
그래서 http 접근을 막고 https로만 접근하도록 수정할 필요가 있습니다.
web.xml 파일에 web-app tag 전에 아래와 같은 내용을 추가해줍니다.
<security-constraint>
<web-resource-collection>
<web-resource-name>my-secure-app</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
(Option : Spring security를 사용하는 경우)
1)web.xml에 spring security 관련 설정 파일을 다음과 같이 추가
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/applicaiton-security.xml
</param-value>
</context-param>
2) 모든 요청에 대해 spring security filter를 타도록 수정
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3) application-security.xml 설정파일에 https로 접근하도록 수정.
<?xml version='1.0' encoding='UTF-8'?>
<beans:beans xmlns='http://www.springframework.org/schema/security'
xmlns:beans='http://www.springframework.org/schema/beans'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd'>
<http auto-config='true' >
<intercept-url pattern='/**' requires-channel='https' />
</http>
<authentication-manager>
</authentication-manager>
</beans:beans>
--------------------------------------------------------------------------------------------------------------------
위와 같이 사설 SSL 인증을 하게 되면 뭔가 불법적인 사이트 같은 경고창이 뜨는데요.
뭔가 공인된 인증서를 사용하면 이러한 경고창이 뜨지 않습니다.
이때 대부분의 경우는 비용이 발생하게 됩니다. ㅡ.ㅡ;;;
공인된 인증서를 발급받기 위해서는 CSR 파일이 필요합니다.
위의 1번 과정에서 생성된 keystore 파일로부터 csr 파일을 만들 수 있습니다.
keytool -certreq -keyalg RSA -alias KeystoreAlias -file 생성되는csr파일명 -keystore /home/laonbud/test.keystore
이 파일을 이용해 Verisign 등의 CA 인증서 발급기관으로 부터 인증서를 받으면 이 인증서를 다시 keystore 파일에 저장하게 됩니다. 보통 인증서 관련 파일은 루트 인증서, 체인인증서, 웹서버인증서 3가지가 오거나, 선택적으로 오거나, 아예 keystore 파일이 오기도 합니다.
keystore 파일이 오면 해당 keystore 파일을 기존 keystore 파일에 대체해서 tomcat의 server,xml에 설정해주면 됩니다.
아래의 경우에는 순서를 꼭 지켜줘야 합니다.
##먼저 발급받은 루트 인증서 파일 import
keytool -import -alias root -keystore /home/laonbud/test.keystore -trustcacerts -file 발급받은루트인증서파일
##이후 발급받은 체인 인증서 파일 import
keytool -import -alias chain -keystore /home/laonbud/test.keystore -trustcacerts -file 발급받은체인인증서파일
##이후 발급받은 웹 인승서 파일 import
keytool -import -alias tomcat -keystore /home/laonbud/test.keystore -trustcacerts -file 발급받은웹서버인증서
fail2ban은 bute force attack에 대응하는 툴로서,
접근 log 파일(/var/log/apache/error_log)을 읽어 잘못된 접근을 일정 수준 이상으로 하는 경우 일정 시간 동안 차단하는 서비스를 제공합니다.
설치)
fail2ban 페이지에서 fail2ban을 다운로드 합니다.
현재 안정버전은 0.8.10이구요.
압축 버전을 다운받아 압축을 풀고 install 해주면 됩니다.
tar xvfj fail2ban-0.8.5.tar.bz2
cd fail2ban-0.8.5
python setup.py install
설정)
fail2ban의 설정은 /etc/fail2ban/jail.conf 디렉토리 하에 있는 설정파일을 통해 합니다.
ignoreip : fail2ban에서 검사하지 않고 그냥 통과시키는 IP(개발 서버 등이 되겠죠?), 여러개인 경우 공백을 이용해서 구분합니다.
bantime : 해킹시도라고 판단 된 경우 해당 IP 차단 기간( 단위 : 초)
findtime : 해킹 시도라고 판단할 때 연속된 시도라고 판단할 기간( 단위 : 초)
maxretry : 여기서 지정한 수 이상을 fail한 경우 해킹 시도라고 판단
backend : 로그 파일 변경을 감지할 방법으로 gamin, polling, auto 방식이 있습니다.
- gamin : gamin(file alteration monitor, 파일 변경 모니터링)이 설치된 경우 해당 프로세스 사용하여 감지
- polling : 일정 시간 단위로 파일 변경된 내용 점검
- auto : gamin이 가능하면 gamin 사용하고 그 외의 경우 polling 사용
그리고 가장 중요한 점은 각각의 감지 rule에서 사용하고 싶은 것의 enabled 속성을 false에서 true로 변경해줘야 합니다.
fail2ban은 해킹 시도가 감지 되었을때 메일을 보낼 수 있게 되어 있습니다.
이때 기본 메일 설정은 you@example.com, fail2ban@example.com 으로 되어 있습니다.
이것을 상황에 맞게 vim 편집기에서 %s 사용해서 변경해주면 됩니다.
실행)
fail2ban-client start
- 실행 해주기전에 설정을 먼저 해줄 필요가 있습니다.
그리고 부팅 시 바로 실행 가능하도록 다음과 같은 명령을 수행.
# cd fail2ban-0.8.1/files
# cp suse-initd /etc/init.d/fail2ban
# chmod 755 /etc/init.d/fail2ban
그리고 fail2ban을 아래와 같은 방식 중 하나로 시작 프로그램에 등록 해줍니다.
chkconfig --add fail2ban
혹은
update-rc.d fail2ban defaults
혹은
ln -s /etc/init.d/fail2ban /etc/rc2.d/S20fail2ban ...
이번 서비스 오픈 준비 하면서 default로 설정한 로그들을 관리하기 위한 process 점검을 진행했었습니다.
이 와중에 그 동안 확인하지 못했던 log들을 보니 여러 차례 brute force 방식으로 공격이 진행되었다는 걸 확인하게 되었습니다.
특히 MySQL은 공격이 성공하기도 해서, 취약점을 보완하기 위한 작업들을 진행했습니다.
1. mysql_history 파일 제거
- 리눅스나 유닉스 상에서 mysql 클라이언트로 실행시킨 명령어는 해당 user의 home 디렉토리에 .mysql_history 파일에 기록되도록 되어 있습니다. 이 경우 비밀번호가 노출이 될 수 있는 위험성이 있기 때문에 아예 히스토리를 저장하지 않도록 설정하는 것이 필요한데요. /etc/profile에 MYSQL_HISTFILE이라는 변수를 /dev/null로 설정해주면 기록이 남지 않도록 할 수 있습니다.
-> MYSQL_HISTFILE=/dev/null
2. 가장 바보 같은 실수 중에 하나인데 mysql의 root 유저에 패스워드를 지정하지 않는 경우입니다.
- 이 경우에는 모든 경우에 대해서 접근을 허용하게 되는데요. 이때는 해당 mysql의 root 계정에 비밀번호를 지정해줘야 합니다.
ex1)update user set password=password('ddd999') where user="root" and host="localhost";
ex2)SET PASSWORD FOR root@localhost=PASSWORD('ddd999');
- root 사용자를 다른 사용자명으로 대체해주는 것도 방법입니다.
- 그리고 host에 host 명 같은 경우는 쓰일 일이 많지 않기 때문에 생략하는 것이 좋곘죠.
- 다른 계정에도 비밀번호나 접근 host 등의 설정등을 상황에 맞게 지정하는 것이 필요합니다.
3. 기본 mysql 3306 포트 말고 다른 포트를 사용
4. ssh에 brute force 공격을 차단
- 가장 보편적으로 사용되는 22번 포트 말고 다른 포트를 ssh 포트로 사용하는 것도 한 방법일 수 있겠습니다.
- fail2ban 같은 보안툴 이용(설치/사용법은 여기에...)
5. 포트 변경한 경우 포트 스캔에 대응
- portsentry 같은 보안툴 이용(설치/사용법은 여기에...)
6. SSL 프로토콜 적용
이 외에도 여러 가지가 있겠으나, 현재 지식으로는 이 정도 수준이네요.
스타트업에서 보안 문제를 해결하기에는 전문 분야가 아닌 이상 어려움이 많은데요.
사실 대단히 큰 문제인데, 어느 정도 위험을 감수하고 가는 부분이 있습니다.
여러 가지 걸리는 것들이 많네요. ^^
'Tech' 카테고리의 다른 글
oracle-jdk-8 설치 (0) | 2017.03.10 |
---|---|
우분투에 젠킨스 설치 'Jenkins_home' 이슈 트랙킹 (0) | 2017.03.10 |
밀리세컨드 를 분, 시간 으로 (0) | 2017.03.09 |
docker 시작하기 (0) | 2017.02.03 |
우분투 외장하드 마운트 & 삼바 설치 (0) | 2017.01.22 |