如何使用 RouterOS API 连接 RouterOS 设备
您可以使用 community.routeros.api 模块 通过 RouterOS API 连接到 RouterOS 设备。修改特定条目的更具体的模块是 community.routeros.api_modify 和 community.routeros.api_find_and_modify 模块。community.routeros.api_info 模块 允许检索特定预定义路径上的信息,这些信息可用作 community.routeros.api_modify 模块的输入,而 community.routeros.api_facts 模块 允许使用 RouterOS API 检索 Ansible facts。
无需特殊设置;该模块需要在能够连接到设备 API 的主机上运行。最常见的情况是模块在 localhost
上运行,方法是在 playbook 中使用 hosts: localhost
,或者为任务使用 delegate_to: localhost
。以下示例显示如何运行等效于 /ip address print
的命令
---
- name: RouterOS test with API
hosts: localhost
gather_facts: false
vars:
hostname: 192.168.1.1
username: admin
password: test1234
tasks:
- name: Get "ip address print"
community.routeros.api:
hostname: "{{ hostname }}"
password: "{{ password }}"
username: "{{ username }}"
path: "ip address"
# The following options configure TLS/SSL.
# Depending on your setup, these options need different values:
tls: true
validate_certs: true
validate_cert_hostname: true
# If you are using your own PKI, specify the path to your CA certificate here:
# ca_path: /path/to/ca-certificate.pem
register: print_path
- name: Show IP address of first interface
ansible.builtin.debug:
msg: "{{ print_path.msg[0].address }}"
这将产生以下输出
PLAY [RouterOS test] *********************************************************************************************
TASK [Get "ip address print"] ************************************************************************************
ok: [localhost]
TASK [Show IP address of first interface] ************************************************************************
ok: [localhost] => {
"msg": "192.168.2.1/24"
}
PLAY RECAP *******************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看 community.routeros.api 模块 的文档,了解选项的详细信息。
使用 community.routeros.api
模块默认组
为了避免必须在每个任务中为所有基于 API 的模块指定常用参数,您可以使用 community.routeros.api
模块默认组
---
- name: RouterOS test with API
hosts: localhost
gather_facts: false
module_defaults:
group/community.routeros.api:
hostname: 192.168.1.1
password: admin
username: test1234
# The following options configure TLS/SSL.
# Depending on your setup, these options need different values:
tls: true
validate_certs: true
validate_cert_hostname: true
# If you are using your own PKI, specify the path to your CA certificate here:
# ca_path: /path/to/ca-certificate.pem
tasks:
- name: Gather facts
community.routeros.api_facts:
- name: Get "ip address print"
community.routeros.api:
path: "ip address"
- name: Change IP address to 192.168.1.1 for interface bridge
community.routeros.api_find_and_modify:
path: ip address
find:
interface: bridge
values:
address: "192.168.1.1/24"
此处所有三个任务都将使用为模块默认组设置的选项。
设置加密
建议始终使用 tls=true
通过 API 连接,即使您只是通过受信任的网络连接到设备。以下选项控制如何使用 TLS/SSL
- force_no_cert:
设置为
true
将连接到设备而无需证书。不建议在生产环境中使用此选项,因为它容易受到中间人攻击,但在设置设备时可能有用。默认值为false
。- validate_certs:
设置为
false
将禁用任何证书验证。不建议在生产环境中使用此选项,但在设置设备时是必需的。默认值为true
。- validate_cert_hostname:
设置为
false
(默认)将禁用证书验证期间的主机名验证。如果证书中指定的主机名与用于连接的主机名(通常是设备的 IP)不匹配,则需要此设置。建议正确设置证书并将此设置为true
;默认值false
是为了向后兼容模块的旧版本而选择的。- ca_path:
如果您没有使用商业可信的 CA 证书来签署设备的证书,或者没有将您的 CA 证书包含在 Python 的信任库中,则需要将此选项指向 CA 证书。
我们建议创建一个用于签署 RouterOS 设备证书的 CA 证书,并使证书包含正确的主机名(包括设备的 IP)。这样,您可以完全启用 TLS 并确保始终与正确的设备通信。
设置 PKI
请按照 community.crypto
如何创建小型 CA 指南中的说明设置 CA 证书并为您的路由器签署证书。您应该为 IP 地址(例如 IP:192.168.1.1
)和 - 如果可用 - 为 DNS 名称(例如 DNS:router.local
)添加主题替代名称到证书中。
在 MikroTik 路由器上安装证书
最好使用 SSH 连接来安装证书。(有关更多信息,请参阅 如何使用 SSH 连接 RouterOS 设备 指南。)安装证书并启用 HTTPS API 后,使用 API 会更容易,因为它存在的问题要少得多,并且会以 JSON 对象而不是您首先必须解析的文本形式返回数据。
首先,您必须将证书及其私钥转换为 PKCS #12 包。这可以使用 community.crypto.openssl_pkcs12 完成。以下 playbook 假设证书可用作 keys/{{ inventory_hostname }}.pem
,其私钥可用作 keys/{{ inventory_hostname }}.key
。它生成一个随机密码来保护 PKCS#12 文件。
---
- name: Install certificates on devices
hosts: routers
gather_facts: false
tasks:
- block:
- set_fact:
random_password: "{{ lookup('community.general.random_string', length=32, override_all='0123456789abcdefghijklmnopqrstuvwxyz') }}"
- name: Create PKCS#12 bundle
openssl_pkcs12:
path: keys/{{ inventory_hostname }}.p12
certificate_path: keys/{{ inventory_hostname }}.pem
privatekey_path: keys/{{ inventory_hostname }}.key
friendly_name: '{{ inventory_hostname }}'
passphrase: "{{ random_password }}"
mode: "0600"
changed_when: false
delegate_to: localhost
- name: Copy router certificate onto router
ansible.netcommon.net_put:
src: 'keys/{{ inventory_hostname }}.p12'
dest: '{{ inventory_hostname }}.p12'
- name: Install router certificate and clean up
community.routeros.command:
commands:
# Import certificate:
- /certificate import name={{ inventory_hostname }} file-name={{ inventory_hostname }}.p12 passphrase="{{ random_password }}"
# Remove PKCS12 bundle:
- /file remove {{ inventory_hostname }}.p12
# Show certificates
- /certificate print
register: output
- name: Show result of certificate import
debug:
var: output.stdout_lines[0]
- name: Show certificates
debug:
var: output.stdout_lines[2]
always:
- name: Wipe PKCS12 bundle
command: wipe keys/{{ inventory_hostname }}.p12
changed_when: false
delegate_to: localhost
- name: Use certificate
community.routeros.command:
commands:
- /ip service set www-ssl address={{ admin_network }} certificate={{ inventory_hostname }} disabled=no tls-version=only-1.2
- /ip service set api-ssl address={{ admin_network }} certificate={{ inventory_hostname }} tls-version=only-1.2
该 playbook 还假设 admin_network
描述了可以访问 HTTPS 和 API 接口的网络。例如,这可以是 192.168.1.0/24
。
成功完成此剧本后,您应该能够使用 HTTPS 管理界面(可通过浏览器访问 https://192.168.1.1/
,请插入正确的 IP 地址),以及启用 TLS 和证书验证的community.routeros.api 模块。
- community.routeros.api:
...
tls: true
validate_certs: true
validate_cert_hostname: true
ca_path: /path/to/ca-certificate.pem