티스토리 뷰

 

HTTPS에서 들어봤던 TLS

 

HTTPS는 HTTP에 SSL이나 TLS 동작이 추가된 프로토콜입니다.

 

SSL(Secure Sockets Layer)

TLS(Transport Layer Security)

는 모두 인증과 암호화를 수행하는 프로토콜입니다.

 

SSL를 개선한 것TLS로, 현재는 TLS만 주로 사용한다고 합니다.

 

TLS는 TCP기반 Application layer에서 이용하는 네트워크 통신 보안 강화를 위한 프로토콜입니다.

HTTP 뿐만 아니라 MQTT, SMTP 등 TCP 위에서 동작하는 프로토콜에 적용할 수 있습니다.

 


 

 

TLS를 적용하면 네트워크 통신이 암호화되고, 서버 신원 인증도 가능합니다.

TLS는 암호화된 통신 시작 전 handshake 과정이 있습니다.

 

 

 

Client ➡️ Server : TLS 요청 

 

Client ⬅️ Server : 서버 인증서 전송

 

Client ➡️ Server : 서버 인증서 확인 및 Session 키 전송

 

 

session키가 없으면 패킷을 복호화할 수 없습니다. 

 

TLS는 통신 전 인증서로 신뢰 확인하고, session 키를 만들어 암호화된 통신을 한다.

 


 

 

실제 MQTT에도 TLS 암호화 통신을 적용해 보겠습니다.

 

실습

 

1. TLS 인증서 준비

 

TLS Handshake 과정에서 서버는 인증서를 클라이언트에게 전송합니다.

클라이언트는 이 인증서를 발급한 인증기관이 신뢰 목록에 있는지 등을 확인합니다.

 

구체적인 흐름은 아래와 같습니다.

이 흐름에 따라 필요한 인증서, 키 등을 생성해야 합니다.

 

 

 

 

❇️ CA (Certificate Authority)

: 인증기관

믿을 수 있는 서버임을 보증해 주는 제 3자입니다.

 

실제 상용 서비스는 공인 CA에서 인증서를 발급받아야 하지만,

개발용, 사내망 서비스용으로는 자체 CA를 만들어도 OK


자체 CA는 클라이언트가 따로 ca.crt를 신뢰하도록 등록해야 한다는 특징이 있습니다. 

 


 

ver 1) 자체 CA

 

(1) CA 키와 CA 인증서 만들기

 
# CA 키 생성
openssl genrsa -out ca.key 2048
 
# CA 인증서 생성 (10년짜리 유효기간)
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt
 
  • ca.key: CA의 비밀 키
  • ca.crt: 클라이언트가 신뢰하도록 등록할 CA 인증서

(2) 서버 비밀키와 CSR (인증요청서) 만들기

 
# 서버 키 생성
openssl genrsa -out server.key 2048
 
# 서버 CSR 생성
openssl req -new -key server.key -out server.csr
 

 

  • server.key: 서버의 개인 키
  • server.csr: 서버의 인증 요청서 (CA에게 보내는 인증 요청서)
  • Common Name(CN)에는 서버 주소를 적습니다. (로컬은 localhost)

 


 

(3) CA로 서버 인증서 발급해 주기

 
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -sha256
 
  • server.crt: 서버 인증서
 
 
 
 
 
 

ver 2) 공인 CA

 
무료 공인 CA인 Let's Encrypt를 사용해보겠습니다.
가 아니라 못하겠습니다.
 
공인 CA는 DNS로 소유권을 검증하기 때문에 도메인이 꼭 필요합니다.
저는 도메인이 없으니까, 자체 CA로만 해볼 수 있겠네요...
 
 

 

 

2. Mosquitto에서 TLS설정

 

 

기존의 moquitto 설정파일에

TLS 인증서 내용을 추가하겠습니다.

 

# TLS 적용 리스너
listener 8883
cafile /{path}/ca.crt
certfile /{path}/server.crt
keyfile /{path}/server.key

# 클라이언트 인증 요구 안함 (필요시 true로)
require_certificate false

 

 


 

 

 

실제로 테스트해보겠습니다.

ca.crt파일을 검증하는 TLS Handshake -> session 키 생성 -> TLS 암호화 통신 채널 -> MQTT 패킷 송수신

과정이 일어나게 됩니다.

 

 

1. mosquitto를 띄웁니다.

mosquitto -c /{path}/mosquitto.conf

 

2. 구독해 주고

mosquitto_sub -h localhost -p 8883 \
  --cafile ./certs/ca.crt \
  -t "test/topic" \
  --insecure

 

3. 발행하면

mosquitto_pub -h localhost -p 8883 \
  --cafile ./certs/ca.crt \
  -t "test/topic" \
  -m "MQTT+TLS test" \
  --insecure

 

잘 전송되고 있습니다.

 

 

진짜 패킷이 암호화되어있을까.. 싶어서 한 번 패킷을 보겠습니다.

 

`tcpdump` : 패킷 캡처 도구

`-i lo0` : localhost

`-X` : 패킷의 내용(HEX+ASCII) 출력

 

오 완전 암호화 잘 되어있어 보이네요.

평문이 아니라 암호화된 바이너리 데이터로 보입니다.

 

성공!!

공지사항
최근에 올라온 글