mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-21 20:14:56 +02:00
Compare commits
158 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bc5a7d8e3a | ||
![]() |
0628857068 | ||
![]() |
de4f6e8994 | ||
![]() |
439dd913f1 | ||
![]() |
9568747d94 | ||
![]() |
20365cf762 | ||
![]() |
fa601c0fa7 | ||
![]() |
00573d0172 | ||
![]() |
c7036a88f1 | ||
![]() |
af21c1d369 | ||
![]() |
b132101b63 | ||
![]() |
71beab548d | ||
![]() |
6de54e5fcd | ||
![]() |
a921427746 | ||
![]() |
2b2b6246f0 | ||
![]() |
98e5dfd6ef | ||
![]() |
9e5c2e7ee9 | ||
![]() |
284c0e9493 | ||
![]() |
5284b5db92 | ||
![]() |
36035d52d3 | ||
![]() |
4d94687c15 | ||
![]() |
7070678ab4 | ||
![]() |
f6281d498c | ||
![]() |
2cab32596a | ||
![]() |
08f6a82bdc | ||
![]() |
82a8524f1a | ||
![]() |
6bb354d3f0 | ||
![]() |
5184176c3b | ||
![]() |
430723ece1 | ||
![]() |
f1dc7f960c | ||
![]() |
370f47b000 | ||
![]() |
8e812620f0 | ||
![]() |
204b612e23 | ||
![]() |
c2c86f4b3d | ||
![]() |
379e685b0f | ||
![]() |
69dd0686e2 | ||
![]() |
48325a209e | ||
![]() |
96f501ab89 | ||
![]() |
3c1bf73e8e | ||
![]() |
e0276b4875 | ||
![]() |
1bc7f1be67 | ||
![]() |
3c3adcbd07 | ||
![]() |
da6a9b932c | ||
![]() |
5f290cd4a0 | ||
![]() |
181a9cab43 | ||
![]() |
a819458cba | ||
![]() |
654862af21 | ||
![]() |
0d8ae29a60 | ||
![]() |
e05a4d9586 | ||
![]() |
0541154a5e | ||
![]() |
00199427ac | ||
![]() |
35b00f8c3f | ||
![]() |
1f3150bdf9 | ||
![]() |
13c73af796 | ||
![]() |
ba9a3efec1 | ||
![]() |
f474c7d4d4 | ||
![]() |
4a350ddd03 | ||
![]() |
628d137f12 | ||
![]() |
28ecf45548 | ||
![]() |
58839b9b86 | ||
![]() |
e436948ebd | ||
![]() |
79d54ebd7c | ||
![]() |
0b64b27172 | ||
![]() |
d116000784 | ||
![]() |
4b5f0b12d9 | ||
![]() |
c8dde526f2 | ||
![]() |
3058e42a21 | ||
![]() |
40b30f7f27 | ||
![]() |
aaad5f53ac | ||
![]() |
db1057158f | ||
![]() |
713c31e8f7 | ||
![]() |
e5ffb39750 | ||
![]() |
19067393b6 | ||
![]() |
1de82a88a1 | ||
![]() |
9928c864ab | ||
![]() |
45515a0afd | ||
![]() |
75f80fa8f8 | ||
![]() |
d8dc72d151 | ||
![]() |
cee3d25d49 | ||
![]() |
afbeb2fb47 | ||
![]() |
c0dc0858de | ||
![]() |
b04317576b | ||
![]() |
af2bbf0352 | ||
![]() |
db9bb2778d | ||
![]() |
674560d2d9 | ||
![]() |
7ab033e64c | ||
![]() |
3131448443 | ||
![]() |
71322e614c | ||
![]() |
d3fdfe08dd | ||
![]() |
46f9ddbf59 | ||
![]() |
e37985b527 | ||
![]() |
0ccd55abd9 | ||
![]() |
60123a8c07 | ||
![]() |
504f1089fb | ||
![]() |
e119350000 | ||
![]() |
a260e3349f | ||
![]() |
5cb36ed213 | ||
![]() |
1a5b9f0e02 | ||
![]() |
2c53605084 | ||
![]() |
537f25dbad | ||
![]() |
63a1e5329f | ||
![]() |
b0a6111054 | ||
![]() |
b07434386b | ||
![]() |
0c963dee06 | ||
![]() |
09bfb8496e | ||
![]() |
9d1afc4268 | ||
![]() |
342ccf62b2 | ||
![]() |
adabd647b1 | ||
![]() |
26f25a43a9 | ||
![]() |
bcda21a2b0 | ||
![]() |
4e6bc8af95 | ||
![]() |
bd4be0d991 | ||
![]() |
1f736c8203 | ||
![]() |
90fa3ab9e2 | ||
![]() |
fd82a312d6 | ||
![]() |
27c1676821 | ||
![]() |
3e26335cbd | ||
![]() |
f4b96672ef | ||
![]() |
c3d080f21a | ||
![]() |
cb268031b7 | ||
![]() |
ac44a5a1fe | ||
![]() |
a3baa78ae2 | ||
![]() |
47e002127c | ||
![]() |
03363a528a | ||
![]() |
58b016f0af | ||
![]() |
8d64e7bd50 | ||
![]() |
dd6cb27da4 | ||
![]() |
06c01131e8 | ||
![]() |
a44c4e4b1d | ||
![]() |
1fb6f187d3 | ||
![]() |
83e474f9ab | ||
![]() |
efd4c91557 | ||
![]() |
65a257a67d | ||
![]() |
5b07e04600 | ||
![]() |
6b175b40cb | ||
![]() |
0887365f8b | ||
![]() |
cebadbfcd7 | ||
![]() |
380b1b6997 | ||
![]() |
8e5219636a | ||
![]() |
760edd3db6 | ||
![]() |
502c1c05aa | ||
![]() |
a7ceccc0f4 | ||
![]() |
10bd08d0f3 | ||
![]() |
1e5315d338 | ||
![]() |
579484ed70 | ||
![]() |
2aa32d4bce | ||
![]() |
5aee8738ed | ||
![]() |
1111edfd85 | ||
![]() |
0d47cb8b37 | ||
![]() |
1c55aec64a | ||
![]() |
dd26ab476c | ||
![]() |
4bf667d8eb | ||
![]() |
0a88bd3435 | ||
![]() |
62fb261265 | ||
![]() |
d97f77a8f5 | ||
![]() |
822c6bebe2 | ||
![]() |
fdf42a3a50 | ||
![]() |
6b2ca78af7 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -6,10 +6,15 @@
|
|||||||
.libs
|
.libs
|
||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
GNUmakefile
|
|
||||||
|
|
||||||
/downloads
|
/downloads
|
||||||
|
|
||||||
|
/Makefile.iptrules
|
||||||
|
/Makefile.mans
|
||||||
|
/.*.lst
|
||||||
|
/matches.man
|
||||||
|
/targets.man
|
||||||
|
|
||||||
/aclocal.m4
|
/aclocal.m4
|
||||||
/autom4te*.cache
|
/autom4te*.cache
|
||||||
/compile
|
/compile
|
||||||
|
16
INSTALL
16
INSTALL
@@ -19,6 +19,8 @@ Supported configurations for this release
|
|||||||
- CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK
|
- CONFIG_NF_CONNTRACK or CONFIG_IP_NF_CONNTRACK
|
||||||
- CONFIG_NF_CONNTRACK_MARK or CONFIG_IP_NF_CONNTRACK_MARK
|
- CONFIG_NF_CONNTRACK_MARK or CONFIG_IP_NF_CONNTRACK_MARK
|
||||||
enabled =y or as module (=m)
|
enabled =y or as module (=m)
|
||||||
|
- CONFIG_CONNECTOR y/m if you wish to receive userspace
|
||||||
|
notifications from pknock through netlink/connector
|
||||||
|
|
||||||
Extra notes:
|
Extra notes:
|
||||||
|
|
||||||
@@ -46,6 +48,9 @@ Configuring and compiling
|
|||||||
/lib/modules/$(running version)/build, which usually points to
|
/lib/modules/$(running version)/build, which usually points to
|
||||||
the right directory. (If not, you need to install something.)
|
the right directory. (If not, you need to install something.)
|
||||||
|
|
||||||
|
For RPM building, it should be /usr/src/linux-obj/...
|
||||||
|
or whatever location the distro makes use of.
|
||||||
|
|
||||||
--with-xtables=
|
--with-xtables=
|
||||||
|
|
||||||
Specifies the path to the directory where we may find
|
Specifies the path to the directory where we may find
|
||||||
@@ -55,11 +60,11 @@ Configuring and compiling
|
|||||||
include/xtables.h. (The latter to support both standard
|
include/xtables.h. (The latter to support both standard
|
||||||
/usr/include and the iptables source root.)
|
/usr/include and the iptables source root.)
|
||||||
|
|
||||||
--with-libxtdir=
|
--with-xtlibdir=
|
||||||
|
|
||||||
Specifies the path to where the newly built extensions should
|
Specifies the path to where the newly built extensions should
|
||||||
be installed when `make install` is run. It uses the same
|
be installed when `make install` is run. It uses the same
|
||||||
default as the Xtables package, ${libexecdir}/xtables.
|
default as the Xtables/iptables package, ${libexecdir}/xtables.
|
||||||
|
|
||||||
If you want to enable debugging, use
|
If you want to enable debugging, use
|
||||||
|
|
||||||
@@ -72,15 +77,10 @@ much easier.)
|
|||||||
Build-time options
|
Build-time options
|
||||||
==================
|
==================
|
||||||
|
|
||||||
V= controls the kernel's make verbosity.
|
V= controls the verbosity of make commands.
|
||||||
V=0 "silent" (output filename)
|
V=0 "silent" (output filename)
|
||||||
V=1 "verbose" (entire gcc command line)
|
V=1 "verbose" (entire gcc command line)
|
||||||
|
|
||||||
VU= controls the Xt-a make verbosity.
|
|
||||||
VU=0 output filename
|
|
||||||
VU=1 output filename and source file
|
|
||||||
VU=2 entire gcc command line
|
|
||||||
|
|
||||||
|
|
||||||
Note to distribution packagers
|
Note to distribution packagers
|
||||||
==============================
|
==============================
|
||||||
|
12
Makefile.am
12
Makefile.am
@@ -5,16 +5,16 @@ SUBDIRS = extensions
|
|||||||
|
|
||||||
man_MANS := xtables-addons.8
|
man_MANS := xtables-addons.8
|
||||||
|
|
||||||
xtables-addons.8: ${srcdir}/xtables-addons.8.in extensions/matches.man extensions/targets.man
|
.PHONY: FORCE
|
||||||
${am__verbose_GEN}sed -e '/@MATCHES@/ r extensions/matches.man' -e '/@TARGET@/ r extensions/targets.man' $< >$@;
|
FORCE:
|
||||||
|
|
||||||
extensions/%:
|
xtables-addons.8: FORCE
|
||||||
${MAKE} ${AM_MAKEFLAGS} -C $(@D) $(@F)
|
${MAKE} -f Makefile.mans all;
|
||||||
|
|
||||||
install-exec-local:
|
install-exec-hook:
|
||||||
depmod -a || :;
|
depmod -a || :;
|
||||||
|
|
||||||
config.status: extensions/GNUmakefile.in
|
config.status: Makefile.iptrules.in
|
||||||
|
|
||||||
.PHONY: tarball
|
.PHONY: tarball
|
||||||
tarball:
|
tarball:
|
||||||
|
29
Makefile.extra
Normal file
29
Makefile.extra
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
# AUTOMAKE
|
||||||
|
|
||||||
|
XA_SRCDIR = ${srcdir}
|
||||||
|
XA_TOPSRCDIR = ${top_srcdir}
|
||||||
|
XA_ABSTOPSRCDIR = ${abs_top_srcdir}
|
||||||
|
export XA_SRCDIR
|
||||||
|
export XA_TOPSRCDIR
|
||||||
|
export XA_ABSTOPSRCDIR
|
||||||
|
|
||||||
|
_mcall = -f ${top_builddir}/Makefile.iptrules
|
||||||
|
|
||||||
|
all-local: user-all-local
|
||||||
|
|
||||||
|
install-exec-local: user-install-local
|
||||||
|
|
||||||
|
clean-local: user-clean-local
|
||||||
|
|
||||||
|
user-all-local:
|
||||||
|
${MAKE} ${_mcall} all;
|
||||||
|
|
||||||
|
# Have no user-install-data-local ATM
|
||||||
|
user-install-local: user-install-exec-local
|
||||||
|
|
||||||
|
user-install-exec-local:
|
||||||
|
${MAKE} ${_mcall} install;
|
||||||
|
|
||||||
|
user-clean-local:
|
||||||
|
${MAKE} ${_mcall} clean;
|
59
Makefile.iptrules.in
Normal file
59
Makefile.iptrules.in
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
# MANUAL
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
xtlibdir = @xtlibdir@
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
CCLD = ${CC}
|
||||||
|
|
||||||
|
regular_CFLAGS = @regular_CFLAGS@
|
||||||
|
xtables_CFLAGS = @xtables_CFLAGS@
|
||||||
|
AM_CFLAGS = ${regular_CFLAGS} ${xtables_CFLAGS}
|
||||||
|
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
||||||
|
|
||||||
|
AM_DEFAULT_VERBOSITY = 0
|
||||||
|
am__v_CC_0 = @echo " CC " $@;
|
||||||
|
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||||
|
am__v_GEN_0 = @echo " GEN " $@;
|
||||||
|
am__v_SILENT_0 = @
|
||||||
|
am__v_CC_ = ${am__v_CC_${AM_DEFAULT_VERBOSITY}}
|
||||||
|
am__v_CCLD_ = ${am__v_CCLD_${AM_DEFAULT_VERBOSITY}}
|
||||||
|
am__v_GEN_ = ${am__v_GEN_${AM_DEFAULT_VERBOSITY}}
|
||||||
|
am__v_SILENT_ = ${am__v_SILENT_${AM_DEFAULT_VERBOSITY}}
|
||||||
|
AM_V_CC = ${am__v_CC_${V}}
|
||||||
|
AM_V_CCLD = ${am__v_CCLD_${V}}
|
||||||
|
AM_V_GEN = ${am__v_GEN_${V}}
|
||||||
|
AM_V_silent = ${am__v_GEN_${V}}
|
||||||
|
|
||||||
|
include ${XA_TOPSRCDIR}/mconfig
|
||||||
|
-include ${XA_TOPSRCDIR}/mconfig.*
|
||||||
|
include ${XA_SRCDIR}/Mbuild
|
||||||
|
-include ${XA_SRCDIR}/Mbuild.*
|
||||||
|
|
||||||
|
targets := $(filter-out %/,${obj-m})
|
||||||
|
subdirs_list := $(filter %/,${obj-m})
|
||||||
|
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
.PHONY: all install clean
|
||||||
|
|
||||||
|
all: ${targets}
|
||||||
|
@for i in ${subdirs_list}; do ${MAKE} -C $$i; done;
|
||||||
|
|
||||||
|
install: ${targets}
|
||||||
|
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@; done;
|
||||||
|
install -dm0755 "${DESTDIR}/${xtlibdir}";
|
||||||
|
install -pm0755 $^ "${DESTDIR}/${xtlibdir}";
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@for i in ${subdirs_list}; do ${MAKE} -C $$i $@; done;
|
||||||
|
rm -f *.oo *.so;
|
||||||
|
|
||||||
|
lib%.so: lib%.oo
|
||||||
|
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
|
||||||
|
|
||||||
|
%.oo: ${XA_SRCDIR}/%.c
|
||||||
|
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
40
Makefile.mans.in
Normal file
40
Makefile.mans.in
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
# MANUAL
|
||||||
|
|
||||||
|
srcdir := @srcdir@
|
||||||
|
|
||||||
|
wcman_matches := $(shell find "${srcdir}" -name 'libxt_[a-z]*.man')
|
||||||
|
wcman_targets := $(shell find "${srcdir}" -name 'libxt_[A-Z]*.man')
|
||||||
|
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
|
||||||
|
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
|
||||||
|
|
||||||
|
.PHONY: FORCE
|
||||||
|
|
||||||
|
FORCE:
|
||||||
|
|
||||||
|
.manpages.lst: FORCE
|
||||||
|
@echo "${wlist_targets} ${wlist_matches}" >$@.tmp; \
|
||||||
|
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
||||||
|
rm -f $@.tmp;
|
||||||
|
|
||||||
|
man_run = \
|
||||||
|
${AM_V_GEN}for ext in $(1); do \
|
||||||
|
name="$${ext%.man}"; \
|
||||||
|
name="$${name\#\#*/libxt_}"; \
|
||||||
|
if [ -f "$$ext" ]; then \
|
||||||
|
echo ".SS $$name"; \
|
||||||
|
cat "$$ext"; \
|
||||||
|
continue; \
|
||||||
|
fi; \
|
||||||
|
done >$@;
|
||||||
|
|
||||||
|
all: xtables-addons.8
|
||||||
|
|
||||||
|
xtables-addons.8: ${srcdir}/xtables-addons.8.in matches.man targets.man
|
||||||
|
${AM_V_GEN}sed -e '/@MATCHES@/ r matches.man' -e '/@TARGET@/ r targets.man' $< >$@;
|
||||||
|
|
||||||
|
matches.man: .manpages.lst ${wcman_matches}
|
||||||
|
$(call man_run,${wlist_matches})
|
||||||
|
|
||||||
|
targets.man: .manpages.lst ${wcman_targets}
|
||||||
|
$(call man_run,${wlist_targets})
|
24
configure.ac
24
configure.ac
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
AC_INIT([xtables-addons], [1.17])
|
AC_INIT([xtables-addons], [1.19])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
AM_INIT_AUTOMAKE([1.10 -Wall foreign subdir-objects])
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
AC_DISABLE_STATIC
|
AC_DISABLE_STATIC
|
||||||
@@ -14,10 +14,7 @@ AC_ARG_WITH([kbuild],
|
|||||||
AS_HELP_STRING([--with-kbuild=PATH],
|
AS_HELP_STRING([--with-kbuild=PATH],
|
||||||
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
|
[Path to kernel build directory [[/lib/modules/CURRENT/build]]]),
|
||||||
[kbuilddir="$withval"])
|
[kbuilddir="$withval"])
|
||||||
AC_ARG_WITH([ksource],
|
AC_ARG_WITH([ksource],,[ksourcedir="$withval"])
|
||||||
AS_HELP_STRING([--with-ksource=PATH],
|
|
||||||
[Path to kernel source directory [[/lib/modules/CURRENT/source]]]),
|
|
||||||
[ksourcedir="$withval"])
|
|
||||||
AC_ARG_WITH([xtables],
|
AC_ARG_WITH([xtables],
|
||||||
AS_HELP_STRING([--with-xtables=PATH],
|
AS_HELP_STRING([--with-xtables=PATH],
|
||||||
[Path to the Xtables includes [[none]]]),
|
[Path to the Xtables includes [[none]]]),
|
||||||
@@ -79,13 +76,16 @@ krel="${krel#*.}";
|
|||||||
kminor="${krel%%.*}";
|
kminor="${krel%%.*}";
|
||||||
krel="${krel#*.}";
|
krel="${krel#*.}";
|
||||||
kmicro="${krel%%.*}";
|
kmicro="${krel%%.*}";
|
||||||
krel="${krel#*.}";
|
if test "$kmicro" = "$krel"; then
|
||||||
kstable="${krel%%.*}";
|
|
||||||
if test -z "$kstable"; then
|
|
||||||
kstable=0;
|
kstable=0;
|
||||||
|
else
|
||||||
|
kstable="${krel#*.}";
|
||||||
|
if test -z "$kstable"; then
|
||||||
|
kstable=0;
|
||||||
|
fi;
|
||||||
fi;
|
fi;
|
||||||
echo "Found kernel version $kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
echo "Found kernel version $kmajor.$kminor.$kmicro.$kstable in $kbuilddir";
|
||||||
if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 30; then
|
if test "$kmajor" -gt 2 -o "$kminor" -gt 6 -o "$kmicro" -gt 32; then
|
||||||
echo "WARNING: You are trying a newer kernel. Results may vary. :-)";
|
echo "WARNING: You are trying a newer kernel. Results may vary. :-)";
|
||||||
elif test \( "$kmajor" -lt 2 -o "$kminor" -lt 6 -o "$kmicro" -lt 17 \) -o \
|
elif test \( "$kmajor" -lt 2 -o "$kminor" -lt 6 -o "$kmicro" -lt 17 \) -o \
|
||||||
\( "$kmajor" -eq 2 -a "$kminor" -eq 6 -a "$kmicro" -eq 18 -a \
|
\( "$kmajor" -eq 2 -a "$kminor" -eq 6 -a "$kmicro" -eq 18 -a \
|
||||||
@@ -100,5 +100,7 @@ AC_SUBST([kinclude_CFLAGS])
|
|||||||
AC_SUBST([kbuilddir])
|
AC_SUBST([kbuilddir])
|
||||||
AC_SUBST([ksourcedir])
|
AC_SUBST([ksourcedir])
|
||||||
AC_SUBST([xtlibdir])
|
AC_SUBST([xtlibdir])
|
||||||
AC_CONFIG_FILES([Makefile extensions/GNUmakefile extensions/ipset/GNUmakefile])
|
AC_CONFIG_FILES([Makefile Makefile.iptrules Makefile.mans
|
||||||
|
extensions/Makefile extensions/ACCOUNT/Makefile
|
||||||
|
extensions/ipset/Makefile extensions/pknock/Makefile])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
4
doc/README.psd
Normal file
4
doc/README.psd
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
PSD (Portscan Detection) External extensions for Xtables-addons
|
||||||
|
|
||||||
|
Example:
|
||||||
|
iptables -A INPUT -m psd --psd-weight-threshold 21 --psd-delay-threshold 300 --psd-lo-ports-weight 1 --psd-hi-ports-weight 10 -j LOG --log-prefix "PSD: "
|
@@ -1,4 +1,42 @@
|
|||||||
|
|
||||||
|
HEAD
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.19 (October 12 2009)
|
||||||
|
=====================================
|
||||||
|
- build: compile fixes for 2.6.31-rt
|
||||||
|
- build: support for Linux 2.6.32
|
||||||
|
- ipp2p: try to address underflows
|
||||||
|
- psd: avoid potential crash when dealing with non-linear skbs
|
||||||
|
- merge xt_ACCOUNT userspace utilities
|
||||||
|
- added reworked xt_pknock module
|
||||||
|
Changes from pknock v0.5:
|
||||||
|
- pknock: "strict" and "checkip" flags were not displayed in `iptables -L`
|
||||||
|
- pknock: the GC expire time's lower bound is now the default gc time
|
||||||
|
(65000 msec) to avoid rendering anti-spoof protection in SPA mode useless
|
||||||
|
- pknock: avoid crash on memory allocation failure and fix memleak
|
||||||
|
- pknock: avoid fillup of peer table during DDoS
|
||||||
|
- pknock: automatic closing of ports
|
||||||
|
- pknock: make non-zero time mandatory for TCP mode
|
||||||
|
- pknock: display only pknock mode and state relevant information in procfs
|
||||||
|
- pknock: check interknock time only for !ST_ALLOWED peers
|
||||||
|
- pknock: preserve time/autoclose values for rules added in
|
||||||
|
reverse/arbitrary order
|
||||||
|
- pknock: add a manpage
|
||||||
|
|
||||||
|
|
||||||
|
Xtables-addons 1.18 (September 09 2009)
|
||||||
|
=======================================
|
||||||
|
- build: support for Linux 2.6.31
|
||||||
|
- ipset: fast forward to v3.2
|
||||||
|
- quota2: support anonymous counters
|
||||||
|
- quota2: reduce memory footprint for anonymous counters
|
||||||
|
- quota2: extend locked period during cleanup (locking bugfix)
|
||||||
|
- quota2: use strtoull instead of strtoul
|
||||||
|
- merged xt_ACCOUNT module
|
||||||
|
- merged xt_psd module
|
||||||
|
|
||||||
|
|
||||||
Xtables-addons 1.17 (June 16 2009)
|
Xtables-addons 1.17 (June 16 2009)
|
||||||
==================================
|
==================================
|
||||||
|
7
extensions/.gitignore
vendored
7
extensions/.gitignore
vendored
@@ -8,8 +8,5 @@ Module.symvers
|
|||||||
Modules.symvers
|
Modules.symvers
|
||||||
modules.order
|
modules.order
|
||||||
|
|
||||||
/*.so
|
*.so
|
||||||
/*.oo
|
*.oo
|
||||||
/matches.man
|
|
||||||
/targets.man
|
|
||||||
/.manpages.lst
|
|
||||||
|
1
extensions/ACCOUNT/.gitignore
vendored
Normal file
1
extensions/ACCOUNT/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/iptaccount
|
5
extensions/ACCOUNT/Kbuild
Normal file
5
extensions/ACCOUNT/Kbuild
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
EXTRA_CFLAGS = -I${src}/..
|
||||||
|
|
||||||
|
obj-m += xt_ACCOUNT.o
|
8
extensions/ACCOUNT/Makefile.am
Normal file
8
extensions/ACCOUNT/Makefile.am
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
include ../../Makefile.extra
|
||||||
|
|
||||||
|
sbin_PROGRAMS = iptaccount
|
||||||
|
iptaccount_LDADD = libxt_ACCOUNT_cl.la
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libxt_ACCOUNT_cl.la
|
3
extensions/ACCOUNT/Mbuild
Normal file
3
extensions/ACCOUNT/Mbuild
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
obj-${build_ACCOUNT} += libxt_ACCOUNT.so
|
223
extensions/ACCOUNT/iptaccount.c
Normal file
223
extensions/ACCOUNT/iptaccount.c
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2004-2006 by Intra2net AG *
|
||||||
|
* opensource@intra2net.com *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Lesser General Public License *
|
||||||
|
* version 2.1 as published by the Free Software Foundation; *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <libxt_ACCOUNT_cl.h>
|
||||||
|
|
||||||
|
bool exit_now;
|
||||||
|
static void sig_term(int signr)
|
||||||
|
{
|
||||||
|
signal(SIGINT, SIG_IGN);
|
||||||
|
signal(SIGQUIT, SIG_IGN);
|
||||||
|
signal(SIGTERM, SIG_IGN);
|
||||||
|
|
||||||
|
exit_now = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *addr_to_dotted(unsigned int);
|
||||||
|
char *addr_to_dotted(unsigned int addr)
|
||||||
|
{
|
||||||
|
static char buf[17];
|
||||||
|
const unsigned char *bytep;
|
||||||
|
|
||||||
|
bytep = (const unsigned char *)&addr;
|
||||||
|
snprintf(buf, 16, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]);
|
||||||
|
buf[16] = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_usage(void)
|
||||||
|
{
|
||||||
|
printf("Unknown command line option. Try: [-u] [-h] [-a] [-f] [-c] [-s] [-l name]\n");
|
||||||
|
printf("[-u] show kernel handle usage\n");
|
||||||
|
printf("[-h] free all kernel handles (experts only!)\n\n");
|
||||||
|
printf("[-a] list all table names\n");
|
||||||
|
printf("[-l name] show data in table <name>\n");
|
||||||
|
printf("[-f] flush data after showing\n");
|
||||||
|
printf("[-c] loop every second (abort with CTRL+C)\n");
|
||||||
|
printf("[-s] CSV output (for spreadsheet import)\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct ipt_ACCOUNT_context ctx;
|
||||||
|
struct ipt_acc_handle_ip *entry;
|
||||||
|
int i;
|
||||||
|
char optchar;
|
||||||
|
bool doHandleUsage = false, doHandleFree = false, doTableNames = false;
|
||||||
|
bool doFlush = false, doContinue = false, doCSV = false;
|
||||||
|
|
||||||
|
char *table_name = NULL;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
printf("\nlibxt_ACCOUNT_cl userspace accounting tool v%s\n\n",
|
||||||
|
LIBXT_ACCOUNT_VERSION);
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
show_usage();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((optchar = getopt(argc, argv, "uhacfsl:")) != -1)
|
||||||
|
{
|
||||||
|
switch (optchar)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
doHandleUsage = true;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
doHandleFree = true;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
doTableNames = true;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
doFlush = true;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
doContinue = true;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
doCSV = true;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
table_name = strdup(optarg);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
default:
|
||||||
|
show_usage();
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// install exit handler
|
||||||
|
if (signal(SIGTERM, sig_term) == SIG_ERR)
|
||||||
|
{
|
||||||
|
printf("can't install signal handler for SIGTERM\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if (signal(SIGINT, sig_term) == SIG_ERR)
|
||||||
|
{
|
||||||
|
printf("can't install signal handler for SIGINT\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if (signal(SIGQUIT, sig_term) == SIG_ERR)
|
||||||
|
{
|
||||||
|
printf("can't install signal handler for SIGQUIT\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipt_ACCOUNT_init(&ctx))
|
||||||
|
{
|
||||||
|
printf("Init failed: %s\n", ctx.error_str);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get handle usage?
|
||||||
|
if (doHandleUsage)
|
||||||
|
{
|
||||||
|
int rtn = ipt_ACCOUNT_get_handle_usage(&ctx);
|
||||||
|
if (rtn < 0)
|
||||||
|
{
|
||||||
|
printf("get_handle_usage failed: %s\n", ctx.error_str);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Current kernel handle usage: %d\n", ctx.handle.itemcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doHandleFree)
|
||||||
|
{
|
||||||
|
int rtn = ipt_ACCOUNT_free_all_handles(&ctx);
|
||||||
|
if (rtn < 0)
|
||||||
|
{
|
||||||
|
printf("handle_free_all failed: %s\n", ctx.error_str);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Freed all handles in kernel space\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doTableNames)
|
||||||
|
{
|
||||||
|
int rtn = ipt_ACCOUNT_get_table_names(&ctx);
|
||||||
|
if (rtn < 0)
|
||||||
|
{
|
||||||
|
printf("get_table_names failed: %s\n", ctx.error_str);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
while ((name = ipt_ACCOUNT_get_next_name(&ctx)) != 0)
|
||||||
|
printf("Found table: %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (table_name)
|
||||||
|
{
|
||||||
|
// Read out data
|
||||||
|
if (doCSV)
|
||||||
|
printf("IP;SRC packets;SRC bytes;DST packets;DST bytes\n");
|
||||||
|
else
|
||||||
|
printf("Showing table: %s\n", table_name);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (!exit_now)
|
||||||
|
{
|
||||||
|
// Get entries from table test
|
||||||
|
if (ipt_ACCOUNT_read_entries(&ctx, table_name, !doFlush))
|
||||||
|
{
|
||||||
|
printf("Read failed: %s\n", ctx.error_str);
|
||||||
|
ipt_ACCOUNT_deinit(&ctx);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doCSV)
|
||||||
|
printf("Run #%d - %u %s found\n", i, ctx.handle.itemcount,
|
||||||
|
ctx.handle.itemcount == 1 ? "item" : "items");
|
||||||
|
|
||||||
|
// Output and free entries
|
||||||
|
while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
|
||||||
|
{
|
||||||
|
if (doCSV)
|
||||||
|
printf("%s;%u;%u;%u;%u\n",
|
||||||
|
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
||||||
|
entry->dst_packets, entry->dst_bytes);
|
||||||
|
else
|
||||||
|
printf("IP: %s SRC packets: %u bytes: %u DST packets: %u bytes: %u\n",
|
||||||
|
addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes,
|
||||||
|
entry->dst_packets, entry->dst_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doContinue)
|
||||||
|
{
|
||||||
|
sleep(1);
|
||||||
|
i++;
|
||||||
|
} else
|
||||||
|
exit_now = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Finished.\n");
|
||||||
|
ipt_ACCOUNT_deinit(&ctx);
|
||||||
|
exit(0);
|
||||||
|
}
|
168
extensions/ACCOUNT/libxt_ACCOUNT.c
Normal file
168
extensions/ACCOUNT/libxt_ACCOUNT.c
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/* Shared library add-on to iptables to add ACCOUNT(ing) support.
|
||||||
|
Author: Intra2net AG <opensource@intra2net.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <xtables.h>
|
||||||
|
#include "xt_ACCOUNT.h"
|
||||||
|
|
||||||
|
static struct option account_tg_opts[] = {
|
||||||
|
{ .name = "addr", .has_arg = 1, .flag = 0, .val = 'a' },
|
||||||
|
{ .name = "tname", .has_arg = 1, .flag = 0, .val = 't' },
|
||||||
|
{ .name = 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Function which prints out usage message. */
|
||||||
|
static void account_tg_help(void)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"ACCOUNT target options:\n"
|
||||||
|
" --%s ip/netmask\t\tBase network IP and netmask used for this table\n"
|
||||||
|
" --%s name\t\t\tTable name for the userspace library\n",
|
||||||
|
account_tg_opts[0].name, account_tg_opts[1].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the target. */
|
||||||
|
static void
|
||||||
|
account_tg_init(struct xt_entry_target *t)
|
||||||
|
{
|
||||||
|
struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)t->data;
|
||||||
|
|
||||||
|
accountinfo->table_nr = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IPT_ACCOUNT_OPT_ADDR 0x01
|
||||||
|
#define IPT_ACCOUNT_OPT_TABLE 0x02
|
||||||
|
|
||||||
|
/* Function which parses command options; returns true if it
|
||||||
|
ate an option */
|
||||||
|
|
||||||
|
static int account_tg_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
|
const void *entry, struct xt_entry_target **target)
|
||||||
|
{
|
||||||
|
struct ipt_acc_info *accountinfo = (struct ipt_acc_info *)(*target)->data;
|
||||||
|
struct in_addr *addrs = NULL, mask;
|
||||||
|
unsigned int naddrs = 0;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'a':
|
||||||
|
if (*flags & IPT_ACCOUNT_OPT_ADDR)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "Can't specify --%s twice",
|
||||||
|
account_tg_opts[0].name);
|
||||||
|
|
||||||
|
if (xtables_check_inverse(optarg, &invert, NULL, 0))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "Unexpected `!' after --%s",
|
||||||
|
account_tg_opts[0].name);
|
||||||
|
|
||||||
|
xtables_ipparse_any(optarg, &addrs, &mask, &naddrs);
|
||||||
|
if (naddrs > 1)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "multiple IP addresses not allowed");
|
||||||
|
|
||||||
|
accountinfo->net_ip = addrs[0].s_addr;
|
||||||
|
accountinfo->net_mask = mask.s_addr;
|
||||||
|
|
||||||
|
*flags |= IPT_ACCOUNT_OPT_ADDR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
if (*flags & IPT_ACCOUNT_OPT_TABLE)
|
||||||
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
|
"Can't specify --%s twice",
|
||||||
|
account_tg_opts[1].name);
|
||||||
|
|
||||||
|
if (xtables_check_inverse(optarg, &invert, NULL, 0))
|
||||||
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
|
"Unexpected `!' after --%s",
|
||||||
|
account_tg_opts[1].name);
|
||||||
|
|
||||||
|
if (strlen(optarg) > ACCOUNT_TABLE_NAME_LEN - 1)
|
||||||
|
xtables_error(PARAMETER_PROBLEM,
|
||||||
|
"Maximum table name length %u for --%s",
|
||||||
|
ACCOUNT_TABLE_NAME_LEN - 1,
|
||||||
|
account_tg_opts[1].name);
|
||||||
|
|
||||||
|
strcpy(accountinfo->table_name, optarg);
|
||||||
|
*flags |= IPT_ACCOUNT_OPT_TABLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void account_tg_check(unsigned int flags)
|
||||||
|
{
|
||||||
|
if (!(flags & IPT_ACCOUNT_OPT_ADDR) || !(flags & IPT_ACCOUNT_OPT_TABLE))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "ACCOUNT: needs --%s and --%s",
|
||||||
|
account_tg_opts[0].name, account_tg_opts[1].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void account_tg_print_it(const void *ip,
|
||||||
|
const struct xt_entry_target *target, char do_prefix)
|
||||||
|
{
|
||||||
|
const struct ipt_acc_info *accountinfo
|
||||||
|
= (const struct ipt_acc_info *)target->data;
|
||||||
|
struct in_addr a;
|
||||||
|
|
||||||
|
if (!do_prefix)
|
||||||
|
printf("ACCOUNT ");
|
||||||
|
|
||||||
|
// Network information
|
||||||
|
if (do_prefix)
|
||||||
|
printf("--");
|
||||||
|
printf("%s ", account_tg_opts[0].name);
|
||||||
|
|
||||||
|
a.s_addr = accountinfo->net_ip;
|
||||||
|
printf("%s", xtables_ipaddr_to_numeric(&a));
|
||||||
|
a.s_addr = accountinfo->net_mask;
|
||||||
|
printf("%s", xtables_ipmask_to_numeric(&a));
|
||||||
|
|
||||||
|
printf(" ");
|
||||||
|
if (do_prefix)
|
||||||
|
printf("--");
|
||||||
|
|
||||||
|
printf("%s %s", account_tg_opts[1].name, accountinfo->table_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
account_tg_print(const void *ip,
|
||||||
|
const struct xt_entry_target *target,
|
||||||
|
int numeric)
|
||||||
|
{
|
||||||
|
account_tg_print_it(ip, target, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Saves the union ipt_targinfo in parsable form to stdout. */
|
||||||
|
static void
|
||||||
|
account_tg_save(const void *ip, const struct xt_entry_target *target)
|
||||||
|
{
|
||||||
|
account_tg_print_it(ip, target, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xtables_target account_tg_reg = {
|
||||||
|
.name = "ACCOUNT",
|
||||||
|
.family = AF_INET,
|
||||||
|
.version = XTABLES_VERSION,
|
||||||
|
.size = XT_ALIGN(sizeof(struct ipt_acc_info)),
|
||||||
|
.userspacesize = offsetof(struct ipt_acc_info, table_nr),
|
||||||
|
.help = account_tg_help,
|
||||||
|
.init = account_tg_init,
|
||||||
|
.parse = account_tg_parse,
|
||||||
|
.final_check = account_tg_check,
|
||||||
|
.print = account_tg_print,
|
||||||
|
.save = account_tg_save,
|
||||||
|
.extra_opts = account_tg_opts,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void account_tg_ldr(void)
|
||||||
|
{
|
||||||
|
xtables_register_target(&account_tg_reg);
|
||||||
|
}
|
72
extensions/ACCOUNT/libxt_ACCOUNT.man
Normal file
72
extensions/ACCOUNT/libxt_ACCOUNT.man
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
The ACCOUNT target is a high performance accounting system for large
|
||||||
|
local networks. It allows per-IP accounting in whole prefixes of IPv4
|
||||||
|
addresses with size of up to /8 without the need to add individual
|
||||||
|
accouting rule for each IP address.
|
||||||
|
.PP
|
||||||
|
The ACCOUNT is designed to be queried for data every second or at
|
||||||
|
least every ten seconds. It is written as kernel module to handle high
|
||||||
|
bandwidths without packet loss.
|
||||||
|
.PP
|
||||||
|
The largest possible subnet size is 24 bit, meaning for example 10.0.0.0/8
|
||||||
|
network. ACCOUNT uses fixed internal data structures
|
||||||
|
which speeds up the processing of each packet. Furthermore,
|
||||||
|
accounting data for one complete 192.168.1.X/24 network takes 4 KB of
|
||||||
|
memory. Memory for 16 or 24 bit networks is only allocated when
|
||||||
|
needed.
|
||||||
|
.PP
|
||||||
|
To optimize the kernel<->userspace data transfer a bit more, the
|
||||||
|
kernel module only transfers information about IPs, where the src/dst
|
||||||
|
packet counter is not 0. This saves precious kernel time.
|
||||||
|
.PP
|
||||||
|
There is no /proc interface as it would be too slow for continuous access.
|
||||||
|
The read-and-flush query operation is the fastest, as no internal data
|
||||||
|
snapshot needs to be created&copied for all data. Use the "read"
|
||||||
|
operation without flush only for debugging purposes!
|
||||||
|
.PP
|
||||||
|
Usage:
|
||||||
|
.PP
|
||||||
|
ACCOUNT takes two mandatory parameters:
|
||||||
|
.TP
|
||||||
|
\fB\-\-addr\fR \fInetwork\fP\fB/\fP\fInetmask\fR
|
||||||
|
where \fInetwork\fP\fB/\fP\fInetmask\fP is the subnet to account for, in CIDR syntax
|
||||||
|
.TP
|
||||||
|
\fB\-\-tname\fP \fINAME\fP
|
||||||
|
where \fINAME\fP is the name of the table where the accounting information
|
||||||
|
should be stored
|
||||||
|
.PP
|
||||||
|
The subnet 0.0.0.0/0 is a special case: all data are then stored in the src_bytes
|
||||||
|
and src_packets structure of slot "0". This is useful if you want
|
||||||
|
to account the overall traffic to/from your internet provider.
|
||||||
|
.PP
|
||||||
|
The data can be queried using the userspace libxt_ACCOUNT_cl library,
|
||||||
|
and by the reference implementation to show usage of this library,
|
||||||
|
the \fBiptaccount\fP(8) tool, which features following options:
|
||||||
|
.PP
|
||||||
|
[\fB\-u\fP] show kernel handle usage
|
||||||
|
.PP
|
||||||
|
[\fB\-h\fP] free all kernel handles (experts only!)
|
||||||
|
.PP
|
||||||
|
[\fB\-a\fP] list all table names
|
||||||
|
.PP
|
||||||
|
[\fB\-l\fP \fIname\fP] show data in table \fIname\fP
|
||||||
|
.PP
|
||||||
|
[\fB\-f\fP] flush data after showing
|
||||||
|
.PP
|
||||||
|
[\fB\-c\fP] loop every second (abort with CTRL+C)
|
||||||
|
.PP
|
||||||
|
Here is an example of use:
|
||||||
|
.PP
|
||||||
|
iptables \-A FORWARD \-j ACCOUNT \-\-addr 0.0.0.0/0 \-\-tname all_outgoing;
|
||||||
|
iptables \-A FORWARD \-j ACCOUNT \-\-addr 192.168.1.0/24 \-\-tname sales;
|
||||||
|
.PP
|
||||||
|
This creates two tables called "all_outgoing" and "sales" which can be
|
||||||
|
queried using the userspace library/iptaccount tool.
|
||||||
|
.PP
|
||||||
|
Note that this target is non-terminating \(em the packet destined to it
|
||||||
|
will continue traversing the chain in which it has been used.
|
||||||
|
.PP
|
||||||
|
Also note that once a table has been defined for specific CIDR address/netmask
|
||||||
|
block, it can be referenced multiple times using \-j ACCOUNT, provided
|
||||||
|
that both the original table name and address/netmask block are specified.
|
||||||
|
.PP
|
||||||
|
For more information go to http://www.intra2net.com/en/developer/ipt_ACCOUNT/
|
199
extensions/ACCOUNT/libxt_ACCOUNT_cl.c
Normal file
199
extensions/ACCOUNT/libxt_ACCOUNT_cl.c
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2004 by Intra2net AG *
|
||||||
|
* opensource@intra2net.com *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Lesser General Public License *
|
||||||
|
* version 2.1 as published by the Free Software Foundation; *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <linux/if.h>
|
||||||
|
|
||||||
|
#include <libxt_ACCOUNT_cl.h>
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
memset(ctx, 0, sizeof(struct ipt_ACCOUNT_context));
|
||||||
|
ctx->handle.handle_nr = -1;
|
||||||
|
|
||||||
|
ctx->sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||||
|
if (ctx->sockfd < 0) {
|
||||||
|
ctx->sockfd = -1;
|
||||||
|
ctx->error_str = "Can't open socket to kernel. "
|
||||||
|
"Permission denied or ipt_ACCOUNT module not loaded";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4096 bytes default buffer should save us from reallocations
|
||||||
|
// as it fits 200 concurrent active clients
|
||||||
|
if ((ctx->data = malloc(IPT_ACCOUNT_MIN_BUFSIZE)) == NULL) {
|
||||||
|
close(ctx->sockfd);
|
||||||
|
ctx->sockfd = -1;
|
||||||
|
ctx->error_str = "Out of memory for data buffer";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ctx->data_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
if (ctx->handle.handle_nr != -1) {
|
||||||
|
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
|
||||||
|
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||||
|
ctx->handle.handle_nr = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->handle.itemcount = 0;
|
||||||
|
ctx->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
free(ctx->data);
|
||||||
|
ctx->data = NULL;
|
||||||
|
|
||||||
|
ipt_ACCOUNT_free_entries(ctx);
|
||||||
|
|
||||||
|
close(ctx->sockfd);
|
||||||
|
ctx->sockfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
|
||||||
|
const char *table, char dont_flush)
|
||||||
|
{
|
||||||
|
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
|
||||||
|
unsigned int new_size;
|
||||||
|
int rtn;
|
||||||
|
|
||||||
|
strncpy(ctx->handle.name, table, ACCOUNT_TABLE_NAME_LEN-1);
|
||||||
|
|
||||||
|
// Get table information
|
||||||
|
if (!dont_flush)
|
||||||
|
rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||||
|
IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH, &ctx->handle, &s);
|
||||||
|
else
|
||||||
|
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_PREPARE_READ,
|
||||||
|
&ctx->handle, &s);
|
||||||
|
|
||||||
|
if (rtn < 0) {
|
||||||
|
ctx->error_str = "Can't get table information from kernel. "
|
||||||
|
"Does it exist?";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check data buffer size
|
||||||
|
ctx->pos = 0;
|
||||||
|
new_size = ctx->handle.itemcount * sizeof(struct ipt_acc_handle_ip);
|
||||||
|
// We want to prevent reallocations all the time
|
||||||
|
if (new_size < IPT_ACCOUNT_MIN_BUFSIZE)
|
||||||
|
new_size = IPT_ACCOUNT_MIN_BUFSIZE;
|
||||||
|
|
||||||
|
// Reallocate if it's too small or twice as big
|
||||||
|
if (ctx->data_size < new_size || ctx->data_size > new_size * 2) {
|
||||||
|
// Free old buffer
|
||||||
|
free(ctx->data);
|
||||||
|
ctx->data_size = 0;
|
||||||
|
|
||||||
|
if ((ctx->data = malloc(new_size)) == NULL) {
|
||||||
|
ctx->error_str = "Out of memory for data buffer";
|
||||||
|
ipt_ACCOUNT_free_entries(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->data_size = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy data from kernel
|
||||||
|
memcpy(ctx->data, &ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||||
|
rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_GET_DATA,
|
||||||
|
ctx->data, &ctx->data_size);
|
||||||
|
if (rtn < 0) {
|
||||||
|
ctx->error_str = "Can't get data from kernel. "
|
||||||
|
"Check /var/log/messages for details.";
|
||||||
|
ipt_ACCOUNT_free_entries(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free kernel handle but don't reset pos/itemcount
|
||||||
|
setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
|
||||||
|
&ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
|
||||||
|
ctx->handle.handle_nr = -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
struct ipt_acc_handle_ip *rtn;
|
||||||
|
|
||||||
|
// Empty or no more items left to return?
|
||||||
|
if (!ctx->handle.itemcount || ctx->pos >= ctx->handle.itemcount)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Get next entry
|
||||||
|
rtn = (struct ipt_acc_handle_ip *)(ctx->data + ctx->pos
|
||||||
|
* sizeof(struct ipt_acc_handle_ip));
|
||||||
|
ctx->pos++;
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
unsigned int s = sizeof(struct ipt_acc_handle_sockopt);
|
||||||
|
if (getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||||
|
IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE, &ctx->handle, &s) < 0) {
|
||||||
|
ctx->error_str = "Can't get handle usage information from kernel";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ctx->handle.handle_nr = -1;
|
||||||
|
|
||||||
|
return ctx->handle.itemcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
if (setsockopt(ctx->sockfd, IPPROTO_IP,
|
||||||
|
IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL, NULL, 0) < 0) {
|
||||||
|
ctx->error_str = "Can't free all kernel handles";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
int rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
|
||||||
|
IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES,
|
||||||
|
ctx->data, &ctx->data_size);
|
||||||
|
if (rtn < 0) {
|
||||||
|
ctx->error_str = "Can't get table names from kernel. Out of memory, "
|
||||||
|
"MINBUFISZE too small?";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ctx->pos = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx)
|
||||||
|
{
|
||||||
|
const char *rtn;
|
||||||
|
if (((char *)ctx->data)[ctx->pos] == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rtn = ctx->data + ctx->pos;
|
||||||
|
ctx->pos += strlen(ctx->data + ctx->pos) + 1;
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
60
extensions/ACCOUNT/libxt_ACCOUNT_cl.h
Normal file
60
extensions/ACCOUNT/libxt_ACCOUNT_cl.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2004 by Intra2net AG *
|
||||||
|
* opensource@intra2net.com *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Lesser General Public License *
|
||||||
|
* version 2.1 as published by the Free Software Foundation; *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _xt_ACCOUNT_cl_H
|
||||||
|
#define _xt_ACCOUNT_cl_H
|
||||||
|
|
||||||
|
#include <xt_ACCOUNT.h>
|
||||||
|
|
||||||
|
#define LIBXT_ACCOUNT_VERSION "1.3"
|
||||||
|
|
||||||
|
/* Don't set this below the size of struct ipt_account_handle_sockopt */
|
||||||
|
#define IPT_ACCOUNT_MIN_BUFSIZE 4096
|
||||||
|
|
||||||
|
struct ipt_ACCOUNT_context
|
||||||
|
{
|
||||||
|
int sockfd;
|
||||||
|
struct ipt_acc_handle_sockopt handle;
|
||||||
|
|
||||||
|
unsigned int data_size;
|
||||||
|
void *data;
|
||||||
|
unsigned int pos;
|
||||||
|
|
||||||
|
char *error_str;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
|
||||||
|
void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
|
||||||
|
const char *table, char dont_flush);
|
||||||
|
struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(
|
||||||
|
struct ipt_ACCOUNT_context *ctx);
|
||||||
|
|
||||||
|
/* ipt_ACCOUNT_free_entries is for internal use only function as this library
|
||||||
|
is constructed to be used in a loop -> Don't allocate memory all the time.
|
||||||
|
The data buffer is freed on deinit() */
|
||||||
|
|
||||||
|
int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
13
extensions/ACCOUNT/xt_ACCOUNT.Kconfig
Normal file
13
extensions/ACCOUNT/xt_ACCOUNT.Kconfig
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
config NETFILTER_XT_TARGET_ACCOUNT
|
||||||
|
tristate "ACCOUNT target support"
|
||||||
|
depends on NETFILTER_XTABLES
|
||||||
|
---help---
|
||||||
|
This module implements an ACCOUNT target
|
||||||
|
|
||||||
|
The ACCOUNT target is a high performance accounting system for large
|
||||||
|
local networks. It allows per-IP accounting in whole prefixes of IPv4
|
||||||
|
addresses with size of up to /8 without the need to add individual
|
||||||
|
accouting rule for each IP address.
|
||||||
|
|
||||||
|
For more information go to:
|
||||||
|
http://www.intra2net.com/de/produkte/opensource/ipt_account/
|
1104
extensions/ACCOUNT/xt_ACCOUNT.c
Normal file
1104
extensions/ACCOUNT/xt_ACCOUNT.c
Normal file
File diff suppressed because it is too large
Load Diff
118
extensions/ACCOUNT/xt_ACCOUNT.h
Normal file
118
extensions/ACCOUNT/xt_ACCOUNT.h
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2004-2006 by Intra2net AG *
|
||||||
|
* opensource@intra2net.com *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License *
|
||||||
|
* version 2 as published by the Free Software Foundation; *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _IPT_ACCOUNT_H
|
||||||
|
#define _IPT_ACCOUNT_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Socket option interface shared between kernel (xt_ACCOUNT) and userspace
|
||||||
|
* library (libxt_ACCOUNT_cl). Hopefully we are unique at least within our
|
||||||
|
* kernel & xtables-addons space.
|
||||||
|
*/
|
||||||
|
#define SO_ACCOUNT_BASE_CTL 90
|
||||||
|
|
||||||
|
#define IPT_SO_SET_ACCOUNT_HANDLE_FREE (SO_ACCOUNT_BASE_CTL + 1)
|
||||||
|
#define IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL (SO_ACCOUNT_BASE_CTL + 2)
|
||||||
|
#define IPT_SO_SET_ACCOUNT_MAX IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL
|
||||||
|
|
||||||
|
#define IPT_SO_GET_ACCOUNT_PREPARE_READ (SO_ACCOUNT_BASE_CTL + 4)
|
||||||
|
#define IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH (SO_ACCOUNT_BASE_CTL + 5)
|
||||||
|
#define IPT_SO_GET_ACCOUNT_GET_DATA (SO_ACCOUNT_BASE_CTL + 6)
|
||||||
|
#define IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE (SO_ACCOUNT_BASE_CTL + 7)
|
||||||
|
#define IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES (SO_ACCOUNT_BASE_CTL + 8)
|
||||||
|
#define IPT_SO_GET_ACCOUNT_MAX IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES
|
||||||
|
|
||||||
|
#define ACCOUNT_MAX_TABLES 128
|
||||||
|
#define ACCOUNT_TABLE_NAME_LEN 32
|
||||||
|
#define ACCOUNT_MAX_HANDLES 10
|
||||||
|
|
||||||
|
/* Structure for the userspace part of ipt_ACCOUNT */
|
||||||
|
struct ipt_acc_info {
|
||||||
|
uint32_t net_ip;
|
||||||
|
uint32_t net_mask;
|
||||||
|
char table_name[ACCOUNT_TABLE_NAME_LEN];
|
||||||
|
int32_t table_nr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Internal table structure, generated by check_entry() */
|
||||||
|
struct ipt_acc_table {
|
||||||
|
char name[ACCOUNT_TABLE_NAME_LEN]; /* name of the table */
|
||||||
|
uint32_t ip; /* base IP of network */
|
||||||
|
uint32_t netmask; /* netmask of the network */
|
||||||
|
unsigned char depth; /* size of network:
|
||||||
|
0: 8 bit, 1: 16bit, 2: 24 bit */
|
||||||
|
uint32_t refcount; /* refcount of this table.
|
||||||
|
if zero, destroy it */
|
||||||
|
uint32_t itemcount; /* number of IPs in this table */
|
||||||
|
void *data; /* pointer to the actual data,
|
||||||
|
depending on netmask */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Internal handle structure */
|
||||||
|
struct ipt_acc_handle {
|
||||||
|
uint32_t ip; /* base IP of network. Used for
|
||||||
|
caculating the final IP during
|
||||||
|
get_data() */
|
||||||
|
unsigned char depth; /* size of network. See above for
|
||||||
|
details */
|
||||||
|
uint32_t itemcount; /* number of IPs in this table */
|
||||||
|
void *data; /* pointer to the actual data,
|
||||||
|
depending on size */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Handle structure for communication with the userspace library */
|
||||||
|
struct ipt_acc_handle_sockopt {
|
||||||
|
uint32_t handle_nr; /* Used for HANDLE_FREE */
|
||||||
|
char name[ACCOUNT_TABLE_NAME_LEN]; /* Used for HANDLE_PREPARE_READ/
|
||||||
|
HANDLE_READ_FLUSH */
|
||||||
|
uint32_t itemcount; /* Used for HANDLE_PREPARE_READ/
|
||||||
|
HANDLE_READ_FLUSH */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Used for every IP entry
|
||||||
|
Size is 16 bytes so that 256 (class C network) * 16
|
||||||
|
fits in one kernel (zero) page */
|
||||||
|
struct ipt_acc_ip {
|
||||||
|
uint32_t src_packets;
|
||||||
|
uint32_t src_bytes;
|
||||||
|
uint32_t dst_packets;
|
||||||
|
uint32_t dst_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used for every IP when returning data
|
||||||
|
*/
|
||||||
|
struct ipt_acc_handle_ip {
|
||||||
|
uint32_t ip;
|
||||||
|
uint32_t src_packets;
|
||||||
|
uint32_t src_bytes;
|
||||||
|
uint32_t dst_packets;
|
||||||
|
uint32_t dst_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
The IPs are organized as an array so that direct slot
|
||||||
|
calculations are possible.
|
||||||
|
Only 8 bit networks are preallocated, 16/24 bit networks
|
||||||
|
allocate their slots when needed -> very efficent.
|
||||||
|
*/
|
||||||
|
struct ipt_acc_mask_24 {
|
||||||
|
struct ipt_acc_ip ip[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipt_acc_mask_16 {
|
||||||
|
struct ipt_acc_mask_24 *mask_24[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipt_acc_mask_8 {
|
||||||
|
struct ipt_acc_mask_16 *mask_16[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _IPT_ACCOUNT_H */
|
@@ -1,141 +0,0 @@
|
|||||||
# -*- Makefile -*-
|
|
||||||
|
|
||||||
top_srcdir := @top_srcdir@
|
|
||||||
srcdir := @srcdir@
|
|
||||||
abstop_srcdir := $(shell readlink -f ${top_srcdir})
|
|
||||||
abssrcdir := $(shell readlink -f ${srcdir})
|
|
||||||
|
|
||||||
ifeq (${abstop_srcdir},)
|
|
||||||
$(error Path resolution of ${top_srcdir} failed)
|
|
||||||
endif
|
|
||||||
ifeq (${abssrcdir},)
|
|
||||||
$(error Path resolution of ${srcdir} failed)
|
|
||||||
endif
|
|
||||||
|
|
||||||
prefix := @prefix@
|
|
||||||
exec_prefix := @exec_prefix@
|
|
||||||
libdir := @libdir@
|
|
||||||
libexecdir := @libexecdir@
|
|
||||||
xtlibdir := @xtlibdir@
|
|
||||||
kbuilddir := @kbuilddir@
|
|
||||||
|
|
||||||
CC := @CC@
|
|
||||||
CCLD := ${CC}
|
|
||||||
CFLAGS := @CFLAGS@
|
|
||||||
LDFLAGS := @LDFLAGS@
|
|
||||||
regular_CFLAGS := @regular_CFLAGS@
|
|
||||||
kinclude_CFLAGS := @kinclude_CFLAGS@
|
|
||||||
xtables_CFLAGS := @xtables_CFLAGS@
|
|
||||||
|
|
||||||
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS}
|
|
||||||
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
|
||||||
|
|
||||||
VU := 0
|
|
||||||
am__v_CC_0 = @echo " CC " $@;
|
|
||||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
|
||||||
am__v_GEN_0 = @echo " GEN " $@;
|
|
||||||
am__v_SILENT_0 = @
|
|
||||||
AM_V_CC = ${am__v_CC_${VU}}
|
|
||||||
AM_V_CCLD = ${am__v_CCLD_${VU}}
|
|
||||||
AM_V_GEN = ${am__v_GEN_${VU}}
|
|
||||||
AM_V_silent = ${am__v_GEN_${VU}}
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Wildcard module list
|
|
||||||
#
|
|
||||||
include ${top_srcdir}/mconfig
|
|
||||||
-include ${top_srcdir}/mconfig.*
|
|
||||||
include ${srcdir}/Mbuild
|
|
||||||
-include ${srcdir}/Mbuild.*
|
|
||||||
-include ${srcdir}/*.Mbuild
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Building blocks
|
|
||||||
#
|
|
||||||
targets := $(filter-out %/,${obj-m})
|
|
||||||
targets_install := ${targets}
|
|
||||||
subdirs_list := $(filter %/,${obj-m})
|
|
||||||
|
|
||||||
.SECONDARY:
|
|
||||||
|
|
||||||
.PHONY: all install clean distclean FORCE
|
|
||||||
|
|
||||||
all: subdirs modules user matches.man targets.man
|
|
||||||
|
|
||||||
subdirs:
|
|
||||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i; done;
|
|
||||||
|
|
||||||
subdirs-install:
|
|
||||||
@for i in ${subdirs_list}; do ${MAKE} -C $$i install; done;
|
|
||||||
|
|
||||||
user: ${targets}
|
|
||||||
|
|
||||||
install: modules_install subdirs-install ${targets_install}
|
|
||||||
@mkdir -p "${DESTDIR}${xtlibdir}";
|
|
||||||
install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/";
|
|
||||||
|
|
||||||
clean: clean_modules
|
|
||||||
@for i in ${subdirs_list}; do make -C $$i clean; done;
|
|
||||||
rm -f *.oo *.so;
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
rm -f .*.d .manpages.lst;
|
|
||||||
|
|
||||||
-include .*.d
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Call out to kbuild
|
|
||||||
#
|
|
||||||
.PHONY: modules modules_install clean_modules
|
|
||||||
|
|
||||||
modules:
|
|
||||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} modules; fi;
|
|
||||||
|
|
||||||
modules_install:
|
|
||||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} INSTALL_MOD_PATH=${DESTDIR} modules_install; fi;
|
|
||||||
|
|
||||||
clean_modules:
|
|
||||||
${AM_V_silent}if [ -n "${kbuilddir}" ]; then make -C ${kbuilddir} M=${abssrcdir} XA_TOPSRCDIR=${abstop_srcdir} clean; fi;
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Shared libraries
|
|
||||||
#
|
|
||||||
lib%.so: lib%.oo
|
|
||||||
${AM_V_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
|
|
||||||
|
|
||||||
lib%.oo: ${srcdir}/lib%.c
|
|
||||||
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Manpages
|
|
||||||
#
|
|
||||||
wcman_matches := $(wildcard ${srcdir}/libxt_[a-z]*.man)
|
|
||||||
wcman_targets := $(wildcard ${srcdir}/libxt_[A-Z]*.man)
|
|
||||||
wlist_matches := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_matches})
|
|
||||||
wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
|
|
||||||
|
|
||||||
.manpages.lst: FORCE
|
|
||||||
@echo "${wlist_targets} ${wlist_matches}" >$@.tmp; \
|
|
||||||
cmp -s $@ $@.tmp || mv $@.tmp $@; \
|
|
||||||
rm -f $@.tmp;
|
|
||||||
|
|
||||||
man_run = \
|
|
||||||
${AM_V_GEN}for ext in $(1); do \
|
|
||||||
f="${srcdir}/libxt_$$ext.man"; \
|
|
||||||
if [ -f "$$f" ]; then \
|
|
||||||
echo ".SS $$ext"; \
|
|
||||||
cat "$$f"; \
|
|
||||||
continue; \
|
|
||||||
fi; \
|
|
||||||
done >$@;
|
|
||||||
|
|
||||||
matches.man: .manpages.lst ${wcman_matches}
|
|
||||||
$(call man_run,${wlist_matches})
|
|
||||||
|
|
||||||
targets.man: .manpages.lst ${wcman_targets}
|
|
||||||
$(call man_run,${wlist_targets})
|
|
@@ -1,10 +1,11 @@
|
|||||||
# -*- Makefile -*-
|
# -*- Makefile -*-
|
||||||
|
|
||||||
include ${XA_TOPSRCDIR}/mconfig
|
include ${XA_ABSTOPSRCDIR}/mconfig
|
||||||
-include ${XA_TOPSRCDIR}/mconfig.*
|
-include ${XA_ABSTOPSRCDIR}/mconfig.*
|
||||||
|
|
||||||
obj-m += compat_xtables.o
|
obj-m += compat_xtables.o
|
||||||
|
|
||||||
|
obj-${build_ACCOUNT} += ACCOUNT/
|
||||||
obj-${build_CHAOS} += xt_CHAOS.o
|
obj-${build_CHAOS} += xt_CHAOS.o
|
||||||
obj-${build_DELUDE} += xt_DELUDE.o
|
obj-${build_DELUDE} += xt_DELUDE.o
|
||||||
obj-${build_DHCPMAC} += xt_DHCPMAC.o
|
obj-${build_DHCPMAC} += xt_DHCPMAC.o
|
||||||
@@ -25,6 +26,8 @@ obj-${build_ipset} += ipset/
|
|||||||
obj-${build_ipv4options} += xt_ipv4options.o
|
obj-${build_ipv4options} += xt_ipv4options.o
|
||||||
obj-${build_length2} += xt_length2.o
|
obj-${build_length2} += xt_length2.o
|
||||||
obj-${build_lscan} += xt_lscan.o
|
obj-${build_lscan} += xt_lscan.o
|
||||||
|
obj-${build_pknock} += pknock/
|
||||||
|
obj-${build_psd} += xt_psd.o
|
||||||
obj-${build_quota2} += xt_quota2.o
|
obj-${build_quota2} += xt_quota2.o
|
||||||
|
|
||||||
-include ${M}/*.Kbuild
|
-include ${M}/*.Kbuild
|
||||||
|
24
extensions/Makefile.am
Normal file
24
extensions/Makefile.am
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
# AUTOMAKE
|
||||||
|
|
||||||
|
# Not having Kbuild in Makefile.extra because it will already recurse
|
||||||
|
.PHONY: modules modules_install clean_modules
|
||||||
|
|
||||||
|
_kcall = -C ${kbuilddir} M=${abs_srcdir}
|
||||||
|
|
||||||
|
modules:
|
||||||
|
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} modules; fi;
|
||||||
|
|
||||||
|
modules_install:
|
||||||
|
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} INSTALL_MOD_PATH=${DESTDIR} ext-mod-dir='$${INSTALL_MOD_DIR}' modules_install; fi;
|
||||||
|
|
||||||
|
clean_modules:
|
||||||
|
${AM_V_silent}if [ -n "${kbuilddir}" ]; then ${MAKE} ${_kcall} clean; fi;
|
||||||
|
|
||||||
|
all-local: modules
|
||||||
|
|
||||||
|
install-exec-local: modules_install
|
||||||
|
|
||||||
|
clean-local: clean_modules
|
||||||
|
|
||||||
|
include ../Makefile.extra
|
@@ -1,3 +1,6 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
obj-${build_ACCOUNT} += ACCOUNT/
|
||||||
obj-${build_CHAOS} += libxt_CHAOS.so
|
obj-${build_CHAOS} += libxt_CHAOS.so
|
||||||
obj-${build_DELUDE} += libxt_DELUDE.so
|
obj-${build_DELUDE} += libxt_DELUDE.so
|
||||||
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
|
obj-${build_DHCPMAC} += libxt_DHCPMAC.so libxt_dhcpmac.so
|
||||||
@@ -18,4 +21,6 @@ obj-${build_ipset} += ipset/
|
|||||||
obj-${build_ipv4options} += libxt_ipv4options.so
|
obj-${build_ipv4options} += libxt_ipv4options.so
|
||||||
obj-${build_length2} += libxt_length2.so
|
obj-${build_length2} += libxt_length2.so
|
||||||
obj-${build_lscan} += libxt_lscan.so
|
obj-${build_lscan} += libxt_lscan.so
|
||||||
|
obj-${build_pknock} += pknock/
|
||||||
|
obj-${build_psd} += libxt_psd.so
|
||||||
obj-${build_quota2} += libxt_quota2.so
|
obj-${build_quota2} += libxt_quota2.so
|
||||||
|
@@ -4,6 +4,23 @@
|
|||||||
struct tcphdr;
|
struct tcphdr;
|
||||||
struct udphdr;
|
struct udphdr;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 30)
|
||||||
|
static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
|
||||||
|
{
|
||||||
|
skb->dst = dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return skb->dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct rtable *skb_rtable(const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
return (void *)skb->dst;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19)
|
||||||
# define skb_ifindex(skb) \
|
# define skb_ifindex(skb) \
|
||||||
(((skb)->input_dev != NULL) ? (skb)->input_dev->ifindex : 0)
|
(((skb)->input_dev != NULL) ? (skb)->input_dev->ifindex : 0)
|
||||||
|
2
extensions/ipset/.gitignore
vendored
2
extensions/ipset/.gitignore
vendored
@@ -1,3 +1 @@
|
|||||||
*.oo
|
|
||||||
*.so
|
|
||||||
/ipset
|
/ipset
|
||||||
|
@@ -1,85 +0,0 @@
|
|||||||
# -*- Makefile -*-
|
|
||||||
|
|
||||||
top_srcdir := @top_srcdir@
|
|
||||||
srcdir := @srcdir@
|
|
||||||
datarootdir := @datarootdir@
|
|
||||||
abstop_srcdir := $(shell readlink -f ${top_srcdir})
|
|
||||||
abssrcdir := $(shell readlink -f ${srcdir})
|
|
||||||
|
|
||||||
ifeq (${abstop_srcdir},)
|
|
||||||
$(error Path resolution of ${top_srcdir} failed)
|
|
||||||
endif
|
|
||||||
ifeq (${abssrcdir},)
|
|
||||||
$(error Path resolution of ${srcdir} failed)
|
|
||||||
endif
|
|
||||||
|
|
||||||
prefix := @prefix@
|
|
||||||
exec_prefix := @exec_prefix@
|
|
||||||
sbindir := @sbindir@
|
|
||||||
libdir := @libdir@
|
|
||||||
libexecdir := @libexecdir@
|
|
||||||
xtlibdir := @xtlibdir@
|
|
||||||
kbuilddir := @kbuilddir@
|
|
||||||
man8dir := @mandir@/man8
|
|
||||||
|
|
||||||
CC := @CC@
|
|
||||||
CCLD := ${CC}
|
|
||||||
CFLAGS := @CFLAGS@
|
|
||||||
LDFLAGS := @LDFLAGS@
|
|
||||||
regular_CFLAGS := @regular_CFLAGS@
|
|
||||||
kinclude_CFLAGS := @kinclude_CFLAGS@
|
|
||||||
xtables_CFLAGS := @xtables_CFLAGS@
|
|
||||||
|
|
||||||
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS} -DIPSET_LIB_DIR=\"${xtlibdir}\"
|
|
||||||
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
|
|
||||||
|
|
||||||
VU := 0
|
|
||||||
am__1verbose_CC_0 = @echo " CC " $@;
|
|
||||||
am__1verbose_CCLD_0 = @echo " CCLD " $@;
|
|
||||||
am__1verbose_CC_1 = @echo " CC " $@ "<-" $<;
|
|
||||||
am__1verbose_CCLD_1 = @echo " CCLD " $@ "<-" $^;
|
|
||||||
am__verbose_CC = ${am__1verbose_CC_${VU}}
|
|
||||||
am__verbose_CCLD = ${am__1verbose_CCLD_${VU}}
|
|
||||||
|
|
||||||
#
|
|
||||||
# Building blocks
|
|
||||||
#
|
|
||||||
targets := $(addsuffix .so,$(addprefix libipset_, \
|
|
||||||
iphash ipmap ipporthash ipportiphash ipportnethash iptree \
|
|
||||||
iptreemap macipmap nethash portmap setlist))
|
|
||||||
|
|
||||||
.SECONDARY:
|
|
||||||
|
|
||||||
.PHONY: all install clean distclean FORCE
|
|
||||||
|
|
||||||
all: ipset ${targets}
|
|
||||||
|
|
||||||
install: all
|
|
||||||
@mkdir -p "${DESTDIR}${sbindir}" "${DESTDIR}${xtlibdir}" "${DESTDIR}${man8dir}";
|
|
||||||
install -pm0755 ipset "${DESTDIR}${sbindir}/";
|
|
||||||
install -pm0755 ${targets} "${DESTDIR}${xtlibdir}/";
|
|
||||||
install -pm0644 ipset.8 "${DESTDIR}${man8dir}/";
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.oo *.so *.o ipset;
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
rm -f .*.d;
|
|
||||||
|
|
||||||
-include .*.d
|
|
||||||
|
|
||||||
|
|
||||||
ipset: ipset.o
|
|
||||||
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -o $@ $< -ldl -rdynamic;
|
|
||||||
|
|
||||||
#
|
|
||||||
# Shared libraries
|
|
||||||
#
|
|
||||||
lib%.so: lib%.oo
|
|
||||||
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
|
|
||||||
|
|
||||||
libipset_%.oo: ${srcdir}/ipset_%.c
|
|
||||||
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<;
|
|
9
extensions/ipset/Makefile.am
Normal file
9
extensions/ipset/Makefile.am
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
AM_CFLAGS = ${regular_CFLAGS} -DIPSET_LIB_DIR=\"${xtlibdir}\"
|
||||||
|
|
||||||
|
include ../../Makefile.extra
|
||||||
|
|
||||||
|
sbin_PROGRAMS = ipset
|
||||||
|
ipset_LDADD = -ldl
|
||||||
|
ipset_LDFLAGS = -rdynamic
|
7
extensions/ipset/Mbuild
Normal file
7
extensions/ipset/Mbuild
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
obj-m += $(addprefix lib,$(patsubst %.c,%.so,$(notdir \
|
||||||
|
$(wildcard ${XA_SRCDIR}/ipset_*.c))))
|
||||||
|
|
||||||
|
libipset_%.oo: ${XA_SRCDIR}/ipset_%.c
|
||||||
|
${AM_V_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
|
@@ -39,7 +39,7 @@
|
|||||||
static struct list_head set_type_list; /* all registered sets */
|
static struct list_head set_type_list; /* all registered sets */
|
||||||
static struct ip_set **ip_set_list; /* all individual sets */
|
static struct ip_set **ip_set_list; /* all individual sets */
|
||||||
static DEFINE_RWLOCK(ip_set_lock); /* protects the lists and the hash */
|
static DEFINE_RWLOCK(ip_set_lock); /* protects the lists and the hash */
|
||||||
static DECLARE_MUTEX(ip_set_app_mutex); /* serializes user access */
|
static struct semaphore ip_set_app_mutex; /* serializes user access */
|
||||||
static ip_set_id_t ip_set_max = CONFIG_IP_NF_SET_MAX;
|
static ip_set_id_t ip_set_max = CONFIG_IP_NF_SET_MAX;
|
||||||
static ip_set_id_t ip_set_bindings_hash_size = CONFIG_IP_NF_SET_HASHSIZE;
|
static ip_set_id_t ip_set_bindings_hash_size = CONFIG_IP_NF_SET_HASHSIZE;
|
||||||
static struct list_head *ip_set_hash; /* hash of bindings */
|
static struct list_head *ip_set_hash; /* hash of bindings */
|
||||||
@@ -1911,13 +1911,23 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
res = -ENOENT;
|
res = -ENOENT;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SETLIST(set) (strcmp(set->type->typename, "setlist") == 0)
|
||||||
|
|
||||||
used = 0;
|
used = 0;
|
||||||
if (index == IP_SET_INVALID_ID) {
|
if (index == IP_SET_INVALID_ID) {
|
||||||
/* Save all sets */
|
/* Save all sets: ugly setlist type dependency */
|
||||||
|
int setlist = 0;
|
||||||
|
setlists:
|
||||||
for (i = 0; i < ip_set_max && res == 0; i++) {
|
for (i = 0; i < ip_set_max && res == 0; i++) {
|
||||||
if (ip_set_list[i] != NULL)
|
if (ip_set_list[i] != NULL
|
||||||
|
&& !(setlist ^ SETLIST(ip_set_list[i])))
|
||||||
res = ip_set_save_set(i, data, &used, *len);
|
res = ip_set_save_set(i, data, &used, *len);
|
||||||
}
|
}
|
||||||
|
if (!setlist) {
|
||||||
|
setlist = 1;
|
||||||
|
goto setlists;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Save an individual set */
|
/* Save an individual set */
|
||||||
res = ip_set_save_set(index, data, &used, *len);
|
res = ip_set_save_set(index, data, &used, *len);
|
||||||
@@ -2006,6 +2016,7 @@ static int __init ip_set_init(void)
|
|||||||
int res;
|
int res;
|
||||||
ip_set_id_t i;
|
ip_set_id_t i;
|
||||||
|
|
||||||
|
sema_init(&ip_set_app_mutex, 1);
|
||||||
get_random_bytes(&ip_set_hash_random, 4);
|
get_random_bytes(&ip_set_hash_random, 4);
|
||||||
if (max_sets)
|
if (max_sets)
|
||||||
ip_set_max = max_sets;
|
ip_set_max = max_sets;
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
|
#include <linux/jiffies.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
|
#include <linux/jiffies.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
@@ -338,7 +339,7 @@ KADT(iptreemap, add, ipaddr, ip)
|
|||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
__delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
__delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||||
ip_set_ip_t ip, unsigned int __nocast flags)
|
ip_set_ip_t ip, gfp_t flags)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
@@ -364,7 +365,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
|
|||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
|
||||||
ip_set_ip_t start, ip_set_ip_t end, unsigned int __nocast flags)
|
ip_set_ip_t start, ip_set_ip_t end, gfp_t flags)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
|
@@ -40,7 +40,7 @@ struct harray {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
__harray_malloc(size_t hashsize, size_t typesize, int flags)
|
__harray_malloc(size_t hashsize, size_t typesize, gfp_t flags)
|
||||||
{
|
{
|
||||||
struct harray *harray;
|
struct harray *harray;
|
||||||
size_t max_elements, size, i, j;
|
size_t max_elements, size, i, j;
|
||||||
@@ -88,7 +88,7 @@ __harray_malloc(size_t hashsize, size_t typesize, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void *
|
static inline void *
|
||||||
harray_malloc(size_t hashsize, size_t typesize, int flags)
|
harray_malloc(size_t hashsize, size_t typesize, gfp_t flags)
|
||||||
{
|
{
|
||||||
void *harray;
|
void *harray;
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
* after ==> ref, index
|
* after ==> ref, index
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline bool
|
static inline int
|
||||||
next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
|
next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
|
||||||
{
|
{
|
||||||
return i < map->size && map->index[i] == index;
|
return i < map->size && map->index[i] == index;
|
||||||
@@ -38,18 +38,16 @@ setlist_utest(struct ip_set *set, const void *data, u_int32_t size,
|
|||||||
struct ip_set *s;
|
struct ip_set *s;
|
||||||
|
|
||||||
if (req->before && req->ref[0] == '\0')
|
if (req->before && req->ref[0] == '\0')
|
||||||
return -EINVAL;
|
return 0;
|
||||||
|
|
||||||
index = __ip_set_get_byname(req->name, &s);
|
index = __ip_set_get_byname(req->name, &s);
|
||||||
if (index == IP_SET_INVALID_ID)
|
if (index == IP_SET_INVALID_ID)
|
||||||
return -EEXIST;
|
return 0;
|
||||||
if (req->ref[0] != '\0') {
|
if (req->ref[0] != '\0') {
|
||||||
ref = __ip_set_get_byname(req->ref, &s);
|
ref = __ip_set_get_byname(req->ref, &s);
|
||||||
if (ref == IP_SET_INVALID_ID) {
|
if (ref == IP_SET_INVALID_ID)
|
||||||
res = -EEXIST;
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (i = 0; i < map->size
|
for (i = 0; i < map->size
|
||||||
&& map->index[i] != IP_SET_INVALID_ID; i++) {
|
&& map->index[i] != IP_SET_INVALID_ID; i++) {
|
||||||
if (req->before && map->index[i] == index) {
|
if (req->before && map->index[i] == index) {
|
||||||
@@ -172,7 +170,7 @@ setlist_kadd(struct ip_set *set,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline int
|
||||||
unshift_setlist(struct ip_set_setlist *map, int i)
|
unshift_setlist(struct ip_set_setlist *map, int i)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
@@ -50,6 +50,9 @@ IP set bindings pointing to sets and iptables matches and targets
|
|||||||
referring to sets creates references, which protects the given sets in
|
referring to sets creates references, which protects the given sets in
|
||||||
the kernel. A set cannot be removed (destroyed) while there is a single
|
the kernel. A set cannot be removed (destroyed) while there is a single
|
||||||
reference pointing to it.
|
reference pointing to it.
|
||||||
|
.P
|
||||||
|
.B
|
||||||
|
Please note, binding sets is a deprecated feature and will be removed in a later release. Switch to the multidata type of sets from using bindings.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
The options that are recognized by
|
The options that are recognized by
|
||||||
.B ipset
|
.B ipset
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
|
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IPSET_VERSION "2.5.0"
|
#define IPSET_VERSION "3.2"
|
||||||
|
|
||||||
char program_name[] = "ipset";
|
char program_name[] = "ipset";
|
||||||
char program_version[] = IPSET_VERSION;
|
char program_version[] = IPSET_VERSION;
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
Causes confusion on the other end by doing odd things with incoming packets.
|
Causes confusion on the other end by doing odd things with incoming packets.
|
||||||
CHAOS will randomly reply (or not) with one of its configurable subtargets:
|
CHAOS will randomly reply (or not) with one of its configurable subtargets:
|
||||||
.TP
|
.TP
|
||||||
\fB--delude\fP
|
\fB\-\-delude\fP
|
||||||
Use the REJECT and DELUDE targets as a base to do a sudden or deferred
|
Use the REJECT and DELUDE targets as a base to do a sudden or deferred
|
||||||
connection reset, fooling some network scanners to return non-deterministic
|
connection reset, fooling some network scanners to return non-deterministic
|
||||||
(randomly open/closed) results, and in case it is deemed open, it is actually
|
(randomly open/closed) results, and in case it is deemed open, it is actually
|
||||||
closed/filtered.
|
closed/filtered.
|
||||||
.TP
|
.TP
|
||||||
\fB--tarpit\fP
|
\fB\-\-tarpit\fP
|
||||||
Use the REJECT and TARPIT target as a base to hold the connection until it
|
Use the REJECT and TARPIT target as a base to hold the connection until it
|
||||||
times out. This consumes conntrack entries when connection tracking is loaded
|
times out. This consumes conntrack entries when connection tracking is loaded
|
||||||
(which usually is on most machines), and routers inbetween you and the Internet
|
(which usually is on most machines), and routers inbetween you and the Internet
|
||||||
|
@@ -4,7 +4,7 @@ VMware does not allow to set a non-VMware MAC address before an operating
|
|||||||
system is booted (and the MAC be changed with `ip link set eth0 address
|
system is booted (and the MAC be changed with `ip link set eth0 address
|
||||||
aa:bb..`).
|
aa:bb..`).
|
||||||
.TP
|
.TP
|
||||||
\fB--set-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
\fB\-\-set\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||||
Replace the client host MAC address field in the DHCP message with the given
|
Replace the client host MAC address field in the DHCP message with the given
|
||||||
MAC address. This option is mandatory. The \fImask\fP parameter specifies the
|
MAC address. This option is mandatory. The \fImask\fP parameter specifies the
|
||||||
prefix length of bits to change.
|
prefix length of bits to change.
|
||||||
@@ -12,13 +12,13 @@ prefix length of bits to change.
|
|||||||
EXAMPLE, replacing all addresses from one of VMware's assigned vendor IDs
|
EXAMPLE, replacing all addresses from one of VMware's assigned vendor IDs
|
||||||
(00:50:56) addresses with something else:
|
(00:50:56) addresses with something else:
|
||||||
.PP
|
.PP
|
||||||
iptables -t mangle -A FORWARD -p udp --dport 67 -m physdev --physdev-in vmnet1
|
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 67 \-m physdev
|
||||||
-m dhcpmac --mac 00:50:56:00:00:00/24 -j DHCPMAC --set-mac
|
\-\-physdev\-in vmnet1 \-m dhcpmac \-\-mac 00:50:56:00:00:00/24 \-j DHCPMAC
|
||||||
ab:cd:ef:00:00:00/24
|
\-\-set\-mac ab:cd:ef:00:00:00/24
|
||||||
.PP
|
.PP
|
||||||
iptables -t mangle -A FORWARD -p udp --dport 68 -m physdev --physdev-out vmnet1
|
iptables \-t mangle \-A FORWARD \-p udp \-\-dport 68 \-m physdev
|
||||||
-m dhcpmac --mac ab:cd:ef:00:00:00/24 -j DHCPMAC --set-mac
|
\-\-physdev\-out vmnet1 \-m dhcpmac \-\-mac ab:cd:ef:00:00:00/24 \-j DHCPMAC
|
||||||
00:50:56:00:00:00/24
|
\-\-set\-mac 00:50:56:00:00:00/24
|
||||||
.PP
|
.PP
|
||||||
(This assumes there is a bridge interface that has vmnet1 as a port. You will
|
(This assumes there is a bridge interface that has vmnet1 as a port. You will
|
||||||
also need to add appropriate ebtables rules to change the MAC address of the
|
also need to add appropriate ebtables rules to change the MAC address of the
|
||||||
|
@@ -4,16 +4,16 @@ firewall based classifier.
|
|||||||
|
|
||||||
This target is to be used inside the \fBmangle\fP table.
|
This target is to be used inside the \fBmangle\fP table.
|
||||||
.TP
|
.TP
|
||||||
\fB--addr\fP {\fBsrc\fP|\fBdst\fP}
|
\fB\-\-addr\fP {\fBsrc\fP|\fBdst\fP}
|
||||||
Select source or destination IP address as a basis for the mark.
|
Select source or destination IP address as a basis for the mark.
|
||||||
.TP
|
.TP
|
||||||
\fB--and-mask\fP \fImask\fP
|
\fB\-\-and\-mask\fP \fImask\fP
|
||||||
Perform bitwise AND on the IP address and this bitmask.
|
Perform bitwise AND on the IP address and this bitmask.
|
||||||
.TP
|
.TP
|
||||||
\fB--or-mask\fP \fImask\fP
|
\fB\-\-or\-mask\fP \fImask\fP
|
||||||
Perform bitwise OR on the IP address and this bitmask.
|
Perform bitwise OR on the IP address and this bitmask.
|
||||||
.TP
|
.TP
|
||||||
\fB--shift\fP \fIvalue\fP
|
\fB\-\-shift\fP \fIvalue\fP
|
||||||
Shift addresses to the right by the given number of bits before taking it
|
Shift addresses to the right by the given number of bits before taking it
|
||||||
as a mark. (This is done before ANDing or ORing it.) This option is needed
|
as a mark. (This is done before ANDing or ORing it.) This option is needed
|
||||||
to select part of an IPv6 address, because marks are only 32 bits in size.
|
to select part of an IPv6 address, because marks are only 32 bits in size.
|
||||||
@@ -34,16 +34,16 @@ tc filter add dev eth3 parent 1:0 protocol ip fw
|
|||||||
.PP
|
.PP
|
||||||
Earlier we had many rules just like below:
|
Earlier we had many rules just like below:
|
||||||
.IP
|
.IP
|
||||||
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.2 -j MARK
|
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.2 \-j MARK
|
||||||
--set-mark 0x10502
|
\-\-set\-mark 0x10502
|
||||||
.IP
|
.IP
|
||||||
iptables -t mangle -A POSTROUTING -o eth3 -d 192.168.5.3 -j MARK
|
iptables \-t mangle \-A POSTROUTING \-o eth3 \-d 192.168.5.3 \-j MARK
|
||||||
--set-mark 0x10503
|
\-\-set\-mark 0x10503
|
||||||
.PP
|
.PP
|
||||||
Using IPMARK target we can replace all the mangle/mark rules with only one:
|
Using IPMARK target we can replace all the mangle/mark rules with only one:
|
||||||
.IP
|
.IP
|
||||||
iptables -t mangle -A POSTROUTING -o eth3 -j IPMARK --addr dst
|
iptables \-t mangle \-A POSTROUTING \-o eth3 \-j IPMARK \-\-addr dst
|
||||||
--and-mask 0xffff --or-mask 0x10000
|
\-\-and\-mask 0xffff \-\-or\-mask 0x10000
|
||||||
.PP
|
.PP
|
||||||
On the routers with hundreds of users there should be significant load
|
On the routers with hundreds of users there should be significant load
|
||||||
decrease (e.g. twice).
|
decrease (e.g. twice).
|
||||||
@@ -52,5 +52,5 @@ decrease (e.g. twice).
|
|||||||
2001:db8:45:1d:20d:93ff:fe9b:e443 and the resulting mark should be 0x93ff,
|
2001:db8:45:1d:20d:93ff:fe9b:e443 and the resulting mark should be 0x93ff,
|
||||||
then a right-shift of 16 is needed first:
|
then a right-shift of 16 is needed first:
|
||||||
.IP
|
.IP
|
||||||
-t mangle -A PREROUTING -s 2001:db8::/32 -j IPMARK --addr src --shift 16
|
\-t mangle \-A PREROUTING \-s 2001:db8::/32 \-j IPMARK \-\-addr src \-\-shift
|
||||||
--and-mask 0xFFFF
|
16 \-\-and\-mask 0xFFFF
|
||||||
|
@@ -1,17 +1,17 @@
|
|||||||
The LOGMARK target will log packet and connection marks to syslog.
|
The LOGMARK target will log packet and connection marks to syslog.
|
||||||
.TP
|
.TP
|
||||||
\fB--log-level\fR \fIlevel\fR
|
\fB\-\-log\-level\fR \fIlevel\fR
|
||||||
A logging level between 0 and 8 (inclusive).
|
A logging level between 0 and 8 (inclusive).
|
||||||
.TP
|
.TP
|
||||||
\fB--log-prefix\fR \fIstring\fR
|
\fB\-\-log\-prefix\fR \fIstring\fR
|
||||||
Prefix log messages with the specified prefix; up to 29 bytes long, and useful
|
Prefix log messages with the specified prefix; up to 29 bytes long, and useful
|
||||||
for distinguishing messages in the logs.
|
for distinguishing messages in the logs.
|
||||||
.TP
|
.TP
|
||||||
\fB--log-nfmark\fR
|
\fB\-\-log\-nfmark\fR
|
||||||
Include the packet mark in the log.
|
Include the packet mark in the log.
|
||||||
.TP
|
.TP
|
||||||
\fB--log-ctmark\fR
|
\fB\-\-log\-ctmark\fR
|
||||||
Include the connection mark in the log.
|
Include the connection mark in the log.
|
||||||
.TP
|
.TP
|
||||||
\fB--log-secmark\fR
|
\fB\-\-log\-secmark\fR
|
||||||
Include the packet secmark in the log.
|
Include the packet secmark in the log.
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
The \fBRAWDNAT\fR target will rewrite the destination address in the IP header,
|
The \fBRAWDNAT\fR target will rewrite the destination address in the IP header,
|
||||||
much like the \fBNETMAP\fR target.
|
much like the \fBNETMAP\fR target.
|
||||||
.TP
|
.TP
|
||||||
\fB--to-destination\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
\fB\-\-to\-destination\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
||||||
Network address to map to. The resulting address will be constructed the
|
Network address to map to. The resulting address will be constructed the
|
||||||
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
||||||
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
||||||
|
@@ -8,7 +8,7 @@ which makes it possible to change the source address either when the packet
|
|||||||
enters the machine or when it leaves it. The reason for this table constraint
|
enters the machine or when it leaves it. The reason for this table constraint
|
||||||
is that RAWNAT must happen outside of connection tracking.
|
is that RAWNAT must happen outside of connection tracking.
|
||||||
.TP
|
.TP
|
||||||
\fB--to-source\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
\fB\-\-to\-source\fR \fIaddr\fR[\fB/\fR\fImask\fR]
|
||||||
Network address to map to. The resulting address will be constructed the
|
Network address to map to. The resulting address will be constructed the
|
||||||
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
following way: All 'one' bits in the \fImask\fR are filled in from the new
|
||||||
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
\fIaddress\fR. All bits that are zero in the mask are filled in from the
|
||||||
@@ -17,13 +17,13 @@ original address.
|
|||||||
As an example, changing the destination for packets forwarded from an internal
|
As an example, changing the destination for packets forwarded from an internal
|
||||||
LAN to the internet:
|
LAN to the internet:
|
||||||
.IP
|
.IP
|
||||||
-t raw -A PREROUTING -i lan0 -d 212.201.100.135 -j RAWDNAT --to-destination 199.181.132.250
|
\-t raw \-A PREROUTING \-i lan0 \-d 212.201.100.135 \-j RAWDNAT \-\-to\-destination 199.181.132.250;
|
||||||
-t rawpost -A POSTROUTING -o lan0 -s 199.181.132.250 -j RAWSNAT --to-source 212.201.100.135
|
\-t rawpost \-A POSTROUTING \-o lan0 \-s 199.181.132.250 \-j RAWSNAT \-\-to\-source 212.201.100.135;
|
||||||
.PP
|
.PP
|
||||||
Note that changing addresses may influence the route selection! Specifically,
|
Note that changing addresses may influence the route selection! Specifically,
|
||||||
it statically NATs packets, not connections, like the normal DNAT/SNAT targets
|
it statically NATs packets, not connections, like the normal DNAT/SNAT targets
|
||||||
would do. Also note that it can transform already-NATed connections -- as said,
|
would do. Also note that it can transform already-NATed connections \(em as
|
||||||
it is completely external to Netfilter's connection tracking/NAT.
|
said, it is completely external to Netfilter's connection tracking/NAT.
|
||||||
.PP
|
.PP
|
||||||
If the machine itself generates packets that are to be rawnat'ed, you need a
|
If the machine itself generates packets that are to be rawnat'ed, you need a
|
||||||
rule in the OUTPUT chain instead, just like you would with the stateful NAT
|
rule in the OUTPUT chain instead, just like you would with the stateful NAT
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
The SYSRQ target allows to remotely trigger sysrq on the local machine over the
|
The SYSRQ target allows to remotely trigger sysrq on the local machine over the
|
||||||
network. This can be useful when vital parts of the machine hang, for example
|
network. This can be useful when vital parts of the machine hang, for example
|
||||||
an oops in a filesystem causing locks to be not released and processes to get
|
an oops in a filesystem causing locks to be not released and processes to get
|
||||||
stuck as a result - if still possible, use /proc/sysrq-trigger. Even when
|
stuck as a result \(em if still possible, use /proc/sysrq-trigger. Even when
|
||||||
processes are stuck, interrupts are likely to be still processed, and as such,
|
processes are stuck, interrupts are likely to be still processed, and as such,
|
||||||
sysrq can be triggered through incoming network packets.
|
sysrq can be triggered through incoming network packets.
|
||||||
.PP
|
.PP
|
||||||
@@ -11,30 +11,30 @@ requests. The initial sequence number comes from the time of day so you will
|
|||||||
have a small window of vulnerability should time go backwards at a reboot.
|
have a small window of vulnerability should time go backwards at a reboot.
|
||||||
However, the file /sys/module/xt_SYSREQ/seqno can be used to both query and
|
However, the file /sys/module/xt_SYSREQ/seqno can be used to both query and
|
||||||
update the current sequence number. Also, you should limit as to who can issue
|
update the current sequence number. Also, you should limit as to who can issue
|
||||||
commands using \fB-s\fP and/or \fB-m mac\fP, and also that the destination is
|
commands using \fB\-s\fP and/or \fB\-m mac\fP, and also that the destination is
|
||||||
correct using \fB-d\fP (to protect against potential broadcast packets), noting
|
correct using \fB\-d\fP (to protect against potential broadcast packets),
|
||||||
that it is still short of MAC/IP spoofing:
|
noting that it is still short of MAC/IP spoofing:
|
||||||
.IP
|
.IP
|
||||||
-A INPUT -s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
|
\-A INPUT \-s 10.10.25.1 \-m mac \-\-mac\-source aa:bb:cc:dd:ee:ff \-d
|
||||||
-p udp --dport 9 -j SYSRQ
|
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
|
||||||
.IP
|
.IP
|
||||||
(with IPsec) -A INPUT -s 10.10.25.1 -d 10.10.25.7 -m policy --dir in --pol
|
(with IPsec) \-A INPUT \-s 10.10.25.1 \-d 10.10.25.7 \-m policy \-\-dir in
|
||||||
ipsec --proto esp --tunnel-src 10.10.25.1 --tunnel-dst 10.10.25.7
|
\-\-pol ipsec \-\-proto esp \-\-tunnel\-src 10.10.25.1 \-\-tunnel\-dst
|
||||||
-p udp --dport 9 -j SYSRQ
|
10.10.25.7 \-p udp \-\-dport 9 \-j SYSRQ
|
||||||
.PP
|
.PP
|
||||||
You should also limit the rate at which connections can be received to limit
|
You should also limit the rate at which connections can be received to limit
|
||||||
the CPU time taken by illegal requests, for example:
|
the CPU time taken by illegal requests, for example:
|
||||||
.IP
|
.IP
|
||||||
-A INPUT -s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
|
\-A INPUT \-s 10.10.25.1 \-m mac \-\-mac\-source aa:bb:cc:dd:ee:ff \-d
|
||||||
-p udp --dport 9 -m limit --limit 5/minute -j SYSRQ
|
10.10.25.7 \-p udp \-\-dport 9 \-m limit \-\-limit 5/minute \-j SYSRQ
|
||||||
.PP
|
.PP
|
||||||
This extension does not take any options. The \fB-p udp\fP options are
|
This extension does not take any options. The \fB\-p udp\fP options are
|
||||||
required.
|
required.
|
||||||
.PP
|
.PP
|
||||||
The SYSRQ password can be changed through
|
The SYSRQ password can be changed through
|
||||||
/sys/module/xt_SYSRQ/parameters/password, for example:
|
/sys/module/xt_SYSRQ/parameters/password, for example:
|
||||||
.IP
|
.IP
|
||||||
echo -n "password" >/sys/module/xt_SYSRQ/parameters/password
|
echo \-n "password" >/sys/module/xt_SYSRQ/parameters/password
|
||||||
.PP
|
.PP
|
||||||
Alternatively, the password may be specified at modprobe time, but this is
|
Alternatively, the password may be specified at modprobe time, but this is
|
||||||
insecure as people can possible see it through ps(1). You can use an option
|
insecure as people can possible see it through ps(1). You can use an option
|
||||||
@@ -59,13 +59,13 @@ sysrq_key="s" # the SysRq key(s)
|
|||||||
password="password"
|
password="password"
|
||||||
seqno="$(date +%s)"
|
seqno="$(date +%s)"
|
||||||
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
|
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
|
||||||
openssl enc -base64)"
|
openssl enc \-base64)"
|
||||||
req="$sysrq_key,$seqno,$salt"
|
req="$sysrq_key,$seqno,$salt"
|
||||||
req="$req,$(echo -n "$req,$password" | sha1sum | cut -c1-40)"
|
req="$req,$(echo \-n "$req,$password" | sha1sum | cut \-c1\-40)"
|
||||||
|
|
||||||
echo "$req" | socat stdin udp-sendto:10.10.25.7:9
|
echo "$req" | socat stdin udp\-sendto:10.10.25.7:9
|
||||||
# or
|
# or
|
||||||
echo "$req" | netcat -uw1 10.10.25.7 9
|
echo "$req" | netcat \-uw1 10.10.25.7 9
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,
|
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,
|
||||||
|
@@ -11,16 +11,16 @@ tarpit.
|
|||||||
|
|
||||||
To tarpit connections to TCP port 80 destined for the current machine:
|
To tarpit connections to TCP port 80 destined for the current machine:
|
||||||
.IP
|
.IP
|
||||||
-A INPUT -p tcp -m tcp --dport 80 -j TARPIT
|
\-A INPUT \-p tcp \-m tcp \-\-dport 80 \-j TARPIT
|
||||||
.P
|
.PP
|
||||||
To significantly slow down Code Red/Nimda-style scans of unused address space,
|
To significantly slow down Code Red/Nimda-style scans of unused address space,
|
||||||
forward unused ip addresses to a Linux box not acting as a router (e.g. "ip
|
forward unused ip addresses to a Linux box not acting as a router (e.g. "ip
|
||||||
route 10.0.0.0 255.0.0.0 ip.of.linux.box" on a Cisco), enable IP forwarding on
|
route 10.0.0.0 255.0.0.0 ip.of.linux.box" on a Cisco), enable IP forwarding on
|
||||||
the Linux box, and add:
|
the Linux box, and add:
|
||||||
.IP
|
.IP
|
||||||
-A FORWARD -p tcp -j TARPIT
|
\-A FORWARD \-p tcp \-j TARPIT
|
||||||
.IP
|
.IP
|
||||||
-A FORWARD -j DROP
|
\-A FORWARD \-j DROP
|
||||||
.PP
|
.PP
|
||||||
NOTE:
|
NOTE:
|
||||||
If you use the conntrack module while you are using TARPIT, you should also use
|
If you use the conntrack module while you are using TARPIT, you should also use
|
||||||
@@ -28,6 +28,6 @@ the NOTRACK target, or the kernel will unnecessarily allocate resources for
|
|||||||
each TARPITted connection. To TARPIT incoming connections to the standard IRC
|
each TARPITted connection. To TARPIT incoming connections to the standard IRC
|
||||||
port while using conntrack, you could:
|
port while using conntrack, you could:
|
||||||
.IP
|
.IP
|
||||||
-t raw -A PREROUTING -p tcp --dport 6667 -j NOTRACK
|
\-t raw \-A PREROUTING \-p tcp \-\-dport 6667 \-j NOTRACK
|
||||||
.IP
|
.IP
|
||||||
-A INPUT -p tcp --dport 6667 -j TARPIT
|
\-A INPUT \-p tcp \-\-dport 6667 \-j TARPIT
|
||||||
|
@@ -3,6 +3,6 @@ machine on the \fBlocal\fP network segment. In other words, the nexthop
|
|||||||
must be the target, or you will have to configure the nexthop to forward it
|
must be the target, or you will have to configure the nexthop to forward it
|
||||||
further if so desired.
|
further if so desired.
|
||||||
.TP
|
.TP
|
||||||
\fB--gw\fP \fIipaddr\fP
|
\fB\-\-gw\fP \fIipaddr\fP
|
||||||
Send the cloned packet to the host reachable at the given IP address.
|
Send the cloned packet to the host reachable at the given IP address.
|
||||||
Use of 0.0.0.0 (for IPv4 packets) or :: (IPv6) is invalid.
|
Use of 0.0.0.0 (for IPv4 packets) or :: (IPv6) is invalid.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
This matches if a specific condition variable is (un)set.
|
This matches if a specific condition variable is (un)set.
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB--condition\fP \fIname\fP
|
[\fB!\fP] \fB\-\-condition\fP \fIname\fP
|
||||||
Match on boolean value stored in /proc/net/nf_condition/\fIname\fP.
|
Match on boolean value stored in /proc/net/nf_condition/\fIname\fP.
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
.TP
|
.TP
|
||||||
\fB--mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
\fB\-\-mac\fP \fIaa:bb:cc:dd:ee:ff\fP[\fB/\fP\fImask\fP]
|
||||||
Matches the DHCP "Client Host" address (a MAC address) in a DHCP message.
|
Matches the DHCP "Client Host" address (a MAC address) in a DHCP message.
|
||||||
\fImask\fP specifies the prefix length of the initial portion to match.
|
\fImask\fP specifies the prefix length of the initial portion to match.
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
This module matches a rate limit based on a fuzzy logic controller (FLC).
|
This module matches a rate limit based on a fuzzy logic controller (FLC).
|
||||||
.TP
|
.TP
|
||||||
\fB--lower-limit\fP \fInumber\fP
|
\fB\-\-lower\-limit\fP \fInumber\fP
|
||||||
Specifies the lower limit, in packets per second.
|
Specifies the lower limit, in packets per second.
|
||||||
.TP
|
.TP
|
||||||
\fB--upper-limit\fP \fInumber\fP
|
\fB\-\-upper\-limit\fP \fInumber\fP
|
||||||
Specifies the upper limit, also in packets per second.
|
Specifies the upper limit, also in packets per second.
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
Match a packet by its source or destination country.
|
Match a packet by its source or destination country.
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB--src-cc\fP, \fB--source-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
[\fB!\fP] \fB\-\-src\-cc\fP, \fB\-\-source\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||||
Match packet coming from (one of) the specified country(ies)
|
Match packet coming from (one of) the specified country(ies)
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB--dst-cc\fP, \fB--destination-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
[\fB!\fP] \fB\-\-dst\-cc\fP, \fB\-\-destination\-country\fP \fIcountry\fP[\fB,\fP\fIcountry\fP\fB...\fP]
|
||||||
Match packet going to (one of) the specified country(ies)
|
Match packet going to (one of) the specified country(ies)
|
||||||
.TP
|
.TP
|
||||||
NOTE:
|
NOTE:
|
||||||
|
@@ -30,7 +30,7 @@ Check the MULTICAST flag.
|
|||||||
[\fB!\fP] \fB\-\-dynamic\fP
|
[\fB!\fP] \fB\-\-dynamic\fP
|
||||||
Check the DYNAMIC flag.
|
Check the DYNAMIC flag.
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB\-\-lower-up\fP
|
[\fB!\fP] \fB\-\-lower\-up\fP
|
||||||
Check the LOWER_UP flag.
|
Check the LOWER_UP flag.
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB\-\-dormant\fP
|
[\fB!\fP] \fB\-\-dormant\fP
|
||||||
|
@@ -1,41 +1,41 @@
|
|||||||
This module matches certain packets in P2P flows. It is not
|
This module matches certain packets in P2P flows. It is not
|
||||||
designed to match all packets belonging to a P2P connection -
|
designed to match all packets belonging to a P2P connection \(em
|
||||||
use IPP2P together with CONNMARK for this purpose.
|
use IPP2P together with CONNMARK for this purpose.
|
||||||
.PP
|
.PP
|
||||||
Use it together with -p tcp or -p udp to search these protocols
|
Use it together with \-p tcp or \-p udp to search these protocols
|
||||||
only or without -p switch to search packets of both protocols.
|
only or without \-p switch to search packets of both protocols.
|
||||||
.PP
|
.PP
|
||||||
IPP2P provides the following options, of which one or more may be specified
|
IPP2P provides the following options, of which one or more may be specified
|
||||||
on the command line:
|
on the command line:
|
||||||
.TP
|
.TP
|
||||||
.B "--edk "
|
\fB\-\-edk\fP
|
||||||
Matches as many eDonkey/eMule packets as possible.
|
Matches as many eDonkey/eMule packets as possible.
|
||||||
.TP
|
.TP
|
||||||
.B "--kazaa "
|
\fB\-\-kazaa\fP
|
||||||
Matches as many KaZaA packets as possible.
|
Matches as many KaZaA packets as possible.
|
||||||
.TP
|
.TP
|
||||||
.B "--gnu "
|
\fB\-\-gnu\fP
|
||||||
Matches as many Gnutella packets as possible.
|
Matches as many Gnutella packets as possible.
|
||||||
.TP
|
.TP
|
||||||
.B "--dc "
|
\fB\-\-dc\fP
|
||||||
Matches as many Direct Connect packets as possible.
|
Matches as many Direct Connect packets as possible.
|
||||||
.TP
|
.TP
|
||||||
.B "--bit "
|
\fB\-\-bit\fP
|
||||||
Matches BitTorrent packets.
|
Matches BitTorrent packets.
|
||||||
.TP
|
.TP
|
||||||
.B "--apple "
|
\fB\-\-apple\fP
|
||||||
Matches AppleJuice packets.
|
Matches AppleJuice packets.
|
||||||
.TP
|
.TP
|
||||||
.B "--soul "
|
\fB\-\-soul\fP
|
||||||
Matches some SoulSeek packets. Considered as beta, use careful!
|
Matches some SoulSeek packets. Considered as beta, use careful!
|
||||||
.TP
|
.TP
|
||||||
.B "--winmx "
|
\fB\-\-winmx\fP
|
||||||
Matches some WinMX packets. Considered as beta, use careful!
|
Matches some WinMX packets. Considered as beta, use careful!
|
||||||
.TP
|
.TP
|
||||||
.B "--ares "
|
\fB\-\-ares\fP
|
||||||
Matches Ares and AresLite packets. Use together with -j DROP only.
|
Matches Ares and AresLite packets. Use together with \-j DROP only.
|
||||||
.TP
|
.TP
|
||||||
.B "--debug "
|
\fB\-\-debug\fP
|
||||||
Prints some information about each hit into kernel logfile. May
|
Prints some information about each hit into kernel logfile. May
|
||||||
produce huge logfiles so beware!
|
produce huge logfiles so beware!
|
||||||
.PP
|
.PP
|
||||||
@@ -44,5 +44,5 @@ exchanged as a result of running filesharing programs.
|
|||||||
.PP
|
.PP
|
||||||
There is more information on http://ipp2p.org/ , but it has not been updated
|
There is more information on http://ipp2p.org/ , but it has not been updated
|
||||||
since September 2006, and the syntax there is different from the ipp2p.c
|
since September 2006, and the syntax there is different from the ipp2p.c
|
||||||
provided in Xtables-addons; most importantly, the --ipp2p flag was removed due
|
provided in Xtables-addons; most importantly, the \-\-ipp2p flag was removed
|
||||||
to its ambiguity to match "all known" protocols.
|
due to its ambiguity to match "all known" protocols.
|
||||||
|
@@ -13,25 +13,25 @@ where only at least one symbol spec must be true.
|
|||||||
.PP
|
.PP
|
||||||
Known symbol names (and their number):
|
Known symbol names (and their number):
|
||||||
.PP
|
.PP
|
||||||
1 - \fBnop\fP
|
1 \(em \fBnop\fP
|
||||||
.PP
|
.PP
|
||||||
2 - \fBsecurity\fP - RFC 1108
|
2 \(em \fBsecurity\fP \(em RFC 1108
|
||||||
.PP
|
.PP
|
||||||
3 - \fBlsrr\fP - Loose Source Routing, RFC 791
|
3 \(em \fBlsrr\fP \(em Loose Source Routing, RFC 791
|
||||||
.PP
|
.PP
|
||||||
4 - \fBtimestamp\fP - RFC 781, 791
|
4 \(em \fBtimestamp\fP \(em RFC 781, 791
|
||||||
.PP
|
.PP
|
||||||
7 - \fBrecord\-route\fP - RFC 791
|
7 \(em \fBrecord\-route\fP \em RFC 791
|
||||||
.PP
|
.PP
|
||||||
9 - \fBssrr\fP - Strict Source Routing, RFC 791
|
9 \(em \fBssrr\fP \(em Strict Source Routing, RFC 791
|
||||||
.PP
|
.PP
|
||||||
11 - \fBmtu\-probe\fP - RFC 1063
|
11 \(em \fBmtu\-probe\fP \(em RFC 1063
|
||||||
.PP
|
.PP
|
||||||
12 - \fBmtu\-reply\fP - RFC 1063
|
12 \(em \fBmtu\-reply\fP \(em RFC 1063
|
||||||
.PP
|
.PP
|
||||||
18 - \fBtraceroute\fP - RFC 1393
|
18 \(em \fBtraceroute\fP \(em RFC 1393
|
||||||
.PP
|
.PP
|
||||||
20 - \fBrouter-alert\fP - RFC 2113
|
20 \(em \fBrouter-alert\fP \(em RFC 2113
|
||||||
.PP
|
.PP
|
||||||
Examples:
|
Examples:
|
||||||
.PP
|
.PP
|
||||||
|
@@ -1,18 +1,19 @@
|
|||||||
This module matches the length of a packet against a specific value or range of
|
This module matches the length of a packet against a specific value or range of
|
||||||
values.
|
values.
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fR] \fB--length\fR \fIlength\fR[\fB:\fR\fIlength\fR]
|
[\fB!\fR] \fB\-\-length\fR \fIlength\fR[\fB:\fR\fIlength\fR]
|
||||||
Match exact length or length range.
|
Match exact length or length range.
|
||||||
.TP
|
.TP
|
||||||
\fB--layer3\fR
|
\fB\-\-layer3\fR
|
||||||
Match the layer3 frame size (e.g. IPv4/v6 header plus payload).
|
Match the layer3 frame size (e.g. IPv4/v6 header plus payload).
|
||||||
.TP
|
.TP
|
||||||
\fB--layer4\fR
|
\fB\-\-layer4\fR
|
||||||
Match the layer4 frame size (e.g. TCP/UDP header plus payload).
|
Match the layer4 frame size (e.g. TCP/UDP header plus payload).
|
||||||
.TP
|
.TP
|
||||||
\fB--layer5\fR
|
\fB\-\-layer5\fR
|
||||||
Match the layer5 frame size (e.g. TCP/UDP payload, often called layer7).
|
Match the layer5 frame size (e.g. TCP/UDP payload, often called layer7).
|
||||||
.PP
|
.PP
|
||||||
If no --layer* option is given, --layer3 is assumed by default. Note that using
|
If no \-\-layer* option is given, \-\-layer3 is assumed by default. Note that
|
||||||
--layer5 may not match a packet if it is not one of the recognized types
|
using \-\-layer5 may not match a packet if it is not one of the recognized
|
||||||
(currently TCP, UDP, UDPLite, ICMP, AH and ESP) or which has no 5th layer.
|
types (currently TCP, UDP, UDPLite, ICMP, AH and ESP) or which has no 5th
|
||||||
|
layer.
|
||||||
|
@@ -6,19 +6,19 @@ out, but this information can be used in conjunction with other rules to block
|
|||||||
the remote host's future connections. So this match module will match on the
|
the remote host's future connections. So this match module will match on the
|
||||||
(probably) last packet the remote side will send to your machine.
|
(probably) last packet the remote side will send to your machine.
|
||||||
.TP
|
.TP
|
||||||
\fB--stealth\fR
|
\fB\-\-stealth\fR
|
||||||
Match if the packet did not belong to any known TCP connection
|
Match if the packet did not belong to any known TCP connection
|
||||||
(Stealth/FIN/XMAS/NULL scan).
|
(Stealth/FIN/XMAS/NULL scan).
|
||||||
.TP
|
.TP
|
||||||
\fB--synscan\fR
|
\fB\-\-synscan\fR
|
||||||
Match if the connection was a TCP half-open discovery (SYN scan), i.e. the
|
Match if the connection was a TCP half-open discovery (SYN scan), i.e. the
|
||||||
connection was torn down after the 2nd packet in the 3-way handshake.
|
connection was torn down after the 2nd packet in the 3-way handshake.
|
||||||
.TP
|
.TP
|
||||||
\fB--cnscan\fR
|
\fB\-\-cnscan\fR
|
||||||
Match if the connection was a TCP full open discovery (connect scan), i.e. the
|
Match if the connection was a TCP full open discovery (connect scan), i.e. the
|
||||||
connection was torn down after completion of the 3-way handshake.
|
connection was torn down after completion of the 3-way handshake.
|
||||||
.TP
|
.TP
|
||||||
\fB--grscan\fR
|
\fB\-\-grscan\fR
|
||||||
Match if data in the connection only flew in the direction of the remote side,
|
Match if data in the connection only flew in the direction of the remote side,
|
||||||
e.g. if the connection was terminated after a locally running daemon sent its
|
e.g. if the connection was terminated after a locally running daemon sent its
|
||||||
identification. (E.g. openssh, smtp, ftpd.) This may falsely trigger on
|
identification. (E.g. openssh, smtp, ftpd.) This may falsely trigger on
|
||||||
|
113
extensions/libxt_pknock.man
Normal file
113
extensions/libxt_pknock.man
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
Pknock match implements so-called "port knocking", a stealthy system
|
||||||
|
for network authentication: a client sends packets to selected
|
||||||
|
ports in a specific sequence (= simple mode, see example 1 below), or a HMAC
|
||||||
|
payload to a single port (= complex mode, see example 2 below),
|
||||||
|
to a target machine that has pknock rule(s) installed. The target machine
|
||||||
|
then decides whether to unblock or block (again) the pknock-protected port(s).
|
||||||
|
This can be used, for instance, to avoid brute force
|
||||||
|
attacks on ssh or ftp services.
|
||||||
|
.PP
|
||||||
|
Example prerequisites:
|
||||||
|
.IP
|
||||||
|
modprobe cn
|
||||||
|
.IP
|
||||||
|
modprobe xt_pknock
|
||||||
|
.PP
|
||||||
|
Example 1 (TCP mode, manual closing of opened port not possible):
|
||||||
|
.IP
|
||||||
|
iptables -P INPUT DROP
|
||||||
|
.IP
|
||||||
|
iptables -A INPUT -p tcp -m pknock --knockports 4002,4001,4004 --strict
|
||||||
|
--name SSH --time 10 --autoclose 60 --dport 22 -j ACCEPT
|
||||||
|
.PP
|
||||||
|
The rule will allow tcp port 22 for the attempting IP address after the successful reception of TCP SYN packets
|
||||||
|
to ports 4002, 4001 and 4004, in this order (a.k.a. port-knocking).
|
||||||
|
Port numbers in the connect sequence must follow the exact specification, no
|
||||||
|
other ports may be "knocked" inbetween. The rule is named '\fBSSH\fP' \(em a file of
|
||||||
|
the same name for tracking port knocking states will be created in
|
||||||
|
\fB/proc/net/xt_pknock\fP .
|
||||||
|
Successive port knocks must occur with delay of at most 10 seconds. Port 22 (from the example) will
|
||||||
|
be automatiaclly dropped after 60 minutes after it was previously allowed.
|
||||||
|
.PP
|
||||||
|
Example 2 (UDP mode \(em non-replayable and non-spoofable, manual closing
|
||||||
|
of opened port possible, secure, also called "SPA" = Secure Port
|
||||||
|
Authorization):
|
||||||
|
.IP
|
||||||
|
iptables -A INPUT -p udp -m pknock --knockports 4000 --name FTP
|
||||||
|
--opensecret foo --closesecret bar --autoclose 240 -j DROP
|
||||||
|
.IP
|
||||||
|
iptables -A INPUT -p tcp -m pknock --checkip --name FTP --dport 21 -j ACCEPT
|
||||||
|
.PP
|
||||||
|
The first rule will create an "ALLOWED" record in /proc/net/xt_pknock/FTP after
|
||||||
|
the successful reception of an UDP packet to port 4000. The packet payload must be
|
||||||
|
constructed as a HMAC256 using "foo" as a key. The HMAC content is the particular client's IP address as a 32-bit network byteorder quantity,
|
||||||
|
plus the number of minutes since the Unix epoch, also as a 32-bit value.
|
||||||
|
(This is known as Simple Packet Authorization, also called "SPA".)
|
||||||
|
In such case, any subsequent attempt to connect to port 21 from the client's IP
|
||||||
|
address will cause such packets to be accepted in the second rule.
|
||||||
|
.PP
|
||||||
|
Similarly, upon reception of an UDP packet constructed the same way, but with
|
||||||
|
the key "bar", the first rule will remove a previously installed "ALLOWED" state
|
||||||
|
record from /proc/net/xt_pknock/FTP, which means that the second rule will
|
||||||
|
stop matching for subsequent connection attempts to port 21.
|
||||||
|
In case no close-secret packet is received within 4 hours, the first rule
|
||||||
|
will remove "ALLOWED" record from /proc/net/xt_pknock/FTP itself.
|
||||||
|
.PP
|
||||||
|
Things worth noting:
|
||||||
|
.PP
|
||||||
|
\fBGeneral\fP:
|
||||||
|
.PP
|
||||||
|
Specifying \fB--autoclose 0\fP means that no automatic close will be performed at all.
|
||||||
|
.PP
|
||||||
|
xt_pknock is capable of sending information about successful matches
|
||||||
|
via a netlink socket to userspace, should you need to implement your own
|
||||||
|
way of receiving and handling portknock notifications.
|
||||||
|
Be sure to read the documentation in the doc/pknock/ directory,
|
||||||
|
or visit the original site \(em http://portknocko.berlios.de/ .
|
||||||
|
.PP
|
||||||
|
\fBTCP mode\fP:
|
||||||
|
.PP
|
||||||
|
This mode is not immune against eavesdropping, spoofing and
|
||||||
|
replaying of the port knock sequence by someone else (but its use may still
|
||||||
|
be sufficient for scenarios where these factors are not necessarily
|
||||||
|
this important, such as bare shielding of the SSH port from brute-force attacks).
|
||||||
|
However, if you need these features, you should use UDP mode.
|
||||||
|
.PP
|
||||||
|
It is always wise to specify three or more ports that are not monotonically
|
||||||
|
increasing or decreasing with a small stepsize (e.g. 1024,1025,1026)
|
||||||
|
to avoid accidentally triggering
|
||||||
|
the rule by a portscan.
|
||||||
|
.PP
|
||||||
|
Specifying the inter-knock timeout with \fB--time\fP is mandatory in TCP mode,
|
||||||
|
to avoid permanent denial of services by clogging up the peer knock-state tracking table
|
||||||
|
that xt_pknock internally keeps, should there be a DDoS on the
|
||||||
|
first-in-row knock port from more hostile IP addresses than what the actual size
|
||||||
|
of this table is (defaults to 16, can be changed via the "peer_hasht_ents" module parameter).
|
||||||
|
It is also wise to use as short a time as possible (1 second) for \fB--time\fP
|
||||||
|
for this very reason. You may also consider increasing the size
|
||||||
|
of the peer knock-state tracking table. Using \fB--strict\fP also helps,
|
||||||
|
as it requires the knock sequence to be exact. This means that if the
|
||||||
|
hostile client sends more knocks to the same port, xt_pknock will
|
||||||
|
mark such attempt as failed knock sequence and will forget it immediately.
|
||||||
|
To completely thwart this kind of DDoS, knock-ports would need to have
|
||||||
|
an additional rate-limit protection. Or you may consider using UDP mode.
|
||||||
|
.PP
|
||||||
|
\fBUDP mode\fP:
|
||||||
|
.PP
|
||||||
|
This mode is immune against eavesdropping, replaying and spoofing attacks.
|
||||||
|
It is also immune against DDoS attack on the knockport.
|
||||||
|
.PP
|
||||||
|
For this mode to work, the clock difference on the client and on the server
|
||||||
|
must be below 1 minute. Synchronizing time on both ends by means
|
||||||
|
of NTP or rdate is strongly suggested.
|
||||||
|
.PP
|
||||||
|
There is a rate limiter built into xt_pknock which blocks any subsequent
|
||||||
|
open attempt in UDP mode should the request arrive within less than one
|
||||||
|
minute since the first successful open. This is intentional;
|
||||||
|
it thwarts eventual spoofing attacks.
|
||||||
|
.PP
|
||||||
|
Because the payload value of an UDP knock packet is influenced by client's IP address,
|
||||||
|
UDP mode cannot be used across NAT.
|
||||||
|
.PP
|
||||||
|
For sending UDP "SPA" packets, you may use either \fBknock.sh\fP or
|
||||||
|
\fBknock-orig.sh\fP. These may be found in doc/pknock/util.
|
158
extensions/libxt_psd.c
Normal file
158
extensions/libxt_psd.c
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
Shared library add-on to iptables to add PSD support
|
||||||
|
|
||||||
|
Copyright (C) 2000,2001 astaro AG
|
||||||
|
|
||||||
|
This file is distributed under the terms of the GNU General Public
|
||||||
|
License (GPL). Copies of the GPL can be obtained from:
|
||||||
|
ftp://prep.ai.mit.edu/pub/gnu/GPL
|
||||||
|
|
||||||
|
2000-05-04 Markus Hennig <hennig@astaro.de> : initial
|
||||||
|
2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
|
||||||
|
2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
|
||||||
|
2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
|
||||||
|
2003-03-02 Harald Welte <laforge@netfilter.org>: fix 'storage' bug
|
||||||
|
2008-04-03 Mohd Nawawi <nawawi@tracenetworkcorporation.com>: update to 2.6.24 / 1.4 code
|
||||||
|
2008-06-24 Mohd Nawawi <nawawi@tracenetworkcorporation.com>: update to 2.6.24 / 1.4.1 code
|
||||||
|
2009-08-07 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to xtables-addons
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <xtables.h>
|
||||||
|
#include <linux/netfilter/x_tables.h>
|
||||||
|
#include "xt_psd.h"
|
||||||
|
|
||||||
|
/* Function which prints out usage message. */
|
||||||
|
static void psd_mt_help(void) {
|
||||||
|
printf(
|
||||||
|
"psd match options:\n"
|
||||||
|
" --psd-weight-threshold threshhold Portscan detection weight threshold\n"
|
||||||
|
" --psd-delay-threshold delay Portscan detection delay threshold\n"
|
||||||
|
" --psd-lo-ports-weight lo Privileged ports weight\n"
|
||||||
|
" --psd-hi-ports-weight hi High ports weight\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct option psd_mt_opts[] = {
|
||||||
|
{.name = "psd-weight-threshold", .has_arg = true, .val = '1'},
|
||||||
|
{.name = "psd-delay-threshold", .has_arg = true, .val = '2'},
|
||||||
|
{.name = "psd-lo-ports-weight", .has_arg = true, .val = '3'},
|
||||||
|
{.name = "psd-hi-ports-weight", .has_arg = true, .val = '4'},
|
||||||
|
{NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initialize the target. */
|
||||||
|
static void psd_mt_init(struct xt_entry_match *match) {
|
||||||
|
struct xt_psd_info *psdinfo = (struct xt_psd_info *)match->data;
|
||||||
|
psdinfo->weight_threshold = SCAN_WEIGHT_THRESHOLD;
|
||||||
|
psdinfo->delay_threshold = SCAN_DELAY_THRESHOLD;
|
||||||
|
psdinfo->lo_ports_weight = PORT_WEIGHT_PRIV;
|
||||||
|
psdinfo->hi_ports_weight = PORT_WEIGHT_HIGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define XT_PSD_OPT_CTRESH 0x01
|
||||||
|
#define XT_PSD_OPT_DTRESH 0x02
|
||||||
|
#define XT_PSD_OPT_LPWEIGHT 0x04
|
||||||
|
#define XT_PSD_OPT_HPWEIGHT 0x08
|
||||||
|
|
||||||
|
static int psd_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
|
const void *entry, struct xt_entry_match **match)
|
||||||
|
{
|
||||||
|
struct xt_psd_info *psdinfo = (struct xt_psd_info *)(*match)->data;
|
||||||
|
unsigned int num;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
/* PSD-weight-threshold */
|
||||||
|
case '1':
|
||||||
|
if (*flags & XT_PSD_OPT_CTRESH)
|
||||||
|
xtables_error(PARAMETER_PROBLEM,"Can't specify --psd-weight-threshold twice");
|
||||||
|
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "bad --psd-weight-threshold '%s'", optarg);
|
||||||
|
psdinfo->weight_threshold = num;
|
||||||
|
*flags |= XT_PSD_OPT_CTRESH;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* PSD-delay-threshold */
|
||||||
|
case '2':
|
||||||
|
if (*flags & XT_PSD_OPT_DTRESH)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-delay-threshold twice");
|
||||||
|
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "bad --psd-delay-threshold '%s'", optarg);
|
||||||
|
psdinfo->delay_threshold = num;
|
||||||
|
*flags |= XT_PSD_OPT_DTRESH;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* PSD-lo-ports-weight */
|
||||||
|
case '3':
|
||||||
|
if (*flags & XT_PSD_OPT_LPWEIGHT)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-lo-ports-weight twice");
|
||||||
|
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "bad --psd-lo-ports-weight '%s'", optarg);
|
||||||
|
psdinfo->lo_ports_weight = num;
|
||||||
|
*flags |= XT_PSD_OPT_LPWEIGHT;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* PSD-hi-ports-weight */
|
||||||
|
case '4':
|
||||||
|
if (*flags & XT_PSD_OPT_HPWEIGHT)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "Can't specify --psd-hi-ports-weight twice");
|
||||||
|
if (!xtables_strtoui(optarg, NULL, &num, 0, PSD_MAX_RATE))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "bad --psd-hi-ports-weight '%s'", optarg);
|
||||||
|
psdinfo->hi_ports_weight = num;
|
||||||
|
*flags |= XT_PSD_OPT_HPWEIGHT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Final check; nothing. */
|
||||||
|
static void psd_mt_final_check(unsigned int flags) {}
|
||||||
|
|
||||||
|
/* Prints out the targinfo. */
|
||||||
|
static void psd_mt_print(const void *ip, const struct xt_entry_match *match, int numeric)
|
||||||
|
{
|
||||||
|
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
|
||||||
|
printf("psd ");
|
||||||
|
printf("weight-threshold: %u ", psdinfo->weight_threshold);
|
||||||
|
printf("delay-threshold: %u ", psdinfo->delay_threshold);
|
||||||
|
printf("lo-ports-weight: %u ", psdinfo->lo_ports_weight);
|
||||||
|
printf("hi-ports-weight: %u ", psdinfo->hi_ports_weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Saves the union ipt_targinfo in parsable form to stdout. */
|
||||||
|
static void psd_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||||
|
{
|
||||||
|
const struct xt_psd_info *psdinfo = (const struct xt_psd_info *)match->data;
|
||||||
|
printf("--psd-weight-threshold %u ", psdinfo->weight_threshold);
|
||||||
|
printf("--psd-delay-threshold %u ", psdinfo->delay_threshold);
|
||||||
|
printf("--psd-lo-ports-weight %u ", psdinfo->lo_ports_weight);
|
||||||
|
printf("--psd-hi-ports-weight %u ", psdinfo->hi_ports_weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xtables_match psd_mt_reg = {
|
||||||
|
.name = "psd",
|
||||||
|
.version = XTABLES_VERSION,
|
||||||
|
.revision = 1,
|
||||||
|
.family = PF_INET,
|
||||||
|
.size = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||||
|
.userspacesize = XT_ALIGN(sizeof(struct xt_psd_info)),
|
||||||
|
.help = psd_mt_help,
|
||||||
|
.init = psd_mt_init,
|
||||||
|
.parse = psd_mt_parse,
|
||||||
|
.final_check = psd_mt_final_check,
|
||||||
|
.print = psd_mt_print,
|
||||||
|
.save = psd_mt_save,
|
||||||
|
.extra_opts = psd_mt_opts,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void psd_mt_ldr(void)
|
||||||
|
{
|
||||||
|
xtables_register_match(&psd_mt_reg);
|
||||||
|
}
|
||||||
|
|
18
extensions/libxt_psd.man
Normal file
18
extensions/libxt_psd.man
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
Attempt to detect TCP and UDP port scans. This match was derived from
|
||||||
|
Solar Designer's scanlogd.
|
||||||
|
.TP
|
||||||
|
\fB\-\-psd\-weight\-threshold\fP \fIthreshold\fP
|
||||||
|
Total weight of the latest TCP/UDP packets with different
|
||||||
|
destination ports coming from the same host to be treated as port
|
||||||
|
scan sequence.
|
||||||
|
.TP
|
||||||
|
\fB\-\-psd\-delay\-threshold\fP \fIdelay\fP
|
||||||
|
Delay (in hundredths of second) for the packets with different
|
||||||
|
destination ports coming from the same host to be treated as
|
||||||
|
possible port scan subsequence.
|
||||||
|
.TP
|
||||||
|
\fB\-\-psd\-lo\-ports\-weight\fP \fIweight\fP
|
||||||
|
Weight of the packet with privileged (<=1024) destination port.
|
||||||
|
.TP
|
||||||
|
\fB\-\-psd\-hi\-ports\-weight\fP \fIweight\fP
|
||||||
|
Weight of the packet with non-priviliged destination port.
|
@@ -121,7 +121,7 @@ static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
|
|||||||
|
|
||||||
static struct xtables_match quota_mt2_reg = {
|
static struct xtables_match quota_mt2_reg = {
|
||||||
.family = AF_UNSPEC,
|
.family = AF_UNSPEC,
|
||||||
.revision = 2,
|
.revision = 3,
|
||||||
.name = "quota2",
|
.name = "quota2",
|
||||||
.version = XTABLES_VERSION,
|
.version = XTABLES_VERSION,
|
||||||
.size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)),
|
.size = XT_ALIGN(sizeof (struct xt_quota_mtinfo2)),
|
||||||
|
@@ -7,25 +7,25 @@ When counting down from the initial quota, the counter will stop at 0 and
|
|||||||
the match will return false, just like the original "quota" match. In growing
|
the match will return false, just like the original "quota" match. In growing
|
||||||
(upcounting) mode, it will always return true.
|
(upcounting) mode, it will always return true.
|
||||||
.TP
|
.TP
|
||||||
\fB--grow\fP
|
\fB\-\-grow\fP
|
||||||
Count upwards instead of downwards.
|
Count upwards instead of downwards.
|
||||||
.TP
|
.TP
|
||||||
\fB--name\fP \fIname\fP
|
\fB\-\-name\fP \fIname\fP
|
||||||
Assign the counter a specific name. This option must be present, as an empty
|
Assign the counter a specific name. This option must be present, as an empty
|
||||||
name is not allowed. Names starting with a dot or names containing a slash are
|
name is not allowed. Names starting with a dot or names containing a slash are
|
||||||
prohibited.
|
prohibited.
|
||||||
.TP
|
.TP
|
||||||
[\fB!\fP] \fB--quota\fP \fIiq\fP
|
[\fB!\fP] \fB\-\-quota\fP \fIiq\fP
|
||||||
Specify the initial quota for this counter. If the counter already exists,
|
Specify the initial quota for this counter. If the counter already exists,
|
||||||
it is not reset. An "!" may be used to invert the result of the match. The
|
it is not reset. An "!" may be used to invert the result of the match. The
|
||||||
negation has no effect when \fB--grow\fP is used.
|
negation has no effect when \fB\-\-grow\fP is used.
|
||||||
.TP
|
.TP
|
||||||
\fB--packets\fP
|
\fB\-\-packets\fP
|
||||||
Count packets instead of bytes that passed the quota2 match.
|
Count packets instead of bytes that passed the quota2 match.
|
||||||
.PP
|
.PP
|
||||||
Because counters in quota2 can be shared, you can combine them for various
|
Because counters in quota2 can be shared, you can combine them for various
|
||||||
purposes, for example, a bytebucket filter that only lets as much traffic go
|
purposes, for example, a bytebucket filter that only lets as much traffic go
|
||||||
out as has come in:
|
out as has come in:
|
||||||
.PP
|
.PP
|
||||||
-A INPUT -p tcp --dport 6881 -m quota --name bt --grow
|
\-A INPUT \-p tcp \-\-dport 6881 \-m quota \-\-name bt \-\-grow;
|
||||||
-A OUTPUT -p tcp --sport 6881 -m quota --name bt
|
\-A OUTPUT \-p tcp \-\-sport 6881 \-m quota \-\-name bt;
|
||||||
|
1
extensions/pknock/.gitignore
vendored
Normal file
1
extensions/pknock/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/pknlusr
|
5
extensions/pknock/Kbuild
Normal file
5
extensions/pknock/Kbuild
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
EXTRA_CFLAGS = -I${src}/..
|
||||||
|
|
||||||
|
obj-m += xt_pknock.o
|
5
extensions/pknock/Makefile.am
Normal file
5
extensions/pknock/Makefile.am
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
include ../../Makefile.extra
|
||||||
|
|
||||||
|
noinst_PROGRAMS = pknlusr
|
3
extensions/pknock/Mbuild
Normal file
3
extensions/pknock/Mbuild
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- Makefile -*-
|
||||||
|
|
||||||
|
obj-${build_pknock} += libxt_pknock.so
|
343
extensions/pknock/libxt_pknock.c
Normal file
343
extensions/pknock/libxt_pknock.c
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
/*
|
||||||
|
* Shared library add-on to iptables to add Port Knocking and SPA matching
|
||||||
|
* support.
|
||||||
|
*
|
||||||
|
* (C) 2006-2009 J. Federico Hernandez <fede.hernandez@gmail.com>
|
||||||
|
* (C) 2006 Luis Floreani <luis.floreani@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is released under the terms of GNU GPL version 2.
|
||||||
|
*/
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <xtables.h>
|
||||||
|
#include <linux/netfilter.h>
|
||||||
|
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
#include "xt_pknock.h"
|
||||||
|
|
||||||
|
static const struct option pknock_mt_opts[] = {
|
||||||
|
/* .name, .has_arg, .flag, .val */
|
||||||
|
{.name = "knockports", .has_arg = true, .val = 'k'},
|
||||||
|
{.name = "time", .has_arg = true, .val = 't'},
|
||||||
|
{.name = "autoclose", .has_arg = true, .val = 'a'},
|
||||||
|
{.name = "name", .has_arg = true, .val = 'n'},
|
||||||
|
{.name = "opensecret", .has_arg = true, .val = 'o'},
|
||||||
|
{.name = "closesecret", .has_arg = true, .val = 'z'},
|
||||||
|
{.name = "strict", .has_arg = false, .val = 'x'},
|
||||||
|
{.name = "checkip", .has_arg = false, .val = 'c'},
|
||||||
|
{NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void pknock_mt_help(void)
|
||||||
|
{
|
||||||
|
printf("pknock match options:\n"
|
||||||
|
" --knockports port[,port,port,...] "
|
||||||
|
"Matches destination port(s).\n"
|
||||||
|
" --time seconds\n"
|
||||||
|
"Max allowed time between knocks.\n"
|
||||||
|
" --autoclose minutes\n"
|
||||||
|
"Time after which to automatically close opened\n"
|
||||||
|
"\t\t\t\t\tport(s).\n"
|
||||||
|
" --strict "
|
||||||
|
"Knocks sequence must be exact.\n"
|
||||||
|
" --name rule_name "
|
||||||
|
"Rule name.\n"
|
||||||
|
" --checkip "
|
||||||
|
"Matches if the source ip is in the list.\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
parse_ports(const char *portstring, uint16_t *ports, const char *proto)
|
||||||
|
{
|
||||||
|
char *buffer, *cp, *next;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
buffer = strdup(portstring);
|
||||||
|
if (buffer == NULL)
|
||||||
|
xtables_error(OTHER_PROBLEM, "strdup failed");
|
||||||
|
|
||||||
|
for (cp = buffer, i = 0; cp != NULL && i < XT_PKNOCK_MAX_PORTS; cp = next, ++i)
|
||||||
|
{
|
||||||
|
next=strchr(cp, ',');
|
||||||
|
if (next != NULL)
|
||||||
|
*next++ = '\0';
|
||||||
|
ports[i] = xtables_parse_port(cp, proto);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp != NULL)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, "too many ports specified");
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
proto_to_name(uint8_t proto)
|
||||||
|
{
|
||||||
|
switch (proto) {
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
return "tcp";
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
return "udp";
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
check_proto(uint16_t pnum, uint8_t invflags)
|
||||||
|
{
|
||||||
|
char *proto;
|
||||||
|
|
||||||
|
if (invflags & XT_INV_PROTO)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
|
||||||
|
|
||||||
|
if ((proto = proto_to_name(pnum)) != NULL)
|
||||||
|
return proto;
|
||||||
|
else if (pnum == 0)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK "needs `-p tcp' or `-p udp'");
|
||||||
|
else
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK "only works with TCP and UDP.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
__pknock_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
|
struct xt_entry_match **match, uint16_t pnum,
|
||||||
|
uint16_t invflags)
|
||||||
|
{
|
||||||
|
const char *proto;
|
||||||
|
struct xt_pknock_mtinfo *info = (void *)(*match)->data;
|
||||||
|
unsigned int tmp;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'k': /* --knockports */
|
||||||
|
if (*flags & XT_PKNOCK_KNOCKPORT)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot use --knockports twice.\n");
|
||||||
|
proto = check_proto(pnum, invflags);
|
||||||
|
|
||||||
|
info->ports_count = parse_ports(optarg, info->port, proto);
|
||||||
|
info->option |= XT_PKNOCK_KNOCKPORT;
|
||||||
|
*flags |= XT_PKNOCK_KNOCKPORT;
|
||||||
|
#if DEBUG
|
||||||
|
printf("ports_count: %d\n", info->ports_count);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't': /* --time */
|
||||||
|
if (*flags & XT_PKNOCK_TIME)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot use --time twice.\n");
|
||||||
|
info->max_time = atoi(optarg);
|
||||||
|
if (info->max_time == 0)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"--time number must be > 0.\n");
|
||||||
|
info->option |= XT_PKNOCK_TIME;
|
||||||
|
*flags |= XT_PKNOCK_TIME;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a': /* --autoclose */
|
||||||
|
if (*flags & XT_PKNOCK_AUTOCLOSE)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot use --autoclose twice.\n");
|
||||||
|
if (!xtables_strtoui(optarg, NULL, &tmp, 0, ~0U))
|
||||||
|
xtables_param_act(XTF_BAD_VALUE, PKNOCK,
|
||||||
|
"--autoclose", optarg);
|
||||||
|
info->autoclose_time = tmp;
|
||||||
|
info->option |= XT_PKNOCK_AUTOCLOSE;
|
||||||
|
*flags |= XT_PKNOCK_AUTOCLOSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n': /* --name */
|
||||||
|
if (*flags & XT_PKNOCK_NAME)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot use --name twice.\n");
|
||||||
|
memset(info->rule_name, 0, sizeof(info->rule_name));
|
||||||
|
strncpy(info->rule_name, optarg, sizeof(info->rule_name) - 1);
|
||||||
|
|
||||||
|
info->rule_name_len = strlen(info->rule_name);
|
||||||
|
info->option |= XT_PKNOCK_NAME;
|
||||||
|
*flags |= XT_PKNOCK_NAME;
|
||||||
|
#if DEBUG
|
||||||
|
printf("info->rule_name: %s\n", info->rule_name);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'o': /* --opensecret */
|
||||||
|
if (*flags & XT_PKNOCK_OPENSECRET)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot use --opensecret twice.\n");
|
||||||
|
memset(info->open_secret, 0, sizeof(info->open_secret));
|
||||||
|
strncpy(info->open_secret, optarg, sizeof(info->open_secret) - 1);
|
||||||
|
|
||||||
|
info->open_secret_len = strlen(info->open_secret);
|
||||||
|
info->option |= XT_PKNOCK_OPENSECRET;
|
||||||
|
*flags |= XT_PKNOCK_OPENSECRET;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'z': /* --closesecret */
|
||||||
|
if (*flags & XT_PKNOCK_CLOSESECRET)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot use --closesecret twice.\n");
|
||||||
|
memset(info->close_secret, 0, sizeof(info->close_secret));
|
||||||
|
strncpy(info->close_secret, optarg, sizeof(info->close_secret) - 1);
|
||||||
|
|
||||||
|
info->close_secret_len = strlen(info->close_secret);
|
||||||
|
info->option |= XT_PKNOCK_CLOSESECRET;
|
||||||
|
*flags |= XT_PKNOCK_CLOSESECRET;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c': /* --checkip */
|
||||||
|
if (*flags & XT_PKNOCK_CHECKIP)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot use --checkip twice.\n");
|
||||||
|
info->option |= XT_PKNOCK_CHECKIP;
|
||||||
|
*flags |= XT_PKNOCK_CHECKIP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x': /* --strict */
|
||||||
|
if (*flags & XT_PKNOCK_STRICT)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot use --strict twice.\n");
|
||||||
|
info->option |= XT_PKNOCK_STRICT;
|
||||||
|
*flags |= XT_PKNOCK_STRICT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invert)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK "does not support invert.");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pknock_mt_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
|
const void *e, struct xt_entry_match **match)
|
||||||
|
{
|
||||||
|
const struct ipt_entry *entry = e;
|
||||||
|
return __pknock_parse(c, argv, invert, flags, match,
|
||||||
|
entry->ip.proto, entry->ip.invflags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pknock_mt_check(unsigned int flags)
|
||||||
|
{
|
||||||
|
if (!(flags & XT_PKNOCK_NAME))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"--name option is required.\n");
|
||||||
|
|
||||||
|
if (flags & XT_PKNOCK_KNOCKPORT) {
|
||||||
|
if (flags & XT_PKNOCK_CHECKIP)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot specify --knockports with --checkip.\n");
|
||||||
|
if ((flags & XT_PKNOCK_OPENSECRET)
|
||||||
|
&& !(flags & XT_PKNOCK_CLOSESECRET))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"--opensecret must go with --closesecret.\n");
|
||||||
|
if ((flags & XT_PKNOCK_CLOSESECRET)
|
||||||
|
&& !(flags & XT_PKNOCK_OPENSECRET))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"--closesecret must go with --opensecret.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & XT_PKNOCK_CHECKIP) {
|
||||||
|
if (flags & XT_PKNOCK_KNOCKPORT)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot specify --checkip with --knockports.\n");
|
||||||
|
if ((flags & XT_PKNOCK_OPENSECRET)
|
||||||
|
|| (flags & XT_PKNOCK_CLOSESECRET))
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot specify --opensecret and"
|
||||||
|
" --closesecret with --checkip.\n");
|
||||||
|
if (flags & XT_PKNOCK_TIME)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot specify --time with --checkip.\n");
|
||||||
|
if (flags & XT_PKNOCK_AUTOCLOSE)
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"cannot specify --autoclose with --checkip.\n");
|
||||||
|
} else if (!(flags & (XT_PKNOCK_OPENSECRET | XT_PKNOCK_TIME))) {
|
||||||
|
xtables_error(PARAMETER_PROBLEM, PKNOCK
|
||||||
|
"you must specify --time.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pknock_mt_print(const void *ip,
|
||||||
|
const struct xt_entry_match *match, int numeric)
|
||||||
|
{
|
||||||
|
const struct xt_pknock_mtinfo *info = (void *)match->data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("pknock ");
|
||||||
|
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
||||||
|
printf("knockports ");
|
||||||
|
for (i = 0; i < info->ports_count; ++i)
|
||||||
|
printf("%s%d", i ? "," : "", info->port[i]);
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
if (info->option & XT_PKNOCK_TIME)
|
||||||
|
printf("time %ld ", (long)info->max_time);
|
||||||
|
if (info->option & XT_PKNOCK_AUTOCLOSE)
|
||||||
|
printf("autoclose %lu ", (unsigned long)info->autoclose_time);
|
||||||
|
if (info->option & XT_PKNOCK_NAME)
|
||||||
|
printf("name %s ", info->rule_name);
|
||||||
|
if (info->option & XT_PKNOCK_OPENSECRET)
|
||||||
|
printf("opensecret ");
|
||||||
|
if (info->option & XT_PKNOCK_CLOSESECRET)
|
||||||
|
printf("closesecret ");
|
||||||
|
if (info->option & XT_PKNOCK_STRICT)
|
||||||
|
printf("strict ");
|
||||||
|
if (info->option & XT_PKNOCK_CHECKIP)
|
||||||
|
printf("checkip ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pknock_mt_save(const void *ip, const struct xt_entry_match *match)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const struct xt_pknock_mtinfo *info = (void *)match->data;
|
||||||
|
|
||||||
|
if (info->option & XT_PKNOCK_KNOCKPORT) {
|
||||||
|
printf("--knockports ");
|
||||||
|
for (i = 0; i < info->ports_count; ++i)
|
||||||
|
printf("%s%d", i ? "," : "", info->port[i]);
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
if (info->option & XT_PKNOCK_TIME)
|
||||||
|
printf("--time %ld ", (long)info->max_time);
|
||||||
|
if (info->option & XT_PKNOCK_AUTOCLOSE)
|
||||||
|
printf("--autoclose %lu ",
|
||||||
|
(unsigned long)info->autoclose_time);
|
||||||
|
if (info->option & XT_PKNOCK_NAME)
|
||||||
|
printf("--name %s ", info->rule_name);
|
||||||
|
if (info->option & XT_PKNOCK_OPENSECRET)
|
||||||
|
printf("--opensecret ");
|
||||||
|
if (info->option & XT_PKNOCK_CLOSESECRET)
|
||||||
|
printf("--closesecret ");
|
||||||
|
if (info->option & XT_PKNOCK_STRICT)
|
||||||
|
printf("--strict ");
|
||||||
|
if (info->option & XT_PKNOCK_CHECKIP)
|
||||||
|
printf("--checkip ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xtables_match pknock_mt_reg = {
|
||||||
|
.name = "pknock",
|
||||||
|
.version = XTABLES_VERSION,
|
||||||
|
.revision = 1,
|
||||||
|
.family = AF_INET,
|
||||||
|
.size = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
|
||||||
|
.userspacesize = XT_ALIGN(sizeof(struct xt_pknock_mtinfo)),
|
||||||
|
.help = pknock_mt_help,
|
||||||
|
.parse = pknock_mt_parse,
|
||||||
|
.final_check = pknock_mt_check,
|
||||||
|
.print = pknock_mt_print,
|
||||||
|
.save = pknock_mt_save,
|
||||||
|
.extra_opts = pknock_mt_opts,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void pknock_mt_ldr(void)
|
||||||
|
{
|
||||||
|
xtables_register_match(&pknock_mt_reg);
|
||||||
|
}
|
93
extensions/pknock/pknlusr.c
Normal file
93
extensions/pknock/pknlusr.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/connector.h>
|
||||||
|
|
||||||
|
#include "xt_pknock.h"
|
||||||
|
|
||||||
|
#define GROUP 1
|
||||||
|
|
||||||
|
static struct sockaddr_nl src_addr, dest_addr;
|
||||||
|
static struct msghdr msg;
|
||||||
|
static int sock_fd;
|
||||||
|
|
||||||
|
static unsigned char *buf;
|
||||||
|
|
||||||
|
static struct xt_pknock_nl_msg *nlmsg;
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
socklen_t addrlen;
|
||||||
|
int status;
|
||||||
|
int group = GROUP;
|
||||||
|
struct cn_msg *cnmsg;
|
||||||
|
|
||||||
|
int i, buf_size;
|
||||||
|
|
||||||
|
const char *ip;
|
||||||
|
char ipbuf[48];
|
||||||
|
|
||||||
|
sock_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
|
||||||
|
|
||||||
|
if (sock_fd == -1) {
|
||||||
|
perror("socket()");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&src_addr, 0, sizeof(src_addr));
|
||||||
|
src_addr.nl_family = AF_NETLINK;
|
||||||
|
src_addr.nl_pid = getpid();
|
||||||
|
src_addr.nl_groups = group;
|
||||||
|
|
||||||
|
status = bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
|
||||||
|
|
||||||
|
if (status == -1) {
|
||||||
|
close(sock_fd);
|
||||||
|
perror("bind()");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&dest_addr, 0, sizeof(dest_addr));
|
||||||
|
dest_addr.nl_family = AF_NETLINK;
|
||||||
|
dest_addr.nl_pid = 0;
|
||||||
|
dest_addr.nl_groups = group;
|
||||||
|
|
||||||
|
buf_size = sizeof(struct xt_pknock_nl_msg) + sizeof(struct cn_msg) + sizeof(struct nlmsghdr);
|
||||||
|
buf = malloc(buf_size);
|
||||||
|
|
||||||
|
if (!buf) {
|
||||||
|
perror("malloc()");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
addrlen = sizeof(dest_addr);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
memset(buf, 0, buf_size);
|
||||||
|
|
||||||
|
status = recvfrom(sock_fd, buf, buf_size, 0, (struct sockaddr *)&dest_addr, &addrlen);
|
||||||
|
|
||||||
|
if (status <= 0) {
|
||||||
|
perror("recvfrom()");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlmsg = (struct xt_pknock_nl_msg *) (buf + sizeof(struct cn_msg) + sizeof(struct nlmsghdr));
|
||||||
|
|
||||||
|
ip = inet_ntop(AF_INET, &nlmsg->peer_ip, ipbuf, sizeof(ipbuf));
|
||||||
|
printf("rule_name: %s - ip %s\n", nlmsg->rule_name, ip);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
close(sock_fd);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
13
extensions/pknock/xt_pknock.Kconfig
Normal file
13
extensions/pknock/xt_pknock.Kconfig
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
config NETFILTER_XT_MATCH_PKNOCK
|
||||||
|
tristate "Port knocking match support"
|
||||||
|
depends on NETFILTER_XTABLES && CONNECTOR
|
||||||
|
---help---
|
||||||
|
pknock match implements so-called Port Knocking, a stealthy system
|
||||||
|
for network authentication: client sends packets to selected, closed
|
||||||
|
ports on target machine in a specific sequence. The target machine
|
||||||
|
(which has pknock match rule set up) then decides whether to
|
||||||
|
unblock or block (again) its protected port with listening
|
||||||
|
service. This can be, for instance, used to avoid brute force attacks
|
||||||
|
on ssh or ftp services.
|
||||||
|
|
||||||
|
For more informations go to: http://portknocko.berlios.de/
|
1200
extensions/pknock/xt_pknock.c
Normal file
1200
extensions/pknock/xt_pknock.c
Normal file
File diff suppressed because it is too large
Load Diff
53
extensions/pknock/xt_pknock.h
Normal file
53
extensions/pknock/xt_pknock.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Kernel module to implement Port Knocking and SPA matching support.
|
||||||
|
*
|
||||||
|
* (C) 2006-2008 J. Federico Hernandez <fede.hernandez@gmail.com>
|
||||||
|
* (C) 2006 Luis Floreani <luis.floreani@gmail.com>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* This program is released under the terms of GNU GPL version 2.
|
||||||
|
*/
|
||||||
|
#ifndef _XT_PKNOCK_H
|
||||||
|
#define _XT_PKNOCK_H
|
||||||
|
|
||||||
|
#define PKNOCK "xt_pknock: "
|
||||||
|
|
||||||
|
enum {
|
||||||
|
XT_PKNOCK_KNOCKPORT = 1 << 0,
|
||||||
|
XT_PKNOCK_TIME = 1 << 1,
|
||||||
|
XT_PKNOCK_NAME = 1 << 2,
|
||||||
|
XT_PKNOCK_STRICT = 1 << 3,
|
||||||
|
XT_PKNOCK_CHECKIP = 1 << 4,
|
||||||
|
XT_PKNOCK_OPENSECRET = 1 << 5,
|
||||||
|
XT_PKNOCK_CLOSESECRET = 1 << 6,
|
||||||
|
XT_PKNOCK_AUTOCLOSE = 1 << 7,
|
||||||
|
|
||||||
|
/* Can never change these, as they are make up the user protocol. */
|
||||||
|
XT_PKNOCK_MAX_PORTS = 15,
|
||||||
|
XT_PKNOCK_MAX_BUF_LEN = 31,
|
||||||
|
XT_PKNOCK_MAX_PASSWD_LEN = 31,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
struct xt_pknock_mtinfo {
|
||||||
|
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
|
||||||
|
uint32_t rule_name_len;
|
||||||
|
char open_secret[XT_PKNOCK_MAX_PASSWD_LEN+1];
|
||||||
|
uint32_t open_secret_len;
|
||||||
|
char close_secret[XT_PKNOCK_MAX_PASSWD_LEN+1];
|
||||||
|
uint32_t close_secret_len;
|
||||||
|
uint8_t option; /* --time, --knock-port, ... */
|
||||||
|
uint8_t ports_count; /* number of ports */
|
||||||
|
uint16_t port[XT_PKNOCK_MAX_PORTS]; /* port[,port,port,...] */
|
||||||
|
uint32_t max_time; /* max matching time between ports */
|
||||||
|
uint32_t autoclose_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct xt_pknock_nl_msg {
|
||||||
|
char rule_name[XT_PKNOCK_MAX_BUF_LEN+1];
|
||||||
|
__be32 peer_ip;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _XT_PKNOCK_H */
|
@@ -119,19 +119,18 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
|
|||||||
addr_type = RTN_LOCAL;
|
addr_type = RTN_LOCAL;
|
||||||
|
|
||||||
/* ip_route_me_harder expects skb->dst to be set */
|
/* ip_route_me_harder expects skb->dst to be set */
|
||||||
dst_hold(oldskb->dst);
|
skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
|
||||||
nskb->dst = oldskb->dst;
|
|
||||||
|
|
||||||
if (ip_route_me_harder(&nskb, addr_type))
|
if (ip_route_me_harder(&nskb, addr_type))
|
||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
else
|
else
|
||||||
niph = ip_hdr(nskb);
|
niph = ip_hdr(nskb);
|
||||||
|
|
||||||
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
|
niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
|
||||||
nskb->ip_summed = CHECKSUM_NONE;
|
nskb->ip_summed = CHECKSUM_NONE;
|
||||||
|
|
||||||
/* "Never happens" */
|
/* "Never happens" */
|
||||||
if (nskb->len > dst_mtu(nskb->dst))
|
if (nskb->len > dst_mtu(skb_dst(nskb)))
|
||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
|
|
||||||
nf_ct_attach(nskb, oldskb);
|
nf_ct_attach(nskb, oldskb);
|
||||||
|
@@ -167,20 +167,20 @@ static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
|
|||||||
nskb->ip_summed = CHECKSUM_NONE;
|
nskb->ip_summed = CHECKSUM_NONE;
|
||||||
|
|
||||||
/* Adjust IP TTL */
|
/* Adjust IP TTL */
|
||||||
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
|
niph->ttl = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
|
||||||
|
|
||||||
/* Adjust IP checksum */
|
/* Adjust IP checksum */
|
||||||
niph->check = 0;
|
niph->check = 0;
|
||||||
niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);
|
niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);
|
||||||
|
|
||||||
/* "Never happens" */
|
/* "Never happens" */
|
||||||
if (nskb->len > dst_mtu(nskb->dst))
|
if (nskb->len > dst_mtu(skb_dst(nskb)))
|
||||||
goto free_nskb;
|
goto free_nskb;
|
||||||
|
|
||||||
nf_ct_attach(nskb, oldskb);
|
nf_ct_attach(nskb, oldskb);
|
||||||
|
|
||||||
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
|
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL,
|
||||||
dst_output);
|
skb_dst(nskb)->dev, dst_output);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free_nskb:
|
free_nskb:
|
||||||
@@ -192,7 +192,7 @@ tarpit_tg(struct sk_buff **pskb, const struct xt_target_param *par)
|
|||||||
{
|
{
|
||||||
const struct sk_buff *skb = *pskb;
|
const struct sk_buff *skb = *pskb;
|
||||||
const struct iphdr *iph = ip_hdr(skb);
|
const struct iphdr *iph = ip_hdr(skb);
|
||||||
const struct rtable *rt = (const void *)skb->dst;
|
const struct rtable *rt = skb_rtable(skb);
|
||||||
|
|
||||||
/* Do we have an input route cache entry? (Not in PREROUTING.) */
|
/* Do we have an input route cache entry? (Not in PREROUTING.) */
|
||||||
if (rt == NULL)
|
if (rt == NULL)
|
||||||
|
@@ -79,9 +79,9 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_release(skb->dst);
|
dst_release(skb_dst(skb));
|
||||||
skb->dst = &rt->u.dst;
|
skb_dst_set(skb, &rt->u.dst);
|
||||||
skb->dev = skb->dst->dev;
|
skb->dev = rt->u.dst.dev;
|
||||||
skb->protocol = htons(ETH_P_IP);
|
skb->protocol = htons(ETH_P_IP);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ static inline bool dev_hh_avail(const struct net_device *dev)
|
|||||||
*/
|
*/
|
||||||
static void tee_tg_send(struct sk_buff *skb)
|
static void tee_tg_send(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
const struct dst_entry *dst = skb->dst;
|
const struct dst_entry *dst = skb_dst(skb);
|
||||||
const struct net_device *dev = dst->dev;
|
const struct net_device *dev = dst->dev;
|
||||||
unsigned int hh_len = LL_RESERVED_SPACE(dev);
|
unsigned int hh_len = LL_RESERVED_SPACE(dev);
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ tee_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
|
|||||||
/*
|
/*
|
||||||
* Copy the skb, and route the copy. Will later return %XT_CONTINUE for
|
* Copy the skb, and route the copy. Will later return %XT_CONTINUE for
|
||||||
* the original skb, which should continue on its way as if nothing has
|
* the original skb, which should continue on its way as if nothing has
|
||||||
* happened. The copy should be independantly delivered to the TEE --gw.
|
* happened. The copy should be independently delivered to the TEE --gw.
|
||||||
*/
|
*/
|
||||||
skb = skb_copy(skb, GFP_ATOMIC);
|
skb = skb_copy(skb, GFP_ATOMIC);
|
||||||
if (skb == NULL) {
|
if (skb == NULL) {
|
||||||
@@ -251,9 +251,9 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_release(skb->dst);
|
dst_release(skb_dst(skb));
|
||||||
skb->dst = dst;
|
skb_dst_set(skb, dst);
|
||||||
skb->dev = skb->dst->dev;
|
skb->dev = dst->dev;
|
||||||
skb->protocol = htons(ETH_P_IPV6);
|
skb->protocol = htons(ETH_P_IPV6);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -55,7 +55,7 @@ struct condition_variable {
|
|||||||
|
|
||||||
/* proc_lock is a user context only semaphore used for write access */
|
/* proc_lock is a user context only semaphore used for write access */
|
||||||
/* to the conditions' list. */
|
/* to the conditions' list. */
|
||||||
static DECLARE_MUTEX(proc_lock);
|
static struct semaphore proc_lock;
|
||||||
|
|
||||||
static LIST_HEAD(conditions_list);
|
static LIST_HEAD(conditions_list);
|
||||||
static struct proc_dir_entry *proc_net_condition;
|
static struct proc_dir_entry *proc_net_condition;
|
||||||
@@ -232,6 +232,7 @@ static int __init condition_mt_init(void)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
sema_init(&proc_lock, 1);
|
||||||
proc_net_condition = proc_mkdir(dir_name, init_net__proc_net);
|
proc_net_condition = proc_mkdir(dir_name, init_net__proc_net);
|
||||||
if (proc_net_condition == NULL)
|
if (proc_net_condition == NULL)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
@@ -844,7 +844,13 @@ ipp2p_mt(const struct sk_buff *skb, const struct xt_match_param *par)
|
|||||||
if (tcph->rst) return 0; /* if RST bit is set bail out */
|
if (tcph->rst) return 0; /* if RST bit is set bail out */
|
||||||
|
|
||||||
haystack += tcph->doff * 4; /* get TCP-Header-Size */
|
haystack += tcph->doff * 4; /* get TCP-Header-Size */
|
||||||
|
if (tcph->doff * 4 > hlen) {
|
||||||
|
if (info->debug)
|
||||||
|
pr_info("TCP header indicated packet larger than it is\n");
|
||||||
|
hlen = 0;
|
||||||
|
} else {
|
||||||
hlen -= tcph->doff * 4;
|
hlen -= tcph->doff * 4;
|
||||||
|
}
|
||||||
while (matchlist[i].command) {
|
while (matchlist[i].command) {
|
||||||
if ((info->cmd & matchlist[i].command) == matchlist[i].command &&
|
if ((info->cmd & matchlist[i].command) == matchlist[i].command &&
|
||||||
hlen > matchlist[i].packet_len)
|
hlen > matchlist[i].packet_len)
|
||||||
|
6
extensions/xt_psd.Kconfig
Normal file
6
extensions/xt_psd.Kconfig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
config NETFILTER_XT_MATCH_PSD
|
||||||
|
tristate 'psd match support'
|
||||||
|
depends on NETFILTER_XTABLES && NETFILTER_ADVANCED
|
||||||
|
---help---
|
||||||
|
This option adds a `psd' match, which allows you to create rules in
|
||||||
|
any iptables table wich will detect TCP and UDP port scans.
|
335
extensions/xt_psd.c
Normal file
335
extensions/xt_psd.c
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
/*
|
||||||
|
This is a module which is used for PSD (portscan detection)
|
||||||
|
Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
|
||||||
|
and LOG target module.
|
||||||
|
|
||||||
|
Copyright (C) 2000,2001 astaro AG
|
||||||
|
|
||||||
|
This file is distributed under the terms of the GNU General Public
|
||||||
|
License (GPL). Copies of the GPL can be obtained from:
|
||||||
|
ftp://prep.ai.mit.edu/pub/gnu/GPL
|
||||||
|
|
||||||
|
2000-05-04 Markus Hennig <hennig@astaro.de> : initial
|
||||||
|
2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
|
||||||
|
2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
|
||||||
|
2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
|
||||||
|
2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
|
||||||
|
2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
|
||||||
|
2007-04-05 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to 2.6.18
|
||||||
|
2008-03-21 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to 2.6.24
|
||||||
|
2009-08-07 Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com> : ported to xtables-addons
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(x) KBUILD_MODNAME ": " x
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/moduleparam.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
|
#include <linux/ip.h>
|
||||||
|
#include <net/tcp.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
#include <linux/netfilter/x_tables.h>
|
||||||
|
#include "xt_psd.h"
|
||||||
|
#include "compat_xtables.h"
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
|
||||||
|
MODULE_AUTHOR("Martijn Lievaart <m@rtij.nl>");
|
||||||
|
MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
|
||||||
|
MODULE_AUTHOR(" Mohd Nawawi Mohamad Jamili <nawawi@tracenetworkcorporation.com>");
|
||||||
|
MODULE_DESCRIPTION("Xtables: PSD - portscan detection");
|
||||||
|
MODULE_ALIAS("ipt_psd");
|
||||||
|
|
||||||
|
#define HF_DADDR_CHANGING 0x01
|
||||||
|
#define HF_SPORT_CHANGING 0x02
|
||||||
|
#define HF_TOS_CHANGING 0x04
|
||||||
|
#define HF_TTL_CHANGING 0x08
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Information we keep per each target port
|
||||||
|
*/
|
||||||
|
struct port {
|
||||||
|
u_int16_t number; /* port number */
|
||||||
|
u_int8_t proto; /* protocol number */
|
||||||
|
u_int8_t and_flags; /* tcp ANDed flags */
|
||||||
|
u_int8_t or_flags; /* tcp ORed flags */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Information we keep per each source address.
|
||||||
|
*/
|
||||||
|
struct host {
|
||||||
|
struct host *next; /* Next entry with the same hash */
|
||||||
|
unsigned long timestamp; /* Last update time */
|
||||||
|
struct in_addr src_addr; /* Source address */
|
||||||
|
struct in_addr dest_addr; /* Destination address */
|
||||||
|
unsigned short src_port; /* Source port */
|
||||||
|
int count; /* Number of ports in the list */
|
||||||
|
int weight; /* Total weight of ports in the list */
|
||||||
|
struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */
|
||||||
|
unsigned char tos; /* TOS */
|
||||||
|
unsigned char ttl; /* TTL */
|
||||||
|
unsigned char flags; /* HF_ flags bitmask */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* State information.
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
spinlock_t lock;
|
||||||
|
struct host list[LIST_SIZE]; /* List of source addresses */
|
||||||
|
struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */
|
||||||
|
int index; /* Oldest entry to be replaced */
|
||||||
|
} state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an IP address into a hash table index.
|
||||||
|
*/
|
||||||
|
static inline int hashfunc(struct in_addr addr)
|
||||||
|
{
|
||||||
|
unsigned int value;
|
||||||
|
int hash;
|
||||||
|
|
||||||
|
value = addr.s_addr;
|
||||||
|
hash = 0;
|
||||||
|
do {
|
||||||
|
hash ^= value;
|
||||||
|
} while ((value >>= HASH_LOG) != 0);
|
||||||
|
|
||||||
|
return hash & (HASH_SIZE - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
xt_psd_match(const struct sk_buff *pskb, const struct xt_match_param *match)
|
||||||
|
{
|
||||||
|
const struct iphdr *iph;
|
||||||
|
const struct tcphdr *tcph;
|
||||||
|
struct tcphdr _tcph;
|
||||||
|
struct in_addr addr;
|
||||||
|
u_int16_t src_port,dest_port;
|
||||||
|
u_int8_t tcp_flags, proto;
|
||||||
|
unsigned long now;
|
||||||
|
struct host *curr, *last, **head;
|
||||||
|
int hash, index, count;
|
||||||
|
/* Parameters from userspace */
|
||||||
|
const struct xt_psd_info *psdinfo = match->matchinfo;
|
||||||
|
|
||||||
|
/* IP header */
|
||||||
|
iph = ip_hdr(pskb);
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (iph->frag_off & htons(IP_OFFSET)) {
|
||||||
|
pr_debug("sanity check failed\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TCP or UDP ? */
|
||||||
|
proto = iph->protocol;
|
||||||
|
|
||||||
|
if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
|
||||||
|
pr_debug("protocol not supported\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the source address, source & destination ports, and TCP flags */
|
||||||
|
|
||||||
|
addr.s_addr = iph->saddr;
|
||||||
|
|
||||||
|
tcph = skb_header_pointer(pskb, match->thoff, sizeof(_tcph), &_tcph);
|
||||||
|
if (tcph == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Yep, it's dirty */
|
||||||
|
src_port = tcph->source;
|
||||||
|
dest_port = tcph->dest;
|
||||||
|
|
||||||
|
if (proto == IPPROTO_TCP)
|
||||||
|
tcp_flags = *((u_int8_t*)tcph + 13);
|
||||||
|
else
|
||||||
|
tcp_flags = 0x00;
|
||||||
|
|
||||||
|
/* We're using IP address 0.0.0.0 for a special purpose here, so don't let
|
||||||
|
* them spoof us. [DHCP needs this feature - HW] */
|
||||||
|
if (addr.s_addr == 0) {
|
||||||
|
pr_debug("spoofed source address (0.0.0.0)\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use jiffies here not to depend on someone setting the time while we're
|
||||||
|
* running; we need to be careful with possible return value overflows. */
|
||||||
|
now = jiffies;
|
||||||
|
|
||||||
|
spin_lock(&state.lock);
|
||||||
|
|
||||||
|
/* Do we know this source address already? */
|
||||||
|
count = 0;
|
||||||
|
last = NULL;
|
||||||
|
if ((curr = *(head = &state.hash[hash = hashfunc(addr)])) != NULL)
|
||||||
|
do {
|
||||||
|
if (curr->src_addr.s_addr == addr.s_addr)
|
||||||
|
break;
|
||||||
|
count++;
|
||||||
|
if (curr->next != NULL)
|
||||||
|
last = curr;
|
||||||
|
} while ((curr = curr->next) != NULL);
|
||||||
|
|
||||||
|
if (curr != NULL) {
|
||||||
|
|
||||||
|
/* We know this address, and the entry isn't too old. Update it. */
|
||||||
|
if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
|
||||||
|
time_after_eq(now, curr->timestamp)) {
|
||||||
|
|
||||||
|
/* Just update the appropriate list entry if we've seen this port already */
|
||||||
|
for (index = 0; index < curr->count; index++) {
|
||||||
|
if (curr->ports[index].number == dest_port) {
|
||||||
|
curr->ports[index].proto = proto;
|
||||||
|
curr->ports[index].and_flags &= tcp_flags;
|
||||||
|
curr->ports[index].or_flags |= tcp_flags;
|
||||||
|
goto out_no_match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
|
||||||
|
if (proto == IPPROTO_TCP && (tcph->ack || tcph->rst))
|
||||||
|
goto out_no_match;
|
||||||
|
|
||||||
|
/* Packet to a new port, and not TCP/ACK: update the timestamp */
|
||||||
|
curr->timestamp = now;
|
||||||
|
|
||||||
|
/* Logged this scan already? Then drop the packet. */
|
||||||
|
if (curr->weight >= psdinfo->weight_threshold)
|
||||||
|
goto out_match;
|
||||||
|
|
||||||
|
/* Specify if destination address, source port, TOS or TTL are not fixed */
|
||||||
|
if (curr->dest_addr.s_addr != iph->daddr)
|
||||||
|
curr->flags |= HF_DADDR_CHANGING;
|
||||||
|
if (curr->src_port != src_port)
|
||||||
|
curr->flags |= HF_SPORT_CHANGING;
|
||||||
|
if (curr->tos != iph->tos)
|
||||||
|
curr->flags |= HF_TOS_CHANGING;
|
||||||
|
if (curr->ttl != iph->ttl)
|
||||||
|
curr->flags |= HF_TTL_CHANGING;
|
||||||
|
|
||||||
|
/* Update the total weight */
|
||||||
|
curr->weight += (ntohs(dest_port) < 1024) ?
|
||||||
|
psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
|
||||||
|
|
||||||
|
/* Got enough destination ports to decide that this is a scan? */
|
||||||
|
/* Then log it and drop the packet. */
|
||||||
|
if (curr->weight >= psdinfo->weight_threshold)
|
||||||
|
goto out_match;
|
||||||
|
|
||||||
|
/* Remember the new port */
|
||||||
|
if (curr->count < SCAN_MAX_COUNT) {
|
||||||
|
curr->ports[curr->count].number = dest_port;
|
||||||
|
curr->ports[curr->count].proto = proto;
|
||||||
|
curr->ports[curr->count].and_flags = tcp_flags;
|
||||||
|
curr->ports[curr->count].or_flags = tcp_flags;
|
||||||
|
curr->count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto out_no_match;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We know this address, but the entry is outdated. Mark it unused, and
|
||||||
|
* remove from the hash table. We'll allocate a new entry instead since
|
||||||
|
* this one might get re-used too soon. */
|
||||||
|
curr->src_addr.s_addr = 0;
|
||||||
|
if (last != NULL)
|
||||||
|
last->next = last->next->next;
|
||||||
|
else if (*head != NULL)
|
||||||
|
*head = (*head)->next;
|
||||||
|
last = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We don't need an ACK from a new source address */
|
||||||
|
if (proto == IPPROTO_TCP && tcph->ack)
|
||||||
|
goto out_no_match;
|
||||||
|
|
||||||
|
/* Got too many source addresses with the same hash value? Then remove the
|
||||||
|
* oldest one from the hash table, so that they can't take too much of our
|
||||||
|
* CPU time even with carefully chosen spoofed IP addresses. */
|
||||||
|
if (count >= HASH_MAX && last != NULL)
|
||||||
|
last->next = NULL;
|
||||||
|
|
||||||
|
/* We're going to re-use the oldest list entry, so remove it from the hash
|
||||||
|
* table first (if it is really already in use, and isn't removed from the
|
||||||
|
* hash table already because of the HASH_MAX check above). */
|
||||||
|
|
||||||
|
/* First, find it */
|
||||||
|
if (state.list[state.index].src_addr.s_addr != 0)
|
||||||
|
head = &state.hash[hashfunc(state.list[state.index].src_addr)];
|
||||||
|
else
|
||||||
|
head = &last;
|
||||||
|
last = NULL;
|
||||||
|
if ((curr = *head) != NULL)
|
||||||
|
do {
|
||||||
|
if (curr == &state.list[state.index])
|
||||||
|
break;
|
||||||
|
last = curr;
|
||||||
|
} while ((curr = curr->next) != NULL);
|
||||||
|
|
||||||
|
/* Then, remove it */
|
||||||
|
if (curr != NULL) {
|
||||||
|
if (last != NULL)
|
||||||
|
last->next = last->next->next;
|
||||||
|
else if (*head != NULL)
|
||||||
|
*head = (*head)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get our list entry */
|
||||||
|
curr = &state.list[state.index++];
|
||||||
|
if (state.index >= LIST_SIZE)
|
||||||
|
state.index = 0;
|
||||||
|
|
||||||
|
/* Link it into the hash table */
|
||||||
|
head = &state.hash[hash];
|
||||||
|
curr->next = *head;
|
||||||
|
*head = curr;
|
||||||
|
|
||||||
|
/* And fill in the fields */
|
||||||
|
curr->timestamp = now;
|
||||||
|
curr->src_addr = addr;
|
||||||
|
curr->dest_addr.s_addr = iph->daddr;
|
||||||
|
curr->src_port = src_port;
|
||||||
|
curr->count = 1;
|
||||||
|
curr->weight = (ntohs(dest_port) < 1024) ? psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
|
||||||
|
curr->ports[0].number = dest_port;
|
||||||
|
curr->ports[0].proto = proto;
|
||||||
|
curr->ports[0].and_flags = tcp_flags;
|
||||||
|
curr->ports[0].or_flags = tcp_flags;
|
||||||
|
curr->tos = iph->tos;
|
||||||
|
curr->ttl = iph->ttl;
|
||||||
|
|
||||||
|
out_no_match:
|
||||||
|
spin_unlock(&state.lock);
|
||||||
|
return false;
|
||||||
|
|
||||||
|
out_match:
|
||||||
|
spin_unlock(&state.lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct xt_match xt_psd_reg __read_mostly = {
|
||||||
|
.name = "psd",
|
||||||
|
.family = AF_INET,
|
||||||
|
.revision = 1,
|
||||||
|
.match = xt_psd_match,
|
||||||
|
.matchsize = sizeof(struct xt_psd_info),
|
||||||
|
.me = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init xt_psd_init(void)
|
||||||
|
{
|
||||||
|
spin_lock_init(&(state.lock));
|
||||||
|
return xt_register_match(&xt_psd_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit xt_psd_exit(void)
|
||||||
|
{
|
||||||
|
xt_unregister_match(&xt_psd_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(xt_psd_init);
|
||||||
|
module_exit(xt_psd_exit);
|
||||||
|
|
41
extensions/xt_psd.h
Normal file
41
extensions/xt_psd.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef _LINUX_NETFILTER_XT_PSD_H
|
||||||
|
#define _LINUX_NETFILTER_XT_PSD_H 1
|
||||||
|
|
||||||
|
#include <linux/param.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* High port numbers have a lower weight to reduce the frequency of false
|
||||||
|
* positives, such as from passive mode FTP transfers.
|
||||||
|
*/
|
||||||
|
#define PORT_WEIGHT_PRIV 3
|
||||||
|
#define PORT_WEIGHT_HIGH 1
|
||||||
|
#define PSD_MAX_RATE 10000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Port scan detection thresholds: at least COUNT ports need to be scanned
|
||||||
|
* from the same source, with no longer than DELAY ticks between ports.
|
||||||
|
*/
|
||||||
|
#define SCAN_MIN_COUNT 7
|
||||||
|
#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
|
||||||
|
#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT
|
||||||
|
#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keep track of up to LIST_SIZE source addresses, using a hash table of
|
||||||
|
* HASH_SIZE entries for faster lookups, but limiting hash collisions to
|
||||||
|
* HASH_MAX source addresses per the same hash value.
|
||||||
|
*/
|
||||||
|
#define LIST_SIZE 0x100
|
||||||
|
#define HASH_LOG 9
|
||||||
|
#define HASH_SIZE (1 << HASH_LOG)
|
||||||
|
#define HASH_MAX 0x10
|
||||||
|
|
||||||
|
struct xt_psd_info {
|
||||||
|
__u32 weight_threshold;
|
||||||
|
__u32 delay_threshold;
|
||||||
|
__u16 lo_ports_weight;
|
||||||
|
__u16 hi_ports_weight;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*_LINUX_NETFILTER_XT_PSD_H*/
|
@@ -21,12 +21,15 @@
|
|||||||
#include "xt_quota2.h"
|
#include "xt_quota2.h"
|
||||||
#include "compat_xtables.h"
|
#include "compat_xtables.h"
|
||||||
|
|
||||||
struct quota_counter {
|
/**
|
||||||
|
* @lock: lock to protect quota writers from each other
|
||||||
|
*/
|
||||||
|
struct xt_quota_counter {
|
||||||
u_int64_t quota;
|
u_int64_t quota;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
atomic_t ref;
|
atomic_t ref;
|
||||||
char name[XT_QUOTA_COUNTER_NAME_LENGTH];
|
char name[sizeof(((struct xt_quota_mtinfo2 *)NULL)->name)];
|
||||||
struct proc_dir_entry *procfs_entry;
|
struct proc_dir_entry *procfs_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,7 +47,7 @@ module_param_named(gid, quota_list_gid, uint, S_IRUGO | S_IWUSR);
|
|||||||
static int quota_proc_read(char *page, char **start, off_t offset,
|
static int quota_proc_read(char *page, char **start, off_t offset,
|
||||||
int count, int *eof, void *data)
|
int count, int *eof, void *data)
|
||||||
{
|
{
|
||||||
struct quota_counter *e = data;
|
struct xt_quota_counter *e = data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
spin_lock_bh(&e->lock);
|
spin_lock_bh(&e->lock);
|
||||||
@@ -56,7 +59,7 @@ static int quota_proc_read(char *page, char **start, off_t offset,
|
|||||||
static int quota_proc_write(struct file *file, const char __user *input,
|
static int quota_proc_write(struct file *file, const char __user *input,
|
||||||
unsigned long size, void *data)
|
unsigned long size, void *data)
|
||||||
{
|
{
|
||||||
struct quota_counter *e = data;
|
struct xt_quota_counter *e = data;
|
||||||
char buf[sizeof("18446744073709551616")];
|
char buf[sizeof("18446744073709551616")];
|
||||||
|
|
||||||
if (size > sizeof(buf))
|
if (size > sizeof(buf))
|
||||||
@@ -66,39 +69,58 @@ static int quota_proc_write(struct file *file, const char __user *input,
|
|||||||
buf[sizeof(buf)-1] = '\0';
|
buf[sizeof(buf)-1] = '\0';
|
||||||
|
|
||||||
spin_lock_bh(&e->lock);
|
spin_lock_bh(&e->lock);
|
||||||
e->quota = simple_strtoul(buf, NULL, 0);
|
e->quota = simple_strtoull(buf, NULL, 0);
|
||||||
spin_unlock_bh(&e->lock);
|
spin_unlock_bh(&e->lock);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct xt_quota_counter *
|
||||||
|
q2_new_counter(const struct xt_quota_mtinfo2 *q, bool anon)
|
||||||
|
{
|
||||||
|
struct xt_quota_counter *e;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
/* Do not need all the procfs things for anonymous counters. */
|
||||||
|
size = anon ? offsetof(typeof(*e), list) : sizeof(*e);
|
||||||
|
e = kmalloc(size, GFP_KERNEL);
|
||||||
|
if (e == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
e->quota = q->quota;
|
||||||
|
spin_lock_init(&e->lock);
|
||||||
|
if (!anon) {
|
||||||
|
INIT_LIST_HEAD(&e->list);
|
||||||
|
atomic_set(&e->ref, 1);
|
||||||
|
strncpy(e->name, q->name, sizeof(e->name));
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* q2_get_counter - get ref to counter or create new
|
* q2_get_counter - get ref to counter or create new
|
||||||
* @name: name of counter
|
* @name: name of counter
|
||||||
*/
|
*/
|
||||||
static struct quota_counter *q2_get_counter(const struct xt_quota_mtinfo2 *q)
|
static struct xt_quota_counter *
|
||||||
|
q2_get_counter(const struct xt_quota_mtinfo2 *q)
|
||||||
{
|
{
|
||||||
struct proc_dir_entry *p;
|
struct proc_dir_entry *p;
|
||||||
struct quota_counter *e;
|
struct xt_quota_counter *e;
|
||||||
|
|
||||||
|
if (*q->name == '\0')
|
||||||
|
return q2_new_counter(q, true);
|
||||||
|
|
||||||
spin_lock_bh(&counter_list_lock);
|
spin_lock_bh(&counter_list_lock);
|
||||||
list_for_each_entry(e, &counter_list, list) {
|
list_for_each_entry(e, &counter_list, list)
|
||||||
if (strcmp(e->name, q->name) == 0) {
|
if (strcmp(e->name, q->name) == 0) {
|
||||||
atomic_inc(&e->ref);
|
atomic_inc(&e->ref);
|
||||||
spin_unlock_bh(&counter_list_lock);
|
spin_unlock_bh(&counter_list_lock);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
e = kmalloc(sizeof(struct quota_counter), GFP_KERNEL);
|
e = q2_new_counter(q, false);
|
||||||
if (e == NULL)
|
if (e == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
e->quota = q->quota;
|
|
||||||
spin_lock_init(&e->lock);
|
|
||||||
INIT_LIST_HEAD(&e->list);
|
|
||||||
atomic_set(&e->ref, 1);
|
|
||||||
strncpy(e->name, q->name, sizeof(e->name));
|
|
||||||
|
|
||||||
p = e->procfs_entry = create_proc_entry(e->name, quota_list_perms,
|
p = e->procfs_entry = create_proc_entry(e->name, quota_list_perms,
|
||||||
proc_xt_quota);
|
proc_xt_quota);
|
||||||
if (p == NULL || IS_ERR(p))
|
if (p == NULL || IS_ERR(p))
|
||||||
@@ -130,15 +152,16 @@ static bool quota_mt2_check(const struct xt_mtchk_param *par)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
q->name[sizeof(q->name)-1] = '\0';
|
q->name[sizeof(q->name)-1] = '\0';
|
||||||
if (*q->name == '\0' || *q->name == '.' ||
|
if (*q->name == '.' || strchr(q->name, '/') != NULL) {
|
||||||
strchr(q->name, '/') != NULL) {
|
printk(KERN_ERR "xt_quota<%u>: illegal name\n",
|
||||||
printk(KERN_ERR "xt_quota.2: illegal name\n");
|
par->match->revision);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
q->master = q2_get_counter(q);
|
q->master = q2_get_counter(q);
|
||||||
if (q->master == NULL) {
|
if (q->master == NULL) {
|
||||||
printk(KERN_ERR "xt_quota.2: memory alloc failure\n");
|
printk(KERN_ERR "xt_quota<%u>: memory alloc failure\n",
|
||||||
|
par->match->revision);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +171,12 @@ static bool quota_mt2_check(const struct xt_mtchk_param *par)
|
|||||||
static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
|
static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
|
||||||
{
|
{
|
||||||
struct xt_quota_mtinfo2 *q = par->matchinfo;
|
struct xt_quota_mtinfo2 *q = par->matchinfo;
|
||||||
struct quota_counter *e = q->master;
|
struct xt_quota_counter *e = q->master;
|
||||||
|
|
||||||
|
if (*q->name == '\0') {
|
||||||
|
kfree(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_bh(&counter_list_lock);
|
spin_lock_bh(&counter_list_lock);
|
||||||
if (!atomic_dec_and_test(&e->ref)) {
|
if (!atomic_dec_and_test(&e->ref)) {
|
||||||
@@ -157,8 +185,8 @@ static void quota_mt2_destroy(const struct xt_mtdtor_param *par)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_del(&e->list);
|
list_del(&e->list);
|
||||||
spin_unlock_bh(&counter_list_lock);
|
|
||||||
remove_proc_entry(e->name, proc_xt_quota);
|
remove_proc_entry(e->name, proc_xt_quota);
|
||||||
|
spin_unlock_bh(&counter_list_lock);
|
||||||
kfree(e);
|
kfree(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,17 +194,15 @@ static bool
|
|||||||
quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
|
quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||||
{
|
{
|
||||||
struct xt_quota_mtinfo2 *q = (void *)par->matchinfo;
|
struct xt_quota_mtinfo2 *q = (void *)par->matchinfo;
|
||||||
struct quota_counter *e = q->master;
|
struct xt_quota_counter *e = q->master;
|
||||||
bool ret = q->flags & XT_QUOTA_INVERT;
|
bool ret = q->flags & XT_QUOTA_INVERT;
|
||||||
|
|
||||||
if (q->flags & XT_QUOTA_GROW) {
|
|
||||||
spin_lock_bh(&e->lock);
|
spin_lock_bh(&e->lock);
|
||||||
|
if (q->flags & XT_QUOTA_GROW) {
|
||||||
e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
|
e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
|
||||||
q->quota = e->quota;
|
q->quota = e->quota;
|
||||||
spin_unlock_bh(&e->lock);
|
|
||||||
ret = true;
|
ret = true;
|
||||||
} else {
|
} else {
|
||||||
spin_lock_bh(&e->lock);
|
|
||||||
if (e->quota >= skb->len) {
|
if (e->quota >= skb->len) {
|
||||||
e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
|
e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
|
||||||
ret = !ret;
|
ret = !ret;
|
||||||
@@ -185,16 +211,15 @@ quota_mt2(const struct sk_buff *skb, const struct xt_match_param *par)
|
|||||||
e->quota = 0;
|
e->quota = 0;
|
||||||
}
|
}
|
||||||
q->quota = e->quota;
|
q->quota = e->quota;
|
||||||
spin_unlock_bh(&e->lock);
|
|
||||||
}
|
}
|
||||||
|
spin_unlock_bh(&e->lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct xt_match quota_mt2_reg[] __read_mostly = {
|
static struct xt_match quota_mt2_reg[] __read_mostly = {
|
||||||
{
|
{
|
||||||
.name = "quota2",
|
.name = "quota2",
|
||||||
.revision = 2,
|
.revision = 3,
|
||||||
.family = NFPROTO_IPV4,
|
.family = NFPROTO_IPV4,
|
||||||
.checkentry = quota_mt2_check,
|
.checkentry = quota_mt2_check,
|
||||||
.match = quota_mt2,
|
.match = quota_mt2,
|
||||||
@@ -204,7 +229,7 @@ static struct xt_match quota_mt2_reg[] __read_mostly = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "quota2",
|
.name = "quota2",
|
||||||
.revision = 2,
|
.revision = 3,
|
||||||
.family = NFPROTO_IPV6,
|
.family = NFPROTO_IPV6,
|
||||||
.checkentry = quota_mt2_check,
|
.checkentry = quota_mt2_check,
|
||||||
.match = quota_mt2,
|
.match = quota_mt2,
|
||||||
|
@@ -6,21 +6,19 @@ enum xt_quota_flags {
|
|||||||
XT_QUOTA_GROW = 1 << 1,
|
XT_QUOTA_GROW = 1 << 1,
|
||||||
XT_QUOTA_PACKET = 1 << 2,
|
XT_QUOTA_PACKET = 1 << 2,
|
||||||
XT_QUOTA_MASK = 0x7,
|
XT_QUOTA_MASK = 0x7,
|
||||||
|
|
||||||
XT_QUOTA_COUNTER_NAME_LENGTH = 31,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct quota_counter;
|
struct xt_quota_counter;
|
||||||
|
|
||||||
struct xt_quota_mtinfo2 {
|
struct xt_quota_mtinfo2 {
|
||||||
char name[XT_QUOTA_COUNTER_NAME_LENGTH];
|
char name[15];
|
||||||
u_int8_t flags;
|
u_int8_t flags;
|
||||||
|
|
||||||
/* Comparison-invariant */
|
/* Comparison-invariant */
|
||||||
aligned_u64 quota;
|
aligned_u64 quota;
|
||||||
|
|
||||||
/* Used internally by the kernel */
|
/* Used internally by the kernel */
|
||||||
struct quota_counter *master __attribute__((aligned(8)));
|
struct xt_quota_counter *master __attribute__((aligned(8)));
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _XT_QUOTA_H */
|
#endif /* _XT_QUOTA_H */
|
||||||
|
3
mconfig
3
mconfig
@@ -1,5 +1,6 @@
|
|||||||
# -*- Makefile -*-
|
# -*- Makefile -*-
|
||||||
#
|
#
|
||||||
|
build_ACCOUNT=m
|
||||||
build_CHAOS=m
|
build_CHAOS=m
|
||||||
build_DELUDE=m
|
build_DELUDE=m
|
||||||
build_DHCPMAC=m
|
build_DHCPMAC=m
|
||||||
@@ -20,4 +21,6 @@ build_ipset=m
|
|||||||
build_ipv4options=m
|
build_ipv4options=m
|
||||||
build_length2=m
|
build_length2=m
|
||||||
build_lscan=m
|
build_lscan=m
|
||||||
|
build_pknock=m
|
||||||
|
build_psd=m
|
||||||
build_quota2=m
|
build_quota2=m
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
.TH xtables\-addons 8 "v1.17 (2009\-06\-16)" "" "v1.17 (2009\-06\-16)"
|
.TH xtables-addons 8 "v1.19 (2009-10-12)" "" "v1.19 (2009-10-12)"
|
||||||
.SH Name
|
.SH Name
|
||||||
Xtables\-addons - additional extensions for iptables, ip6tables, etc.
|
Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
|
||||||
.SH Targets
|
.SH Targets
|
||||||
.\" @TARGET@
|
.\" @TARGET@
|
||||||
.SH Matches
|
.SH Matches
|
||||||
|
Reference in New Issue
Block a user