-
Notifications
You must be signed in to change notification settings - Fork 186
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
111 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
WireGuard for SMF | ||
================= | ||
|
||
The example `wg-quick.xml` file may be used for running wg-quick(8) | ||
using SMF. | ||
|
||
Usage | ||
----- | ||
|
||
Choose a name for your wg-quick config. It can be pretty much any simple string. | ||
It will be used for naming your config file and your SMF service instance name. | ||
The underlying tun device will be allocated dynamically. | ||
|
||
Create `/etc/wireguard/<something>.conf` | ||
|
||
``` | ||
# svccfg import wg-quick.xml | ||
# svccfg -s svc:/vpn/wg-quick add something | ||
# svcadm enable wg-quick:something | ||
``` | ||
|
||
Helpful references | ||
------------------ | ||
|
||
- https://blogs.warwick.ac.uk/chrismay/entry/solaris_smf_manifest/ | ||
- (archive) https://web.archive.org/web/20210613085120/https://blogs.warwick.ac.uk/chrismay/entry/solaris_smf_manifest/ | ||
- https://github.com/omniosorg/omnios-extra/blob/800489a/build/wireguard-tools/files/wg-quick.xml | ||
- https://github.com/TritonDataCenter/pkgsrc-extra/blob/4423c14/wireguard-tools/files/smf/manifest.xml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?xml version="1.0"?> | ||
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> | ||
<service_bundle type="manifest" name="export"> | ||
<service name="vpn/wg-quick" type="service" version="0"> | ||
<!--instance name="default" enabled="false" --> | ||
<dependency name="network" grouping="require_all" restart_on="error" type="service"> | ||
<service_fmri value="svc:/milestone/network:default"/> | ||
</dependency> | ||
<dependency name="filesystem" grouping="require_all" restart_on="error" type="service"> | ||
<service_fmri value="svc:/system/filesystem/local"/> | ||
</dependency> | ||
<exec_method name="start" type="method" exec="/usr/local/bin/wg-quick up %i" timeout_seconds="180"> | ||
<method_context> | ||
<method_credential group="root" user="root"/> | ||
<method_environment> | ||
<envvar name="WG_QUICK_USERSPACE_IMPLEMENTATION" value="/usr/local/sbin/wireguard"/> | ||
</method_environment> | ||
</method_context> | ||
</exec_method> | ||
<exec_method name="stop" type="method" exec="/usr/local/bin/wg-quick down %i" timeout_seconds="180"> | ||
<method_context> | ||
<method_credential group="root" user="root"/> | ||
<method_environment> | ||
<envvar name="WG_QUICK_USERSPACE_IMPLEMENTATION" value="/usr/local/sbin/wireguard"/> | ||
</method_environment> | ||
</method_context> | ||
</exec_method> | ||
<property_group name="application" type="application"/> | ||
<property_group name="startd" type="framework"> | ||
<propval name="duration" type="astring" value="contract"/> | ||
<propval name="ignore_error" type="astring" value="core,signal"/> | ||
</property_group> | ||
<!-- /instance --> | ||
<stability value="Evolving"/> | ||
<template> | ||
<common_name> | ||
<loctext xml:lang="C">WireGuard via wg-quick(8)</loctext> | ||
</common_name> | ||
</template> | ||
</service> | ||
</service_bundle> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,13 @@ | ||
#!/usr/local/bin/bash | ||
#!/usr/bin/env bash | ||
# SPDX-License-Identifier: GPL-2.0 | ||
# | ||
# Copyright (C) 2015-2020 Jason A. Donenfeld <[email protected]>. All Rights Reserved. | ||
# Copyright (C) 2015-2023 Jason A. Donenfeld <[email protected]>. All Rights Reserved. | ||
# | ||
|
||
set -e -o pipefail | ||
shopt -s extglob | ||
export LC_ALL=C | ||
|
||
exec 3>&2 | ||
SELF="$(readlink -f "${BASH_SOURCE[0]}")" | ||
export PATH="${SELF%/*}:$PATH" | ||
|
||
|
@@ -29,7 +28,7 @@ PROGRAM="${0##*/}" | |
ARGS=( "$@" ) | ||
|
||
cmd() { | ||
echo "[#] $*" >&3 | ||
echo "[#] $*" >&2 | ||
"$@" | ||
} | ||
|
||
|
@@ -45,7 +44,7 @@ parse_options() { | |
[[ -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" | ||
CONFIG_FILE="$(readlink -f "$CONFIG_FILE")" | ||
((($(stat -f '0%#p' "$CONFIG_FILE") & $(stat -f '0%#p' "${CONFIG_FILE%/*}") & 0007) == 0)) || echo "Warning: \`$CONFIG_FILE' is world accessible" >&2 | ||
((($(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 | ||
while read -r line || [[ -n $line ]]; do | ||
|
@@ -83,37 +82,32 @@ read_bool() { | |
} | ||
|
||
auto_su() { | ||
[[ $UID == 0 ]] || exec doas -- "$BASH" -- "$SELF" "${ARGS[@]}" | ||
# Other platforms appear to escalate priviliges silently. | ||
# We will just require root permissions. | ||
[[ $UID == 0 ]] || die "must be run as root" | ||
} | ||
|
||
|
||
get_real_interface() { | ||
local interface line | ||
while IFS= read -r line; do | ||
if [[ $line =~ ^([a-z]+[0-9]+):\ .+ ]]; then | ||
interface="${BASH_REMATCH[1]}" | ||
continue | ||
fi | ||
if [[ $interface == wg* && $line =~ ^\ description:\ wg-quick:\ (.+) && ${BASH_REMATCH[1]} == "$INTERFACE" ]]; then | ||
REAL_INTERFACE="$interface" | ||
return 0 | ||
fi | ||
done < <(ifconfig) | ||
return 1 | ||
local interface diff | ||
wg show interfaces >/dev/null | ||
[[ -f "/var/run/wireguard/$INTERFACE.name" ]] || return 1 | ||
interface="$(< "/var/run/wireguard/$INTERFACE.name")" | ||
[[ -n $interface && -S "/var/run/wireguard/$interface.sock" ]] || return 1 | ||
diff=$(( $(stat -c %Y "/var/run/wireguard/$interface.sock" 2>/dev/null || echo 200) - $(stat -c %Y "/var/run/wireguard/$INTERFACE.name" 2>/dev/null || echo 100) )) | ||
[[ $diff -ge 2 || $diff -le -2 ]] && return 1 | ||
REAL_INTERFACE="$interface" | ||
echo "[+] Interface for $INTERFACE is $REAL_INTERFACE" >&2 | ||
return 0 | ||
} | ||
|
||
add_if() { | ||
while true; do | ||
local -A existing_ifs="( $(wg show interfaces | sed 's/\([^ ]*\)/[\1]=1/g') )" | ||
local index ret | ||
for ((index=0; index <= 2147483647; ++index)); do [[ -v existing_ifs[wg$index] ]] || break; done | ||
if ret="$(cmd ifconfig wg$index create description "wg-quick: $INTERFACE" 2>&1)"; then | ||
REAL_INTERFACE="wg$index" | ||
return 0 | ||
fi | ||
[[ $ret == *"ifconfig: SIOCIFCREATE: File exists"* ]] && continue | ||
echo "$ret" >&3 | ||
return 1 | ||
export WG_TUN_NAME_FILE="/var/run/wireguard/$INTERFACE.name" | ||
mkdir -p "/var/run/wireguard/" | ||
cmd "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" tun | ||
cmd sleep 0.1 | ||
get_real_interface | ||
until ipadm show-if $REAL_INTERFACE 2>/dev/null | grep -q $REAL_INTERFACE; do | ||
cmd sleep 0.1 | ||
done | ||
} | ||
|
||
|
@@ -143,12 +137,18 @@ del_routes() { | |
} | ||
|
||
del_if() { | ||
local addr | ||
unset_dns | ||
[[ -n $REAL_INTERFACE ]] && cmd ifconfig $REAL_INTERFACE destroy | ||
[[ -n $REAL_INTERFACE ]] && ipadm show-addr -p -o addrobj | grep $REAL_INTERFACE/ | while read addr; do | ||
cmd ipadm delete-addr $addr | ||
done | ||
[[ -z $REAL_INTERFACE ]] || cmd rm -f "/var/run/wireguard/$REAL_INTERFACE.sock" | ||
cmd rm -f "/var/run/wireguard/$INTERFACE.name" | ||
} | ||
|
||
up_if() { | ||
cmd ifconfig "$REAL_INTERFACE" up | ||
# Due to illumos tun driver quirks there is nothing to do here. | ||
true | ||
} | ||
|
||
add_addr() { | ||
|
@@ -160,7 +160,9 @@ add_addr() { | |
family=inet | ||
[[ -n $FIRSTADDR4 ]] || FIRSTADDR4="${1%/*}" | ||
fi | ||
cmd ifconfig "$REAL_INTERFACE" $family "$1" alias | ||
# cleanup just in case | ||
ipadm delete-addr "$REAL_INTERFACE/$2" &>/dev/null || true | ||
cmd ipadm create-addr -t -T static -a "local=$1,remote=$1" "$REAL_INTERFACE/$2" | ||
} | ||
|
||
set_mtu() { | ||
|
@@ -283,25 +285,14 @@ monitor_daemon() { | |
|
||
set_dns() { | ||
[[ ${#DNS[@]} -gt 0 ]] || return 0 | ||
|
||
# TODO: add exclusive support for nameservers | ||
if pgrep -qx unwind; then | ||
echo "[!] WARNING: unwind will leak DNS queries" >&2 | ||
elif pgrep -qx resolvd; then | ||
echo "[!] WARNING: resolvd may leak DNS queries" >&2 | ||
else | ||
echo "[+] resolvd is not running, DNS will not be configured" >&2 | ||
return 0 | ||
fi | ||
|
||
cmd cp /etc/resolv.conf "/etc/resolv.conf.wg-quick-backup.$INTERFACE" | ||
[[ ${#DNS_SEARCH[@]} -eq 0 ]] || cmd printf 'search %s\n' "${DNS_SEARCH[*]}" > /etc/resolv.conf | ||
route nameserver ${REAL_INTERFACE} ${DNS[@]} | ||
{ cmd printf 'nameserver %s\n' "${DNS[@]}" | ||
[[ ${#DNS_SEARCH[@]} -eq 0 ]] || cmd printf 'search %s\n' "${DNS_SEARCH[*]}" | ||
} > /etc/resolv.conf | ||
} | ||
|
||
unset_dns() { | ||
[[ -f "/etc/resolv.conf.wg-quick-backup.$INTERFACE" ]] || return 0 | ||
route nameserver ${REAL_INTERFACE} | ||
cmd mv "/etc/resolv.conf.wg-quick-backup.$INTERFACE" /etc/resolv.conf | ||
} | ||
|
||
|
@@ -415,14 +406,16 @@ cmd_usage() { | |
|
||
cmd_up() { | ||
local i | ||
local n=0 | ||
get_real_interface && die "\`$INTERFACE' already exists as \`$REAL_INTERFACE'" | ||
trap 'del_if; del_routes; exit' INT TERM EXIT | ||
execute_hooks "${PRE_UP[@]}" | ||
add_if | ||
set_config | ||
for i in "${ADDRESSES[@]}"; do | ||
add_addr "$i" | ||
add_addr "$i" "$INTERFACE$n" | ||
n=$((n + 1)) | ||
done | ||
set_config | ||
set_mtu | ||
up_if | ||
set_dns | ||
|