物联网设备常见的web服务器——uhttpd源码分析(一)
字数 2061 2025-08-05 11:39:33

uHTTPd Web服务器源码分析教学文档

0x00 前言

uHTTPd 是一个为OpenWrt/LUCI开发者设计的轻量级Web服务器,主要特点包括:

  • 专为嵌入式设备设计,资源占用低
  • 与OpenWrt配置框架(UCI)深度整合
  • 默认用于OpenWrt的Web管理接口LuCI
  • 提供常规Web服务器所需的所有功能

0x01 为什么分析uHTTPd

分析uHTTPd的主要原因:

  1. 在物联网设备中极为常见
  2. 物联网设备漏洞多出现在Web服务器上
  3. 理解开源Web服务器开发流程有助于挖掘物联网漏洞
  4. 事半功倍的效果

源码下载地址:https://git.openwrt.org/?p=project/uhttpd.git;a=summary (点击snapshot下载)

0x02 主函数main分析

主要功能流程

  1. 初始化默认参数
  2. 设置信号屏蔽
  3. 解析用户输入参数
  4. 解析配置文件
  5. 初始化工作目录
  6. 初始化默认主页和CGI路径
  7. 初始化TLS(HTTPS)支持
  8. 初始化插件(Lua/UBUS)
  9. 创建守护进程
  10. 运行服务器主循环

关键代码结构

int main(int argc, char **argv) {
    // 初始化
    uh_dispatch_add(&cgi_dispatch);
    init_defaults_pre();
    signal(SIGPIPE, SIG_IGN);
    
    // 参数解析
    while ((ch = getopt(...)) != -1) {
        // 处理各种参数
    }
    
    // 配置解析
    uh_config_parse();
    
    // 目录和默认设置
    if (!conf.docroot) {
        // 设置工作目录
    }
    init_defaults_post();
    
    // TLS初始化
#ifdef HAVE_TLS
    if (n_tls) {
        uh_tls_init(tls_key, tls_crt, tls_ciphers);
    }
#endif
    
    // 插件初始化
#ifdef HAVE_LUA
    uh_plugin_init("uhttpd_lua.so");
#endif
#ifdef HAVE_UBUS
    uh_plugin_init("uhttpd_ubus.so");
#endif
    
    // 守护进程
    if (!nofork) {
        fork();
    }
    
    // 主循环
    return run_server();
}

0x03 信号处理

关键信号处理:

signal(SIGPIPE, SIG_IGN);

作用:

  • SIGPIPE默认会导致进程终止
  • 在发送/接收数据时可能产生SIGPIPE信号
  • 设置SIG_IGN忽略该信号,避免进程意外退出

参考资料:

  1. SIGPIPE信号详解
  2. signal函数手册

0x04 配置文件解析

uh_config_parse()函数功能:

  • 默认配置文件路径:/etc/httpd.conf
  • 支持解析的配置项:
    • 认证信息:/path:user:pass
    • 默认主页:I:index.html
    • 错误处理:E404:/error.html
    • 解释器:*.ext:/path/to/interpreter

解析逻辑:

while (fgets(line, sizeof(line) - 1, c)) {
    if ((line[0] == '/') && (strchr(line, ':') != NULL)) {
        // 处理认证信息
        uh_auth_add(line, col1, col2);
    } else if (!strncmp(line, "I:", 2)) {
        // 处理默认主页
        uh_index_add(strdup(col1));
    } else if (!strncmp(line, "E404:", 5)) {
        // 处理错误页面
        conf.error_handler = strdup(col1);
    } else if ((line[0] == '*') && (strchr(line, ':') != NULL)) {
        // 处理解释器
        uh_interpreter_add(col1, col2);
    }
}

0x05 默认设置初始化

init_defaults_post()函数功能:

  1. 设置默认主页文件:
    • index.html
    • index.htm
    • default.html
    • default.htm
  2. 初始化CGI路径:
    • 将docroot与cgi_prefix拼接
    • 如:/var/www + /cgi-bin = /var/www/cgi-bin

关键代码:

void init_defaults_post(void) {
    uh_index_add("index.html");
    uh_index_add("index.htm");
    uh_index_add("default.html");
    uh_index_add("default.htm");
    
    if (conf.cgi_prefix) {
        char *str = malloc(strlen(conf.docroot) + strlen(conf.cgi_prefix) + 1);
        strcpy(str, conf.docroot);
        strcat(str, conf.cgi_prefix);
        conf.cgi_docroot_path = str;
        conf.cgi_prefix_len = strlen(conf.cgi_prefix);
    };
}

0x06 插件系统

uh_plugin_init()函数功能:

  • 动态加载.so插件
  • 查找并调用插件初始化函数
  • 支持插件:Lua、UBUS等

关键流程:

  1. 使用dlopen加载.so文件
  2. 使用dlsym查找初始化函数
  3. 调用插件初始化函数

代码实现:

int uh_plugin_init(const char *name) {
    // 加载动态库
    dlh = dlopen(name, RTLD_LAZY | RTLD_GLOBAL);
    
    // 查找初始化函数
    sym = "uhttpd_plugin";
    p = dlsym(dlh, sym);
    
    // 调用初始化
    list_add(&p->list, &plugins);
    return p->init(&ops, &conf);
}

dlopen函数

  • 功能:打开动态链接库
  • 默认路径:/usr/lib/
  • 失败返回NULL
  • 参考:dlopen手册

dlsym函数

  • 功能:获取符号地址
  • 可获取函数或变量地址
  • uHTTPd中用于获取初始化函数
  • 参考:dlsym百科

0x07 服务器主循环

run_server()函数(待续):

  • 主要功能:
    • 初始化事件循环
    • 设置监听socket
    • 处理客户端连接
    • 分发HTTP请求

关键参数说明

uHTTPd支持的主要命令行参数:

参数 功能描述
-p 指定监听端口
-h 指定文档根目录
-H 添加处理程序脚本
-E 指定错误处理程序
-I 添加索引页面
-S 禁用符号链接
-D 禁用目录列表
-x 设置CGI路径前缀
-y 添加别名
-i 添加解释器
-t 设置脚本超时
-T 设置网络超时
-f 禁止fork(前台运行)
-c 指定配置文件

安全相关配置

  1. 认证配置:

    • 格式:/path:user:pass
    • 存储在/etc/httpd.conf中
  2. 解释器配置:

    • 格式:*.ext:/path/to/interpreter
    • 用于指定特定扩展名的处理程序
  3. 安全限制:

    • -S 禁用符号链接(防止目录遍历)
    • -D 禁用目录列表(防止信息泄露)
    • -R 启用RFC1918过滤(限制内网访问)

开发建议

  1. 插件开发:

    • 实现uhttpd_plugin结构体
    • 提供初始化函数
    • 放置在/usr/lib/目录下
  2. 功能扩展:

    • 通过dispatch_handlers链表添加处理器
    • 支持CGI、Lua等多种扩展方式
  3. 安全注意事项:

    • 正确处理信号
    • 验证所有输入路径
    • 限制脚本执行权限

总结

uHTTPd作为物联网设备常用的轻量级Web服务器,其设计特点包括:

  1. 模块化架构,支持插件扩展
  2. 精简的代码实现,适合嵌入式环境
  3. 灵活的配置方式,支持命令行和配置文件
  4. 完善的安全控制选项

通过分析其源码,可以深入理解:

  • 嵌入式Web服务器的设计原理
  • HTTP协议的处理流程
  • 插件系统的实现方式
  • 安全防护的最佳实践

这为物联网设备的安全分析和漏洞挖掘提供了坚实基础。

uHTTPd Web服务器源码分析教学文档 0x00 前言 uHTTPd 是一个为OpenWrt/LUCI开发者设计的轻量级Web服务器,主要特点包括: 专为嵌入式设备设计,资源占用低 与OpenWrt配置框架(UCI)深度整合 默认用于OpenWrt的Web管理接口LuCI 提供常规Web服务器所需的所有功能 0x01 为什么分析uHTTPd 分析uHTTPd的主要原因: 在物联网设备中极为常见 物联网设备漏洞多出现在Web服务器上 理解开源Web服务器开发流程有助于挖掘物联网漏洞 事半功倍的效果 源码下载地址:https://git.openwrt.org/?p=project/uhttpd.git;a=summary (点击snapshot下载) 0x02 主函数main分析 主要功能流程 初始化默认参数 设置信号屏蔽 解析用户输入参数 解析配置文件 初始化工作目录 初始化默认主页和CGI路径 初始化TLS(HTTPS)支持 初始化插件(Lua/UBUS) 创建守护进程 运行服务器主循环 关键代码结构 0x03 信号处理 关键信号处理: 作用: SIGPIPE默认会导致进程终止 在发送/接收数据时可能产生SIGPIPE信号 设置SIG_ IGN忽略该信号,避免进程意外退出 参考资料: SIGPIPE信号详解 signal函数手册 0x04 配置文件解析 uh_config_parse() 函数功能: 默认配置文件路径:/etc/httpd.conf 支持解析的配置项: 认证信息: /path:user:pass 默认主页: I:index.html 错误处理: E404:/error.html 解释器: *.ext:/path/to/interpreter 解析逻辑: 0x05 默认设置初始化 init_defaults_post() 函数功能: 设置默认主页文件: index.html index.htm default.html default.htm 初始化CGI路径: 将docroot与cgi_ prefix拼接 如:/var/www + /cgi-bin = /var/www/cgi-bin 关键代码: 0x06 插件系统 uh_plugin_init() 函数功能: 动态加载.so插件 查找并调用插件初始化函数 支持插件:Lua、UBUS等 关键流程: 使用dlopen加载.so文件 使用dlsym查找初始化函数 调用插件初始化函数 代码实现: dlopen函数 功能:打开动态链接库 默认路径:/usr/lib/ 失败返回NULL 参考: dlopen手册 dlsym函数 功能:获取符号地址 可获取函数或变量地址 uHTTPd中用于获取初始化函数 参考: dlsym百科 0x07 服务器主循环 run_server() 函数(待续): 主要功能: 初始化事件循环 设置监听socket 处理客户端连接 分发HTTP请求 关键参数说明 uHTTPd支持的主要命令行参数: | 参数 | 功能描述 | |------|----------| | -p | 指定监听端口 | | -h | 指定文档根目录 | | -H | 添加处理程序脚本 | | -E | 指定错误处理程序 | | -I | 添加索引页面 | | -S | 禁用符号链接 | | -D | 禁用目录列表 | | -x | 设置CGI路径前缀 | | -y | 添加别名 | | -i | 添加解释器 | | -t | 设置脚本超时 | | -T | 设置网络超时 | | -f | 禁止fork(前台运行) | | -c | 指定配置文件 | 安全相关配置 认证配置: 格式: /path:user:pass 存储在/etc/httpd.conf中 解释器配置: 格式: *.ext:/path/to/interpreter 用于指定特定扩展名的处理程序 安全限制: -S 禁用符号链接(防止目录遍历) -D 禁用目录列表(防止信息泄露) -R 启用RFC1918过滤(限制内网访问) 开发建议 插件开发: 实现 uhttpd_plugin 结构体 提供初始化函数 放置在/usr/lib/目录下 功能扩展: 通过dispatch_ handlers链表添加处理器 支持CGI、Lua等多种扩展方式 安全注意事项: 正确处理信号 验证所有输入路径 限制脚本执行权限 总结 uHTTPd作为物联网设备常用的轻量级Web服务器,其设计特点包括: 模块化架构,支持插件扩展 精简的代码实现,适合嵌入式环境 灵活的配置方式,支持命令行和配置文件 完善的安全控制选项 通过分析其源码,可以深入理解: 嵌入式Web服务器的设计原理 HTTP协议的处理流程 插件系统的实现方式 安全防护的最佳实践 这为物联网设备的安全分析和漏洞挖掘提供了坚实基础。