Initial Project Import

This commit is contained in:
2023-02-15 20:22:07 +13:00
commit 890ec39113
5 changed files with 89 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.pyc
.venv

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"python.formatting.provider": "black"
}

16
Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
FROM python:3-slim AS build
COPY src/ /app
WORKDIR /app
RUN python3 -m pip install -r requirements.txt
VOLUME /app/data
ENV NOIP_HOST="127.0.0.1"
ENV NOIP_USERNAME=""
ENV NOIP_PASSWORD=""
CMD ["python3", "app.py"]

66
src/app.py Normal file
View File

@@ -0,0 +1,66 @@
#!/usr/bin/env python3
import paramiko
import click
import re
def return_ip_and_prefix(lines :str, scheme :str ="ipv6" ) -> str:
""" Lookup and return IP Address and a suffix.
Supports both IPv6 and IPv4
Args:
lines (str): The lines of text to check. e.g. output from Paramiko
scheme (str, optional): The IP scheme (IPv4 or IPv6). Defaults to "ipv6".
Returns:
str: An IP with prefix/CIDR
"""
if scheme == "ipv6":
m = re.search(r"inet6 ([\d\w:/]+).+prefixlen (56|64)$", lines)
ip_split = ":".join(m.group(1).split(":", 4)[:4])
return ip_split + "::1/" + m.group(2)
elif scheme == "ipv4":
m = re.search(r"inet ([\d./]+)", lines)
return m.group(1) + "/32"
@click.command()
@click.option("--host", required=True, help="The hostname/ip to connect to.")
@click.option("--port", default=22, help="The SSH port to connect on.")
@click.option("--username", required=True, help="The username you wish to use.")
@click.option("--password", required=True, help="The Password/Secret for this user.")
def main(host: str, port: int, username: str, password: str) -> None:
""" This application will connect to an OpnSense firewall. The aim is to retrieve
the IPv6 Segment and Prefix along with the IPv4 address for the WAN.
"""
click.echo("Checking for IPv6 Prefix")
command = "8;ifconfig vtnet1 | grep -E 'prefixlen [0-9]{2}$'"
ipv4_command = "ifconfig vtnet0 | grep -E 'inet.+ netmask'"
logout_command = "exit; 0\n"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
_, stdout, _ = ssh.exec_command(command)
output = stdout.read().decode()
f = open("data/gallow.txt", "w")
f.write(return_ip_and_prefix(output, "ipv6") + "\n")
click.echo("Fetched IPv6 Prefix")
click.echo("Checking for IPv4 Address on WAN")
_, stdout, _ = ssh.exec_command(ipv4_command)
output = stdout.read().decode()
f.write(return_ip_and_prefix(output, "ipv4") + "\n")
click.echo("Retrieved IPv4 Address from WAN")
f.close()
ssh.exec_command(logout_command)
ssh.close()
if __name__ == "__main__":
main(auto_envvar_prefix="NOIP")

2
src/requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
paramiko==3.0.0
click==8.1.3