Friday, February 21, 2025

[F-Stack] Sử dụng Kernel NIC Interface trong F-Stack

-

Khi sử dụng F-Stack với KNI (Kernel NIC Interface), đoạn này hướng dẫn cách thiết lập một virtual NIC (veth0) để kernel có thể xử lý một phần lưu lượng mạng thông qua giao diện ảo KNI. Đây là một bước cần thiết vì F-Stack vận hành trong không gian người dùng (user space) và không tương tác trực tiếp với các giao diện mạng của kernel.

Nếu bạn đã bật KNI trong file cấu hình của F-Stack (enable=1), bạn cần tạo một virtual NIC sau khi F-Stack khởi chạy.

Virtual NIC này (thường là veth0) là cầu nối giữa kernel và F-Stack, cho phép kernel xử lý các gói tin được F-Stack chuyển về thông qua KNI.

Bạn phải thiết lập thông tin (IP address, netmask, MAC address, route table) trên interface KNI.

Các thông tin này phải trùng khớp với cấu hình của F-Stack, đảm bảo kernel và F-Stack hiểu đúng cách xử lý các gói tin qua virtual NIC.

Nếu hệ thống của bạn không có port management riêng ví dụ như eth0 để giao tiếp với kernel, bạn cần cấu hình interface KNI (veth0) để sử dụng theo quy trình sau:

Khởi chạy Nginx đã được tích hợp với F-Stack.

/usr/local/nginx_fstack/sbin/nginx

Thiết lập thông tin cho veth0:

  • <ipaddr>: Địa chỉ IP (phải trùng với cấu hình của F-Stack).
  • <netmask>: Subnet mask (phải giống F-Stack).
  • <broadcast>: Địa chỉ broadcast (tùy thuộc vào subnet mask).
  • <mac addr>: Địa chỉ MAC (phải giống F-Stack).

Thêm một route để kernel có thể xử lý lưu lượng mạng thông qua veth0.

  • <gateway>: Gateway mà interface veth0 sử dụng.
route add -net 0.0.0.0 gw <gateway> dev veth0

Nếu carrier không được tự động bật khi nạp kernel module rte_kni.ko, lệnh này sẽ kích hoạt trạng thái “carrier on” cho interface veth0. Điều này cần thiết để interface hoạt động bình thường.

echo 1 > /sys/class/net/veth0/carrier

Thêm các route bổ sung nếu cần.

# route add -net ...  # other route rules

Khi nào cần thực hiện các bước này?

  • KNI bật (enable=1): Khi bạn muốn một phần lưu lượng mạng được xử lý bởi kernel (thay vì hoàn toàn do F-Stack xử lý).
  • Hệ thống không có cổng management port.

Lưu ý.

  • Đồng bộ cấu hình giữa F-Stack và KNI:
    • IP, netmask, MAC, và bảng định tuyến của interface veth0 phải khớp hoàn toàn với cấu hình của F-Stack trong file cấu hình (f-stack.conf).
  • Tác dụng của carrier:
    • Nếu trạng thái carrier không bật, interface veth0 sẽ không nhận hoặc gửi được lưu lượng. Dòng lệnh echo 1 khắc phục vấn đề này.
  • Cần quyền root:
    • Các thao tác trên yêu cầu quyền root hoặc người dùng có đủ đặc quyền (sudo).

Kết quả mong đợi.

Sau khi thực hiện, bạn sẽ:

  • Có một interface KNI (veth0) hoạt động như một port mạng ảo giữa kernel và F-Stack.
  • Kernel có thể xử lý gói tin thông qua veth0 và chúng ta có thể dùng công cụ như tcpdump để giám sát lưu lượng trên interface này.

Ví dụ để cấu hình F-Stack KNI cho phép lưu lượng SSH thông qua kernel.

Để cấu hình sao cho chỉ cổng 22 được xử lý bởi kernel, còn cổng 80 và 443 được xử lý bởi F-Stack, bạn cần sử dụng 1 trong 2 tùy chọn cấu hình như sau:

Tùy chọn KNI với method là reject.

Vào file /usr/local/nginx_fstack/conf/f-stack.conf.

[kni]
enable=1
method=reject
tcp_port=80,443
udp_port=
  • method=reject: Khi bạn sử dụng reject, các gói tin không thuộc các cổng được liệt kê trong tcp_port sẽ được xử lý bởi kernel.
  • tcp_port=80,443: Các gói tin đến cổng 80 và 443 sẽ được xử lý bởi F-Stack.
  • Không liệt kê cổng 22: Cổng 22 không được liệt kê trong tcp_port, vì vậy kernel sẽ xử lý các gói tin đến cổng này.

Với cấu hình trên, bạn sẽ đạt được mục tiêu là chỉ có cổng 22 được xử lý bởi kernel, còn các cổng 80 và 443 sẽ được xử lý bởi F-Stack.

Tùy chọn KNI với method là accept.

Vào file /usr/local/nginx_fstack/conf/f-stack.conf.

[kni]
enable=1
method=accept
tcp_port=80,443
udp_port=

Giải thích:

  • method=accept: Khi bạn sử dụng accept, chỉ các gói tin đến cổng được liệt kê trong tcp_port sẽ được xử lý bởi F-Stack, còn lại sẽ được xử lý bởi kernel.
  • tcp_port=80,443: Các gói tin đến cổng 80 và 443 sẽ được xử lý bởi F-Stack.
  • Không liệt kê cổng 22: Cổng 22 không có trong tcp_port, vì vậy kernel sẽ xử lý các gói tin đến cổng này.
  • Với 2 tùy chọn trên chúng ta có cùng kết quả.
    • Cổng 80 và 443: Xử lý bởi F-Stack.
    • Cổng 22: Xử lý bởi kernel.
  • method=accept so với cấu hình method=reject:
    • method=accept là ngược lại với method=reject. Khi bạn chọn accept, F-Stack sẽ xử lý các gói tin đến cổng được liệt kê (80, 443 trong trường hợp này), còn tất cả các cổng khác sẽ được xử lý bởi kernel.
    • method=reject thì sẽ xử lý các cổng không liệt kê trong tcp_port qua kernel.

Vì vậy, với cấu hình method=accept, bạn vẫn đạt được mục tiêu là F-Stack xử lý cổng 80 và 443, và kernel xử lý cổng 22.

Lưu ý: Vì tôi chỉ cài Nginx F-Stack và Nginx F-Stack chỉ xử lý HTTP/HTTPS (cổng 80 và 443), không có tích hợp xử lý SSH. SSH chỉ có thể được xử lý bởi kernel qua cổng 22. Vì vậy cấu hình dưới đây sẽ không chạy được cho port 22 của SSH.

[kni]
enable=1
method=reject
tcp_port=80,443,22

Sau khi thay đổi f-stack.conf, nhớ restart lại F-Stack Nginx nhé.

/usr/local/nginx_fstack/sbin/nginx -s stop
/usr/local/nginx_fstack/sbin/nginx

Verify F-Stack Nginx đã chạy.

shell> ps -aef | grep nginx
root       24339       1  0 19:56 ?        00:00:00 nginx: master process /usr/local/nginx_fstack/sbin/nginx
root       24340   24339 99 19:56 ?        00:01:54 nginx: worker process
root       24351   24227  0 19:58 pts/0    00:00:00 grep nginx

Kết quả thành công khi curl 10.237.7.79.

shell> curl 10.237.7.79
Chào mừng bạn đến với website của tôi

Nhưng với port 22 của SSH thì vẫn chưa được nhé.

shell> telnet 10.237.7.79 22
Trying 10.237.7.79...

Cấu hình thông tin network cho interface ảo veth0.

Trong file cấu hình chính (f-stack.conf), mình đã cấu hình thông tin network như sau:

[port0]
addr=10.237.7.79
netmask=255.255.255.0
broadcast=10.237.7.255
gateway=10.237.7.1

Điều này thiết lập địa chỉ IP và thông tin network của F-Stack cho NIC chính.

Các bước sau khi cấu hình

  • Khởi động F-Stack và KNI:
    • Sau khi bật KNI, F-Stack sẽ chuyển các gói tin không xử lý được (theo method=reject) về kernel.
    • Đảm bảo kernel module rte_kni.ko đã được nạp trước đó (lsmod | grep rte_kni).
  • Cấu hình interface KNI:
    • Nếu interface veth0 chưa được tự động cấu hình, thực hiện thủ công:

Khi mình check trạng thái veth0 thì mình thấy veth0 chưa được cấu hình.

shell> ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:80:d0:38 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 10.237.7.78/24 brd 10.237.7.255 scope global ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe80:d038/64 scope link 
       valid_lft forever preferred_lft forever
5: veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:50:56:80:28:3c brd ff:ff:ff:ff:ff:ff

Dưới đây mình sẽ cấu hình thủ công cho veth0 theo thông tin đã khai báo trong file cấu hình f-stack.conf.

ifconfig veth0 10.237.7.79 netmask 255.255.255.0 broadcast 10.237.7.255
route add default gw 10.237.7.1 dev veth0
echo 1 > /sys/class/net/veth0/carrier

Kết quả kiểm tra lại bằng lệnh ip a.

shell> ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:80:d0:38 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 10.237.7.78/24 brd 10.237.7.255 scope global ens160
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe80:d038/64 scope link 
       valid_lft forever preferred_lft forever
5: veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UNKNOWN group default qlen 1000
    link/ether 00:50:56:80:28:3c brd ff:ff:ff:ff:ff:ff
    inet 10.237.7.79/24 brd 10.237.7.255 scope global veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe80:283c/64 scope link 
       valid_lft forever preferred_lft forever

Kiểm tra kết nối SSH:

Từ một máy nào đó có kết nối network đến 10.237.7.79, thử telnet port 22 và bạn thấy kết quả thành công như dưới.

shell> telnet 10.237.7.79 22
Trying 10.237.7.79...
Connected to hoanghd.com.
Escape character is '^]'.
SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.7

Thử SSH đến IP của bạn (10.237.7.79) qua port 22.

Lưu ý quan trọng.

  • Nếu bạn có firewall (iptables, nftables) hoặc dịch vụ khác kiểm soát kết nối, hãy đảm bảo rằng port 22 được mở.
  • Cấu hình KNI cần khớp với thiết lập mạng của F-Stack để tránh xung đột hoặc lỗi không mong muốn.
  • Kiểm tra log của F-Stack (/usr/local/nginx_fstack/logs/error.log) để đảm bảo cấu hình KNI đã được áp dụng chính xác.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories