Giới thiệu
Trong thời gian vừa qua, mình có thử config cho homelab chạy Dualstack IP, vừa v4 vừa v6 song song.
Khi tìm hiểu về IPv6, mình thấy ấn tượng với 1 điểm mạnh của nó, đó là End-to-end connectivity, hay tức là mình sẽ không còn cần tới NAT nữa. Chắc chắn ai tìm hiểu chủ đề Network cũng đã đều quá quen với NAT rồi. Theo quan điểm cá nhân của mình thì sử dụng NAT giống như một cách làm workaround/hacking để xử lý vấn đề cạn kiệt tài nguyên IPv4.
Vậy hãy xem với IPv6 thì liệu việc config mạng có đơn giản đi hay sẽ mở ra những phức tạp ra sao.
Nhận IPv6 từ nhà mạng
Trước tiên, mình phải yêu cầu nhà mạng cấp IPv6. Mình dùng mạng FPT và sau 1 cú điện thoại thì nhà mạng vui vẻ enable IPv6 cho mình, rất là nhanh luôn. Với IPv6 thì thay vì cấp 1 public IP duy nhất như v4, nhà mạng sẽ cấp 1 dải prefix, thường sẽ là /56 nhưng với trường hợp của mình là dải /60. Vẫn chấp nhận được vì số lượng LAN interface của mình cũng không nhiều.
IPv6 có độ dài 128 bit. Vậy tức là với dải prefix /60, mình có thể tạo được 2^68 địa chỉ IP tất cả. Hãy nhớ rằng IPv4 chỉ có 2^32 địa chỉ tất cả thôi. 2^68 cho một hộ gia đình thôi là quá trời nhiều luôn đó!
Và vậy là cục router nhà mình đã được cấp IPv6. Lưu ý dải IPv6 này là dynamic, tức là lâu lâu có thể bị đổi, cũng tương tự như cái public IPv4 mà nhà mạng cấp cho mình vậy. Mặc dù không phải khách hàng doanh nghiệp nhưng mình nghĩ với số lượng vượt trội của IPv6, chưa rõ tại sao nhà mạng lại không mặc định cấp dải prefix IPv6 tĩnh cho người dùng.
Config IPv6 cho LAN Interface
Tiếp theo, mình cần đưa IPv6 tới từng LAN interface.
1 cái IPv6 sẽ có cấu thành như sau:
- 64 bit đầu tiên là network prefix, chỉ ra network mà 1 IPv6 thuộc về
- 64 bit sau đó là interface id, chỉ ra device cụ thể trên network đó
Gần giống với network/host address của IPv4 đúng không nào. Nhưng với IPv4 thì mình thích chia phần network và host sao tùy ý (/16, /24, …) thì với IPv6, phần prefix và phần interface luôn được chia là /64.
Vậy khi FPT cấp cho mình 1 dải /60, tức là mình được phép thay đổi 4 bit tiếp theo để tạo thành 1 network prefix hoàn chỉnh. Nói cách khác, mình có thể tạo ra 16(2^4) subnet khác nhau và cấp chúng cho các LAN Interface.
Để mình dùng bảng này minh họa cho các bạn: 60 bit đầu tiên giữ nguyên, chỉ có 4 bit tiếp theo thay đổi để tạo thành các Prefix 64 bit.
Cấp IPv6 tới từng device
Với IPv4, để cấp phát IP tới từng device thì mình cần dùng DHCP. Còn với IPv6, mình có 2 sự lựa chọn:
- SLAAC - Stateless Address Auto-configuration: Nôm na là device tự chọn lấy 1 IPv6 cho chính mình. Yên tâm là giao thức này có built-in sẵn cách để chống trường hợp 2 device chọn trùng 1 IP rồi. Mạng nhà setup đơn giản mình nghĩ chỉ cần enable cái này là OK.
- DHCP: Tương tự với IPv4, DHCP server sẽ cấp IP cho device.
Sau khi thử cả 2, mình thấy có vài điểm sau cần chú ý:
- Các thiết bị Android không support DHCP đối với IPv6, chỉ support SLAAC thôi.
- Mặc dù có thể chạy cả 2 SLAAC và DHCP cùng lúc nhưng mình nghĩ không nên, vì mình thấy các thiết bị của mình, bất kể Linux hay Windows đều ưu tiên SLAAC. Khi vào DHCP server check sẽ không hề thấy có 1 lease nào cho tới khi mình tắt SLAAC đi. Nên chia thành nhiều VLAN rồi chỉ chạy SLAAC hoặc DHCP trên mỗi VLAN thôi.
- Mình không thích đặt IP tĩnh và cũng không thích phải nhớ rồi typing IP, dù là v4 hay v6, nên mình đã config để DNS server của mình có thể resolve hostname ra IP. Ví dụ mình có 1 con server có hostname là frigate, mình không cần nhớ IP của nó là gì, chỉ cần nhớ tên frigate là đủ rồi: Nhưng với IPv6 thì không thể config đuợc, tại vì DHCP server cho IPv6 mình dùng không nhận thông tin hostname từ các device. Mình sẽ tiếp tục tìm cách để khắc phục vấn đề này với IPv6, có thể chuyển sang dùng 1 DHCP server khác chẳng hạn.
End-to-end connectivity
Đây là phần mình thấy IPv6 vượt trội hơn hẳn so với IPv4.
Trước tiên hãy cùng xem các device trong mạng của mình sẽ kết nối ra public Internet như nào.
Đây là hình minh họa một device cần connect tới website google.com. Phần Source IP và Destination IP của các gói tin sẽ được giữ nguyên trước và sau khi đi qua Router, tức là NAT không hề xảy ra.
Mỗi device sẽ có địa chỉ GUA - Global Unicast Address IPv6 của riêng mình, tương đương với việc mỗi device có một Public IPv4 vậy. Các device có thể dùng địa chỉ GUA IPv6 này để kết nối tới nhau trong cùng mạng LAN và ngoài public Internet luôn.
Giờ hãy thử expose một service chạy bên trong mạng LAN ra ngoài Public Internet xem.
Hãy nhớ lại với IPv4, để public một service nào đó, mình sẽ cần setup Port Forwarding và đôi khi là HairPIN NAT hoặc Split-horizon DNS nữa. Chưa kể là nếu nhà bạn dính CGNAT thì không thể làm được luôn.
Vậy với IPv6 thì sao? Với việc mỗi device đã có địa chỉ GUA rồi, mình chỉ cần tạo một rule ở Firewall để chấp nhận kết nối từ bên ngoài Public Internet tới device đó là xong. Với Firewall OPNsense của mình sẽ có config như này:
Lưu ý: Prefix IPv6 mà nhà mạng cung cấp cho mình là dynamic, nên khi config các phần DHCP hay Firewall, mình sẽ chỉ điền thông tin Interface ID - 64 bit sau cùng của IPv6 mà thôi.
Sau đó mình thử chuyển điện thoại sang mạng 4G và kết nối tới service đang host ở nhà. Và kết quả là thành công.
Chỉ với 1 IP mà có thể dùng để kết nối trong mạng LAN hay ngoài Public Internet luôn. Thật là tiện lợi. Setup cũng đơn giản nữa.
Mình thấy có một số ý kiến cho rằng sử dụng IPv4 và NAT sẽ tăng cường bảo mật hơn, do có riêng phần mạng private, còn IPv6 thì quá dễ dàng để một service bị expose ra ngoài Public Internet. Cá nhân mình không đồng ý với quan điểm này, bởi NAT không thay thế được chức năng của Firewall. Nếu muốn bảo mật thì vẫn cứ phải config Firewall cẩn thận.
Multicast
Một điểm mạnh của IPv6 là không support ARP và Broadcast mà thay vào đó là sử dụng NDP và Multicast. Giải thích một cách ngắn gọn thì Multicast giúp đưa gói tin tới đúng device đích trong cùng mạng mà không cần sử dụng ARP và Broadcast để tìm MAC Address. Ví dụ về địa chỉ của 1 số các Multicast group hay gặp:
- FF01::1: Group dành cho tất cả các devices
- FF01::2: Group dành cho tất cả các router
Nhưng Multicast chỉ hoạt động đúng như lí thuyết khi bạn có 1 con Switch support IGMP Snooping (IPv4) và MLD Snooping ( IPv6) mà thôi. Trong trường hợp bạn không có hoặc không enable những feature này, Multicast sẽ hoạt động tương tự như Broadcast vậy.
Hên là mình có 1 con switch managed của TP-Link. Sau khi enable và config MLD Snooping lên (cũng hơi phiền vì document của TP-Link kém), mình thấy các device đã register được vào các group Multilcast: Mọi thứ có vẻ OK nhưng thật sự thì homelab của mình quá bé để có thể cảm nhận được ích lợi mà Multicast đem lại, và nếu là mạng gia đình setup đơn giản thì lại càng không.
Cấp IP tĩnh
Mình có nói là không thích đặt IP tĩnh và luôn tìm cách dùng domain name hoặc hostname. Thế nhưng vẫn có một số trường hợp mà bắt buộc device phải có IP tĩnh, ví dụ như DNS server chẳng hạn.
Khi dùng IPv4, mình có thể dễ dàng tạo địa chỉ private tĩnh (192.168.1.10, 172.17.10.1,…) cho từng device thông qua DHCP static mapping hoặc hardcode config trực tiếp trên device luôn. Vậy với IPv6, khi mà prefix nhà mạng cấp là dynamic thì các địa chỉ GUA được cấp cho các device trong mạng cũng sẽ dynamic theo.
Lúc này, mình có xem xét setup ULA - Unique Local Address, có thể nói nó tương đương với địa chỉ private bên IPv4.
Prefix của ULA là fc00::/8, tức là cứ thấy IP nào bắt đầu bằng fc hoặc fd thì nó chính là ULA đó.
Nhưng nảy sinh 1 vấn đề, router OPNsense của mình không cho phép config DHCP cho ULA. Đành quay trở lại sử dụng SLAAC để advertise ULA, và đây là kết quả: Trên các device đã có cả địa chỉ GUA và ULA. Mặc dù nhìn cái ULA này thì việc nhớ và typing cũng rất mệt :))
Tóm lại
IPv6 rất thú vị, giúp mình nhận ra việc không còn NAT sẽ khiến cho mọi thứ đơn giản đi, đạt được end-to-end connectivity. Nhưng bên cạnh đó, mình thấy các service mình xài có vẻ chưa support IPv6 được tốt nhất, điển hình như cái DHCP server không support hostname resolve khi dùng với IPv6, ULA thì chỉ dùng được với SLAAC. Có cơ hội mình sẽ thử setup IPv6 với Router và DHCP server khác.
Trong thời gian sắp tới, mình có ý định chuyển 1 LAN interface sang dùng IPv6-only xem thế nào. DNS64 và NAT64 sẽ là những thứ mình cần setup để phục vụ bài toán này.