When I add a wireguard interface via wg-quick up wg0, wg-quick sets up the following nftable rules. What are these doing and why are they needed?
Here are some example rules for ipv4:
table ip wg-quick-wg0 {
chain preraw {
type filter hook prerouting priority raw; policy accept;
iifname != "wg0" ip daddr 10.4.125.231 fib saddr type != local drop
}
chain premangle {
type filter hook prerouting priority mangle; policy accept;
meta l4proto 17 meta mark set ct mark
}
chain postmangle {
type filter hook postrouting priority mangle; policy accept;
meta l4proto 17 meta mark 0x0000ca6c ct mark set meta mark
}
}
I am interested in these, because my virtual machine needs those to function properly, but my host does not need them to have a working wireguard interface. Sadly the script itself is not documented on why they are setup.
The wg-quick script sets up these rules only when you configure the AllowedIPs of a WireGuard peer to include /0 -- aka "all addresses" or the "default route" for an address family (0.0.0.0/0 for IPv4 and ::/0 for IPv6).
Using a tunnel like WireGuard for a default route requires some tricks to work correctly in most scenarios. The main trick wg-quick uses is to put the new default route into a custom routing table, while adding policy routing rules with a firewall mark to overide only the default route of the main table. This is the purpose for the route and policy rules you'll see wg-quick set up in this case:
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
The firewall rules listed in your question help with a few additional edge cases: The first rule prevents certain routing loops and other issues when packets are sent to the WireGuard interface's address outside of the tunnel; and the second and third rules fix up reverse-path lookups for packets received through the tunnel (allowing reverse-path filtering to work).
If you don't want wg-quick to do these things, you can set Table = off in the [Interface] section of your WireGuard configuration, and set up the appropriate routes yourself. For more details about these routing tricks, see the Routing All Your Traffic section of the routing guide on the WireGuard site, or the Understanding Modern Linux Routing article. See the Wg-quick Default Firewall Rules article for more details about these firewall rules specifically.
Related
What i am trying to achieve with iptables is setting a rule(s) that when a specific packet arrives from wan it gets redirected to a new address on wan.
Example:
Any UDP packet arriving on port 10000 gets redirected to 8.8.8.8:10000.
This can be more specific, like it originates from ip 1.1.1.1 or destination lan ip is 192.168.1.1 if there is a requirement for the rule to work.
Is this possible? Been trying a couple of rules in chain PREROUTING and using DNAT but i'm honestly in the dark here...
First: your question is more appropriate at Server Fault or Unix & Linux.
To answer your question: it isn't sufficient to only change the destination address because all returned datagrams would go directly from 8.8.8.8 to the original sender who could not relate them to the original datagrams.
So you would add DNAT rules in the PREROUTING chain and additional SNAT rules in the POSTROUTING chain so that the answers gets back to your machine and then can be sent back to the original sender with the appropriate addresses. You have to be very careful when designing these rules.
I understand that
a. one can maintain multiple routing tables in linux using "ip route ..... table "
b. forwarding decision for packets that ingress from outside network could be done using "ip rule add iif dev table "
However, if I want an user-app to talk to the outside world using specific routing table, I don't see an easy way out except to use "ip netns".
Is there a way to tell the system to use "lookup route" using specific routing table?
My understanding is "ip rules" apply only after a packet has been generated, but the user-apps consult the routing table even before the packet is generated so that ARP for the gateway can be sent.
This is a bit complicated matter. You should familiarize with SELinux labels and containers.
Docker documentation for RedHat states:
by default, docker creates a virtual ethernet card for each container. each container has its own routing tables and iptables. in addition to this, when you ask for specific ports to be forwarded, docker creates certain host iptables rules for you. the docker daemon itself does some of the proxying. the takeaway here is that if you map applications to containers, you provide flexibility to yourself by limiting network access on a per-application basis.
I have a question about security in iptables.
Is it safe to give ACCEPT policy to FORWARD chain? I mean, if packet gets there, it has come through PREROUTING table and in PREROUTING you only change destination ip of packet if you "like it".
all packets that get in FORWARD was matched against one of the rules in PREROUTING right?
If a packet does not match any rules in your PREROUTING chain, there is nothing to prevent it from hitting your FORWARD chain, unless you set the default PREROUTING policy to DROP.
Packets only go to the INPUT chain if their destination address is an address that belongs to a local interface on your host. Otherwise, they go to the FORWARD chain, and if they pass that chain AND the ip_forward sysctl is enabled, your system will forward them based on your routing table.
Your system may receive packets that are not destined for a local interface. This is how basic routing works: when your system wants to contact, say, Google's dns server at 8.8.8.8, packets are sent to your local default gateway, which receives and routes them even though the destination address is somewhere else entirely.
Your system may explicitly route traffic for physical networks to which it is attached or for containers or virtual machines hosted on the system. All of these involve your system accepting and forwarding packets that do not match a local interface.
I have a VPS on which eth0 is configured , i want to configure a interface eth0.1 but i want to know if i will configure this new interface the data flow will be divided between eth0 and eth0.1 ?
I want to use eth0 Ip address for all the data flow on server like custom written scripts and eth0.1 Ip address to access it from browser as i have web-server on it.
Linux, by default, will send all packets out the default interface for the subnet, which is most likely eth0.
iproute2 attempts to solve this problem by redirecting packets out on the same interface on which they have been received.
http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
So, to answer your question, most packets on your system will probably already go out eth0 (assuming it's the same subnet).
If you set up an alias interface, eth0.1 (from your example), any programs listening on either all interfaces, or specifically, to eth0.1 will be able to receive packets on that IP address.
To add a secondary IP address you use the : separator on the interface name. Suppose you have eth0 assigned with 11.22.33.44 and you also want it to work with 11.22.33.55. Then you would just do:
ifconfig eth0:1 11.22.33.55
If you don't touch routing through the ip route command, 11.22.33.55 won't ever be used as an outbound interface, unless you're answering a request that points to 11.22.33.55 itself, so there are two more things to do.
The first is setting up your webserver's listening address to 11.22.33.55 instead of 'any' IP or 11.22.33.44. This depends on your webserver, in the case of apache check out the Listen directive.
The second thing, if you use a domain, to do is setting up a DNS record to point to 11.22.33.55 instead of 11.22.33.44. Take care because a domain name can't be resolved to a different address depending on the destination port, so you'll need a domain name for each interface. The alternative is directly using the IP address 11.22.33.44 for the script stuff and using the domain name for the webserver only.
After you've done this you can safely use tcpdump, iptables & friends on both the physical and the virtual interface.
I want send out data from one NIC and received by another NIC on a CENTOS6.4( X86 frame ,3 NIC, one is onboard realtek's, the other two is intel NICs ).
First,I configured intel nic ip: (eth0) 192.168.1.1/24 and (eth1) 192.168.1.2/24 on two intel NICs.
Second, I add route by following cmds:
# route add -host 192.168.1.1 dev eth1
# route add -host 192.168.1.2 dev eth0
Third, I enabled accept_local in /etc/sysctl.conf:
net.ipv4.conf.eth0.accept_local = 1
net.ipv4.conf.eth1.accept_local = 1
And I also disabled iptables and SElinux. I reboot the system, then use a wire connect eth0 and eth1, then I test like this:
#ping 192.168.1.1 -I eth1
Message returned:
"From 192.168.1.2 icmp_seq=xx Destination Host Unreachable"
Has I missed something?
I have read this topic How can configure linux routing to send packets out one interface, over a bridge and into another interface on the same box already.
try set sysctl -w net.ipv4.conf.all.rp_filter=2
Refer https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
accept_local - BOOLEAN
Accept packets with local source addresses. In combination
with suitable routing, this can be used to direct packets
between two local interfaces over the wire and have them
accepted properly.
rp_filter must be set to a non-zero value in order for
accept_local to have an effect.
rp_filter - INTEGER
0 - No source validation.
1 - Strict mode as defined in RFC3704 Strict Reverse Path
Each incoming packet is tested against the FIB and if the interface
is not the best reverse path the packet check will fail.
By default failed packets are discarded.
2 - Loose mode as defined in RFC3704 Loose Reverse Path
Each incoming packet's source address is also tested against the FIB
and if the source address is not reachable via any interface
the packet check will fail.
Current recommended practice in RFC3704 is to enable strict mode
to prevent IP spoofing from DDos attacks. If using asymmetric routing
or other complicated routing, then loose mode is recommended.
The max value from conf/{all,interface}/rp_filter is used
when doing source validation on the {interface}.
Default value is 0. Note that some distributions enable it
in startup scripts.