---
# System prepended metadata

title: 'Week6: Nflog API'

---

@iamproz2911 
# Week6: Nflog API
[6th week] Nflog Ulogd

## Nội dung
Yêu cầu triển khai: 
![image](https://hackmd.io/_uploads/HJ_9wvHD1x.png)

Dựa vào Sequence Diagram hãy xây dựng API của Nflog để thu thập và báo cáo các thao tác của người dùng khi tương tác với WebOS trên Raspberry. 

Chỉ ra các vi phạm vào chính sách tường lửa của người dùng. 
## Ý tưởng 
ý tưởng của mình là gộp tất cả các file lại và trình bày data theo dạng bảng 
Đầu tiên mình sẽ lấy các trường chung của các loại file log (json pcap oprint gprint logemu)
Mình sẽ chọn ra 4 cột của bảng như sau 
Time     IP SRC     IP DST    Protocol   MAC Address 
 
Bây giờ mình sẽ lấy các trường chung riêng các file sau đó sẽ ánh xạ qua cái bảng trên như thế này 
 
Đối với syslogemu:
Log file của syslogemu có dạng như sau 
Jan  3 21:35:48 iamproz2911 pingclear! IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.98.212 DST=192.168.98.212 LEN=28 TOS=00 PREC=0x00 TTL=64 ID=58524 PROTO=ICMP TYPE=8 CODE=0 ID=61500 SEQ=0 MARK=0
Jan  3 21:35:48 iamproz2911 pingclear! IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.98.212 DST=192.168.98.212 LEN=28 TOS=00 PREC=0x00 TTL=64 ID=35819 PROTO=ICMP TYPE=8 CODE=0 ID=61500 SEQ=15744 MARK=0
 
vậy mình sẽ lấy 
Jan  3 21:35:48 : Time 
SRC=192.168.98.212 : IP SRC 
DST=192.168.98.212 : IP DST
PROTO=ICMP : Protocol 
MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 : MAC Address
 
Đối với Json:
Log file dạng như sau:
{"timestamp": "2025-01-03T21:35:48.371888+0700", "dvc": "Netfilter", "raw.pktlen": 28, "raw.pktcount": 1, "oob.prefix": "pingclear!", "oob.time.sec": 1735914948, "oob.time.usec": 371888, "oob.mark": 0, "oob.ifindex_in": 1, "oob.hook": 1, "raw.mac_len": 14, "oob.family": 2, "oob.protocol": 2048, "raw.label": 0, "raw.type": 772, "raw.mac.addrlen": 6, "ip.protocol": 1, "ip.tos": 0, "ip.ttl": 64, "ip.totlen": 28, "ip.ihl": 5, "ip.csum": 20299, "ip.id": 58524, "ip.fragoff": 0, "icmp.type": 8, "icmp.code": 0, "icmp.echoid": 61500, "icmp.echoseq": 0, "icmp.csum": 49927, "oob.in": "lo", "oob.out": "", "src_ip": "192.168.98.212", "dest_ip": "192.168.98.212", "mac.saddr.str": "00:00:00:00:00:00", "mac.str": "00:00:00:00:00:00:00:00:00:00:00:00:08:00"}
{"timestamp": "2025-01-03T21:35:48.371991+0700", "dvc": "Netfilter", "raw.pktlen": 28, "raw.pktcount": 1, "oob.prefix": "pingclear!", "oob.time.sec": 1735914948, "oob.time.usec": 371991, "oob.mark": 0, "oob.ifindex_in": 1, "oob.hook": 1, "raw.mac_len": 14, "oob.family": 2, "oob.protocol": 2048, "raw.label": 0, "raw.type": 772, "raw.mac.addrlen": 6, "ip.protocol": 1, "ip.tos": 0, "ip.ttl": 64, "ip.totlen": 28, "ip.ihl": 5, "ip.csum": 43004, "ip.id": 35819, "ip.fragoff": 0, "icmp.type": 8, "icmp.code": 0, "icmp.echoid": 61500, "icmp.echoseq": 15744, "icmp.csum": 17098, "oob.in": "lo", "oob.out": "", "src_ip": "192.168.98.212", "dest_ip": "192.168.98.212", "mac.saddr.str": "00:00:00:00:00:00", "mac.str": "00:00:00:00:00:00:00:00:00:00:00:00:08:00"}

vậy mình sẽ lấy 
"timestamp": "2025-01-03T21:35:48.371991+0700" : Time 
"src_ip": "192.168.98.212" : IP SRC 
"dest_ip": "192.168.98.212" : IP DST
ip.protocol": 1: Protocol 
"mac.str": "00:00:00:00:00:00:00:00:00:00:00:00:08:00" : MAC Address
 
 
 
Đối với PCAP:
Log file có dangj:
21:35:48.372040 IP 192.168.98.212 > 192.168.98.212: ICMP echo request, id 61500, seq 0, length 8
21:35:48.372047 IP 192.168.98.212 > 192.168.98.212: ICMP echo request, id 61500, seq 15744, length 8
21:35:50.387977 IP 192.168.98.212 > 192.168.98.212: ICMP echo request, id 61500, seq 62206, length 8
21:35:50.387984 IP 192.168.98.212 > 192.168.98.212: ICMP echo request, id 61500, seq 15491, length 8
21:35:52.372115 IP 192.168.98.212 > 192.168.98.212: ICMP echo reply, id 61500, seq 34565, length 8

vậy mình sẽ lấy 
21:35:50.387977 : Time 
192.168.98.212 : IP SRC 
192.168.98.212: IP DST (trước dấu > là ip nguồn còn sau dấu là ip đích , ví dụ: 192.168.98.212 > 192.168.98.212 thì cái trước sẽ là ip nguồn cái sau dấu > là ip ddichs)
ICMP : Protocol (Sau dấu : )
Trường hợp này không có thì sẽ hiển thị là N/A: MAC Address
 
 
 
Đối với Gprint:
log có dạng như sau: 
timestamp=2025/01/03-21:35:48,raw.pktlen=28,raw.pktcount=1,oob.prefix=pingclear!,oob.time.sec=1735914948,oob.time.usec=372051,oob.mark=0,oob.ifindex_in=1,oob.hook=1,raw.mac_len=14,oob.family=2,oob.protocol=2048,raw.label=0,raw.type=772,raw.mac.addrlen=6,ip.saddr=192.168.98.212,ip.daddr=192.168.98.212,ip.protocol=1,ip.tos=0,ip.ttl=64,ip.totlen=28,ip.ihl=5,ip.csum=20299,ip.id=58524,ip.fragoff=0,icmp.type=8,icmp.code=0,icmp.echoid=61500,icmp.echoseq=0,icmp.csum=49927,oob.protocol=2048

vậy mình sẽ lấy 
timestamp=2025/01/03-21:35:48 : Time 
ip.saddr=192.168.98.212 : IP SRC 
ip.daddr=192.168.98.212: IP DST 
ip.protocol=1: Protocol
Trường hợp này không có thì sẽ hiển thị là N/A: MAC Address
 
 
Đối với Oprint 
log của nó trình bày theo dạng thẳng xuống như sau:
===>PACKET BOUNDARY
raw.mac=default
raw.pkt=default
raw.pktlen=28
raw.pktcount=1
oob.prefix=pingclear!
oob.time.sec=1735914948
oob.time.usec=372098
oob.mark=0
oob.ifindex_in=1
oob.hook=1
raw.mac_len=14
oob.family=2
oob.protocol=2048
raw.label=0
raw.type=772
raw.mac.saddr=default
raw.mac.addrlen=6
raw=default
ip.saddr=212.98.168.192
ip.daddr=212.98.168.192
ip.protocol=1
ip.tos=0
ip.ttl=64
ip.totlen=28
ip.ihl=5
ip.csum=20299
ip.id=58524
ip.fragoff=0
icmp.type=8
icmp.code=0
icmp.echoid=61500
icmp.echoseq=0
icmp.csum=49927
oob.protocol=2048
oob.in=lo
oob.out=
ip.saddr.str=192.168.98.212
ip.daddr.str=192.168.98.212
print=pingclear! IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.98.212 DST=192.168.98.212 LEN=28 TOS=00 PREC=0x00 TTL=64 ID=58524 PROTO=ICMP TYPE=8 CODE=0 ID=61500 SEQ=0 MARK=0

 
vậy mình sẽ lấy 
timestamp=2025/01/03-21:35:48 : Time 
ip.saddr=212.98.168.192 : IP SRC
ip.daddr=212.98.168.192 : IP DST
 PROTO=ICMP : Protocol
MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00: MAC Address

## Ulogd 
Cài đặt stack phù hợp cho Ulogd, tạo các group và các log file tương ứng với các group. 

```
stack=log25:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,emu1:LOGEMU 

stack=log20:NFLOG,base1:BASE,xml1:XML 

stack=log21:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,mac2str1:HWHDR,json1:JSON 

stack=log22:NFLOG,base1:BASE,pcap1:PCAP 

stack=log23:NFLOG,base1:BASE,gp1:GPRINT 

stack=log24:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,op1:OPRINT 

[log25] 
 group=25 

[log20] 
 group=20 

[log21] 
 group=21 

[log22] 
 group=22 

[log23] 
 group=23 

[log24] 
 group=24 
``` 
## Iptables 
Tạo Rules Iptables để nhận log cảnh báo 

iptables -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j NFLOG --nflog-prefix "pingclear!" --nflog-group 19 

Tương ứng tiếp cho các group19->23. Ở đây lấy chung Protocol để kiểm tra tiện hơn. 

![image](https://hackmd.io/_uploads/HkMxuvSwye.png)

## Nflog API
    Đầu tiên mình sẽ detect ra được những cái stack sử dụng trong trong ulogd.conf. 

    Dùng Python để phân tích cấu hình của ulogd, thu thập và hiển thị các log từ các plugin khác nhau (như PCAP, JSON, syslogEMU, v.v.).  

![image](https://hackmd.io/_uploads/Sy7M_DSvyg.png)

Ở đây set cứng các tham số plugin như pcap1, emu1...  

Kiểm tra sự tồn tại của file cấu hình (/etc/ulogd.conf). 

Đọc từng dòng trong file cấu hình và xử lý: 

Nếu dòng bắt đầu với stack=, tìm kiếm tên của stack và các plugin kèm theo. 

Nếu có file= hoặc directory=, tìm kiếm đường dẫn của các file log hoặc thư mục. 

![image](https://hackmd.io/_uploads/B1GX_DSv1l.png)
Code detect ra các plugin và nhóm log trong file conf được sử dụng. 

Sau đó có tùy chọn trích dẫn đường dẫn các file đã tìm thấy trong cấu hình: 
![image](https://hackmd.io/_uploads/r1C7OwHP1e.png)

Phương thức display_logs: 

Kiểm tra xem có logs hay không. 

Duyệt qua các stack và plugin, xác định xem log có ở dạng file hay thư mục. 

Gọi các phương thức phù hợp để thu thập log từ file, thư mục hoặc PCAP. 

Cuối cùng, hiển thị các log dưới dạng bảng. 

Các phương thức thu thập log từ file hoặc thư mục: 

collect_log_file: Đọc log từ một file đơn lẻ và xử lý dựa trên loại plugin. 

collect_directory_logs: Duyệt qua tất cả các file trong thư mục có phần mở rộng phù hợp với plugin (ví dụ: .json, .xml). 

collect_pcap_file: Dùng tcpdump để đọc và phân tích một file PCAP. 

 

List các file log ra dưới dạng DataFrame: 

Triển khai dưới dạng DataFrame bằng Pandas Python: 
![image](https://hackmd.io/_uploads/BkOruPBDyx.png)
Hoặc có thể là dạng bảng: 
![image](https://hackmd.io/_uploads/rkuIODHDye.png)
Khi có log file mới được cập nhật vào file config, khởi động lại chương trình để có thể đọc được cái plugin đăng kí trong ulogd.conf. Và không có yêu cầu RealTime. 

## Demo
Dùng 2 plugin là Pcap và Json để để thu thập log 
Cấu hình trong ulogd: 
![image](https://hackmd.io/_uploads/r14q_Drw1x.png)

Cấu hình Rules tương tự trong Iptables để thu thập log về 2 group20-22 
![image](https://hackmd.io/_uploads/Bkio_wSD1l.png)

Detect Stack và Check Valid Repo: 
![image](https://hackmd.io/_uploads/SJvhuDrv1l.png)

Code detect ra 2 stack sử dụng trong bài, cũng như là đường dẫn file chính xác. 

Dùng Hping3 để tạo log trong iptables  

Hping3 –icmp --flood 10.10.16.57 

Sau khi kiểm tra Iptables nhận thấy có các thông số về log được lưu: 
![image](https://hackmd.io/_uploads/rkmpOwBP1g.png)

List Log: 
Dạng DataFrame  

Không có thông tin về MAC nên sẽ hiển thị là N/A  
![image](https://hackmd.io/_uploads/HJGCuPHD1e.png)
Hoặc có thể list ra dạng bảng: 
![image](https://hackmd.io/_uploads/BywyFwHDkl.png)

Tiếp theo, mình sẽ làm 2 kiểu Logemu, Gprint:
![image](https://hackmd.io/_uploads/rJMWYvrD1x.png)

Thêm 2 rules mới vào để log về group  
![image](https://hackmd.io/_uploads/BJgGYwSwyg.png)

Detect Stack và Check Valid Repo: 
![image](https://hackmd.io/_uploads/BJiGKwBPke.png)

List logemu ra dạng bảng: 
![image](https://hackmd.io/_uploads/HkUQKwrvyx.png)

List log detail cho Gprint vì Gprint chứa khá nhiều thông tin. 
![image](https://hackmd.io/_uploads/H1fNtvBvkl.png)

## Nhận xét:
    Mình đã triển khai các bước để thu thập log trong Ulogd, các stack được cấu hình đúng, đã thu thập được log và hiển thị trong file. 

    Xây dựng code detect tự động và list file ra các định dạng khác nhau tùy với cơ chế của loại file đó.  

    Các kết quả cho thấy code hoạt động tốt và detect cũng như kiểm tra link file hợp lệ, đầu ra cho kết quả trực quan và rõ ràng. 
