C. PHầN MềM dl-cryptor
2. Lập trỡnh module bảo mật mạng
2.1 Lập trỡnh module
Module cũng giống như hầu hết mọi chương trỡnh khỏc chỉ khỏc rằng cỏc trỡnh
ứng dụng bỡnh thường thỡ chạy trong mụi trường người dựng cũn module thỡ chạy
trong nhõn của hệ điều hành. Vỡ thế, chỳng phải được định nghĩa MODULE và
phải khai bỏo (include) file header module.h, cựng với cỏc file kernel header cần thiết khỏc mà định nghĩa hàm hoặc cỏc biến mà được dựng trong module. Module cú thể khỏ đơn giản, nhưng chỳng cũng cú thể là khỏ phức tạp như cỏc trỡnh điều khiển thiết bị và hệ thống file.
Sau đõy là định dạng chung của một module:
#define MODULE
#include <linux/module.h>
/* ... cỏc file header cần thiết khỏc ... */ /*
* ... cỏc khai bỏo cho module và cỏc hàm sử dụng trong module ... */
int init_module() {
/* mó kernel sẽ gọi khi chỳng ta cài đặt module */ ...
}
void cleanup_module( ) {
/* mó kernel sẽ gọi khi chỳng ta loại bỏ module */ }
Chỳng ta phải chỳ ý rằng khụng phải tất cả mọi biến trong kernel cũng
được xuất khẩu (export) cho cỏc module sử dụng, cho dự là trong đoạn trỡnh chỳng
ta cú khai bỏo extern. Gần đõy nhõn linux cú xuất khẩu cả hai đối tượng (symbol) và phiờn bản của nú sử dụng macro EXPORT_SYMBOL(x). Đối với biến mà do
người dựng tạo ra, sử dụng macro EXPORT_SYMBOL_NOVERS(x) để thay thế,
trỡnh liờn kết sẽ khụng tỡm biến này trong bảng đối tượng của nhõn. Người lập
trỡnh module cú thể muốn sử dụng macro EXPORT_NO_SYMBOL, theo ngầm
định module sẽ xuất khẩu tất cả cỏc biến của nú.
Cài đặt và xoỏ bỏ module đơn giản như gọi một chương trỡnh với tờn của
module biờn dịch. Bạn phải là siờu người dựng (super user) thỡ mới được phộp cài
đặt hoặc loại bỏ module. Chương trỡnh insmod sẽ tiến hành cài đặt module, đầu
tiờn nú sẽ liờn kết module với bảng đối tượng mà nhõn xuất khẩu để giải quyết vấn
đề về tham chiếu và sau đú nú sẽ cài đặt mó vào trong nhõn (kernel space).
/sbin/insmod module_name
Chương trỡnh rmmod sẽ xoỏ bỏ module đó được cài đặt và mọi tham chiếu mà nú
đó xuất khẩu.
/sbin/rmmod module_name
Trỡnh lsmod sẽ liệt kờ danh sỏch tất cả cỏc module hiện tại được nạp /sbin/lsmod
2.3 Module bảo mật mạng ở tầng datalink
Trong nhõn linux việc gửi và nhận gúi tin mạng được chứa trong cấu trỳc chứa gúi tin struct sk_buff. Mọi xử lý ở cỏc tầng khỏc nhau đều xử lý trờn cấu trỳc này. Ta thấy trong nhõn linux việc gửi và nhận gúi tin ở tầng data link được thực hiện nhờ hai hàm là dev_queue_xmit() trong trường hợp gửi gúi tin đi và net_bh() trong trường hợp nhận gúi tin. Hàm dev_queue_xmit() sẽ chuyển dữ liệu vào hàng đợi cho giao diện vật lý gửi gúi tin đi. Mặt khỏc hàm net_bh() sẽ lấy gúi tin do giao diện vật lý nhận được đưa vào bộ đệm hàng đợi để chuyển lờn cho cỏc giao thức ở trờn xử lý. Vỡ vậy chỳng ta thấy để can thiệp mật mó vào tầng data link thỡ giải
phỏp can thiệp vào hai hàm này là phương phỏp tối ưu nhất. Khi gúi tin được
truyền đi, hàm dev_queue_xmit() sẽ thực hiện việc mó hoỏ và sang bờn nhận hàm net_bh() sẽ thực hiện việc giải mó. Như vậy, đối với cỏc giao thức mạng ở tầng
cao hơn (vớ dụ, giao thức tầng mạng IP) ở hai mỏy là trong suốt. Mó hoỏ Giải mó LAN 2 GW 2 GW 1 LAN 1 Giải mó Mó hoỏ
Trong mỏy thực hiện việc định tuyến (router, gateway) thỡ việc gúi tin đi ra
card mạng nào thỡ được mó là điều rất quan trọng. Bởi vỡ hàm dev_queue_xmit() và hàm net_bh() được hệ điều hành dựng chung cho mọi giao diện. Nếu tất cả mọi gúi tin đi và đến đều thực hiện mó hoỏ hoặc giải mó thỡ hệ thống của chỳng ta cú thể khụng làm việc được nữa (bởi vỡ gúi tin được mó hoỏ hay giải mó một chiều thỡ cấu trỳc của nú bị phỏ vỡ và cỏc giao thức ở tầng trờn khụng thể xử lý được nữa). Rất may, trong linux việc lựa chọn gúi tin đi ra hay nhận về card mạng nào thỡ được mó hoỏ hay giải mó là bài toỏn rất đơn giản. Bởi vỡ, gúi tin nhận hay gửi trong cấu trỳc sk_buff của gúi tin đều cú chứa cấu trỳc thiết bị (struct device) mà gửi hay nhận. Vỡ thế ta sử dụng cấu trỳc device này để quyết định mó hay giải mó gúi tin gửi đi hay nhận được.
Người lập trỡnh ỏp dụng cơ chế con trỏ hàm trong ngụn ngữ C để thi hành nhõn Linux một cỏch linh hoạt. Bằng chứng là Linux hỗ trợ nhiều kiểu hệ thống file, nhiều họ giao thức, và mang tớnh tương thớch cao với cỏc hệ thống khỏc.
Chớnh con trỏ hàm cho phộp người lập trỡnh thi hành cơ chế module đối với nhõn Linux. Cụ thể, khi chốn module vào nhõn thỡ con trỏ hàm trỏ tới module của họ, kể từ đú nhõn Linux hoạt động với tớch năng mới cú trong module. Khi loại bỏ module, người lập trỡnh cần thiết lập cho nhõn hoạt động như lỳc chưa nạp
module.
Người viết module cú thể lợi dụng luụn con trỏ hàm cú sẵn trong nhõn, cũng cú lỳc người lập trỡnh phải tự tạo ra con trỏ hàm cho bài toỏn cụ thể của mỡnh. Trong trường hợp thứ nhất người lập trỡnh khụng phải biờn dịch lại nhõn, trong trường hợp thứ hai người lập trỡnh phải tiến hành biờn dịch lại nhõn một lần duy nhất sau khi đó thờm con trỏ hàm vào nhõn. Sau đú người lập trỡnh chỉ cũn phải tập trung phỏt triển hồn thiện module.
Việc can thiệp mật mó vào tầng data link để bảo mật luồng dữ liệu truyền thụng mạng được viết thành dạng module. Để cú thể can thiệp vào nhõn ở tầng
mạng này, chỳng ta phải tự tạo ra biến con trỏ hàm cho chớnh mỡnh. Cụng việc
được chia thành hai phần:
• Chốn cỏc con trỏ hàm tại cỏc vị trớ thớch hợp trong nhõn và sau đú biờn dịch lại nhõn.
+ Thờm vào gần cuối file net/netsyms.c cỏc dũng sau: extern int (*encrypt_ptr)(struct sk_buff *);
EXPORT_SYMBOL_NOVERS(encrypt_ptr); extern int (*decrypt_ptr)(struct sk_buff *);
EXPORT_SYMBOL_NOVERS(decrypt_ptr);
+ Chốn vào file net/core/dev.c (ngay trước hàm dev_queue_xmit() ) dũng sau: int (*encrypt_ptr)(struct sk_buff *) = 0;
+ Chốn vào file net/core/dev.c (ngay trước hàm net_bh( )) dũng sau: int (*decrypt_ptr)(struct sk_buff *) = 0;
+ Chốn vào hàm dev_queue_xmit (trong file net/core/dev.c ) đoạn mó in nghiờng sau:
int dev_queue_xmit(struct sk_buff *skb) {
struct device * dev = skb->dev;
struct Qdisc *q;
if (encrypt_ptr)
(*encrypt_ptr)(skb);
. . .
}
void net_bh(void) { . . . handle_bridge(skb, type); #endif if (decrypt_ptr) (*decrypt_ptr)(skb); . . . }
+ Biờn dịch lại nhõn bằng cỏc lệnh make menuconfig, make dep, make bzImage, copy nhõn vào thư mục /boot , sửa file /etc/lilo.conf để chạy nhõn vừa dịch xong.
• Viết mó cho module
#include <linux/module.h> #include <linux/skbuff.h> #include <linux/if_ether.h> #include <linux/netdevice.h> #include “blockcipher.h”
extern int (*encrypt_ptr)(struct sk_buff *); extern int (*decrypt_ptr)(struct sk_buff *);
/* Hàm thực hiện kiểm tra gúi tin và mó hoỏ trong hàm dev_queue_xmit() */ int encrypt_func(struct sk_buff *skb)
{
/* Nếu khụng phải gúi tin chuyển qua eth0 thỡ khụng mó hoỏ */ if (strcmp(skb->dev, “eth0”) !=0)
goto NOT_ENCRYPT; /* Nếu gúi tin chuyển qua eth0 thỡ mó hoỏ gúi tin */
Encrypt(skb); /* Gọi hàm mó hoỏ gúi tin */ return 1;
NOT_ENCRYPT: return 0; return 0; }
/* Hàm thực hiện kiểm tra gúi tin và giải mó trong hàm net_bh() */ int decrypt_func(struct sk_buf *skb)
{
/* Nếu gúi tin nhận được khụng phải nhận từ eth0 thỡ khụng giải mó */ if (strcmp(skb->dev, “eth0”)
goto NOT_DECRYPT;
/* Nếu gúi tin nhận được từ card eth0 thỡ giải mó gúi tin */ Decrypt(skb);
return 1; NOT_DECRYPT: return 0;
}
/* Hàm khởi tạo module */ int init_module() { EXPORT_NO_SYMBOLS; encrypt_ptr = encrypt_func; decrypt_ptr = decrypt_func; printk(“Begining encryption !\n”); return 0; }
/* Hàm được gọi khi loại module */ void cleanup_module()
{
encrypt_ptr = 0; / * Khụng dựng hàm mó hoỏ */ decrypt_ptr = 0; /* Khụng dựng hàm giải mó */ printk(“Stopping encryption network frame \n”); }
+ Ta tạo ra make file dựng để biờn dịch thành module: CC=gcc
all:
$(CC) –c datalink.c –O6 –D__KERNEL__ -DMODULE –Wall clean:
rm –f datalink.o core
+ Sau khi dịch xong module ta cú thể dựng hai cõu lệnh sau để liờn kết hoặc gỡ bỏ module ra khỏi nhõn:
insmod datalink.o
Ch−ơng 2