SSL 활용하기(Secure Socket Layers)
SSL을 이용한 키로 ssh, scp, https, sftp 등에 활용하면 일반적인 평문장 연결이 아닌 키를 사용하는 암호화된 연결을 이루므로 보안이 좋아진다.
유명 포털 사이트는 이미 불특정 사용자들이 접속하는 것을 대비해서 각 브라우저별로 인증서를 넣어 두었다. 중소기업에서는 자신의 SSL을 사용하는 서비스에 접속하려면 브라우저에 SSL 키가 있어야 한다.
인증서의 내용은 CN(Common Name), O(Organization), OU(Organizational Unit) 등과 Fingerprints에서 SHA-256과 같은 암호화 알고리즘, Period of Validity에서 키의 유효기간 등을 볼 수 있다. 유명 사이트는 각종 웹 브라우저에 이미 해당 사이트의 인증키를 넣어서 누구나 들어갈 수 있게 한 이유는 https 상태에서는 통신 중에 패킷이 추출되어도 이 인증서의 키가 없으면 내용을 변경하지 못하거나 볼 수 없게 하기 위해서이다.
SSL은 인증서를 생성해서 클라이언트의 웹브라우저에게 배포한 뒤, 서버 인터페이스(소켓)로 접속하는 클라이언트들을 인증해주는 모듈이다. 서버에 자체적으로 인증한 인증서를 두거나 VeriSign, COMODO, DigiCert, Global sign, Go Daddy, Microsoft Root, Thawte Premium,..과 같은 공적인 인증기관에서 발행한 인증서를 두고 클라이언트가 다운받아서 자신의 웹 브라우저에 넣어두고 접속하게 한다. 인증서는 heartbleed라는 취약점도 발견되기도 하지만 현재 대부분 사이트는 SSL을 사용한다.
SSL은 Transport(TCP) 층의 TLS 프로토콜을 사용하기 때문에 SSL을 TLS로도 부르는데 HTTPS(HTTP over SSL), SMTPS(SMTP over SSL), FTPS(FTP over SSL) 등이 있다. FTPS는 사용자명, 패스워드, 그리고 인증서로 인증하고, SFTP(FTP over SSH)는 사용자와 패스워드로 인증하며, FTP는 anonymous(익명) 사용자와 패스워드 없이도 인증된다.
가끔 이 SSL과 SSH를 혼동하는 경우가 있는데
SSH는 평문장 Telnet 대신 A가 B에 접속할 때 A의 인증서로 B에게서 허락(인증)받아 연결해주는 도구이고
SSL은 A가 ssh로 B에 접속할 때 B의 인증서로 A를 인증해 주는 키 생성 모듈이다.
조직에서 https:// ~ 웹 서버를 운영할 때(이 웹 서버에 접속을 제한하는 .htpasswd 설정과 함께) 클라이언트 브라우저에 이 SSL 키를 가지고 있는 사용자만 접속할 수 있도록 해서 보안을 더욱 강화할 수도 있다.
조직의 사설 웹 서버인 경우 '개인키(key) 생성 =>인증서 요청서(csr) 생성 =>정식 인증서(crt) 생성(OR 사용자 개인키 key와 공개키 crt를 합친 pem) =>웹 서버 설정의 httpd.conf 파일에서 인증서 위치 지정 =>SSL 설정을 위한 ssl.conf 파일에서 인증서 위치 지정 =>클라이언트의 웹브라우저에 해당 서버의 crt 키 등록 =>클라이언트가 이 crt 키로 인증 받아서 해당 웹 서버에 https:// ~ 로 접속' 순으로 진행한다.
==>위 과정에서 개인키(key)와 인증서 요청서(csr)를 조직에서 생성했다면 이 두 키를
공적 인증기관 CA(Certificate Authority)에 보내면 정식 인증서 파일(crt)을 보내온다. 이를 사용하면 된다.
사설 사이트이기 때문에 이런 식으로 SSL을 구축하지만 공적 사이트로 불특정 다수가 접속한다면 모든 클라이언트들을 위한 키를 그들의 웹 브라우저 별로 넣어두는 방법도 함께 연구해 두어야 한다. 하지만 이것이 어렵기 때문에 유명 사이트나 대기업은 불특정 다수의 클라이언트들을 위한 각종 브라우저에 자신들 사이트에 대한 인증서를 미리 넣어둔다.
웹 사용자의 연결을 제한하는 .htpasswd를 사용해서 웹 서버의 보안을 더욱 증가시킬 수 있다.
보안으로 클라이언트가 (웹) 서버에 접근하는 방법에는
▪ 서버가 인증서를 생성한 뒤, 연결할 클라이언트들에게 인증서 *.crt를 뿌리고,
클라이언트의 웹 브라우저에 인증서를 넣고, 클라이언트들이 서버에 연결하는 방법과
▪ 클라이언트들이 개인키와 공개키를 생성한 뒤, 개인키는 자신이 소유하고, 서버에게 자신의 공개키 *.pub를 보내서 연결하는 방법, 그리고
▪ 서버가 개인키와 공개키를 생성한 뒤, 개인키는 자신이 소유하고, 클라이언트들에게 자신의 공개키 *.pub를 보내서 클라이언트들이 연결시키는 방법이 있다.
파일 시스템 암호화
서버 관리에 있어서 보안은 매우 중요한 일이다. 보안 관리라는 것은 내부 정보를 외부로 노출시키지 않는 것과 외부로부터의 잠재적인 침투를 사전에 감지해내는 일이지만 침투 당했을 때 침투당한 요소들을 확인해서 정리해두고 나중에 더욱 강화된 보안 설정을 통해서 재 침투에 대한 예방적 조치를 취해두는 일까지 포함되어야 한다.
여기서 디지털 인증서와 SSL을 사용한 암호화된 채널인 캡슐화 네트워크(이를 터널로 부름)로 트래픽을 안전하게 전송해서 전송정보가 외부로 유출되지 않게 하는 법을 알아보고, SELinux를 사용해서 인증되지 않은 서비스를 통한 파일 접근을 막아보는 SELinux 기반 침입감지와 침입예방도 알아본다. 여기서 주로 사용되는 용어도 주의해서 살펴보아야 한다.
여기서 자주 사용되는 용어로
용어 설명
인증 프로세스 (Authentication Process)공개키 암호화를 수행해서 유일한 이름을 증명해주는 인증서를 생성하는 일련의 과정을 말한다.
유일한 이름 (Distinguished Name)웹상에서 구별되는 이름으로 어느 것도 될 수 있지만 보통 서버머신의 FQDN(Fully Qualified Domain Name) www.kahn.edu나 centos1.kahn.edu식으로 '호스트_명.도메인_명'이 된다.
CA (Certification Authority)디지털 인증서를 발급해주는 주체(entity)로써 신뢰 관계의 써드파티도 될 수 있는데 Linux/UNIX에서는 X.509 표준을 따라야 한다.
전자 인증서 (Digital Certificate)CA가 발행한 것으로 해당 인증서의 주체가 해당 인증서의 공유키의 소유자임을 증명해주는 증서이다. 여기서 '공유(shared)'는 인증서를 발급하는 기관과 해당 인증서를 가지고 있는 조직/사용자가 이미 공유된 키를 서로가지고 있다는 의미이다.
기본적으로 root 인증서 하나를 생성한 뒤, 이 root 인증서로 다른 모든 인증서를 서명해서 인증하는 구조이다. root 인증서는 어느 도메인의 인증서들을 서명 할 때 사용되는 메인 CA가 가지고 있는 특수 인증서로서 '인증서의 뿌리'이다. root 인증서는 자기 자신 외에는 다른 인증서에 의해서 서명 받지 않으므로 개발자들은 root가 서명한 인증서는 전적으로 신뢰하도록 클라이언트의 어플들을 구성해 둬야 한다. 일반적으로 전자 인증서는 공개키 인증서를 말하는데 인증서 가 자주 필요한 SSH나 HTTPS, SFTP 등 서버 서비스에서 사용되는 CRT이다.
전자서명 (Digital Signature)수학적 기법을 사용해서 사용자, 조직, 문서, 메시지, 그리고 어플 등을 전자적으로 인증해주는 것을 말한다. ASC 확장자이다.
디지털 인증서(Digital Certificate)
네트워크 서비스를 안전하게 해주는 일반적인 방법이 TLS(Transport Layer Security)를 사용하는 것인데 TLS의 리거시한 이름이 바로 앞에서 살펴보았던 SSL(Secure Socket Layer)이다. 관리자들도 자주 이 두 용어를 혼용해서 사용하고 실제적으로 두 프로토콜을 같은 것으로 보기도 하지만 SSL의 일부 버전은 보안에 취약점이 있어서 최신의 TLS를 사용하는 것이 더 좋다. TLS는 대부분 네트워크 패킷 전송에 사용되는 TCP 프로토콜에 많은 보안기법을 제공해서 데이터 송수신 시 해커에 의해 가로채여 수정되는 것을 막거나 서버와 클라이언트 상호인증 등에서 활용된다.
인증서를 생성하기 전에 인증서에 관한 전략을 잘 구상해야 한다. 인증서를 마구 만들면 그 인증서가 조직 도메인 내의 여러 곳으로 뿌려지는 경우가 생기고 어느 하나가 해커에 의해서 탈취당하면 도메인 전체가 보안상 취약해질 수 있기 때문에 대부분 조직에서는 모든 인증서 생성과 요청을 처리할 리포지터리(저장소) 레벨의 머신 하나를 지정해두고 인증서를 필요로 하는 서버 서비스 데몬들에게 이 저장소에서 인증서를 복사해가도록 구성해서 운영하고 있다. 인증서는 공개키(public key)로 볼 수 있다.
대부분 인증서는 매해 혹은 특정 숫자 년도에 인증서를 생성하도록 '/srv/cert/년도'식의 디렉터리 구조를 만들어서 운영하고 있는데 이 디렉터리에 있는 파일을 읽거나 작성할 때 오직 인증받은 사용자들만 작업할 수 있도록 파일 권한설정, 특히 개인 사설키 파일관리에 주의를 기울여야 한다. 만일 root가 인증서 관리 작업을 안 한다면 인증서 관리를 위한 별도의 그룹을 만들고 특정 사용자를 그 그룹에 넣어서 권한을 주고 운영시키면 된다.
예를 들어 centos 사용자에게 인증서 관리 권한을 위임시킨다면
① mkdir /srv/cert 하고 인증서 작성 등에 필요한 파일들을 /srv/cert 디렉터리에 넣고,
② groupadd certificates 해서 certificates 그룹을 만들고,
③ chown root:certificates /srv/cert 해서 /srv/cert 디렉터리의 그룹을 변경 한 뒤,
④ chmod 0277 /srv/cert 해서 디렉터리에 적절한 권한을 주고,
⑤ usermod -G certificates –a centos 해서 centos 사용자를 certificates 그룹에 넣어서 /srv/cert 디렉터리에 들어가서 인증서 작업을 담당시킬 수 있다.
TLS로 보호되는 https://www.kahn.edu라는 웹 사이트를 운영한다고 해보자.
아무 사용자나 이 사이트에 들어와서 중요한 웹 파일 등을 봐서는 안 되므로 관리자는 신뢰하는 CA에서 발급한 인증서를 가지고 있는 사용자만 웹 파일을 읽을 수 있게 해줘야 한다. 대부분 웹 브라우저는 해당 사이트에 대한 유료/무료로 발급받은 CA 리스트를 내장하고 있어서 해당 사이트에 들어갈 때 인증서를 요구하거나 신뢰하지 못한다는 메시지를 안 보인다.
CentOS1의 Firefox에서 https://www.naver.com 하면 잘 들어가진다. 주소창 앞의 열쇠 모양을 클릭해서 뜨는 작은 창에서 보면 Sectigo RSA ~나 COMODO CA Limited를 보인다. 이 인증서로 네이버 사이트를 인증했기 때문에 https로 네이버에 들어갈 수 있는 것이다. 아래에 있는 More Information...을 클릭하면 Security 탭 창이 열리는데, 우측의 View Certificate를 클릭하고, General 탭과 Details 탭으로 들어가면 내장된 인증서들을 볼 수 있다.
=>현재 Linux 계열은 SSLeay에서 발전된 OpenSSL이라는 도구를 사용해서 전자서명이 된 인증서를 관리하는데 대부분의 오픈소스 보안 어플은 이 OpenSSL 라이브러리에서 파생된 것들이다. Windows 머신에서는 OpenSSL for Windows 프로그램을 다운받아서 설치하고 콘솔에서 실행하면 된다.
우리가 인터넷 뱅킹 등을 이용하려면 해당 은행에 들어갈 수 있는 공인 인증서가 필요하기 때문에 매년 얼마씩 돈을 지불하고 공인 인증서를 발급받는다. 하지만 로컬이나 도메인 내에서만 사용하는 인증서를 만들면 비용이 들 필요가 없고 기간도 맘대로 정해서 사용할 수 있다. 인증서 생성은 '개인키(*.key) 생성 =>공인인증서 발급 신청서(*.csr) 생성 =>공인인증서(*.crt) 발급 =>공인 인증서로 타겟 인증하기'의 순서로 진행된다.
보호하고자 하는 조직과 사용자, 혹은 사이트에 대한 정보를 가지고 있는 개인키 KEY를 먼저 만들고, 이를 서명해서 인증서를 신청하는 CSR(Certificate Signing Request)을 만든 뒤 이를 공적인 공인인증서 발행소 CA(Certificate Authority)에 보내면 공인인증서 CRT를 발급해준다(KEY와 CRT 두 개를 하나의 *.PEM 패키지로 만들기도 한다), CSR은 저장된 송수신 과정에서 내용이 변경되는 것을 막기 위해서 별도로 암호문구(pass phrases)를 사용하기도 한다. 인터넷 뱅킹에서 공인 인증서를 사용하면서 패스워드도 넣는 것을 생각해보면 이해될 것이다.
유료 CA로 COMODO, Symantec의 VeriSign(GeoTrust와 Thawte), GoDaddy 등이 있고, 기간제한이 있거나 테스트용 CA로 Letsencrypt, COMODO, Startssl, CloudFlare, ACM(Amazon Certificate Manager) 등이 있다.
조직은 개인키 key와 crt 요청서 csr을 만들고, Root CA의 하부 조직인 Intermediate CA에 이 csr 내용을 보내면 유료나 일정기간 사용의 조직을 위한 crt를 제공받을 수 있다. 조직은 이 crt로 https, sftp(ftps), scp, ssh, smtps, ..등 서버에 접속하는 각 사용자의 브라우저에 이 crt를 제공해서 보안모드로 들어오게 한다.
CSR 파일을 가지고 인증서 CRT를 발급받는데 다음 세 가지 방법이 있다.
∎ 첫째는 VeriSign과 같은 공인된 곳에서 CRT를 받는 방법이다.
*.csr 파일을 공인된 인증서 센터에 보내면 공인된 CRT를 서명해서 만들어서 돌려준다. CRT 서명은 인증에 필요한 문서, 인증서를 받기까지 걸리는 시간이 회사마다 각각 다르고 비용도 다르므로 CA에게서 서명된 인증서를 요청하기 전에 이런 사항들을 확인해둘 필요가 있다. 유료 CA에서 COMODO 42%, Symantec(VeriSign, Thawte, GeoTrust) 15%, GoDaddy 7.6%, 그리고 GlobalSign 4.8%의 점유율이다.
둘째는 테스트용 CRT를 발급받는 방법이다.
∎ COMODO, letsencrypt, startssl 그리고 rapidssl 등에서 일정 기간 test 용 CA를 얻을 수 있다. 이를 실습하려면 정식 도메인을 가지고 있는 이메일로만 테스트용 CA를 얻을 수 있어서 실습을 하지는 못하지만 얻는 과정까지만 잠시 살펴본다. COMODO CA를 이용해도 되는데 여러 가지 성가신 게 많아서 비추이다.
∎ 세 번째는 앞에서 실습해본 것처럼 사설 CRT를 생성해서 사용하는 방법이다.
앞에서 서버에서 생성한 웹 인증서 www.kahn.edu.crt는 'kahn.edu 도메인 내의 www 호스트를 인증해주는 인증서'로서 클라이언트가 이 웹 서버(호스트)에 접속하면 서버는 클라이언트에게 서버의 인증서를 보내서 클라이언트의 웹 브라우저에 저장시켜서 상호 인증된 연결을 이루게 한다. 클라이언트는 서버에서 생성한 ~.crt 파일만(여기에 개인 key도 들어 있다) 웹 브라우저에 가지고 있으면 된다.
하지만 HTTPS 프로토콜은 하나의 서버 호스트에 여러 HTTPS 사이트를 운영한다면 각 도메인_명마다 고유한 IP_주소를 가지고 있고, 대부분 상업 CA가 하나의 서버에서 실행되는 여러 HTTPS 인증서를 통합해서 지원하지 않기 때문에 - 예를 들어서 사용자는 A 은행의 CRT를 A 은행에만 접속할 때 사용하고, B 은행에 접속할 때에는 새로 B 은행의 CRT를 가지고 있어야 한다는 뜻이다. 이런 제약을 없앤 것이 바로 '범용 인증서(Wild CRT)'인데 단일 CRT 인증서에 여러 도메인_명을 추가해주면 각 도메인에 CRT를 제공할 수 있는 기법이다. 간단히 말해서 하나의 CRT에 A 은행과 B 은행의 정보를 넣어서 A와 B 은행에 동시 접속할 수 있게 해주는 기법이다.
이렇게 하나의 인증서에서 여러 도메인_명을 인증해주는 '범용 인증서'가 있지만 여러 표준화 시도에도 불구하고 아직까지 정식으로 표준화된 모듈은 없다. 각 브라우저는 각 도메인_명을 일일이 인식하거나 여러 도메인_명을 묶어서 하나의 와일드 문자(*나?)로 인식하는 두 가지 이름 포맷을 가지고 있기 때문에 로컬에서 직접 생성한 인증서가 모든 브라우저에서 잘 작동되게 하려면 IE, Firefox, Chrome 등 각 브라우저에서 인증서를 각각 시도해 보아야 한다. X.509의 subjectAltName 확장자를 사용하면 브라우저별로 지원되는 확장자가 다를 때 유용하게 쓰일 수 있다.
OpenSSL에 여러 도메인_명을 지정해서 범용 CRT를 생성하기 위한 CSR을 생성한다면, CSR 구성파일 /etc/pki/tls/openssl.cnf에 이 도메인을 저장해 놓으면 된다. 일부 브라우저에서는 이름의 순서도 중요하므로 여러 종류의 구성 파일을 작성해 두고 적용시키면 편리할 수 있다.