From 5c4b2487534f5fdeae293f025b69477d3690f4fb Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 3 Apr 2024 22:26:34 +0100 Subject: [PATCH 1/4] Ignore duplicate packets if they match the previous stage of a door --- src/knockd.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/knockd.c b/src/knockd.c index eff10bc..50604af 100644 --- a/src/knockd.c +++ b/src/knockd.c @@ -1825,8 +1825,17 @@ void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet) } else { /* invalidate the knock sequence, it will be removed in the * next sniff() call. + * + * ... unless it matches a previous stage, in which case assume it's a dupe and ignore */ - attempt->stage = -1; + + if(attempt->stage > 0 && + ip_proto == attempt->door->protocol[attempt->stage - 1] && + dport == attempt->door->sequence[attempt->stage - 1]) { + dprint("got attempt, ip %s, matching previous stage - assuming duplicate packet\n", attempt->src); + } else { + attempt->stage = -1; + } } } else { /* did they hit the first port correctly? */ From 1adfb884ea0c304eb0f0e7c9ac571951d3ef2e9e Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 3 Apr 2024 22:26:48 +0100 Subject: [PATCH 2/4] Add config to enable ignoring of duplicates --- src/knockd.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/knockd.c b/src/knockd.c index 50604af..526e98f 100644 --- a/src/knockd.c +++ b/src/knockd.c @@ -97,6 +97,7 @@ typedef struct opendoor { FILE *one_time_sequences_fd; char *pcap_filter_exp; char *pcap_filter_expv6; + int allowdupes; } opendoor_t; PMList *doors = NULL; @@ -624,6 +625,7 @@ int parseconfig(char *configfile) door->one_time_sequences_fd = NULL; door->pcap_filter_exp = NULL; door->pcap_filter_expv6 = NULL; + door->allowdupes = 0; doors = list_add(doors, door); } } else { @@ -644,6 +646,14 @@ int parseconfig(char *configfile) if(!strcmp(key, "USESYSLOG")) { o_usesyslog = 1; dprint("config: usesyslog\n"); + } else if(!strcmp(key, "ALLOWDUPES")) { + if(door == NULL) { + fprintf(stderr, "config: line %d: \"%s\" can only be used within a Door section\n", + linenum, key); + return(1); + } + door->allowdupes = 1; + dprint("config: %s: allowdupes: %d\n", door->name, door->allowdupes); } else { fprintf(stderr, "config: line %d: syntax error\n", linenum); return(1); @@ -1829,7 +1839,8 @@ void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet) * ... unless it matches a previous stage, in which case assume it's a dupe and ignore */ - if(attempt->stage > 0 && + if(attempt->door->allowdupes && + attempt->stage > 0 && ip_proto == attempt->door->protocol[attempt->stage - 1] && dport == attempt->door->sequence[attempt->stage - 1]) { dprint("got attempt, ip %s, matching previous stage - assuming duplicate packet\n", attempt->src); From 422c3e724522e25ed3ef88f0577cff8239a0589b Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 3 Apr 2024 22:35:01 +0100 Subject: [PATCH 3/4] Document the AllowDupes option --- doc/knockd.1.in | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/knockd.1.in b/doc/knockd.1.in index b69ca06..c928b39 100644 --- a/doc/knockd.1.in +++ b/doc/knockd.1.in @@ -196,6 +196,13 @@ interfere with (and thus invalidate) the knock. Separate multiple flags with commas (eg, TCPFlags = syn,ack,urg). Flags can be explicitly excluded by a "!" (eg, TCPFlags = syn,!ack). .TP +.B "AllowDupes" +Ignore packets (that is, don't invalidate the entire knock), if the packet is a +duplicate of the sequence stage we've just seen. This may be the case if our +firewall is configured to drop packets (rather than respond with a rst), so we +may receive multiple/duplicate TCP syn packets from the knocker, for a single +stage. +.TP .B "Target = " Use the specified IP address instead of the address determined for the \fBInterface\fP when matching the \fBSequence\fP. From 2cf2243c9d0b66d81c513f7e0a49a64a96e13b6b Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 3 Apr 2024 22:36:28 +0100 Subject: [PATCH 4/4] Version bump: 0.9 --- ChangeLog | 1 + configure.ac | 2 +- src/knock.c | 2 +- src/knockd.c | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1c65ab3..766fadf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ VERSION DESCRIPTION ----------------------------------------------------------------------------- +0.9 - Permit ignoring duplicate packets. 0.8 - Multiple fixes (#67, #77) - IPv6 support (Sebastien Valat) 0.7.8 - Fix for Issue #33, #34 and #35 contributed by Alexander diff --git a/configure.ac b/configure.ac index 1d6acb0..8e00387 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT([knock], [0.8], [https://github.com/jvinet/knock/issues]) +AC_INIT([knock], [0.9], [https://github.com/jvinet/knock/issues]) AM_INIT_AUTOMAKE([dist-xz no-dist-gzip foreign subdir-objects]) AC_CONFIG_HEADER([config.h]) diff --git a/src/knock.c b/src/knock.c index 851f80a..a48f4b5 100644 --- a/src/knock.c +++ b/src/knock.c @@ -35,7 +35,7 @@ #include #include -static char version[] = "0.8"; +static char version[] = "0.9"; #define PROTO_TCP 1 #define PROTO_UDP 2 diff --git a/src/knockd.c b/src/knockd.c index 526e98f..6ac1a56 100644 --- a/src/knockd.c +++ b/src/knockd.c @@ -63,7 +63,7 @@ extern int daemon(int, int); #endif -static char version[] = "0.8"; +static char version[] = "0.9"; #define SEQ_TIMEOUT 25 /* default knock timeout in seconds */ #define CMD_TIMEOUT 10 /* default timeout in seconds between start and stop commands */