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 tun0
giao 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ờ, tun0
gửi các gói hơn nữa. Địa chỉ nguồn là 10.0.0.1
và bạn muốn các gói đi qua một giao diện khác ( wlp2s0
trong 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 tcpdump
cho wlp2s0
bạn có thể nhận thấy các gói rời với địa chỉ nguồn 10.0.0.1
và 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 FORWARD
chuỗi của bạn có ACCEPT
chí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ừ tun0
giao diện sang wlp2s0
. netfilter nên thay đổi IP nguồn 10.0.0.1
thà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 wlp2s0
giao 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 OUTPUT
chuỗi và sau đó được định tuyến và đi đến PREROUTING
chuỗ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à TRACE
tí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 FORWARD
chuỗi (và nó không bị bắt bởi nat/POSTROUTING
chuỗ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.c
vớ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.c
khở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 - tun0
chỉ 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 SNAT
trước khi tun0
giao 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 tun0
thiết bị. tun0.c
mã 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/POSTROUTING
chuỗi trên wlp2s0
giao 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 SNAT
như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 tun0
vì 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