mongoose 支持https踩坑纪实

简述

mongoose是C编写的嵌入式web服务,它能够支持https协议,可以简单的部署,但要做到完美部署,不是那么容易。

部署方法

本人使用的是最新的7.16版,以前版本似乎是要通过修改 头文件中的 MG_ENABLE_SSL 宏定义,将其值设置为 1 来开启 SSL 功能,这一版不是了。这一版要在 mongoose.h 头文件中将MG_TLS宏定义为如下六种中的一个。

#define MG_TLS_NONE 0 // No TLS support

#define MG_TLS_MBED 1 // mbedTLS

#define MG_TLS_OPENSSL 2 // OpenSSL

#define MG_TLS_WOLFSSL 5 // WolfSSL (based on OpenSSL)

#define MG_TLS_BUILTIN 3 // Built-in

#define MG_TLS_CUSTOM 4 // Custom implementation

#ifndef MG_TLS

#define MG_TLS MG_TLS_OPENSSL //我选择了OPENSSL

#endif

如果定义为MG_TLS_BUILTIN最简单,似乎是mongoose内置的TLS库,我最早就是用的它。它可以运行mongoose中的tutorials中的http示例了。也能够正确的加载它自签名的证书和私钥了。但很不幸,我在国内淘宝上购买的证书它不认,总是提醒不认识pks格式的证书。

所以我最终采用了MG_TLS_OPENSSL。这种方式需要装载OPENSSL库。我的方法是从OPENSSL网站下载完整的安装包,装完后,将其中的include目录考到工程里,然后指定该目录为工程的include目录(mongoose.h中采用#include <openssl/ssl.h>,所有必须置为工程的include目录)。然后将libcrypto.lib libssl.lib装载。我试了静态库,提示缺东西,我就没接着试,直接采用了引入动态lib库,并且将libcrypto-3-x64.dll,libssl-3-x64考到可执行目录下,结果编译成了。它也支持国内颁发的证书了。

程序的重要代码:

//事件处理函数:

// We use the same event handler function for HTTP and HTTPS connections

// fn_data is NULL for plain HTTP, and non-NULL for HTTPS

static void fn(struct mg_connection* c, int ev, void* ev_data) {

if (ev == MG_EV_ACCEPT && c->fn_data != NULL) {//如果事件是https的链接接收事件

struct mg_tls_opts opts;//最重要的tls配置参数

memset(&opts, 0, sizeof(opts));

#ifdef TLS_TWOWAY//如果是双向的,只有银行那样的应用,才会验证客户端的证书,所以一般不要设ca(证书机构的证书)

opts.ca = mg_str(s_tls_ca);

#endif

opts.cert = mg_str(s_tls_cert);//服务器证书字符串,你要想办法从文件中装进来

opts.key = mg_str(s_tls_key);//服务器私钥字符串,你要想办法从文件中装进来

mg_tls_init(c, &opts); //初始化tls链接,即若干握手、交换证书等等标准操作

}

if (ev == MG_EV_HTTP_MSG) {

//接收到数据消息事件

}

}

}

//启动消息循环处理代码

struct mg_mgr mgr; // Event manager

mg_mgr_init(&mgr); // Initialise event manager

mg_http_listen(&mgr, "http://0.0.0.0:80", fn, NULL); // Create HTTP listener

mg_http_listen(&mgr, "http://0.0.0.0:443", fn, (void*)1); // Create HTTP listener

for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop

mg_mgr_free(&mgr);

大坑

正常情况下,程序应该可以正常执行了,但大坑刚刚开始:由于我要将它作为微信小程序的后台,而微信小程序,要求网站的ssl评分要达到A级(使用https://myssl.com进行评估),而我的网站只有B级。

默认情况下是没有优先级的,所以需要#define MG_ENABLE_OPENSSL_CIPHER_SERVER_PREFERENCE宏

我放在了 mongoose.h 头文件大约2394行处

#if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL

#define MG_ENABLE_OPENSSL_CIPHER_SERVER_PREFERENCE

#include <openssl/err.h>

#include <openssl/ssl.h>

我在仔细分析了证书链后,发现mongoose默认根本没有向客户端发送证书链,struct mg_tls_opts中根本没有证书链的位置,最后我发现openssl本身提供了几个方法设置证书链,我挑了一个简单的函数SSL_use_certificate_chain_file(tls->ssl, "server_cert.pem"); 我把它加在了mg_tls_init函数中装载证书和私钥的代码下面,大约13172行处。结果就成了。

设置优先级

相关推荐
老蒋新思维7 小时前
创客匠人:认知即资产 ——AI 时代创始人 IP 知识变现的底层逻辑
网络·人工智能·网络协议·tcp/ip·重构·创始人ip·创客匠人
ZXF_H7 小时前
Linux tcpdump抓包实践(以http为例)
linux·http·wireshark·tcpdump
白驹过隙^^8 小时前
OB-USP-AGENT安装使用方法
数据库·经验分享·网络协议·tcp/ip·github·ssl
sdszoe49228 小时前
IP地址规划与VLSM技术
网络·网络协议·tcp/ip·vlsm·ip地址规划
北京耐用通信9 小时前
耐达讯自动化网关:用Profinet唤醒沉睡的DeviceNet流量计,省下60%改造费!
人工智能·科技·物联网·网络协议·自动化·信息与通信
Running_slave10 小时前
聊聊TCP滑窗的一些有趣“病症”
前端·网络协议·tcp/ip
想用offer打牌11 小时前
一站式了解跨域问题
网络协议·面试·架构
伊玛目的门徒11 小时前
HTTP SSE 流式响应处理:调用腾讯 智能应用开发平台ADP智能体的 API
python·网络协议·http·腾讯智能体·adp·智能应用开发平台
2501_9388101111 小时前
动态IP的使用方法
网络·网络协议·tcp/ip
无限大.12 小时前
为什么网站需要“域名“?——从 IP 地址到网址的演进
网络·网络协议·tcp/ip