Title: CS 498 Lecture 13 Inside Netfilter
1CS 498 Lecture 13 Inside Netfilter
- Jennifer Hou
- Department of Computer Science
- University of Illinois at Urbana-Champaign
- Reading
- Oskar Andreasson, Iptables Tutorial,
http//iptables-tutorial.frozentux.net/ - Rusty Russell and Harald Welta, Netfilter Hacking
Howto , http//www.netfilter.org/documentation/ind
ex.html
2Internet Protocol Implementation in Linux
Higher Layers
ip_input.c
ip_output.c
ip_queue_xmit
ip_local_deliver
MULTICAST
IP_LOCAL_OUTPUT
. . .
ip_mr_input
IP_LOCAL_INPUT
ip_queue_xmit2
ip_forward.c
IP_FORWARD
ip_local_deliver
ip_forward_finish
ip_forward
ip_output
ip_fragment
ip_rcv_finish
ip_finish_output
ROUTING
ForwardingInformation Base
IP_POST_ROUTING
IP_PRE_ROUTING
ip_route_input
ip_rcv
ip_finish_output2
ARP
ARP
neigh_resolve_output
dev.c
dev.c
dev_queue_xmit
net_rx_action
3Data Structures in Netfilter
- Defined in include/linux/netfilter_ipv4/ip_tables.
h
4Data Structure - Table
- struct ipt_table (ip_tables.h)
- Is a linked list to store all tables
- Defines a table, e.g., 'nat','filter','mangle'
- Contains a struct ipt_table_info that stores the
firewall rules in entries - A table is registerd using ipt_register_table (in
init_module()) and unregistered by
ipt_unregister_table (in cleanup_module())
5How Data Structures are Organized
ipt_entry next target
ipt_entry next target
ipt_entry next target
ipt_table_info entries
ipt_table private
ipt_entry next target
ipt_entry next target
ipt_entry next target
ipt_entry next target
ipt_entry next target
6Data Structure - Entry
- struct ipt_entry contains
- A struct ipt_ip that contains the specification
for the IP header that it is to match - An nfcache bitfield that gives what parts of the
packet the rule exams. - A target_offset field that indicates the offset
where the ipt_entry_target structure begins. - A next_offset field that indicates the total size
of this rule. - A comefrom field that keeps track of packet
traversal. - A struct ipt_counter field that contains the
packet/byte counters for packets that matched
this rule. - struct ipt_entry stores a variable number of
ipt_entry_match after ipt_entry, and an
ipt_entry_target after matches
7The ipt_entry Struct
ipt_entry target_offset next_offset elems
ipt_entry target_offset next_offset elems
ipt_entry_match match data
ipt_entry_match match data
One or more matches
ipt_entry_match match data
ipt_entry_match match data
ipt_entry_target target data
ipt_entry_target target data
8Data Structure - Match
- struct ipt_entry_match
- u.kernel.match a pointer to a struct ipt_match
- data the user-defined matchinfo
- struct ipt_match
- list is set to NULL,NULL
- name the name of the match function, as referred
to by userspace - match is a pointer to the match function returns
true if the packet matches - If hotdrop is set to 1 and the return value is
zero, the packet should be dropped immediately. - checkentry is a pointer to a function that checks
the specifications for a rule. If the function
returns 0, the rule will not be accepted from the
user. - A user-defined match is registered by
ipt_register_match and unregistered by
ipt_unregister_match
9Data Structure - Target
- struct ipt_entry_target
- u.kernel.target a pointer to struct ipt_target
- data user-defined targetinfo
- struct ipt_target
- list is set to NULL,NULL
- name the name of the match function, as referred
to by userspace - target is a pointer to the target function
- takes the skb buffer, the hook number, the input
and output device pointers, a pointer to the
target area, and the position of the rule in the
table. - Returns IPT_CONTINUE to continue traversing, or a
verdict (NF_DROP, NF_ACCEPT, NF_STOLEN, etc)
10Data Structure - Target
- struct ipt_target (contd)
- checkentry is a pointer to a function that checks
the specifications for a rule if the function
returns 0, then the rule will not be accepted
from the user. - A user-defined target is registered by
ipt_register_target and unregistered by
ipt_unregister_target
11How to Implement a Network Hook
12Hooks
- NF_HOOK(int pf, unsigned int hook, struct sk_buff
skb, struct net_device indev, struct net_device
outdev, int (okfn)(struct sk_buff ) - Defined as a macro
- NF_HOOK(pf, hook, skb, indev, outdev, okfn)
\ (list_empty(nf_hooks(pf)(hook)) ?
(okfn)(skb) \ nf_hook_slow((pf), (hook), (skb),
(indev), (outdev), (okfn), INT_MIN)) - Invoked in, for exmaple, ip_local_ deliver() in
net/ipv4/ip_input.c - return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb,
skb-gtdev, NULL, ip_local_deliver_finish)
13nf_hook_ops
- struct nf_hook_ops
-
- struct list_head list
- / User fills in from here down. /
- nf_hookfn hook
- struct module owner
- int pf
- int hooknum
- / Hooks are ordered in ascending priority. /
- int priority
-
- Hooks are registered by calling nf_register_hook
in the module_init functions
14Netfilter Hook Implementation Step 1
- To implement a network filter, fill out the
nf_hook_ops structure - static struct nf_hook_ops simple_ops
NULL, NULL , simple_hook, PF_INET,
NF_IP_LOCAL_OUT, NF_IP_PRI_FILTER-1
15Netfilter Hook Implementation Step 2
- Write the hook function
- static unsigned int
- simple_hook(unsigned int hook, struct sk_buff
pskb, const struct net_device indev, const
struct net_device outdev, int (okfn)(struct
sk_buff )) -
- / Get a handle to the packet data /
- unsigned char data (void )(pskb)-gtnh.iph
- (pskb)-gtnh.iph-gtihl4
- (pskb)-gtnfcache NFC_UNKNOWN
- switch ((pskb)-gtlen)
- case 100
- printk("linuxmag corrupting packet\n")
- data99
- (pskb)-gtnfcache NFC_ALTERED
- return NF_ACCEPT
- case 200
- printk("linuxmag dropping packet\n")
- return NF_DROP
- default return NF_ACCEPT
-
16Netfilter Hook Implementation Step 3
- Register the network filter with
nf_register_hook() - include ltlinux/config.hgt
- include ltlinux/module.hgt
- include ltlinux/netfilter_ipv4.hgt
- include ltlinux/ip.hgt
- Following this comes the simple_hook function,
then the simple_ops structure, then - static int __init init(void)
- return nf_register_hook(linuxmag_ops)
-
- static void __exit fini(void)
- nf_unregister_hook(linuxmag_ops)
-
- module_init(init)
- module_exit(fini)
17From IP Stack to Hooks
NF_HOOK( NF_IP_PRE_ROUTING )
NF_HOOK( NF_IP_LOCAL_IN )
NF_HOOK( NF_IP_FORWARD )
NF_HOOK( NF_IP_POST_ROUTING )
NF_HOOK( NF_IP_LOCAL_OUT )
nf_hook_slow() elem nf_hookspfhook verdic
t nf_iterate(...,elem,...)
nf_iterate() for each elem in list elem-gthook(.
..)
ipt_do_table(.., table,.. ) traverse the entries
of table if match do target
18ipt_do_table
ipt_do_table() e get_entry(...) back
get_entry(...) do if( ip_packet_match(...) )
if( IPT_MATCH_ITERATE(...) !0) goto
no_match t ipt_get_target(e) if( t is
standard target) v t-gtverdict if( v
IPT_RETURN) eback back... if( v lt 0
) verdict (-v)-1 break else eget
_entry(...,v) else v t-gttarget(...)
while(!hotdrop)
19A Generic Hook
- ipt_do_table in ip_tables.c
- Do generic ip packet check (ip_packet_match)
- Iterate through all the matches of an entry in a
given table - If the packet matches, call the target of the
entry - If the verdict returned from the target function
is IPT_RETURN, go back to the entry where we came
from - If IPT_CONTINUE, go to the next entry
20How to Implement a Netfilter Match
21Implementing a Netfilter Match
- In the iptables framework
- Under iptables/extensions/, place the
libipt_xxx.c program, where xxx is the name of
the match. - Add xxx in iptables/extensions/Makefile
- The shared library, libipt_xxx.c, should have an
_init() function, which will automatically be
called upon loading. - The moral equivalent of the kernel module is
init_module() function. - The _init() function should call register_match()
with a pointer to an iptables_match entry as the
argument.
22Data Structure in iptables.h
- struct iptables_match
-
- struct iptables_match next
- ipt_chainlabel name
- const char version
- / Size of match data. /
- size_t size
- / Size of match data relevent for userspace
comparison purposes / - size_t userspacesize
- / Function which prints out usage message. /
- void (help)(void)
- / Initialize the match. /
- void (init)(struct ipt_entry_match m, unsigned
int nfcache) - / Function which parses command options
returns true if it ate an option / - int (parse)(int c, char argv, int invert,
unsigned int flags, const struct ipt_entry
entry, unsigned int nfcache, struct
ipt_entry_match match) -
Set to IPTABLES_VERSION
Use IPT_ALIGN(0 macro to ensure it is correctly
aligned
Used to initialize the extra space (if any) in
ipt_entry_match structure and set nfcache bits
23Data Structure in iptables.h
- / Final check exit if not ok. /
- void (final_check)(unsigned int flags)
- / Prints out the match iff non-NULL put space
at end / - void (print)(const struct ipt_ip ip, const
struct ipt_entry_match match, int numeric) - / Saves the match info in parsable form to
stdout. / - void (save)(const struct ipt_ip ip, const
struct ipt_entry_match match) - / Pointer to list of extra command-line options
/ - const struct option extra_opts
Used by the chain listing code to print the match
information
24In libipt_xxx.c
- Define the iptables_match structure
- static struct iptables_match ipaddr
- .name "ipaddr",
- .version IPTABLES_VERSION,
- .size IPT_ALIGN(sizeof(struct
ipt_ipaddr_info)), - .userspacesize IPT_ALIGN(sizeof(struct
ipt_ipaddr_info)), - .help help,
- .init init,
- .parse parse,
- .final_check final_check,
- .print print,
- .save save,
- .extra_opts opts
- Register the match in the _init() function.
- void _init(void) register_match(ipaddr)
25Implementing a Netfilter Match
- In the netfilter framework
- Under linux/net/ipv4/netfilter, place the
ipt_xxx.c kernel module - Under linux/include/linux/netfilter_ipv4/, add
ipt_xxx.h header file.
26The Netfilter Kernel Module
- See the handout for the match function
- static struct ipt_match ipaddr_match
- .name "ipaddr",
- .match match,
- .checkentry checkentry,
- .me THIS_MODULE,
-
- static int __init init(void)
- printk(KERN_INFO "ipt_ipaddr init!\n")
- return ipt_register_match(ipaddr_match)
-
- static void __exit fini(void)
- printk(KERN_INFO "ipt_ipaddr exit!\n")
ipt_unregister_match(ipaddr_match) -
- module_init(init)
- module_exit(fini)
27The psd Match Module
- Port scan detector
- Doesn't come with the default netfilter code. Use
patch-o-matic to add this module - Keep a hash table to store entries based on its
source address. - If a packet destined to a different port arrives
within the delay threshold, add lo_ports_weight
(for port lt1024) or hi_ports_weight to the total
weight. - If the total weight exceeds weight_threshold,
alerts a possible port scan. - The structure is similar to the port knocking
module in project 5
28The psd Match Module (cont.)
- ipt_psd_match (ipt_psd.c)
- L167 find this source address in the hash table
- L177 if the entry is not too old, check if we
have seen this port - L221 add this port
- L286 add a new entry to the hash table
29Port Knocking
30Port scanning
- A method of probing a computer to see what ports
are open. - A brute force operation
- One simply tries to establish a connection to
each and every port on the target computer. - When a connection is established, the caller
makes note of the port number and continues on. - The caller can then examine these ports later to
see if any known security holes exist.
31Port Knocking
- As long as ports remain open, network
applications are susceptible to attack ? ports
are initially closed. - A handful of ports are configured to deny all
traffic no ICMP error packets are sent back to
the connecting client. - Users make connection attempts to sequence of
closed ports. All failed connection attempts are
logged by the server-side packet filtering
firewall and detected by a daemon that monitors
the firewall log file. - When a properly formatted knock sequence is
received, firewall rules are manipulated based on
the information content of the sequence.
32Example
- Ports 100-109 are configured to deny all traffic.
- ipchains -A input -p tcp -s 0/0 -d IPF/32 100109
-j DENY -l - A user attempts to connect from IPC to the
following firewall ports in sequence
102,100,100,103. - From the point of view of the user, the
connections fail silently. - On the firewall, the 102,100,100,103 number
sequence has been recorded. - Feb 12 001326 ... input DENY eth1 PROTO6
IPC64137 IPF102 ... - Feb 12 001327 ... input DENY eth1 PROTO6
IPC64138 IPF100 ... - Feb 12 001327 ... input DENY eth1 PROTO6
IPC64139 IPF100 ... - Feb 12 001328 ... input DENY eth1 PROTO6
IPC64140 IPF103 ... - The knock sequence appears in the firewall log.
33Implementation
- A method is needed to monitor the firewall log
file. - A method is required to extract the sequence of
ports from the log file and translate them into
usable information. - How to detect a port sequence begins and ends.
- How to correctly detect a port sequence in the
presence of spurious connection attempts that are
not part of the sequence.
34Example of Implementation
- Ports 100-109 are used to listen to knocks.
- The port sequence is expected to be of the form
- 102,100,110 10a,10b,10c,10d 10(abcd
mod 10) 110,100,102 - header payload
checksum footer - The first and last three ports let the port
knocking dæmon know that a sequence is starting
and ending. - The next four ports encode the port (abcd) to be
opened. - For example, if a connection to port 143 is
required, the sequence would be 100,101,104,103. - The final element in the sequence is a checksum
that validates the sequence payload. - In this example, the checksum is 8 (143 mod
10). - The full sequence would be 102,100,103
100,101,104,103 108 103,100,102.
35Example of Implementation
- When this sequence is detected, port 143 would be
made available to the incoming IP address. - If the port is open already, the knock would
rendered it closed. - The knock can be extended to include additional
information, such as an anticipated session
length, that can be used to close the port after
a set amount of time.
36Mapping with Encryption
- The information contained in the knock sequence
can be encrypted to provide an additional measure
of security. - Example
- 256 ports are allocated and logged.
- A knock map of the form
- remote IP port time checksum
- is used where the remote IP, port, time and
checksum (sum of other fields mod 255) are
encrypted. - The encrypted string can be mapped onto eight
unsigned chars using, for example, Perl's
pack("C",STRING) command.
37Benefits
- Port knocking provides a stealthy method of
authentication and information transfer to a host
that has no open ports. - It is not possible to determine successfully
whether the machine is listening for knock
sequences. - It is unlikely that the form of connection
attempts would be detected by monitoring traffic. - A sequence can corresponds to a request that a
port be opened for a specific length of time and
then closed.
38Disadvantages
- Performance penality use of port knocking
imposes an overhead for each connection. - A number of ports have to be allocated for
exclusive use by port knocking. - In the case that no ports are initially open, if
the listening daemon fails or is not able to
interpret the knocks correctly, it becomes
impossible to conect remotely to the host.