]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-pom-ng-TARPIT.patch
- revert
[packages/kernel.git] / kernel-pom-ng-TARPIT.patch
CommitLineData
9f54053a
JR
1diff -Nru linux-2.6.22/net/ipv4/netfilter/ipt_TARPIT.c linux-2.6.22-pom2patch/net/ipv4/netfilter/ipt_TARPIT.c
2--- linux-2.6.22/net/ipv4/netfilter/ipt_TARPIT.c 1970-01-01 01:00:00.000000000 +0100
3+++ linux-2.6.22-pom2patch/net/ipv4/netfilter/ipt_TARPIT.c 2007-08-07 18:38:14.000000000 +0200
4@@ -0,0 +1,291 @@
1aedc22c 5+/*
6+ * Kernel module to capture and hold incoming TCP connections using
7+ * no local per-connection resources.
8+ *
9+ * Based on ipt_REJECT.c and offering functionality similar to
10+ * LaBrea <http://www.hackbusters.net/LaBrea/>.
11+ *
12+ * Copyright (c) 2002 Aaron Hopkins <tools@die.net>
13+ *
14+ * This program is free software; you can redistribute it and/or modify
15+ * it under the terms of the GNU General Public License as published by
16+ * the Free Software Foundation; either version 2 of the License, or
17+ * (at your option) any later version.
18+ *
19+ * This program is distributed in the hope that it will be useful,
20+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+ * GNU General Public License for more details.
23+ *
24+ * You should have received a copy of the GNU General Public License
25+ * along with this program; if not, write to the Free Software
26+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27+ *
28+ * Goal:
29+ * - Allow incoming TCP connections to be established.
30+ * - Passing data should result in the connection being switched to the
31+ * persist state (0 byte window), in which the remote side stops sending
32+ * data and asks to continue every 60 seconds.
33+ * - Attempts to shut down the connection should be ignored completely, so
34+ * the remote side ends up having to time it out.
35+ *
36+ * This means:
37+ * - Reply to TCP SYN,!ACK,!RST,!FIN with SYN-ACK, window 5 bytes
38+ * - Reply to TCP SYN,ACK,!RST,!FIN with RST to prevent spoofing
39+ * - Reply to TCP !SYN,!RST,!FIN with ACK, window 0 bytes, rate-limited
40+ */
41+
1aedc22c 42+#include <linux/version.h>
43+#include <linux/module.h>
44+#include <linux/skbuff.h>
45+#include <linux/ip.h>
46+#include <net/ip.h>
47+#include <net/tcp.h>
48+#include <net/icmp.h>
49+struct in_device;
50+#include <net/route.h>
51+#include <linux/random.h>
52+#include <linux/netfilter_ipv4/ip_tables.h>
53+
54+#if 0
55+#define DEBUGP printk
56+#else
57+#define DEBUGP(format, args...)
58+#endif
59+
60+MODULE_LICENSE("GPL");
61+MODULE_AUTHOR("Aaron Hopkins <tools@die.net>");
62+
63+/* Stolen from ip_finish_output2 */
64+static int ip_direct_send(struct sk_buff *skb)
65+{
66+ struct dst_entry *dst = skb->dst;
1aedc22c 67+
9f54053a
JR
68+ if (dst->hh)
69+ return neigh_hh_output(dst->hh, skb);
70+ else if (dst->neighbour)
71+ return dst->neighbour->output(skb);
1aedc22c 72+
73+ if (net_ratelimit())
74+ printk(KERN_DEBUG "TARPIT ip_direct_send: no header cache and no neighbor!\n");
75+ kfree_skb(skb);
76+ return -EINVAL;
77+}
78+
79+
80+/* Send reply */
81+static void tarpit_tcp(struct sk_buff *oskb,struct rtable *ort,int local)
82+{
83+ struct sk_buff *nskb;
84+ struct rtable *nrt;
85+ struct tcphdr *otcph, *ntcph;
86+ struct flowi fl = {};
87+ unsigned int otcplen;
88+ u_int16_t tmp;
89+
90+ /* A truncated TCP header isn't going to be useful */
5ce52adc 91+ if (oskb->len < (ip_hdr(oskb)->ihl*4) + sizeof(struct tcphdr))
1aedc22c 92+ return;
93+
5ce52adc
JR
94+ otcph = (struct tcphdr *)((u_int32_t*)ip_hdr(oskb)
95+ + ip_hdr(oskb)->ihl);
96+ otcplen = oskb->len - ip_hdr(oskb)->ihl*4;
1aedc22c 97+
98+ /* No replies for RST or FIN */
99+ if (otcph->rst || otcph->fin)
100+ return;
101+
102+ /* No reply to !SYN,!ACK. Rate-limit replies to !SYN,ACKs */
103+ if (!otcph->syn && (!otcph->ack || !xrlim_allow(&ort->u.dst, 1*HZ)))
104+ return;
105+
106+ /* Check checksum. */
5ce52adc
JR
107+ if (tcp_v4_check(otcplen, ip_hdr(oskb)->saddr,
108+ ip_hdr(oskb)->daddr,
1aedc22c 109+ csum_partial((char *)otcph, otcplen, 0)) != 0)
110+ return;
111+
112+ /* Copy skb (even if skb is about to be dropped, we can't just
113+ clone it because there may be other things, such as tcpdump,
114+ interested in it) */
115+ nskb = skb_copy(oskb, GFP_ATOMIC);
116+ if (!nskb)
117+ return;
118+
119+ /* This packet will not be the same as the other: clear nf fields */
120+ nf_conntrack_put(nskb->nfct);
121+ nskb->nfct = NULL;
122+#ifdef CONFIG_NETFILTER_DEBUG
123+ nskb->nf_debug = 0;
124+#endif
125+
5ce52adc 126+ ntcph = (struct tcphdr *)((u_int32_t*)ip_hdr(nskb) + ip_hdr(nskb)->ihl);
1aedc22c 127+
128+ /* Truncate to length (no data) */
129+ ntcph->doff = sizeof(struct tcphdr)/4;
5ce52adc
JR
130+ skb_trim(nskb, ip_hdr(nskb)->ihl*4 + sizeof(struct tcphdr));
131+ ip_hdr(nskb)->tot_len = htons(nskb->len);
1aedc22c 132+
133+ /* Swap source and dest */
5ce52adc 134+ ip_hdr(nskb)->daddr = xchg(&ip_hdr(nskb)->saddr, ip_hdr(nskb)->daddr);
1aedc22c 135+ tmp = ntcph->source;
136+ ntcph->source = ntcph->dest;
137+ ntcph->dest = tmp;
138+
139+ /* Use supplied sequence number or make a new one */
140+ ntcph->seq = otcph->ack ? otcph->ack_seq
5ce52adc
JR
141+ : htonl(secure_tcp_sequence_number(ip_hdr(nskb)->saddr,
142+ ip_hdr(nskb)->daddr,
1aedc22c 143+ ntcph->source,
144+ ntcph->dest));
145+
146+ /* Our SYN-ACKs must have a >0 window */
147+ ntcph->window = (otcph->syn && !otcph->ack) ? htons(5) : 0;
148+
149+ ntcph->urg_ptr = 0;
150+
151+ /* Reset flags */
152+ ((u_int8_t *)ntcph)[13] = 0;
153+
154+ if (otcph->syn && otcph->ack) {
155+ ntcph->rst = 1;
156+ ntcph->ack_seq = 0;
157+ } else {
158+ ntcph->syn = otcph->syn;
159+ ntcph->ack = 1;
160+ ntcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn);
161+ }
162+
163+ /* Adjust TCP checksum */
164+ ntcph->check = 0;
6447fea8 165+ ntcph->check = tcp_v4_check(sizeof(struct tcphdr),
5ce52adc
JR
166+ ip_hdr(nskb)->saddr,
167+ ip_hdr(nskb)->daddr,
1aedc22c 168+ csum_partial((char *)ntcph,
169+ sizeof(struct tcphdr), 0));
170+
5ce52adc
JR
171+ fl.nl_u.ip4_u.daddr = ip_hdr(nskb)->daddr;
172+ fl.nl_u.ip4_u.saddr = local ? ip_hdr(nskb)->saddr : 0;
173+ fl.nl_u.ip4_u.tos = RT_TOS(ip_hdr(nskb)->tos) | RTO_CONN;
1aedc22c 174+ fl.oif = 0;
175+
55a5df0a 176+ if (ip_route_output_key(&init_net, &nrt, &fl))
1aedc22c 177+ goto free_nskb;
178+
179+ dst_release(nskb->dst);
180+ nskb->dst = &nrt->u.dst;
181+
182+ /* Adjust IP TTL */
5ce52adc 183+ ip_hdr(nskb)->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
1aedc22c 184+
185+ /* Set DF, id = 0 */
5ce52adc
JR
186+ ip_hdr(nskb)->frag_off = htons(IP_DF);
187+ ip_hdr(nskb)->id = 0;
1aedc22c 188+
189+ /* Adjust IP checksum */
5ce52adc
JR
190+ ip_hdr(nskb)->check = 0;
191+ ip_hdr(nskb)->check = ip_fast_csum((unsigned char *)ip_hdr(nskb),
192+ ip_hdr(nskb)->ihl);
1aedc22c 193+
194+ /* "Never happens" */
195+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
196+ if (nskb->len > dst_mtu(nskb->dst))
197+#else
198+ if (nskb->len > dst_pmtu(nskb->dst))
199+#endif
200+ goto free_nskb;
201+
202+ ip_direct_send (nskb);
203+
204+ return;
205+
206+ free_nskb:
207+ kfree_skb(nskb);
208+}
209+
210+
211+static unsigned int tarpit(struct sk_buff **pskb,
212+ const struct net_device *in,
213+ const struct net_device *out,
214+ unsigned int hooknum,
cec6e58a 215+ const struct xt_target *target,
216+ const void *targinfo)
1aedc22c 217+{
218+ struct sk_buff *skb = *pskb;
219+ struct rtable *rt = (struct rtable*)skb->dst;
220+
221+ /* Do we have an input route cache entry? */
222+ if (!rt)
223+ return NF_DROP;
224+
225+ /* No replies to physical multicast/broadcast */
226+ if (skb->pkt_type != PACKET_HOST && skb->pkt_type != PACKET_OTHERHOST)
227+ return NF_DROP;
228+
229+ /* Now check at the protocol level */
230+ if (rt->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST))
231+ return NF_DROP;
232+
233+ /* Our naive response construction doesn't deal with IP
234+ options, and probably shouldn't try. */
5ce52adc 235+ if (ip_hdr(skb)->ihl*4 != sizeof(struct iphdr))
1aedc22c 236+ return NF_DROP;
237+
238+ /* We aren't interested in fragments */
5ce52adc 239+ if (ip_hdr(skb)->frag_off & htons(IP_OFFSET))
1aedc22c 240+ return NF_DROP;
241+
55a5df0a 242+ tarpit_tcp(skb,rt,hooknum == NF_INET_LOCAL_IN);
1aedc22c 243+
244+ return NF_DROP;
245+}
246+
247+
248+static int check(const char *tablename,
249+ const void *e_void,
cec6e58a 250+ const struct xt_target *target,
1aedc22c 251+ void *targinfo,
1aedc22c 252+ unsigned int hook_mask)
253+{
254+ const struct ipt_entry *e = e_void;
255+
256+ /* Only allow these for input/forward packet filtering. */
257+ if (strcmp(tablename, "filter") != 0) {
258+ DEBUGP("TARPIT: bad table %s'.\n", tablename);
259+ return 0;
260+ }
55a5df0a 261+ if ((hook_mask & ~((1 << NF_INET_LOCAL_IN)
262+ | (1 << NF_INET_FORWARD))) != 0) {
1aedc22c 263+ DEBUGP("TARPIT: bad hook mask %X\n", hook_mask);
264+ return 0;
265+ }
266+
267+ /* Must specify that it's a TCP packet */
268+ if (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & IPT_INV_PROTO)) {
269+ DEBUGP("TARPIT: not valid for non-tcp\n");
270+ return 0;
271+ }
272+
273+ return 1;
274+}
275+
9f54053a 276+static struct xt_target ipt_tarpit_reg = {
1aedc22c 277+ .name = "TARPIT",
9f54053a 278+ .family = AF_INET,
1aedc22c 279+ .target = tarpit,
280+ .checkentry = check,
281+ .me = THIS_MODULE
282+};
283+
284+static int __init init(void)
285+{
6447fea8 286+ return xt_register_target(&ipt_tarpit_reg);
1aedc22c 287+}
288+
289+static void __exit fini(void)
290+{
6447fea8 291+ xt_unregister_target(&ipt_tarpit_reg);
1aedc22c 292+}
293+
294+module_init(init);
295+module_exit(fini);
9f54053a
JR
296diff -Nru linux-2.6.22/net/ipv4/netfilter/Kconfig linux-2.6.22-pom2patch/net/ipv4/netfilter/Kconfig
297--- linux-2.6.22/net/ipv4/netfilter/Kconfig 2007-07-09 01:32:17.000000000 +0200
298+++ linux-2.6.22-pom2patch/net/ipv4/netfilter/Kconfig 2007-08-07 18:38:14.000000000 +0200
299@@ -402,5 +402,22 @@
300 Allows altering the ARP packet payload: source and destination
301 hardware and network addresses.
302
303+config IP_NF_TARGET_TARPIT
304+ tristate 'TARPIT target support'
305+ depends on IP_NF_FILTER
306+ help
307+ Adds a TARPIT target to iptables, which captures and holds
308+ incoming TCP connections using no local per-connection resources.
309+ Connections are accepted, but immediately switched to the persist
310+ state (0 byte window), in which the remote side stops sending data
311+ and asks to continue every 60-240 seconds. Attempts to close the
312+ connection are ignored, forcing the remote side to time out the
313+ connection in 12-24 minutes.
314+
315+ This offers similar functionality to LaBrea
316+ <http://www.hackbusters.net/LaBrea/> but doesn't require dedicated
317+ hardware or IPs. Any TCP port that you would normally DROP or REJECT
318+ can instead become a tarpit.
319+
320 endmenu
321
322diff -Nru linux-2.6.22/net/ipv4/netfilter/Makefile linux-2.6.22-pom2patch/net/ipv4/netfilter/Makefile
323--- linux-2.6.22/net/ipv4/netfilter/Makefile 2007-07-09 01:32:17.000000000 +0200
324+++ linux-2.6.22-pom2patch/net/ipv4/netfilter/Makefile 2007-08-07 18:38:14.000000000 +0200
2bb1cfd6 325@@ -0,0 +0,1 @@
9f54053a 326+obj-$(CONFIG_IP_NF_TARGET_TARPIT) += ipt_TARPIT.o
39f44568 327--- linux-2.6.22/drivers/char/random.c~ 2007-08-10 21:18:33.000000000 +0200
328+++ linux-2.6.22/drivers/char/random.c 2007-08-10 22:02:26.079943000 +0200
329@@ -1569,6 +1569,8 @@ __u32 secure_tcp_sequence_number(__be32
330 return seq;
331 }
332
333+EXPORT_SYMBOL(secure_tcp_sequence_number);
334+
335 /* Generate secure starting point for ephemeral IPV4 transport port search */
336 u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
337 {
This page took 0.514623 seconds and 4 git commands to generate.