From bfb20063164f862117763ba932959ef0abaae9ea Mon Sep 17 00:00:00 2001 From: sgf Date: Tue, 27 Sep 2022 00:00:20 +0300 Subject: [PATCH 1/1] Initial commit. Make external client IP visible to a backend server behind wireguard. --- direct_routing/back-rules.v4 | 38 ++++++++++++++++++++ direct_routing/back-wg0.conf | 53 ++++++++++++++++++++++++++++ direct_routing/front-rules.v4 | 13 +++++++ direct_routing/front-wg0.conf | 9 +++++ direct_routing/iptables-log-rules.v4 | 47 ++++++++++++++++++++++++ 5 files changed, 160 insertions(+) create mode 100644 direct_routing/back-rules.v4 create mode 100644 direct_routing/back-wg0.conf create mode 100644 direct_routing/front-rules.v4 create mode 100644 direct_routing/front-wg0.conf create mode 100644 direct_routing/iptables-log-rules.v4 diff --git a/direct_routing/back-rules.v4 b/direct_routing/back-rules.v4 new file mode 100644 index 0000000..fa44c37 --- /dev/null +++ b/direct_routing/back-rules.v4 @@ -0,0 +1,38 @@ +*mangle +:PREROUTING ACCEPT [4435:301540] +:INPUT ACCEPT [4435:301540] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [2902:569216] +:POSTROUTING ACCEPT [2902:569216] + +# Restore packet mark from connection mark on transit packets. This rule is +# needed, if proxied server is running _behind NAT_ on backend server (e.g. in +# docker or regular NAT, where backend server is default gateway). Therefore +# it's in PREROUTING chain. +-A PREROUTING -m connmark --mark 0x3 -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff + +# Two rules for marking connection. +# First, is to mark _packets_ going out from wg0 interface. This rule can only +# be in PREROUTING chain, because i match on input interface ('-i') here. +-A PREROUTING -i wg0 -m state --state NEW -j MARK --set-xmark 0x3/0xffffffff +# Second, is to copy packet mark to connection mark. +-A PREROUTING -m mark --mark 0x3 -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff + +# Restore packet mark from connection mark on replies from _this_ host. This +# rule is needed, if proxied server is running _on backend server_. Therefore, +# it's in OUTPUT chain. +-A OUTPUT -m connmark --mark 0x3 -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff + +COMMIT + +*nat +:PREROUTING ACCEPT [26:2416] +:INPUT ACCEPT [26:2416] +:OUTPUT ACCEPT [4:572] +:POSTROUTING ACCEPT [4:572] + +# DNAT to some host in NAT-ed network behind backend server. Essentially, +# docker adds the same rules for exposed ports of its containers. +-A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.10.11.1:80 + +COMMIT diff --git a/direct_routing/back-wg0.conf b/direct_routing/back-wg0.conf new file mode 100644 index 0000000..01ec5ca --- /dev/null +++ b/direct_routing/back-wg0.conf @@ -0,0 +1,53 @@ +[Interface] +PrivateKey = BACK_PRIVKEY +ListenPort = 51820 +Address = 10.30.1.1/32 + +# Disable automatic routing configuration. +Table = off + +# Add rule and corresponding routing table for marked packets (i.e. packets +# originated from behind of wireguard interface). Default gateway for this +# packets is wireguard interface. +PostUp = ip rule add pref 333 fwmark 3 table 333 +PostUp = ip ro add default via 10.30.1.1 dev %i table 333 + +# But because packet marks are set up _before_ routing in PREROUTING chain, +# packets destined (DNAT-ed) to docker or NAT-ed network behind backend +# server, will _also_ have mark 3 and, thus, will be routed using table 333. +# And, thus, will go back to default route and never reach its destination. + +# So, to fix this i may add route to NAT-ed network .. +PostUp = ip ro add 10.10.11.0/24 dev ens5 table 333 +# .. or route to docker network. +#PostUp = ip ro add 172.17.0.0/16 dev docker0 table 333 + +# Though, in case of docker above route won't work, because docker starts +# after wireguard during boot and 'docker0' interface don't exist yet, when +# wireguard will try to add this route. Thus, i need a rule to use 'main' +# table instead for docker network with lower priority 200. +PostUp = ip rule add pref 200 to 172.17.0.0/16 table main + +# Note, also that above rule is not needed, when service is running on backend +# server itself, because routing to local IPs is done by 'local' routing table +# with priority 0 (i.e. it matches before rule for table 333). + +# I may also add route for pinging frontend peer. But it's not necessary at +# all. +#PostUp = ip ro add 10.30.1.2/32 dev %i + +PreDown = ip rule del pref 333 fwmark 3 table 333 +PreDown = ip ro del default via 10.30.1.1 dev %i table 333 + +PreDown = ip ro del 10.10.11.0/24 dev ens5 table 333 +#PreDown = ip ro del 172.17.0.0/16 dev docker0 table 333 +PreDown = ip rule del pref 200 to 172.17.0.0/16 table main +#PreDown = ip ro del 10.30.1.2/32 dev %i + +[Peer] +PublicKey = FRONT_PUBKEY +Endpoint = 10.10.2.1:51820 + +# Since there is no SNAT on fronted, source IP of packets from wg interface +# may be any. +AllowedIPs = 0.0.0.0/0 diff --git a/direct_routing/front-rules.v4 b/direct_routing/front-rules.v4 new file mode 100644 index 0000000..829b34c --- /dev/null +++ b/direct_routing/front-rules.v4 @@ -0,0 +1,13 @@ +*nat +:PREROUTING ACCEPT [0:0] +:INPUT ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] + +# DNAT rules for different exposed ports of backend server. Some of these +# ports may be DNAT-ed further on backned server to docker containers or hosts +# in NAT-ed network behind backend server. +-A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.30.1.1 +-A PREROUTING -p tcp -m tcp --dport 8080 -j DNAT --to-destination 10.30.1.1 +-A PREROUTING -p tcp -m tcp --dport 8081 -j DNAT --to-destination 10.30.1.1 +COMMIT diff --git a/direct_routing/front-wg0.conf b/direct_routing/front-wg0.conf new file mode 100644 index 0000000..6be4ec3 --- /dev/null +++ b/direct_routing/front-wg0.conf @@ -0,0 +1,9 @@ +[Interface] +PrivateKey = FRONT_PRIVKEY +ListenPort = 51820 +Address = 10.30.1.2/32 + +[Peer] +PublicKey = BACK_PUBKEY +Endpoint = 10.10.1.1:51820 +AllowedIPs = 10.30.1.1/32 diff --git a/direct_routing/iptables-log-rules.v4 b/direct_routing/iptables-log-rules.v4 new file mode 100644 index 0000000..5c42b5e --- /dev/null +++ b/direct_routing/iptables-log-rules.v4 @@ -0,0 +1,47 @@ +*mangle +:PREROUTING ACCEPT [4435:301540] +:INPUT ACCEPT [4435:301540] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [2902:569216] +:POSTROUTING ACCEPT [2902:569216] +-A PREROUTING -p tcp -m multiport ! --ports 22 -j LOG --log-prefix "mangle PRE: " +-A PREROUTING -p udp -m multiport ! --ports 22 -j LOG --log-prefix "mangle PRE: " +-A PREROUTING -p icmp -j LOG --log-prefix "mangle PRE: " +-A OUTPUT -p udp -m multiport ! --ports 22 -j LOG --log-prefix "mangle OUT: " +-A OUTPUT -p tcp -m multiport ! --ports 22 -j LOG --log-prefix "mangle OUT: " +-A OUTPUT -p icmp -j LOG --log-prefix "mangle OUT: " +-A POSTROUTING -p udp -m multiport ! --ports 22 -j LOG --log-prefix "mangle POST: " +-A POSTROUTING -p tcp -m multiport ! --ports 22 -j LOG --log-prefix "mangle POST: " +-A POSTROUTING -p icmp -j LOG --log-prefix "mangle POST: " +COMMIT +# Completed on Tue Sep 13 17:38:12 2022 +# Generated by iptables-save v1.8.7 on Tue Sep 13 17:38:12 2022 +*filter +:INPUT ACCEPT [4435:301540] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [2902:569216] +-A INPUT -p tcp -m multiport ! --ports 22 -j LOG --log-prefix "filter IN: " +-A INPUT -p udp -m multiport ! --ports 22 -j LOG --log-prefix "filter IN: " +-A INPUT -p icmp -j LOG --log-prefix "filter IN: " +-A OUTPUT -p tcp -m multiport ! --ports 22 -j LOG --log-prefix "filter OUT: " +-A OUTPUT -p udp -m multiport ! --ports 22 -j LOG --log-prefix "filter OUT: " +-A OUTPUT -p icmp -j LOG --log-prefix "filter OUT: " +COMMIT +# Completed on Tue Sep 13 17:38:12 2022 +# Generated by iptables-save v1.8.7 on Tue Sep 13 17:38:12 2022 +*nat +:PREROUTING ACCEPT [26:2416] +:INPUT ACCEPT [26:2416] +:OUTPUT ACCEPT [4:572] +:POSTROUTING ACCEPT [4:572] +-A PREROUTING -p tcp -m multiport ! --ports 22 -j LOG --log-prefix "nat PRE: " +-A PREROUTING -p udp -m multiport ! --ports 22 -j LOG --log-prefix "nat PRE: " +-A PREROUTING -p icmp -j LOG --log-prefix "nat PRE: " +-A OUTPUT -p tcp -m multiport ! --ports 22 -j LOG --log-prefix "nat OUT: " +-A OUTPUT -p udp -m multiport ! --ports 22 -j LOG --log-prefix "nat OUT: " +-A OUTPUT -p icmp -j LOG --log-prefix "nat OUT: " +-A POSTROUTING -p tcp -m multiport ! --ports 22 -j LOG --log-prefix "nat POST: " +-A POSTROUTING -p udp -m multiport ! --ports 22 -j LOG --log-prefix "nat POST: " +-A POSTROUTING -p icmp -j LOG --log-prefix "nat POST: " +COMMIT +# Completed on Tue Sep 13 17:38:12 2022 -- 2.20.1