TSG-14789 TFE扫描service chaining策略,执行Decrypted Traffic Steering
This commit is contained in:
@@ -37,6 +37,7 @@ option(ENABLE_PLUGIN_PANGU_HTTP "Enable Pangu-HTTP business" TRUE)
|
||||
option(ENABLE_PLUGIN_HTTP2 "Enable HTTP2 business" TRUE)
|
||||
option(ENABLE_PLUGIN_SSL_POLICY "Enable SSL policy support" TRUE)
|
||||
option(ENABLE_PLUGIN_TCP_POLICY "Enable TCP policy support" TRUE)
|
||||
option(ENABLE_PLUGIN_CHAINING_POLICY "Enable Chaining policy support" TRUE)
|
||||
|
||||
if(ENABLE_PIC)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE 1)
|
||||
|
||||
@@ -72,6 +72,7 @@ enum tfe_cmsg_tlv_type
|
||||
TFE_CMSG_UPSTREAM_TCP_USER_TIMEOUT,
|
||||
|
||||
TFE_CMSG_TCP_PASSTHROUGH,
|
||||
TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING,
|
||||
|
||||
/* Share tsg scan result */
|
||||
TFE_CMSG_SRC_SUB_ID, // string max size 256
|
||||
|
||||
@@ -52,6 +52,10 @@ if(ENABLE_PLUGIN_TCP_POLICY)
|
||||
target_link_libraries(tfe -Wl,--whole-archive tcp-policy -Wl,--no-whole-archive)
|
||||
endif()
|
||||
|
||||
if(ENABLE_PLUGIN_CHAINING_POLICY)
|
||||
target_link_libraries(tfe -Wl,--whole-archive chaining-policy -Wl,--no-whole-archive)
|
||||
endif()
|
||||
|
||||
if(ENABLE_PLUGIN_TRAFFIC_MIRROR)
|
||||
target_link_libraries(tfe -Wl,--whole-archive traffic-mirror -Wl,--no-whole-archive)
|
||||
endif()
|
||||
|
||||
@@ -132,6 +132,7 @@ struct tfe_proxy
|
||||
struct ssl_mgr * ssl_mgr_handler;
|
||||
struct tcp_policy_enforcer *tcp_ply_enforcer;
|
||||
struct ssl_policy_enforcer *ssl_ply_enforcer;
|
||||
struct chaining_policy_enforcer *chain_ply_enforcer;
|
||||
struct key_keeper * key_keeper_handler;
|
||||
|
||||
unsigned int en_kni_v1_acceptor;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define TCP_RESTORE_TCPOPT_KIND 88
|
||||
|
||||
extern void tcp_policy_enforce(struct tcp_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id);
|
||||
extern void chaining_policy_enforce(struct chaining_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id);
|
||||
|
||||
struct acceptor_kni_v3
|
||||
{
|
||||
@@ -601,8 +602,10 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
|
||||
struct pkt_info pktinfo;
|
||||
struct tcp_restore_info restore_info;
|
||||
uint8_t stream_protocol_in_char = 0;
|
||||
uint8_t enalbe_decrypted_traffic_steering = 0;
|
||||
uint16_t size = 0;
|
||||
uint64_t rule_id = 0;
|
||||
uint64_t chaining_rule_id = 0; // only use for acceptv4
|
||||
struct acceptor_kni_v3 *__ctx = (struct acceptor_kni_v3 *)data;
|
||||
clock_gettime(CLOCK_MONOTONIC, &(__ctx->start));
|
||||
memset(&pktinfo, 0, sizeof(pktinfo));
|
||||
@@ -720,6 +723,7 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
|
||||
goto end;
|
||||
}
|
||||
tcp_policy_enforce(__ctx->proxy->tcp_ply_enforcer, cmsg, rule_id);
|
||||
chaining_policy_enforce(__ctx->proxy->chain_ply_enforcer, cmsg, chaining_rule_id);
|
||||
|
||||
if (overwrite_tcp_mss(cmsg, &restore_info))
|
||||
{
|
||||
@@ -745,9 +749,12 @@ static int payload_handler_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, s
|
||||
}
|
||||
|
||||
tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (unsigned char *)&stream_protocol_in_char, sizeof(stream_protocol_in_char), &size);
|
||||
tfe_cmsg_get_value(cmsg, TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING, (unsigned char *)&enalbe_decrypted_traffic_steering, sizeof(enalbe_decrypted_traffic_steering), &size);
|
||||
|
||||
if (steering_device_is_available() && (
|
||||
(STREAM_PROTO_PLAIN == (enum tfe_stream_proto)stream_protocol_in_char && __ctx->proxy->traffic_steering_options.enable_steering_http) ||
|
||||
(STREAM_PROTO_SSL == (enum tfe_stream_proto)stream_protocol_in_char && __ctx->proxy->traffic_steering_options.enable_steering_ssl)))
|
||||
(STREAM_PROTO_SSL == (enum tfe_stream_proto)stream_protocol_in_char && __ctx->proxy->traffic_steering_options.enable_steering_ssl) ||
|
||||
enalbe_decrypted_traffic_steering == 1))
|
||||
{
|
||||
if (fake_tcp_handshake(__ctx->proxy, &restore_info) == -1)
|
||||
{
|
||||
|
||||
@@ -58,10 +58,11 @@
|
||||
/* Systemd */
|
||||
#include <systemd/sd-daemon.h>
|
||||
|
||||
extern struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger);
|
||||
extern struct chaining_policy_enforcer *chaining_policy_enforcer_create(void *logger);
|
||||
extern struct ssl_policy_enforcer *ssl_policy_enforcer_create(void *logger);
|
||||
extern enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void *u_para);
|
||||
|
||||
extern struct tcp_policy_enforcer *tcp_policy_enforcer_create(void *logger);
|
||||
static int signals[] = {SIGHUP, SIGPIPE, SIGUSR1, SIGUSR2};
|
||||
|
||||
/* Global Resource */
|
||||
@@ -703,6 +704,9 @@ int main(int argc, char * argv[])
|
||||
g_default_proxy->ssl_ply_enforcer = ssl_policy_enforcer_create(g_default_logger);
|
||||
CHECK_OR_EXIT(g_default_proxy->ssl_ply_enforcer == NULL, "Failed at creating ssl policy enforcer. Exit.");
|
||||
|
||||
g_default_proxy->chain_ply_enforcer = chaining_policy_enforcer_create(g_default_logger);
|
||||
CHECK_OR_EXIT(g_default_proxy->chain_ply_enforcer == NULL, "Failed at creating chaining policy enforcer. Exit.");
|
||||
|
||||
ssl_manager_set_new_upstream_cb(g_default_proxy->ssl_mgr_handler, ssl_policy_enforce, g_default_proxy->ssl_ply_enforcer);
|
||||
ret = tfe_proxy_work_thread_run(g_default_proxy);
|
||||
CHECK_OR_EXIT(ret == 0, "Failed at creating thread. Exit.");
|
||||
|
||||
@@ -3,3 +3,4 @@ add_subdirectory(doh)
|
||||
add_subdirectory(tsg-http)
|
||||
add_subdirectory(ssl-policy)
|
||||
add_subdirectory(tcp-policy)
|
||||
add_subdirectory(chaining-policy)
|
||||
4
plugin/business/chaining-policy/CMakeLists.txt
Normal file
4
plugin/business/chaining-policy/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
add_library(chaining-policy src/chaining_policy.cpp)
|
||||
target_link_libraries(chaining-policy PUBLIC common)
|
||||
target_link_libraries(chaining-policy PUBLIC cjson)
|
||||
target_link_libraries(chaining-policy PUBLIC maatframe)
|
||||
204
plugin/business/chaining-policy/src/chaining_policy.cpp
Normal file
204
plugin/business/chaining-policy/src/chaining_policy.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
#include <assert.h>
|
||||
#include <tfe_cmsg.h>
|
||||
#include <tfe_utils.h>
|
||||
#include <tfe_stream.h>
|
||||
#include <tfe_resource.h>
|
||||
#include <cjson/cJSON.h>
|
||||
#include <MESA/maat.h>
|
||||
|
||||
#include "chaining_policy.h"
|
||||
|
||||
enum traffic_type
|
||||
{
|
||||
TRAFFIC_TYPE_NONE = 0,
|
||||
TRAFFIC_TYPE_RAW = 1,
|
||||
TRAFFIC_TYPE_DECRYPTED = 2,
|
||||
};
|
||||
|
||||
struct chaining_param
|
||||
{
|
||||
uint64_t rule_id;
|
||||
int ref_cnt;
|
||||
enum traffic_type type;
|
||||
};
|
||||
|
||||
struct chaining_policy_enforcer
|
||||
{
|
||||
struct maat *maat;
|
||||
int table_id;
|
||||
void *logger;
|
||||
};
|
||||
|
||||
static void chaining_param_new_cb(const char *table_name, int table_id, const char *key, const char *table_line, void **ad, long argl, void *argp)
|
||||
{
|
||||
cJSON *json = NULL;
|
||||
cJSON *item = NULL;
|
||||
cJSON *element = NULL;
|
||||
size_t user_region_offset = 0;
|
||||
size_t user_region_len = 0;
|
||||
struct chaining_param *param = NULL;
|
||||
struct chaining_policy_enforcer *enforcer = (struct chaining_policy_enforcer *)argp;
|
||||
|
||||
if (maat_helper_read_column(table_line, 7, &user_region_offset, &user_region_len) < 0)
|
||||
{
|
||||
TFE_LOG_ERROR(enforcer->logger, "unexpected chaining rule: (invalid user region) %s", table_line);
|
||||
return;
|
||||
}
|
||||
|
||||
char *json_str = (char *)calloc(user_region_len + 1, sizeof(char));
|
||||
memcpy(json_str, table_line + user_region_offset, user_region_len);
|
||||
json = cJSON_Parse(json_str);
|
||||
if (json == NULL)
|
||||
{
|
||||
TFE_LOG_ERROR(enforcer->logger, "unexpected chaining rule: (invalid json format) %s", table_line);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
param = (struct chaining_param *)calloc(1, sizeof(struct chaining_param));
|
||||
param->rule_id = atoll(key);
|
||||
param->ref_cnt = 1;
|
||||
|
||||
item = cJSON_GetObjectItem(json, "targeted_traffic");
|
||||
if (!item || !cJSON_IsString(item))
|
||||
{
|
||||
TFE_LOG_ERROR(enforcer->logger, "unexpected chaining rule: (invalid targeted_traffic param) %s", table_line);
|
||||
goto error_out;
|
||||
}
|
||||
if (strcasecmp(item->valuestring, "raw") == 0)
|
||||
{
|
||||
param->type = TRAFFIC_TYPE_RAW;
|
||||
}
|
||||
else if (strcasecmp(item->valuestring, "decrypted") == 0)
|
||||
{
|
||||
param->type = TRAFFIC_TYPE_DECRYPTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
TFE_LOG_ERROR(enforcer->logger, "unexpected chaining rule: (invalid targeted_traffic param) %s", table_line);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
*ad = param;
|
||||
TFE_LOG_INFO(enforcer->logger, "Add chaining rule: %lu", param->rule_id);
|
||||
|
||||
cJSON_Delete(json);
|
||||
free(json_str);
|
||||
return;
|
||||
|
||||
error_out:
|
||||
if (json)
|
||||
{
|
||||
cJSON_Delete(json);
|
||||
json = NULL;
|
||||
}
|
||||
|
||||
if (json_str)
|
||||
{
|
||||
free(json_str);
|
||||
json_str = NULL;
|
||||
}
|
||||
|
||||
if (param)
|
||||
{
|
||||
free(param);
|
||||
param = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void chaining_param_free_cb(int table_id, void **ad, long argl, void *argp)
|
||||
{
|
||||
struct chaining_policy_enforcer *enforcer = (struct chaining_policy_enforcer *)argp;
|
||||
struct chaining_param *param = (struct chaining_param *)*ad;
|
||||
if (param == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((__sync_sub_and_fetch(¶m->ref_cnt, 1) == 0))
|
||||
{
|
||||
TFE_LOG_INFO(enforcer->logger, "Del chaining policy %lu", param->rule_id);
|
||||
free(param);
|
||||
*ad = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void chaining_param_free(struct chaining_param *param)
|
||||
{
|
||||
chaining_param_free_cb(0, (void **)¶m, 0, NULL);
|
||||
}
|
||||
|
||||
static void chaining_param_dup_cb(int table_id, void **to, void **from, long argl, void *argp)
|
||||
{
|
||||
struct chaining_param *param = (struct chaining_param *)*from;
|
||||
if (param)
|
||||
{
|
||||
__sync_add_and_fetch(&(param->ref_cnt), 1);
|
||||
*to = param;
|
||||
}
|
||||
else
|
||||
{
|
||||
*to = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct chaining_policy_enforcer *chaining_policy_enforcer_create(void *logger)
|
||||
{
|
||||
int ret = 0;
|
||||
struct chaining_policy_enforcer *enforcer = ALLOC(struct chaining_policy_enforcer, 1);
|
||||
enforcer->maat = (struct maat *)tfe_bussiness_resouce_get(STATIC_MAAT);
|
||||
enforcer->logger = logger;
|
||||
enforcer->table_id = maat_get_table_id(enforcer->maat, "SERVICE_CHAINING_COMPILE");
|
||||
if (enforcer->table_id < 0)
|
||||
{
|
||||
TFE_LOG_ERROR(enforcer->logger, "failed at register table of SERVICE_CHAINING_COMPILE, ret = %d", enforcer->table_id);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
ret = maat_plugin_table_ex_schema_register(enforcer->maat, "SERVICE_CHAINING_COMPILE",
|
||||
chaining_param_new_cb,
|
||||
chaining_param_free_cb,
|
||||
chaining_param_dup_cb,
|
||||
0, enforcer);
|
||||
if (ret < 0)
|
||||
{
|
||||
TFE_LOG_ERROR(enforcer->logger, "failed at register callback of SERVICE_CHAINING_COMPILE, ret = %d", ret);
|
||||
goto error_out;
|
||||
}
|
||||
return enforcer;
|
||||
|
||||
error_out:
|
||||
chaining_policy_enforcer_destory(enforcer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void chaining_policy_enforcer_destory(struct chaining_policy_enforcer *enforcer)
|
||||
{
|
||||
if (enforcer)
|
||||
{
|
||||
free(enforcer);
|
||||
enforcer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void chaining_policy_enforce(struct chaining_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id)
|
||||
{
|
||||
char rule_id_str[16] = {0};
|
||||
uint8_t enalbe_decrypted_traffic_steering = 0;
|
||||
|
||||
snprintf(rule_id_str, sizeof(rule_id_str), "%lu", rule_id);
|
||||
struct chaining_param *param = (struct chaining_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->table_id, rule_id_str);
|
||||
if (param == NULL)
|
||||
{
|
||||
TFE_LOG_INFO(enforcer->logger, "Failed to get chaining parameter of policy %lu.", rule_id);
|
||||
tfe_cmsg_set(cmsg, TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING, (unsigned char *)&enalbe_decrypted_traffic_steering, sizeof(enalbe_decrypted_traffic_steering));
|
||||
return;
|
||||
}
|
||||
|
||||
if (param->type == TRAFFIC_TYPE_DECRYPTED)
|
||||
{
|
||||
enalbe_decrypted_traffic_steering = 1;
|
||||
}
|
||||
|
||||
tfe_cmsg_set(cmsg, TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING, (unsigned char *)&enalbe_decrypted_traffic_steering, sizeof(enalbe_decrypted_traffic_steering));
|
||||
chaining_param_free(param);
|
||||
}
|
||||
8
plugin/business/chaining-policy/src/chaining_policy.h
Normal file
8
plugin/business/chaining-policy/src/chaining_policy.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include <tfe_cmsg.h>
|
||||
#include <MESA/maat.h>
|
||||
|
||||
struct chaining_policy_enforcer;
|
||||
struct chaining_policy_enforcer *chaining_policy_enforcer_create(void *logger);
|
||||
void chaining_policy_enforcer_destory(struct chaining_policy_enforcer *enforcer);
|
||||
void chaining_policy_enforce(struct chaining_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id);
|
||||
@@ -454,5 +454,15 @@
|
||||
"key":1,
|
||||
"key_type":"pointer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"table_id":44,
|
||||
"table_name":"SERVICE_CHAINING_COMPILE",
|
||||
"table_type":"plugin",
|
||||
"valid_column":8,
|
||||
"custom":{
|
||||
"key":1,
|
||||
"key_type":"pointer"
|
||||
}
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user