Linux firewall program design
Zhao Zhiang Mu Huajun
In early February this year, famous business websites such as Yahoo, eBay, Cnn.com, Amazon, Buy.com and E * Trade were continuously attacked, causing billions of dollars in losses, once again sounded again. Not safe alarm. The firewall is an important means of ensuring network security as a mechanism for enforcing access controls between networks or systems. At present, there are many firewalls in various commercial products in society, and it is very functional. We have no matter how the price of these firewall products is concerned that they pay attention to the versatility and compatibility of the product in the development and design, consider more market and profits, so it is not necessarily suitable for certain special applications. If the user can combine the general theory and method of the firewall design with its own actual needs, design some small and fine, strong firewall procedures, often can play more than spending big price. Universal firewall better role.
Due to the limited space limit, this paper cannot be discussed in-depth discussion on the general theory and structure of the firewall, so only the Linux system is used as an example, and the design method of the firewall program is specifically described.
First, look at the Linux network from the perspective of program design
Writing a firewall program does not necessarily require a deep understanding of the Linux network, just need to understand that there is such a mechanism in the network core, that is, the kernel can automatically call the firewall program written by the user, and returned according to this firewall program To determine the processing strategy for sending and receiving the network. This can be seen from Figure 1.
Second, how to register your own firewall program to the kernel
We already know that the kernel automatically calls the firewall program written by the user in the network layer. But there is a prerequisite that the user must register the firewall program written by himself into the kernel. For the writing method of the Linux kernel driver, see the article "LINUX Device Driver Design Example" in the fourth phase of this article.
The kernel provides the firewall registration and unloading function, respectively, respectively_firewall, and unregister_firewall, see FireWall.c.
1, Register_FireWall
The function prototype is as follows:
Int Register_firewall (int Pf, Struct FireWall_Ops * fw)
Return value: 0 The representative is successful, less than 0 is not successful.
parameter:
* The protocol flag PF, the main value and its representative agreement are as follows:
2 represents the IPv4 protocol, 4 represents the IPX protocol, 10 represents the IPv6 protocol, etc.
* The parameter structure FW is defined as follows:
Struct FireWall_Ops {
Struct FireWall_Ops * Next;
INT (* fw_forward) (struct firewall_ops * this, int Pf,
Struct Device * dev, void * phdr, void * arg, struct SK_Buff ** PSKB);
INT (* fw_input) (struct firewall_ops * this, int Pf,
Struct Device * dev, void * phdr, void * arg, struct SK_Buff ** PSKB);
INT (* fw_output) (struct firewall_ops * this, int Pf,
Struct Device * dev, void * phdr, void * arg, struct SK_Buff ** PSKB);
INT FW_PF;
INT fw_priority;
}
The NEXT domain in the structure will be modified by the kernel to point to the next firewall module.
The FW_PF domain is the protocol flag, the meaning is the same.
Fw_priority specifies the priority, generally more greater than 0.
FW_INPUT, FW_OUTPUT, FW_FORWARD are the firewall function modules written by the user, and the kernel will call these modules when receiving the network newspapers and send a network report, which will be discussed in detail later. 2, unregister_firewall
The prototype of Unregister_FireWall and the calling method is REGISTER_FIREWALL.
Third, the design of firewall function module
1. Return value of firewall function module
The return value is crucial, the kernel will determine the processing strategy adopted on the network datagram according to it. The main return value and the significance are as follows:
0 and 1 Notification of the network report.
-1 Notification The network is kept the network and sends an unacceptable network control (ICMP packet).
2 Notify the internal nuclear recognition.
2, entry parameters of each module function
* Parameters this
Point to the FW parameter structure in Register_FireWall.
* Parameter PF
Meaning with the PF parameters in Register_FireWall.
* Parameter dev
DEV is a pointer to the data structure Device. In the Linux system, each network device is described in the Device data structure. During the system boot, the network device driver to Linux registration device information, such as device name, device's I / O base address, device interrupt number, network card 48-bit hardware address, etc., the Device data structure includes these device information and device services. The address of the function. See NetDevice.h header files for more information on the Device structure.
* Parameter PHDR
This parameter points to the first site of the link layer datagram.
* Parameter arg
With this parameter, you can transfer information to kernel, such as the port number when redirecting.
* Parameter PSKB
This parameter is a pointer to the SK_BUFF structure pointer. In Linux, all network data is transmitted and received with a SK_BUFF data structure. A DEVICE address, a transport layer, a network layer, a link layer protocol header address, and the like of the corresponding device structure are included in the SK_BUFF data structure. See Skbuff.h header files for definitions of SK_Buff.
3, firewall program example
A simple firewall program is given below. It is assumed here to understand that the reader has a certain understanding of the common protocols such as the Ether Agreement, IP protocol, TCP protocol. After compiling with the command line "gcc -wall -o2 -c myfirewall.c", after loading the program with the Insmod command, the system will only respond to access to the 80 port of the external network with the TCP protocol. To allow the system to restore the original features, you can use the RMMOD command to uninstall the program, and the source code sees the same name on the website www.pcboPuting.com.cn.
// myfirewall.c Written March 7, 2000
#ifndef __kernel__
# Define __kernel__ // Compile by the kernel module
#ENDIF
#ifndef module
# Define Module / / Compile by device driver module
#ENDIF
#include // The most basic kernel module header file
#include
#include // The most basic kernel module header file
#include
#include
#include
#include
#include
#include
#include
#include
#define SOL_ICMP 1
#define permit_port 80 // only allows access to the 80 port of TCP
INT ZZL_INPUT (Struct Firewall_ops * this, int Pf, Struct Device * dev,
Void * phdr, void * arg, struct SK_Buff ** PSKB)
{// Whenever a network is received, this function will be called by the kernel.
Struct TCPHDR * TCPH; / / TCP head pointer
Struct iphdr * iph; // ip head pointer
Struct SK_Buff * SKB = * PSKB;
IF (SKB-> Protocol == HTONS (Eth_P_ARP)) {
Printk ("/ NPERMIT A ARP PACKET"); RETURN FW_ACCEPT; / / Allow Address Resolution Protocol News
}
IF (SKB-> protocol == htons (eth_p_rarp)) {
Printk ("/ NPERMIT a RARP Packet");
Return fw_accept; // Allows the reverse address analysis agreement
}
IF (SKB-> Protocol == HTONS (Eth_P_IP))
{
IPH = SKB-> NH.IPH;
IF (iPh-> protocol == SOL_ICMP)
{
Printk ("/ NPERMIT A ICMP Packet");
Return fw_accept; // Allow network control newspaper
}
IF (iPh-> protocol == sol_tcp) {
TCPH = SKB-> H.TH;
IF (TCPH-> DEST == permit_port) {
Printk ("/ NPERMIT A VALID Access");
Return fw_accept; // Allows access to TCP port 80
}
}
}
Return fw_reject; // Do not prohibit all other access to this computer
}
INT ZZL_OUTPUT (Struct FireWall_ops * this, int Pf, Struct Device * dev,
Void * phdr, void * arg, struct SK_Buff ** PSKB)
{// Program writing method with zzl_input function module
Printk ("/ NZZL_OUTPUT IS CALLED");
Return fw_skip;
}
INT ZZL_FOREWARD (Struct FireWall_Ops * this, int Pf, Struct Device * dev,
Void * phdr, void * arg, struct SK_Buff ** PSKB)
{// Program writing method with zzl_input function module
Printk ("/ NZZL_FOREWARD IS CALLED");
Return fw_skip;
}
Struct firewall_ops zzl_ops =
{
NULL,
ZZL_FOREWARD,
ZZL_INPUT,
ZZL_Output,
PF_INET,
01
}
INT init_module (void)
{
IF (register_firewall (pf_inet, & zzl_ops)! = 0)
{
Printk ("/ NUNABLE REGISTER FIREWALL");
Return -1;
}
Printk ("/ NZZL_OPS =% P", & zzl_ops);
Return 0;
}
Void Cleanup_Module (Void)
{
Printk ("unload / n");
Unregister_firewall (PF_INET, & ZZL_OPS);
}
(Author Address: No. 4, No. 4, North Third Ring Road, Beijing, China