]>
Commit | Line | Data |
---|---|---|
c6410bf7 | 1 | include/linux/netfilter_ipv4/ipt_psd.h | 40 +++ |
2 | net/ipv4/netfilter/Kconfig | 10 | |
3 | net/ipv4/netfilter/Makefile | 1 | |
4 | net/ipv4/netfilter/ipt_psd.c | 358 +++++++++++++++++++++++++++++++++ | |
5 | 4 files changed, 409 insertions(+) | |
6 | ||
7 | diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter_ipv4/ipt_psd.h linux/include/linux/netfilter_ipv4/ipt_psd.h | |
8 | --- linux.org/include/linux/netfilter_ipv4/ipt_psd.h 1970-01-01 01:00:00.000000000 +0100 | |
9 | +++ linux/include/linux/netfilter_ipv4/ipt_psd.h 2006-05-04 10:21:57.000000000 +0200 | |
10 | @@ -0,0 +1,40 @@ | |
11 | +#ifndef _IPT_PSD_H | |
12 | +#define _IPT_PSD_H | |
13 | + | |
14 | +#include <linux/param.h> | |
15 | +#include <linux/types.h> | |
16 | + | |
17 | +/* | |
18 | + * High port numbers have a lower weight to reduce the frequency of false | |
19 | + * positives, such as from passive mode FTP transfers. | |
20 | + */ | |
21 | +#define PORT_WEIGHT_PRIV 3 | |
22 | +#define PORT_WEIGHT_HIGH 1 | |
23 | + | |
24 | +/* | |
25 | + * Port scan detection thresholds: at least COUNT ports need to be scanned | |
26 | + * from the same source, with no longer than DELAY ticks between ports. | |
27 | + */ | |
28 | +#define SCAN_MIN_COUNT 7 | |
29 | +#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV) | |
30 | +#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT | |
31 | +#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */ | |
32 | + | |
33 | +/* | |
34 | + * Keep track of up to LIST_SIZE source addresses, using a hash table of | |
35 | + * HASH_SIZE entries for faster lookups, but limiting hash collisions to | |
36 | + * HASH_MAX source addresses per the same hash value. | |
37 | + */ | |
38 | +#define LIST_SIZE 0x100 | |
39 | +#define HASH_LOG 9 | |
40 | +#define HASH_SIZE (1 << HASH_LOG) | |
41 | +#define HASH_MAX 0x10 | |
42 | + | |
43 | +struct ipt_psd_info { | |
44 | + unsigned int weight_threshold; | |
45 | + unsigned int delay_threshold; | |
46 | + unsigned short lo_ports_weight; | |
47 | + unsigned short hi_ports_weight; | |
48 | +}; | |
49 | + | |
50 | +#endif /*_IPT_PSD_H*/ | |
51 | diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Kconfig linux/net/ipv4/netfilter/Kconfig | |
52 | --- linux.org/net/ipv4/netfilter/Kconfig 2006-05-02 23:38:44.000000000 +0200 | |
53 | +++ linux/net/ipv4/netfilter/Kconfig 2006-05-04 10:21:57.000000000 +0200 | |
54 | @@ -606,5 +606,15 @@ | |
55 | Allows altering the ARP packet payload: source and destination | |
56 | hardware and network addresses. | |
57 | ||
58 | +config IP_NF_MATCH_PSD | |
59 | + tristate 'psd match support' | |
60 | + depends on IP_NF_IPTABLES | |
61 | + help | |
62 | + This option adds a `psd' match, which allows you to create rules in | |
63 | + any iptables table wich will detect TCP and UDP port scans. | |
64 | + | |
65 | + If you want to compile it as a module, say M here and read | |
66 | + Documentation/modules.txt. If unsure, say `N'. | |
67 | + | |
68 | endmenu | |
69 | ||
70 | diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile | |
71 | --- linux.org/net/ipv4/netfilter/Makefile 2006-05-02 23:38:44.000000000 +0200 | |
72 | +++ linux/net/ipv4/netfilter/Makefile 2006-05-04 10:21:57.000000000 +0200 | |
73 | @@ -0,0 +0,1 @@ | |
74 | +obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o | |
75 | diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ipt_psd.c linux/net/ipv4/netfilter/ipt_psd.c | |
76 | --- linux.org/net/ipv4/netfilter/ipt_psd.c 1970-01-01 01:00:00.000000000 +0100 | |
77 | +++ linux/net/ipv4/netfilter/ipt_psd.c 2006-05-04 10:21:57.000000000 +0200 | |
78 | @@ -0,0 +1,359 @@ | |
79 | +/* | |
80 | + This is a module which is used for PSD (portscan detection) | |
81 | + Derived from scanlogd v2.1 written by Solar Designer <solar@false.com> | |
82 | + and LOG target module. | |
83 | + | |
84 | + Copyright (C) 2000,2001 astaro AG | |
85 | + | |
86 | + This file is distributed under the terms of the GNU General Public | |
87 | + License (GPL). Copies of the GPL can be obtained from: | |
88 | + ftp://prep.ai.mit.edu/pub/gnu/GPL | |
89 | + | |
90 | + 2000-05-04 Markus Hennig <hennig@astaro.de> : initial | |
91 | + 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release | |
92 | + 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added | |
93 | + 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified | |
94 | + 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match | |
95 | + 2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6 | |
96 | +*/ | |
97 | + | |
98 | +#include <linux/module.h> | |
99 | +#include <linux/skbuff.h> | |
100 | +#include <linux/ip.h> | |
101 | +#include <net/tcp.h> | |
102 | +#include <linux/spinlock.h> | |
103 | +#include <linux/netfilter_ipv4/ip_tables.h> | |
104 | +#include <linux/netfilter_ipv4/ipt_psd.h> | |
105 | + | |
106 | +#if 0 | |
107 | +#define DEBUGP printk | |
108 | +#else | |
109 | +#define DEBUGP(format, args...) | |
110 | +#endif | |
111 | + | |
112 | +MODULE_LICENSE("GPL"); | |
113 | +MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>"); | |
114 | + | |
115 | +#define HF_DADDR_CHANGING 0x01 | |
116 | +#define HF_SPORT_CHANGING 0x02 | |
117 | +#define HF_TOS_CHANGING 0x04 | |
118 | +#define HF_TTL_CHANGING 0x08 | |
119 | + | |
120 | +/* | |
121 | + * Information we keep per each target port | |
122 | + */ | |
123 | +struct port { | |
124 | + u_int16_t number; /* port number */ | |
125 | + u_int8_t proto; /* protocol number */ | |
126 | + u_int8_t and_flags; /* tcp ANDed flags */ | |
127 | + u_int8_t or_flags; /* tcp ORed flags */ | |
128 | +}; | |
129 | + | |
130 | +/* | |
131 | + * Information we keep per each source address. | |
132 | + */ | |
133 | +struct host { | |
134 | + struct host *next; /* Next entry with the same hash */ | |
135 | + clock_t timestamp; /* Last update time */ | |
136 | + struct in_addr src_addr; /* Source address */ | |
137 | + struct in_addr dest_addr; /* Destination address */ | |
138 | + unsigned short src_port; /* Source port */ | |
139 | + int count; /* Number of ports in the list */ | |
140 | + int weight; /* Total weight of ports in the list */ | |
141 | + struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */ | |
142 | + unsigned char tos; /* TOS */ | |
143 | + unsigned char ttl; /* TTL */ | |
144 | + unsigned char flags; /* HF_ flags bitmask */ | |
145 | +}; | |
146 | + | |
147 | +/* | |
148 | + * State information. | |
149 | + */ | |
150 | +static struct { | |
151 | + spinlock_t lock; | |
152 | + struct host list[LIST_SIZE]; /* List of source addresses */ | |
153 | + struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */ | |
154 | + int index; /* Oldest entry to be replaced */ | |
155 | +} state; | |
156 | + | |
157 | +/* | |
158 | + * Convert an IP address into a hash table index. | |
159 | + */ | |
160 | +static inline int hashfunc(struct in_addr addr) | |
161 | +{ | |
162 | + unsigned int value; | |
163 | + int hash; | |
164 | + | |
165 | + value = addr.s_addr; | |
166 | + hash = 0; | |
167 | + do { | |
168 | + hash ^= value; | |
169 | + } while ((value >>= HASH_LOG)); | |
170 | + | |
171 | + return hash & (HASH_SIZE - 1); | |
172 | +} | |
173 | + | |
174 | +static int | |
175 | +ipt_psd_match(const struct sk_buff *pskb, | |
176 | + const struct net_device *in, | |
177 | + const struct net_device *out, | |
178 | + const void *matchinfo, | |
179 | + int offset, | |
180 | + unsigned int protoff, | |
181 | + int *hotdrop) | |
182 | +{ | |
183 | + struct iphdr *ip_hdr; | |
184 | + struct tcphdr *tcp_hdr; | |
185 | + struct in_addr addr; | |
186 | + u_int16_t src_port,dest_port; | |
187 | + u_int8_t tcp_flags, proto; | |
188 | + clock_t now; | |
189 | + struct host *curr, *last, **head; | |
190 | + int hash, index, count; | |
191 | + | |
192 | + /* Parameters from userspace */ | |
193 | + const struct ipt_psd_info *psdinfo = matchinfo; | |
194 | + | |
195 | + /* IP header */ | |
196 | + ip_hdr = pskb->nh.iph; | |
197 | + | |
198 | + /* Sanity check */ | |
199 | + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) { | |
200 | + DEBUGP("PSD: sanity check failed\n"); | |
201 | + return 0; | |
202 | + } | |
203 | + | |
204 | + /* TCP or UDP ? */ | |
205 | + proto = ip_hdr->protocol; | |
206 | + | |
207 | + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) { | |
208 | + DEBUGP("PSD: protocol not supported\n"); | |
209 | + return 0; | |
210 | + } | |
211 | + | |
212 | + /* Get the source address, source & destination ports, and TCP flags */ | |
213 | + | |
214 | + addr.s_addr = ip_hdr->saddr; | |
215 | + | |
216 | + tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl); | |
217 | + | |
218 |