Talk:WireGuard

From Gentoo Wiki
Jump to:navigation Jump to:search
Note
Before creating a discussion or leaving a comment, please read about using talk pages. To create a new discussion, click here. Comments on an existing discussion should be signed using ~~~~:
A comment [[User:Larry|Larry]] 13:52, 13 May 2024 (UTC)
: A reply [[User:Sally|Sally]] 12:11, 11 December 2024 (UTC)
:: Your reply ~~~~

Definitions

Talk status
This discussion is done.

Anyone can point me to the technical description of site-to-point and site-to-site connections? I have never heard of site-to-point connections, and site-to-site connections. Point-to-point is a networking term, point-to-multipoint is a networking term too. Hub and spoke is a networking term. But what is a site-to-site connection? This both terms I am referring to are used in the first sentences on this article. Thanks Needle (talk) 12:02, 30 December 2020 (UTC)

Hi Needle, I'm no VPN or network expert, but does this help? --Maffblaster (talk) 18:08, 31 December 2020 (UTC)
I believe that a "site-to-point" connection is what is also called a "client-to-site" connection, i.e. a connection in which one VPN endpoint, the "client", is a single device (e.g. a laptop computer) and the other one is a gateway to a network of devices, giving the "client" secure access to the entire network. A "site-to-site" connection is a connection in which both VPN endpoints are gateways to networks, enabling secure communications between any pair of devices from those "sites". — GuillermoDH (talk) 21:03, 2 January 2021 (UTC)
Thanks. This all VPN jargon is kind of buzzword bingo for me, and most probably for the future readers too. I am not sure it makes sense mentioning, these 3 terms right at the beginning of the article. The reason is, this 3 connection types mentioned are possible with all kind of IPSec software. It is not exclusive to wireguard, actually even using openvpn, openconnect and vpnc. From my point of view these 3 connection types should be further explained in the article and and howto implement them. For example, as seen from the IP level, a "site-to-site" connection implementation is the same as "point-to-point", it only differs by the amount of IP routes on both sides, and the used routed protocol static routing or dynamic routing protocol. "site-to-point connection" might be maybe a term from the security area. I have been asking around on freenode in the known networking channels if "site-to-point" is actually a term that means something technical , and we all came to the same conclusion, this is marketing buzzword. I have swapped these 3 terms with "secure connections" Mentioning "full tunnel" or "split tunnel" conneciton would make more sense, not only here but also on other wiki articles. I might be biased, and have very limited knowledge about the security networking. I suggest to remove these 3 connection types if they are not explicitelly described in the article. Instead I would write "secure connections". Because then the article is more understandable for users and does not add any buzzword that are not eplained. I am not against mentioning these terms, I am more against it using "difficult to explain" terms that are not explained anymore. If someone would explain and howto implement I am for it. But as long as it is not found anywhere then I am a friend of simplicity. From my point of view, less is more. Needle (talk) 18:59, 3 January 2021 (UTC)

wg0.conf?

Talk status
This discussion is done as of 2022-08-02.

as a point of feedback, got here trying to set up wireguard and this completely glosses over how to write wg0.conf and I have no idea how to proceed. including instructions or linking to them would be incredibly helpful Witchyanna (talk) 16:46, 2 August 2022 (UTC)

I have taken the time to add more on the information you are requesting. See Special:Diff/1075103/1080553. --Maffblaster (talk) 21:37, 2 August 2022 (UTC)

WireGuard setup for netifrc does not work

Talk status
This discussion is ready to be implemented as of 2024-08-20 because
  • it provides a proposal that can be merged as is,
  • that proposal has been unchanged and uncontested for 30 days, and
  • all participants have reached a consensus.
Proposed changes to section Kernel - Please make edits here until a final revision is agreed upon.

  • Add CONFIG_NF_CONNTRACK_MARK to the list of modules if using wg-quick

(this proposal has been applied)

Proposed changes to section Avoid using wg-quick - Please make edits here until a final revision is agreed upon.

  • Add example nftable rule from the Nftabes/Examples Gentoo Wiki page and instruct where to put it (should be /var/lib/nftables/rules-save)

(this proposal has been applied)

  • Change nft command in postup() from using 'ip' to 'inet' to support IPv4 and IPv6

(this proposal has been applied)

To put simply, the instructions for setting up WireGuard (WG) via netifrc are incomplete and do not work.

Part 1 of problem:

In the "postup()" function, an nft command is ran to update the firewall; the issue is that the default rule set for nftables is an empty file located at /var/lib/nftables/rules-save. The nft command tries to add a rule to a chain named "output" in a table named "filter"; neither of which exist if the user simply emerged net-firewall/nftables manually or it got pulled in as a dependency. The solution I found was to copy-paste the "Typical workstation (combined IPv4 and IPv6)" from the Nftables/Examples wiki page into /var/lib/nftables/rules-save and edit the nft command to "nft insert rule inet filter ..." instead of "nft insert rule ip filter ..." so that it works for IPv4 and IPv6. I will probably add this to the wiki myself soon.

Part 2 of problem:

The "postup()" function does not actually route packets to the WG interface. I tested this with my home network and cannot get any packets to/from my router; I know the setup works because when I tested WG using "wg-quick", it works. When trying to use the netifrc method, the WG tunnel is established, but that's it -- no internet. On my router, I see that the WG tunnel is connected, but again -- no internet. I then commented out the nft command in "postup()" to see if that was the issue -- it was not. Commenting out the nft command resulted in internet, but my router stated that no packets were going through the WG tunnel. The "wg set wg0 ...", "ip route add ...", and the "ip rule add ..." commands are not routing the packets to the wg0 interface.

I tried looking at the "wg-quick" bash script to see how it makes WG work, but I don't know enough about "ip" nor "nft" to translate it.

FlyingBullets (talk) 13:39, 20 August 2024 (UTC)

I can confirm that example doesn't work. I tried that set up about a year ago and figured out wg-quick is a better solution. I'm not sure the rule 'nft insert rule ip filter output oifname!="wg0" mark!=334455 fib daddr type!=local counter reject || exit 1' makes sense. I suspect the 'official' method using 'ip rule add table main suppress_prefixlength 0' would work better, but I'm to lazy to test it. Finoderi (talk) 14:43, 20 August 2024 (UTC)
Update 1: I tried to copy some of the nft commands from the wg-quick script, specifically the "meta l4proto udp meta set ..." and "meta l4proto udp meta mark 334455 ..." (I inserted the 334455) -- it still does not work. I don't understand how wg-quick does it even after reading the commands; the commands in the "postup()" function make more sense, yet they don't work... FlyingBullets (talk) 15:48, 20 August 2024 (UTC)
It seems the example /etc/conf.d/net provided takes into account that we should already have a working nftables configuration with the needed kernel config and with the table and chain already configured as well. I've been able to make the example work by performing the following changes:
1. Configure the following options in the kernel: CONFIG_NFT_FIB, CONFIG_NFT_FIB_INET, CONFIG_NFT_FIB_NETDEV, CONFIG_NFT_FIB_IPV4, CONFIG_NFT_FIB_IPV6, CONFIG_FIB_RULES, CONFIG_NFT_REJECT, CONFIG_NFT_REJECT_NETDEV. If these options are not present, the nft command in line 58 of the example ends with the "Error: Could not process rule: No such file or directory" error message.
2. Run the following commands to initialize the table and chain needed for the rule in line 58:
$ nft add table ip filter # create table
$ nft add chain ip filter output { type filter hook input priority 0 \; } # create chain
$ /etc/init.d/nftables save # to save the above information as default
With the above changes I'm able to connect to the Wireguard endpoint by netifrc and as far as I've tested, network seems to work as expected. It will be great if anyone could also test this approach to ensure it works as expected for everyone.
Dwosky (talk) 11:08, 23 August 2024 (UTC)
Dwosky, I've checked all the CONFIG_* options that you listed in my kernel and they are all already enabled (6.6.47-gentoo). Also, I've tried testing this with the 'ip' table instead of the 'inet' table -- still no dice. One thing I want to add is that the Kernel section should add CONFIG_NF_CONNTRACK_MARK if compiling net-vpn/wireguard-tools with the "wg-quick" USE flag; Portage gave me a warning stating that I needed this CONFIG option. Strangely, Portage doesn't say anything when compiling without this USE flag.
And just to clarify: using WG with "wg-quick" works as expected (WG connects and packets go through the tunnel). Using WG with "netifrc"... WG connects, but no packets are going through the tunnel.
FlyingBullets (talk) 13:15, 23 August 2024 (UTC)
FlyingBullets, is the start command giving you any error? If you get the "Could not process rule: No such file or directory" error message means that you're missing a kernel configuration. ntf usually highlights the part of the rule that's failing. Here's my kernel config if you want to check it out agains yours: https://termbin.com/o4zd --Dwosky (talk) 13:51, 23 August 2024 (UTC)
There is no error; OpenRC goes through the entire startup process via 'rc-service net.wg0 start' without any problems. The nft rule fails because the default nftables rule file is empty, but you can copy-paste a rule set from the Nftables/Examples page and use that. I used the "Typical workstation (combined IPv4 and IPv6)" and changed the nft command to use 'inet' instead of 'ip'.
When you tested it, did you actually have an internet connection? For me, WG found the endpoint and connected to it, but running 'ping gnu.org' failed (wait ~1 minute after WG connects to test for an internet connection). I know for a fact that my kernel and system as a whole is configured properly because everything works when using the wg-quick script.
I don't know what the problem is. I read the wg-quick script (it's literally just a bash script) to see what commands it runs to get it to work. There are only 1-2 commands in the end that are different, that difference however requires deep knowledge of iproute2 and nftables. I compared the routes and tables of both via 'ip route list table all' and 'nft list tables'.
FlyingBullets (talk) 15:00, 23 August 2024 (UTC)
From my side all networking seems to work fine when I enable/start wg0. I can ping/ssh/etc to the IPs in WireGuard's endpoint and I can browse the internet without issues as well. Not sure if it could be something related with the ip routes or rules as you suggest. --Dwosky (talk) 16:17, 23 August 2024 (UTC)
That's because your command,
'nft add chain ip filter output { type filter hook input priority 0 \; }'
has the hook "input"; this is an input chain, not an output chain. The "output" in the command is just the name of the chain, which can be anything. The nft command in postup() will put its rule in a table named "filter" in a chain named "output". nftables will test the rule 'oifname!="wg0" ...' for all incoming packets; this test will fail because it's impossible for an incoming packet to use the output interface of the local machine. This explains why you still have an internet connection because nothing is being rejected.
FlyingBullets (talk) 16:54, 23 August 2024 (UTC)
I've updated the input word for output and it seems to be working the same. One thing I've seen, not sure if its ok or not is that the filter its created with 'policy accept' by default and the priority is 'filter' instead of 0, not sure if that has anything to do:
$ nft list chain ip filter output
table ip filter {
chain output {
type filter hook output priority filter; policy accept;
oifname != "wg0" meta mark != 0x00051a77 fib daddr type != local counter packets 0 bytes 0 reject
--Dwosky (talk) 16:51, 29 August 2024 (UTC)
In the manual page for nftables, man nft:
The policy defines "what happens to packets not explicitly accepted or refused in contained rules. Supported policy values are accept (which is the default) or drop." So, the policy accept; part means to allow packets through the chain by default; this is okay for the output chain because we (the local machine) want to be able to communicate with any other machine.
Again in the manual:
"The priority parameter accepts a signed integer value or a standard priority name which specifies the order in which chains with the same hook value are traversed. The ordering is ascending, i.e. lower priority values have precedence over higher ones." If you take a look at Table 6. Standard priority names, family and hook compatibility matrix, you will see that the value of 0 is the same as the name filter; not to be confused with the chain type filter.
table ip filter {---------> A table NAMED "filter" for the IPv4 address family (this has no effect on the firewall rules).
type filter ...-----------> A chain of TYPE "filter", which is a standard chain type to use in doubt.
... priority filter; ...--> A chain of priority VALUE "filter", which is the value of 0 (raw=-300, mangle=-150, security=50, etc.).
I still believe that packets are not going through your WG interface because the routing commands in /etc/conf.d/net are not working. You might have internet and can ping/ssh/etc. at your WG endpoint, but that doesn't prove that that packets are going through it. Do you have statistics of traffic going through that specific interface at the endpoint? If you watch a 4K video over the internet, do you see the number of sent/received packets on interface wg0 increase?
FlyingBullets (talk) 14:46, 30 August 2024 (UTC)
Update 2:
I managed to walk through the wg-quick script and re-make it without changing the functionality. The following script should work with the following setup:
- WG config file is located in /etc/wireguard/wg0.conf
- Address = and DNS = lines are commented out under [Interface] in the WG config file
- local_ipv4 and local_ipv6 are assigned the values from Address =
FILE simple_wg_quick.bash
#!/bin/bash

nftcmd=''
local_ipv4=''
local_ipv6=''
case "$@" in
up)
	ip link add wg0 type wireguard
	wg setconf wg0 /etc/wireguard/wg0.conf
	ip -4 address add "$local_ipv4" dev wg0
	ip -6 address add "$local_ipv6" dev wg0
	ip link set mtu 1420 up dev wg0
	wg set wg0 fwmark 51820

	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
	printf -v nftcmd '%sadd table %s %s\n' "$nftcmd" "ip" "wg0_table"
	printf -v nftcmd '%sadd chain %s %s preraw { type filter hook prerouting priority -300; }\n' "$nftcmd" "ip" "wg0_table"
	printf -v nftcmd '%sadd chain %s %s premangle { type filter hook prerouting priority -150; }\n' "$nftcmd" "ip" "wg0_table"
	printf -v nftcmd '%sadd chain %s %s postmangle { type filter hook postrouting priority -150; }\n' "$nftcmd" "ip" "wg0_table"

	printf -v nftcmd '%sadd rule %s %s preraw iifname != "%s" %s daddr %s fib saddr type != local drop\n' "$nftcmd" "ip" "wg0_table" "wg0" "ip" "$local_ipv4"

	printf -v nftcmd '%sadd rule %s %s postmangle meta l4proto udp mark %d ct mark set mark \n' "$nftcmd" "ip" "wg0_table" 51820
	printf -v nftcmd '%sadd rule %s %s premangle meta l4proto udp meta mark set ct mark \n' "$nftcmd" "ip" "wg0_table"
	sysctl -q net.ipv4.conf.all.src_valid_mark=1



	ip -6 route add "::/0" dev wg0 table 51820
	ip -6 rule add not fwmark 51820 table 51820
	ip -6 rule add table main suppress_prefixlength 0
	printf -v nftcmd '%sadd table %s %s\n' "$nftcmd" "ip6" "wg0_table"
	printf -v nftcmd '%sadd chain %s %s preraw { type filter hook prerouting priority -300; }\n' "$nftcmd" "ip6" "wg0_table"
	printf -v nftcmd '%sadd chain %s %s premangle { type filter hook prerouting priority -150; }\n' "$nftcmd" "ip6" "wg0_table"
	printf -v nftcmd '%sadd chain %s %s postmangle { type filter hook postrouting priority -150; }\n' "$nftcmd" "ip6" "wg0_table"

	printf -v nftcmd '%sadd rule %s %s preraw iifname != "%s" %s daddr %s fib saddr type != local drop\n' "$nftcmd" "ip6" "wg0_table" "wg0" "ip6" "$local_ipv6"

	printf -v nftcmd '%sadd rule %s %s postmangle meta l4proto udp mark %d ct mark set mark \n' "$nftcmd" "ip6" "wg0_table" 51820
	printf -v nftcmd '%sadd rule %s %s premangle meta l4proto udp meta mark set ct mark \n' "$nftcmd" "ip6" "wg0_table"
	nft -f <(echo -n "$nftcmd")
	;;

down)
	printf -v nftcmd '%sdelete %s\n' "$nftcmd" "table ip wg0_table"
	printf -v nftcmd '%sdelete %s\n' "$nftcmd" "table ip6 wg0_table"
	nft -f <(echo -n "$nftcmd")
	ip -4 rule delete table 51820
	ip -4 rule delete table main suppress_prefixlength 0
	ip -6 rule delete table 51820
	ip -6 rule delete table main suppress_prefixlength 0
	ip link delete dev wg0
	;;
esac
I will be working on a version that combines the ip and ip6 tables into a single inet table. If anyone has problems with this script, please let me know; this script should work regardless of your nftable configuration because it creates a new, independent table.
FlyingBullets (talk) 22:06, 5 September 2024 (UTC)
Update 3:
Success! Here is the inet version (same setup required for original):
FILE simple_wg_quick_v2.bash
#!/bin/bash

nftcmd=''
local_ipv4=''
local_ipv6=''
wg_iface='wg0'
wg_fwmark='51820'
wg_routing_table='51820'
case "$@" in
up)
	ip link add "$wg_iface" type wireguard
	wg setconf "$wg_iface" /etc/wireguard/"$wg_iface".conf
	ip -4 address add "$local_ipv4" dev "$wg_iface"
	ip -6 address add "$local_ipv6" dev "$wg_iface"
	ip link set mtu 1420 up dev "$wg_iface"
	wg set "$wg_iface" fwmark "$wg_fwmark"
	sysctl -q net.ipv4.conf.all.src_valid_mark=1

	# Allowed-IPs.
	ip -4 route add "0.0.0.0/0" dev "$wg_iface" table "$wg_routing_table"
	ip -6 route add "::/0"      dev "$wg_iface" table "$wg_routing_table"

	ip -4 rule add not fwmark "$wg_fwmark" table "$wg_routing_table"
	ip -6 rule add not fwmark "$wg_fwmark" table "$wg_routing_table"

	ip -4 rule add table main suppress_prefixlength 0
	ip -6 rule add table main suppress_prefixlength 0

	# Keep nftables atomic.
	printf -v nftcmd '%sadd table %s %s\n'                                                                "$nftcmd" inet "${wg_iface}_nftable"
	printf -v nftcmd '%sadd chain %s %s preraw { type filter hook prerouting priority -300; }\n'          "$nftcmd" inet "${wg_iface}_nftable"
	printf -v nftcmd '%sadd chain %s %s premangle { type filter hook prerouting priority -150; }\n'       "$nftcmd" inet "${wg_iface}_nftable"
	printf -v nftcmd '%sadd chain %s %s postmangle { type filter hook postrouting priority -150; }\n'     "$nftcmd" inet "${wg_iface}_nftable"

	printf -v nftcmd '%sadd rule %s %s preraw iifname != "%s" %s daddr %s fib saddr type != local drop\n' "$nftcmd" inet "${wg_iface}_nftable" "$wg_iface" ip  "$local_ipv4"
	printf -v nftcmd '%sadd rule %s %s preraw iifname != "%s" %s daddr %s fib saddr type != local drop\n' "$nftcmd" inet "${wg_iface}_nftable" "$wg_iface" ip6 "$local_ipv6"

	printf -v nftcmd '%sadd rule %s %s postmangle meta l4proto udp mark %d ct mark set mark \n'           "$nftcmd" inet "${wg_iface}_nftable" "$wg_fwmark"
	printf -v nftcmd '%sadd rule %s %s premangle meta l4proto udp meta mark set ct mark \n'               "$nftcmd" inet "${wg_iface}_nftable"
	nft -f <(echo -n "$nftcmd")
	;;

down)
	nft delete table inet "${wg_iface}_nftable"
	ip -4 rule delete table "$wg_routing_table"
	ip -6 rule delete table "$wg_routing_table"
	ip -4 rule delete table main suppress_prefixlength 0
	ip -6 rule delete table main suppress_prefixlength 0
	ip link delete dev "$wg_iface"
	;;
esac
My next goals were:
- find out what parts I do and don't need
- find out how to merge this script with /etc/conf.d/net
- who knows from there...
But, while reading the official WG documentation, I found that this is a "Classic Solution" and that there is a "New Namespace Solution" that has some benifits such as being able to selectively route commands outside the WG tunnel without having to shut down the tunnel; I will be working on a script that implements this namespace solution.
For now, this inet implimentation of the wg-quick script should work.
FlyingBullets (talk) 22:22, 5 September 2024 (UTC)
Update 4:
I have completed the "New Namespace Solution" and am currently working on the wiki changes. :3
FlyingBullets (talk) 14:17, 2 October 2024 (UTC)
Update 5:
I have completed the changes to the Wiki. If anyone has any questions, comments, or concerns about the new "Network Namespaces" section, let me know.
FlyingBullets (talk) 00:07, 3 October 2024 (UTC)