Randomize system hostname from device profile to match MAC identity

This commit is contained in:
Cobra
2026-04-07 13:33:54 -04:00
parent 7070f6548c
commit 8037462276
+38
View File
@@ -11,6 +11,7 @@ import json
import logging import logging
import os import os
import random import random
import socket
import sqlite3 import sqlite3
import time import time
from pathlib import Path from pathlib import Path
@@ -58,6 +59,7 @@ class MacManager(BaseModule):
self._wifi_iface: Optional[str] = None self._wifi_iface: Optional[str] = None
self._original_eth_mac: Optional[str] = None self._original_eth_mac: Optional[str] = None
self._original_wifi_mac: Optional[str] = None self._original_wifi_mac: Optional[str] = None
self._original_hostname: Optional[str] = None
self._db_path = self._resolve_db_path() self._db_path = self._resolve_db_path()
# ------------------------------------------------------------------ # ------------------------------------------------------------------
@@ -90,6 +92,8 @@ class MacManager(BaseModule):
except Exception: except Exception:
pass pass
self._original_hostname = socket.gethostname()
# Select and apply profile # Select and apply profile
self._profile = self._select_profile() self._profile = self._select_profile()
if self._profile is None: if self._profile is None:
@@ -131,6 +135,18 @@ class MacManager(BaseModule):
logger.warning("Failed to restore original MAC: %s", exc) logger.warning("Failed to restore original MAC: %s", exc)
self._cleanup_dhclient_conf() self._cleanup_dhclient_conf()
if self._original_hostname:
try:
import subprocess
subprocess.run(
["hostnamectl", "set-hostname", self._original_hostname],
check=True, capture_output=True,
)
logger.debug("Hostname restored to %s", self._original_hostname)
except Exception:
pass
self._running = False self._running = False
self.state.set_module_status(self.name, "stopped") self.state.set_module_status(self.name, "stopped")
logger.info("MacManager stopped — original MACs restored") logger.info("MacManager stopped — original MACs restored")
@@ -145,6 +161,8 @@ class MacManager(BaseModule):
base["profile_name"] = self._profile.get("device_name", "unknown") base["profile_name"] = self._profile.get("device_name", "unknown")
base["applied_mac"] = self._profile.get("applied_mac", "unknown") base["applied_mac"] = self._profile.get("applied_mac", "unknown")
base["dhcp_hostname"] = self._profile.get("dhcp_hostname", "unknown") base["dhcp_hostname"] = self._profile.get("dhcp_hostname", "unknown")
if self._profile.get("applied_hostname"):
base["applied_hostname"] = self._profile["applied_hostname"]
if self._eth_iface: if self._eth_iface:
try: try:
base["current_eth_mac"] = get_mac(self._eth_iface) base["current_eth_mac"] = get_mac(self._eth_iface)
@@ -304,6 +322,8 @@ class MacManager(BaseModule):
logger.debug("TCP stack: TTL=%d, window=%d", ttl, tcp_win) logger.debug("TCP stack: TTL=%d, window=%d", ttl, tcp_win)
self._set_system_hostname(profile)
def _write_dhclient_conf(self, profile: dict) -> None: def _write_dhclient_conf(self, profile: dict) -> None:
"""Write dhclient.conf with hostname + vendor class matching the profile.""" """Write dhclient.conf with hostname + vendor class matching the profile."""
hostname = profile.get("dhcp_hostname", "localhost") hostname = profile.get("dhcp_hostname", "localhost")
@@ -327,6 +347,24 @@ class MacManager(BaseModule):
except (IOError, PermissionError) as exc: except (IOError, PermissionError) as exc:
logger.warning("Failed to write dhclient.conf: %s", exc) logger.warning("Failed to write dhclient.conf: %s", exc)
def _set_system_hostname(self, profile: dict) -> None:
"""Set system hostname to match the device profile for full fingerprint consistency."""
import subprocess
hostname = profile.get("dhcp_hostname", "")
if not hostname:
return
suffix = "".join(f"{random.randint(0, 15):x}" for _ in range(4))
new_hostname = f"{hostname}-{suffix}"
try:
subprocess.run(
["hostnamectl", "set-hostname", new_hostname],
check=True, capture_output=True,
)
profile["applied_hostname"] = new_hostname
logger.info("System hostname set to %s", new_hostname)
except Exception as exc:
logger.warning("Failed to set hostname: %s", exc)
def _cleanup_dhclient_conf(self) -> None: def _cleanup_dhclient_conf(self) -> None:
"""Remove our DHCP config on clean exit.""" """Remove our DHCP config on clean exit."""
conf_file = "/etc/dhcp/dhclient.conf.d/bb-profile.conf" conf_file = "/etc/dhcp/dhclient.conf.d/bb-profile.conf"