Last active
June 13, 2026 22:57
-
-
Save schossel/c49477f1fed7591223e056cf02ca4b84 to your computer and use it in GitHub Desktop.
Get OPNSense DHCP Leases by python script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| # Scrapes pfSense DHCP Leases into List of (IP, MAC, Hostname, Description) format. | |
| # Change URL/Username/Password below ... pip install lxml ... then you are all set. | |
| # | |
| # Modified 6/23/2019 (FryGuy) | |
| # Edits: Aligned IP/MAC/Hostname into struct accounting for blank lines | |
| # Minor: Cleaned up spacing, created global url/user/password vars, removed write to file | |
| # Original Code/Inspiration: https://gist.github.com/pletch/037a4a01c95688fff65752379534455f | |
| # Modified 03/14/2023 (schossel) | |
| # Added Field Description and changed CSRF to work with OPNsense | |
| import sys | |
| import requests | |
| from lxml import html # pip install lxml | |
| import re | |
| import time | |
| import json | |
| # Change these to your network | |
| url = "https://yourIP:yourPort/status_dhcp_leases.php" #change url to match your pfsense machine address | |
| user = 'yourUsername' | |
| password = 'yourPassword' | |
| def scrape_opnsense_dhcp(url, user, password): | |
| ip = [] | |
| mac = [] | |
| dhcp_name = [] | |
| descr = [] | |
| s = requests.session() | |
| r = s.get(url,verify = False) | |
| head= { 'Content-Type':'application/x-www-form-urlencoded', | |
| 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36' | |
| } | |
| print(r.cookies) | |
| match_csrf_token = '"X-CSRFToken",\s"(.*)".+\);' | |
| match_csrf_name = '<form.*id="iform".*name="(.*?)".*new-password"' | |
| csrf_token = re.search(match_csrf_token,str(r.text)).group(1) | |
| csrf_name = re.search(match_csrf_name,str(r.text)).group(1) | |
| #print(name.group(1)) | |
| payload = { | |
| csrf_name : csrf_token, | |
| 'login' : 'Login', | |
| 'usernamefld' : user, | |
| 'passwordfld' : password | |
| } | |
| r = s.post(url,data=payload,cookies=r.cookies,headers=head,verify = False) | |
| s.headers.update(head) | |
| r = s.get(url,verify = False) | |
| tree = html.fromstring(r.content) | |
| ip.extend([element.text for element in tree.xpath('//body[1]//table[1]//tbody[1]//tr//td[2]')]) | |
| mac.extend([element.text for element in tree.xpath('//body[1]//table[1]//tbody[1]//tr//td[3]')]) | |
| for node_dhcp_name in tree.xpath('//body[1]//table[1]//tbody[1]//tr//td[4]'): | |
| if node_dhcp_name.text is None: | |
| dhcp_name.append('no_hostname') | |
| else: | |
| dhcp_name.append(node_dhcp_name.text) | |
| for node_descr in tree.xpath('//body[1]//table[1]//tbody[1]//tr//td[5]'): | |
| if node_descr.text is None: | |
| descr.append('no_description') | |
| else: | |
| descr.append(node_descr.text) | |
| for i in range(len(mac)): | |
| mac[i] = mac[i].strip() | |
| dhcp = zip(ip, mac, dhcp_name, descr) | |
| return(dhcp) | |
| if __name__ == "__main__": | |
| dhcp_list = scrape_opnsense_dhcp(url, user, password) | |
| for x in dhcp_list: | |
| print(x) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment