rahunas-next - based on ipset >= 6.19

ห่างหายจากการพัฒนา โครงการ RahuNAS ไปนาน ถึงจะมี update เล็ก ๆ น้อย ๆ แต่ก็ไม่มากมายอะไร รุ่นล่าสุดที่เปิดออกไปแบบ เงียบ ๆ คือ 0.2.5 ออกไปแบบพอขัดตาทัพ

สถานะการรองรับ Debian ล่าสุดของ RahuNAS คือ Squeeze (Debian 6.0) ซึ่ง ณ ปัจจุบันเป็น old-stable เนื่องจากถูก Wheezy หรือ Debian 7.0 เข้ามาแทนที่ในตำแหน่ง stable release

ระยะเวลาระหว่าง Squeeze จนมาถึง Wheezy ช่างผ่านไปอย่างรวดเร็ว แต่ด้วยการที่ผม เป็นผู้ดูแล ipset package ในฐานะ Debian Maintainer อยู่สถานะนี้มาปีกว่าละ อยากขึ้นไปเป็น DD กับเขาเหมือนกัน แต่ด้วยประสบการณ์ยังอ่อนด้อย ก็ต้องเก็บเกี่ยวประสบการณ์เพิ่มเติมต่อไป ซึ่งการเป็น package maintainer ทำให้ได้ติดตามความเคลื่อนไหวของ ipset อยู่ตลอด ทั้งการลงทะเบียน mailing-list ของนักพัฒนา netfilter (netfilter-devel) ก็ยิ่งทำให้ได้รับข่าวสารเร็วตามไปด้วย

ณ ปัจจุบัน ipset ซึ่งพัฒนาโดยนักพัฒนาหลัก คือ คุณ Jozsef Kadlecsik และทีม Netfilter ได้ออกรุ่น 6.19 ที่ได้เพิ่มความสามารถเข้าไปให้กับ ipset ซึ่งสอดคล้องกับความต้องการที่ RahuNAS วางแผนไว้

* เพิ่มช่องทางให้สามารถสร้าง third-party module เข้ามา โดยที่ไม่ต้องแก้ ipset code หรือ compile ipset ใหม่ ซึ่งส่วนนี้ ผมเป็นคนผลักดันเข้าไป (http://git.netfilter.org/ipset/commit/?id=2da431d3685c65d4355d387e213a3c...) ซึ่งคราวนั้นใช้เวลาร่วม 2 เดือน สำหรับการรอการ review และตอบรับ แต่ต้องถือว่าคุ้มค่า เพราะมาถึงวันนี้ ผมจะได้ใช้ช่องทางนี้ที่ผมเตรียมไว้
* เพิ่ม timeout โดยทาง upstream ได้เพิ่มความสามารถนี้เข้ามาได้สักระยะแล้ว ผมก็ได้ใช้ความสามารถนี้ ในการจัดการกับ ผู้ใช้ที่พยายามโหลด bittorrent โดยใช้งานร่วมกับ Suricata ทำให้ลดความยุ่งยากในการจัดการไปได้ดีทีเดียว
* เพิ่ม counters โดยความสามารถนี้ จะทำให้ ipset สามารถที่จะเก็บจำนวน packets/bytes ของแต่ละ element ได้ ซึ่งก็ตรงกับความต้องการของ RahuNAS ที่ต้องการทำ accounting และโยงไปถึงแนวคิด Bandwidth หนึ่งหลอด ที่ทาง ม.เกษตรฯ ทำอยู่ ณ ปัจจุบัน และทาง ม.ขอนแก่น ก็ต้องการความสามารถนี้เช่นกัน แต่อย่างไรก็ตาม ความสามารถนี้ ยังไม่รวมเข้ากับ mainline kernel ต้องรอหลังจาก 3.10 ออก แต่ในระหว่างนี้ สามารถนำ patch จาก ipset upstream ไปปะกับ kernel >= 3.9.0 ได้

จาก 3 ความสามารถที่ ipset มีในขณะนี้ ก็ถึงเวลาที่รอคอย คือเวลาที่พร้อมที่จะพัฒนา rahunas-next (version 2) โดยตั้งใจจะ "ยกเครื่อง" เขียนใหม่หมดทั้งกระบิ ด้วยเหตุผลที่ว่า maintain code เก่า ดูจะลำบากกว่าเริ่มเขียนใหม่ -_-'' และ Architecture ต่าง ๆ ก็ได้เปลี่ยนไปพอสมควร จากจุดเริ่มต้นของ RahuNAS (จริง ๆ ก็ตัดสินใจจะเขียนใหม่ตั้งนานแล้วหละ แต่ก็ติดตรงว่าจะ ๆ นี่หละครับ)

หลังจากจัดแจง เตรียมที่เตรียมทาง เพื่อพัฒนา ก็เริ่มที่จุดเดียวกันกับเมื่อหลายปีก่อน คือ พัฒนาในส่วนของ rahunas kernel/userspace module โดยส่วนที่เหมือนกันกับคราวก่อนคือ ดึง module เข้ามาปรับแก้ในส่วนที่เราต้องการสำหรับ RahuNAS แต่สิ่งที่ต่างไปจากเดิม คือ ผมไม่ต้อง compile ipset ใหม่ทั้งหมดเหมือนแต่ก่อนโน้นแล้ว :P

ผลที่ได้คือ ผมได้ ip_set_rahunas.ko (kernel module) และ ipset_rahunas.so (userspace module) ไปวางให้ถูกที่ถูกทาง ก็ใช้งานได้ละ

# ipset create rh_test rahunas range 192.168.12.0/24 timeout 3600 counters
# ipset add rh_test 192.168.12.1,00:17:42:62:xx:xx
# iptables -A INPUT -m set --match-set rh_test src,src
# ipset list rh_test

Name: rh_test
Type: rahunas
Revision: 0
Header: range 192.168.12.0-192.168.12.255 timeout 3600 counters
Size in memory: 12464
References: 1
Members:
192.168.12.1,00:17:42:62:xx:xx timeout 3599 packets 1773 bytes 114658
# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 2973 packets, 192K bytes)
 pkts bytes target     prot opt in     out     source               destination         
 2973  192K            all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set rh_test src,src

หลังจากทดสอบเบื้องต้น โดยผมปรับแก้จาก bitmap:ip,mac module ซึ่งสิ่งที่เพิ่มเข้าไปคือ ให้ timeout ถูก reset ถ้า set นี้ ถูก match ซึ่งก็คือ idle-timeout นั่นเอง :)

สิ่งที่จะทำเพิ่ม โดยได้อ่านเนื้อหา เรื่อง Generic Netlink มาพอสมควรแล้ว และก่อนหน้านี้ คุณ Jean-Philippe Menil ซึ่งพัฒนาระบบสำหรับสถานศึกษาเขาที่ฝรั่งเศส ได้คุยกับผม และบอกแนวทางที่เขาได้คุยกับนักพัฒนา netfilter ว่า สามารถใช้ netlink ในการส่ง message เพื่อ notify daemon ให้รู้ว่า element ไหน timeout ไปแล้วได้ โดยเขาได้ส่งตัวอย่าง patch และตัวอย่าง daemon ให้ผมดู (นานมากแล้วเหมือนกัน) แต่ code ของเขา define netlink group ขึ้นมาใหม่ ซึ่งท่าจะลำบากในการที่ต้องไป patch kernel ผมเลยลองหาข้อมูล และพบว่า Generic Netlink หรือที่ทาง นักพัฒนาบอกมาว่ามันคือ Netlink Multiplexer น่าจะเหมาะกับสิ่งที่ผมต้องการ เพราะเป้าหมายที่ผมวางไว้ในปลายทางคือ ผมจะพยายามผลักดัน RahuNAS เข้า Debian ให้ได้ การมีโครงสร้างที่ไม่ต้องไป patch โน่นนี่นั่น จะทำให้งานผมง่ายขึ้น