Vì vậy, trong cấu hình của bạn, tất cả các gói bạn cố gắng gửi đến mạng ban đầu có nguồn gốc từ 10.0.0.1(vì chúng đang đi qua tun0giao diện và địa chỉ cục bộ của nó là 10.0.0.1). Bạn chụp các gói, mọi thứ đều ổn cho đến nay.
Bây giờ, tun0gửi các gói hơn nữa. Địa chỉ nguồn là 10.0.0.1và bạn muốn các gói đi qua một giao diện khác ( wlp2s0trong trường hợp của bạn). Đó là định tuyến vì vậy hãy cho phép định tuyến trước:
sysctl -w net.ipv4.ip_forward=1
Sau đó, nếu bạn sẽ xem xét tcpdumpcho wlp2s0bạn có thể nhận thấy các gói rời với địa chỉ nguồn 10.0.0.1và không phải với địa chỉ nguồn của giao diện wlan (những gì bạn mong chờ tôi đoán). Vì vậy, chúng ta cần thay đổi địa chỉ nguồn và nó được gọi là NAT nguồn . Trong linux, thật dễ dàng với sự trợ giúp của netfilter / iptables :
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
Vui lòng kiểm tra xem FORWARDchuỗi của bạn có ACCEPTchính sách hay bạn sẽ cần cho phép chuyển tiếp với nội dung như:
iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
Mọi thứ sẽ hoạt động ngay bây giờ: kernel linux thực hiện định tuyến, đó là chuyển các gói từ tun0giao diện sang wlp2s0. netfilter nên thay đổi IP nguồn 10.0.0.1thành wlp2s0địa chỉ được gán giao diện của bạn cho các gói đầu ra. Nó ghi nhớ tất cả các kết nối và khi các gói trả lời quay trở lại (nếu chúng), nó sẽ thay đổi địa chỉ đích của wlp2s0giao diện được gán địa chỉ thành 10.0.0.1(tính năng "conntrack").
Vâng, nó nên nhưng nó không. Dường như, netfilter bị nhầm lẫn với cấu hình định tuyến phức tạp này và thực tế là cùng một gói đầu tiên đi qua OUTPUTchuỗi và sau đó được định tuyến và đi đến PREROUTINGchuỗi. Ít nhất là trên hộp Debian 8 nó không hoạt động.
Cách tốt nhất để khắc phục sự cố netfilter là TRACEtính năng:
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
Tôi chỉ kích hoạt theo dõi cho các gói ICMP, bạn có thể sử dụng bộ lọc khác để gỡ lỗi.
Nó sẽ hiển thị những bảng và chuỗi mà gói đi qua. Và tôi có thể thấy rằng gói không đi xa hơn FORWARDchuỗi (và nó không bị bắt bởi nat/POSTROUTINGchuỗi thực sự làm SNAT).
Dưới đây là một số cách tiếp cận để làm cho công việc này.
TIẾP CẬN # 1
Cách tốt nhất để không nhầm lẫn bộ lọc mạng là thay đổi địa chỉ IP nguồn của các gói trong tun0.cứng dụng. Đó cũng là cách tự nhiên nhất. Chúng ta cần thay đổi 10.0.0.1 thành 10.0.0.2 trên đường ra ngoài và 10.0.0.2 thành 10.0.0.1 trên đường trở về.
Tôi đã sửa đổi tun0.cvới mã thay đổi địa chỉ nguồn. Đây là tập tin mới và đây là patchfile cho bạn tun0.c. Các thay đổi đối với tiêu đề IP cũng liên quan đến sửa lỗi tổng kiểm tra , vì vậy tôi đã lấy một số mã từ dự án OpenVPN . Dưới đây là danh sách đầy đủ các lệnh tôi thực hiện sau khi khởi động lại và tun0_changeip.ckhởi chạy sạch :
ifconfig tun0 inet 10.0.0.1/30 up
sysctl -w net.ipv4.ip_forward=1
ip route add default dev tun0 table John
ip rule add from all lookup John
ip rule add from 10.0.0.2 lookup main priority 500
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
Xin lưu ý rằng bạn không cần tắt bộ lọc đường dẫn ngược trong trường hợp đó, vì mọi thứ đều hợp pháp - tun0chỉ nhận và gửi các gói thuộc mạng con của nó. Ngoài ra, bạn có thể thực hiện định tuyến dựa trên nguồn thay vì dựa trên giao diện.
TIẾP CẬN # 2
Có thể làm SNATtrước khi tun0giao diện tiếp cận gói . Nó không đúng lắm. Bạn chắc chắn sẽ cần phải tắt bộ lọc đường dẫn ngược trong trường hợp này:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Bây giờ, hãy làm SNAT: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT - to-source ip.address.of.your.wlan.interface
Ở đây chúng tôi thay đổi địa chỉ nguồn ngay trước khi các gói đến tun0thiết bị. tun0.cmã gửi lại các gói này "như hiện tại" (với địa chỉ nguồn đã thay đổi) và chúng được định tuyến thành công thông qua giao diện wlan. Nhưng bạn có thể có một IP động trên giao diện wlan và muốn sử dụng MASQUERADE(để không chỉ định rõ ràng địa chỉ giao diện). Đây là cách bạn có thể sử dụng MASQUERADE:
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
Vui lòng lưu ý 10.0.55.1địa chỉ IP "" - nó khác. Bạn có thể sử dụng bất kỳ IP nào ở đây, điều đó không thành vấn đề. Các gói đạt nat/POSTROUTINGchuỗi trên wlp2s0giao diện nếu chúng ta thay đổi IP nguồn trước đó. Và bây giờ nó không phụ thuộc vào IP tĩnh cho giao diện wlan.
TIẾP CẬN # 3
Bạn cũng có thể sử dụng fwmark. Bằng cách đó bạn không cần SNATnhưng bạn sẽ nắm bắt các gói tin chỉ ra:
Đầu tiên chúng ta cần phải vô hiệu hóa con đường ngược lọc cho tun0vì nó sẽ chuyển tiếp các gói tin thuộc mạng khác:
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Now let's alter the routing rules a bit:
# Delete old rules
ip rule del iif tun0 lookup main
ip rule del from all lookup John
# Packets will start going from wlan interface so they will have source address of it
iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
ip rule add fwmark 0x1 lookup John
Đó là một "hack" khác để định tuyến và bộ lọc mạng hoạt động trên hộp Debian 8 của tôi, nhưng tôi vẫn khuyên bạn nên thực hiện cách tiếp cận đầu tiên vì nó tự nhiên hơn và không sử dụng bất kỳ hack nào.
Bạn cũng có thể xem xét để xây dựng ứng dụng của mình như một proxy minh bạch . Tôi nghĩ rằng nó sẽ dễ dàng hơn nhiều thay vì phân tích các gói từ thiết bị tun.
-j SNAT, không phải-s SNAT