-
Notifications
You must be signed in to change notification settings - Fork 4
/
iptables_synproxy.sh
147 lines (129 loc) · 3.73 KB
/
iptables_synproxy.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/bin/bash
#
# iptables SYNPROXY target usage example
# (support added in iptables v1.4.21)
#
# WARNING: This script is for localhost INPUT
# REMEMBER to change INPUT to FORWARD
# if you are using this on a firewall
#
# Author: Jesper Dangaard Brouer <[email protected]>
#export IPTABLES_CMD=
default_ipt_cmd="/usr/local/sbin/iptables"
if [ "$EUID" -ne 0 ]; then
# Can be run as normal user, will just use "sudo"
export su=sudo
fi
function usage() {
echo ""
echo " $0 - SYNPROXY setup script"
echo ""
echo "Usage:"
echo "------"
echo " Script : $0"
echo " Parameters: [-vf] -i interface -p dest-port"
echo ""
echo " -v : verbose"
echo " -i : Interface/device"
echo " -p : Destination TCP port"
echo " -f : Flush rules before creating new rules"
echo ""
}
## --- Parse command line arguments ---
while getopts ":i:p:vf" option; do
case $option in
i)
DEV=$OPTARG
;;
p)
PORT=$OPTARG
;;
v)
VERBOSE=yes
;;
f)
FLUSH=yes
;;
?|*)
echo ""
echo "[ERROR] Unknown parameter \"$OPTARG\""
usage
exit 2
esac
done
shift $[ OPTIND - 1 ]
if [ -z "$DEV" ]; then
usage
echo "ERROR: no device specified"
exit 1
fi
if [ -z "$PORT" ]; then
usage
echo "ERROR: no port specified"
exit 1
fi
# Extra checking for iptables
if [ -z "$IPTABLES_CMD" ]; then
echo "WARNING: Shell env variable IPTABLES_CMD is undefined"
export IPTABLES_CMD=${default_ipt_cmd}
echo "WARNING: Fallback to default IPTABLES_CMD=${default_ipt_cmd}"
fi
#
# A shell iptables function wrapper
#
iptables() {
$su $IPTABLES_CMD "$@"
local result=$?
if [ ${result} -gt 0 ]; then
echo "WARNING -- Error (${result}) when executing the iptables command:"
echo " \"iptables $@\""
else
if [ -n "${VERBOSE}" ]; then
echo "iptables $@"
fi
fi
}
# Cleanup before applying our rules
if [ -n "$FLUSH" ]; then
iptables -t raw -F
iptables -t raw -X
iptables -F
iptables -X
fi
# SYNPROXY works on untracked conntracks
# it will create the appropiate conntrack proxied TCP conn
# NOTICE: table "raw"
iptables -t raw -I PREROUTING -i $DEV -p tcp -m tcp --syn \
--dport $PORT -j CT --notrack
# Catching state
# UNTRACKED == SYN packets
# INVALID == ACK from 3WHS
iptables -A INPUT -i $DEV -p tcp -m tcp --dport $PORT \
-m state --state INVALID,UNTRACKED \
-j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
# Drop rest of state INVALID
# This will e.g. catch SYN-ACK packet attacks
iptables -A INPUT -i $DEV -p tcp -m tcp --dport $PORT \
-m state --state INVALID -j DROP
# More strict conntrack handling to get unknown ACKs (from 3WHS) to be
# marked as INVALID state (else a conntrack is just created)
#
$su /sbin/sysctl -w net/netfilter/nf_conntrack_tcp_loose=0
# Enable timestamping, because SYN cookies uses TCP options field
$su /sbin/sysctl -w net/ipv4/tcp_timestamps=1
# Adjusting maximum number of connection tracking entries possible
#
# Conntrack element size 288 bytes found in /proc/slabinfo
# "nf_conntrack" <objsize> = 288
#
# 288 * 2000000 / 10^6 = 576.0 MB
$su /sbin/sysctl -w net/netfilter/nf_conntrack_max=2000000
# IMPORTANT: Also adjust hash bucket size for conntracks
# net/netfilter/nf_conntrack_buckets writeable
# via /sys/module/nf_conntrack/parameters/hashsize
#
# Hash entry 8 bytes pointer (uses struct hlist_nulls_head)
# 8 * 2000000 / 10^6 = 16 MB
$su sh -c 'echo 2000000 > /sys/module/nf_conntrack/parameters/hashsize'
# Hint: Monitor nf_conntrack usage searched, found, new, etc.:
# lnstat -c -1 -f nf_conntrack