This commit is contained in:
Eliezer Croitoru 2026-02-15 14:09:34 +02:00
commit 9db3ef9157
3 changed files with 147 additions and 0 deletions

32
Makefile Normal file
View File

@ -0,0 +1,32 @@
all:
echo OK
install: install-service enable-service start-service
cp -vf wg-healthcheck.py /usr/local/bin/
uninstall: remove-service
rm -vf /usr/local/bin/wg-healthcheck.py
install-service:
cp -vf wg-healthcheck-service.service /etc/systemd/system/wg-healthcheck-wg1.service
systemctl daemon-reload
remove-service: stop-service disable-service
systemctl daemon-reload
enable-service:
systemctl enable wg-healthcheck-wg1.service
disable-service:
systemctl disable wg-healthcheck-wg1.service
start-service:
systemctl start wg-healthcheck-wg1.service
stop-service:
systemctl start wg-healthcheck-wg1.service;true
restart-service: stop-service start-service

View File

@ -0,0 +1,28 @@
[Unit]
Description=Network Device Health Check Service
After=network.target
[Service]
# Run as a specific unprivileged user
User=nobody
Group=nobody
# Path to your Python script
ExecStart=/usr/bin/python3 /usr/local/bin/wg-healthcheck.py --device wg1 --port 18081
# Restart settings
Restart=always
RestartSec=5
# Security Hardening
# Allows the script to query network state without being root
AmbientCapabilities=CAP_NET_ADMIN
NoNewPrivileges=true
# Standard isolation
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target

87
wg-healthcheck.py Executable file
View File

@ -0,0 +1,87 @@
#!/usr/bin/env python3
import subprocess
import argparse
from http.server import HTTPServer, BaseHTTPRequestHandler
class HealthCheckHandler(BaseHTTPRequestHandler):
"""
HTTP server that returns 200 if a network device is up,
and 503 if it is down or missing.
"""
def check_device(self):
device = self.server.device
try:
# -run command: ip link show <device> up
# -check=True ensures we can catch errors easily
# -capture_output=True keeps the terminal clean
result = subprocess.run(
["ip", "link", "show", device, "up"],
capture_output=True,
text=True,
check=False
)
# Return True only if exit code is 0 and output is not empty
return result.returncode == 0 and len(result.stdout.strip()) > 0
except FileNotFoundError:
print("Error: 'ip' command not found. Are you on Linux?")
return False
def do_GET(self):
if self.check_device():
self.send_response(200)
self.send_header("Content-Type", "text/plain")
self.end_headers()
self.wfile.write(b"healthy\n")
else:
self.send_response(503)
self.send_header("Content-Type", "text/plain")
self.end_headers()
self.wfile.write(b"unhealthy\n")
def do_HEAD(self):
self.do_GET()
# Suppress standard logging to keep console clean, optional
def log_message(self, format, *args):
return
def main():
parser = argparse.ArgumentParser(
description="Modern HTTP health check for network devices."
)
parser.add_argument("-d", "--device", default="wg0",
help="Device name to check (e.g., eth0, wg0). Default: wg0")
parser.add_argument("-p", "--port", type=int, default=8080,
help="Port to listen on. Default: 8080")
parser.add_argument("-t", "--test", action="store_true",
help="Check status once and exit.")
args = parser.parse_args()
# logic for --test flag
if args.test:
# Temporary mock-up of the check logic for CLI test
cmd = ["ip", "link", "show", args.device, "up"]
res = subprocess.run(cmd, capture_output=True, text=True)
if res.returncode == 0 and res.stdout:
print(f"Device {args.device}: UP")
exit(0)
else:
print(f"Device {args.device}: DOWN")
exit(1)
# Start the Server
server = HTTPServer(('', args.port), HealthCheckHandler)
server.device = args.device
print(f"Starting health check server for {args.device} on port {args.port}...")
try:
server.serve_forever()
except KeyboardInterrupt:
print("\nShutting down server.")
server.server_close()
if __name__ == "__main__":
main()