在嵌入式Linux平台上实现HTTPS服务器,核心是集成TLS/SSL加密库与轻量级HTTP服务框架,同时兼顾资源限制(如内存、CPU)。以下是分步骤的详细实现指南,适用于i.MX6ULL、树莓派等嵌入式设备。

一、环境准备与依赖配置
基础环境要求

嵌入式Linux系统(如Yocto、Buildroot构建)需预装:

交叉编译工具链(如arm-linux-gnueabihf-gcc)。

基础网络库(如libpthread、librt)。

轻量级HTTP服务器框架(可选libmicrohttpd或自定义实现)。

TLS/SSL加密库(推荐mbedTLS,轻量且适合嵌入式)。
交叉编译mbedTLS库

mbedTLS是嵌入式场景的首选,需为其交叉编译静态库(减少动态依赖):
下载mbedTLS源码

git clone https://github.com/Mbed-TLS/mbedtls.git
cd mbedtls

配置交叉编译环境(假设目标平台为arm-linux-gnueabihf)

make clean
make CC=arm-linux-gnueabihf-gcc
CFLAGS=“-Os -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard”
LDFLAGS=“-Wl,–gc-sections”
library -j4

安装头文件和库到目标目录(如/rootfs/usr)

mkdir -p …/output/usr/lib …/output/usr/include
cp -r include …/output/usr/
cp library/libmbedtls.a library/libmbedcrypto.a library/libmbedx509.a …/output/usr/lib/

选择HTTP服务器框架

方案1:轻量级库(如libmicrohttpd)

libmicrohttpd是GNU开发的轻量级HTTP服务器库,支持回调模式,适合嵌入式。需交叉编译并集成mbedTLS。
方案2:自定义HTTP解析

若需极致轻量,可手动解析HTTP请求(基于TCP套接字),但开发成本较高。

二、基于libmicrohttpd的HTTPS服务器实现
交叉编译libmicrohttpd(集成mbedTLS)

libmicrohttpd支持通过–with-tls选项启用TLS,需指定mbedTLS路径:
下载libmicrohttpd源码

git clone https://github.com/libmicrohttpd/libmicrohttpd.git
cd libmicrohttpd

配置(启用HTTPS并指定mbedTLS路径)

./configure --host=arm-linux-gnueabihf
–prefix=/usr
–with-tls=mbedtls
–with-pic
CFLAGS=“-I…/output/usr/include”
LDFLAGS=“-L…/output/usr/lib -lmbedtls -lmbedcrypto -lmbedx509”

编译并安装到目标目录

make -j4
make install DESTDIR=…/output

编写HTTPS服务器代码

以下是简化的示例代码,实现HTTPS GET请求处理:
include <stdio.h>

include <stdlib.h>

include <string.h>

include <microhttpd.h>

include <mbedtls/ssl.h>

define PORT 443

define CERT_FILE “/etc/ssl/certs/server.crt” // 设备存储的证书路径

define KEY_FILE “/etc/ssl/private/server.key” // 私钥路径

// 回调函数:处理客户端请求
static int answer_to_connection(void cls, struct MHD_Connection connection,
const char url, const char method,
const char version, const char upload_data,
size_t upload_data_size, void *con_cls) {
const char *response_str = “

Embedded HTTPS Server

”;
struct MHD_Response *response;
int ret;

// 创建响应对象
response = MHD_create_response_from_buffer(strlen(response_str), 
                                          (void*)response_str, 
                                          MHD_RESPMEM_PERSISTENT);
if (!response) return MHD_NO;

// 发送响应(自动处理TLS加密)
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
MHD_destroy_response(response);
return ret;

int main() {

struct MHD_Daemon *daemon;

// 启动HTTPS服务器(指定证书和私钥)
daemon = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL,
                         PORT, NULL, NULL,
                         &answer_to_connection, NULL,
                         MHD_OPTION_HTTPS_MEM_KEY, KEY_FILE,
                         MHD_OPTION_HTTPS_MEM_CERT, CERT_FILE,
                         MHD_OPTION_END);

if (!daemon) {
    fprintf(stderr, "Failed to start HTTPS server\n");
    return 1;

printf(“HTTPS server running on port %d…\n”, PORT);

getchar(); // 按回车停止服务器
MHD_stop_daemon(daemon);
return 0;

交叉编译服务器程序

编译命令(假设已安装libmicrohttpd开发库)

arm-linux-gnueabihf-gcc -o https_server https_server.c
-I…/output/usr/include
-L…/output/usr/lib
-lmicrohttpd -lmbedtls -lmbedcrypto -lmbedx509 -lpthread

部署到嵌入式设备

将编译后的https_server二进制文件、证书(server.crt)、私钥(server.key)复制到设备的/usr/bin/和/etc/ssl/目录。

确保设备防火墙开放443端口(或自定义端口)。

三、证书生成与管理

HTTPS服务器需要数字证书验证身份,嵌入式设备常用自签名证书(生产环境建议由CA签发)。
生成自签名证书(OpenSSL)

在PC上生成证书,再烧录到设备:
生成私钥(2048位)

openssl genrsa -out server.key 2048

生成证书请求(CSR)

openssl req -new -key server.key -out server.csr
-subj “/CN=embedded-server.local/O=MyCompany/C=CN”

生成自签名证书(有效期365天)

openssl x509 -req -in server.csr -signkey server.key -out server.crt -days 365

设备端证书存储

将server.crt(公钥证书)和server.key(私钥)存入设备的非易失性存储(如/etc/ssl/)。

注意私钥权限:需设置为仅服务器进程可读(如chmod 600 server.key)。

四、调试与优化
测试服务器连通性

在PC上使用curl测试(需信任自签名证书):

curl -k https://嵌入式设备IP:443  # -k跳过证书验证(测试用)

若返回HTML内容,说明服务器正常工作。
常见问题排查

证书验证失败:检查证书路径是否正确,私钥是否匹配(openssl x509 -noout -modulus -in server.crt openssl md5与openssl rsa -noout -modulus -in server.key
openssl md5应一致)。

TLS握手失败:确认mbedTLS支持的TLS版本(默认TLS 1.2),可通过MHD_OPTION_HTTPS_TLS_VERSION选项调整。

内存不足:使用valgrind或嵌入式内存分析工具(如gdbserver)检查内存泄漏。
性能优化

启用硬件加速:若设备支持(如i.MX6ULL的AES/SHA引擎),需在mbedTLS中启用硬件加速(修改mbedtls/config.h):

#define MBEDTLS_AES_ALT

#define MBEDTLS_SHA256_ALT

会话复用:配置TLS会话重用(mbedtls_ssl_conf_session_cache),减少握手开销。

轻量级配置:关闭不必要的TLS特性(如RSA密钥交换,改用ECC),减小计算量。

五、替代方案:自定义HTTP服务器(极轻量场景)

若需极致资源优化(如无库依赖),可手动实现TCP+TLS+HTTP逻辑:
TCP套接字创建:使用socket()、bind()、listen()、accept()建立TCP连接。

TLS握手:基于mbedTLS的mbedtls_ssl_context完成加密协商。

HTTP解析:手动解析请求行(如GET / HTTP/1.1)、头部(如Host:),生成响应。

示例流程(简化):
include <mbedtls/net_sockets.h>

include <mbedtls/ssl.h>

include <mbedtls/entropy.h>

include <mbedtls/ctr_drbg.h>

void https_server() {
mbedtls_net_context listen_fd;
mbedtls_ssl_config conf;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;

// 初始化随机数生成器
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);

// 初始化TLS配置
mbedtls_ssl_config_init(&conf);
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
mbedtls_ssl_conf_min_version(&conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); // TLS 1.2+

// 创建TCP监听套接字
mbedtls_net_init(&listen_fd);
mbedtls_net_bind(&listen_fd, NULL, "443", MBEDTLS_NET_PROTO_TCP);

while (1) {
    mbedtls_net_context client_fd;
    mbedtls_ssl_init(&ssl);

    // 接受客户端连接
    mbedtls_net_accept(&listen_fd, &client_fd, NULL, 0, NULL);

    // 设置TLS上下文
    mbedtls_ssl_setup(&ssl, &conf);
    mbedtls_ssl_set_fd(&ssl, client_fd.fd);

    // 执行TLS握手
    mbedtls_ssl_handshake(&ssl);

    // 读取HTTP请求(示例:读取GET请求)
    char buf[1024];
    mbedtls_ssl_read(&ssl, (unsigned char*)buf, sizeof(buf)-1);
    printf("Received: %s\n", buf);

    // 发送HTTP响应
    const char *resp = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>Hello</h1>";
    mbedtls_ssl_write(&ssl, (unsigned char*)resp, strlen(resp));

    // 清理资源
    mbedtls_ssl_close_notify(&ssl);
    mbedtls_ssl_free(&ssl);
    mbedtls_net_free(&client_fd);

}

总结

在嵌入式Linux上实现HTTPS服务器的核心是集成轻量级TLS库(如mbedTLS)与HTTP服务框架(如libmicrohttpd),关键步骤包括:
交叉编译依赖库;

生成并部署证书;

实现TLS握手与HTTP请求处理;

调试优化资源使用。

根据设备资源限制选择方案(libmicrohttpd适合通用场景,自定义实现适合极轻量需求)。

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐