pping: Ignore SYN packets by default

Make ePPing ignore TCP SYN packets by default, so that the
initial handshake phase of the connection is ignored. Add an
option (--include-syn/-s) to explicitly include SYN packets.

The main reason it can be a good idea to avoid SYN-packets is to avoid
being affected by SYN-flood attacks. When ePPing also includes
SYN-packets it becomes quite vulnerable to SYN-flood attacks, which
will quickly fill up its flow_state table, blocking actual useful
flows from being tracked. As ePPing will consider the connection
opened as soon as it sees the SYN-ACK (it will not wait for final
ACK), flow-state created from SYN-flood attacks will also stay around
in the flow-state table for a long time (5 minutes currently) as no
RST/FIN will be sent that can be used to close it.

The drawback from ignoring SYN-packets is that no RTTs will be
collected during the handshake phase, and all connections will be
considered opened due to "first observed packet".

A more refined approach could be to properly track the full TCP
handshake (SYN + SYN-ACK + ACK) instead of the more generic "open once
we see reply in reverse direction" used now. However, this adds a fair
bit of additional protocol-specific logic. Furthermore, to track the
full handshake we will still need to store some flow-state before the
handshake is completed, and thus such a solution would still be
vulnerable to SYN-flood attacks (although the incomplete flow states
could potentially be cleaned up faster).

Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
This commit is contained in:
Simon Sundberg
2022-09-01 16:46:16 +02:00
parent 7a9db7b08c
commit 70f255cbf8
3 changed files with 11 additions and 2 deletions

View File

@@ -102,6 +102,7 @@ static const struct option long_options[] = {
{ "tcp", no_argument, NULL, 'T' }, // Calculate and report RTTs for TCP traffic (with TCP timestamps)
{ "icmp", no_argument, NULL, 'C' }, // Calculate and report RTTs for ICMP echo-reply traffic
{ "include-local", no_argument, NULL, 'l' }, // Also report "internal" RTTs
{ "include-SYN", no_argument, NULL, 's' }, // Include SYN-packets in tracking (may fill up flow state with half-open connections)
{ 0, 0, NULL, 0 }
};
@@ -170,8 +171,9 @@ static int parse_arguments(int argc, char *argv[], struct pping_config *config)
config->force = false;
config->bpf_config.track_tcp = false;
config->bpf_config.track_icmp = false;
config->bpf_config.skip_syn = true;
while ((opt = getopt_long(argc, argv, "hflTCi:r:R:t:c:F:I:",
while ((opt = getopt_long(argc, argv, "hflTCsi:r:R:t:c:F:I:",
long_options, NULL)) != -1) {
switch (opt) {
case 'i':
@@ -266,6 +268,9 @@ static int parse_arguments(int argc, char *argv[], struct pping_config *config)
case 'C':
config->bpf_config.track_icmp = true;
break;
case 's':
config->bpf_config.skip_syn = false;
break;
case 'h':
printf("HELP:\n");
print_usage(argv);

View File

@@ -64,7 +64,8 @@ struct bpf_config {
bool track_tcp;
bool track_icmp;
bool localfilt;
__u32 reserved;
bool skip_syn;
__u8 reserved[3];
};
/*

View File

@@ -339,6 +339,9 @@ static int parse_tcp_identifier(struct parsing_context *pctx,
if (parse_tcphdr(&pctx->nh, pctx->data_end, &hdr) < 0)
return -1;
if (config.skip_syn && hdr->syn)
return -1;
if (parse_tcp_ts(hdr, pctx->data_end, &proto_info->pid,
&proto_info->reply_pid) < 0)
return -1; //Possible TODO, fall back on seq/ack instead