Skip to content

Commit 63cd400

Browse files
authored
Merge pull request #103 from vincentmli/vli-dev
Add xdp-synproxy to bpf-examples
2 parents c726367 + d445099 commit 63cd400

File tree

11 files changed

+1441
-0
lines changed

11 files changed

+1441
-0
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ SUBDIRS += tc-policy
2525
SUBDIRS += traffic-pacing-edt
2626
SUBDIRS += AF_XDP-forwarding
2727
SUBDIRS += AF_XDP-example
28+
SUBDIRS += xdp-synproxy
2829

2930
.PHONY: check_submodule help clobber distclean clean $(SUBDIRS)
3031

headers/vmlinux/vmlinux_common.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#ifndef __VMLINUX_COMMON_H__
22
#define __VMLINUX_COMMON_H__
33

4+
enum {
5+
false = 0,
6+
true = 1,
7+
};
8+
9+
typedef _Bool bool;
10+
411
struct list_head {
512
struct list_head *next;
613
struct list_head *prev;

headers/vmlinux/vmlinux_net.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,13 @@ struct sk_buff {
135135
struct skb_ext *extensions;
136136
};
137137

138+
struct nf_conn {
139+
unsigned long status;
140+
};
141+
142+
enum ip_conntrack_status {
143+
/* Connection is confirmed: originating packet has left box */
144+
IPS_CONFIRMED_BIT = 3,
145+
};
146+
138147
#endif /* __VMLINUX_NET_H__ */

xdp-synproxy/Dockerfile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#docker build . -t xdp-synproxy:0.1
2+
#docker run -it -h xdp-synproxy --network=host --privileged xdp-synproxy:0.1
3+
4+
FROM ubuntu:latest
5+
6+
RUN apt-get update && \
7+
apt-get install -y libelf1 \
8+
iptables \
9+
iproute2
10+
11+
COPY bpftool /usr/local/bin
12+
COPY install-rules.sh /
13+
COPY uninstall-rules.sh /
14+
COPY xdp_synproxy /usr/local/bin
15+
16+
#ENTRYPOINT ["/usr/local/bin/xdp_synproxy", "--iface", "ens192", "--file", "/usr/local/bin/xdp_synproxy_kern.o", "--mss4", "1460", "--mss6", "1440", "--wscale", "7", "--ttl", "254", "--ports", "80,8080"]
17+
18+

xdp-synproxy/Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
2+
3+
USER_TARGETS := xdp_synproxy
4+
BPF_TARGETS := xdp_synproxy_kern
5+
BPF_SKEL_OBJ := xdp_synproxy_kern.o
6+
7+
LIB_DIR = ../lib
8+
9+
include $(LIB_DIR)/common.mk

xdp-synproxy/README.org

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#+Title: XDP SYNPROXY sample application
2+
3+
This is a sample application for XDP SYNPROXY. It was cloned from
4+
the Linux source code tree under tools/testing/selftests/bpf and called
5+
xdp_synproxy. main purpose of it is to demonstrate capabilities of
6+
XDP accelerating SYN Proxying for SYN flood DDOS protection. It is
7+
a real practical example for user to use. For an overview of accelerating
8+
SYNPROXY WITH XDP, Please refer to this paper
9+
(https://netdevconf.info/0x15/slides/30/Netdev%200x15%20Accelerating%20synproxy%20with%20XDP.pdf)
10+
11+
This sample application is tested with Ubuntu 22.04 with 6.2 kernel.
12+
13+
Note XDP SYNPROXY requires netfilter connection tracking and here are the
14+
sysctl knobs and iptables rules preparation for XDP SYNPROXY:
15+
#+BEGIN_SRC sh
16+
sudo sysctl -w net.ipv4.tcp_syncookies=2
17+
sudo sysctl -w net.ipv4.tcp_timestamps=1
18+
sudo sysctl -w net.netfilter.nf_conntrack_tcp_loose=0
19+
sudo iptables -t raw -I PREROUTING -i <interface> -p tcp -m tcp --syn --dport <port> -j CT --notrack
20+
sudo iptables -t filter -A INPUT -i <interface> -p tcp -m tcp --dport <port> -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
21+
sudo iptables -t filter -A INPUT -i <interface> -m state --state INVALID -j DROP
22+
#+END_SRC
23+
24+
Here is how to start the XDP SYNPROXY application:
25+
#+BEGIN_SRC sh
26+
sudo xdp_synproxy --iface <interface> --mss4 1460 --mss6 1440 --wscale 7 --ttl 64 --ports <port1>,<port2>
27+
#+END_SRC
28+
29+
XDP SYNPROXY could be built in in container and run by docker
30+
#+BEGIN_SRC sh
31+
sudo docker build . -t xdp-synproxy:0.1
32+
sudo docker run -it -h xdp-synproxy --network=host --privileged xdp-synproxy:0.1
33+
#+END_SRC
34+
35+
XDP SYNPROXY could be deployed in Kubernetes cluster as DaemonSet, Please see
36+
(https://youtu.be/nIrp0Lv-e0g?si=g-pXl4agVQM6_FYW)
37+
#+BEGIN_SRC sh
38+
sudo kubectl apply -f xdp-synproxy-daemonset.yaml
39+
sudo kubectl get po -o wide -l app=xdp-synproxy
40+
41+
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
42+
xdp-synproxy-6x29j 1/1 Running 0 5d2h 10.169.72.239 cilium-dev <none> <none>
43+
xdp-synproxy-xj98j 1/1 Running 0 5d2h 10.169.72.233 centos-dev.localdomain <none> <none>
44+
#+END_SRC
45+
46+
XDP SYNPROXY can coexist with other XDP programs since we use libxdp
47+
to attach the XDP SYNPROXY program, meaning you could build chain of
48+
XDP programs and attach them to same network interface. Note xdp-loader
49+
could be built statically and shipped with xdp-synproxy container.
50+
51+
#+BEGIN_SRC sh
52+
sudo kubectl exec -it xdp-synproxy-6x29j -- xdp-loader status
53+
54+
CURRENT XDP PROGRAM STATUS:
55+
56+
Interface Prio Program name Mode ID Tag Chain actions
57+
--------------------------------------------------------------------------------------
58+
ens192 xdp_dispatcher native 899 90f686eb86991928
59+
=> 50 syncookie_xdp 908 6c6615566a2e0419 XDP_PASS
60+
#+END_SRC
61+

xdp-synproxy/install-rules.sh

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
sysctl -w net.ipv4.tcp_syncookies=2
6+
sysctl -w net.ipv4.tcp_timestamps=1
7+
sysctl -w net.netfilter.nf_conntrack_tcp_loose=0
8+
9+
SYNPROXY="-m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460"
10+
CT="-j CT --notrack"
11+
12+
while test $# -gt 0; do
13+
case "$1" in
14+
--interface*)
15+
# shellcheck disable=SC2001
16+
# the below sed is to support both formats "--flag value" and "--flag=value"
17+
INTERFACE=$(echo "$1" | sed -e 's/^[^=]*=//g')
18+
shift
19+
;;
20+
--ports*)
21+
# shellcheck disable=SC2001
22+
# the below sed is to support both formats "--flag value" and "--flag=value"
23+
PORTS=$(echo "$1" | sed -e 's/^[^=]*=//g')
24+
shift
25+
;;
26+
*)
27+
break
28+
;;
29+
esac
30+
done
31+
32+
33+
34+
COMMA=','
35+
if [[ "$PORTS" == *"$COMMA"* ]]; then
36+
37+
IFS=',' read -ra PORT <<< "$PORTS"
38+
for p in "${PORT[@]}"; do
39+
echo $p
40+
/usr/sbin/iptables -t raw -I PREROUTING -i $INTERFACE -p tcp -m tcp --syn --dport $p $CT
41+
/usr/sbin/iptables -t filter -A INPUT -i $INTERFACE -p tcp -m tcp --dport $p $SYNPROXY
42+
done
43+
else
44+
/usr/sbin/iptables -t raw -I PREROUTING -i $INTERFACE -p tcp -m tcp --syn --dport $PORTS $CT
45+
/usr/sbin/iptables -t filter -A INPUT -i $INTERFACE -p tcp -m tcp --dport $PORTS $SYNPROXY
46+
fi
47+
48+
/usr/sbin/iptables -t filter -A INPUT -i $INTERFACE -m state --state INVALID -j DROP

xdp-synproxy/uninstall-rules.sh

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
SYNPROXY="-m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460"
6+
CT="-j CT --notrack"
7+
8+
while test $# -gt 0; do
9+
case "$1" in
10+
--interface*)
11+
# shellcheck disable=SC2001
12+
# the below sed is to support both formats "--flag value" and "--flag=value"
13+
INTERFACE=$(echo "$1" | sed -e 's/^[^=]*=//g')
14+
shift
15+
;;
16+
--ports*)
17+
# shellcheck disable=SC2001
18+
# the below sed is to support both formats "--flag value" and "--flag=value"
19+
PORTS=$(echo "$1" | sed -e 's/^[^=]*=//g')
20+
shift
21+
;;
22+
*)
23+
break
24+
;;
25+
esac
26+
done
27+
28+
29+
30+
COMMA=','
31+
if [[ "$PORTS" == *"$COMMA"* ]]; then
32+
33+
IFS=',' read -ra PORT <<< "$PORTS"
34+
for p in "${PORT[@]}"; do
35+
echo $p
36+
/usr/sbin/iptables -t raw -D PREROUTING -i $INTERFACE -p tcp -m tcp --syn --dport $p $CT
37+
/usr/sbin/iptables -t filter -D INPUT -i $INTERFACE -p tcp -m tcp --dport $p $SYNPROXY
38+
done
39+
else
40+
/usr/sbin/iptables -t raw -D PREROUTING -i $INTERFACE -p tcp -m tcp --syn --dport $PORTS $CT
41+
/usr/sbin/iptables -t filter -D INPUT -i $INTERFACE -p tcp -m tcp --dport $PORTS $SYNPROXY
42+
fi
43+
44+
/usr/sbin/iptables -t filter -D INPUT -i $INTERFACE -m state --state INVALID -j DROP
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
apiVersion: apps/v1
2+
kind: DaemonSet
3+
metadata:
4+
name: xdp-synproxy
5+
labels:
6+
app: xdp-synproxy
7+
spec:
8+
selector:
9+
matchLabels:
10+
app: xdp-synproxy
11+
template:
12+
metadata:
13+
labels:
14+
app: xdp-synproxy
15+
spec:
16+
hostNetwork: true
17+
containers:
18+
- args:
19+
- "--iface=ens192"
20+
- "--mss4=1460"
21+
- "--mss6=1440"
22+
- "--wscale=7"
23+
- "--ttl=254"
24+
- "--ports=80,8080"
25+
command:
26+
- /usr/local/bin/xdp_synproxy
27+
image: vli39/xdp-synproxy:0.1
28+
imagePullPolicy: Always
29+
lifecycle:
30+
postStart:
31+
exec:
32+
command:
33+
- "/install-rules.sh"
34+
- "--interface=ens192"
35+
- "--ports=80,8080"
36+
preStop:
37+
exec:
38+
command:
39+
- "/uninstall-rules.sh"
40+
- "--interface=ens192"
41+
- "--ports=80,8080"
42+
name: xdp-synproxy
43+
securityContext:
44+
capabilities:
45+
add:
46+
- NET_ADMIN
47+
privileged: true
48+
volumeMounts:
49+
- mountPath: /sys/fs/bpf
50+
name: xdp-synproxy
51+
volumes:
52+
- hostPath:
53+
path: /sys/fs/bpf
54+
type: DirectoryOrCreate
55+
name: xdp-synproxy

0 commit comments

Comments
 (0)