feat(vpn-overlay): dynamic Endpoint switching and WireGuard keys generation

- Support dynamic AllowedIPs and Endpoint based on enable_vless
- Fix wg1 -> wg0 in iptables rules
- Update config files
- Support dynamic WireGuard keys generation in gen_wireguard_keys.sh
This commit is contained in:
Haitao Pan 2025-04-27 15:28:16 +08:00
parent 24c6ff4de4
commit d8367ba012
5 changed files with 115 additions and 25 deletions

View File

@ -18,6 +18,7 @@
{{ overlay_keys['keys']
| selectattr('name', 'equalto', inventory_hostname)
| list | first }}
features: "{{ overlay_data.features }}"
- name: 提取对端 peer 节点列表
set_fact:

View File

@ -6,15 +6,19 @@ DNS = 8.8.8.8
MTU = 1400
PostUp = iptables -I FORWARD -o %i -j ACCEPT
PostUp = iptables -A FORWARD -i wg1 -j ACCEPT
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o {{ current_interface }} -j MASQUERADE
PostDown = iptables -D FORWARD -o %i -j ACCEPT
PostDown = iptables -D FORWARD -i wg1 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o {{ current_interface }} -j MASQUERADE
[Peer]
PublicKey = {{ peer_public_key }}
AllowedIPs = {{ current_allowed_ips }}
{% if features.enable_vless %}
Endpoint = 127.0.0.1:51830
{% else %}
Endpoint = {{ peer_endpoint }}
{% endif %}
PersistentKeepalive = 25

View File

@ -1,21 +1,4 @@
keys:
- name: deepflow-demo
private_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
66623962303236653931333431393932336164313365656664333636316262343137333933303166
3162656332643130353739373531636564336539653561620a323032666662623864656332306130
65306165666264633738316563313439316164393030316431663265383634366165333334633131
6166623463633836350a356132353939613636336139386165303563383763363164393365383838
61393833346334386531316666373438613966313864396462373865393465343236376664643237
6364326161363433386431623963623733653736663639373162
public_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
63613935616137343434666164663963333632663266636663386536373264373234616135633631
3633393835383231363863346335366463303565373034350a623862393837373830333832336433
37323538653962373632623531366130373764313036613637646536663466336661336639393861
3561373939393765360a653036303535623865613462666534383930663939646239373435626635
64346433343064353835663936366434326262333265363837663632363966356435333363346534
6335633637363463653831366438303835633066333062653264
- name: master-1
private_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
@ -63,3 +46,21 @@ keys:
- name: global-hub
private_key: <hub2_private_key>
public_key: <hub2_public_key>
- name: deepflow-demo
private_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
36316136663466336564383766626434626338356130626537663163373530326332366335306136
3266383533373032623366396139653063626338646237310a353439346238653832646437313663
62623239623761326436613833313739386662356263353338666461363438613766663962386162
3539343836623936370a313439316335346235306633333333643738333461323963313038313161
62376566626335306335623134346361326364346433626234383162616636326265356364313938
6534613330643764613733333266313365633635663138636633
public_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
32326461646138373831356335656664643737313032656134663138323439313164353766363134
6232303034663064303235303363663661326433313536660a666133616438316436306463303163
64646530633639616266396563383362306235313662373565323963633039653931376431303565
6136396164346563660a643235646232353061323463396539383266333133343532396139373035
39653262653638363930383861353262303030373332313538383362393633663562303566373737
3062336434313031613534393033616330333363613863613464

View File

@ -1,15 +1,15 @@
# 基础网络参数
wg_network: 172.16.0.0/24
wg_network: 172.16.0.0/16
bridge_network: 10.253.0.0/16
vxlan_id: 100
hub_port: 51820
# 全局功能开关
features:
enable_vxlan_between_sits: true # 是否开启 vxlan 桥接(站点接入 Hub
enable_vxlan_between_hubs: true # 是否开启 Hub 之间的 VXLAN Mesh
enable_vless: true # 是否通过 VLESS 中转 WG 流量
enable_multi_hub: true # 是否支持多 Hub 架构false 则为单 Hub star 架构)
enable_vxlan_between_sits: true # 是否开启 vxlan 桥接(站点接入 Hub
enable_vxlan_between_hubs: true # 是否开启 Hub 之间的 VXLAN Mesh
only_wireguard: false # 若为 true仅使用 WireGuard 点对点,忽略 gretap/vxlan
# WireGuard Hub 节点配置
@ -139,13 +139,14 @@ sites:
path: /xray
- name: deepflow-demo
interface: eth0
interface: wlp0s20f3
public_ip: 172.30.0.10
wg_ip: 172.30.0.10
br_ip: 10.253.253.2
local_ip: 172.30.0.10
remote_ip: 172.30.0.1
hub: hub2
public_ip: c.example.com
wireguard_peer: cn-hub
allowed_ips: "172.30.0.0/16"
vless:
enabled: true
endpoint: vless-c.example.com

View File

@ -0,0 +1,83 @@
#!/bin/bash
# scripts/gen_wireguard_keys.sh
# 支持全量或指定 name 生成 WireGuard 密钥并加密到 keys.yaml
set -euo pipefail
VAULT_PASSWORD_FILE="$HOME/.vault_password" # ✅ 正确展开用户目录
VPN_CONFIG="config/sit/vpn-overlay.yaml"
OUTPUT_FILE="config/sit/vpn-keys.yaml"
if [[ ! -f "$VAULT_PASSWORD_FILE" ]]; then
echo "ERROR: 未找到 $VAULT_PASSWORD_FILE,请创建 ~/.vault_password 保存 ansible vault 密码。" >&2
exit 1
fi
# 参数
SPECIFIC_NAME="${1:-}" # 第一个参数指定name可选
# 读取 hubs 和 sites 的 name
names=($(yq '.hubs[].name' "$VPN_CONFIG") $(yq '.sites[].name' "$VPN_CONFIG"))
# 检查是否指定 name
if [[ -n "$SPECIFIC_NAME" ]]; then
if ! printf "%s\n" "${names[@]}" | grep -q "^${SPECIFIC_NAME}$"; then
echo "ERROR: 指定的 name \"$SPECIFIC_NAME\" 不在 vpn-overlay.yaml 的 hubs 或 sites 里。" >&2
exit 1
fi
names=("$SPECIFIC_NAME")
echo "🔵 只更新指定 name: $SPECIFIC_NAME"
else
echo "🟢 全量生成所有 names: ${names[*]}"
echo "keys:" > "$OUTPUT_FILE" # 只有全量时才清空 output
fi
for name in "${names[@]}"; do
echo "生成 $name 的 WireGuard 密钥对..."
tmpdir=$(mktemp -d)
wg genkey > "$tmpdir/privatekey"
cat "$tmpdir/privatekey" | wg pubkey > "$tmpdir/publickey"
private_key_encrypted=$(ansible-vault encrypt_string --vault-password-file "$VAULT_PASSWORD_FILE" --encrypt-vault-id default "$(cat "$tmpdir/privatekey")" --name "private_key")
public_key_encrypted=$(ansible-vault encrypt_string --vault-password-file "$VAULT_PASSWORD_FILE" --encrypt-vault-id default "$(cat "$tmpdir/publickey")" --name "public_key")
if [[ -n "$SPECIFIC_NAME" ]]; then
# 只更新某个 name需要保留原有 keys.yaml
tmp_keys=$(mktemp)
# 先去掉原本存在的同名块
awk -v NAME="$name" '
BEGIN { skip=0 }
/^ - name: / {
if ($3 == NAME) { skip=1 }
else { skip=0 }
}
skip==0 { print }
' "$OUTPUT_FILE" > "$tmp_keys"
# 追加新的 key 块
{
echo " - name: $name"
echo "$private_key_encrypted" | sed 's/^/ /'
echo "$public_key_encrypted" | sed 's/^/ /'
echo ""
} >> "$tmp_keys"
mv "$tmp_keys" "$OUTPUT_FILE"
else
# 全量生成直接写
{
echo " - name: $name"
echo "$private_key_encrypted" | sed 's/^/ /'
echo "$public_key_encrypted" | sed 's/^/ /'
echo ""
} >> "$OUTPUT_FILE"
fi
rm -rf "$tmpdir"
done
echo "✅ 完成生成keys 写入到 $OUTPUT_FILE"