https://~(443 port)로 시작하는 URL의 파일을 리눅스 명령행(wget 사용)에서 다운로드할 때 에러가 발생하면 '--no-check-certificate' 옵션을 제공하면 된다는 것을 이제는 상식적으로 알고 있다. 하지만 왜 윈도우에서는 문제가 없을까? 집에서 테스트를 하면 왜 잘 될까? 리눅스 환경에서 프로그램이 자체적으로 다운로드를 실시할 때 알아서 진행되게 할 수는 없을까?
이에 대한 고민을 2018년부터 해 왔고 부분적으로는 해결 방법을 찾았지만 체계적인 지식이 부족하여 늘 애를 먹다가 TORMES pipeline의 업그레이드를 계기로 진지하게 접근해 보기로 하였다.
간단히 설명하면 이러하다. SSL(TLS가 더 정확한 용어일지도 모름)은 서버와 클라이언트 사이에서 패킷을 암호화하여 주고받음으로써 외부에서 이를 가로채도 무슨 의미인지 알 수 없게 만드는 것이 목적이다. 또 다른 목적은 내가 접속하는 웹사이트가 가짜가 아님을 확인해 주는 것이다. 보안 전문가의 견해로는 SSL에 대한 나의 해석이 100% 정확하지 않을 수도 있지만, 일반인 수준에서는 이 정도로 이해하면 된다.
그런데 패킷이 암호화되어서 돌아다니게 되니 기관의 보안 관리 입장에서는 내부의 중요한 정보가 빠져나가도 알 수가 없게 되었다. 그래서 이를 감시하는 SSL 복호화 솔루션을 쓰게 된다. SOMANSA니 SOOSAN INT니 하는 회사가 바로 이런 네트워크 보안 솔루션을 제공하는 곳이다. 이런 보안 솔루션이 적용되는 전산망 내부에서 인터넷을 쓰려면 이들 회사에서 제공하는 CA 인증서를 받아서 웹브라우저에 설치해야 한다. 처음에는 이를 이해하지 못했었다. 왜냐하면 SOMANSA나 SOOSAN INT는 원래 인증서를 발급하는 기관이 아니기 때문이다. 기업에서 2년 동안 근무할 때에는 SOMANSA의 것을, 한 뒤 연구소에 돌아와서 처음으로 인터넷을 연결했더니 SOOSAN INT의 SSLPrisim.crt라는 파일을 웹브라우저에 설치하라고 한다. 이 파일은 일종의 CA(certificate authority 또는 root certificate) 역할을 한다. 연구소 전산망 내의 컴퓨터에서 웹브라우저의 주소창에 sslcert.cc라는 곳을 치면 자동으로 다운로드할 수 있다. 리눅스의 파이어폭스에서도 똑같은 일을 하면 된다.
2021년 5월 18일 업데이트: 내가 근무하는 곳의 전산망을 벗어난 곳에서 sslcert.cc를 웹브라우저의 주소창에 입력하면 SSLPrisim.crt 파일을 받을 수가 없다. 이건 당연한 이야기이다. 화면에 보이는 메시지에는 'ePrism SSL 정식 사용자에게만 제공'함을 밝히고 있다.
만약 모든 인터넷 접속(파일 다운로드 포함) 작업을 웹브라우저에서 한다면 이렇게 하는 것만으로도 문제가 없다. 그런데 리눅스에서는 wget, curl 등을 써서 명령행에서 파일을 가져올 일이 많다. 또한 conda, curl, R, pip 등 자체적으로 https:// 위치에 있는 파일을 가져오는 명령어가 있는데, 웹브라우저(SSLPrism.crt를 이미 알고 있는)는 전혀 경유하지 않으므로 문제가 생긴다.
https:// 위치에 있는 모든 파일을 가져오는데 문제가 생기는 것은 아니다. 테스트를 해 본 결과 자체 인증서를 쓰는 웹사이트만 그러한 것 같다. 예를 들어 보자.
$ wget https://cran.rstudio.com --2021-04-30 09:28:19-- https://cran.rstudio.com/ cran.rstudio.com (cran.rstudio.com)을(를) 해석하는 중... 52.84.166.5, 52.84.166.79, 52.84.166.102, ... 접속 cran.rstudio.com (cran.rstudio.com)|52.84.166.5|:443... 접속됨. 오류: cran.rstudio.com의 인증서를 확인할 수 없습니다. 발행자는 `CN=ePrism SSL,O=SOOSAN INT,C=KR'입니다: 자기 자신이 서명한 인증서를 발견했습니다. cran.rstudio.com에 안전하지 않게 연결하려면 `--no-check-certificate'를 사용하십시오.
OpenSSL 명령어를 사용하여 접속 테스트를 해 보아도 같은 종류의 메시지가 나온다.
$ echo quit | openssl s_client -showcerts -servername "cran.rstudio.com" -connect cran.rstudion.com:443 > test.ca-bundle depth=1 C = KR, O = SOOSAN INT, CN = ePrism SSL verify error:num=19:self signed certificate in certificate chain verify return:1 depth=1 C = KR, O = SOOSAN INT, CN = ePrism SSL verify return:1 depth=0 CN = cran.rstudio.com verify return:1 DONE
자체 서명한 인증서를 쓴다는 것이고, 직장 전산망을 보호(?)하는 ePrism SSL VA 장비는 이를 차단하는 것으로 보인다.만약 같은 웹사이트에 대해서 집에서 wget 명령어를 실행하면 어떻게 될까? 아무런 문제가 없이 다운로드가 잘 이루어진다. OpenSSL 명령어에 대한 결과는 이러하다.
$ echo quit | openssl s_client -showcerts -servername "cran.rstudio.com" -connect cran.rstudio.com:443 > test.ca-bundle depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon verify return:1 depth=0 CN = cran.rstudio.com verify return:1 DONE
접속한 사이트가 자체 인증서를 쓰는지의 여부는 화면상으로 출력되지는 않는다. 파일로 리다이렉트한 CA bundle에는 혹시 그런 내용이 기록되는지는 아직 확인해보지 않았다.
SSLPrism.crt 파일은 자체 인증서를 쓰는 웹사이트임을 알게 된 경우에 사용하는 대체용 CA 인증서일 것이라는 생각이 들었다. 리눅스 혹은 윈도우 웹브라우저에서 이 사이트를 접속한 뒤 주소창 왼쪽의 잠겨진 자물쇠를 클릭하여 인증서 정보를 확인하여 보라. 발급자는 ePrism SSL로 나타난다.
자, 그러면 리눅스 명령행에서 wget 명령어가 SSLPrism.crt 파일을 이용하게 만들면, 매번 '--no-check-certificate'를 쓸 일이 없을 것이다. ~/.wgetrc 파일을 편집하여 사용자가 원하는 설정 사항을 기록하면 된다고 하여 그대로 따라해 보았다.
$ echo 'ca-certificate=~/SSLPrism.crt' > .wgetrc $ wget https://cran.rstudio.com --2021-04-30 09:05:11-- https://cran.rstudio.com/ cran.rstudio.com (cran.rstudio.com)을(를) 해석하는 중... 52.84.166.102, 52.84.166.5, 52.84.166.64, ... 접속 cran.rstudio.com (cran.rstudio.com)|52.84.166.102|:443... 접속됨. HTTP 요청을 전송했습니다. 응답을 기다리는 중입니다... 200 OK 길이: 850 [text/html] 다음 위치에 저장: `index.html' index.html 100%[======================================>] 850 --.-KB/s / 0s 2021-04-30 09:05:11 (27.9 MB/s) - `index.html' 저장됨 [850/850]
옳거니! SSLPrism.crt 파일을 이렇게 하여 웹브라우저가 아닌 다른 애플리케이션이 쓰도록 만들어 보았다. 이것으로 만족할 수 있는가? 전혀 그렇지 않다. 겨우 wget 명령어에 대해서만 개별적인 CA 인증서를 적용하게 만들었기 때문이다.
명령행을 위한 인증서 설치 방법
$ rm .wgetrc index.html $ sudo mkdir /usr/local/share/ca-certificates/kribb $ sudo cp SSLPrism.crt /usr/local/share/ca-certificates/kribb $ sudo update-ca-certificates Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done. $ wget https://cran.rstudio.com --2021-04-30 09:58:14-- https://cran.rstudio.com/ cran.rstudio.com (cran.rstudio.com)을(를) 해석하는 중... 52.84.166.79, 52.84.166.5, 52.84.166.102, ... 접속 cran.rstudio.com (cran.rstudio.com)|52.84.166.79|:443... 접속됨. HTTP 요청을 전송했습니다. 응답을 기다리는 중입니다... 200 OK 길이: 850 [text/html] 다음 위치에 저장: `index.html' index.html 100%[=============================>] 850 --.-KB/s / 0s 2021-04-30 09:58:14 (24.7 MB/s) - `index.html' 저장됨 [850/850]
잘 작동한다! 그러나 아직 안심을 하기는 이르다. Conda, git, pip, R(패키지 업데이트) 등의 명령이 잘 돌아가는지 전부 확인을 해 보지는 못했기 때문이다. TORMES v1.2.1를 지우고 새로 설치해 보니 CA 인증서를 업데이트한 것만으로 모든 명령어(443번 포트에서 파일을 다운로드하는)에 전부 대응하는 것은 아니었다. 이에 대해서는 다시 한번 확인을 한 다음 새 글에서 정리하겠다.
TORMES 1.2.1의 재설치 테스트
# tormes-1.2.1 환경 셋업 과정에서 ... ClobberError: This transaction has incompatible packages due to a shared path. packages: bioconda/noarch::abricate-1.0.1-ha8f3691_1, bioconda/noarch::mlst-2.19.0-hdfd78af_1 path: 'LICENSE' ... # tormes-setup 스크립트의 마지막 부분인 RDPToos 설치 과정 ... BUILD SUCCESSFUL Total time: 4 seconds (cp Framebot/dist/FrameBot.jar Clustering/dist/Clustering.jar SequenceMatch/dist/SequenceMatch.jar classifier/dist/classifier.jar AbundanceStats/dist/AbundanceStats.jar ReadSeq/dist/ReadSeq.jar SeqFilters/dist/SeqFilters.jar ProbeMatch/dist/ProbeMatch.jar KmerFilter/dist/KmerFilter.jar Xander-HMMgs/dist/hmmgs.jar AlignmentTools/dist/AlignmentTools.jar ./; cp -r */dist/lib/* lib/; rm -r classifier/dist/) cp: 방금 만든 'lib/ReadSeq.jar'를 'AlignmentTools/dist/lib/ReadSeq.jar'로 덮어쓰지 않음 cp: 방금 만든 'lib/commons-cli-1.2.jar'를 'AlignmentTools/dist/lib/commons-cli-1.2.jar'로 덮어쓰지 않음 cp: 방금 만든 'lib/ReadSeq.jar'를 'Clustering/dist/lib/ReadSeq.jar'로 덮어쓰지 않음 ...