Skip to content

Commit

Permalink
v0.1.20
Browse files Browse the repository at this point in the history
  • Loading branch information
ji-podhead committed Nov 12, 2024
1 parent 95dc3f0 commit acae993
Show file tree
Hide file tree
Showing 17 changed files with 772 additions and 1,238 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ __pycache__

# Log-Dateien
*.log

config.xml
# Temporäre Dateien
*.tmp
*.swp
Expand Down
83 changes: 67 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
# opnsense-helper
- assign and enable lan / phy interfaces! - ***Not enabled in the opnsense api***
- create vlans, vlan-interfaces - ***Not enabled in the opnsense api***
- setup dhcp
- uses the opnsense backend via shh - ***much faster than the frontend api!!!***
- all configctl commands
- all pluginctl commands
- all opnsense scripts
## Some of the docs are currently outdated
- create, assign and enable lan / phy interfaces and all the other stuff that is ***Not enabled*** in the opnsense api
- use the config_manager to apply all your configs in runtime at once
- uses the opnsense backend via shh


## install
## pip
Expand All @@ -15,10 +11,13 @@ pip install opnsense-helper
```
## usage
> you can run the provided snippets directly by pulling the [example file](https://github.com/the-pod-shop/opnsense-helper/blob/main/python/examples/add_vlans.py)
### required variables
* import the package and define the needed variables for the main class

```python
from opnsense_helper.classes import Opnsense_Helper
from opnsense_helper.opnsense_helper import Opnsense_Helper
from opnsense_helper.config_manager.config_manager import Vlan, Dhcpd, Interface

host= "192.168.1.103"
auth={
Expand All @@ -28,6 +27,9 @@ auth={
temp_path="./config.xml"
helper=Opnsense_Helper(host=host,ssh_auth=auth,temp_path=temp_path, init=True)
```
### config_manager
> add or change existing modules
> - currently supports vlans, dhcpd, interfaces and soon routes, as well as firewall rules
- create the objects of the modules you want to set
```python
vlans=[
Expand Down Expand Up @@ -58,6 +60,55 @@ helper.set("vlans",vlans)
helper.save(temp_path)
#helper.remove_items()
```
### scripts and commands
> - you can run every script fron `/usr/local/opnsense/scripts/`
> - you can use every `pluginctl` and `configctl` commands
> - use `<command: str> <argument:str> <flags:arr>`
> - besides command, argument may be required based on the method
```python
helper.scripts.system.run("status")
helper.scripts.routes.run("show_routes")

helper.commands.pluginctl.run("ipv4")
helper.commands.pluginctl.run("service", "dhcpd status")
helper.commands.pluginctl.run("config", "dhcp")
```
#### Result
```bash
$ /usr/local/opnsense/scripts/system/status.php*
{"CrashReporter":{"statusCode":2,"message":"No problems were detected.","logLocation":"\/crash_reporter.php","timestamp":"0"},"Firewall":{"statusCode":-1,"message":"There were error(s) loading the rules: \/tmp\/rules.debug:25: syntax error - The line in question reads [25]: set loginterface \n","logLocation":"\/ui\/diagnostics\/log\/core\/firewall","timestamp":1731025409}}

$ /usr/local/opnsense/scripts/routes/show_routes.py*
destination gateway flags nhop# mtu netif expire
ipv4 default 192.168.0.1 UGS 5 1500 vtnet0
ipv4 localhost link#4 UH 2 16384 lo0
ipv4 192.168.0.1 link#1 UHS 4 1500 vtnet0
ipv4 192.168.1.0/24 link#1 U 1 1500 vtnet0
ipv4 192.168.1.1 link#1 UHS 4 1500 vtnet0
ipv4 192.168.1.103 link#1 UHS 3 16384 lo0
ipv4 200.1.0.0/24 link#2 U 6 1500 vtnet1
ipv4 200.1.0.1 link#2 UHS 7 16384 lo0
ipv6 localhost link#4 UHS 1 16384 lo0
ipv6 fe80::%lo0/64 link#4 U 3 16384 lo0
ipv6 fe80::1%lo0 link#4 UHS 2 16384 lo0

$ pluginctl -4
{
"address": null,
"network": null,
"bits": null,
"device": null,
"interface": null
}

$ pluginctl -s dhcpd status
dhcpd is running as pid 16072.

$ pluginctl -c dhcp
Starting DHCPv4 service...done.
```


### Frontend Api
- you can download the config.xml and add vlans via api
Expand Down Expand Up @@ -95,29 +146,29 @@ def using_api():
| interfaces | list[dict] | {id: str, descr: str, enable: int, ipaddr: str, subnet: str, type: str, virtual: bool, spoofmac: str, interface: str} |
| dhcp | list[dict] | {id: str, enable: str, ddnsdomainalgorithm: str, range: {from: str, _to: str}} |

#### Manual steps
#### config_manager manual usage

* pull the config.xml from the firewall via ssh

```python
helper.get_conf(conf_path)
helper.config_manager.get_conf(conf_path)
```

* initialize the the Opnsense_Helper-class and parse the config.xml
```python
helper.initialize()
helper.config_manager.initialize()
```
- add the items
```python
helper.add_Items("vlans",vlans)
helper.config_manager.add_Items("vlans",vlans)
```

* save the configuration as xml and copy it back to the firewall
> this will also reconfigure your vlans for you, if you have any
```python
helper.save(output)
helper.put_file(output,conf_path)
helper.close_con()
helper.config_manager.save(output)
helper.config_manager.put_file(output,conf_path)
helper.config_manager.close_con()
```


Expand Down
18 changes: 0 additions & 18 deletions pyproject.toml.old

This file was deleted.

125 changes: 15 additions & 110 deletions python/build/lib/opnsense_helper/opnsense_helper.py
Original file line number Diff line number Diff line change
@@ -1,111 +1,16 @@
import xml.etree.ElementTree as ET
import paramiko
from .utils import parseChild,update_xml_file,aliases, get_element, getRes


class Interface:
def __init__(self, name, parent):
self.descr = parseChild(parent, "descr")
self.enable = parseChild(parent, "enable")
self.ipaddr = parseChild(parent, "ipaddr")
self.subnet = parseChild(parent, "subnet")
self.type = parseChild(parent, "type")
self.virtual = parseChild(parent, "virtual")
self.spoofmac=parseChild(parent, "spoofmac")
self.attr=None

class Vlan:
def __init__(self,name, parent):
self.parentinterface =parseChild(parent, "if")
self.tag = parseChild(parent,"tag")
self.pcp = parseChild(parent,"pcp")
self.proto = parseChild(parent,"proto")
self.descr = parseChild(parent,"descr")
self.vlanif = parseChild(parent,"vlanif")
self.attr=None

class Dhcpd:
def __init__(self, name, parent):
self.enable = parseChild(parent, "enable")
self.ddnsdomainalgorithm = parseChild(parent, "ddnsdomainalgorithm")
self.range={
"_from":"",
"_to":""
}
self.attr=None


class OpennsenseHelper():
def __init__(self, filepath, method=None, user=None, passw=None, host=None, api_key=None, api_secret=None):
self.filepath=filepath
self.tree = ET.parse(filepath)
self.root = self.tree.getroot()
self.objects={
"vlans":{},
"dhcpd":{},
"interfaces":{}
}

if(method=="ssh"):
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(host, username=user, password=passw)
self.sftp = self.ssh.open_sftp()
#self.ssh .open_sftp
if(method=="http"):
self.url = host
self.api_key = api_key
self.api_secret = api_secret
self.host=host

def initialize(self):
self.get_all("dhcpd")
self.get_all("vlans")
self.get_all("interfaces")
def save(self,output):
update_xml_file(self.objects["dhcpd"],self.root,"dhcpd")
update_xml_file(self.objects["interfaces"],self.root,"interfaces")
update_xml_file(self.objects["vlans"],self.root,"vlans")
with open(output, 'w') as f:
f.write(ET.tostring(self.root, encoding='unicode', method='xml'))

def get_all(self,element):
print(f''' -----------------------------
{element}''')
for parent in self.root.findall(element):
for key in parent:
if element== "dhcpd":
child = Dhcpd(key.tag,parent)
elif element== "interfaces":
child = Interface(key.tag,parent)
elif element== "vlans":
child = Vlan(key.tag,parent)

child=get_element(parent, key.tag, child)
if element== "dhcpd":
_range={"_from": parent.find(key.tag).find("range/from"),
"_to":parent.find(key.tag).find("range/to")}
if _range["_from"] is not None:
_range["_from"]=_range["_from"].text
_range["_to"]=_range["_to"].text
child.range =_range
child.attr=key.attrib if key.attrib is not None else None
print(child.attr)
self.objects[element][key.tag]=child.__dict__
print(f'''{key.tag} : {child.__dict__}
-------------------''')

return(self.objects[element])
def close_con(self):
self.sftp.close()
self.ssh.close()
def put_file(self, _from,_to):
self.sftp.put(_from, _to)
def get_file(self,_from,_to):
self.sftp.get(_from,_to)
def get_backup(self,_from,_to):
command = 'core/firmware/status'
timeout = 5
getRes(self.host, command, self.api_key, self.api_secret, timeout)


from opnsense_helper.config_manager.config_manager import Interface, Vlan, Dhcpd, Config_Manager
from opnsense_helper.utils.baseclass import Base_Class
from opnsense_helper.commands.commands import Commands
from opnsense_helper.scripts.scripts import Scripts
class Opnsense_Helper():
def __init__(self, host=None, ssh_auth=None, api_auth=None, conf_path="/conf/config.xml", temp_path="./config.xml", verbose=False, init_config_manager=True):

base_class = Base_Class(host, ssh_auth, api_auth, conf_path, temp_path, verbose)
self.config_manager=Config_Manager(base_class)
self.commands=Commands(base_class)
self.scripts=Scripts(base_class)

if init_config_manager:
self.config_manager.get_conf()
self.config_manager.initialize()
Loading

0 comments on commit acae993

Please sign in to comment.