Cấu hình DHCP Relay (dhcrelay) trên Linux: Chuyển tiếp DHCP qua nhiều VLAN

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

Bắt đầu nhanh (5 phút): Chạy dhcrelay trên Ubuntu/Debian

Trong các môi trường đa VLAN, các gói tin broadcast DHCP discovery sẽ dừng lại hoàn toàn tại ranh giới Layer 3. Các router được thiết kế mặc định để loại bỏ chúng. Việc chạy các DHCP daemon độc lập trên 20 VLAN khác nhau là một cơn ác mộng về quản trị. Mua switch Layer 3 có tính năng IP helper address ở khắp mọi nơi cũng nhanh chóng làm tăng chi phí. Một Linux router có thể giải quyết bài toán này dễ dàng: nó sẽ chặn các gói broadcast từ client và chuyển tiếp dưới dạng unicast trực tiếp tới DHCP server tập trung.

Chúng ta sẽ cấu hình một relay cơ bản chuyển tiếp yêu cầu từ hai sub-interface VLAN (eth1.10 và eth1.20) đến một Kea hoặc ISC server tập trung tại 192.168.10.50.

# 1. Cài đặt ISC DHCP relay
sudo apt update && sudo apt install -y isc-dhcp-relay

# 2. Bật tính năng chuyển tiếp gói tin IPv4 trong kernel
sudo sysctl -w net.ipv4.ip_forward=1

# 3. Khởi chạy dhcrelay thủ công để kiểm tra kết nối
sudo dhcrelay -d -4 -i eth1.10 -i eth1.20 192.168.10.50

Giữ lệnh này tiếp tục chạy trong terminal. Bất kỳ máy trạm nào phát broadcast trên VLAN 10 hoặc 20 giờ đây sẽ được chuyển tiếp dưới dạng gói tin unicast UDP tới 192.168.10.50:67. Hãy kiểm tra việc cấp phát IP trên một máy client. Khi đã hoạt động tốt, nhấn Ctrl+C và chuyển sang cấu hình systemd để service tự khởi động cùng hệ thống.

Tìm hiểu sâu: Cơ chế hoạt động của dhcrelay qua các VLAN Interface

Để khắc phục sự cố relay, bạn cần theo dõi gói tin ở cấp độ byte. Ban đầu, client chưa có cấu hình mạng hoàn chỉnh. Chúng sẽ broadcast một gói tin DHCPDISCOVER từ IP nguồn 0.0.0.0:68 tới đích 255.255.255.255:67. Ở điều kiện bình thường, Linux sẽ hủy gói broadcast này ngay tại ranh giới interface để tránh bão broadcast (broadcast storm).

Cơ chế Relay và trường GIADDR

Khi dhcrelay lắng nghe trên các sub-interface, nó sẽ bắt các frame UDP port 67 gửi đến trước khi kernel loại bỏ chúng. Nó không chỉ đơn thuần sao chép gói tin mà sẽ ghi lại payload với hai thay đổi quan trọng:

  • Nó điền vào trường giaddr (Gateway IP Address) trong DHCP payload bằng IP gán cho chính VLAN interface đó (ví dụ: 10.0.10.1 trên eth1.10).
  • Nó đóng gói yêu cầu thành một gói tin unicast UDP chuẩn. IP nguồn trở thành IP interface cục bộ của relay, và IP đích là DHCP server tập trung của bạn (192.168.10.50).

Server phía trên phụ thuộc hoàn toàn vào trường giaddr. Nếu không có nó, server không thể biết client thuộc subnet nào. Khi đọc được 10.0.10.1, server sẽ lấy một lease khả dụng từ dải mạng tương ứng 10.0.10.0/24. Sau đó, nó gửi unicast một gói DHCPOFFER ngược lại 10.0.10.1:67. Cuối cùng, dhcrelay mở gói offer và chuyển tiếp đến địa chỉ MAC phần cứng của client trên VLAN 10.

Cấu hình bền vững qua Systemd

Debian và Ubuntu quản lý các tham số relay cố định thông qua file /etc/default/isc-dhcp-relay. Lưu ý rằng bạn phải chỉ định cả các VLAN hướng về phía client lẫn interface hướng ra DHCP server upstream:

# /etc/default/isc-dhcp-relay

# Các DHCP server upstream
SERVERS="192.168.10.50"

# Các interface lắng nghe (sub-interface client + egress interface hướng lên upstream)
INTERFACES="eth1.10 eth1.20 eth0"

# Các cờ khởi động cho daemon
OPTIONS=""

Lưu file lại, sau đó restart và kiểm tra trạng thái systemd unit:

sudo systemctl restart isc-dhcp-relay
sudo systemctl status isc-dhcp-relay

Sử dụng nâng cao: Option 82 và cụm DHCP dự phòng (Redundant Clusters)

Định tuyến dựa trên giaddr cơ bản chỉ cho server biết cần dùng subnet nào. Tuy nhiên, nó không thể xác định chính xác port switch, tủ rack hay interface của tenant nào đằng sau yêu cầu đó. Các hệ thống quy mô lớn giải quyết vấn đề này bằng DHCP Option 82 và các cụm server dự phòng.

Bật Option 82 (Circuit ID & Remote ID)

Option 82 đính kèm thêm dữ liệu theo dõi đặc thù của thiết bị vào gói DHCP trước khi định tuyến lên upstream. Dữ liệu này bao gồm tên interface vật lý hoặc định danh mạch kết nối tùy chỉnh (circuit identifier). Bạn có thể bật tính năng này bằng cờ -a:

# Trong /etc/default/isc-dhcp-relay
OPTIONS="-a -m replace"

Tham số -m replace là một cơ chế bảo vệ quan trọng. Nếu một máy tính bị xâm nhập cố tình chèn các tag Option 82 giả mạo, relay sẽ loại bỏ chúng và ghi đè bằng metadata đã được xác thực từ interface cục bộ. Với ISC Kea hoặc FreeRADIUS, bạn có thể dựa vào Circuit ID này để áp dụng chính sách cấp IP tĩnh nghiêm ngặt hoặc dynamic firewall access list.

Chuyển tiếp tới nhiều DHCP Server

Hệ thống production không bao giờ nên phụ thuộc vào một DHCP daemon duy nhất. Sự cố sập dịch vụ vào khung giờ cao điểm cấp phát buổi sáng sẽ ảnh hưởng đến hàng trăm thiết bị. dhcrelay hỗ trợ failover bằng cách nhân bản các gói discovery gửi tới nhiều mục tiêu upstream:

SERVERS="192.168.10.50 192.168.20.50"

Relay sẽ gửi các gói tin unicast giống hệt nhau tới cả hai server cùng một thời điểm. Server nào phản hồi trước sẽ được ưu tiên. Client chấp nhận DHCPOFFER đầu tiên nhận được, xác nhận lại qua DHCPREQUEST và bỏ qua các phản hồi chậm hơn. Quá trình cấp phát IP của bạn vẫn hoạt động bình thường ngay cả khi một server phải khởi động lại để vá lỗi kernel.

Tối ưu hóa và Khắc phục sự cố trong môi trường Production

Những kinh nghiệm thực tế sau giúp duy trì các router Linux cốt lõi của chúng tôi hoạt động ổn định khi xử lý hơn 40 VLAN cùng hàng nghìn lease DHCP đồng thời.

1. Theo dõi đường đi gói tin với tcpdump

Khi client không nhận được IP, đừng thay đổi file cấu hình một cách mù quáng. Hãy chạy tcpdump trên máy relay để kiểm tra từng giai đoạn bắt tay:

# Giám sát các trao đổi DHCP trên tất cả interface với thông tin chi tiết
sudo tcpdump -env -n -i any port 67 or port 68

Một chu trình bắt tay hoàn chỉnh sẽ hiển thị tuần tự rõ ràng: gói broadcast DHCPDISCOVER gửi đến trên eth1.10, ngay lập tức có gói unicast gửi đi tới 192.168.10.50, tiếp theo là gói DHCPOFFER trả về trên eth0.

2. Lưu ý về Firewall (iptables & nftables)

Nguyên nhân phổ biến nhất khiến triển khai thất bại là firewall máy chủ âm thầm chặn các UDP broadcast frame. Chuỗi INPUT của bạn phải cho phép DHCP trước khi xét đến các quy tắc chặn chung:

# Cho phép lưu lượng DHCP trên các socket relay cục bộ
sudo iptables -A INPUT -p udp -m multiport --dports 67,68 -j ACCEPT

# Duy trì định tuyến kernel cho các kết nối đang hoạt động
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

3. Ngăn ngừa tràn bộ nhớ đệm ARP (ARP Cache Exhaustion)

Tần suất thiết bị kết nối và ngắt kết nối liên tục sẽ làm xoay vòng bảng ARP cache rất nhanh. Nếu kernel xóa một bản ghi MAC đã hết hạn trước khi chu trình phản hồi DHCP hoàn tất, relay sẽ không thể phân phát gói offer tới đích. Hãy kiểm tra bảng neighbor khi việc cấp phát IP bị nghẽn:

ip neighbor show dev eth1.10

Đối với mạng có hàng trăm thiết bị kết nối tạm thời (như Wi-Fi công cộng hoặc lab test động), hãy nâng ngưỡng neighbor của kernel trong /etc/sysctl.d/99-arp.conf bằng cách thiết lập net.ipv4.neigh.default.gc_thresh1 = 1024 và gc_thresh2 = 2048. Cấu hình này giúp ngăn chặn tình trạng rớt gói tin âm thầm trong giờ cao điểm.

Share: