Sáu tháng trước, dịch vụ IPTV của nhà mạng tôi chỉ chạy được ở cổng LAN trực tiếp của router — Wi-Fi không được, cổng switch cũng không, không gì cả. Nguyên nhân gốc rễ là multicast. Các bản tin IGMP membership report không vượt qua được ranh giới giữa interface upstream của ISP và mạng LAN nội bộ. Tôi thử pimd trước, rồi đến smcroute, nhưng igmpproxy hóa ra là giải pháp gọn gàng nhất. Nó đã chạy liên tục không cần khởi động lại một lần nào kể từ đó.
Hướng dẫn này đi qua toàn bộ quá trình thiết lập — từ cấu hình tối giản hoạt động được đến các quy tắc tường lửa và định tuyến multi-VLAN — theo đúng con đường tôi đã đi để đến được đó.
Khởi Động Nhanh: igmpproxy Chạy trong 5 Phút
Cài đặt igmpproxy
Trên Debian/Ubuntu:
sudo apt update && sudo apt install igmpproxy -y
Trên RHEL/Rocky/AlmaLinux:
sudo dnf install igmpproxy -y
Bật định tuyến IP multicast trong kernel
igmpproxy sẽ không hoạt động cho đến khi kernel được tải hỗ trợ định tuyến multicast:
sudo modprobe ip_mr_route
echo "net.ipv4.conf.all.mc_forwarding = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Cấu hình /etc/igmpproxy.conf tối giản
Giả sử eth0 là interface upstream (WAN/ISP) và eth1 là mạng LAN nội bộ:
##
## igmpproxy.conf — cấu hình tối giản hoạt động được
##
phyint eth0 upstream ratelimit 0 threshold 1
altnet 0.0.0.0/0
phyint eth1 downstream ratelimit 0 threshold 1
Khởi động và kích hoạt service:
sudo systemctl enable --now igmpproxy
sudo systemctl status igmpproxy
Các luồng multicast từ upstream giờ sẽ chảy đến bất kỳ thiết bị nào trên eth1 gửi yêu cầu IGMP join. Kiểm tra bằng:
sudo tcpdump -i eth1 'udp and dst net 224.0.0.0/4' -n -c 20
Các gói UDP xuất hiện trên interface LAN nghĩa là proxy đang hoạt động. Đó là con đường năm phút. Mọi thứ bên dưới sẽ biến nguyên mẫu hoạt động thành thiết lập production vững chắc.
Đào Sâu: igmpproxy Thực Sự Hoạt Động Như Thế Nào
IGMP và định tuyến multicast — những điều cơ bản
Multicast hoạt động khác với unicast. Một người gửi duy nhất truyền một luồng. Mạng chỉ gửi bản sao đến các router và host đã tham gia nhóm multicast một cách tường minh qua IGMP (Internet Group Management Protocol). Bộ giải mã IPTV của bạn gửi IGMP Join cho địa chỉ nhóm như 239.1.1.1, và các router upstream cần nhận join đó rồi định tuyến lưu lượng xuống segment đang yêu cầu.
Đây là lúc định tuyến Linux cản trở: một Linux router mặc định không chuyển tiếp các bản tin IGMP membership report giữa các interface. igmpproxy lấp đầy khoảng trống đó. Nó lắng nghe IGMP report trên các interface downstream, tạo ra các IGMP join tương ứng hướng về upstream, và lập trình các route multicast trong kernel theo đó.
Topology mạng trong thực tế
Mạng ISP (nguồn multicast)
│
eth0 ← upstream (WAN) — nhận multicast từ ISP
[Linux Router đang chạy igmpproxy]
eth1 ← downstream (LAN) — phân phối multicast đến bộ giải mã IPTV
│
Mạng LAN gia đình (IPTV STB, smart TV)
igmpproxy duy trì một bảng chuyển tiếp trong socket định tuyến multicast của kernel (MRT_ADD_MFC). Khi một client trên eth1 gửi IGMP Membership Report, igmpproxy nhận nó, gửi IGMP Join upstream trên eth0, sau đó lập trình kernel để chuyển tiếp các gói multicast khớp từ eth0 đến eth1.
Chỉ thị altnet — tại sao nó quan trọng
Chỉ thị altnet dưới interface upstream cho igmpproxy biết những địa chỉ nguồn nào được chấp nhận multicast từ đó. Nhiều ISP gửi luồng IPTV từ dải địa chỉ private — 10.x.x.x hoặc 172.x.x.x là phổ biến. Dùng 0.0.0.0/0 chấp nhận tất cả, phù hợp trong giai đoạn kiểm tra ban đầu. Với môi trường production, thu hẹp lại sẽ ngăn igmpproxy chuyển tiếp multicast bất ngờ đến từ phía ISP cho các lưu lượng không liên quan:
phyint eth0 upstream ratelimit 0 threshold 1
altnet 10.0.0.0/8
altnet 172.16.0.0/12
Sử Dụng Nâng Cao
Quy tắc tường lửa cho multicast (iptables / nftables)
Tường lửa Linux chặn lưu lượng multicast theo mặc định. Các quy tắc tường lửa này bao phủ những khoảng hở phổ biến nhất:
iptables:
# Cho phép IGMP (giao thức 2) trên tất cả interface liên quan
sudo iptables -A INPUT -p igmp -j ACCEPT
sudo iptables -A OUTPUT -p igmp -j ACCEPT
sudo iptables -A FORWARD -p igmp -j ACCEPT
# Cho phép chuyển tiếp UDP multicast (224.0.0.0/4 bao phủ tất cả nhóm multicast)
sudo iptables -A FORWARD -d 224.0.0.0/4 -j ACCEPT
sudo iptables -A FORWARD -s 224.0.0.0/4 -j ACCEPT
nftables (hệ thống hiện đại):
sudo nft add rule inet filter forward ip daddr 224.0.0.0/4 accept
sudo nft add rule inet filter forward ip protocol igmp accept
Một điều khiến tôi khổ sở từ sớm: nf_conntrack không xử lý multicast tốt. Có quy tắc drop trạng thái INVALID trong chain FORWARD không? Các gói UDP multicast sẽ biến mất âm thầm — không lỗi, không log. Hoặc loại trừ multicast khỏi conntrack hoàn toàn, hoặc chèn ACCEPT tường minh trước khi kiểm tra trạng thái:
# Chèn vào vị trí 1 để chạy trước các quy tắc trạng thái conntrack
sudo iptables -I FORWARD 1 -d 224.0.0.0/4 -j ACCEPT
Nhiều interface downstream (VLAN)
Khi dùng VLAN — ví dụ eth1.10 cho VLAN media và eth1.20 cho các thiết bị thông thường — chỉ cần thêm mỗi cái như một mục downstream:
phyint eth0 upstream ratelimit 0 threshold 1
altnet 0.0.0.0/0
phyint eth1.10 downstream ratelimit 0 threshold 1
phyint eth1.20 downstream ratelimit 0 threshold 1
igmpproxy sao chép luồng đến bất kỳ interface downstream nào có thành viên IGMP đang hoạt động. Không cần cấu hình thêm — nó tự động hoạt động khi các interface VLAN tồn tại ở tầng kernel:
# Tạo các interface VLAN nếu chưa có
sudo ip link add link eth1 name eth1.10 type vlan id 10
sudo ip link add link eth1 name eth1.20 type vlan id 20
sudo ip link set eth1.10 up
sudo ip link set eth1.20 up
quickleave — giảm độ trễ chuyển kênh
Thêm quickleave vào đầu file /etc/igmpproxy.conf và igmpproxy sẽ dừng chuyển tiếp ngay khi nhận được IGMP Leave đầu tiên, thay vì chờ toàn bộ chu kỳ query/response:
quickleave
phyint eth0 upstream ratelimit 0 threshold 1
altnet 0.0.0.0/0
phyint eth1 downstream ratelimit 0 threshold 1
Với một client IPTV duy nhất, điều này giảm độ trễ chuyển kênh từ 3–5 giây xuống dưới 1 giây. Khi có nhiều client đang xem các kênh khác nhau cùng lúc, hãy bỏ qua tùy chọn này — một client rời nhóm sẽ tắt luồng cho tất cả người khác.
Mẹo Thực Tế từ 6 Tháng Sử Dụng Production
igmpproxy không khởi động được? Kiểm tra điều này trước
Lỗi âm thầm phổ biến nhất khi chạy lần đầu: module định tuyến multicast chưa được tải.
# Kiểm tra module đã được tải chưa
lsmod | grep mroute
# Nếu thiếu:
sudo modprobe ip_mr_route
# Xác nhận chuyển tiếp multicast đang hoạt động
cat /proc/sys/net/ipv4/conf/all/mc_forwarding
igmpproxy thoát ngay lập tức nếu socket định tuyến multicast không thể mở được, và systemctl status igmpproxy không phải lúc nào cũng hiển thị lỗi rõ ràng. Kiểm tra toàn bộ journal output:
journalctl -u igmpproxy -n 50
Giữ module tồn tại qua các lần khởi động lại:
echo "ip_mr_route" | sudo tee /etc/modules-load.d/igmpproxy.conf
Xác minh toàn bộ đường chuyển tiếp với tcpdump
Khi có gì đó không hoạt động, kiểm tra từng bước riêng lẻ:
# Bước 1: Multicast có đang đến interface upstream từ ISP không?
sudo tcpdump -i eth0 'udp and dst net 224.0.0.0/4' -n -c 20
# Bước 2: IGMP join có đang rời eth0 hướng về ISP không?
sudo tcpdump -i eth0 igmp -n
# Bước 3: Luồng có đang đến được mạng LAN không?
sudo tcpdump -i eth1 'udp and dst net 224.0.0.0/4' -n -c 20
Ba bước, ba điểm hỏng có thể: phân phối upstream, báo hiệu IGMP, hoặc chuyển tiếp downstream. Chỗ nào trong chuỗi bị đứt sẽ cho bạn biết chính xác cần sửa gì.
Kiểm tra bảng định tuyến multicast của kernel trực tiếp
# Các route multicast đang hoạt động
cat /proc/net/ip_mr_cache
# Các interface ảo đã đăng ký với kernel
cat /proc/net/ip_mr_vif
Các mục hoạt động trong ip_mr_cache xác nhận kernel đang chuyển tiếp lưu lượng. Bảng trống có nghĩa là igmpproxy không nhận được IGMP join từ các client downstream — rất có thể do tường lửa chặn IGMP, hoặc client không gửi join.
igmpproxy vs smcroute
smcroute theo cách tiếp cận khác: route multicast tĩnh thay vì proxy IGMP động. Điều đó đơn giản hơn khi bạn có một danh sách cố định, đã biết các nhóm multicast — nhưng có nghĩa là phải nhập route thủ công cho mỗi kênh. igmpproxy xử lý toàn bộ việc đàm phán IGMP tự động. Thêm thiết bị IPTV mới hoặc gói kênh mới và không cần thay đổi gì trong cấu hình.
Chạy Linux router đủ lâu nghĩa là sớm muộn gì cũng phải đối mặt với multicast. IPTV thường là thứ buộc bạn phải giải quyết vấn đề này. Làm đúng ngay từ lần đầu thực sự khó — nhưng một khi igmpproxy đã được cấu hình và các quy tắc tường lửa đã ổn định, nó sẽ không làm phiền bạn nữa. Cùng một file cấu hình trong sáu tháng. Thay đổi duy nhất tôi thực hiện là thêm interface VLAN thứ hai cho một media player mới trong phòng ngủ.

