VyOS API scripting
I spent some time reading the VyOS documentation again, and rediscovered that there is an API…and that VyOS ships with both python and requests installed. So I hacked together some code to solve a problem, and it actually worked!
Enabling the API #
First thing I did was to enable the API, in my case only over loopback:
set service https api keys id helloworld key replaceme
set service https api port 8080
Hacky script #
I then hacked together a short Python script to check my external IP, compare it to an IP stored in an address-group, and update this IP if necessary.
Why, one might ask? I will use this external IP to setup NAT reflection, but since I’m on a residental connection my IP is dynamic, and I need to keep track of the current one.
The script isn’t pretty but it should do the trick. I saved mine to
/config/scripts/check-wan-ip.py
.
#!/usr/bin/env python3
import json
import requests
API_KEY = "replaceme"
API_URL = "http://localhost:8080"
GROUP_NAME = "wan-ip"
def build_cmds(ip_list, external):
cmds, internal = [], ip_list[-1]
if internal != external:
for ip in ip_list:
if len(ip) > 0:
cmds.append(split_cfg_cmd(f"delete firewall group address-group {GROUP_NAME} address {ip}"))
cmds.append(split_cfg_cmd(f"set firewall group address-group {GROUP_NAME} address {external}"))
return cmds
def split_cfg_cmd(cmd):
parts = cmd.split(" ")
return { 'op': parts[0], 'path': parts[1:] }
def api_request(api_url, headers, payload):
request = requests.request("POST", api_url, headers=headers, data=payload)
return request.json()
if __name__ == '__main__':
external_ip = requests.get('https://ifconfig.me/').text
cmd = split_cfg_cmd(f"showConfig firewall group address-group {GROUP_NAME}")
payload = { 'data': json.dumps(cmd), 'key': f'{API_KEY}' }
internal_ip = api_request(f"{API_URL}/retrieve", {}, payload)
ip_data = internal_ip.get('data')
address = ip_data.get('address')
cmds = []
if isinstance(address, str):
cmds = build_cmds([address,], external_ip)
elif isinstance(address, list):
cmds = build_cmds(address, external_ip)
else:
cmds = api_single_ip(["",], external_ip)
if cmds:
update_payload = { 'data': json.dumps(cmds), 'key': API_KEY }
url = f"{API_URL}/configure"
api_request(url, {}, update_payload)
Schedule execution #
Then, run this script using the builtin task scheduler (aka as a cronjob):
# Also remember to make the script executable...
set system task-scheduler task check-wan-ip interval 7m
set system task-scheduler task check-wan-ip executable path /config/scripts/check-wan-ip.py