Quick start (Lên lab trong 5 phút)
Cần một con PPPoE Server gọn nhẹ trên Ubuntu hoặc Debian để test vội router MikroTik, Cisco hay OpenWrt? Dưới đây là các bước gõ lệnh ăn ngay.
Cài đặt các package cần thiết gồm pppoe (chứa bộ công cụ rp-pppoe), ppp daemon và iptables:
sudo apt update
sudo apt install -y ppp pppoe iptables
Tạo file cấu hình session mẫu tại /etc/ppp/pppoe-server-options:
sudo bash -c 'cat <<EOF > /etc/ppp/pppoe-server-options
require-chap
login
lcp-echo-interval 10
lcp-echo-failure 2
ms-dns 8.8.8.8
ms-dns 1.1.1.1
netmask 255.255.255.255
default-mru 1492
default-asyncmap
EOF'
Khai báo tài khoản quay số trong /etc/ppp/chap-secrets. Bạn có thể gán IP tĩnh hoặc để server tự cấp:
# client server secret IP addresses
"khachhang01" * "MatKhau@123" 10.0.0.50
"khachhang02" * "MatKhau@456" *
Bật IP Forwarding và cấu hình NAT. Giả sử eth0 cắm ra Internet, còn eth1 nối vào switch lab:
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Khởi chạy PPPoE Server daemon trên card eth1:
sudo pppoe-server -I eth1 -L 10.0.0.1 -R 10.0.0.10 -N 20
Xong. Cắm dây từ router client vào cổng eth1, quay số với user khachhang01, bạn sẽ thấy client nhận đúng IP 10.0.0.50 và ra mạng bình thường.
Bản chất kỹ thuật
Vì sao DHCP không thay thế được PPPoE trong lab ISP?
Mạng gia đình hay văn phòng chỉ cần DHCP là đủ. Mọi chuyện thay đổi khi dựng lab mô phỏng ISP (BNG/BRAS). Lúc này DHCP lộ rõ điểm yếu.
DHCP không yêu cầu xác thực user. Nó khó cô lập session theo từng hợp đồng thuê bao và gần như không thể áp QoS động theo phiên đăng nhập. Do đó, các nhà mạng viễn thông như VNPT, Viettel hay FPT vẫn bám trụ với PPPoE trên hạ tầng FTTH dân dụng.
PPPoE bắt tay như thế nào?
PPPoE đóng gói (encapsulate) khung PPP truyền thống vào thẳng Ethernet frame. Quá trình bắt tay chia làm 2 giai đoạn rõ rệt:
- Giai đoạn Discovery (Layer 2): Client và Server tìm nhau bằng 4 bản tin tuần tự:
PADI(Client phát sóng broadcast tìm server) →PADO(Server unicast chào gói dịch vụ) →PADR(Client gửi yêu cầu kết nối) →PADS(Server xác nhận và cấp kèm Session ID). - Giai đoạn PPP Session: Có Session ID rồi, hai bên bắt đầu đàm phán LCP (Link Control Protocol). Tiếp theo là bước xác thực mật khẩu qua CHAP. Cuối cùng, giao thức IPCP trao đổi để thống nhất IP, gateway và DNS.
Bóc tách các cờ lệnh pppoe-server
Một dòng lệnh ngắn gọn nhưng gom đủ tham số vận hành cốt lõi:
-I eth1: Interface lắng nghe gói tin Discovery (PADI). Cổng mạng này không cần gán IP trước. Gói PPPoE Discovery chạy thẳng ở tầng 2 với EtherType0x8863.-L 10.0.0.1: IP đầu tunnel phía server. Client sẽ nhận địa chỉ này làm Default Gateway.-R 10.0.0.10: IP khởi đầu cho dải cấp phát tự động (IP Pool). Nếu bạn đặt dấu*trongchap-secrets, server sẽ cấp tăng dần từ IP này.-N 20: Giới hạn tối đa 20 session chạy cùng lúc. Cờ này giúp máy ảo không bị tràn RAM khi client gửi broadcast request liên tục.
Tối ưu & Vận hành
1. Xử lý triệt để bẫy MTU và TCP MSS Clamping
Ethernet frame chuẩn có MTU là 1500 bytes. Header của PPPoE nuốt mất 6 bytes, thêm 2 bytes Protocol ID của PPP. Tổng cộng mất 8 bytes overhead. Vì vậy, MTU tối đa trên interface ảo pppX bị kéo tụt xuống đúng 1492 bytes.
Vấn đề phát sinh từ đây.
Client thường giữ thói quen gửi gói TCP với MSS mặc định 1460 bytes. Gói tin đi kèm IP header 20 bytes và TCP header 20 bytes sẽ phình lên 1500 bytes. Chui vào tunnel PPPoE, tổng kích thước thành 1508 bytes và lập tức bị phân mảnh.
Tệ nhất là khi gói tin bật cờ DF (Don’t Fragment). Router trung gian drop gói nhưng vô tình chặn luôn bản tin báo lỗi ICMP Type 3 Code 4. Hậu quả là lỗi “black hole”: ping IP vẫn thông 1ms, nhưng mở web HTTPS hay tải file thì đứng kim.
Phương án chuẩn nhất là ép MSS trên bảng mangle của iptables:
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Lệnh này tự động soi MTU của interface rồi nén MSS gói SYN xuống mức an toàn (thường là 1452 bytes). Lưu lượng web sẽ trơn tru trở lại.
2. Gom vào Systemd Service
Muốn server tự bật sau mỗi lần reboot máy ảo lab, hãy tạo service tại /etc/systemd/system/pppoe-server.service:
[Unit]
Description=RP-PPPoE Server Service
After=network.target
[Service]
Type=forking
ExecStartPre=/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
ExecStartPre=/sbin/iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
ExecStart=/usr/sbin/pppoe-server -I eth1 -L 10.0.0.1 -R 10.0.0.10 -N 50
ExecStop=/usr/bin/killall pppoe-server
Restart=on-failure
[Install]
WantedBy=multi-user.target
Nạp lại daemon và khởi động service:
sudo systemctl daemon-reload
sudo systemctl enable --now pppoe-server
Kinh nghiệm thực chiến
Trong một lần test router lab cho văn phòng 60 nhân sự, mình từng dính ca rớt gói rất kỳ quặc. Buổi sáng lướt web, họp Google Meet hoàn toàn bình thường. Đến chiều, người dùng bắt đầu kêu ca vì không thể upload tài liệu PDF 15MB hay tải ảnh từ Nextcloud.
Bật tcpdump trên cổng ppp0 bắt gói tin, nguyên nhân mới lộ diện: switch core ở giữa đã vô tình drop toàn bộ ICMP Type 3 Code 4. Các file ảnh lớn đều đẩy kích thước gói kịch trần 1500 bytes với cờ DF=1. Gói tin bị drop trong im lặng mà client không nhận được tín hiệu hạ MTU.
Từ sau ca đó, mỗi khi setup lab PPPoE hay GRE tunnel, dòng lệnh TCPMSS --clamp-mss-to-pmtu luôn là thứ đầu tiên mình thêm vào bảng mangle trước khi test bất cứ dịch vụ nào khác.
Debug và theo dõi session thời gian thực
Mỗi khi client quay số thành công, Linux kernel sẽ tạo ra một interface ảo dạng ppp0, ppp1. Bạn kiểm tra nhanh danh sách kết nối bằng lệnh:
ip link show | grep ppp
Để bắt lỗi sai mật khẩu hoặc fail pha LCP negotiation, mở terminal và bám sát log thời gian thực bằng journalctl:
sudo journalctl -t pppd -f
Nếu vẫn chưa rõ nguyên nhân, hãy thêm dòng debug vào file /etc/ppp/pppoe-server-options. Toàn bộ frame LCP ConfReq, ConfAck và bản tin CHAP Challenge sẽ hiển thị chi tiết, giúp bạn định vị lỗi chỉ trong vài phút.

