* [PATCH 0/2] xt_connlimit - connection limiting @ 2007-06-03 11:12 Jan Engelhardt 2007-06-03 11:12 ` Jan Engelhardt 2007-06-03 11:14 ` [PATCH 2/2] xt_connlimit (iptables) " Jan Engelhardt 0 siblings, 2 replies; 14+ messages in thread From: Jan Engelhardt @ 2007-06-03 11:12 UTC (permalink / raw) To: Netfilter Developer Mailing List Cc: Netfilter Mailing List, Linux Kernel Mailing List Hello! as with xt_u32, I would like to get xt_connlimit merged. Find patches as a reply to this mail. Runtime tested. Jan -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/2] xt_connlimit (kernel) - connection limiting 2007-06-03 11:12 [PATCH 0/2] xt_connlimit - connection limiting Jan Engelhardt @ 2007-06-03 11:12 ` Jan Engelhardt 2007-06-03 11:14 ` [PATCH 2/2] xt_connlimit (iptables) " Jan Engelhardt 1 sibling, 0 replies; 14+ messages in thread From: Jan Engelhardt @ 2007-06-03 11:12 UTC (permalink / raw) To: Netfilter Developer Mailing List Cc: Netfilter Mailing List, Linux Kernel Mailing List Adds the connlimit match that has been in POM-NG for a long time. * works with 2.6.22, xtables'ified and all that * will request nf_conntrack_ipv4 upon load (otherwise it hotdrops every packet - a glitch that goes back to at least 2.6.20.2) Signed-off-by: Jan Engelhardt <jengelh@gmx.de> --- include/linux/netfilter/nf_conntrack_common.h | 1 include/linux/netfilter/xt_connlimit.h | 14 + net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 5 net/netfilter/Kconfig | 7 net/netfilter/Makefile | 1 net/netfilter/xt_connlimit.c | 250 +++++++++++++++++++++++++ 6 files changed, 278 insertions(+) Index: linux-2.6.22-rc3-git6/include/linux/netfilter/nf_conntrack_common.h =================================================================== --- linux-2.6.22-rc3-git6.orig/include/linux/netfilter/nf_conntrack_common.h +++ linux-2.6.22-rc3-git6/include/linux/netfilter/nf_conntrack_common.h @@ -164,6 +164,7 @@ struct ip_conntrack_stat /* call to create an explicit dependency on nf_conntrack. */ extern void need_conntrack(void); +extern void need_conntrack_ipv4(void); #endif /* __KERNEL__ */ Index: linux-2.6.22-rc3-git6/include/linux/netfilter/xt_connlimit.h =================================================================== --- /dev/null +++ linux-2.6.22-rc3-git6/include/linux/netfilter/xt_connlimit.h @@ -0,0 +1,14 @@ +#ifndef _XT_CONNLIMIT_H +#define _XT_CONNLIMIT_H + +struct xt_connlimit_data; + +struct xt_connlimit_info { + uint32_t mask; + unsigned int limit, inverse; + + /* this needs to be at the end */ + struct xt_connlimit_data *data; +}; + +#endif /* _XT_CONNLIMIT_H */ Index: linux-2.6.22-rc3-git6/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c =================================================================== --- linux-2.6.22-rc3-git6.orig/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ linux-2.6.22-rc3-git6/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -519,3 +519,8 @@ static void __exit nf_conntrack_l3proto_ module_init(nf_conntrack_l3proto_ipv4_init); module_exit(nf_conntrack_l3proto_ipv4_fini); + +void need_conntrack_ipv4(void) +{ +} +EXPORT_SYMBOL(need_conntrack_ipv4); Index: linux-2.6.22-rc3-git6/net/netfilter/Kconfig =================================================================== --- linux-2.6.22-rc3-git6.orig/net/netfilter/Kconfig +++ linux-2.6.22-rc3-git6/net/netfilter/Kconfig @@ -411,6 +411,13 @@ config NETFILTER_XT_MATCH_CONNBYTES If you want to compile it as a module, say M here and read <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. +config NETFILTER_XT_MATCH_CONNLIMIT + tristate '"connlimit" match support"' + depends on NETFILTER_XTABLES && NF_CONNTRACK_IPV4 + ---help--- + This match allows you to match against the number of parallel TCP + connections to a server per client IP address (or address block). + config NETFILTER_XT_MATCH_CONNMARK tristate '"connmark" connection mark match support' depends on NETFILTER_XTABLES Index: linux-2.6.22-rc3-git6/net/netfilter/Makefile =================================================================== --- linux-2.6.22-rc3-git6.orig/net/netfilter/Makefile +++ linux-2.6.22-rc3-git6/net/netfilter/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSEC # matches obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o +obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o Index: linux-2.6.22-rc3-git6/net/netfilter/xt_connlimit.c =================================================================== --- /dev/null +++ linux-2.6.22-rc3-git6/net/netfilter/xt_connlimit.c @@ -0,0 +1,250 @@ +/* + * netfilter module to limit the number of parallel tcp + * connections per IP address. + * (c) 2000 Gerd Knorr <kraxel@bytesex.org> + * Nov 2002: Martin Bene <martin.bene@icomedias.com>: + * only ignore TIME_WAIT or gone connections + * © Jan Engelhardt <jengelh@gmx.de>, 2007 + * + * based on ... + * + * Kernel module to match connection tracking information. + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au). + */ +#include <linux/in.h> +#include <linux/ip.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/spinlock.h> +#include <linux/netfilter/nf_conntrack_common.h> +#include <linux/netfilter/nf_conntrack_tcp.h> +#include <linux/netfilter/x_tables.h> +#include <linux/netfilter/xt_connlimit.h> +#include <net/netfilter/nf_conntrack.h> +#include <net/netfilter/nf_conntrack_core.h> +#include <net/netfilter/nf_conntrack_tuple.h> + +#define DEBUG 0 + +/* we will save the tuples of all connections we care about */ +struct xt_connlimit_conn { + struct list_head list; + struct nf_conntrack_tuple tuple; +}; + +struct xt_connlimit_data { + struct list_head iphash[256]; + spinlock_t lock; +}; + +static inline unsigned int connlimit_iphash(uint32_t addr) +{ + return (addr ^ (addr >> 8) ^ (addr >> 16) ^ (addr >> 24)) & 0xff; +} + +static int count_them(struct xt_connlimit_data *data, uint32_t addr, + uint32_t mask, struct nf_conn *ct) +{ +#if DEBUG + static const char const *tcp_state[] = { + "none", "established", "syn_sent", "syn_recv", "fin_wait", + "time_wait", "close", "close_wait", "last_ack", "listen" + }; +#endif + struct nf_conntrack_tuple_hash *found; + struct nf_conntrack_tuple tuple; + struct xt_connlimit_conn *conn; + struct list_head *hash, *lh; + int addit = 1, matches = 0; + struct nf_conn *found_ct; + + spin_lock_bh(&data->lock); + tuple = ct->tuplehash[0].tuple; + hash = &data->iphash[connlimit_iphash(addr & mask)]; + + /* check the saved connections */ + for (lh = hash->next; lh != hash; lh = lh->next) { + conn = list_entry(lh, struct xt_connlimit_conn, list); + found = nf_conntrack_find_get(&conn->tuple, ct); + found_ct = NULL; + + if (found != NULL && + (found_ct = nf_ct_tuplehash_to_ctrack(found)) != NULL && + memcmp(&conn->tuple, &tuple, sizeof(tuple)) == 0 && + found_ct->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) + /* + * Just to be sure we have it only once in the list. + * We should not see tuples twice unless someone hooks + * this into a table without "-p tcp --syn". + */ + addit = 0; + +#if DEBUG + printk(KERN_WARNING "xt_connlimit [%u]: src=%u.%u.%u.%u:%u " + "dst=%u.%u.%u.%u:%d %s\n", + connlimit_iphash(addr & mask), + NIPQUAD(conn->tuple.src.u3.ip), + ntohs(conn->tuple.src.u.tcp.port), + NIPQUAD(conn->tuple.dst.u3.ip), + ntohs(conn->tuple.dst.u.tcp.port), + (found == NULL) ? "gone" : + tcp_state[found_ct->proto.tcp.state]); +#endif + + if (found == NULL) { + /* this one is gone */ + lh = lh->prev; + list_del(lh->next); + kfree(conn); + continue; + } + + if (found_ct->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) { + /* + * we do not care about connections which are + * closed already -> ditch it + */ + lh = lh->prev; + list_del(lh->next); + kfree(conn); + nf_conntrack_put(&found_ct->ct_general); + continue; + } + + if ((addr & mask) == (conn->tuple.src.u3.ip & mask)) + /* same source IP address -> be counted! */ + ++matches; + + nf_conntrack_put(&found_ct->ct_general); + } + + if (addit) { + /* save the new connection in our list */ +#if DEBUG + printk(KERN_WARNING "xt_connlimit [%u]: src=%u.%u.%u.%u:%u " + "dst=%u.%u.%u.%u:%u new\n", + connlimit_iphash(addr & mask), + NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port), + NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port)); +#endif + + conn = kzalloc(sizeof(*conn), GFP_ATOMIC); + if (conn == NULL) + return -ENOMEM; + + INIT_LIST_HEAD(&conn->list); + conn->tuple = tuple; + list_add(&conn->list, hash); + ++matches; + } + + spin_unlock_bh(&data->lock); + return matches; +} + +static int xt_connlimit_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct xt_match *match, + const void *matchinfo, int offset, + unsigned int protoff, int *hotdrop) +{ + const struct xt_connlimit_info *info = matchinfo; + enum ip_conntrack_info ctinfo; + const struct iphdr *iph; + int connections, rv; + struct nf_conn *ct; + + ct = nf_ct_get(skb, &ctinfo); + if (ct == NULL) { + printk(KERN_INFO "xt_connlimit: INVALID connection or " + "nf_conntrack_ipv4 not loaded\n"); + *hotdrop = 1; + return false; + } + + iph = ip_hdr(skb); + connections = count_them(info->data, iph->saddr, info->mask, ct); + if (connections < 0) { + /* kmalloc failed, drop it entirely */ + printk(KERN_DEBUG "xt_connlimit: kmalloc failed\n"); + *hotdrop = 1; + return false; + } + + rv = info->inverse ^ (connections > info->limit); +#if DEBUG + printk(KERN_DEBUG "xt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u " + "connections=%d limit=%u match=%s\n", + NIPQUAD(iph->saddr), NIPQUAD(info->mask), + connections, info->limit, match ? "yes" : "no"); +#endif + + return rv; +} + +static int xt_connlimit_check(const char *tablename, const void *ip, + const struct xt_match *match, void *matchinfo, + unsigned int hook_mask) +{ + struct xt_connlimit_info *info = matchinfo; + unsigned int i; + + /* init private data */ + info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); + spin_lock_init(&info->data->lock); + for (i = 0; i < 256; ++i) + INIT_LIST_HEAD(&info->data->iphash[i]); + + return 1; +} + +static void xt_connlimit_destroy(const struct xt_match *match, void *matchinfo) +{ + struct xt_connlimit_info *info = matchinfo; + struct xt_connlimit_conn *conn; + struct list_head *hash; + unsigned int i; + + for (i = 0; i < 256; ++i) { + hash = &info->data->iphash[i]; + while (hash != hash->next) { + conn = list_entry(hash->next, + struct xt_connlimit_conn, list); + list_del(hash->next); + kfree(conn); + } + } + + kfree(info->data); + return; +} + +static struct xt_match xt_connlimit_reg = { + .name = "connlimit", + .family = AF_INET, + .proto = IPPROTO_TCP, + .checkentry = xt_connlimit_check, + .match = xt_connlimit_match, + .matchsize = sizeof(struct xt_connlimit_info), + .destroy = xt_connlimit_destroy, + .me = THIS_MODULE, +}; + +static int __init xt_connlimit_init(void) +{ + need_conntrack_ipv4(); + return xt_register_match(&xt_connlimit_reg); +} + +static void __exit xt_connlimit_exit(void) +{ + xt_unregister_match(&xt_connlimit_reg); + return; +} + +module_init(xt_connlimit_init); +module_exit(xt_connlimit_exit); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("ipt_connlimit"); ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/2] xt_connlimit (kernel) - connection limiting @ 2007-06-03 11:12 ` Jan Engelhardt 0 siblings, 0 replies; 14+ messages in thread From: Jan Engelhardt @ 2007-06-03 11:12 UTC (permalink / raw) To: Netfilter Developer Mailing List Cc: Netfilter Mailing List, Linux Kernel Mailing List Adds the connlimit match that has been in POM-NG for a long time. * works with 2.6.22, xtables'ified and all that * will request nf_conntrack_ipv4 upon load (otherwise it hotdrops every packet - a glitch that goes back to at least 2.6.20.2) Signed-off-by: Jan Engelhardt <jengelh@gmx.de> --- include/linux/netfilter/nf_conntrack_common.h | 1 include/linux/netfilter/xt_connlimit.h | 14 + net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 5 net/netfilter/Kconfig | 7 net/netfilter/Makefile | 1 net/netfilter/xt_connlimit.c | 250 +++++++++++++++++++++++++ 6 files changed, 278 insertions(+) Index: linux-2.6.22-rc3-git6/include/linux/netfilter/nf_conntrack_common.h =================================================================== --- linux-2.6.22-rc3-git6.orig/include/linux/netfilter/nf_conntrack_common.h +++ linux-2.6.22-rc3-git6/include/linux/netfilter/nf_conntrack_common.h @@ -164,6 +164,7 @@ struct ip_conntrack_stat /* call to create an explicit dependency on nf_conntrack. */ extern void need_conntrack(void); +extern void need_conntrack_ipv4(void); #endif /* __KERNEL__ */ Index: linux-2.6.22-rc3-git6/include/linux/netfilter/xt_connlimit.h =================================================================== --- /dev/null +++ linux-2.6.22-rc3-git6/include/linux/netfilter/xt_connlimit.h @@ -0,0 +1,14 @@ +#ifndef _XT_CONNLIMIT_H +#define _XT_CONNLIMIT_H + +struct xt_connlimit_data; + +struct xt_connlimit_info { + uint32_t mask; + unsigned int limit, inverse; + + /* this needs to be at the end */ + struct xt_connlimit_data *data; +}; + +#endif /* _XT_CONNLIMIT_H */ Index: linux-2.6.22-rc3-git6/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c =================================================================== --- linux-2.6.22-rc3-git6.orig/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ linux-2.6.22-rc3-git6/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -519,3 +519,8 @@ static void __exit nf_conntrack_l3proto_ module_init(nf_conntrack_l3proto_ipv4_init); module_exit(nf_conntrack_l3proto_ipv4_fini); + +void need_conntrack_ipv4(void) +{ +} +EXPORT_SYMBOL(need_conntrack_ipv4); Index: linux-2.6.22-rc3-git6/net/netfilter/Kconfig =================================================================== --- linux-2.6.22-rc3-git6.orig/net/netfilter/Kconfig +++ linux-2.6.22-rc3-git6/net/netfilter/Kconfig @@ -411,6 +411,13 @@ config NETFILTER_XT_MATCH_CONNBYTES If you want to compile it as a module, say M here and read <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. +config NETFILTER_XT_MATCH_CONNLIMIT + tristate '"connlimit" match support"' + depends on NETFILTER_XTABLES && NF_CONNTRACK_IPV4 + ---help--- + This match allows you to match against the number of parallel TCP + connections to a server per client IP address (or address block). + config NETFILTER_XT_MATCH_CONNMARK tristate '"connmark" connection mark match support' depends on NETFILTER_XTABLES Index: linux-2.6.22-rc3-git6/net/netfilter/Makefile =================================================================== --- linux-2.6.22-rc3-git6.orig/net/netfilter/Makefile +++ linux-2.6.22-rc3-git6/net/netfilter/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSEC # matches obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o +obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o Index: linux-2.6.22-rc3-git6/net/netfilter/xt_connlimit.c =================================================================== --- /dev/null +++ linux-2.6.22-rc3-git6/net/netfilter/xt_connlimit.c @@ -0,0 +1,250 @@ +/* + * netfilter module to limit the number of parallel tcp + * connections per IP address. + * (c) 2000 Gerd Knorr <kraxel@bytesex.org> + * Nov 2002: Martin Bene <martin.bene@icomedias.com>: + * only ignore TIME_WAIT or gone connections + * © Jan Engelhardt <jengelh@gmx.de>, 2007 + * + * based on ... + * + * Kernel module to match connection tracking information. + * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au). + */ +#include <linux/in.h> +#include <linux/ip.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/spinlock.h> +#include <linux/netfilter/nf_conntrack_common.h> +#include <linux/netfilter/nf_conntrack_tcp.h> +#include <linux/netfilter/x_tables.h> +#include <linux/netfilter/xt_connlimit.h> +#include <net/netfilter/nf_conntrack.h> +#include <net/netfilter/nf_conntrack_core.h> +#include <net/netfilter/nf_conntrack_tuple.h> + +#define DEBUG 0 + +/* we will save the tuples of all connections we care about */ +struct xt_connlimit_conn { + struct list_head list; + struct nf_conntrack_tuple tuple; +}; + +struct xt_connlimit_data { + struct list_head iphash[256]; + spinlock_t lock; +}; + +static inline unsigned int connlimit_iphash(uint32_t addr) +{ + return (addr ^ (addr >> 8) ^ (addr >> 16) ^ (addr >> 24)) & 0xff; +} + +static int count_them(struct xt_connlimit_data *data, uint32_t addr, + uint32_t mask, struct nf_conn *ct) +{ +#if DEBUG + static const char const *tcp_state[] = { + "none", "established", "syn_sent", "syn_recv", "fin_wait", + "time_wait", "close", "close_wait", "last_ack", "listen" + }; +#endif + struct nf_conntrack_tuple_hash *found; + struct nf_conntrack_tuple tuple; + struct xt_connlimit_conn *conn; + struct list_head *hash, *lh; + int addit = 1, matches = 0; + struct nf_conn *found_ct; + + spin_lock_bh(&data->lock); + tuple = ct->tuplehash[0].tuple; + hash = &data->iphash[connlimit_iphash(addr & mask)]; + + /* check the saved connections */ + for (lh = hash->next; lh != hash; lh = lh->next) { + conn = list_entry(lh, struct xt_connlimit_conn, list); + found = nf_conntrack_find_get(&conn->tuple, ct); + found_ct = NULL; + + if (found != NULL && + (found_ct = nf_ct_tuplehash_to_ctrack(found)) != NULL && + memcmp(&conn->tuple, &tuple, sizeof(tuple)) == 0 && + found_ct->proto.tcp.state != TCP_CONNTRACK_TIME_WAIT) + /* + * Just to be sure we have it only once in the list. + * We should not see tuples twice unless someone hooks + * this into a table without "-p tcp --syn". + */ + addit = 0; + +#if DEBUG + printk(KERN_WARNING "xt_connlimit [%u]: src=%u.%u.%u.%u:%u " + "dst=%u.%u.%u.%u:%d %s\n", + connlimit_iphash(addr & mask), + NIPQUAD(conn->tuple.src.u3.ip), + ntohs(conn->tuple.src.u.tcp.port), + NIPQUAD(conn->tuple.dst.u3.ip), + ntohs(conn->tuple.dst.u.tcp.port), + (found == NULL) ? "gone" : + tcp_state[found_ct->proto.tcp.state]); +#endif + + if (found == NULL) { + /* this one is gone */ + lh = lh->prev; + list_del(lh->next); + kfree(conn); + continue; + } + + if (found_ct->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT) { + /* + * we do not care about connections which are + * closed already -> ditch it + */ + lh = lh->prev; + list_del(lh->next); + kfree(conn); + nf_conntrack_put(&found_ct->ct_general); + continue; + } + + if ((addr & mask) == (conn->tuple.src.u3.ip & mask)) + /* same source IP address -> be counted! */ + ++matches; + + nf_conntrack_put(&found_ct->ct_general); + } + + if (addit) { + /* save the new connection in our list */ +#if DEBUG + printk(KERN_WARNING "xt_connlimit [%u]: src=%u.%u.%u.%u:%u " + "dst=%u.%u.%u.%u:%u new\n", + connlimit_iphash(addr & mask), + NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port), + NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port)); +#endif + + conn = kzalloc(sizeof(*conn), GFP_ATOMIC); + if (conn == NULL) + return -ENOMEM; + + INIT_LIST_HEAD(&conn->list); + conn->tuple = tuple; + list_add(&conn->list, hash); + ++matches; + } + + spin_unlock_bh(&data->lock); + return matches; +} + +static int xt_connlimit_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct xt_match *match, + const void *matchinfo, int offset, + unsigned int protoff, int *hotdrop) +{ + const struct xt_connlimit_info *info = matchinfo; + enum ip_conntrack_info ctinfo; + const struct iphdr *iph; + int connections, rv; + struct nf_conn *ct; + + ct = nf_ct_get(skb, &ctinfo); + if (ct == NULL) { + printk(KERN_INFO "xt_connlimit: INVALID connection or " + "nf_conntrack_ipv4 not loaded\n"); + *hotdrop = 1; + return false; + } + + iph = ip_hdr(skb); + connections = count_them(info->data, iph->saddr, info->mask, ct); + if (connections < 0) { + /* kmalloc failed, drop it entirely */ + printk(KERN_DEBUG "xt_connlimit: kmalloc failed\n"); + *hotdrop = 1; + return false; + } + + rv = info->inverse ^ (connections > info->limit); +#if DEBUG + printk(KERN_DEBUG "xt_connlimit: src=%u.%u.%u.%u mask=%u.%u.%u.%u " + "connections=%d limit=%u match=%s\n", + NIPQUAD(iph->saddr), NIPQUAD(info->mask), + connections, info->limit, match ? "yes" : "no"); +#endif + + return rv; +} + +static int xt_connlimit_check(const char *tablename, const void *ip, + const struct xt_match *match, void *matchinfo, + unsigned int hook_mask) +{ + struct xt_connlimit_info *info = matchinfo; + unsigned int i; + + /* init private data */ + info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); + spin_lock_init(&info->data->lock); + for (i = 0; i < 256; ++i) + INIT_LIST_HEAD(&info->data->iphash[i]); + + return 1; +} + +static void xt_connlimit_destroy(const struct xt_match *match, void *matchinfo) +{ + struct xt_connlimit_info *info = matchinfo; + struct xt_connlimit_conn *conn; + struct list_head *hash; + unsigned int i; + + for (i = 0; i < 256; ++i) { + hash = &info->data->iphash[i]; + while (hash != hash->next) { + conn = list_entry(hash->next, + struct xt_connlimit_conn, list); + list_del(hash->next); + kfree(conn); + } + } + + kfree(info->data); + return; +} + +static struct xt_match xt_connlimit_reg = { + .name = "connlimit", + .family = AF_INET, + .proto = IPPROTO_TCP, + .checkentry = xt_connlimit_check, + .match = xt_connlimit_match, + .matchsize = sizeof(struct xt_connlimit_info), + .destroy = xt_connlimit_destroy, + .me = THIS_MODULE, +}; + +static int __init xt_connlimit_init(void) +{ + need_conntrack_ipv4(); + return xt_register_match(&xt_connlimit_reg); +} + +static void __exit xt_connlimit_exit(void) +{ + xt_unregister_match(&xt_connlimit_reg); + return; +} + +module_init(xt_connlimit_init); +module_exit(xt_connlimit_exit); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("ipt_connlimit"); ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] xt_connlimit (kernel) - connection limiting 2007-06-03 11:12 ` Jan Engelhardt (?) @ 2007-06-03 11:46 ` Yasuyuki KOZAKAI -1 siblings, 0 replies; 14+ messages in thread From: Yasuyuki KOZAKAI @ 2007-06-03 11:46 UTC (permalink / raw) To: jengelh; +Cc: netfilter-devel, netfilter, linux-kernel Hi, From: Jan Engelhardt <jengelh@linux01.gwdg.de> Date: Sun, 3 Jun 2007 13:12:55 +0200 (MEST) > +static int __init xt_connlimit_init(void) > +{ > + need_conntrack_ipv4(); > + return xt_register_match(&xt_connlimit_reg); > +} You can use nf_ct_l3proto_try_module_get() instead of introducing need_conntrack_ipv4(). Please refer xt_state.c and xt_conntrack.c as example. -- Yasuyuki Kozakai ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] xt_connlimit (kernel) - connection limiting 2007-06-03 11:12 ` Jan Engelhardt (?) (?) @ 2007-06-03 11:46 ` Yasuyuki KOZAKAI -1 siblings, 0 replies; 14+ messages in thread From: Yasuyuki KOZAKAI @ 2007-06-03 11:46 UTC (permalink / raw) To: jengelh; +Cc: netfilter-devel, netfilter, linux-kernel Hi, From: Jan Engelhardt <jengelh@linux01.gwdg.de> Date: Sun, 3 Jun 2007 13:12:55 +0200 (MEST) > +static int __init xt_connlimit_init(void) > +{ > + need_conntrack_ipv4(); > + return xt_register_match(&xt_connlimit_reg); > +} You can use nf_ct_l3proto_try_module_get() instead of introducing need_conntrack_ipv4(). Please refer xt_state.c and xt_conntrack.c as example. -- Yasuyuki Kozakai ^ permalink raw reply [flat|nested] 14+ messages in thread
[parent not found: <200706031146.l53BkuaZ011945@toshiba.co.jp>]
* Re: [PATCH 1/2] xt_connlimit (kernel) - connection limiting [not found] ` <200706031146.l53BkuaZ011945@toshiba.co.jp> @ 2007-06-03 12:35 ` Jan Engelhardt 0 siblings, 0 replies; 14+ messages in thread From: Jan Engelhardt @ 2007-06-03 12:35 UTC (permalink / raw) To: Yasuyuki KOZAKAI; +Cc: netfilter-devel, netfilter, linux-kernel Hello, >From: Jan Engelhardt <jengelh@linux01.gwdg.de> >Date: Sun, 3 Jun 2007 13:12:55 +0200 (MEST) > >> +static int __init xt_connlimit_init(void) >> +{ >> + need_conntrack_ipv4(); >> + return xt_register_match(&xt_connlimit_reg); >> +} > >You can use nf_ct_l3proto_try_module_get() instead of introducing >need_conntrack_ipv4(). Please refer xt_state.c and xt_conntrack.c as >example. Thank you for this hint. I will add it and post updates versions of the patch(es) when I am done with all. Thanks, Jan -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] xt_connlimit (kernel) - connection limiting 2007-06-03 11:12 ` Jan Engelhardt ` (3 preceding siblings ...) (?) @ 2007-06-03 17:00 ` Andrew Beverley 2007-06-03 17:18 ` Jan Engelhardt -1 siblings, 1 reply; 14+ messages in thread From: Andrew Beverley @ 2007-06-03 17:00 UTC (permalink / raw) To: Jan Engelhardt Cc: Netfilter Developer Mailing List, Netfilter Mailing List, Linux Kernel Mailing List On Sun, 2007-06-03 at 13:12 +0200, Jan Engelhardt wrote: > Adds the connlimit match that has been in POM-NG for a long time. > > * works with 2.6.22, xtables'ified and all that > > * will request nf_conntrack_ipv4 upon load > (otherwise it hotdrops every packet - a glitch that goes back > to at least 2.6.20.2) Excellent! This has been at the back of my mind for a while. Is there any chance of getting UDP flows added as well as TCP connections? I use connlimit for detecting p2p software, but some p2p software now uses UDP instead. Thanks, Andy Beverley ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] xt_connlimit (kernel) - connection limiting 2007-06-03 17:00 ` Andrew Beverley @ 2007-06-03 17:18 ` Jan Engelhardt 2007-06-03 18:32 ` Andrew Beverley 0 siblings, 1 reply; 14+ messages in thread From: Jan Engelhardt @ 2007-06-03 17:18 UTC (permalink / raw) To: Andrew Beverley Cc: Netfilter Developer Mailing List, Netfilter Mailing List, Linux Kernel Mailing List On Jun 3 2007 18:00, Andrew Beverley wrote: >On Sun, 2007-06-03 at 13:12 +0200, Jan Engelhardt wrote: >> Adds the connlimit match that has been in POM-NG for a long time. >> >> * works with 2.6.22, xtables'ified and all that >> >> * will request nf_conntrack_ipv4 upon load >> (otherwise it hotdrops every packet - a glitch that goes back >> to at least 2.6.20.2) > >Excellent! This has been at the back of my mind for a while. > >Is there any chance of getting UDP flows added as well as TCP >connections? I dare to say it's easy. The real problem is rather, that UDP is connectionless, so for one, connlimit can, by definition of the word 'connectionless', not apply to UDP, though it is technically possible. Second, because UDP "connections" "fly" (timeout after 30 seconds), just spewing one UDP packet out may kill another connection (e.g. if you use connlimit in conjunction with DROP or REJECT). What's more, UDP packets can be easily forged, much more than TCP, so anyone on the same subtree (not subnet, because that's something different) can send a bogus UDP packet and stop your connections from working. Let's see how to implement UDP counting... Jan -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] xt_connlimit (kernel) - connection limiting 2007-06-03 17:18 ` Jan Engelhardt @ 2007-06-03 18:32 ` Andrew Beverley 0 siblings, 0 replies; 14+ messages in thread From: Andrew Beverley @ 2007-06-03 18:32 UTC (permalink / raw) To: Jan Engelhardt Cc: Netfilter Developer Mailing List, Netfilter Mailing List, Linux Kernel Mailing List On Sun, 2007-06-03 at 19:18 +0200, Jan Engelhardt wrote: > On Jun 3 2007 18:00, Andrew Beverley wrote: > >On Sun, 2007-06-03 at 13:12 +0200, Jan Engelhardt wrote: > >> Adds the connlimit match that has been in POM-NG for a long time. > >> > >> * works with 2.6.22, xtables'ified and all that > >> > >> * will request nf_conntrack_ipv4 upon load > >> (otherwise it hotdrops every packet - a glitch that goes back > >> to at least 2.6.20.2) > > > >Excellent! This has been at the back of my mind for a while. > > > >Is there any chance of getting UDP flows added as well as TCP > >connections? > > I dare to say it's easy. The real problem is rather, that UDP is > connectionless, so for one, connlimit can, by definition of the word > 'connectionless', not apply to UDP, though it is technically > possible. Understood. > Second, because UDP "connections" "fly" (timeout after 30 > seconds), just spewing one UDP packet out may kill another connection > (e.g. if you use connlimit in conjunction with DROP or REJECT). I see what you mean, although I personally would use this with an IPSET target, and I would argue it is the responsibility of the administrator to ensure it is used correctly. > What's more, UDP packets can be easily forged, much more than TCP, so > anyone on the same subtree (not subnet, because that's something > different) can send a bogus UDP packet and stop your connections from > working. I didn't know that, but I doubt anyone where I would use it would be able to do that :-) > Let's see how to implement UDP counting... The alternative, as I see it, is to adapt hashlimit to have an option to limit by number of different concurrent streams to different port numbers (but same source/destination IP address). However, I personally think it would sit better in connlimit, even if UDP is not a connection by strict definition. Is it something you would consider, or shall I look at it myself? With regards to Patrick's comment, IIRC this was one of the points he originally raised. Regards, Andy Beverley ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] xt_connlimit (kernel) - connection limiting 2007-06-03 11:12 ` Jan Engelhardt ` (4 preceding siblings ...) (?) @ 2007-06-03 17:34 ` Patrick McHardy 2007-06-05 8:33 ` Jan Engelhardt -1 siblings, 1 reply; 14+ messages in thread From: Patrick McHardy @ 2007-06-03 17:34 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List Jan Engelhardt wrote: > Adds the connlimit match that has been in POM-NG for a long time. This has about half the points I mentioned last time unfixed, starting with proper use of list.h. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] xt_connlimit (kernel) - connection limiting 2007-06-03 17:34 ` Patrick McHardy @ 2007-06-05 8:33 ` Jan Engelhardt 2007-06-05 11:36 ` Patrick McHardy 0 siblings, 1 reply; 14+ messages in thread From: Jan Engelhardt @ 2007-06-05 8:33 UTC (permalink / raw) To: Patrick McHardy; +Cc: Netfilter Developer Mailing List Hi, On Jun 3 2007 19:34, Patrick McHardy wrote: >Jan Engelhardt wrote: >> Adds the connlimit match that has been in POM-NG for a long time. > >This has about half the points I mentioned last time unfixed, >starting with proper use of list.h. #include <linux/list.h> ... struct xt_connlimit_conn { struct list_head list; struct nf_conntrack_tuple tuple; }; struct xt_connlimit_data { struct list_head iphash[256]; spinlock_t lock; }; That looks like lists to me. Please enlighten me where you think lists were missing. I remember "last time" as http://lists.netfilter.org/pipermail/netfilter-devel/2006-December/026341.html http://lists.netfilter.org/pipermail/netfilter-devel/2007-January/026577.html where you did not thought negatively about connlimit. Please let me know of the post you were referring to. Thanks! Jan -- ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] xt_connlimit (kernel) - connection limiting 2007-06-05 8:33 ` Jan Engelhardt @ 2007-06-05 11:36 ` Patrick McHardy 0 siblings, 0 replies; 14+ messages in thread From: Patrick McHardy @ 2007-06-05 11:36 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List Jan Engelhardt wrote: > Hi, > > > On Jun 3 2007 19:34, Patrick McHardy wrote: > >>Jan Engelhardt wrote: >> >>>Adds the connlimit match that has been in POM-NG for a long time. >> >>This has about half the points I mentioned last time unfixed, >>starting with proper use of list.h. > > > #include <linux/list.h> > ... > struct xt_connlimit_conn { > struct list_head list; > struct nf_conntrack_tuple tuple; > }; > struct xt_connlimit_data { > struct list_head iphash[256]; > spinlock_t lock; > }; > > That looks like lists to me. Please enlighten me where you think > lists were missing. + for (lh = hash->next; lh != hash; lh = lh->next) { + for (i = 0; i < 256; ++i) { + hash = &info->data->iphash[i]; + while (hash != hash->next) { + conn = list_entry(hash->next, + struct xt_connlimit_conn, list); > > I remember "last time" as > http://lists.netfilter.org/pipermail/netfilter-devel/2006-December/026341.html > http://lists.netfilter.org/pipermail/netfilter-devel/2007-January/026577.html > where you did not thought negatively about connlimit. Please let me know of the > post you were referring to. Thanks! This one: http://lists.netfilter.org/pipermail/netfilter/2007-April/068411.html ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/2] xt_connlimit (iptables) - connection limiting 2007-06-03 11:12 [PATCH 0/2] xt_connlimit - connection limiting Jan Engelhardt 2007-06-03 11:12 ` Jan Engelhardt @ 2007-06-03 11:14 ` Jan Engelhardt 2007-06-03 11:23 ` Jan Engelhardt 1 sibling, 1 reply; 14+ messages in thread From: Jan Engelhardt @ 2007-06-03 11:14 UTC (permalink / raw) To: Netfilter Developer Mailing List Cc: Netfilter Mailing List, Linux Kernel Mailing List Adds connlimit to iptables. Signed-off-by: Jan Engelhardt <jengelh@gmx.de> --- extensions/.connlimit-test | 2 extensions/libipt_connlimit.c | 129 ++++++++++++++++++++++++++++++++++++++++ extensions/libipt_connlimit.man | 21 ++++++ 3 files changed, 152 insertions(+) Index: iptables/extensions/.connlimit-test =================================================================== --- /dev/null +++ iptables/extensions/.connlimit-test @@ -0,0 +1,2 @@ +#!/bin/sh +[ -f "$KERNEL_DIR/include/linux/netfilter/xt_connlimit.h" ] && echo connlimit Index: iptables/extensions/libipt_connlimit.c =================================================================== --- /dev/null +++ iptables/extensions/libipt_connlimit.c @@ -0,0 +1,129 @@ +/* Shared library add-on to iptables to add connection limit support. */ +#include <stdio.h> +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include <getopt.h> +#include <iptables.h> +#include <linux/netfilter_ipv4/ip_conntrack.h> +#include <linux/netfilter_ipv4/xt_connlimit.h> + +/* Function which prints out usage message. */ +static void help(void) +{ + printf( +"connlimit v%s options:\n" +"[!] --connlimit-above n match if the number of existing tcp connections is (not) above n\n" +" --connlimit-mask n group hosts using mask\n" +"\n", IPTABLES_VERSION); +} + +static struct option opts[] = { + {"connlimit-above", 1, NULL, '1'}, + {"connlimit-mask", 1, NULL, '2'}, + {NULL}, +}; + +/* Function which parses command options; returns true if it + ate an option */ +static int parse(int c, char **argv, int invert, unsigned int *flags, + const struct ipt_entry *entry, unsigned int *nfcache, + struct ipt_entry_match **match) +{ + struct xt_connlimit_info *info = (void *)(*match)->data; + int i; + + if (!(*flags & 2)) + /* + * set default mask unless we have already seen a mask option + */ + info->mask = htonl(0xFFFFFFFF); + + switch (c) { + case '1': + check_inverse(optarg, &invert, &optind, 0); + info->limit = strtoul(argv[optind-1], NULL, 0); + info->inverse = invert; + *flags |= 1; + break; + + case '2': + i = strtol(argv[optind-1], NULL, 0); + if (i < 0 || i > 32) + exit_error(PARAMETER_PROBLEM, + "--connlimit-mask must be between 0 and 32"); + + if (i == 0) + info->mask = 0; + else + info->mask = htonl(0xFFFFFFFF << (32 - i)); + + *flags |= 2; + break; + + default: + return 0; + } + + return 1; +} + +/* Final check */ +static void final_check(unsigned int flags) +{ + if (!(flags & 1)) + exit_error(PARAMETER_PROBLEM, "You must specify `--connlimit-above'"); +} + +static int count_bits(u_int32_t mask) +{ + int i, bits; + + for (bits = 0, i = 31; i >= 0; i--) { + if (mask & htonl((u_int32_t)1 << i)) { + bits++; + continue; + } + break; + } + return bits; +} + +/* Prints out the matchinfo. */ +static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, + int numeric) +{ + const struct xt_connlimit_info *info = (const void *)match->data; + + printf("#conn/%d %s %d ", count_bits(info->mask), + info->inverse ? "<" : ">", info->limit); +} + +/* Saves the matchinfo in parsable form to stdout. */ +static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) +{ + const struct xt_connlimit_info *info = (const void *)match->data; + + printf("%s--connlimit-above %u --connlimit-mask %u ", + info->inverse ? "! " : "", info->limit, + count_bits(info->mask)); +} + +static struct iptables_match connlimit = { + .name = "connlimit", + .version = IPTABLES_VERSION, + .size = IPT_ALIGN(sizeof(struct xt_connlimit_info)), + .userspacesize = offsetof(struct xt_connlimit_info, data), + .help = help, + .parse = parse, + .final_check = final_check, + .print = print, + .save = save, + .extra_opts = opts, +}; + +static __attribute__((constructor)) void libipt_connlimit_init(void) +{ + register_match(&connlimit); +} Index: iptables/extensions/libipt_connlimit.man =================================================================== --- /dev/null +++ iptables/extensions/libipt_connlimit.man @@ -0,0 +1,21 @@ +Allows you to restrict the number of parallel TCP connections to a +server per client IP address (or address block). +.TP +[\fB!\fR] \fB--connlimit-above \fIn\fR +match if the number of existing tcp connections is (not) above n +.TP +.BI "--connlimit-mask " "bits" +group hosts using mask +.P +Examples: +.TP +# allow 2 telnet connections per client host +iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT +.TP +# you can also match the other way around: +iptables -A INPUT -p tcp --syn --dport 23 -m connlimit ! --connlimit-above 2 -j ACCEPT +.TP +# limit the nr of parallel http requests to 16 per class C sized \ +network (24 bit netmask) +iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 16 +--connlimit-mask 24 -j REJECT ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] xt_connlimit (iptables) - connection limiting 2007-06-03 11:14 ` [PATCH 2/2] xt_connlimit (iptables) " Jan Engelhardt @ 2007-06-03 11:23 ` Jan Engelhardt 0 siblings, 0 replies; 14+ messages in thread From: Jan Engelhardt @ 2007-06-03 11:23 UTC (permalink / raw) To: Netfilter Developer Mailing List Cc: Netfilter Mailing List, Linux Kernel Mailing List Previous patch had a wrong #include line, this one seems better :) ================ Adds connlimit to iptables. Signed-off-by: Jan Engelhardt <jengelh@gmx.de> --- extensions/.connlimit-test | 2 extensions/libipt_connlimit.c | 129 ++++++++++++++++++++++++++++++++++++++++ extensions/libipt_connlimit.man | 21 ++++++ 3 files changed, 152 insertions(+) Index: iptables/extensions/.connlimit-test =================================================================== --- /dev/null +++ iptables/extensions/.connlimit-test @@ -0,0 +1,2 @@ +#!/bin/sh +[ -f "$KERNEL_DIR/include/linux/netfilter/xt_connlimit.h" ] && echo connlimit Index: iptables/extensions/libipt_connlimit.c =================================================================== --- /dev/null +++ iptables/extensions/libipt_connlimit.c @@ -0,0 +1,129 @@ +/* Shared library add-on to iptables to add connection limit support. */ +#include <stdio.h> +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include <getopt.h> +#include <iptables.h> +#include <linux/netfilter_ipv4/ip_conntrack.h> +#include <linux/netfilter/xt_connlimit.h> + +/* Function which prints out usage message. */ +static void help(void) +{ + printf( +"connlimit v%s options:\n" +"[!] --connlimit-above n match if the number of existing tcp connections is (not) above n\n" +" --connlimit-mask n group hosts using mask\n" +"\n", IPTABLES_VERSION); +} + +static struct option opts[] = { + {"connlimit-above", 1, NULL, '1'}, + {"connlimit-mask", 1, NULL, '2'}, + {NULL}, +}; + +/* Function which parses command options; returns true if it + ate an option */ +static int parse(int c, char **argv, int invert, unsigned int *flags, + const struct ipt_entry *entry, unsigned int *nfcache, + struct ipt_entry_match **match) +{ + struct xt_connlimit_info *info = (void *)(*match)->data; + int i; + + if (!(*flags & 2)) + /* + * set default mask unless we have already seen a mask option + */ + info->mask = htonl(0xFFFFFFFF); + + switch (c) { + case '1': + check_inverse(optarg, &invert, &optind, 0); + info->limit = strtoul(argv[optind-1], NULL, 0); + info->inverse = invert; + *flags |= 1; + break; + + case '2': + i = strtol(argv[optind-1], NULL, 0); + if (i < 0 || i > 32) + exit_error(PARAMETER_PROBLEM, + "--connlimit-mask must be between 0 and 32"); + + if (i == 0) + info->mask = 0; + else + info->mask = htonl(0xFFFFFFFF << (32 - i)); + + *flags |= 2; + break; + + default: + return 0; + } + + return 1; +} + +/* Final check */ +static void final_check(unsigned int flags) +{ + if (!(flags & 1)) + exit_error(PARAMETER_PROBLEM, "You must specify `--connlimit-above'"); +} + +static int count_bits(u_int32_t mask) +{ + int i, bits; + + for (bits = 0, i = 31; i >= 0; i--) { + if (mask & htonl((u_int32_t)1 << i)) { + bits++; + continue; + } + break; + } + return bits; +} + +/* Prints out the matchinfo. */ +static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, + int numeric) +{ + const struct xt_connlimit_info *info = (const void *)match->data; + + printf("#conn/%d %s %d ", count_bits(info->mask), + info->inverse ? "<" : ">", info->limit); +} + +/* Saves the matchinfo in parsable form to stdout. */ +static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) +{ + const struct xt_connlimit_info *info = (const void *)match->data; + + printf("%s--connlimit-above %u --connlimit-mask %u ", + info->inverse ? "! " : "", info->limit, + count_bits(info->mask)); +} + +static struct iptables_match connlimit = { + .name = "connlimit", + .version = IPTABLES_VERSION, + .size = IPT_ALIGN(sizeof(struct xt_connlimit_info)), + .userspacesize = offsetof(struct xt_connlimit_info, data), + .help = help, + .parse = parse, + .final_check = final_check, + .print = print, + .save = save, + .extra_opts = opts, +}; + +static __attribute__((constructor)) void libipt_connlimit_init(void) +{ + register_match(&connlimit); +} Index: iptables/extensions/libipt_connlimit.man =================================================================== --- /dev/null +++ iptables/extensions/libipt_connlimit.man @@ -0,0 +1,21 @@ +Allows you to restrict the number of parallel TCP connections to a +server per client IP address (or address block). +.TP +[\fB!\fR] \fB--connlimit-above \fIn\fR +match if the number of existing tcp connections is (not) above n +.TP +.BI "--connlimit-mask " "bits" +group hosts using mask +.P +Examples: +.TP +# allow 2 telnet connections per client host +iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT +.TP +# you can also match the other way around: +iptables -A INPUT -p tcp --syn --dport 23 -m connlimit ! --connlimit-above 2 -j ACCEPT +.TP +# limit the nr of parallel http requests to 16 per class C sized \ +network (24 bit netmask) +iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 16 +--connlimit-mask 24 -j REJECT ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2007-06-05 11:36 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-03 11:12 [PATCH 0/2] xt_connlimit - connection limiting Jan Engelhardt
2007-06-03 11:12 ` [PATCH 1/2] xt_connlimit (kernel) " Jan Engelhardt
2007-06-03 11:12 ` Jan Engelhardt
2007-06-03 11:46 ` Yasuyuki KOZAKAI
2007-06-03 11:46 ` Yasuyuki KOZAKAI
[not found] ` <200706031146.l53BkuaZ011945@toshiba.co.jp>
2007-06-03 12:35 ` Jan Engelhardt
2007-06-03 17:00 ` Andrew Beverley
2007-06-03 17:18 ` Jan Engelhardt
2007-06-03 18:32 ` Andrew Beverley
2007-06-03 17:34 ` Patrick McHardy
2007-06-05 8:33 ` Jan Engelhardt
2007-06-05 11:36 ` Patrick McHardy
2007-06-03 11:14 ` [PATCH 2/2] xt_connlimit (iptables) " Jan Engelhardt
2007-06-03 11:23 ` Jan Engelhardt
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.