Development discussion of WireGuard
 help / color / mirror / Atom feed
* [PATCH 1/1] Added network namespacing support to wq-quick
@ 2020-03-03 10:35 endre.szabo
  2020-03-04 11:17 ` Jason A. Donenfeld
  0 siblings, 1 reply; 2+ messages in thread
From: endre.szabo @ 2020-03-03 10:35 UTC (permalink / raw)
  To: wireguard

[-- Attachment #1: Type: text/plain, Size: 5507 bytes --]

Hi all,

I added netns support to wq-quick, works quite well for me. An example:

# wg-quick up s2s
[#] ip -n phy link add s2s type wireguard
[#] ip -n phy link set s2s netns 1
[#] wg setconf s2s /dev/fd/63
[#] ip -4 address add 192.168.0.1/32 dev s2s
[#] ip link set mtu 1420 up dev s2s
...

Please go easy on me, this is my first time sending a patch.

--Endre

---

  contrib/highlighter/gui/highlight.cpp |  1 +
  contrib/highlighter/highlight.c       |  1 +
  contrib/highlighter/highlighter.h     |  1 +
  src/man/wg-quick.8                    |  3 +++
  src/wg-quick/linux.bash               | 16 +++++++++++++++-
  5 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/contrib/highlighter/gui/highlight.cpp 
b/contrib/highlighter/gui/highlight.cpp
index a95857b..a698d05 100644
--- a/contrib/highlighter/gui/highlight.cpp
+++ b/contrib/highlighter/gui/highlight.cpp
@@ -25,6 +25,7 @@ static QColor colormap[] = {
      [HighlightDelimiter] = QColor("#7aa6da"),
  #ifndef MOBILE_WGQUICK_SUBSET
      [HighlightTable] = QColor("#c397d8"),
+    [HighlightNetNS] = QColor("#c397d8"),
      [HighlightFwMark] = QColor("#c397d8"),
      [HighlightSaveConfig] = QColor("#c397d8"),
      [HighlightCmd] = QColor("#969896"),
diff --git a/contrib/highlighter/highlight.c 
b/contrib/highlighter/highlight.c
index e9034f7..44b335c 100644
--- a/contrib/highlighter/highlight.c
+++ b/contrib/highlighter/highlight.c
@@ -51,6 +51,7 @@ static const char *colormap[] = {
      [HighlightDelimiter] = TERMINAL_FG_CYAN,
  #ifndef MOBILE_WGQUICK_SUBSET
      [HighlightTable] = TERMINAL_FG_BLUE,
+    [HighlightNetNS] = TERMINAL_FG_BLUE,
      [HighlightFwMark] = TERMINAL_FG_BLUE,
      [HighlightSaveConfig] = TERMINAL_FG_BLUE,
      [HighlightCmd] = TERMINAL_FG_WHITE,
diff --git a/contrib/highlighter/highlighter.h 
b/contrib/highlighter/highlighter.h
index 65cc230..d1ed6d1 100644
--- a/contrib/highlighter/highlighter.h
+++ b/contrib/highlighter/highlighter.h
@@ -21,6 +21,7 @@ enum highlight_type {
      HighlightDelimiter,
  #ifndef MOBILE_WGQUICK_SUBSET
      HighlightTable,
+    HighlightNetNS,
      HighlightFwMark,
      HighlightSaveConfig,
      HighlightCmd,
diff --git a/src/man/wg-quick.8 b/src/man/wg-quick.8
index c38c7d9..3f0565a 100644
--- a/src/man/wg-quick.8
+++ b/src/man/wg-quick.8
@@ -91,6 +91,9 @@ special values: `off' disables the creation of routes 
altogether, and `auto'
  (the default) adds routes to the default table and enables special 
handling of
  default routes.
  .IP \(bu
+NetNS \(em Controls in which network namespace the WireGuard UDP socket 
is added to. The
+namespace has to be created before WireGuard use.
+.IP \(bu
  PreUp, PostUp, PreDown, PostDown \(em script snippets which will be 
executed by
  .BR bash (1)
  before/after setting up/tearing down the interface, most commonly used
diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash
index 7c2c002..6957cba 100755
--- a/src/wg-quick/linux.bash
+++ b/src/wg-quick/linux.bash
@@ -17,6 +17,7 @@ ADDRESSES=( )
  MTU=""
  DNS=( )
  TABLE=""
+NETNS=""
  PRE_UP=( )
  POST_UP=( )
  PRE_DOWN=( )
@@ -58,6 +59,7 @@ parse_options() {
              MTU) MTU="$value"; continue ;;
              DNS) DNS+=( ${value//,/ } ); continue ;;
              Table) TABLE="$value"; continue ;;
+            NetNS) NETNS="$value"; continue ;;
              PreUp) PRE_UP+=( "$value" ); continue ;;
              PreDown) PRE_DOWN+=( "$value" ); continue ;;
              PostUp) POST_UP+=( "$value" ); continue ;;
@@ -84,7 +86,18 @@ auto_su() {

  add_if() {
      local ret
-    if ! cmd ip link add "$INTERFACE" type wireguard; then
+    if [[ -n $NETNS ]]; then
+        if ! ip netns pids "${NETNS}" > /dev/null; then
+            ret=$?
+            echo "[!] Target namespace '${NETNS}' not found"
+            exit $ret
+        elif ! cmd ip -n "${NETNS}" link add "$INTERFACE" type 
wireguard; then
+            ret=$?
+            [[ -e /sys/module/wireguard ]] || ! command -v 
"${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" >/dev/null && exit $ret
+            echo "[!] Missing WireGuard kernel module. Falling back to 
slow userspace implementation."
+        fi
+        cmd ip -n "${NETNS}" link set "$INTERFACE" netns 1
+    elif ! cmd ip link add "$INTERFACE" type wireguard; then
          ret=$?
          [[ -e /sys/module/wireguard ]] || ! command -v 
"${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" >/dev/null && exit $ret
          echo "[!] Missing WireGuard kernel module. Falling back to 
slow userspace implementation."
@@ -258,6 +271,7 @@ save_config() {
      done < <(resolvconf -l "$(resolvconf_iface_prefix)$INTERFACE" 
2>/dev/null || cat 
"/etc/resolvconf/run/interface/$(resolvconf_iface_prefix)$INTERFACE" 
2>/dev/null)
      [[ -n $MTU && $(ip link show dev "$INTERFACE") =~ mtu\ ([0-9]+) ]] 
&& new_config+="MTU = ${BASH_REMATCH[1]}"$'\n'
      [[ -n $TABLE ]] && new_config+="Table = $TABLE"$'\n'
+    [[ -n $NETNS ]] && new_config+="NetNS = $NETNS"$'\n'
      [[ $SAVE_CONFIG -eq 0 ]] || new_config+=$'SaveConfig = true\n'
      for cmd in "${PRE_UP[@]}"; do
          new_config+="PreUp = $cmd"$'\n'
-- 
2.25.1


[-- Attachment #2: 0001-Added-network-namespacing-support.patch --]
[-- Type: text/x-patch, Size: 4671 bytes --]

From 9af84a9996130691b060da2b04b63564d2993a75 Mon Sep 17 00:00:00 2001
From: Endre Szabo <git@end.re>
Date: Tue, 3 Mar 2020 11:20:35 +0100
Subject: [PATCH 1/1] Added network namespacing support

---
 contrib/highlighter/gui/highlight.cpp |  1 +
 contrib/highlighter/highlight.c       |  1 +
 contrib/highlighter/highlighter.h     |  1 +
 src/man/wg-quick.8                    |  3 +++
 src/wg-quick/linux.bash               | 16 +++++++++++++++-
 5 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/contrib/highlighter/gui/highlight.cpp b/contrib/highlighter/gui/highlight.cpp
index a95857b..a698d05 100644
--- a/contrib/highlighter/gui/highlight.cpp
+++ b/contrib/highlighter/gui/highlight.cpp
@@ -25,6 +25,7 @@ static QColor colormap[] = {
 	[HighlightDelimiter] = QColor("#7aa6da"),
 #ifndef MOBILE_WGQUICK_SUBSET
 	[HighlightTable] = QColor("#c397d8"),
+	[HighlightNetNS] = QColor("#c397d8"),
 	[HighlightFwMark] = QColor("#c397d8"),
 	[HighlightSaveConfig] = QColor("#c397d8"),
 	[HighlightCmd] = QColor("#969896"),
diff --git a/contrib/highlighter/highlight.c b/contrib/highlighter/highlight.c
index e9034f7..44b335c 100644
--- a/contrib/highlighter/highlight.c
+++ b/contrib/highlighter/highlight.c
@@ -51,6 +51,7 @@ static const char *colormap[] = {
 	[HighlightDelimiter] = TERMINAL_FG_CYAN,
 #ifndef MOBILE_WGQUICK_SUBSET
 	[HighlightTable] = TERMINAL_FG_BLUE,
+	[HighlightNetNS] = TERMINAL_FG_BLUE,
 	[HighlightFwMark] = TERMINAL_FG_BLUE,
 	[HighlightSaveConfig] = TERMINAL_FG_BLUE,
 	[HighlightCmd] = TERMINAL_FG_WHITE,
diff --git a/contrib/highlighter/highlighter.h b/contrib/highlighter/highlighter.h
index 65cc230..d1ed6d1 100644
--- a/contrib/highlighter/highlighter.h
+++ b/contrib/highlighter/highlighter.h
@@ -21,6 +21,7 @@ enum highlight_type {
 	HighlightDelimiter,
 #ifndef MOBILE_WGQUICK_SUBSET
 	HighlightTable,
+	HighlightNetNS,
 	HighlightFwMark,
 	HighlightSaveConfig,
 	HighlightCmd,
diff --git a/src/man/wg-quick.8 b/src/man/wg-quick.8
index c38c7d9..3f0565a 100644
--- a/src/man/wg-quick.8
+++ b/src/man/wg-quick.8
@@ -91,6 +91,9 @@ special values: `off' disables the creation of routes altogether, and `auto'
 (the default) adds routes to the default table and enables special handling of
 default routes.
 .IP \(bu
+NetNS \(em Controls in which network namespace the WireGuard UDP socket is added to. The
+namespace has to be created before WireGuard use.
+.IP \(bu
 PreUp, PostUp, PreDown, PostDown \(em script snippets which will be executed by
 .BR bash (1)
 before/after setting up/tearing down the interface, most commonly used
diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash
index 7c2c002..6957cba 100755
--- a/src/wg-quick/linux.bash
+++ b/src/wg-quick/linux.bash
@@ -17,6 +17,7 @@ ADDRESSES=( )
 MTU=""
 DNS=( )
 TABLE=""
+NETNS=""
 PRE_UP=( )
 POST_UP=( )
 PRE_DOWN=( )
@@ -58,6 +59,7 @@ parse_options() {
 			MTU) MTU="$value"; continue ;;
 			DNS) DNS+=( ${value//,/ } ); continue ;;
 			Table) TABLE="$value"; continue ;;
+			NetNS) NETNS="$value"; continue ;;
 			PreUp) PRE_UP+=( "$value" ); continue ;;
 			PreDown) PRE_DOWN+=( "$value" ); continue ;;
 			PostUp) POST_UP+=( "$value" ); continue ;;
@@ -84,7 +86,18 @@ auto_su() {
 
 add_if() {
 	local ret
-	if ! cmd ip link add "$INTERFACE" type wireguard; then
+	if [[ -n $NETNS ]]; then
+		if ! ip netns pids "${NETNS}" > /dev/null; then
+			ret=$?
+			echo "[!] Target namespace '${NETNS}' not found"
+			exit $ret
+		elif ! cmd ip -n "${NETNS}" link add "$INTERFACE" type wireguard; then
+			ret=$?
+			[[ -e /sys/module/wireguard ]] || ! command -v "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" >/dev/null && exit $ret
+			echo "[!] Missing WireGuard kernel module. Falling back to slow userspace implementation."
+		fi
+		cmd ip -n "${NETNS}" link set "$INTERFACE" netns 1
+	elif ! cmd ip link add "$INTERFACE" type wireguard; then
 		ret=$?
 		[[ -e /sys/module/wireguard ]] || ! command -v "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" >/dev/null && exit $ret
 		echo "[!] Missing WireGuard kernel module. Falling back to slow userspace implementation."
@@ -258,6 +271,7 @@ save_config() {
 	done < <(resolvconf -l "$(resolvconf_iface_prefix)$INTERFACE" 2>/dev/null || cat "/etc/resolvconf/run/interface/$(resolvconf_iface_prefix)$INTERFACE" 2>/dev/null)
 	[[ -n $MTU && $(ip link show dev "$INTERFACE") =~ mtu\ ([0-9]+) ]] && new_config+="MTU = ${BASH_REMATCH[1]}"$'\n'
 	[[ -n $TABLE ]] && new_config+="Table = $TABLE"$'\n'
+	[[ -n $NETNS ]] && new_config+="NetNS = $NETNS"$'\n'
 	[[ $SAVE_CONFIG -eq 0 ]] || new_config+=$'SaveConfig = true\n'
 	for cmd in "${PRE_UP[@]}"; do
 		new_config+="PreUp = $cmd"$'\n'
-- 
2.25.1


[-- Attachment #3: Type: text/plain, Size: 148 bytes --]

_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH 1/1] Added network namespacing support to wq-quick
  2020-03-03 10:35 [PATCH 1/1] Added network namespacing support to wq-quick endre.szabo
@ 2020-03-04 11:17 ` Jason A. Donenfeld
  0 siblings, 0 replies; 2+ messages in thread
From: Jason A. Donenfeld @ 2020-03-04 11:17 UTC (permalink / raw)
  To: endre.szabo; +Cc: Luis Ressel, WireGuard mailing list

Thanks for the patch! I've generally been hesitant to add network
namespacing stuff to wg-quick, because it seemed a bit too complex for
the scope, but your idea here of thinking of it as simply the socket
netns, while the link stays in the namespace of the running process is
kind of nice, and I'm willing to consider this.

Would be interested in feedback on the idea from Luis (CC'd) too.

Some comments on the implementation, below:

On Wed, Mar 4, 2020 at 7:14 AM <endre.szabo@wg-ml-rkaofgr.redir.email> wrote:
> Please go easy on me, this is my first time sending a patch.
>
> --Endre

The patch needs a Signed-off-by: line. Git will automatically add this
using the lowercase -s option to git-commit, such as:

$ git commit -a -s -m "blah"

>   contrib/highlighter/gui/highlight.cpp |  1 +
>   contrib/highlighter/highlight.c       |  1 +
>   contrib/highlighter/highlighter.h     |  1 +

Thanks for not forgetting the highlighters. However, you'll still need
to add parsing of this field to the actual parser. This might involve
looking up what valid netns names are.

> +NetNS \(em Controls in which network namespace the WireGuard UDP socket
> is added to. The
> +namespace has to be created before WireGuard use.
> +.IP \(bu

Let's call this "SocketNamespace".

SocketNamespace \(em the namespace of the interface's UDP sockets,
though not the interface itself.

> +            NetNS) NETNS="$value"; continue ;;

Might need some validation after?

> +    if [[ -n $NETNS ]]; then
> +        if ! ip netns pids "${NETNS}" > /dev/null; then
> +            ret=$?
> +            echo "[!] Target namespace '${NETNS}' not found"
> +            exit $ret

`ip -n NS` will fail if NS doesn't exist, right? Might as well allow
that to fail organically rather than the TOCTOU here.

> +        elif ! cmd ip -n "${NETNS}" link add "$INTERFACE" type
> wireguard; then

Rather than putting the whole thing in an if [[ -n $NETNS ]] like
that, you can instead use this pattern:

local knetns unetns
[[ -z $NETNS ]] || knetns="-n $NETNS" unetns="ip netns exec $NETNS"
cmd ip $knetns link add ...
cmd $unetns wireguard-go ...

Also, ${NETNS} --> $NETNS.

> +            ret=$?
> +            [[ -e /sys/module/wireguard ]] || ! command -v
> "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" >/dev/null && exit $ret

That should be run in the right namespace, right? via `ip netns exec`

> +        cmd ip -n "${NETNS}" link set "$INTERFACE" netns 1

Using "1" here isn't correct, since we want people to be able to run
wg-quick itself in a network namespace. Instead use `$$`, which will
expand to the shell's PID, which has an associated netns.
_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-03-04 11:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-03 10:35 [PATCH 1/1] Added network namespacing support to wq-quick endre.szabo
2020-03-04 11:17 ` Jason A. Donenfeld

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).