⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netfilter-hacking-howto.txt

📁 这是我对防火墙技术的一些见解
💻 TXT
📖 第 1 页 / 共 5 页
字号:

  One warning about doing tricky things (such as providing counters) in
  the extra space in your new match or target.  On SMP machines, the
  entire table is duplicated using memcpy for each CPU: if you really
  want to keep central information, you should see the method used in
  the `limit' match.


  4.2.1.1.  New Match Functions

  New match functions are usually written as a standalone module.  It's
  possible to have these modules extensible in turn, although it's
  usually not necessary.  One way would be to use the netfilter
  framework's `nf_register_sockopt' function to allows users to talk to
  your module directly.  Another way would be to export symbols for
  other modules to register themselves, the same way netfilter and
  ip_tables do.


  The core of your new match function is the struct ipt_match which it
  passes to `ipt_register_match()'.  This structure has the following
  fields:


     list
        This field is set to any junk, say `{ NULL, NULL }'.


     name
        This field is the name of the match function, as referred to by
        userspace.  The name should match the name of the module (i.e.,
        if the name is "mac", the module must be "ipt_mac.o") for auto-
        loading to work.


     match
        This field is a pointer to a match function, which takes the
        skb, the in and out device pointers (one of which may be NULL,
        depending on the hook), a pointer to the match data in the rule
        that is worked on (the structure that was prepared in
        userspace), the IP offset (non-zero means a non-head fragment),
        a pointer to the protocol header (i.e., just past the IP
        header), the length of the data (ie. the packet length minus the
        IP header length) and finally a pointer to a `hotdrop' variable.
        It should return non-zero if the packet matches, and can set
        `hotdrop' to 1 if it returns 0, to indicate that the packet must
        be dropped immediately.


     checkentry
        This field is a pointer to a function which checks the
        specifications for a rule; if this returns 0, then the rule will
        not be accepted from the user.  For example, the "tcp" match
        type will only accept tcp packets, and so if the `struct ipt_ip'
        part of the rule does not specify that the protocol must be tcp,
        a zero is returned.  The tablename argument allows your match to
        control what tables it can be used in, and the `hook_mask' is a
        bitmask of hooks this rule may be called from: if your match
        does not make sense from some netfilter hooks, you can avoid
        that here.


     destroy
        This field is a pointer to a function which is called when an
        entry using this match is deleted.  This allows you to
        dynamically allocate resources in checkentry and clean them up
        here.


     me This field is set to `THIS_MODULE', which gives a pointer to
        your module.  It causes the usage-count to go up and down as
        rules of that type are created and destroyed.  This prevents a
        user removing the module (and hence cleanup_module() being
        called) if a rule refers to it.


  4.2.1.2.  New Targets

  If your target alters the packet (ie. the headers or the body), it
  must call skb_unshare() to copy the packet in case it is cloned:
  otherwise any raw sockets which have a clone of the skbuff will see
  the alterations (ie. people will see wierd stuff happening in
  tcpdump).


  New targets are also usually written as a standalone module.  The
  discussions under the above section on `New Match Functions' apply
  equally here.


  The core of your new target is the struct ipt_target that it passes to
  ipt_register_target().  This structure has the following fields:


     list
        This field is set to any junk, say `{ NULL, NULL }'.


     name
        This field is the name of the target function, as referred to by
        userspace.  The name should match the name of the module (i.e.,
        if the name is "REJECT", the module must be "ipt_REJECT.o") for
        auto-loading to work.


     target
        This is a pointer to the target function, which takes the
        skbuff, the hook number, the input and output device pointers
        (either of which may be NULL), a pointer to the target data, and
        the position of the rule in the table. The target function may
        return either IPT_CONTINUE (-1) if traversing should continue,
        or a netfilter verdict (NF_DROP, NF_ACCEPT, NF_STOLEN etc.).


     checkentry
        This field is a pointer to a function which checks the
        specifications for a rule; if this returns 0, then the rule will
        not be accepted from the user.


     destroy
        This field is a pointer to a function which is called when an
        entry using this target is deleted.  This allows you to
        dynamically allocate resources in checkentry and clean them up
        here.


     me This field is set to `THIS_MODULE', which gives a pointer to
        your module.  It causes the usage-count to go up and down as
        rules with this as a target are created and destroyed.  This
        prevents a user removing the module (and hence cleanup_module()
        being called) if a rule refers to it.


  4.2.1.3.  New Tables

  You can create a new table for your specific purpose if you wish.  To
  do this, you call `ipt_register_table()', with a `struct ipt_table',
  which has the following fields:


     list
        This field is set to any junk, say `{ NULL, NULL }'.


     name
        This field is the name of the table function, as referred to by
        userspace.  The name should match the name of the module (i.e.,
        if the name is "nat", the module must be "iptable_nat.o") for
        auto-loading to work.


     table
        This is a fully-populated `struct ipt_replace', as used by
        userspace to replace a table.  The `counters' pointer should be
        set to NULL.  This data structure can be declared `__initdata'
        so it is discarded after boot.


     valid_hooks
        This is a bitmask of the IPv4 netfilter hooks you will enter the
        table with: this is used to check that those entry points are
        valid, and to calculate the possible hooks for ipt_match and
        ipt_target `checkentry()' functions.


     lock
        This is the read-write spinlock for the entire table; initialize
        it to RW_LOCK_UNLOCKED.


     private
        This is used internally by the ip_tables code.


  4.2.2.  Userspace Tool

  Now you've written your nice shiny kernel module, you may want to
  control the options on it from userspace.  Rather than have a branched
  version of iptables for each extension, I use the very latest 90's
  technology: furbies.  Sorry, I mean shared libraries.


  New tables generally don't require any extension to iptables: the user
  just uses the `-t' option to make it use the new table.


  The shared library should have an `_init()' function, which will
  automatically be called upon loading: the moral equivalent of the
  kernel module's `init_module()' function.  This should call
  `register_match()' or `register_target()', depending on whether your
  shared library provides a new match or a new target.


  You need to provide a shared library: this can be used to initialize
  part of the structure, or provide additional options.  I now insist on
  a shared library even if it doesn't do anything, to reduce problem
  reports where the shares libraries are missing.


  There are useful functions described in the `iptables.h' header,
  especially:

     check_inverse()
        checks if an argument is actually a `!', and if so, sets the
        `invert' flag if not already set.  If it returns true, you
        should increment optind, as done in the examples.


     string_to_number()
        converts a string into a number in the given range, returning -1
        if it is malformed or out of range.  `string_to_number' rely on
        `strtol' (see the manpage), meaning that a leading "0x" would
        make the number be in Hexadecimal base, a leading "0" would make
        it be in Octal base.


     exit_error()
        should be called if an error is found.  Usually the first
        argument is `PARAMETER_PROBLEM', meaning the user didn't use the
        command line correctly.

  4.2.2.1.  New Match Functions

  Your shared library's _init() function hands `register_match()' a
  pointer to a static `struct iptables_match', which has the following
  fields:


     next
        This pointer is used to make a linked list of matches (such as
        used for listing rules).  It should be set to NULL initially.


     name
        The name of the match function.  This should match the library
        name (eg "tcp" for `libipt_tcp.so').


     version
        Usually set to the IPTABLES_VERSION macro: this is used to
        ensure that the iptables binary doesn't pick up the wrong shared
        libraries by mistake.


     size
        The size of the match data for this match; you should use the
        IPT_ALIGN() macro to ensure it is correctly aligned.


     userspacesize
        For some matches, the kernel changes some fields internally (the
        `limit' target is a case of this).  This means that a simple
        `memcmp()' is insufficient to compare two rules (required for
        delete-matching-rule functionality).  If this is the case, place
        all the fields which do not change at the start of the
        structure, and put the size of the unchanging fields here.
        Usually, however, this will be identical to the `size' field.


     help
        A function which prints out the option synopsis.


     init
        This can be used to initialize the extra space (if any) in the
        ipt_entry_match structure, and set any nfcache bits; if you are
        examining something not expressible using the contents of
        `linux/include/netfilter_ipv4.h', then simply OR in the
        NFC_UNKNOWN bit.  It will be called before `parse()'.


     parse
        This is called when an unrecognized option is seen on the
        command line: it should return non-zero if the option was indeed
        for your library.  `invert' is true if a `!' has already been
        seen.  The `flags' pointer is for the exclusive use of your
        match library, and is usually used to store a bitmask of options
        which have been specified.  Make sure you adjust the nfcache
        field.  You may extend the size of the `ipt_entry_match'
        structure by reallocating if necessary, but then you must ensure
        that the size is passed through the IPT_ALIGN macro.


     final_check
        This is called after the command line has been parsed, and is
        handed the `flags' integer reserved for your library.  This
        gives you a chance to check that any compulsory options have
        been specified, for example: call `exit_error()' if this is the
        case.


     print
        This is used by the chain listing code to print (to standard
        output) the extra match information (if any) for a rule.  The
        numeric flag is set if the user specified the `-n' flag.


     save
        This is the reverse of parse: it is used by `iptables-save' to
        reproduce the options which created the rule.


     extra_opts
        This is a NULL-terminated list of extra options which your
        library offers.  This is merged with the current options and
        handed to getopt_long; see the man page for details.  The return
        code for getopt_long becomes the first argument (`c') to your
        `parse()' function.

  There are extra elements at the end of this structure for use
  internally by iptables: you don't need to set them.


  4.2.2.2.  New Targets

  Your shared library's _init() function hands `register_target()' it a
  pointer to a static `struct iptables_target', which has similar fields
  to the iptables_match structure detailed above.


  4.2.3.  Using `libiptc'

  libiptc is the iptables control library, designed for listing and
  manipulating rules in the iptables kernel module.  While its current
  use is for the iptables program, it makes writing other tools fairly
  easy.  You need to be root to use these functions.


  The kernel tables themselves are simply a table of rules, and a set of
  numbers representing entry points.  Chain names ("INPUT", etc) are
  provided as an abstraction by the library.  User defined chains are
  labelled by inserting an error node before the head of the user-
  defined chain, which contains the chain name in the extra data section
  of the target (the builtin chain positions are defined by the three
  table entry points).


  The following standard targets are supported: ACCEPT, DROP, QUEUE
  (which are translated to NF_ACCEPT, NF_DROP, and NF_QUEUE,
  respectively), RETURN (which is translated to a special IPT_RETURN
  value handled by ip_tables), and JUMP (which is translated from the
  chain name to an actual offset within the table).


  When `iptc_init()' is called, the table, including the counters, is
  read.  This table is manipulated by the `iptc_insert_entry()',
  `iptc_replace_entry()', `iptc_append_entry()', `iptc_delete_entry()',
  `iptc_delete_num_entry()', `iptc_flush_entries()',
  `iptc_zero_entries()', `iptc_create_chain()' `iptc_delete_chain()',
  and `iptc_set_policy()' functions.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -