HAProxy Lua 无法在 <tcp-request connect> 上添加操作

HAProxy Lua can't add action on <tcp-request connect>

我有 lua haproxy 脚本,它检查白名单中的 ip,我需要将它添加到 haproxy 配置中。 我需要在 tcp 连接上执行此操作,正如 haproxy blog post 所说 - 我可以执行此操作。

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 }

一看the source发现注册Luatcp-reqaction确实只是为了内容,没办法注册Luaaction为了连接:

        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, but unfortunately that's not exposed to Lua. The only callers of that function are for some hardcoded actions in proto_tcp.c and stick_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 不支持它的关键原因,所以它可能会被添加到未来的版本中。