1
This commit is contained in:
commit
9db3ef9157
32
Makefile
Normal file
32
Makefile
Normal 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
|
||||||
|
|
||||||
|
|
||||||
28
wg-healthcheck-service.service
Normal file
28
wg-healthcheck-service.service
Normal 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
87
wg-healthcheck.py
Executable 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()
|
||||||
Loading…
x
Reference in New Issue
Block a user