,haproxy"/>

首页 > 解决方案 > HAProxy Lua 无法添加操作

问题描述

我有用于 haproxy 的 lua 脚本,它检查白名单中的 ip,我需要将其添加到 haproxy 配置中。我需要在 tcp 连接上执行此操作,正如haproxy 博客文章所述 - 我可以执行此操作。

tcp-request connection <action>
tcp-request content <action>
tcp-response content <action>
http-request <action>
http-response <action>

但是如果我使用tcp-request connection lua.checkip - haproxy 不能以错误消息开始:

haproxy[9384]: [ALERT] 124/000121 (9384) : parsing [/etc/haproxy/haproxy.cfg:42] : 'tcp-request connection' expects 'accept', 'reject', 'track-sc0' ... 'track-sc2', 'sc-inc-gpc0(*)', 'sc-inc-gpc1(*)', 'sc-set-gpt0(*)', 'set-src', 'set-src-port', 'set-dst', 'set-dst-port', 'silent-drop' in frontend 'haproxy_rserve' (got 'lua.checkip').

但我可以使用tcp-request content lua.checkip 并且这个工作。

据我了解,这两个功能必须有区别,对我来说最好的解决方案是connetion或者我可以使用content吗?我正在尝试构建一个高负载的系统,所以我不想在配置阶段搞砸。

我尝试将此行添加到前端:

tcp-request inspect-delay 5s
tcp-request connection lua.checkip
tcp-request connection reject if { var(req.blocked) -m bool }

标签: haproxy

解决方案


源码发现注册一个 Luatcp-req动作确实只是为了内容,没有办法为一个连接注册一个 Lua 动作:

        if (strcmp(lua_tostring(L, -1), "tcp-req") == 0)
            tcp_req_cont_keywords_register(akl);
        else if (strcmp(lua_tostring(L, -1), "tcp-res") == 0)
            tcp_res_cont_keywords_register(akl);
        else if (strcmp(lua_tostring(L, -1), "http-req") == 0)
            http_req_keywords_register(akl);
        else if (strcmp(lua_tostring(L, -1), "http-res") == 0)
            http_res_keywords_register(akl);
        else
            WILL_LJMP(luaL_error(L, "Lua action environment '%s' is unknown. "
                                    "'tcp-req', 'tcp-res', 'http-req' or 'http-res' "
                                    "are expected.", lua_tostring(L, -1)));

它需要调用的函数是tcp_req_conn_keywords_register,但不幸的是它没有暴露给 Lua。该函数的唯一调用者是proto_tcp.cstick_table.c中的一些硬编码操作:

static struct action_kw_list tcp_req_conn_actions = {ILH, {
        { "set-src",      tcp_parse_set_src_dst },
        { "set-src-port", tcp_parse_set_src_dst },
        { "set-dst"     , tcp_parse_set_src_dst },
        { "set-dst-port", tcp_parse_set_src_dst },
        { "silent-drop",  tcp_parse_silent_drop },
        { /* END */ }
}};

INITCALL1(STG_REGISTER, tcp_req_conn_keywords_register, &tcp_req_conn_actions);
static struct action_kw_list tcp_conn_kws = { { }, {
        { "sc-inc-gpc0", parse_inc_gpc0, 1 },
        { "sc-inc-gpc1", parse_inc_gpc1, 1 },
        { "sc-set-gpt0", parse_set_gpt0, 1 },
        { /* END */ }
}};

INITCALL1(STG_REGISTER, tcp_req_conn_keywords_register, &tcp_conn_kws);

然而,我再次有两个好消息:

  • 如果你可以把你的白名单放在一个文件中,你就可以使用tcp-request connection reject unless { src -f /etc/haproxy/whitelist.lst }而不需要使用 Lua。
  • 没有什么是 Lua 无法支持它的关键原因,所以它可能会被添加到未来的版本中。

推荐阅读