suricata新增协议处理流程

发布于:2025-07-06 ⋅ 阅读:(16) ⋅ 点赞:(0)

suricata安装

根据文档suricata document完成suricata基于源码的安装

suricata源码下载

可通过命令下载源码
git clone https://github.com/OISF/suricata
如果发现github网速不理想,可使用gitee加速
git clone https://gitee.com/mirrors/suricata.git

suricata源码编译

编译过程可参考博文suricata编译
sh autogen.sh
./configure #该过程涉及到多个参数
make

框架代码产生

在代码根目录下执行 python scripts/setup-app-layer.py
在这里插入图片描述
提示需要输入协议名称;本文以mysql为例
python scripts/setup-app-layer.py mysql
执行完以上命令后,在rust/src目录下会产生
applayermysql目录;目录下的内容如下:

logger.rs mod.rs mysql.rs parser.rs

重新编译后,会发现相关的rust代码会编译进suricata

协议框架说明

在mysql.rs中会有一段代码,注册协议解析的各函数的入口


#[no_mangle]
pub unsafe extern "C" fn rs_mysql_register_parser() {
    let default_port = CString::new("[3306]").unwrap();
    let parser = RustParser {
        name: PARSER_NAME.as_ptr() as *const c_char,
        default_port: default_port.as_ptr(),
        ipproto: IPPROTO_TCP,
        probe_ts: Some(rs_mysql_probing_parser_ts),
        probe_tc: Some(rs_mysql_probing_parser_tc),
        min_depth: 0,
        max_depth: 16,
        state_new: rs_mysql_state_new,
        state_free: rs_mysql_state_free,
        tx_free: rs_mysql_state_tx_free,
        parse_ts: rs_mysql_parse_request,
        parse_tc: rs_mysql_parse_response,
        get_tx_count: rs_mysql_state_get_tx_count,
        get_tx: rs_mysql_state_get_tx,
        tx_comp_st_ts: 1,
        tx_comp_st_tc: 1,
        tx_get_progress: rs_mysql_tx_get_alstate_progress,
        get_eventinfo: Some(MysqlEvent::get_event_info),
        get_eventinfo_byid: Some(MysqlEvent::get_event_info_by_id),
        localstorage_new: None,
        localstorage_free: None,
        get_tx_files: None,
        get_tx_iterator: Some(applayer::state_get_tx_iterator::<MysqlState, MysqlTransaction>),
        get_tx_data: rs_mysql_get_tx_data,
        get_state_data: rs_mysql_get_state_data,
        apply_tx_config: None,
        flags: APP_LAYER_PARSER_OPT_ACCEPT_GAPS,
        truncate: None,
        get_frame_id_by_name: None,
        get_frame_name_by_id: None,
    };

    let ip_proto_str = CString::new("tcp").unwrap();

    if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
        let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
        ALPROTO_MYSQL = alproto;
        if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
            let _ = AppLayerRegisterParser(&parser, alproto);
        }
        if let Some(val) = conf_get("app-layer.protocols.mysql.max-tx") {
            if let Ok(v) = val.parse::<usize>() {
                MYSQL_MAX_TX = v;
            } else {
                SCLogError!("Invalid value for mysql.max-tx");
            }
        }
        SCLogNotice!("Rust mysql parser registered.");
    } else {
        SCLogNotice!("Protocol detector and parser disabled for MYSQL.");
    }
}

RustParse中定义了各个处理的函数入口;如state_new,用于新的连接进行调用;对于过程当中请求和响应分别调用parse_ts及parse_ts;具体的处理流程,后续再详细介绍。
针对Mysql协议解析,首先需要知道Mysql各个数据包的结构,可以参照Mysql的官方文档
有了以上内容,做好了基于suricata进行Mysql协议解析的准备。


网站公告

今日签到

点亮在社区的每一天
去签到