donaldzou / WGDashboard

Simple dashboard for WireGuard VPN written in Python & Vue.js
https://donaldzou.github.io/WGDashboard-Documentation/
Apache License 2.0
1.63k stars 248 forks source link

OpenBSD Support #483

Open donaldzou opened 1 week ago

donaldzou commented 1 week ago

Installation Commands for 7.6

pkg_add python-3.11.10p0 wireguard-tools-1.0.20210914p2v0 git-2.46.1 sudo-1.9.15.5p0 rust-1.81.0
mkdir WGDashboard
git clone https://github.com/donaldzou/WGDashboard.git WGDashboard
cd WGDashboard/src
chmod +x ./wgd.sh
./wgd.sh install

Issue

(venv) openbsd# bash ./wgd.sh debug                                                                              
------------------------------------------------------------
[WGDashboard] WireGuard is already installed.
[WGDashboard] Starting WGDashboard in the foreground.
Unknown distro type 'OpenBSD'.
Traceback (most recent call last):
  File "/root/WGDashboard/src/dashboard.py", line 1640, in <module>
    DashboardConfig = DashboardConfig()
                      ^^^^^^^^^^^^^^^^^
  File "/root/WGDashboard/src/dashboard.py", line 1339, in __init__
    "remote_endpoint": ifcfg.default_interface()['inet'] if ifcfg.default_interface() else '',
                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/WGDashboard/src/venv/lib/python3.11/site-packages/ifcfg/__init__.py", line 81, in default_interface
    return Parser(ifconfig=ifconfig)._default_interface(route_output=route_output)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NullParser' object has no attribute '_default_interface'. Did you mean: 'default_interface'?

If any OpenBSD user/expert know why this is happening that would be great!

DaanSelen commented 6 days ago

Can you also output the ./log/install.txt?

NOXCIS commented 4 days ago

@donaldzou You cant use ifcfg. Its a Linux Kernel tool and isn't directly supported in BSD based kernels, use netstat -rn .

Either way mod the dashboard to use ifconfig (Most Universal Option), or if cases to use netstat when the OS == OpenBSD, or use some kind of enviorment loading. Your choice.

Oh and BTW, automation or making anything easy for users upsets the BSD purist for some reason.

Screenshot 2024-11-17 at 3 07 54 AM

Also stumbled into this, No idea what it means yet.

Screenshot 2024-11-17 at 3 08 13 AM

flys off back to Darwin

MDAwMDAwMDAgIDQzIDZkIDUwIDMyIDQ1IDRmIDUxIDY3IDQ1IDMyIDM5IDc1IDYyIDZkIDRjIDY3ICB8Q21QMkVPUWdFMjl1Ym1MZ3wKMDAwMDAwMTAgIDQ1IDMyIDZjIDMyIDQ1IDQxIDRiIDM1IDYyIDMzIDQ5IDY3IDY0IDRmIDVhIDU4ICB8RTJsMkVBSzViM0lnZE9aWHwKMDAwMDAwMjAgIDQzIDZkIDUwIDMyIDQ1IDRmIDUxIDY3IDQ1IDMyIDM5IDc1IDYyIDZkIDRjIDY3ICB8Q21QMkVPUWdFMjl1Ym1MZ3wKMDAwMDAwMzAgIDYyIDUyIDUwIDMwIDUxIDQ4IDZjIDc2IDY0IDQxIDRiIDZiIDYyIDMzIDY0IDc1ICB8YlJQMFFIbHZkQUtrYjNkdXwKMDAwMDAwNDAgIDU0IDZiIDM1IDZjIDY0IDZkIDUwIDc5IDUxIDUyIDY0IDc2IDYyIDZkIDM1IDY4ICB8VGs1bGRtUHlRUmR2Ym01aHwKMDAwMDAwNTAgIDUxIDQ4IDRhIDMxIDYyIDY5IDRiIDY4IDYzIDZkIDM5IDMxIDYyIDZkIDRlIDY3ICB8UUhKMWJpS2hjbTkxYm1OZ3wKMDAwMDAwNjAgIDQ0IDU1IDM1IDZiIDUxIDUyIDQ3IDZjIDYzIDMyIDUwIDc5IDY0IDU0IDRiIDM1ICB8RFU1a1FSR2xjMlB5ZFRLNXwKMDAwMDAwNzAgIDYyIDMzIDQ5IDU4IDQzIDZkIDUwIDMyIDQ1IDRmIDUxIDY3IDQ1IDMyIDM5IDc1ICB8YjNJWENtUDJFT1FnRTI5dXwKMDAwMDAwODAgIDYyIDZkIDRjIDY3IDYyIDU1IDQ2IDcyIDQ1IDQxIDRiIDM1IDYyIDMzIDQ5IDY3ICB8Ym1MZ2JVRnJFQUs1YjNJZ3wKMDAwMDAwOTAgIDQ0IDMzIDRhIDM1IDU0IDZiIDM1IDZjIDY0IDZkIDUwIDc5IDUxIDUyIDY0IDc2ICB8RDNKNVRrNWxkbVB5UVJkdnwKMDAwMDAwYTAgIDYyIDZkIDM1IDY4IDUxIDQ4IDQyIDY4IDY1IDQxIDRiIDZlIDYyIDMyIDM5IDZiICB8Ym01aFFIQmhlQUtuYjI5a3wKMDAwMDAwYjAgIDQ0IDZlIDZjIDZjIDU0IDZiIDM1IDZjIDY0IDZkIDUwIDc5IDUxIDUyIDY0IDc2ICB8RG5sbFRrNWxkbVB5UVJkdnwKMDAwMDAwYzAgIDYyIDZkIDM1IDY4IDUxIDQ4IDQ3IDZjIDYyIDUyIDc3IDY3IDQ0IDQxIDRiIDczICB8Ym01aFFIR2xiUndnREFLc3wKMDAwMDAwZDAgIDYxIDU1IDQ5IDY3IDQ0IDU1IDM1IDZiIDUxIDUyIDY4IDMxIDYzIDZlIDRlIDY3ICB8YVVJZ0RVNWtRUmgxY25OZ3wKMDAwMDAwZTAgIDY1IDU1IDM5IDMxIDU0IDZiIDRhIDQzIDQ3IDU0IDRiIDMxIDYzIDMyIDUwIDc5ICB8ZVU5MVRrSkNHVEsxYzJQeXwKMDAwMDAwZjAgIDYzIDc5IDRiIDZiIDYyIDMyIDM1IDMwIDUxIDUyIDM1IDZjIDQ1IDU1IDRlIDY3ICB8Y3lLa2IyNTBRUjVsRVVOZ3wKMDAwMDAxMDAgIDYzIDMyIDM5IDc0IDQ1IDU1IDM5IDc1IDQ1IDQxIDRiIDMwIDYyIDc5IDRiIDZmICB8YzI5dEVVOXVFQUswYnlLb3wKMDAwMDAxMTAgIDYyIDMyIDc4IDZiIDUxIDQ4IDQ3IDZmIDQ1IDU1IDZjIDc5IDUxIDUyIDY4IDY4ICB8YjJ4a1FIR29FVWx5UVJoaHwKMDAwMDAxMjAgIDYyIDZkIDQ3IDdhIDU5IDY5IDRiIDQ5IDYxIDUyIDUwIDM1IDUxIDUyIDQ2IDczICB8Ym1HellpS0lhUlA1UVJGc3wKMDAwMDAxMzAgIDYzIDZkIDUwIDY4IDQ1IDQ4IDZiIDY3IDY0IDRmIDQyIDZjIDUxIDRjIDRhIDQzICB8Y21QaEVIa2dkT0JsUUxKQ3wKMDAwMDAxNDAgIDQ3IDU0IDRiIDMzIDYxIDUyIDM5IDdhIDUxIDUyIDM1IDZjIDY1IDQ4IDRlIDY3ICB8R1RLM2FSOXpRUjVsZUhOZ3wKMDAwMDAxNTAgIDQ1IDMyIDUwIDc1IDY0IDUyIDM5IDc2IDU2IDc3ICAgICAgICAgICAgICAgICAgICB8RTJQdWRSOXZWd3w=

NOXCIS commented 3 days ago

@donaldzou @DaanSelen This feature should be abandoned.

  1. BSD users are not going to install this on Bare Metal. No chance in hell

  2. BSD users will just use vmd and install via a Linux VM anyway.

  3. Much of the dashboard will need to be rewritten to properly handle the BSD kernel (Which is Not Linux at All).

  4. If someone is using BSD as a daily or Server, they dont need an auto install option, id like to think the user is technical enogh to figure it out.

  5. Unless you want to be pointed towards the MAN pages, dont expect any help from the community. No seriously, BSD Unix kernels are great but always expect an uphill battle doing anything the first time. I use macOS becuase Darwin is BSD with builtin support for everyday stuff. Otherwise its Linux for severs and OpenBSD/ Free BSD for routers.

  6. If you still want to add the OpenBSD option..., heres how you can start.

In short, BSD install support is kind of pointless as users will just run a linux VM anyway, allowing them to use the installer or docker option as they see fit. Not to metion BSD users will look at anyone trying to run the dashboard on bare metal as if they were smoking crack. You could look into OpenBSD Jails if you still want bare metal to be an option people would actually use. Finally OpenBSD users DO NOT, play with fast and loose code, hence the secuirty first ethos.

DaanSelen commented 2 days ago

@donaldzou @DaanSelen This feature should be abandoned.

  1. BSD users are not going to install this on Bare Metal. No chance in hell
  2. BSD users will just use vmd and install via a Linux VM anyway.
  3. Much of the dashboard will need to be rewritten to properly handle the BSD kernel (Which is Not Linux at All).
  4. If someone is using BSD as a daily or Server, they dont need an auto install option, id like to think the user is technical enogh to figure it out.
  5. Unless you want to be pointed towards the MAN pages, dont expect any help from the community. No seriously, BSD Unix kernels are great but always expect an uphill battle doing anything the first time. I use macOS becuase Darwin is BSD with builtin support for everyday stuff. Otherwise its Linux for severs and OpenBSD/ Free BSD for routers...

I second this train of thought. BSD support sounds cool. But I don't see many users coming from there.

NOXCIS commented 2 days ago

@donaldzou @DaanSelen Its still feasible, just not sensible to automate for users on WGDashboard, due to the extra configuartion overhead.

Screenshot 2024-11-19 at 4 20 54 AM
theninjageek commented 2 days ago

As a FreeBSD user I agree with some of the points already mentioned, especially with the OpenBSD community not being helpful with much better support from the FreeBSD community.

Although most cloud providers don't offer a FreeBSD VM, with Azure and AWS being the very few that do, I would still run this for myself as part of a home lab install, albeit in a Jail due to the requirement of running it as root, it's not that complicated to get it installed. the packages needed are:

python311/python3
py311-sqlite3
py311-pip
py311-virtualenv
wireguard-tools

and an adjustment to the default wireguard config location is needed as FreeBSD stores the configs in /usr/local/etc/wireguard also the wgd.sh script should change to #! /usr/bin/env bash to make it more compatible with multiple OSes.

Regardless of the above, the main issue is with the ifcfg python module, which doesn't support FreeBSD/OpenBSD at this point in time and is not an issue really with this project. For me the workaround to the issue, which solves the error that @donaldzou got, was to add FreeBSD support to the ifcfg module after it was installed by doing the following:

--- venv/lib/python3.11/site-packages/ifcfg/__init__.py
+++ venv/lib/python3.11/site-packages/ifcfg/__init__.py.orig
@@ -28,7 +28,7 @@
                 Log.warning("Neither `ifconfig` (`%s`) nor `ip` (`%s`) commands are available, listing network interfaces is likely to fail",
                             parser.LinuxParser.get_command(),
                             parser.UnixIPParser.get_command())
-    elif distro in ['Darwin', 'MacOSX', 'FreeBSD']:
+    elif distro in ['Darwin', 'MacOSX']:
         Parser = parser.MacOSXParser
     elif distro == 'Windows':
         # For some strange reason, Windows will always be win32, see:

We can re-use the MacOSXParser because its' pretty much the same for BSD.

NOXCIS commented 2 days ago

@theninjageek Hmm great idea, got one better. Ditch the ifcfg library entirely and use socket for UNIX independence

import socket

{....}

CONFIGURATION_PATH = os.getenv('CONFIGURATION_PATH', '.')
DB_PATH = os.path.join(CONFIGURATION_PATH, 'db')
if not os.path.isdir(DB_PATH):
    os.mkdir(DB_PATH)
DASHBOARD_CONF = os.path.join(CONFIGURATION_PATH, 'db', 'wg-dashboard.ini')

{....}

if not os.path.exists(DASHBOARD_CONF):
    load_dotenv()

{....}
wgd_pass = os.environ.get('WGD_PASS') or "admin"
wgd_global_dns = os.environ.get('WGD_DNS') or "1.1.1.1"
wgd_peer_endpoint_allowed_ip = os.environ.get('WGD_PEER_ENDPOINT_ALLOWED_IP') or "0.0.0.0/0, ::/0"
wgd_remote_endpoint = os.environ.get('WGD_REMOTE_ENDPOINT') or "0.0.0.0" 
if wgd_remote_endpoint == '0.0.0.0': #<- use socket to get endpoint
    try:
        # Get the default IP address using a socket trick
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
            s.connect(("1.1.1.1", 80))  # Connecting to a public IP
            wgd_remote_endpoint = s.getsockname()[0]
    except Exception:
        wgd_remote_endpoint = '0.0.0.0'  # Fallback if socket fails

{....}
class DashboardConfig:

    def __init__(self):

{....}

        "Peers": {
                        "peer_global_DNS": wgd_global_dns,
                        "peer_endpoint_allowed_ip": wgd_peer_endpoint_allowed_ip,
                        "peer_display_mode": "grid",
                        "remote_endpoint": wgd_remote_endpoint, #<--pass as var
                        "peer_MTU": wgd_mtu,
                        "peer_keep_alive": wgd_keep_alive,

{....}
theninjageek commented 1 day ago

@NOXCIS Thanks, that actually works way better than having to modify the ifcfg module every time I rebuild.

donaldzou commented 9 hours ago

@theninjageek Hmm great idea, got one better. Ditch the ifcfg library entirely and use socket for UNIX independence

import socket

{....}

CONFIGURATION_PATH = os.getenv('CONFIGURATION_PATH', '.')
DB_PATH = os.path.join(CONFIGURATION_PATH, 'db')
if not os.path.isdir(DB_PATH):
    os.mkdir(DB_PATH)
DASHBOARD_CONF = os.path.join(CONFIGURATION_PATH, 'db', 'wg-dashboard.ini')

{....}

if not os.path.exists(DASHBOARD_CONF):
    load_dotenv()

{....}
wgd_pass = os.environ.get('WGD_PASS') or "admin"
wgd_global_dns = os.environ.get('WGD_DNS') or "1.1.1.1"
wgd_peer_endpoint_allowed_ip = os.environ.get('WGD_PEER_ENDPOINT_ALLOWED_IP') or "0.0.0.0/0, ::/0"
wgd_remote_endpoint = os.environ.get('WGD_REMOTE_ENDPOINT') or "0.0.0.0" 
if wgd_remote_endpoint == '0.0.0.0': #<- use socket to get endpoint
    try:
        # Get the default IP address using a socket trick
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
            s.connect(("1.1.1.1", 80))  # Connecting to a public IP
            wgd_remote_endpoint = s.getsockname()[0]
    except Exception:
        wgd_remote_endpoint = '0.0.0.0'  # Fallback if socket fails

{....}
class DashboardConfig:

    def __init__(self):

{....}

        "Peers": {
                        "peer_global_DNS": wgd_global_dns,
                        "peer_endpoint_allowed_ip": wgd_peer_endpoint_allowed_ip,
                        "peer_display_mode": "grid",
                        "remote_endpoint": wgd_remote_endpoint, #<--pass as var
                        "peer_MTU": wgd_mtu,
                        "peer_keep_alive": wgd_keep_alive,

{....}

@NOXCIS Ohh I think this is actually a good idea.. if i understand it correctly, we are rely the udp socket to pick whichever net interface to handle the outbound public connection and get the IP address of that interface?