• Thứ Tư, 07/01/2004 17:22 (GMT+7)

    Hệ thống firewall trên linux kernel 2.4 & Netfilter Iptables


    Nâng cấp từ kernel 2.2, kernel 2.4 đưa ra rất nhiều  tính năng mới giúp Linux hoạt động tin cậy hơn và hỗ trợ cho nhiều thiết bị. Một trong những tính năng mới của nó đó là hỗ trợ Netfilter Iptables ngay trong kernel, giúp thao tác trên packet hiệu quả hơn so với các đàn anh trước đó như Ipfwadm trong kernel 2.0 và Ipchains trong kernel 2.2, tuy vẫn hỗ trợ cho các bộ lệnh cũ. Thiết lập firewall theo kiểu lọc packet (packet filtering – lọc gói thông tin) với Ipfwadm hoặc Ipchains có nhiều hạn chế: thiếu các tích hợp cần thiết để mở rộng tính năng, khi sử dụng lọc packet cho các giao thức thông thường và chuyển đổi địa chỉ mạng (Network Address Translation - NAT) thì thực hiện hoàn toàn tách biệt mà không có được tính kết hợp. Netfilter và Iptables trên kernel 2.4 giải quyết tốt các hạn chế trên, uyển chuyển hơn và có thêm nhiều tính năng khác mà Ipfwadm và Ipchains không có.

    Nguyên Tắc Làm Việc Của Netfilter Và Iptables
    Netfilter là thành phần cơ bản API (Application Program Interface) cho phép giao diện ở các lớp trên như Iptables có thể dùng nó để thao tác trên các mạng gói. Hiện nay Netfilter đưa ra bốn module cho các lớp trên sử dụng đó là Ipfwadm+ipchains, Iptables, Connection tracking và Nat. Trong Iptables định nghĩa sẵn các bảng sau:
    1. Filter: Dùng để thao tác trên các packet
    2. Nat: Sử dụng để thực hiện NAT, ví dụ như dùng để che các địa chỉ xuất phát từ trong mạng LAN khi chúng đi ra ngoài internet mà ngày nay hầu hết các mạng đều sử dụng.
    3. Mangle: Thường dùng để đánh dấu các packet dùng cho những mục đích như QoS hoặc chuyển hướng packet.

    Stateless Packet Filtering
    Dạng bộ lọc không biết được quan hệ của những packet vào với packet đi trước nó hoặc đi sau nó, gọi là cơ chế lọc không phân biệt được trạng thái của các packet hoặc nôm na là lọc thụ động (stateless packet filtering), trong kernel 2.0 hoặc 2.2 thì Ipfwadm hoặc Ipchains chỉ thực hiện được đến mức độ này. Với các firewall không phân biệt được quan hệ của các packet với nhau, chúng ta gọi là firewall chặn thụ động (stateless firewalling). Loại firewall này khó có thể bảo vệ được mạng bên trong trước các kiểu tấn công phá hoại như DoS, SYN flooding, SYN cookie, ping of death, packet fragmentation... hay  các hacker chỉ cần dùng công cụ dò mạng như nmap chẳng hạn là có thể biết được các trạng thái của các hosts nằm sau firewall. Điều này không xảy ra với firewall tích cực (stateful firewall).

    Stateful Packet Filtering
    Với mọi packet đi vào mà bộ lọc có thể biết được quan hệ của chúng như thế nào đối với packet đi trước hoặc đi sau nó, ví dụ như các trạng thái bắt tay ba lần trước khi thực hiện một kết nối trong giao thức TCP/IP (SYN, SYN/ACK, ACK), gọi là firewall có thể phân biệt được trạng thái của các packet hay nôm na là firewall tích cực (stateful firewalling). Với loại firewall này, chúng ta có thể xây dựng các quy tắc lọc để có thể ngăn chặn được ngay cả các kiểu tấn công phá hoại như SYN flooding hay Xmas tree... Hơn thế nữa Iptables còn hỗ trợ khả năng giới hạn tốc độ kết nối đối với các kiểu kết nối khác nhau từ bên ngoài, cực kỳ hữu hiệu để ngăn chặn các kiểu tấn công từ chối phục vụ (DoS) mà hiện nay vẫn là mối đe doạ hàng đầu đối vói các website trên thế giới. Một đặc điểm nổi bật nữa của Iptables là nó hỗ trợ chức năng dò tìm chuỗi tương ứng (string pattern matching), chức năng cho phép phát triển firewall lên một mức cao hơn, có thể đưa ra quyết định loại bỏ hay chấp nhận packet dựa trên việc giám sát nội dung của nó. Chức năng này có thể được xem như là can thiệp được đến mức ứng dụng như HTTP, TELNET, FTP... mặc dù thực sự Netfilter Iptables vẫn chỉ hoạt động ở mức mạng (lớp 3 theo mô hình OSI 7 lớp).

    Thực Hiện
    Chi tiết về mô tả các bảng và các tham số trong iptables các bạn có thể tham khảo tại địa chỉ http://www.unixcircle.com/iptables/iptables-tutorial/iptables-tutorial.html. Sau đây tôi sẽ trình bày cách thực hiện cụ thể trên hệ điều hành RedHat Linux 7.1 để minh hoạ.
    RedHat 7.1 được đóng gói với kernel 2.4.2 và đã được biên dịch để hỗ trợ cho Netfilter và Iptables, tuy nhiên muốn sử dụng đầy đủ các tính năng của Iptables nói trên thì cần phải nâng cấp Iptables lên phiên bản mới nhất 1.2.4 (http://netfilter.samba.org/iptables-1.2.4.tar.bz2) và biên dịch lại nhân Linux với phiên bản 2.4.16 (http://www.kernel.org/pub/linux/kernel/v2.4/linux-2.4.16.tar.gz, hiện đã có phiên bản 2.4.17).
    Khi sử dụng Linux RedHat 7.1 làm chức năng firewall, chúng ta nên cài đặt chế độ  server với chế độ văn bản và loại bỏ tất cả các chức năng (daemon) không cần thiết như sendmail, ftpd, httpd, telnetd, sshd, lpd v.v... chỉ nên login ngay tại máy để thao tác. Loại bỏ phiên bản cũ của iptables trên máy nếu nó đã được đưa vào trong quá trình cài đặt bằng lệnh rpm –e iptables.
    Giải nén kernel 2.4.16 vào thư mục /usr/src, chúng ta được source của kernel trong /usr/src/linux.
    Ví dụ: tar zxvf  linux-2.4.16.tar.gz
    Giải nén iptables-1.2.4 vào thư mục /usr/local/src chúng ta được /usr/local/src/iptables-1.2.4
    Trong thư mục iptables-1.2.4, chúng ta thực hiện các bước sau để gắn các chức năng của iptables-1.2.4 vào kernel.
    make pending-patches KERNEL_DIR=/usr/src/linux
    Sau khi gắn xong vào kernel, chúng ta tiếp tục thêm vào những chức năng mới nhất vừa được phát triển để đưa vào kernel, sử dụng lệnh sau:

    make patch-o-matic KERNEL_DIR=/usr/src/linux

    Khi thực hiện các lệnh để gắn vào kernel như trên, chúng ta nên chú ý đến dòng trạng thái mô tả chức năng của gói thêm vào, nếu hàng trạng thái chỉ ra là gói này tốt (working) hay ổn định (stable) hoặc đang chuẩn bị đưa vào hoạt động (experimental) thì có thể đưa ngay vào trong kernel, còn các trạng thái khác thì xem như là vẫn còn đang thử nghiệm, bạn cũng có thể dùng những tính năng này nếu thích.
    Chú ý để có thể sử dụng được chức năng “string pattern matching” bạn phải nhớ thêm vào chức năng CONFIG_IP_NF_MATCH_STRING trong khi thực hiện patch-o-matic. Qua kiểm nghiệm nếu các gói trong patch-o-matic hoạt động tốt thì chúng sẽ được đưa thẳng vào trong kernel ở các phiên bản kế tiếp.

    Tiếp tục tiến hành biên dịch iptables, vẫn ở trong /usr/local/src/iptables-1.2.4

    make KERNEL_DIR=/usr/src/linux

    make install KERNEL_DIR=/usr/src/linux

    Lúc này iptables đã được cài đặt trong /usr/local/sbin và  /usr/local/lib

    Tiến hành biên dịch kernel 2.4.16:

    Sau khi các gói cần thiết của Netfilter đã được đưa vào kernel xong, chúng ta bắt đầu biên dịch lại kernel và các module của nó.

    Chuyển vào thư mục /usr/src/linux và đánh lệnh: make menuconfig
    Trên giao diện cấu hình này, để tối ưu kernel chúng ta chỉ nên đưa vào những thiết bị nào cần thiết cho hệ điều hành và nên chọn chức năng làm “router”. Mục đích chính của chúng ta là sử dụng Netfilter/Iptables nên trong phần Network Options -> Netfilter Configuration chúng ta nên chọn tất cả các chức năng trong đó. Sau khi chọn xong thoát ra khỏi menu và dùng các lệnh sau để biên dịch:

    make dep; make clean; make bzImage; make modules; make modules_install

    Quá trình biên dịch nhanh hay chậm tuỳ thuộc vào cấu hình máy, sau khi quá trình biên dịch kết thúc bạn cần phải làm thêm một số thủ tục sau đây để hệ điều hành có thể chạy được kernel mới vừa biên dịch

    Chuyển tập tin  /usr/src/linux/arch/i386/boot/bzImage  vào thư mục /boot.

    Ví dụ: mv  /usr/src/linux/arch/i386/boot/bzImage  /boot/bzImage.fw

    Chuyển tập tin  /usr/src/linux/System.map  vào thư mục /boot.

    Ví dụ: mv  /usr/src/linux/System.map  /boot/System.map.fw

    Tạo liên kết mới : ln  –fs  /boot/System.map.fw  /boot/System.map

    Để đề phòng bất trắc đối với kernel mới, bạn nên tạo thêm cho quá trình khởi động máy một menu để chọn nạp kernel bằng cách hiệu chỉnh tập tin /etc/lilo.conf.

    Ví dụ:

    boot=/dev/hda

    map=/boot/map

    install=/boot/boot.b

    prompt

    timeout=30

    message=/boot/message

    linear

    default=origin

    image=/boot/vmlinuz-2.4.2-2

            label=origin

            read-only

            root=/dev/hda8

    image=/boot/bzImage.fw

            label=firewall

            read-only

            root=/dev/hda8

    Công việc cuối cùng là nhớ đánh lệnh /sbin/lilo để nạp lại cấu hình trong tập tin /etc/lilo.conf và reboot lại máy.
    Sau đây là một số ví dụ minh họa để thiết lập một firewall trên Linux

    Giả sử local network là 10.0.0.0/8 và firewall sử dụng hai card mạng, kết nối với internet bằng card mạng eth0 và với local network là eth1.

    Chống Syn Flooding:

    iptables -A FORWARD -p tcp —syn -m limit —limit 1/s -j ACCEPT

    Chống Scan Port:

    iptables -A FORWARD -p tcp —tcp-flags SYN,ACK,FIN,RST RST -m limit —limit 1/s -j ACCEPT

    Chống Ping of Death:

    iptables -A FORWARD -p icmp —icmp-type echo-request -m limit —limit 1/s -j ACCEPT

    Cho các packet đã thiết lập kết nối tiếp tục đi qua firewall:

    iptables -A FORWARD -m state —state ESTABLISHED,RELATED -j ACCEPT

    Chống giả mạo địa chỉ nội bộ từ bên ngoài để xâm nhập:

    iptables -t nat -A PREROUTING -i eth0 -s 10.0.0.0/8 -j DROP

    Chuyển đổi địa chỉ từ trong mạng nội bộ ra bên ngoài (SNAT):

    iptables -t nat -A POSTROUTING -o eth0 -j SNAT —to 203.162.0.10

    Chuyển đổi địa chỉ của web server từ bên ngoài vào trong mạng nội bộ (DNAT):

    iptables -t nat -A PREROUTING -d 203.162.0.9 -p tcp —dport 80 -j DNAT —to 10.0.0.10

    Thiết lập Transparent proxy  bằng cách chuyển hướng port 80 đến server squid proxy 10.0.0.9:

    iptables -t nat -A PREROUTING -p tcp —dport 80 -j DNAT —to 10.0.0.9:3128

    Chỉ cho máy tính trong mạng nội bộ có địa chỉ card mạng 00:C7:8F:72:14 đi ra:

    iptables -A FORWARD -m state —state NEW -m mac —mac-source 00:C7:8F:72:14 -j ACCEPT

    Thực hiện chia tải trên cả hai hướng inbound và outbound: (load balancing):

    iptables -t nat -A POSTROUTING -o eth0 -m nth —counter 7 —every 3 —packet 0 -j SNAT —to-source 10.0.0.5

    iptables -t nat -A POSTROUTING -o eth0 -m nth —counter 7 —every 3 —packet 1 -j SNAT —to-source 10.0.0.6

    iptables -t nat -A POSTROUTING -o eth0 -m nth —counter 7 —every 3 —packet 2 -j SNAT —to-source 10.0.0.7

    Chức năng ưu tiên thông lượng đối với truy cập web:

    iptables -A PREROUTING -t mangle -p tcp —sport 80 -j TOS —set-tos Maximize-Throughput

    Ngăn chặn sâu Nimda hay CodeRed (mức ứng dụng):

    iptables -I INPUT -j DROP -m string -p tcp -s 0.0.0.0/0 —string “c+dir”

    iptables -I INPUT -j DROP -m string -p tcp -s 0.0.0.0/0 —string “cmd.exe”

    iptables -I INPUT -j DROP -m string -p tcp -s 0.0.0.0/0 —string “default.ida”

    Đến đây chúng ta đã hoàn thành việc xây dựng một hệ thống firewall mạnh mẽ có thể đương đầu được với bất kỳ loại tấn công nào và là một lá chắn tin cậy cho hệ thống mạng. Bạn cũng có thể kết hợp thêm chức năng cửa ngõ mạng ảo (VPN gateway) cho firewall bằng gói freeswan có thể download tại www.freeswan.org.

    Hoàng Long
    Senior Network Engineer
    Arrive Technologies Vietnam

    ID: A0204_82