164 lines
5.0 KiB
YAML
164 lines
5.0 KiB
YAML
---
|
|
- name: 安装 WireGuard 与 FRR
|
|
ansible.builtin.apt:
|
|
name: [wireguard-tools, frr, iptables]
|
|
state: present
|
|
update_cache: true
|
|
cache_valid_time: 3600
|
|
register: packages
|
|
retries: 3
|
|
delay: 5
|
|
until: packages is succeeded
|
|
|
|
- name: 创建 WireGuard 受限目录
|
|
ansible.builtin.file:
|
|
path: /etc/wireguard
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: '0700'
|
|
|
|
- name: 在站点本机生成私钥,永不复制到控制机
|
|
ansible.builtin.shell: 'umask 077; wg genkey > /etc/wireguard/{{ wg_interface }}.key'
|
|
args:
|
|
creates: '/etc/wireguard/{{ wg_interface }}.key'
|
|
no_log: true
|
|
|
|
- name: 检查现有私钥
|
|
ansible.builtin.stat:
|
|
path: '/etc/wireguard/{{ wg_interface }}.key'
|
|
register: wg_key_file
|
|
|
|
- name: 读取可交换的公钥
|
|
ansible.builtin.shell: 'wg pubkey < /etc/wireguard/{{ wg_interface }}.key'
|
|
register: wg_public_key
|
|
changed_when: false
|
|
check_mode: false
|
|
when: wg_key_file.stat.exists
|
|
|
|
- name: 启用 BGP daemon,保留其他协议
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/frr/daemons
|
|
regexp: '^bgpd='
|
|
line: bgpd=yes
|
|
notify: 重载 FRR daemons
|
|
when: not ansible_check_mode or not packages.changed
|
|
|
|
- name: 确保 FRR 运行
|
|
ansible.builtin.systemd_service:
|
|
name: frr
|
|
enabled: true
|
|
state: started
|
|
when: not ansible_check_mode
|
|
|
|
- name: 配置 DN42 路由器地址
|
|
ansible.builtin.include_tasks: dn42-loopback.yml
|
|
when: bgp_export6 is defined
|
|
|
|
- name: 开启 IPv4 转发
|
|
ansible.posix.sysctl:
|
|
name: net.ipv4.ip_forward
|
|
value: '1'
|
|
sysctl_file: /etc/sysctl.d/90-oci-wireguard.conf
|
|
sysctl_set: true
|
|
|
|
- name: 安装专用防火墙规则脚本
|
|
ansible.builtin.template:
|
|
src: firewall.sh.j2
|
|
dest: /usr/local/sbin/oci-wg-firewall
|
|
owner: root
|
|
group: root
|
|
mode: '0755'
|
|
notify: 刷新专用防火墙
|
|
|
|
- name: 安装防火墙启动单元
|
|
ansible.builtin.copy:
|
|
dest: /etc/systemd/system/oci-wg-firewall.service
|
|
mode: '0644'
|
|
content: |
|
|
[Unit]
|
|
Description=OCI WireGuard scoped forwarding (no NAT)
|
|
After=network-pre.target
|
|
Before=wg-quick@{{ wg_interface }}.service
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/local/sbin/oci-wg-firewall
|
|
RemainAfterExit=yes
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
notify: 刷新专用防火墙
|
|
|
|
- name: 启动防火墙规则
|
|
ansible.builtin.systemd_service:
|
|
name: oci-wg-firewall
|
|
daemon_reload: true
|
|
enabled: true
|
|
state: started
|
|
when: not ansible_check_mode
|
|
|
|
- name: 写入只含公钥的隧道配置
|
|
ansible.builtin.template:
|
|
src: wg.conf.j2
|
|
dest: '/etc/wireguard/{{ wg_interface }}.conf'
|
|
owner: root
|
|
group: root
|
|
mode: '0600'
|
|
when: wg_key_file.stat.exists and (hostvars[wg_peer_host].wg_key_file | default({"stat":{"exists":false}})).stat.exists
|
|
notify: 重启 WireGuard
|
|
|
|
- name: 启动 WireGuard
|
|
ansible.builtin.systemd_service:
|
|
name: 'wg-quick@{{ wg_interface }}'
|
|
enabled: true
|
|
state: started
|
|
when: not ansible_check_mode
|
|
|
|
- name: 写入受管 BGP 增量配置
|
|
ansible.builtin.template:
|
|
src: bgp.conf.j2
|
|
dest: /etc/frr/oci-wireguard.vtysh
|
|
owner: frr
|
|
group: frr
|
|
mode: '0640'
|
|
notify: 应用 BGP 增量配置
|
|
when: not ansible_check_mode or not packages.changed
|
|
|
|
- name: 先完成配置变更再验证
|
|
ansible.builtin.meta: flush_handlers
|
|
|
|
- name: 检查 WireGuard 对端握手
|
|
ansible.builtin.command: 'wg show {{ wg_interface }} latest-handshakes'
|
|
changed_when: false
|
|
register: wg_handshake
|
|
retries: 12
|
|
delay: 5
|
|
until: wg_handshake.stdout.split() | length == 2 and (wg_handshake.stdout.split()[-1] | int) > 0
|
|
when: not ansible_check_mode
|
|
|
|
- name: 验证隧道互通
|
|
ansible.builtin.command: "{{ ('ping -6 -I ' ~ wg_interface ~ ' -c 3 -W 3 ' ~ bgp_transport_peer) if bgp_transport_peer is defined else ('ping -I ' ~ wg_interface ~ ' -c 3 -W 3 ' ~ wg_peer_address) }}"
|
|
changed_when: false
|
|
when: not ansible_check_mode
|
|
|
|
- name: 验证 BGP 建邻并收到预期前缀数量
|
|
ansible.builtin.command: vtysh -c 'show bgp summary json'
|
|
changed_when: false
|
|
register: bgp_summary
|
|
retries: 12
|
|
delay: 5
|
|
until: >-
|
|
(bgp_summary.stdout | from_json).get('ipv4Unicast', {}).get('peers', {}).get(bgp_transport_peer | default(wg_peer_address), {}).get('state') == 'Established'
|
|
and (bgp_summary.stdout | from_json).get('ipv4Unicast', {}).get('peers', {}).get(bgp_transport_peer | default(wg_peer_address), {}).get('pfxRcd', 0) == bgp_import | length
|
|
when: not ansible_check_mode
|
|
|
|
- name: 验证 IPv6 iBGP 建邻与前缀
|
|
ansible.builtin.command: vtysh -c 'show bgp summary json'
|
|
changed_when: false
|
|
register: bgp_summary6
|
|
retries: 12
|
|
delay: 5
|
|
until: >-
|
|
(bgp_summary6.stdout | from_json).get('ipv6Unicast', {}).get('peers', {}).get(bgp_transport_peer | default(wg_peer_ipv6), {}).get('state') == 'Established'
|
|
and (bgp_summary6.stdout | from_json).get('ipv6Unicast', {}).get('peers', {}).get(bgp_transport_peer | default(wg_peer_ipv6), {}).get('pfxRcd', 0) == bgp_import6 | length
|
|
when: not ansible_check_mode and bgp_import6 is defined
|