From f9d824077ec7a7c13b02a771630ee10ea845776c Mon Sep 17 00:00:00 2001 From: Derry Date: Wed, 19 Dec 2018 15:46:55 +0800 Subject: [PATCH] =?UTF-8?q?[kernel]=E5=A2=9E=E5=8A=A0https=20url=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE=E6=8F=90=E5=8F=96=E5=92=8C=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/af_utils.c | 17 +++++++++- kernel/af_utils.h | 4 ++- kernel/app_filter.c | 82 ++++++++++++++++++++++++++++++++++++++++++++- kernel/app_filter.h | 8 +++-- 4 files changed, 106 insertions(+), 5 deletions(-) diff --git a/kernel/af_utils.c b/kernel/af_utils.c index 2dc8de8..bfb3aab 100755 --- a/kernel/af_utils.c +++ b/kernel/af_utils.c @@ -16,7 +16,7 @@ int check_local_network_ip(unsigned int ip) return 0; } -void dump_str(char *name, char *p, int len) +void dump_str(char *name, unsigned char *p, int len) { #define MAX_DUMP_STR_LEN 64 int i; @@ -30,4 +30,19 @@ void dump_str(char *name, char *p, int len) printk("\n"); } +void dump_hex(char *name, unsigned char *p, int len) +{ + #define MAX_DUMP_STR_LEN 64 + int i; + if (len > MAX_DUMP_STR_LEN) { + len = MAX_DUMP_STR_LEN - 1; + } + printk("%s: ",name); + for (i = 0; i < len; i++) { + if (i % 16 == 0) + printk("\n"); + printk("%02X ",*(p + i)); + } + printk("\n"); +} diff --git a/kernel/af_utils.h b/kernel/af_utils.h index 3d6c7f1..0ab37df 100755 --- a/kernel/af_utils.h +++ b/kernel/af_utils.h @@ -3,7 +3,9 @@ int check_local_network_ip(unsigned int ip); -void dump_str(char *name, char *p, int len); +void dump_str(char *name, unsigned char *p, int len); + +void dump_hex(char *name, unsigned char *p, int len); #endif diff --git a/kernel/app_filter.c b/kernel/app_filter.c index 2de407b..bf3a9d4 100755 --- a/kernel/app_filter.c +++ b/kernel/app_filter.c @@ -65,6 +65,56 @@ int parse_flow_base(struct sk_buff *skb, flow_info_t *flow) } +/* + desc: 解析https url信息,保存到flow中 + return: + -1: error + 0: match + author: Derry + Date:2018/12/19 +*/ +int parse_https_proto(flow_info_t *flow) { + int i ; + short url_len = 0 ; + char * p = flow->l4_data; + int data_len = flow->l4_len; + + if (NULL == flow) { + AF_ERROR("flow is NULL\n"); + return -1; + } + if (NULL == p || data_len == 0) { + return -1; + } + if (!(p[0] == 0x16 && p[1] == 0x03 && p[2] == 0x01)) + return -1; + + for(i = 0; i < data_len; i++) { + if(i + HTTPS_URL_OFFSET >= data_len) { + return -1; + } + + if(p[i] == 0x0 && p[i + 1] == 0x0 && p[i + 2] == 0x0 && p[i + 3] != 0x0) { + // 2 bytes + memcpy(&url_len , p + i + HTTPS_LEN_OFFSET, 2); + if(ntohs(url_len) <= 0 || ntohs(url_len) > data_len) { + continue ; + } + + if(i + HTTPS_URL_OFFSET + ntohs(url_len) < data_len) { + //dump_hex("https hex", p, data_len); + flow->https.match = AF_TRUE; + flow->https.url_pos = p + i + HTTPS_URL_OFFSET; + //dump_str("https url", flow->https.url_pos, 5); + flow->https.url_len = ntohs(url_len); + return 0; + } + } + } + return -1; +} + + void parse_http_proto(flow_info_t *flow) { if (!flow) { @@ -140,6 +190,22 @@ static void dump_http_flow_info(http_proto_t *http) { printk("--------------------------------------------------------\n\n\n"); } +static void dump_https_flow_info(https_proto_t *https) { + if (!https) { + AF_ERROR("https ptr is NULL\n"); + return ; + } + if (!https->match) + return; + + + if (https->url_len > 0 && https->url_pos){ + printk("url len = %d\n",https->url_len); + dump_str("https server name", https->url_pos, https->url_len); + } + + printk("--------------------------------------------------------\n\n\n"); +} static void dump_flow_info(flow_info_t *flow) { @@ -162,6 +228,9 @@ static void dump_flow_info(flow_info_t *flow) flow->sport, flow->dport, flow->l4_len); dump_http_flow_info(&flow->http); } + if (AF_TRUE == flow->https.match) { + dump_https_flow_info(&flow->https); + } } else if (flow->l4_protocol == IPPROTO_UDP) { // printk("protocol:UDP ,sport: %-8d, dport: %-8d, data_len: %-8d\n", @@ -182,12 +251,14 @@ static u_int32_t app_filter_hook(unsigned int hook, struct nf_conn *ct = (struct nf_conn *)pskb->nfct; if (ct == NULL) { + AF_ERROR("ct is null\n"); return NF_ACCEPT; } flow_info_t flow; memset((char *)&flow, 0x0, sizeof(flow_info_t)); parse_flow_base(pskb, &flow); parse_http_proto(&flow); + parse_https_proto(&flow); dump_flow_info(&flow); // todo: match url rules // this is example @@ -195,7 +266,15 @@ static u_int32_t app_filter_hook(unsigned int hook, if (flow.http.host_pos && strnstr(flow.http.host_pos, "sohu", flow.http.host_len)){ - dump_str("Drop url ",flow.http.host_pos, flow.http.host_len); + dump_str("Drop http url ",flow.http.host_pos, flow.http.host_len); + return NF_DROP; + } + } + if (flow.https.match == AF_TRUE) { + if (flow.https.url_pos && + strnstr(flow.https.url_pos, "hao123", flow.https.url_len)){ + + dump_str("Drop https url ",flow.https.url_pos, flow.https.url_len); return NF_DROP; } } @@ -227,6 +306,7 @@ static void app_filter_fini(void) */ static int __init app_filter_init(void) { + AF_INFO("appfilter version:"AF_VERSION"\n"); AF_DEBUG("app filter module init\n"); nf_register_hooks(app_filter_ops, ARRAY_SIZE(app_filter_ops)); printk("init app filter ........ok\n"); diff --git a/kernel/app_filter.h b/kernel/app_filter.h index 4f07f9a..7680349 100755 --- a/kernel/app_filter.h +++ b/kernel/app_filter.h @@ -3,7 +3,7 @@ #define AF_DEBUG printk #define AF_ERROR printk #define AF_INFO printk - +#define AF_VERSION "1.0.1" //#define CONFIG_KERNEL_FUNC_TEST 1 #define HTTP_GET_METHOD_STR "GET" @@ -18,6 +18,10 @@ #define AF_TRUE 1 #define AF_FALSE 0 + +#define HTTPS_URL_OFFSET 9 +#define HTTPS_LEN_OFFSET 7 + enum e_http_method{ HTTP_METHOD_GET = 1, HTTP_METHOD_POST, @@ -35,7 +39,7 @@ typedef struct http_proto{ typedef struct https_proto{ int match; - char url_pos; + char *url_pos; int url_len; }https_proto_t;