본문 바로가기

개발/인프라

TLS 1.0 은 취약하다!

nginx에 ssl_protocols를 따로 설정하지 않으면 기본 값으로 TLSv1, TLSv1.1, and TLSv1.2 등을 지원한다 (nginx 버전 0.7.65 이상, OpenSSL 버전 1.0.1 이상). 근데 TSLv1  까지는 보안에 취약하다!! 뚠!!

그래서 1.TLSv1 vs TLSv1.1 vs TLSv1.2의 차이랑 2. nginx에서 사용하는 TLS 버전 확인 방법, 3. nginx 에서 TLS 버전 변경 방법, 정확히는 버전 1을 사용하지 않는 방법을 정리해보았다.


TLSv1 vs TLSv1.1 vs TLSv1.2

1. TLSv1.1 이 TLSv1과 다른 점 (RFC 4346)

- CBC 모드에 대한 공격에 방어하기 위해 명시적인 Initialization Vector(IV)가 아닌 implicit 한 IV를 사용하도록 했다.
- CBC 모드에 대한 공격에 방어하기 위해 패딩 에러를 처리할 때 bad_record_mac 경고를 사용하도록 변경되었다.
- 프로토콜 파라미터로 IANA registries 가 정의되었다.
- 통신이 중간에 끊겼을 때 해당 세션이 재활용될 수 있도록 했다.
- TLS에 대한 새로운 다양한 공격들에 대해 추가적인 정보들이 추가되었다.

(얼마 전에 AES 공부하면서 CBC에 대해 잠깐 보았었는 데, 다시 나와서 반가움..)

2. TLSv1.2 이 TLSv1.1과 다른 점 (RFC 5246)

굉장히 많은 데, 핵심적인 차이점은 유연성을 높이고, 암호화 협상을 위한 알고리즘을 개선이라고 한다. 
아래는 일부이다. 

- MD5/SHA-1을 사용하는 난수 생성 함수(PRF, pseudorandom function)가  P_SHA256을 사용하는 암호화 알고리즘의 PRF로 대체되었다.
- MD5/SHA-1을 사용하는 디지털 서명이 해시 함수(single hash)로 대체되었다.  디지털 서명은 사용된 해시 알고리즘을 명시하는 필드를 가지게 되었다.
- 암호화 알고리즘에 TLS_RSA_WITH_AES_128_CBC_SHA가 추가되었다. 
- HMAC-SHA256 암호화 알고리즘이 추가되었다.


지원하는 TLS 버전 확인 방법

테스트 환경: ubuntu 18.04.6 LTS, nginx 및 openSSL, https 도메인 연결

 1. nginx.conf 및 nginx 버전 확인

nginx.conf 에 ssl_protocols 가 정의되어있는지 확인해본다.
만약 정의되어있다면 nginx와 OpenSSL 버전이 지원하는 한에서 정의된 프로토콜들을 지원할 것이다.
만약 정의되어있지 않다면, nginx의 버전을 확인해본다.

nginx -v

테스트한 서버에서 nginx 의 버전은 1.20.1로 기본 적으로 TLSv1, TLSv1.1, TLSv1.2 등을 지원한다. 

2. OpenSSL 버전 확인

nginx에서 지원해도 OpenSSl 버전에 따라 지원되지 않을 수 있으니 OpenSSL 버전을 확인해본다.

openssl version

테스트한 서버에서 OpenSSL의 버전은 1.1.1로 TLSv1.2까지 지원한다

3. 지원하는 TLS 버전 확인

nginx에 정의된 도메인에 실제로 TLSv1과 TLSv1.1, TLSv1.2 가 지원되는지 확인해보았다.

curl -I -v --tlsv1.0 --tls-max 1.0 도메인
curl -I -v --tlsv1.1 --tls-max 1.1 도메인
curl -I -v --tlsv1.2 --tls-max 1.2 도메인
curl -I -v --tlsv1.3 --tls-max 1.3 도메인

-I와 -v 옵션을 제외해도 된다. 헤더 정보만 보여줄지, 결과를 자세하게 보여주는지에 대한 값이다.
위의 명령문을 실행해보았을 때, 지원되지 않으면 아래와 같이 에러가 발생한다.

curl: (35) error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version


TLSv1 사용하지 않기

위의 과정을 통해서 테스트 환경의 nginx에서 TLSv1.0 프로토콜을 지원하는 걸 확인했으니, 지원하지 않도록 수정해 보았다.
수정하는 방법은 정말 간단하다.

nginx.conf의 해당 도메인의 서버 블록에 ssl_protocols에 TLSv1.0을 제외해주면 된다!

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1.1 TLSv1.2;
    ...
}

그리고 nginx를 껐다 켜주면 되는 데, 테스트 환경은 도커를 사용하고 있고 nginx.conf를 바인딩했기 때문에 그냥 수정 후에 컨테이너를 restart 해주면 된다.

위에서 해주었던 대로 지원하는 TLS 버전을 확인해보면, 기존과 달리 --tlsv1.0 --tls-max 1.0 옵션의 curl 문에서 에러를 리턴한다.

curl -I -v --tlsv1.0 --tls-max 1.0 도메인

curl: (35) error:141E70BF:SSL routines:tls_construct_client_hello:no protocols available


이렇게 서버가 더 안전해졌다. 뿌-듯.

 

'개발 > 인프라' 카테고리의 다른 글

Git Action 으로 배포 자동화하기  (1) 2022.04.03
유저에게 도커 권한 주기  (0) 2022.03.20
계정 별 SSH 설정  (0) 2022.03.20
파일 권한 관리  (0) 2022.03.06
도커 네트워크 bridge, host 모드  (0) 2022.03.05