Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wg-quick linux: Add strip-and-eval cmd to extract keys from PostUp #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/man/wg-quick.8
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ wg-quick - set up a WireGuard interface simply
.I save
|
.I strip
|
.I strip-and-eval
] [
.I CONFIG_FILE
|
Expand All @@ -34,6 +36,7 @@ with all
.BR wg-quick (8)-specific
options removed, suitable for use with
.BR wg (8).
Use \fIstrip-and-eval\fP in case you use `PostUp' to read PrivateKey or PresharedKey from a file or command and need them in the output.

\fICONFIG_FILE\fP is a configuration file, whose filename is the interface name
followed by `.conf'. Otherwise, \fIINTERFACE\fP is an interface name, with configuration
Expand Down Expand Up @@ -256,6 +259,12 @@ sessions:

\fB # wg syncconf wgnet0 <(wg-quick strip wgnet0)\fP

\fIstrip-and-eval\fP additionally extracts PrivateKey and PresharedKey from `PostUp` statements and translates them into configuration that
.BR wg (8)
does understand:

\fB # wg syncconf wgnet0 <(wg-quick strip-and-eval wgnet0)\fP

.SH SEE ALSO
.BR wg (8),
.BR ip (8),
Expand Down
2 changes: 1 addition & 1 deletion src/systemd/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/wg-quick up %i
ExecStop=/usr/bin/wg-quick down %i
ExecReload=/bin/bash -c 'exec /usr/bin/wg syncconf %i <(exec /usr/bin/wg-quick strip %i)'
ExecReload=/bin/bash -c 'exec /usr/bin/wg syncconf %i <(exec /usr/bin/wg-quick strip-and-eval %i)'
Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity

[Install]
Expand Down
36 changes: 33 additions & 3 deletions src/wg-quick/linux.bash
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ die() {
}

parse_options() {
local parsing_mode part_of_command peer_pubkey
local interface_section=0 line key value stripped v
declare -A peer_pubkey_to_psk
CONFIG_FILE="$1"
parsing_mode="${2:-safe}"
[[ $CONFIG_FILE =~ ^[a-zA-Z0-9_=+.-]{1,15}$ ]] && CONFIG_FILE="/etc/wireguard/$CONFIG_FILE.conf"
[[ -e $CONFIG_FILE ]] || die "\`$CONFIG_FILE' does not exist"
[[ $CONFIG_FILE =~ (^|/)([a-zA-Z0-9_=+.-]{1,15})\.conf$ ]] || die "The config file must be a valid interface name, followed by .conf"
Expand All @@ -63,12 +66,35 @@ parse_options() {
Table) TABLE="$value"; continue ;;
PreUp) PRE_UP+=( "$value" ); continue ;;
PreDown) PRE_DOWN+=( "$value" ); continue ;;
PostUp) POST_UP+=( "$value" ); continue ;;
PostUp) POST_UP+=( "$value" );
if [[ $parsing_mode == "unsafe" ]]; then
part_of_command=""
if [[ $value =~ ^wg\ +set\ +%i\ +private-key\ +(.+)$ ]]; then
key='PrivateKey'
part_of_command="${BASH_REMATCH[1]}"
elif [[ $value =~ ^wg\ +set\ +%i\ +peer\ +(.+)\ +preshared-key\ +(.+)$ ]]; then
key='PresharedKey'
peer_pubkey="${BASH_REMATCH[1]}"
part_of_command="${BASH_REMATCH[2]}"
fi
if [[ -n "$part_of_command" ]]; then
part_of_command="${part_of_command//%i/$INTERFACE}"
value="$(eval "cat $part_of_command")"
case "$key" in
PresharedKey) peer_pubkey_to_psk["$peer_pubkey"]="$value" ;;
*) WG_CONFIG+="$key = $value"$'\n' ;;
esac
fi
fi
continue ;;
PostDown) POST_DOWN+=( "$value" ); continue ;;
SaveConfig) read_bool SAVE_CONFIG "$value"; continue ;;
esac
fi
WG_CONFIG+="$line"$'\n'
if [[ $interface_section -eq 0 && $key == 'PublicKey' && -n "${peer_pubkey_to_psk[$value]}" ]]; then
WG_CONFIG+="PresharedKey = ${peer_pubkey_to_psk[$value]}"$'\n'
fi
done < "$CONFIG_FILE"
shopt -u nocasematch
}
Expand Down Expand Up @@ -224,7 +250,7 @@ add_default() {
cmd ip $proto rule add not fwmark $table table $table
cmd ip $proto rule add table main suppress_prefixlength 0

local marker="-m comment --comment \"wg-quick(8) rule for $INTERFACE\"" restore=$'*raw\n' nftable="wg-quick-$INTERFACE" nftcmd
local marker="-m comment --comment \"wg-quick(8) rule for $INTERFACE\"" restore=$'*raw\n' nftable="wg-quick-$INTERFACE" nftcmd
printf -v nftcmd '%sadd table %s %s\n' "$nftcmd" "$pf" "$nftable"
printf -v nftcmd '%sadd chain %s %s preraw { type filter hook prerouting priority -300; }\n' "$nftcmd" "$pf" "$nftable"
printf -v nftcmd '%sadd chain %s %s premangle { type filter hook prerouting priority -150; }\n' "$nftcmd" "$pf" "$nftable"
Expand Down Expand Up @@ -298,7 +324,7 @@ execute_hooks() {

cmd_usage() {
cat >&2 <<-_EOF
Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]
Usage: $PROGRAM [ up | down | save | strip | strip-and-eval ] [ CONFIG_FILE | INTERFACE ]

CONFIG_FILE is a configuration file, whose filename is the interface name
followed by \`.conf'. Otherwise, INTERFACE is an interface name, with
Expand Down Expand Up @@ -381,6 +407,10 @@ elif [[ $# -eq 2 && $1 == strip ]]; then
auto_su
parse_options "$2"
cmd_strip
elif [[ $# -eq 2 && $1 == strip-and-eval ]]; then
auto_su
parse_options "$2" "unsafe"
cmd_strip
else
cmd_usage
exit 1
Expand Down