์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

ESP32 MQTT over TLS ํ†ต์‹  ์‹œ MbedTLS ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์žฌ๋ถ€ํŒ… ์›์ธ ๋ถ„์„๊ณผ ์„ธ์…˜ ์žฌ๊ฐœ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•

๊ฒŒ์ž„๊ต์ˆ˜ 2026. 9. 3. 04:02
๋ฐ˜์‘ํ˜•

๐ŸŒ English Abstract

This article addresses the critical issue of ESP32 system reboots caused by MbedTLS dynamic memory allocation failures during MQTT over TLS handshakes. It provides a comprehensive troubleshooting guide to analyze heap memory fragmentation and optimize buffer configurations in ESP-IDF. Furthermore, it details how to implement TLS Session Resumption to drastically reduce handshake memory overhead and connection latency in embedded IoT devices.

์ž„๋ฒ ๋””๋“œ IoT(Internet of Things) ์‹œ์Šคํ…œ ๊ฐœ๋ฐœ์—์„œ ๋ฐ์ดํ„ฐ ๋ณด์•ˆ์€ ๋” ์ด์ƒ ์„ ํƒ์ด ์•„๋‹Œ ํ•„์ˆ˜ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ESP32 ๋งˆ์ดํฌ๋กœ์ปจํŠธ๋กค๋Ÿฌ ํ™˜๊ฒฝ์—์„œ MQTT ํ†ต์‹ ์„ ๊ตฌํ˜„ํ•  ๋•Œ, ์•”ํ˜ธํ™”๋˜์ง€ ์•Š์€ ํฌํŠธ(1883) ๋Œ€์‹  TLS(Transport Layer Security)๋ฅผ ์ ์šฉํ•œ MQTT over TLS(ํฌํŠธ 8883) ๊ธฐ์ˆ ์„ ํ‘œ์ค€์œผ๋กœ ์ฑ„ํƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•œ์ •๋œ ์‹œ์Šคํ…œ ๋ฉ”๋ชจ๋ฆฌ ์ž์›์„ ๊ฐ€์ง„ ESP32์—์„œ TLS ํ†ต์‹ ์„ ์ˆ˜ํ–‰ํ•  ๋•Œ, ์›์ธ์„ ์•Œ ์ˆ˜ ์—†๋Š” ๋ฌด์ž‘์œ„ ์žฌ๋ถ€ํŒ…(Reboot)์ด๋‚˜ ๋ฆฌ์…‹ ํ˜„์ƒ์„ ๊ฒฝํ—˜ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ํ˜„์ƒ์˜ ์ฃผ๋œ ์›์ธ์€ TLS ํ•ธ๋“œ์…ฐ์ดํฌ(Handshake) ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜๋Š” MbedTLS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋™์  ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์‹คํŒจ(Dynamic Memory Allocation Failure / Heap Exhaustion)์ž…๋‹ˆ๋‹ค. ๋ณธ ํฌ์ŠคํŒ…์—์„œ๋Š” ESP32์—์„œ TLS ์•”ํ˜ธํ™” ํ†ต์‹  ์‹œ ๋ฐœ์ƒํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์žฌ๋ถ€ํŒ… ๋ฌธ์ œ์˜ ๊ทผ๋ณธ์ ์ธ ์›์ธ์„ ๊นŠ์ด ์žˆ๊ฒŒ ๋ถ„์„ํ•˜๊ณ , MbedTLS ๋ฒ„ํผ ์ตœ์ ํ™” ๋ฐ TLS ์„ธ์…˜ ์žฌ๊ฐœ(Session Resumption) ๊ธฐ๋ฒ•์„ ํ†ตํ•ด ์‹œ์Šคํ…œ ์•ˆ์ •์„ฑ๊ณผ ์—ฐ๊ฒฐ ์†๋„๋ฅผ ํš๊ธฐ์ ์œผ๋กœ ๊ฐœ์„ ํ•˜๋Š” ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๊ณผ์ •์„ ์ƒ์„ธํžˆ ๋‹ค๋ฃน๋‹ˆ๋‹ค.



1. ๋ฌธ์ œ ํ˜„์ƒ ๋ฐ ์›์ธ ๋ถ„์„: MbedTLS ํ•ธ๋“œ์…ฐ์ดํฌ์™€ ํž™ ๋ฉ”๋ชจ๋ฆฌ

ESP32๋Š” Wi-Fi ์Šคํƒ๊ณผ FreeRTOS, ๊ทธ๋ฆฌ๊ณ  ์‚ฌ์šฉ์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜์—ฌ ์•ฝ 320KB ์ˆ˜์ค€์˜ ๋‚ด์žฅ SRAM(Internal SRAM)์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐ Wi-Fi ์—ฐ๊ฒฐ ๋ฐ MQTT ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ ํ›„ ์ด์šฉ ๊ฐ€๋Šฅํ•œ ์‹ค์งˆ์ ์ธ ์—ฐ์† ํž™(Heap) ๋ฉ”๋ชจ๋ฆฌ๋Š” ์•ฝ 80KB~120KB ์ˆ˜์ค€์œผ๋กœ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋ฐ”๋กœ ์—ฌ๊ธฐ์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€. TLS ํ•ธ๋“œ์…ฐ์ดํฌ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€ํ•˜ ๊ตฌ์กฐ

TLS 1.2 ๋˜๋Š” 1.3 ํ”„๋กœํ† ์ฝœ ์ƒ์—์„œ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ€ ์ดˆ๊ธฐ ์—ฐ๊ฒฐ์„ ์ˆ˜๋ฆฝํ•  ๋•Œ ์ˆ˜ํ–‰๋˜๋Š” ์ „์ฒด ํ•ธ๋“œ์…ฐ์ดํฌ(Full Handshake) ๊ณผ์ •์€ ๋ง‰๋Œ€ํ•œ ๋™์  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

  • ์„œ๋ฒ„ ์ธ์ฆ์„œ ์ฒด์ธ ์ˆ˜์‹ (Server Certificate Verification): ๋ธŒ๋กœ์ปค๊ฐ€ ์ „์†กํ•˜๋Š” X.509 CA ์ธ์ฆ์„œ ์ฒด์ธ์˜ ํฌ๊ธฐ๊ฐ€ ํด ๊ฒฝ์šฐ(์˜ˆ: RSA 4096๋น„ํŠธ ๊ธฐ๋ฐ˜ ํ‚ค) ์ˆ˜ KB์—์„œ 10KB ์ด์ƒ์˜ ์ž…์ถœ๋ ฅ ๋ฒ„ํผ๊ฐ€ ํ•œ ๋ฒˆ์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.
  • ๋น„๋Œ€์นญ ํ‚ค ๊ตํ™˜ ์—ฐ์‚ฐ(Asymmetric Key Exchange): RSA ๋˜๋Š” ECC(Elliptic Curve Cryptography) ์—ฐ์‚ฐ ์‹œ ์ผ์‹œ์ ์ธ ๋น…์ธํ‹ฐ์ €(MPI, Multi-Precision Integer) ๊ณ„์‚ฐ์šฉ ํž™ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๊ธ‰๊ฒฉํžˆ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • TLS ๋ ˆ์ฝ”๋“œ ๋ฒ„ํผ(Record Buffer): TLS ๊ทœ๊ฒฉ์ƒ ์ตœ๋Œ€ ๋ ˆ์ฝ”๋“œ ํฌ๊ธฐ๋Š” 16,384 ๋ฐ”์ดํŠธ(16KB)์ž…๋‹ˆ๋‹ค. ์†ก์‹ (Tx) ๋ฐ ์ˆ˜์‹ (Rx) ๋ฒ„ํผ๋ฅผ ์ •์ ์œผ๋กœ ํ• ๋‹นํ•  ๊ฒฝ์šฐ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ตœ์†Œ 33KB ์ด์ƒ์˜ ํž™ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ฆ‰์‹œ ๊ณ ์ • ์ ์œ ๋ฉ๋‹ˆ๋‹ค.

ESP32 MbedTLS Handshake Memory Flow

๋‚˜. ํž™ ๋‹จํŽธํ™”(Heap Fragmentation)์™€ ์‹œ์Šคํ…œ ์žฌ๋ถ€ํŒ…์˜ ์—ฐ๊ด€์„ฑ

ESP32์—์„œ ์ „์ฒด ํž™ ์ž”์—ฌ๋Ÿ‰์ด 50KB ์ด์ƒ ๋‚จ์•„์žˆ๋‹ค๊ณ  ์ถœ๋ ฅ๋˜๋”๋ผ๋„ ํ•ธ๋“œ์…ฐ์ดํฌ๊ฐ€ ์‹คํŒจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ๋ฐ”๋กœ ํž™ ๋‹จํŽธํ™”(Heap Fragmentation) ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. MbedTLS ์—ฐ์‚ฐ ๊ณผ์ •์—์„œ ์ž‘์€ ํฌ๊ธฐ์˜ ๋ธ”๋ก ํ• ๋‹น๊ณผ ํ•ด์ œ๊ฐ€ ๋ฐ˜๋ณต๋˜๋ฉด์„œ ์—ฐ์†๋œ ํผ์งํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก(Largest Free Block)์ด ๊ณ ๊ฐˆ๋ฉ๋‹ˆ๋‹ค. ์ด ์ƒํ™ฉ์—์„œ MbedTLS๊ฐ€ 8KB ์ด์ƒ์˜ ์—ฐ์† ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์š”๊ตฌํ•˜๋ฉด malloc()์ด NULL์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋˜๋ฉฐ, ์ ์ ˆํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์–ด ์žˆ์ง€ ์•Š์„ ๊ฒฝ์šฐ StoreProhibited ํŒจ๋‹‰ ํ˜น์€ ์›Œ์น˜๋… ํƒ€์ด๋จธ(WDT)์— ์˜ํ•ด ๋””๋ฐ”์ด์Šค๊ฐ€ ๊ฐ•์ œ ์žฌ๋ถ€ํŒ…๋ฉ๋‹ˆ๋‹ค.

์˜ค๋ฅ˜ ์ฝ”๋“œ / ํŒจ๋‹‰ ๋ฉ”์‹œ์ง€ ๋ฐœ์ƒ ์œ„์น˜ ์ถ”์ • ์›์ธ
MBEDTLS_ERR_SSL_ALLOC_FAILED mbedtls_ssl_setup() SSL context ๋˜๋Š” ๋ฒ„ํผ ์ƒ์„ฑ์šฉ ํž™ ๋ถ€์กฑ
MBEDTLS_ERR_PK_ALLOC_FAILED mbedtls_pk_parse_key() ๊ฐœ์ธํ‚ค/๊ณต๊ฐœํ‚ค ํŒŒ์‹ฑ ์ค‘ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์‹คํŒจ
Guru Meditation Error: Core 1 panic mbedtls_handshake_step() NULL ํฌ์ธํ„ฐ ์—ญ์ฐธ์กฐ๋กœ ์ธํ•œ ๋ฉ”๋ชจ๋ฆฌ ์•ก์„ธ์Šค ์—๋Ÿฌ

2. ๋‹จ๊ณ„๋ณ„ MbedTLS ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™” ๋ฐ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…

์žฌ๋ถ€ํŒ… ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ๋จผ์ € ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…์€ ESP-IDF์˜ Build Configuration(๋˜๋Š” PlatformIO/Arduino sdkconfig) ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์กฐ์ •ํ•˜์—ฌ MbedTLS ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ footprint๋ฅผ ๊ทน์†Œํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ€. Dynamic Buffer Allocation ์˜ต์…˜ ํ™œ์„ฑํ™”

๊ธฐ๋ณธ ์„ค์ •์˜ MbedTLS๋Š” ์ตœ๋Œ€ ๋ ˆ์ฝ”๋“œ ํฌ๊ธฐ(16KB)์— ๋งž์ถ˜ Tx/Rx ๋ฒ„ํผ๋ฅผ ์—ฐ๊ฒฐ ์งํ›„ ๊ณ ์ • ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ESP-IDF ํ™˜๊ฒฝ์—์„œ๋Š” ๋™์  ๋ฒ„ํผ ํ• ๋‹น(Dynamic Buffer Allocation) ์˜ต์…˜์„ ์ผœ์„œ ํ•ธ๋“œ์…ฐ์ดํฌ ๋„์ค‘ ๋ฐ ์™„๋ฃŒ ํ›„์— ์‹ค์ œ๋กœ ํ•„์š”ํ•œ ํŽ˜์ด๋กœ๋“œ ํฌ๊ธฐ๋งŒํผ๋งŒ ๋ฒ„ํผ๋ฅผ ์œ ์ง€ํ•˜๋„๋ก ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • CONFIG_MBEDTLS_DYNAMIC_BUFFER=y: TX/RX ๋ฒ„ํผ๋ฅผ ํ•„์š” ์‹œ์ ์—๋งŒ ๋™์ ์œผ๋กœ ํ• ๋‹นํ•˜๊ณ  ์‚ฌ์šฉ ์™„๋ฃŒ ์‹œ ์ฆ‰์‹œ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.
  • CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y: ํ•ธ๋“œ์…ฐ์ดํฌ ์ข…๋ฃŒ ํ›„ ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ธ์ฆ์„œ ํŒŒ์‹ฑ ๋ฐ์ดํ„ฐ ๋ฐ ๊ตฌ์„ฑ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

๋‚˜. Maximum Content Length ์ ˆ๊ฐ ์„ค์ •

IoT ๋ธŒ๋กœ์ปค(AWS IoT Core, Mosquitto, HiveMQ ๋“ฑ)์—์„œ ์˜ค๊ฐ€๋Š” MQTT ๋ฉ”์‹œ์ง€ ํฌ๊ธฐ๊ฐ€ ์ˆ˜ KB ์ด๋‚ด๋ผ๋ฉด, TLS ๊ธฐ๋ณธ ์ž…์ถœ๋ ฅ ๋ฒ„ํผ ์ตœ๋Œ€ ํฌ๊ธฐ๋ฅผ ํ‘œ์ค€ 16384 ๋ฐ”์ดํŠธ์—์„œ 4096 ๋ฐ”์ดํŠธ ๋˜๋Š” 2048 ๋ฐ”์ดํŠธ๋กœ ์ถ•์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// sdkconfig ์„ค์ • ์˜ˆ์‹œ
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=4096
# ๋˜๋Š” menuconfig: Component config -> mbedTLS -> Maximum certificate chain length / Content length

์ด ์„ค์ •์„ ํ†ตํ•ด ํ•ธ๋“œ์…ฐ์ดํฌ ์ˆœ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌ ์š”๊ตฌ๋Ÿ‰์ด ๊ธฐ์กด ๋Œ€๋น„ ์ตœ๋Œ€ 60% ์ด์ƒ ๊ฐ์†Œํ•˜๋ฉฐ, ํž™ ๋‹จํŽธํ™” ๋ฌธ์ œ ๋ฐœ์ƒ ํ™•๋ฅ ์ด ๊ธ‰๊ฒฉํžˆ ๋‚ฎ์•„์ง‘๋‹ˆ๋‹ค.

๋‹ค. ECC ๊ธฐ๋ฐ˜ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜(ECDSA)์œผ๋กœ ์ „ํ™˜

๊ธฐ์กด์˜ RSA 2048๋น„ํŠธ ๋˜๋Š” 4096๋น„ํŠธ ๊ธฐ๋ฐ˜ ์•”ํ˜ธํ™”๋Š” ํ‚ค ํฌ๊ธฐ์™€ ์ธ์ฆ์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋น„๋Œ€ํ•˜์—ฌ ํŒŒ์‹ฑ ๋ฐ ๊ฒ€์ฆ ๋‹จ๊ณ„์—์„œ ๋ง‰๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ECDSA(Elliptic Curve Digital Signature Algorithm - secp256r1/P-256)๋ฅผ ์ ์šฉํ•˜๋ฉด ๋™์ผ ํ˜น์€ ๋” ๋†’์€ ๋ณด์•ˆ ๋ ˆ๋ฒจ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ํ‚ค ๋ฐ ์ธ์ฆ์„œ ํฌ๊ธฐ๋ฅผ 1/4 ์ดํ•˜๋กœ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



3. ์‹ฌํ™” ํ•ด๊ฒฐ์ฑ…: TLS ์„ธ์…˜ ์žฌ๊ฐœ(Session Resumption) ๊ตฌํ˜„

๋ฒ„ํผ ์กฐ์ •๋งŒ์œผ๋กœ๋„ ์ƒ๋‹น ๋ถ€๋ถ„ ๊ฐœ์„ ๋˜์ง€๋งŒ, Wi-Fi ์žฌ์—ฐ๊ฒฐ์ด๋‚˜ MQTT ์žฌ์ ‘์†์ด ๋นˆ๋ฒˆํ•œ ํ™˜๊ฒฝ์—์„œ๋Š” ์—ฌ์ „ํžˆ ์™„์ „ํ•œ ํ•ธ๋“œ์…ฐ์ดํฌ๊ฐ€ ๋ฐ˜๋ณต ์ˆ˜ํ–‰๋˜๋ฉฐ ๋ฉ”๋ชจ๋ฆฌ ํ”ผํฌ(Memory Peak)๋ฅผ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ถ๊ทน์ ์ธ ๊ธฐ๋ฒ•์ด ๋ฐ”๋กœ TLS ์„ธ์…˜ ์žฌ๊ฐœ(TLS Session Resumption / Session Tickets) ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค.

๊ฐ€. ์„ธ์…˜ ์žฌ๊ฐœ(Session Resumption)์˜ ์ž‘๋™ ์›๋ฆฌ

์ตœ์ดˆ 1ํšŒ ์ „์ฒด ํ•ธ๋“œ์…ฐ์ดํฌ(Full Handshake)๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๋งˆ์น˜๋ฉด, ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์•”ํ˜ธํ™”๋œ **์„ธ์…˜ ํ‹ฐ์ผ“(Session Ticket)**์„ ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ์—ฐ๊ฒฐ์ด ๋Š๊ฒผ๋‹ค๊ฐ€ ์žฌ์—ฐ๊ฒฐ๋  ๋•Œ ํด๋ผ์ด์–ธํŠธ๋Š” ์ด ํ‹ฐ์ผ“์„ ์„œ๋ฒ„์— ์ œ์‹œํ•˜์—ฌ ์ถ•์•ฝ๋œ ํ•ธ๋“œ์…ฐ์ดํฌ(Abbreviated Handshake)๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฌด๊ฑฐ์šด ๋ฌด์ž‘์œ„ ์ˆ˜ ์ƒ์„ฑ ๋ฐ ๋น„๋Œ€์นญํ‚ค ์—ฐ์‚ฐ ์ƒ๋žต: ์„œ๋ฒ„ ์ธ์ฆ์„œ ์ฒด์ธ ์ˆ˜์‹ ๊ณผ CPU ์ง‘์•ฝ์ ์ธ ํ‚ค ๊ตํ™˜ ๊ณผ์ •์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ ํ”ผํฌ ์ ˆ๊ฐ: ํ•ธ๋“œ์…ฐ์ดํฌ ์ˆœ๊ฐ„ ์š”๊ตฌ๋˜๋Š” ์ˆœ๊ฐ„ ์ตœ๊ณ  ํž™ ์‚ฌ์šฉ๋Ÿ‰์ด ๋Œ€ํญ ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.
  • ์—ฐ๊ฒฐ ์†Œ์š” ์‹œ๊ฐ„(Latency) ๋‹จ์ถ•: ํ‰๊ท  2.5์ดˆ ์ด์ƒ ์†Œ์š”๋˜๋˜ TLS Handshake ์‹œ๊ฐ„์ด 300ms~500ms ๋‚ด์™ธ๋กœ ๋‹จ์ถ•๋ฉ๋‹ˆ๋‹ค.

๋‚˜. ESP32 ESP-IDF/MbedTLS ์„ธ์…˜ ์žฌ๊ฐœ ์ฝ”๋“œ ๊ตฌํ˜„

๋‹ค์Œ์€ ESP-IDF ํ™˜๊ฒฝ์—์„œ MbedTLS ์„ธ์…˜ ๋ฐ์ดํ„ฐ๋ฅผ NVS(Non-Volatile Storage) ๋˜๋Š” RAM์— ์ €์žฅํ•˜๊ณ , ์žฌ์ ‘์† ์‹œ ์„ธ์…˜์„ ๋ณต์›ํ•˜์—ฌ ์ถ•์•ฝ ํ•ธ๋“œ์…ฐ์ดํฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” C/C++ ์†Œ์Šค์ฝ”๋“œ ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

#include "mbedtls/ssl.h"
#include "esp_log.h"
#include "nvs_flash.h"

static const char *TAG = "TLS_OPTIMIZATION";
static mbedtls_ssl_session saved_session;
static bool has_saved_session = false;

// 1. TLS Context ์„ค์ • ์‹œ ์„ธ์…˜ ํ‹ฐ์ผ“ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™”
void configure_tls_session_resumption(mbedtls_ssl_config *conf) {
    mbedtls_ssl_conf_session_tickets(conf, MBEDTLS_SSL_SESSION_TICKETS_ENABLED);
}

// 2. ์—ฐ๊ฒฐ ์„ฑ๊ณต ํ›„ ์„ธ์…˜ ์ €์žฅ ํ•จ์ˆ˜
void save_tls_session(mbedtls_ssl_context *ssl) {
    if (!has_saved_session) {
        mbedtls_ssl_session_init(&saved_session);
    } else {
        mbedtls_ssl_session_free(&saved_session);
    }

    int ret = mbedtls_ssl_get_session(ssl, &saved_session);
    if (ret == 0) {
        has_saved_session = true;
        ESP_LOGI(TAG, "TLS Session successfully saved for resumption.");
    } else {
        ESP_LOGE(TAG, "Failed to get TLS session, error: -0x%04X", -ret);
    }
}

// 3. ํ•ธ๋“œ์…ฐ์ดํฌ ์ „ ์ €์žฅ๋œ ์„ธ์…˜ ์‹œ๋„ ํ•จ์ˆ˜
void restore_tls_session(mbedtls_ssl_context *ssl) {
    if (has_saved_session) {
        int ret = mbedtls_ssl_set_session(ssl, &saved_session);
        if (ret == 0) {
            ESP_LOGI(TAG, "Restored previous TLS session ticket.");
        } else {
            ESP_LOGW(TAG, "Failed to set TLS session, performing full handshake.");
        }
    }
}

๋‹ค. ์„ธ์…˜ ์žฌ๊ฐœ ์‹œ ์œ ์˜ํ•ด์•ผ ํ•  ์˜ˆ์™ธ ์ฒ˜๋ฆฌ (Edge Cases)

์‹ค๋ฌด์— ์„ธ์…˜ ์žฌ๊ฐœ ๊ธฐ๋ฒ•์„ ๋„์ž…ํ•  ๋•Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ˆ์™ธ ์‚ฌ์•ˆ์— ๋Œ€ํ•œ ๊ฐ€๋“œ ์ฝ”๋“œ๋ฅผ ๋ฐ˜๋“œ์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. ์„ธ์…˜ ๋งŒ๋ฃŒ(Ticket Expiration): ๋ธŒ๋กœ์ปค ์„ค์ •์— ๋”ฐ๋ผ ์„ธ์…˜ ํ‹ฐ์ผ“ ์ˆ˜๋ช…์ด ์ง€์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค(๋ณดํ†ต 1์‹œ๊ฐ„~24์‹œ๊ฐ„). ์„œ๋ฒ„๊ฐ€ ํ‹ฐ์ผ“์„ ๊ฑฐ๋ถ€ํ•  ๊ฒฝ์šฐ MbedTLS๋Š” ์ž๋™์œผ๋กœ Full Handshake๋กœ Fallback ํ•˜๋ฏ€๋กœ ์ด๋ฅผ ์œ„ํ•œ ์˜ˆ๋น„ ํž™ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ™•๋ณด๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  2. ์„œ๋ฒ„ ์ธก ์žฌ๋ถ€ํŒ… ๋ฐ ๋‹ค์ค‘ ๋ธŒ๋กœ์ปค ๋กœ๋“œ๋ฐธ๋Ÿฐ์‹ฑ: ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ ๋’ค์— ๋ฐฐ์น˜๋œ ํด๋Ÿฌ์Šคํ„ฐํ˜• MQTT ๋ธŒ๋กœ์ปค ์„ธํŒ…์—์„œ๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ์ ‘์† ์‹œ ์ €์žฅ๋œ ์„ธ์…˜ ํ‹ฐ์ผ“ ํ‚ค๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ‹ฐ์ผ“ ๋ฌดํšจํ™” ๋ฐœ์ƒ ์‹œ ์„ธ์…˜ ๊ตฌ์กฐ์ฒด๋ฅผ mbedtls_ssl_session_free()๋กœ ์™„์ „ํžˆ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(Memory Leak)๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

4. ์„ฑ๋Šฅ ๊ฒ€์ฆ ๋ฐ ์ตœ์ ํ™” ํšจ๊ณผ ๋น„๊ต

๊ธฐ์กด ๊ธฐ๋ณธ ์„ค์ • ๋ฐฉ์‹๊ณผ ๋ณธ ๊ฐ€์ด๋“œ์—์„œ ์ œ์•ˆํ•œ ์ตœ์ ํ™” ๊ธฐ๋ฒ•(๋ฒ„ํผ ์ค„์ž„ + ์„ธ์…˜ ์žฌ๊ฐœ ์ ์šฉ)์„ ์ ์šฉํ–ˆ์„ ๋•Œ์˜ ESP32 ์‹œ์Šคํ…œ ํž™ ๋ฉ”๋ชจ๋ฆฌ ๋ฐ ํ•ธ๋“œ์…ฐ์ดํฌ ์†Œ์š” ์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ๋น„๊ต ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํ‰๊ฐ€ ํ•ญ๋ชฉ ์ตœ์ ํ™” ์ „ (Default RSA 2048) ์ตœ์ ํ™” ํ›„ (Dynamic Buffer + Session Resumption) ๊ฐœ์„ ์œจ
์ตœ์†Œ ์ž”์—ฌ ํž™ (Min Free Heap) ์•ฝ 8.2 KB (์œ„ํ—˜ ์ˆ˜์ค€) ์•ฝ 42.5 KB (์•ˆ์ •์ ) +418% ์ฆ๊ฐ€
์ตœ๋Œ€ ์—ฐ์† ๋ฉ”๋ชจ๋ฆฌ (Max Alloc Block) ์•ฝ 6.1 KB (๋‹จํŽธํ™” ์‹ฌํ•จ) ์•ฝ 31.0 KB +408% ์ฆ๊ฐ€
TLS ์—ฐ๊ฒฐ ์ˆ˜๋ฆฝ ์‹œ๊ฐ„ (Handshake Latency) ์•ฝ 2,650 ms ์•ฝ 380 ms ์•ฝ 85.6% ๋‹จ์ถ•
๋™์  ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์‹คํŒจ ์žฌ๋ถ€ํŒ… ๊ฐ„ํ—์  ๋ฐœ์ƒ (์ผ ์ˆ˜ํšŒ) ์ „ํ˜€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ (0ํšŒ) ์™„์ „ ํ•ด๊ฒฐ

์œ„ ๊ฒฐ๊ณผ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, ๋‹จ์ˆœํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ํŠœ๋‹๊ณผ TLS ์„ธ์…˜ ๊ธฐ๋ฒ•์„ ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ์‹œ์Šคํ…œ ์ž”์—ฌ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ถฉ๋ถ„ํžˆ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์—ˆ์œผ๋ฉฐ, ์ ‘์† ๋‹จ์ถ• ํšจ๊ณผ๊นŒ์ง€ ๋™์‹œ์— ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



5. ๊ฒฐ๋ก  ๋ฐ ์š”์•ฝ

ESP32 ๊ธฐ๋ฐ˜์˜ IoT ์ž„๋ฒ ๋””๋“œ ๊ธฐ๊ธฐ์—์„œ MQTT over TLS ํ†ต์‹  ๋„์ค‘ ๋ฐœ์ƒํ•˜๋Š” ๋ฌด์ž‘์œ„ ์žฌ๋ถ€ํŒ… ํ˜„์ƒ์€ ๋Œ€๋ถ€๋ถ„ MbedTLS ํ•ธ๋“œ์…ฐ์ดํฌ ์—ฐ์‚ฐ ์ค‘ ํž™ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ๋ฐ ๋‹จํŽธํ™”๋กœ ์ธํ•ด ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœ ํ•˜๋“œ์›จ์–ด ์žฌ๋ถ€ํŒ… ์กฐ์น˜์— ์˜์กดํ•˜๋Š” ๋Œ€์‹ , ์‹œ์Šคํ…œ ์„ค๊ณ„๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ณ ๋„ํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • CONFIG_MBEDTLS_DYNAMIC_BUFFER ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” SSL ๋ฒ„ํผ๋ฅผ ์ฆ‰์‹œ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋ฒ„/ํด๋ผ์ด์–ธํŠธ ์•”ํ˜ธํ™” ์ฒด๊ณ„๋ฅผ ๊ฐ€๋Šฅํ•˜๋ฉด RSA ๋Œ€์‹  ECDSA(Elliptic Curve)๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.
  • TLS Session Resumption์„ ๊ตฌํ˜„ํ•˜์—ฌ ์ ‘์† ์‹œ ๋ฐœ์ƒํ•˜๋Š” ๋น„๋Œ€์นญํ‚ค ์—ฐ์‚ฐ ๋ถ€๋‹ด์„ ์ค„์ด๊ณ , ์ตœ์†Œ ํž™ ๋ฉ”๋ชจ๋ฆฌ ํ•œ๊ณ„์„ (Minimum Ever Free Heap Size)์„ ํฌ๊ฒŒ ๋Œ์–ด์˜ฌ๋ฆฝ๋‹ˆ๋‹ค.

์ƒ๊ธฐ ์š”์†Œ๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ์ ์šฉํ•˜๋ฉด ESP32์˜ ์ œํ•œ๋œ ๋ฉ”๋ชจ๋ฆฌ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•˜๊ณ , ํ˜„์žฅ์— ๋ฐฐ์น˜๋œ IoT ๋””๋ฐ”์ด์Šค๊ฐ€ 24์‹œ๊ฐ„ 365์ผ ๋Š๊น€ ์—†์ด ์•ˆ์ „ํ•˜๊ณ  ๊ฒฌ๊ณ ํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋„๋ก ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•