Friendly peer names in wg-quick

Andreas Christ 24cdg at christ-faesch.ch
Tue Mar 12 15:03:17 UTC 2024


Dear wg-quick developers and maintainers 

Peer names are a feature request since a long time, e.g., 
https://www.mail-archive.com/wireguard@lists.zx2c4.com/msg02262.html. I
understand that this feature is not added to wg itself. Instead, I
suggest to consider adding the option to define human readable peer names ("FriendlyName") to wg-quick. The 4 sequential patches below
demonstrate how FriendlyName could be implemented; example given is the
linux.bash version of wg-quick.

'wg-quick show' then produces the same output as 'wg show' plus human
readable peer names.

Andreas


[PATCH 1/4] FriendlyName as an extra configuration value in the [Peer]
sections

FriendlyName allows to give peers a human readable name. This commit
permits 
adding the extra configuration value and to retrieve those values. But
the 
values are not used, e.g., not displayed. 
--- 
src/wg-quick/linux.bash | 21 ++++++++++++++++++++- 
1 file changed, 20 insertions(+), 1 deletion(-) 

diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash 
index 4193ce5..388f256 100755 
--- a/src/wg-quick/linux.bash 
+++ b/src/wg-quick/linux.bash 
@@ -26,6 +26,7 @@ SAVE_CONFIG=0 
CONFIG_FILE="" 
PROGRAM="${0##*/}" 
ARGS=( "$@" ) 
+declare -A PEERS=( ) 

cmd() { 
    echo "[#] $*" >&2 
@@ -47,12 +48,16 @@ parse_options() { 
    ((($(stat -c '0%#a' "$CONFIG_FILE") & $(stat -c '0%#a'
"${CONFIG_FILE%/*}") & 0007) == 0)) || echo "Warning: `$CONFIG_FILE' is
world accessible" >&2 
    INTERFACE="${BASH_REMATCH[2]}" 
    shopt -s nocasematch 
+    local peer_id 
+    local peer_name 
+    local -i peer_section 
    while read -r line || [[ -n $line ]]; do 
        stripped="${line%%#*}" 
        key="${stripped%%=*}"; key="${key##*([[:space:]])}";
key="${key%%*([[:space:]])}" 
        value="${stripped#*=}"; value="${value##*([[:space:]])}";
value="${value%%*([[:space:]])}" 
-        [[ $key == "["* ]] && interface_section=0 
+        [[ $key == "["* ]] && interface_section=0 && peer_section=0 
        [[ $key == "[Interface]" ]] && interface_section=1 
+        [[ $key == "[Peer]" ]] && peer_section=1 && peer_id='' &&
peer_name='no name' 
        if [[ $interface_section -eq 1 ]]; then 
            case "$key" in 
            Address) ADDRESSES+=( ${value//,/ } ); continue ;; 
@@ -68,9 +73,23 @@ parse_options() { 
            SaveConfig) read_bool SAVE_CONFIG "$value"; continue ;; 
            esac 
        fi 
+        if [[ $peer_section -eq 1 ]]; then 
+            case "$key" in 
+            PublicKey) 
+                peer_id="$value" 
+                PEERS[$peer_id]="$peer_name" 
+                ;; 
+            FriendlyName) 
+                peer_name="$value" 
+                [ -n "$peer_id" ] && PEERS[$peer_id]="$peer_name" 
+                continue 
+                ;; 
+            esac 
+        fi 
        WG_CONFIG+="$line"$' ' 
    done < "$CONFIG_FILE" 
    shopt -u nocasematch 
+    # for i in "${!PEERS[@]}" ; do echo "${i} -> ${PEERS[$i]}" ; done 
} 

read_bool() { 
-- 
2.34.1 

[PATCH 2/4] Add 'show' as a new command to wg-quick

The new command 'show' forwards to wg show, unmodified. This is a
preparatory 
step to include human readable names of peers. 
--- 
src/wg-quick/linux.bash | 9 +++++++++ 
1 file changed, 9 insertions(+) 

diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash 
index 388f256..95be1c3 100755 
--- a/src/wg-quick/linux.bash 
+++ b/src/wg-quick/linux.bash 
@@ -380,6 +380,11 @@ cmd_strip() { 
    echo "$WG_CONFIG" 
} 

+cmd_show() { 
+    [[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die
"`$INTERFACE' is not a WireGuard interface" 
+    wg show $INTERFACE 
+} 
+ 
# ~~ function override insertion point ~~ 

if [[ $# -eq 1 && ( $1 == --help || $1 == -h || $1== help ) ]]; then 
@@ -400,6 +405,10 @@ elif [[ $# -eq 2 && $1== strip ]]; then 
    auto_su 
    parse_options "$2" 
    cmd_strip 
+elif [[ $# -eq 2 && $1 == show ]]; then 
+    auto_su 
+    parse_options "$2" 
+    cmd_show 
else 
    cmd_usage 
    exit 1 
-- 
2.34.1 

[PATCH 3/4] wg-quick show labels peers by human readable name
("FriendlyName")

--- 
src/wg-quick/linux.bash | 16 +++++++++++++++- 
1 file changed, 15 insertions(+), 1 deletion(-) 

diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash 
index 95be1c3..a8f135c 100755 
--- a/src/wg-quick/linux.bash 
+++ b/src/wg-quick/linux.bash 
@@ -382,7 +382,21 @@ cmd_strip() { 

cmd_show() { 
    [[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die
"`$INTERFACE' is not a WireGuard interface" 
-    wg show $INTERFACE 
+    local -i empty=0 
+    local -r regex='peer.*: .*(.{43}=)' 
+    while read -r line ; do 
+        if [ ${empty} -eq 1 ] ; then 
+            empty=0 
+            # echo "after an empty line; now $line" 
+            if [[ "${line}" =~ ${regex} ]] ; then 
+                local peer_id="${BASH_REMATCH[1]}" 
+                #echo "peer_id = ${peer_id}" 
+                [ -n "${peer_id}" ] &&    echo "[ ${PEERS[$peer_id]}
]" 
+            fi 
+        fi 
+        [ -z "${line}" ] && empty=1 
+        echo "${line}" 
+    done < <( WG_COLOR_MODE=always wg show $INTERFACE ) 
} 

# ~~ function override insertion point ~~ 
-- 
2.34.1

[PATCH 4/4] Honors environment variable WG_COLOR_CODE, see man wg

Relies on [ -t 1 ] to determine whether the output is a tty or a pipe. 
--- 
src/wg-quick/linux.bash | 7 +++++-- 
1 file changed, 5 insertions(+), 2 deletions(-) 

diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash 
index a8f135c..4847fc7 100755 
--- a/src/wg-quick/linux.bash 
+++ b/src/wg-quick/linux.bash 
@@ -101,7 +101,7 @@ read_bool() { 
} 

auto_su() { 
-    [[ $UID == 0 ]] || exec sudo -p "$PROGRAM must be run as root.
Please enter the password for %u to continue: " -- "$BASH" -- "$SELF"
"${ARGS[@]}" 
+    [[ $UID == 0 ]] || exec sudo --preserve-env=WG_COLOR_MODE -p
"$PROGRAM must be run as root. Please enter the password for %u to
continue: " -- "$BASH" -- "$SELF" "${ARGS[@]}" 
} 

add_if() { 
@@ -382,6 +382,9 @@ cmd_strip() { 

cmd_show() { 
    [[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die
"`$INTERFACE' is not a WireGuard interface" 
+    if [ "${WG_COLOR_MODE:-auto}" == 'auto' ] ; then 
+        [ -t 1 ] && WG_COLOR_MODE='always' || WG_COLOR_MODE='never' 
+    fi 
    local -i empty=0 
    local -r regex='peer.*: .*(.{43}=)' 
    while read -r line ; do 
@@ -396,7 +399,7 @@ cmd_show() { 
        fi 
        [ -z "${line}" ] && empty=1 
        echo "${line}" 
-    done < <( WG_COLOR_MODE=always wg show $INTERFACE ) 
+    done < <( WG_COLOR_MODE="${WG_COLOR_MODE}" wg show $INTERFACE ) 
} 

# ~~ function override insertion point ~~ 
-- 
2.34.1




More information about the WireGuard mailing list