Linux Kernel netfilter ip_conntrack module-FTP example

Source: Internet
Author: User

Many Protocol control information is included in the application layer data, which directly affects the establishment of The Link. For example, the FTP protocol is like this. FTP is divided into port mode, pass mode, and port mode, at first, the client connects to port 21 of the server. When data needs to be transmitted, the client sends a control package to the server, which contains the port opened by the client and its own IP address, after receiving the packet, the server uses its own port 20 to connect to the recommended IP address and port in the client control package. In this case, if the client uses a private IP address after Nat, the server cannot connect to the client. Therefore, the NAT gateway must handle this situation by modifying the control package sent from the client to the server (if encryption is not possible, fortunately, FTP is not encrypted). In pass mode, after the client connects to port 21 of the server, if you want to transmit data, the client also needs to connect to another random port of the server, this port is sent by the control package sent by the server to the clie NT. If the firewall on the client or server prohibits any ports that are not well-known, the data will be intercepted by the firewall; whether in port or pass mode, the firewall must handle the "second" data connection path release issue. In Linux, the related status is used for release. As mentioned above, you only need to configure one -- state related-J accept rule. However, this article details how to implement this rule and how the Linux Connection Tracing module handles the FTP Nat problem.
Start with the hook function of ip_conntrack:
Unsigned int ip_conntrack_in (...)
{
...
PROTO = ip_ct_find_proto (* pskb)-> NH. iph-> Protocol); // retrieve the Protocol number from the packet
... // Resolve_normal_ct will try to find the connection of the newly entered package in the established connection. If it cannot be found, create a new connection in the new status, at the same time, we also need to initialize the connection-related data, such as helper
Ct = resolve_normal_ct (* pskb, proto, & set_reply, hooknum, & ctinfo); // The init_conntrack function called in this example is a function that has done a lot of things.
...
If (Ret! = Nf_drop & CT-> helper) {// call the help function if helper exists.
Ret = CT-> helper-> help (* pskb, CT, ctinfo );
...
}
...
}
Init_conntrack has the following logic:
... // Search for the connection from the linked list. If the connection is found, this is a "prediction" connection.
Expected = list_find (& ip_conntrack_expect_list, expect_cmp,
Struct ip_conntrack_regular CT *, tuple );
...
If (expected ){
_ Set_bit (ips_expected_bit, & conntrack-> status); // The predicted connection is established. If a flag is set, if the resolve_normal_ct returns an existing connection, it will determine if this flag exists, set the ip_ct_related status, which can be used for filter judgment.
Expected-> sibling = conntrack; // The predicted connection has arrived and is initialized. Expected-> sibling is null during prediction, because it is only a prediction at that time, and the connection has not actually arrived. We can see that ip_conntrak will use the prediction result after ip_nat predicts, then, call helper's help to modify connection-related control data at the application layer, such as IP address and port information, when you traverse all the predicted connections of an existing connection and decide whether to call the helper of ip_nat, if the sibling field of ip_conntrack_expect is not null, ip_nat skips the prediction result, because it is already a real connection, it indicates that it has been helped when it is still a predicted connection.
...
}
...
Each ip_conntrack can have multiple helper to help process connection-related information. For example, if the FTP protocol crosses the firewall, you need to handle Nat and data connections, therefore, it is necessary to use a helper module to deal with this type of situation. helper for FTP Nat processing and helper for sub-connection processing are actually not a type of helper. The former is the ip_nat_ftp structure and the latter is the ip_conntrack_ftp structure, although they are different, their processing logic and registration logic are the same. Therefore, we will describe them in a unified way later on FTP Nat. The implementation logic of the Help function registered by ip_conntrack_ftp is as follows:
Static int help (...)
{
... // Operate SKB to retrieve all the information we need
Skb_copy_bits (SKB, dataoff, ftp_buffer, SKB-> len-dataoff );
...
Array [0] = (ntohl (CT-> tuplehash [dir]. tuple. SRC. IP)> 24) & 0xff;
Array [1] = (ntohl (CT-> tuplehash [dir]. tuple. SRC. IP)> 16) & 0xff;
Array [2] = (ntohl (CT-> tuplehash [dir]. tuple. SRC. IP)> 8) & 0xff;
Array [3] = ntohl (CT-> tuplehash [dir]. tuple. SRC. IP) & 0xff;
// The array above is the IP address that the server needs to connect.
For (I = 0; I <array_size (Search); I ++ ){
If (search [I]. dir! = DIR) continue;
Found = find_pattern (...); // search for the search character in ftp_buffer. If the search character is found, help is required for this data packet. One parameter is an array, and each element of the array is a matching key, this is called search, which is an ftp_search struct type array.
If (found) break;
}
... // If no help is found, the returned result indicates that no help is required for the data coming this time.
Exp = ip_conntrack_expect_alloc ();
... // Initialize an ip_conntrack_exact CT, which can be used to describe a connection to be established
EXP-> expectfn = NULL;
Ip_conntrack_expect_related (exp, CT); // you are about to add a related connection. If you configure a related connection in iptables rules, then the ftp port mode data connection can be unobstructed. The related connection of iptables is "expected" here, and then added to the existing connection.
Ret = nf_accept;
Out:
Unlock_bh (& ip_ftp_lock );
Return ret;
}
In the end, the "expected" connection will be added to the linked list associated with the "expected" connection in the ip_conntrack_expect_insert function, at the same time, we also add the expected connection to a global linked list of the system. If the existing connection needs to limit the connection establishment time of the "expected" connection, we need to start a timer, if the timer timeout connection fails, the expected connection will be deleted. This related connection will be used by the State module of Netfilter. For example, if you use -- state new/established /... in the match callback function of the state module, the system will retrieve the connection to which the data packet belongs, and then retrieve the state of the connection to compare it with the state of the parameter, then return to the target to select.
The above is the process of data in the ip_conntrack module. If ip_conntrack is generated, it is time to enter ip_nat, or start with its HOOK:
Static unsigned int ip_nat_fn (...)
{
...
Ct = ip_conntrack_get (* pskb, & ctinfo); // get the connection. If no connection is obtained, null is returned.
... // If an existing connection is not obtained, the accept is returned (note the special circumstances of ICMP redirection), which is determined by the future chain. In any case, Nat always takes effect after conntrack, therefore, as long as there is a connection, conntrack will add it to hash
Switch (ctinfo ){
...
Case ip_ct_new: // if it is the first package of a connection, it is necessary to initialize a series of struct, including two-direction Nat translation tables, FTP and other structures related to the Protocol requiring help, etc.
Info = & CT-> nat.info;
Write_lock (& ip_nat_lock );
If (! (Info-> initialized & (1 <maniptype ))){
...
Ret = ip_nat_rule_find (pskb, hooknum, in, out, CT, Info );
...
Return do_bindings (CT, ctinfo, info, hooknum, pskb );
}
Unsigned int do_bindings (...)
{
...
Int proto = (* pskb)-> NH. iph-> protocol;

... // Implement address/port conversion, omitted. The protocol header of the data packet is modified in the Two-Direction conversion table based on the direction and address/port information.
Helper = Info-> helper; // info will be created when ip_nat_setup_info is used to initialize the connection.
If (helper ){
... // A primary connection can have multiple secondary connections with the related, so the following will traverse these secondary connections
List_for_each_prev (cur_item, & CT-> sibling_list ){
... // If the connection is already established, it means that the following work has been done and will not be done.
If (exp_for_packet (exp, * pskb) {// if the package is reasonable, call the help function to handle special Nat translation in the Help function, such as ftp port mode-related Nat Translation
Ret = helper-> help (CT, exp, info, ctinfo, hooknum, pskb );
...
}
For the ip_nat_ftp help module, the execution logic of the Help function is as follows:
Static unsigned int help (...)
{
...
Ct_ftp_info = & EXP-> help. exp_ftp_info;
...
Ftp_data_fixup (ct_ftp_info, CT, pskb, ctinfo, exp );
...
}
In the end, ftp_data_fixup calls mangle [ct_ftp_info-> ftptype] (...). function. Apparently, the final function modifies the data packets so that the FTP server can successfully connect to the client. Because the client often uses a private IP address after a firewall with the NAT Function, in the port mode of FTP, if the client recommends a private address to the FTP server for connection, the server cannot be connected. The recommended IP address is in the FTP data packet, so the data packet must be modified, modify the recommended address and port to the address and port after Nat, and then lay a NAT entry for the server to transfer requests to the Intranet client when connecting to the client. Ip_nat_mangle_tcp_packet is a very important function in ip_nat_helper.c, which completes the modification of application layer data packets.
Ip_conntrack and ip_nat process the FTP process. The ip_conntrack module obtains the connection information and obtains a helper Based on the connection information. Note that a connection can have no helper, in addition, most of them do not have helper. Whether or not helper is required depends on the connection type. Generally, helper is used only when the application layer controls data modification, for example, FTP control commands are transmitted at the application layer, and connection types can be obtained from data packets and protocol headers. Therefore, the ip_conntrack module requires that data packets cannot be segmented, that is to say, complete IP data packets are required. After obtaining helper, call the help function to determine whether the current data packet requires help. For example, to determine whether it is a special FTP command, this command can create a new connection. If so, then, the Help function "predicts" a connection to be established and associates the current connection with it. Then, ip_conntrack basically has nothing to do. data packets continue to flow in netfilter and enter Nat, likewise, Nat is like ip_conntrack to determine whether to require help. If so, call the help function of helper, the basis for determining whether to require help is generally whether to "predict" the connection to be established in the ip_conntrack module. If so, call the help function of NAT helper, the predicted connection parameters are passed in, and the control data of the application layer is modified based on the predicted connection information in the Help function of ip_nat_ftp.
The registration of two types of helper is carried out during module initialization, while the binding between helper and connection or NAT is carried out during connection initialization. Ip_nat_fn is a NAT hook. For the ip_ct_new package, call_expect needs to be called. The latter eventually calls the following function to specify the ftp-related ip_nat_helper struct, which is registered during module initialization:
Unsigned int ip_nat_setup_info (...)
{
...
Info-> helper = list_find (& helpers, helper_cmp, struct ip_nat_helper *, & reply );
// Find the helper of ip_nat_ftp. In the init of ip_nat_ftp, ip_conntrack_helper_register is called to register FTP-related information into the kernel. The information is contained in the ip_nat_helper struct, there is a lot of static data used to match helper. For example, to create a connection, ip_nat_setup_info will be called when the data enters Nat over conntrack. In this function, for example, list_find, in fact, the current ADDR, port and other information are used to compare with the registered helper one by one. Once there is a life cycle, the Helper is taken out and reserved for use. The most important of ip_nat_helper is the help function.
...
}
The initialization function of the ip_nat_ftp module is as follows:
Static int _ init Init (void)
{
...
For (I = 0; (I <max_ports) & ports [I]; I ++ ){
FTP [I]. tuple. SRC. U. tcp. Port = htons (ports [I]);
FTP [I]. tuple. dst. protonum = ipproto_tcp;
FTP [I]. Mask. SRC. U. tcp. Port = 0 xFFFF;
FTP [I]. Mask. dst. protonum = 0 xFFFF;
FTP [I]. max_expected = 1;
FTP [I]. Timeout = 0;
FTP [I]. Flags = ip_ct_helper_f_reuse_reset CT;
FTP [I]. Me = ip_conntrack_ftp;
FTP [I]. Help = help;
...
Ret = ip_conntrack_helper_register (& FTP [I]);
...
}
Return 0;
}
The helper of ip_conntrack is also registered during module initialization and specified during connection initialization. The principle is the same as that of Nat.
In short, the Helper module is generally helpful for the protocol that needs to transmit control data in the application layer, because the protocol stack implemented by the OS does not include the application layer, however, sometimes you have to modify the control data at the application layer, so you have to need an additional help module. Note that generally, helper modifies the control data instead of the business data, the so-called control data is unrelated to the business and only affects the data connected to itself.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.