Created
December 17, 2025 23:11
-
-
Save NeySlim/67917b6c3feece85a867f66321576862 to your computer and use it in GitHub Desktop.
Kea dhcp server sanitize hostname hook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| #debian trixie: | |
| apt update && apt -y install kea-dev libboost-dev g++ | |
| g++ -fPIC -shared -o libkea_sanitize_hostname.so sanitize_hostname.cc \ | |
| -I/usr/include/kea -lkea-dhcp++ -lkea-hooks | |
| cp libkea_sanitize_hostname.so /usr/local/lib/libkea_sanitize_hostname.so |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "Dhcp4": { | |
| "control-socket": { | |
| "socket-type": "unix", | |
| "socket-name": "kea4-ctrl-socket" | |
| }, | |
| "hooks-libraries": [ | |
| { | |
| "library": "/usr/lib/-ARCH-/kea/hooks/libdhcp_lease_cmds.so" | |
| }, | |
| { | |
| "library": "/usr/local/lib/libkea_sanitize_hostname.so" | |
| } | |
| ], | |
| ... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <hooks/hooks.h> | |
| #include <dhcp/pkt4.h> | |
| #include <dhcp/option_string.h> | |
| #include <boost/algorithm/string.hpp> | |
| #include <iostream> | |
| #include <chrono> | |
| #include <iomanip> | |
| #include <sstream> | |
| #include <thread> | |
| #include <unistd.h> | |
| using namespace isc::hooks; | |
| using namespace isc::dhcp; | |
| using namespace std; | |
| // Timestamp | |
| static std::string kea_timestamp() { | |
| using namespace std::chrono; | |
| auto now = system_clock::now(); | |
| auto t = system_clock::to_time_t(now); | |
| auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000; | |
| std::tm tm{}; | |
| localtime_r(&t, &tm); | |
| std::ostringstream oss; | |
| oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S") | |
| << "." << std::setw(3) << std::setfill('0') << ms.count(); | |
| return oss.str(); | |
| } | |
| // Thread ID | |
| static std::string thread_id() { | |
| std::ostringstream oss; | |
| oss << std::this_thread::get_id(); | |
| return oss.str(); | |
| } | |
| // Logger Kea-like | |
| static void kea_log(const std::string& msg) { | |
| std::cerr | |
| << kea_timestamp() | |
| << " INFO [kea-dhcp4.hook_sanitize_hostname/" | |
| << getpid() << "." << thread_id() | |
| << "] MESSAGE " | |
| << msg | |
| << std::endl; | |
| } | |
| extern "C" { | |
| int version() { | |
| return KEA_HOOKS_VERSION; | |
| } | |
| bool multi_threading_compatible() { | |
| return true; | |
| } | |
| int load(LibraryHandle&) { | |
| kea_log("hook loaded"); | |
| return 0; | |
| } | |
| int unload() { | |
| kea_log("hook unloaded"); | |
| return 0; | |
| } | |
| int lease4_select(CalloutHandle& handle) { | |
| Pkt4Ptr query; | |
| handle.getArgument("query4", query); | |
| if (!query) { | |
| return 0; | |
| } | |
| OptionPtr opt = query->getOption(DHO_HOST_NAME); | |
| if (!opt) { | |
| return 0; | |
| } | |
| auto hostname_opt = dynamic_pointer_cast<OptionString>(opt); | |
| if (!hostname_opt) { | |
| return 0; | |
| } | |
| std::string hostname = hostname_opt->getValue(); | |
| kea_log("original hostname: " + hostname); | |
| boost::replace_all(hostname, "_", "-"); | |
| boost::algorithm::to_lower(hostname); | |
| hostname_opt->setValue(hostname); | |
| kea_log("rewritten hostname: " + hostname); | |
| return 0; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment