内网 WireGuard 不支持域名地址,难不成每次都手动开启关闭吗?有没有优雅点的方式?

271 天前
 PatrickLe
2377 次点击
所在节点    宽带症候群
18 条回复
sky96111
271 天前
怎么可能不支持域名地址?你指的是内网域名 endpoint 吗?
terrancesiu
271 天前
支持域名,不支持动态域名
ghostwwg
271 天前
检查对方 A 记录是否更新,更新即重启 wg
liuweisj
271 天前
/usr/bin/wg set xxx peer xxx endpoint “xxx"
liuweisj
271 天前
@liuweisj 建个定时任务一直执行这个命令就好了 上边的 endpoint 写域名
PatrickLe
271 天前
@sky96111 我用的威联通路由器,自带了 DDNS 系统,我说的域名指的就是这个,WG 也是部署在威联通路由上的
PatrickLe
271 天前
@liuweisj 大哥麻烦说细一点?还是不会啊😂
ranaanna
271 天前
@PatrickLe @ghostwwg 或者定期检查 wg 的最近握手时间,如果握手时间离当前时间超过上限就重启,比如

#!/bin/bash
a = $( wg show wg latest-handshakes | awk '{print $2}' )
b = $( date +%s)
if [ ("$b" - "$a") -gt 300 ]; then
wg-quick down wg0 && wg-quick up wg0 或者 systemctl restart wg-quick@wg0 之类
fi
ranaanna
271 天前
@PatrickLe @ghostwwg 续上,如果你的胃联通支持 bash

#!/bin/bash
REMOTEIP = $( nslookup your.domain.name | tail -n +3 | sed -n 's/Address:\s*//p' )
if [ ! -e /tmp/remoteip ]; then
echo "${REMOTEIP}" > /tmp/remoteip
fi
OLDIP=`cat /tmp/remoteip`
if [ "$REMOTEIP" != "$OLDIP" ]; then
echo "${REMOTEIP}" > /tmp/remoteip
wg-quick down wg0 && wg-quick up wg0
fi
ranaanna
271 天前
@PatrickLe 续上,以及 crontab
dude4
271 天前
如果是用 openwrt 作为 WG 的网关路由,在 21.02 之后的版本里,官方(注意是官方,第三方的譬如 lean 的库不知道有没有)自带 peer 动态域名保活脚本,位置在
`/usr/bin/wireguard_watchdog`

自己看看就知道是什么原理了
lovelylain
271 天前
evalfun
270 天前
写个 wg 保活脚本,ping 不通对端了就重启隧道
#!/bin/sh
ping -W1 -c 3 10.0.7.1 > /dev/null
if [ $? -eq 0 ]
then
date >> /tmp/wg-check
echo "wireguard connection check success." >> /tmp/wg-check
else
date >> /tmp/wg-check
echo "wireguard connection check failure. restart wireguard" >> /tmp/wg-check
ifdown wg0
ifup wg0

fi
lovelylain
270 天前
@evalfun 太粗暴了,要知道可能连多个 peer ,而多个 peer 不是同时换 ip ,你重启接口全部影响了
lpdswing
268 天前
肯定支持域名啊,映射一下,配置都不用改
JerryYuan
268 天前
如 12#所说,改过一版,基本只替换了 luci 读配置那些东西。
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2018 Aleksandr V. Piskunov <aleksandr.v.piskunov@gmail.com>.
# Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
#
# This watchdog script tries to re-resolve hostnames for inactive WireGuard peers.
# Use it for peers with a frequently changing dynamic IP.
# persistent_keepalive must be set, recommended value is 25 seconds.
#
# Run this script from cron every minute:
# echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root

check_peer_activity() {
local iface=$1
local public_key=$2
local endpoint_host=$3
local endpoint_port=$4
local persistent_keepalive
local last_handshake
local idle_seconds

persistent_keepalive=$(wg show ${iface} persistent-keepalive | grep ${public_key} | awk '{print $2}')

echo "checking $1 $2 $3 $4..."

# only process peers with endpoints and keepalive set
echo 1
[ -z ${endpoint_host} ] && return 0;
echo 2
[ -z ${persistent_keepalive} -o ${persistent_keepalive} = "off" ] && return 0;
echo 3

# skip IP addresses
# check taken from packages/net/ddns-scripts/files/dynamic_dns_functions.sh
local IPV4_REGEX="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
local IPV6_REGEX="\(\([0-9A-Fa-f]\{1,4\}:\)\{1,\}\)\(\([0-9A-Fa-f]\{1,4\}\)\{0,1\}\)\(\(:[0-9A-Fa-f]\{1,4\}\)\{1,\}\)"
local IPV4=$(echo ${endpoint_host} | grep -m 1 -o "$IPV4_REGEX$") # do not detect ip in 0.0.0.0.example.com
local IPV6=$(echo ${endpoint_host} | grep -m 1 -o "$IPV6_REGEX")
echo 4
[ -n "${IPV4}" -o -n "${IPV6}" ] && return 0;
echo 5

# re-resolve endpoint hostname if not responding for too long
last_handshake=$(wg show ${iface} latest-handshakes | grep ${public_key} | awk '{print $2}')
[ -z ${last_handshake} ] && return 0;
idle_seconds=$(($(date +%s)-${last_handshake}))
[ ${idle_seconds} -lt 150 ] && return 0;
logger -t "wireguard_monitor" "${iface} endpoint ${endpoint_host}:${endpoint_port} is not responding for ${idle_seconds} seconds, trying to re-resolve hostname"
wg set ${iface} peer ${public_key} endpoint "${endpoint_host}:${endpoint_port}"
}

# query ubus for all active wireguard interfaces
wg_ifaces=$(wg show interfaces | awk '{print $1}' | tr '\n' ' ')

# check every peer in every active wireguard interface
for iface in $wg_ifaces; do
config_file="/etc/wireguard/${iface}.conf"
# parsing wireguard config file
eval `cat $config_file | tr -d ' ' |awk -F '=' '
BEGIN {peer_index = 0;status = 0;}
# close previous peer section
status==1 && $1 ~ /^\[/ {status = 0;}
# open new peer section
status==0 && $1 == "[Peer]" {status = 1;peer_index++;}
# parse PublicKey in Peer section
status==1 && $1 == "PublicKey" {public_key = \$0;sub(/PublicKey=/, "", public_key);printf("public_key%d=%s\n", peer_index, public_key);}
# parse Endpoint in Peer section
status==1 && $1 == "Endpoint" {printf("endpoint%d=%s\n", peer_index, $2);}
END {printf("peer_count=%d\n",peer_index)}'`

for ((i = 1; i <= $peer_count; i++)); do
public_key_var="public_key$i"
endpoint_var="endpoint$i"
public_key="${!public_key_var}"
endpoint="${!endpoint_var}"

endpoint_host=`echo "${endpoint}"|awk -F '[:]' '{print $1}'`
endpoint_port=`echo "${endpoint}"|awk -F '[:]' '{print $2}'`
check_peer_activity "${iface}" "${public_key}" "${endpoint_host}" "${endpoint_port}"
done
done
bmy001
267 天前
See: https://wiki.archlinux.org/title/WireGuard

After resolving a server's domain, WireGuard will not check for changes in DNS again.
If the WireGuard server is frequently changing its IP-address due DHCP, Dyndns, IPv6, etc., any WireGuard client is going to lose its connection, until its endpoint is updated via something like wg set "$INTERFACE" peer "$PUBLIC_KEY" endpoint "$ENDPOINT".
Also be aware, if the endpoint is ever going to change its address (for example when moving to a new provider/datacenter), just updating DNS will not be enough, so periodically running reresolve-dns might make sense on any DNS-based setup.
Luckily, wireguard-tools provides an example script /usr/share/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh, that parses WG configuration files and automatically resets the endpoint address.
One needs to run the /usr/share/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh /etc/wireguard/wg.conf periodically to recover from an endpoint that has changed its IP.
One way of doing so is by updating all WireGuard endpoints once every thirty seconds[6] via a systemd timer:

/etc/systemd/system/wireguard_reresolve-dns.timer

[Unit]
Description=Periodically reresolve DNS of all WireGuard endpoints

[Timer]
OnCalendar=*:*:0/30

[Install]
WantedBy=timers.target


/etc/systemd/system/wireguard_reresolve-dns.service

[Unit]
Description=Reresolve DNS of all WireGuard endpoints
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'for i in /etc/wireguard/*.conf; do /usr/share/doc/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh "$i"; done'

Afterwards enable and start wireguard_reresolve-dns.timer
flynaj
265 天前
openwrt 有专门自动化 wireguard 的软件 unetd ,
你安装 luci-proto-unet 后使用,使用方法 https://openwrt.org/docs/techref/unetd
。小白还是建议上 zerotier.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1028210

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX