1. 문제의 시작
잘 운용되고 있던 통계 로그 서버가 갑자기 먹통이 되었다.
사실 전부 인수인계 되어있던 건데.... 갑자기 안된다는 메일이 한통 딱 날라왔다.
뭔가 작업을 했으면 작업을 했었다... 그래서 안된다. 이런식으로 메일을 써 주면 좋으련만, 자기들 원하는 대로만 메일을 쓰지.....
일단 2월부터 통계 데이터가 없다고 하니, 해당 날짜부터 무슨 일이 있었는지 확인을 해보자..
2. 처음 보는 에러 로그
해당 로그는 다음과 같았다.
sendBatchLog|HTTP Send error|sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
흐음.. 느낌상으로는 https 로 통신하는데 문제가 있는것으로 보인다.
3. https 통신 여부 확인하기.
일단 os level에서 정상적으로 해당 데이터를 가지고 올 수 있는지 확인해 보았다.
하지만 결과는 참담했다.
1) 해당 장비에는 curl 이 깔려 있지 않았고,
2) wget으로 페이지를 다운로드를 받으니, dns에서 해당 url을 찾을 수 없댄다.
3) 게다가 apt-get으로 curl 같은 것을 다운로드 받을 수도 없다.
일단 하나씩 해결해 보자.
문제의 장비 정보
$ cat /etc/issue
Ubuntu 12.04.5 LTS \n \l
일단 apt-get을 사용할 수 있도록 해보자.
기존에는 /etc/apt/source.list 에 ubuntu repository 주소가 다음과 같이 되어 있었다.
http://kr.archive.ubuntu.com/ubuntu/
적절하게 백업뜨고 다음과 같이 변경해 주자.
# cp /etc/apt/sources.list /etc/apt/sources.list.bak
# cat /etc/apt/sources.list | sed -e 's/http:\/\/kr.archive.ubuntu.com\/ubuntu\//http:\/\/ftp.daumkakao.com\/ubuntu\//g' > /etc/apt/sources.list
하지만 이게 잘 되면 얼마나 좋으련만....
dns 서버 문제가 있는것 같다.
ftp.daumkakao.com을 못찾는다....
일단 static 으로 구성된 network환경을 확인해 보자
# vi /etc/network/interfaces
~
dns-nameservers 192.168.0.1
역시나 dns-nameservers 가 없다. 추가한 뒤에 파일을 수정해 준다.
해주는 김에 /etc/resolv.conf 도 추가해 준다.
# vi /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 192.168.0.1
그 다음엔 깔끔하게 장비 reboot를 해 주자
# reboot
reboot가 끝이 나고, 정상적으로 dns 서버가 동작하는 것을 확인했다.
하는 김에 apt-get update 도 진행해줌
$ sudo apt-get update
잘 된다....
4. 문제의 서버에는 역시 접근이 안된다.
https로 된 문제의 서버에는 self signed certificate 라는 이유의 에러 메시지를 뱉어내며 정상 동작을 하지 않는다...
google 신의 도움으로 다음과 같이 업데이트를 진행해 준다.
# update-ca-certificates -f
ref. http://manpages.ubuntu.com/manpages/cosmic/en/man1/c_rehash.1ssl.html
일단 wget, curl로 발생하던 에러는 드디어 사라졌다.
5. java에서는 아직도 동일한 에러가 발생한다.
이거가 뭔 일이냥?
다시 또 검색을 해 보았다.
ref. https://www.lesstif.com/pages/viewpage.action?pageId=12451848
상기 사이트에서 나온 결론은 다음과 같다.
1) java keystore 상에 해당 CA 인증서 정보가 없다.
2) 그렇기 때문에 https 사이트에 대해서 PKIX 에러가 발생되는 것이다.
3) java default path에 있는 cacert에 문제의 인증서를 추가해 주자.
잘 정리하신 분이 계시길래.... 일단 따라해 보도록 한다.
6. 변경 작업 시작
혹시라도 저 파일이 없어질 수도 있으니.. 다운을 받아봄..
$ curl -O https://gist.githubusercontent.com/lesstif/cd26f57b7cfd2cd55241b20e05b5cd93/raw/InstallCert.java
$ javac InstallCert.java
-bash: javac: command not found
아나... javac 이 없다고 합니다 그렇다면...
심볼릭 링크를 걸어서 javac을 쓰도록 하자...
$ java -version
java version "1.8.0_161"
Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)
$ which java
/usr/bin/java
$ ll /usr/bin/java
lrwxrwxrwx 1 root root 26 Feb 19 2018 /usr/bin/java -> /opt/jdk1.8.0_161/bin/java
$ sudo ln -s /opt/jdk1.8.0_161/bin/javac /usr/bin/javac
$ javac InstallCert.java
음... 이제 돌아가는구만...
그렇다면.. 문제의 사이트에서 인증서를 가져오도록 합니다.
$ java -cp ./ InstallCert sample.kkus.com
Loading KeyStore /opt/jdk1.8.0_161/jre/lib/security/cacerts...
Opening connection to sample.kkus.com:443...
Starting SSL handshake...
javax.net.ssl.SSLException: java.lang.UnsupportedOperationException
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1916)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1899)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1420)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at InstallCert.main(InstallCert.java:116)
Caused by: java.lang.UnsupportedOperationException
at InstallCert$SavingTrustManager.getAcceptedIssuers(InstallCert.java:187)
at sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(SSLContextImpl.java:1098)
at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:1044)
at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:986)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
... 2 more
Server sent 3 certificate(s):
1 Subject CN=sample.kkus.com, OU=InstantSSL, OU="Hosted by Korea Information Certificate Authority, Inc.", OU=IT, O=kkus Corporation, L="Bundang-gu, Seongnam-si", ST=Gyeonggi-do, C=KR
Issuer CN=COMODO RSA Organization Validation Secure Server CA, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
sha1 72 54 e2 76 7e 5d 8a 64 92 48 81 b6 68 f1 14 ef 8b 95 6c 9a
md5 ce 0a dd e9 20 c0 ea 57 07 5c 09 a8 64 8e 8f bb
2 Subject CN=COMODO RSA Organization Validation Secure Server CA, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
Issuer CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
sha1 10 4c 63 d2 54 6b 80 21 dd 10 5e 9f ba 5a 8d 78 16 9f 6b 32
md5 91 29 73 32 12 d5 f5 65 18 64 d8 6b 7b ae 0b 98
3 Subject CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
Issuer CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
sha1 af e5 d2 44 a8 d1 19 42 30 ff 47 9f e2 f8 97 bb cd 7a 8c b4
md5 1b 31 b0 71 40 36 cc 14 36 91 ad c4 3e fd ec 18
Enter certificate to add to trusted keystore or 'q' to quit: [1]
2
여기서 2를 선택한 이유는 문제의 사이트에서 CA 인증서만 필요하기 때문입니다.
root 인증서를 집어 넣어도 되지만... 난 그냥.. 되기만 하면 되니깐, CA 인증서만....
[
[
Version: V3
Subject: CN=COMODO RSA Organization Validation Secure Server CA, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
Signature Algorithm: SHA384withRSA, OID = 1.2.840.113549.1.1.12
Key: Sun RSA public key, 2048 bits
modulus: ....
public exponent: 65537
Validity: [From: Wed Feb 12 09:00:00 KST 2014,
To: Mon Feb 12 08:59:59 KST 2029]
Issuer: CN=COMODO RSA Certification Authority, O=COMODO CA Limited, L=Salford, ST=Greater Manchester, C=GB
SerialNumber: [ 36825e7f b5a48193 7ef6d173 6bb93ca6]
Certificate Extensions: 8
[1]: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
[
accessMethod: caIssuers
accessLocation: URIName: http://crt.comodoca.com/COMODORSAAddTrustCA.crt
,
accessMethod: ocsp
accessLocation: URIName: http://ocsp.comodoca.com
]
]
[2]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
....
]
]
[3]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen:0
]
[4]: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
[DistributionPoint:
[URIName: http://crl.comodoca.com/COMODORSACertificationAuthority.crl]
]]
[5]: ObjectId: 2.5.29.32 Criticality=false
CertificatePolicies [
[CertificatePolicyId: [2.5.29.32.0]
[] ]
[CertificatePolicyId: [2.23.140.1.2.2]
[] ]
]
[6]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
serverAuth
clientAuth
]
[7]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_CertSign
Crl_Sign
]
[8]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
....
]
]
]
Algorithm: [SHA384withRSA]
Signature:
....
]
Added certificate to keystore 'jssecacerts' using alias 'sample.kkus.com-2'
좀 은밀한 것은 가렸음...
이제 추출 작업은 끝났으니.... 파일이 제대로 있는지 확인
$ ls
InstallCert.class InstallCert.java InstallCert$SavingTrustManager.class jssecacerts
일단 추출을 해 봅니다.
$ keytool -exportcert -keystore jssecacerts -storepass changeit -file output.cert -alias sample.kkus.com-2
-bash: keytool: command not found
오 지쟈스...
우울하구만... 또 symbolic link다
$ sudo ln -s /opt/jdk1.8.0_161/bin/keytool /usr/bin/keytool
$ keytool -exportcert -keystore jssecacerts -storepass changeit -file output.cert -alias sample.kkus.com-2
Certificate stored in file <output.cert>
이 다음은 추출한 인증서를 java_root에 있는 인증서에 삽입
$ JAVA_HOME=/opt/jdk1.8.0_161
$ keytool -importcert -keystore ${JAVA_HOME}/jre/lib/security/cacerts -storepass changeit -file output.cert -alias sample.kkus.com-2
Certificate was added to keystore
이렇게 작업 후에 문제를 해결했음...