mirror of
https://github.com/yury-sannikov/amnezia-wg-docker.git
synced 2026-10-23 03:26:40 +09:00
initial commit
This commit is contained in:
commit
03b1a04122
11 files changed
+601
No files matched your search
@@ -0,0 +1 @@
|
||||
wg/
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "amnezia-wg"]
|
||||
path = amnezia-wg
|
||||
url = https://github.com/amnezia-vpn/amnezia-wg.git
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
FROM golang:alpine AS builder
|
||||
RUN apk update && apk add --no-cache git make bash
|
||||
RUN apk update && apk add --no-cache build-base linux-headers
|
||||
RUN git clone https://github.com/amnezia-vpn/amnezia-wg-tools.git
|
||||
RUN cd amnezia-wg-tools/src && \
|
||||
make && \
|
||||
make install
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk update && apk add --no-cache bash openrc iptables
|
||||
COPY amnezia-wg/wireguard-go /usr/bin/amnezia-wg
|
||||
COPY --from=builder /usr/bin/wg* /usr/bin/
|
||||
COPY wireguard-fs /
|
||||
|
||||
RUN \
|
||||
sed -i 's/^\(tty\d\:\:\)/#\1/' /etc/inittab && \
|
||||
sed -i \
|
||||
-e 's/^#\?rc_env_allow=.*/rc_env_allow="\*"/' \
|
||||
-e 's/^#\?rc_sys=.*/rc_sys="docker"/' \
|
||||
/etc/rc.conf && \
|
||||
sed -i \
|
||||
-e 's/VSERVER/DOCKER/' \
|
||||
-e 's/checkpath -d "$RC_SVCDIR"/mkdir "$RC_SVCDIR"/' \
|
||||
/lib/rc/sh/init.sh && \
|
||||
rm \
|
||||
/etc/init.d/hwdrivers \
|
||||
/etc/init.d/machine-id
|
||||
RUN sed -i 's/cmd sysctl -q \(.*\?\)=\(.*\)/[[ "$(sysctl -n \1)" != "\2" ]] \&\& \0/' /usr/bin/wg-quick
|
||||
RUN rc-update add wg-quick default
|
||||
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
ENV WG_SUDO=1
|
||||
HEALTHCHECK --interval=15m --timeout=30s CMD /bin/bash /data/healthcheck.sh
|
||||
CMD ["/sbin/init"]
|
||||
@@ -0,0 +1,9 @@
|
||||
awg-arm7:
|
||||
cd amnezia-wg; GOOS=linux GOARCH=arm GOARM=7 make; cd ..
|
||||
|
||||
microtic-arm7: awg-arm7
|
||||
DOCKER_BUILDKIT=1 docker buildx build --platform linux/arm/v7 --output=type=docker --tag microtic-awg:latest .
|
||||
|
||||
export-arm7:
|
||||
docker save microtic-awg:latest > microtic-awg-arm7.tar
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
## About The Project
|
||||
Microtic compatible Docker image to run Amnezia WG on Microtic routers. As of now, support Arm v7 boards
|
||||
|
||||
## About The Project
|
||||
This is a highly experimental attempt to run [Amnezia-WG](https://github.com/amnezia-vpn/amnezia-wg) on a Microtic router.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Follow the [Microtic guidelines](https://help.mikrotik.com/docs/display/ROS/Container) to enable container support.
|
||||
|
||||
Install [Docker buildx](https://github.com/docker/buildx) subsystem, make and go.
|
||||
|
||||
|
||||
### Building Docker Image
|
||||
|
||||
You may need to initialize submodules
|
||||
|
||||
```
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
To build a Docker container for the Microtic run
|
||||
```
|
||||
make microtic-arm7
|
||||
```
|
||||
This command should cross-compile amnezia-wg locally and then build a docker image for ArmV7 arch.
|
||||
|
||||
To export a generated image, use
|
||||
```
|
||||
make export-arm7
|
||||
```
|
||||
|
||||
You will get the `microtic-awg-arm7.tar` archive ready to upload to the Microtic router.
|
||||
|
||||
### Running locally
|
||||
|
||||
Just run `docker compose up`
|
||||
|
||||
Make sure to create a `wg` folder with the `wg0.conf` file.
|
||||
|
||||
Example `wg0.conf`:
|
||||
|
||||
```
|
||||
[Interface]
|
||||
PrivateKey = gG...Y3s=
|
||||
Address = 10.0.0.1/32
|
||||
ListenPort = 51820
|
||||
# Jc лучше брать в интервале [3,10], Jmin = 100, Jmax = 1000,
|
||||
Jc = 3
|
||||
Jmin = 100
|
||||
Jmax = 1000
|
||||
# Parameters below will not work with the existing WireGuarg implementation.
|
||||
# Use if your peer running Amnesia-WG
|
||||
# S1 = 324
|
||||
# S2 = 452
|
||||
# H1 = 25
|
||||
|
||||
# IP masquerading
|
||||
PreUp = iptables -t nat -A POSTROUTING ! -o %i -j MASQUERADE
|
||||
# Firewall wg peers from other hosts
|
||||
PreUp = iptables -A FORWARD -o %i -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
PreUp = iptables -A FORWARD -o %i -j REJECT
|
||||
|
||||
# Remote settings for my workstation
|
||||
[Peer]
|
||||
PublicKey = wx...U=
|
||||
AllowedIPs = 10.0.0.2/32
|
||||
# An IP address to check peer connectivity (specific to this repo)
|
||||
TestIP = 10.0.0.2
|
||||
# Your existing Wireguard server
|
||||
Endpoint=xx.xx.xx.xx:51820
|
||||
PersistentKeepalive = 25
|
||||
|
||||
```
|
||||
Submodule
+1
Submodule amnezia-wg added at c493b95f66.
@@ -0,0 +1,17 @@
|
||||
version: '3'
|
||||
services:
|
||||
wireguard:
|
||||
image: awg-docker
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
# network_mode: host
|
||||
sysctls:
|
||||
net.ipv4.conf.all.src_valid_mark: 1
|
||||
ports:
|
||||
- 51820:51820/udp
|
||||
volumes:
|
||||
- ./wg:/etc/wireguard
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#! /bin/bash
|
||||
|
||||
|
||||
# Container healthcheck script
|
||||
mapfile -t wg_elements < <( /usr/bin/wg )
|
||||
|
||||
if [ ${#wg_elements[@]} -gt 5 ]; then
|
||||
for key in "${!wg_elements[@]}"; do
|
||||
if [[ ${wg_elements[$key]} =~ "peer:" ]] || [[ ${wg_elements[$key]} =~ "handshake:" ]]; then
|
||||
printf " ${wg_elements[$key]}:";
|
||||
fi
|
||||
done
|
||||
exit 0;
|
||||
else
|
||||
echo "wg not started"
|
||||
exit 1;
|
||||
fi
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
#! /bin/bash
|
||||
|
||||
# create /dev/net/tun if it does not exist
|
||||
if [[ ! -c /dev/net/tun ]]; then
|
||||
mkdir -p /dev/net && mknod /dev/net/tun c 10 200
|
||||
fi
|
||||
Executable
+406
@@ -0,0 +1,406 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
#
|
||||
|
||||
set -e -o pipefail
|
||||
shopt -s extglob
|
||||
export LC_ALL=C
|
||||
|
||||
SELF="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
export PATH="${SELF%/*}:$PATH"
|
||||
|
||||
WG_CONFIG=""
|
||||
INTERFACE=""
|
||||
ADDRESSES=( )
|
||||
TEST_ADDRESSES=( )
|
||||
MTU=""
|
||||
DNS=( )
|
||||
DNS_SEARCH=( )
|
||||
TABLE=""
|
||||
PRE_UP=( )
|
||||
POST_UP=( )
|
||||
PRE_DOWN=( )
|
||||
POST_DOWN=( )
|
||||
SAVE_CONFIG=0
|
||||
CONFIG_FILE=""
|
||||
PROGRAM="${0##*/}"
|
||||
ARGS=( "$@" )
|
||||
|
||||
cmd() {
|
||||
echo "[#] $*" >&2
|
||||
"$@"
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "$PROGRAM: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
parse_options() {
|
||||
local interface_section=0 line key value stripped v
|
||||
CONFIG_FILE="$1"
|
||||
[[ $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"
|
||||
CONFIG_FILE="$(readlink -f "$CONFIG_FILE")"
|
||||
((($(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
|
||||
stripped="${line%%\#*}"
|
||||
key="${stripped%%=*}"; key="${key##*([[:space:]])}"; key="${key%%*([[:space:]])}"
|
||||
value="${stripped#*=}"; value="${value##*([[:space:]])}"; value="${value%%*([[:space:]])}"
|
||||
[[ $key == "["* ]] && interface_section=0
|
||||
[[ $key == "[Interface]" ]] && interface_section=1
|
||||
|
||||
if [[ $interface_section -eq 0 ]]; then
|
||||
case "$key" in
|
||||
TestIP) TEST_ADDRESSES+=( ${value//,/ } ); continue ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [[ $interface_section -eq 1 ]]; then
|
||||
case "$key" in
|
||||
Address) ADDRESSES+=( ${value//,/ } ); continue ;;
|
||||
MTU) MTU="$value"; continue ;;
|
||||
DNS) for v in ${value//,/ }; do
|
||||
[[ $v =~ (^[0-9.]+$)|(^.*:.*$) ]] && DNS+=( $v ) || DNS_SEARCH+=( $v )
|
||||
done; continue ;;
|
||||
Table) TABLE="$value"; continue ;;
|
||||
PreUp) PRE_UP+=( "$value" ); continue ;;
|
||||
PreDown) PRE_DOWN+=( "$value" ); continue ;;
|
||||
PostUp) POST_UP+=( "$value" ); continue ;;
|
||||
PostDown) POST_DOWN+=( "$value" ); continue ;;
|
||||
SaveConfig) read_bool SAVE_CONFIG "$value"; continue ;;
|
||||
esac
|
||||
fi
|
||||
WG_CONFIG+="$line"$'\n'
|
||||
done < "$CONFIG_FILE"
|
||||
shopt -u nocasematch
|
||||
}
|
||||
|
||||
read_bool() {
|
||||
case "$2" in
|
||||
true) printf -v "$1" 1 ;;
|
||||
false) printf -v "$1" 0 ;;
|
||||
*) die "\`$2' is neither true nor false"
|
||||
esac
|
||||
}
|
||||
|
||||
auto_su() {
|
||||
[[ $UID == 0 ]] || exec sudo -p "$PROGRAM must be run as root. Please enter the password for %u to continue: " -- "$BASH" -- "$SELF" "${ARGS[@]}"
|
||||
}
|
||||
|
||||
add_if() {
|
||||
amnezia-wg $INTERFACE
|
||||
# local ret
|
||||
# if ! 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." >&2
|
||||
# cmd "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" "$INTERFACE"
|
||||
# fi
|
||||
}
|
||||
|
||||
del_if() {
|
||||
local table
|
||||
[[ $HAVE_SET_DNS -eq 0 ]] || unset_dns
|
||||
[[ $HAVE_SET_FIREWALL -eq 0 ]] || remove_firewall
|
||||
if [[ -z $TABLE || $TABLE == auto ]] && get_fwmark table && [[ $(wg show "$INTERFACE" allowed-ips) =~ /0(\ |$'\n'|$) ]]; then
|
||||
while [[ $(ip -4 rule show 2>/dev/null) == *"lookup $table"* ]]; do
|
||||
cmd ip -4 rule delete table $table
|
||||
done
|
||||
while [[ $(ip -4 rule show 2>/dev/null) == *"from all lookup main suppress_prefixlength 0"* ]]; do
|
||||
cmd ip -4 rule delete table main suppress_prefixlength 0
|
||||
done
|
||||
while [[ $(ip -6 rule show 2>/dev/null) == *"lookup $table"* ]]; do
|
||||
cmd ip -6 rule delete table $table
|
||||
done
|
||||
while [[ $(ip -6 rule show 2>/dev/null) == *"from all lookup main suppress_prefixlength 0"* ]]; do
|
||||
cmd ip -6 rule delete table main suppress_prefixlength 0
|
||||
done
|
||||
fi
|
||||
cmd ip link delete dev "$INTERFACE"
|
||||
}
|
||||
|
||||
add_addr() {
|
||||
local proto=-4
|
||||
[[ $1 == *:* ]] && proto=-6
|
||||
cmd ip $proto address add "$1" dev "$INTERFACE"
|
||||
}
|
||||
|
||||
set_mtu_up() {
|
||||
local mtu=0 endpoint output
|
||||
if [[ -n $MTU ]]; then
|
||||
cmd ip link set mtu "$MTU" up dev "$INTERFACE"
|
||||
return
|
||||
fi
|
||||
while read -r _ endpoint; do
|
||||
[[ $endpoint =~ ^\[?([a-z0-9:.]+)\]?:[0-9]+$ ]] || continue
|
||||
output="$(ip route get "${BASH_REMATCH[1]}" || true)"
|
||||
[[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
|
||||
done < <(wg show "$INTERFACE" endpoints)
|
||||
if [[ $mtu -eq 0 ]]; then
|
||||
read -r output < <(ip route show default || true) || true
|
||||
[[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
|
||||
fi
|
||||
[[ $mtu -gt 0 ]] || mtu=1500
|
||||
cmd ip link set mtu $(( mtu - 80 )) up dev "$INTERFACE"
|
||||
}
|
||||
|
||||
resolvconf_iface_prefix() {
|
||||
[[ -f /etc/resolvconf/interface-order ]] || return 0
|
||||
local iface
|
||||
while read -r iface; do
|
||||
[[ $iface =~ ^([A-Za-z0-9-]+)\*$ ]] || continue
|
||||
echo "${BASH_REMATCH[1]}." && return 0
|
||||
done < /etc/resolvconf/interface-order
|
||||
}
|
||||
|
||||
HAVE_SET_DNS=0
|
||||
set_dns() {
|
||||
[[ ${#DNS[@]} -gt 0 ]] || return 0
|
||||
{ printf 'nameserver %s\n' "${DNS[@]}"
|
||||
[[ ${#DNS_SEARCH[@]} -eq 0 ]] || printf 'search %s\n' "${DNS_SEARCH[*]}"
|
||||
} | cmd resolvconf -a "$(resolvconf_iface_prefix)$INTERFACE" -m 0 -x
|
||||
HAVE_SET_DNS=1
|
||||
}
|
||||
|
||||
unset_dns() {
|
||||
[[ ${#DNS[@]} -gt 0 ]] || return 0
|
||||
cmd resolvconf -d "$(resolvconf_iface_prefix)$INTERFACE" -f
|
||||
}
|
||||
|
||||
add_route() {
|
||||
local proto=-4
|
||||
[[ $1 == *:* ]] && proto=-6
|
||||
[[ $TABLE != off ]] || return 0
|
||||
|
||||
if [[ -n $TABLE && $TABLE != auto ]]; then
|
||||
cmd ip $proto route add "$1" dev "$INTERFACE" table "$TABLE"
|
||||
elif [[ $1 == */0 ]]; then
|
||||
add_default "$1"
|
||||
else
|
||||
[[ -n $(ip $proto route show dev "$INTERFACE" match "$1" 2>/dev/null) ]] || cmd ip $proto route add "$1" dev "$INTERFACE"
|
||||
fi
|
||||
}
|
||||
|
||||
get_fwmark() {
|
||||
local fwmark
|
||||
fwmark="$(wg show "$INTERFACE" fwmark)" || return 1
|
||||
[[ -n $fwmark && $fwmark != off ]] || return 1
|
||||
printf -v "$1" "%d" "$fwmark"
|
||||
return 0
|
||||
}
|
||||
|
||||
remove_firewall() {
|
||||
if type -p nft >/dev/null; then
|
||||
local table nftcmd
|
||||
while read -r table; do
|
||||
[[ $table == *" wg-quick-$INTERFACE" ]] && printf -v nftcmd '%sdelete %s\n' "$nftcmd" "$table"
|
||||
done < <(nft list tables 2>/dev/null)
|
||||
[[ -z $nftcmd ]] || cmd nft -f <(echo -n "$nftcmd")
|
||||
fi
|
||||
if type -p iptables >/dev/null; then
|
||||
local line iptables found restore
|
||||
for iptables in iptables ip6tables; do
|
||||
restore="" found=0
|
||||
while read -r line; do
|
||||
[[ $line == "*"* || $line == COMMIT || $line == "-A "*"-m comment --comment \"wg-quick(8) rule for $INTERFACE\""* ]] || continue
|
||||
[[ $line == "-A"* ]] && found=1
|
||||
printf -v restore '%s%s\n' "$restore" "${line/#-A/-D}"
|
||||
done < <($iptables-save 2>/dev/null)
|
||||
[[ $found -ne 1 ]] || echo -n "$restore" | cmd $iptables-restore -n
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
HAVE_SET_FIREWALL=0
|
||||
add_default() {
|
||||
local table line
|
||||
if ! get_fwmark table; then
|
||||
table=51820
|
||||
while [[ -n $(ip -4 route show table $table 2>/dev/null) || -n $(ip -6 route show table $table 2>/dev/null) ]]; do
|
||||
((table++))
|
||||
done
|
||||
cmd wg set "$INTERFACE" fwmark $table
|
||||
fi
|
||||
local proto=-4 iptables=iptables pf=ip
|
||||
[[ $1 == *:* ]] && proto=-6 iptables=ip6tables pf=ip6
|
||||
cmd ip $proto rule add not fwmark $table table $table
|
||||
cmd ip $proto rule add table main suppress_prefixlength 0
|
||||
cmd ip $proto route add "$1" dev "$INTERFACE" table $table
|
||||
|
||||
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"
|
||||
printf -v nftcmd '%sadd chain %s %s postmangle { type filter hook postrouting priority -150; }\n' "$nftcmd" "$pf" "$nftable"
|
||||
while read -r line; do
|
||||
[[ $line =~ .*inet6?\ ([0-9a-f:.]+)/[0-9]+.* ]] || continue
|
||||
printf -v restore '%s-I PREROUTING ! -i %s -d %s -m addrtype ! --src-type LOCAL -j DROP %s\n' "$restore" "$INTERFACE" "${BASH_REMATCH[1]}" "$marker"
|
||||
printf -v nftcmd '%sadd rule %s %s preraw iifname != "%s" %s daddr %s fib saddr type != local drop\n' "$nftcmd" "$pf" "$nftable" "$INTERFACE" "$pf" "${BASH_REMATCH[1]}"
|
||||
done < <(ip -o $proto addr show dev "$INTERFACE" 2>/dev/null)
|
||||
printf -v restore '%sCOMMIT\n*mangle\n-I POSTROUTING -m mark --mark %d -p udp -j CONNMARK --save-mark %s\n-I PREROUTING -p udp -j CONNMARK --restore-mark %s\nCOMMIT\n' "$restore" $table "$marker" "$marker"
|
||||
printf -v nftcmd '%sadd rule %s %s postmangle meta l4proto udp mark %d ct mark set mark \n' "$nftcmd" "$pf" "$nftable" $table
|
||||
printf -v nftcmd '%sadd rule %s %s premangle meta l4proto udp meta mark set ct mark \n' "$nftcmd" "$pf" "$nftable"
|
||||
[[ $proto == -4 ]] && cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1
|
||||
if type -p nft >/dev/null; then
|
||||
cmd nft -f <(echo -n "$nftcmd")
|
||||
else
|
||||
echo -n "$restore" | cmd $iptables-restore -n
|
||||
fi
|
||||
HAVE_SET_FIREWALL=1
|
||||
return 0
|
||||
}
|
||||
|
||||
set_config() {
|
||||
cmd wg setconf "$INTERFACE" <(echo "$WG_CONFIG")
|
||||
}
|
||||
|
||||
save_config() {
|
||||
local old_umask new_config current_config address cmd
|
||||
[[ $(ip -all -brief address show dev "$INTERFACE") =~ ^$INTERFACE\ +\ [A-Z]+\ +(.+)$ ]] || true
|
||||
new_config=$'[Interface]\n'
|
||||
for address in ${BASH_REMATCH[1]}; do
|
||||
new_config+="Address = $address"$'\n'
|
||||
done
|
||||
while read -r address; do
|
||||
[[ $address =~ ^nameserver\ ([a-zA-Z0-9_=+:%.-]+)$ ]] && new_config+="DNS = ${BASH_REMATCH[1]}"$'\n'
|
||||
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'
|
||||
[[ $SAVE_CONFIG -eq 0 ]] || new_config+=$'SaveConfig = true\n'
|
||||
for cmd in "${PRE_UP[@]}"; do
|
||||
new_config+="PreUp = $cmd"$'\n'
|
||||
done
|
||||
for cmd in "${POST_UP[@]}"; do
|
||||
new_config+="PostUp = $cmd"$'\n'
|
||||
done
|
||||
for cmd in "${PRE_DOWN[@]}"; do
|
||||
new_config+="PreDown = $cmd"$'\n'
|
||||
done
|
||||
for cmd in "${POST_DOWN[@]}"; do
|
||||
new_config+="PostDown = $cmd"$'\n'
|
||||
done
|
||||
old_umask="$(umask)"
|
||||
umask 077
|
||||
current_config="$(cmd wg showconf "$INTERFACE")"
|
||||
trap 'rm -f "$CONFIG_FILE.tmp"; exit' INT TERM EXIT
|
||||
echo "${current_config/\[Interface\]$'\n'/$new_config}" > "$CONFIG_FILE.tmp" || die "Could not write configuration file"
|
||||
sync "$CONFIG_FILE.tmp"
|
||||
mv "$CONFIG_FILE.tmp" "$CONFIG_FILE" || die "Could not move configuration file"
|
||||
trap - INT TERM EXIT
|
||||
umask "$old_umask"
|
||||
}
|
||||
|
||||
execute_hooks() {
|
||||
local hook
|
||||
for hook in "$@"; do
|
||||
hook="${hook//%i/$INTERFACE}"
|
||||
echo "[#] $hook" >&2
|
||||
(eval "$hook")
|
||||
done
|
||||
}
|
||||
|
||||
cmd_usage() {
|
||||
cat >&2 <<-_EOF
|
||||
Usage: $PROGRAM [ up | down | save | strip ] [ 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
|
||||
configuration found at /etc/wireguard/INTERFACE.conf. It is to be readable
|
||||
by wg(8)'s \`setconf' sub-command, with the exception of the following additions
|
||||
to the [Interface] section, which are handled by $PROGRAM:
|
||||
|
||||
- Address: may be specified one or more times and contains one or more
|
||||
IP addresses (with an optional CIDR mask) to be set for the interface.
|
||||
- DNS: an optional DNS server to use while the device is up.
|
||||
- MTU: an optional MTU for the interface; if unspecified, auto-calculated.
|
||||
- Table: an optional routing table to which routes will be added; if
|
||||
unspecified or \`auto', the default table is used. If \`off', no routes
|
||||
are added.
|
||||
- PreUp, PostUp, PreDown, PostDown: script snippets which will be executed
|
||||
by bash(1) at the corresponding phases of the link, most commonly used
|
||||
to configure DNS. The string \`%i' is expanded to INTERFACE.
|
||||
- SaveConfig: if set to \`true', the configuration is saved from the current
|
||||
state of the interface upon shutdown.
|
||||
|
||||
See wg-quick(8) for more info and examples.
|
||||
_EOF
|
||||
}
|
||||
|
||||
cmd_up() {
|
||||
local i
|
||||
[[ -z $(ip link show dev "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists"
|
||||
trap 'del_if; exit' INT TERM EXIT
|
||||
add_if
|
||||
execute_hooks "${PRE_UP[@]}"
|
||||
set_config
|
||||
for i in "${ADDRESSES[@]}"; do
|
||||
add_addr "$i"
|
||||
done
|
||||
set_mtu_up
|
||||
set_dns
|
||||
|
||||
for i in $(while read -r _ i; do for i in $i; do [[ $i =~ ^[0-9a-z:.]+/[0-9]+$ ]] && echo "$i"; done; done < <(wg show "$INTERFACE" allowed-ips) | sort -nr -k 2 -t /); do
|
||||
add_route "$i"
|
||||
done
|
||||
execute_hooks "${POST_UP[@]}"
|
||||
cmd wg
|
||||
cmd ip addr
|
||||
cmd ip -4 route
|
||||
cmd wg show "$INTERFACE"
|
||||
for i in "${TEST_ADDRESSES[@]}"; do
|
||||
cmd ping -4 -q -c 1 "$i" || true
|
||||
done
|
||||
trap - INT TERM EXIT
|
||||
}
|
||||
|
||||
cmd_down() {
|
||||
[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
|
||||
execute_hooks "${PRE_DOWN[@]}"
|
||||
[[ $SAVE_CONFIG -eq 0 ]] || save_config
|
||||
del_if
|
||||
unset_dns || true
|
||||
remove_firewall || true
|
||||
execute_hooks "${POST_DOWN[@]}"
|
||||
}
|
||||
|
||||
cmd_save() {
|
||||
[[ " $(wg show interfaces) " == *" $INTERFACE "* ]] || die "\`$INTERFACE' is not a WireGuard interface"
|
||||
save_config
|
||||
}
|
||||
|
||||
cmd_strip() {
|
||||
echo "$WG_CONFIG"
|
||||
}
|
||||
|
||||
# ~~ function override insertion point ~~
|
||||
|
||||
if [[ $# -eq 1 && ( $1 == --help || $1 == -h || $1 == help ) ]]; then
|
||||
cmd_usage
|
||||
elif [[ $# -eq 2 && $1 == up ]]; then
|
||||
auto_su
|
||||
parse_options "$2"
|
||||
cmd_up
|
||||
elif [[ $# -eq 2 && $1 == down ]]; then
|
||||
auto_su
|
||||
parse_options "$2"
|
||||
cmd_down
|
||||
elif [[ $# -eq 2 && $1 == save ]]; then
|
||||
auto_su
|
||||
parse_options "$2"
|
||||
cmd_save
|
||||
elif [[ $# -eq 2 && $1 == strip ]]; then
|
||||
auto_su
|
||||
parse_options "$2"
|
||||
cmd_strip
|
||||
else
|
||||
cmd_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/sbin/openrc-run
|
||||
|
||||
description="WireGuard Quick Up"
|
||||
|
||||
depend() {
|
||||
need localmount
|
||||
need net
|
||||
}
|
||||
|
||||
start_pre()
|
||||
{
|
||||
/data/pre_up.sh
|
||||
}
|
||||
|
||||
start() {
|
||||
for file in $(grep '\[Interface\]' /etc/wireguard/*.conf -l 2>/dev/null); do
|
||||
interface=$(basename $file .conf)
|
||||
ebegin "Starting WireGuard interface $interface"
|
||||
/data/wg_quick.sh up $file
|
||||
done
|
||||
eend 0
|
||||
}
|
||||
|
||||
stop() {
|
||||
for file in $(grep '\[Interface\]' /etc/wireguard/*.conf -l 2>/dev/null); do
|
||||
interface=$(basename $file .conf)
|
||||
ebegin "Stopping WireGuard interface $interface"
|
||||
/data/wg_quick.sh down $file
|
||||
done
|
||||
eend 0
|
||||
}
|
||||
Reference in new issue
Block a user