实习中遇到个问题,现有的openvpn配置很乱
需要重新梳理客户端和服务端的对应关系。于是写了个Ansible脚本来扫描客户端配置文件
提取出所有Client的配置文件,并生成一个对应关系报告。
已知现在机器上面所有的OpenVPN客户端配置文件都在/etc/openvpn/client/目录下。
ansible-playbook的脚本文件如下(因为我这用的服务器的ansible比较老,所以格式可能不太一样):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
| ---
- name: 第 1 步 - 从 OpenVPN 客户端配置中发现公网 IP 及其文件名
hosts: all
become: yes
gather_facts: no
vars:
# 定义要扫描的 OpenVPN 客户端配置目录
openvpn_client_dir: /etc/openvpn/client
tasks:
- name: "扫描 {{ openvpn_client_dir }} 目录下的配置文件 (递归搜索并关联文件名)"
shell: >
grep -rHE '^remote\s+' {{ openvpn_client_dir }} 2>/dev/null |
grep -vE ':remote\s+(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|127\.|localhost)' |
sed -E 's#^.*/([^:]+):remote[[:space:]]+([^ ]+).*#\2--->\1#' |
sort -u || true
# 这个 shell 命令执行以下操作:
# 1. `grep -rHE '^remote\s+'`: 递归搜索并打印“文件名:匹配行”。
# - `-H`: 强制打印文件名。
# 2. `grep -vE ':remote\s+(私网IP正则)'`: 过滤掉包含私网IP的行。
# 3. `sed -E 's#...#...#'`: 使用正则表达式重新格式化输出。
# - 它会将 "路径/文件名.ovpn:remote 1.2.3.4 ..." 格式化为 "1.2.3.4--->文件名.ovpn"
# 4. `sort -u`: 对最终结果进行排序和去重。
# 5. `|| true`: 确保在没有找到文件或匹配项时,任务不会失败。
register: public_ips_found
changed_when: false
- name: "为找到的 'IP--->文件名' 设置变量"
set_fact:
openvpn_public_ips: "{{ public_ips_found.stdout_lines }}"
- name: 第 2 步 - 生成汇总报告
hosts: localhost
connection: local
gather_facts: no
become: no
tasks:
- name: "汇总所有主机上发现的'IP--->文件名'映射"
set_fact:
all_public_ips: "{{ all_public_ips | default([]) + hostvars[item]['openvpn_public_ips'] }}"
loop: "{{ groups['all'] }}"
when: hostvars[item]['openvpn_public_ips'] is defined and hostvars[item]['openvpn_public_ips'] | length > 0
- name: "将唯一的'IP--->文件名'列表写入本地文件"
copy:
content: "{{ all_public_ips | unique | join('\n') }}\n"
dest: "./result_public_ip_mapping.txt"
when: all_public_ips is defined and all_public_ips | length > 0
|
把这个ansible脚本保存为 scan_openvpn_ips.yml。
把需要扫描的客户端主机名写入一个文件 vpnclient_list.ini,这里我不知道Client的登录端口是22还是8822,所以都写上了。
类似这样:
1
2
3
| [shimokitazawa]
1.2.3.4 ansible_port=22
1.2.3.4 ansible_port=8822
|
执行
1
| ansible-playbook -i vpnclient_list.ini count_vpn_client.yml 2>&1 | tee playbook.log
|
最终输出会到result_public_ip_mapping.txt里面
效果如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| |># cat result_public_ip_mapping.txt
114.514.19.81--->xiuxiu.ovpn
114.514.19.81--->shimokitazawa.ovpn
114.514.19.81--->sample.ovpn
191.981.0.81--->tokyo.ovpn
810.191.98.10--->osaka.ovpn
233.333.33.33--->nagoya.ovpn
666.666.66.66--->kyoto.ovpn
404.404.40.44--->sapporo.ovpn
520.131.41.41--->fukuoka.ovpn
250.250.25.25--->sendai.ovpn
123.456.78.90--->hakata.ovpn
999.888.77.66--->shibuya.ovpn
314.159.26.53--->akihabara.ovpn
810.191.98.10--->ikebukuro.ovpn
114.514.19.10--->kawasaki.ovpn
114.514.19.10--->yokohama.ovpn
191.981.0.10--->chiba.ovpn
233.666.66.66--->kobe.ovpn
191.981.0.81--->saitama.ovpn
404.404.40.44--->ueno.ovpn
810.191.98.10--->shinagawa.ovpn
114.514.19.81--->shimokitazawa.ovpn
|
自此,所有的OpenVPN客户端配置文件的公网IP和对应的文件名都被提取出来了。
参考资料:
https://ansible-tran.readthedocs.io/en/latest/docs/playbooks_intro.html#playbook-basics