V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
PatrickLe
V2EX  ›  宽带症候群

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

  •  
  •   PatrickLe · 266 天前 · 2364 次点击
    这是一个创建于 266 天前的主题,其中的信息可能已经有所发展或是发生改变。
    18 条回复    2024-04-04 10:49:37 +08:00
    sky96111
        1
    sky96111  
       266 天前 via Android
    怎么可能不支持域名地址?你指的是内网域名 endpoint 吗?
    terrancesiu
        2
    terrancesiu  
       266 天前 via iPhone
    支持域名,不支持动态域名
    ghostwwg
        3
    ghostwwg  
       266 天前
    检查对方 A 记录是否更新,更新即重启 wg
    liuweisj
        4
    liuweisj  
       266 天前   ❤️ 2
    /usr/bin/wg set xxx peer xxx endpoint “xxx"
    liuweisj
        5
    liuweisj  
       266 天前
    @liuweisj 建个定时任务一直执行这个命令就好了 上边的 endpoint 写域名
    PatrickLe
        6
    PatrickLe  
    OP
       266 天前
    @sky96111 我用的威联通路由器,自带了 DDNS 系统,我说的域名指的就是这个,WG 也是部署在威联通路由上的
    PatrickLe
        7
    PatrickLe  
    OP
       266 天前
    @liuweisj 大哥麻烦说细一点?还是不会啊😂
    ranaanna
        8
    ranaanna  
       266 天前
    @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
        9
    ranaanna  
       266 天前
    @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
        10
    ranaanna  
       266 天前
    @PatrickLe 续上,以及 crontab
    dude4
        11
    dude4  
       266 天前
    如果是用 openwrt 作为 WG 的网关路由,在 21.02 之后的版本里,官方(注意是官方,第三方的譬如 lean 的库不知道有没有)自带 peer 动态域名保活脚本,位置在
    `/usr/bin/wireguard_watchdog`

    自己看看就知道是什么原理了
    evalfun
        13
    evalfun  
       265 天前
    写个 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
        14
    lovelylain  
       265 天前 via Android
    @evalfun 太粗暴了,要知道可能连多个 peer ,而多个 peer 不是同时换 ip ,你重启接口全部影响了
    lpdswing
        15
    lpdswing  
       263 天前
    肯定支持域名啊,映射一下,配置都不用改
    JerryYuan
        16
    JerryYuan  
       263 天前 via Android
    如 12#所说,改过一版,基本只替换了 luci 读配置那些东西。
    #!/bin/bash
    # SPDX-License-Identifier: GPL-2.0
    #
    # Copyright (C) 2018 Aleksandr V. Piskunov <[email protected]>.
    # Copyright (C) 2015-2018 Jason A. Donenfeld <[email protected]>. 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
        17
    bmy001  
       262 天前
    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
        18
    flynaj  
       260 天前 via Android
    openwrt 有专门自动化 wireguard 的软件 unetd ,
    你安装 luci-proto-unet 后使用,使用方法 https://openwrt.org/docs/techref/unetd
    。小白还是建议上 zerotier.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2300 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 01:06 · PVG 09:06 · LAX 17:06 · JFK 20:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.