Skip to content

Instantly share code, notes, and snippets.

@f-vicente
Created February 6, 2026 07:56
Show Gist options
  • Select an option

  • Save f-vicente/9967d3d69bc885601647ff4d6528b29b to your computer and use it in GitHub Desktop.

Select an option

Save f-vicente/9967d3d69bc885601647ff4d6528b29b to your computer and use it in GitHub Desktop.
Opnsense ISC static leases to Kea
<!DOCTYPE html>
<!--
INSTRUCTIONS
0 - Download this file an open in a browser
1 - Login to your opnsense page (in my case 10.0.1.1:543)
2 - Browse https://10.0.1.1:543/api/dhcpv4/leases/searchlease
3 - Copy the whole JSON into the textarea, and click generate
4 - Configure Kea and use the import button (in the low right of the screen) to import static leases
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OPNsense → Kea CSV Converter</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
textarea { width: 100%; height: 220px; margin-top: 10px; font-family: monospace; }
button { margin-top: 10px; padding: 8px 16px; font-size: 14px; }
</style>
</head>
<body>
<h2>OPNsense → Kea DHCP CSV Converter</h2>
<b>Input JSON:</b>
<textarea id="inputJson" placeholder="Paste OPNsense JSON here..."></textarea>
<button onclick="convert()">Convert to CSV</button>
<button onclick="downloadCSV()">Download CSV</button>
<b>Output CSV:</b>
<textarea id="outputCsv" placeholder="CSV will appear here..."></textarea>
<script>
function convert() {
try {
const raw = document.getElementById("inputJson").value.trim();
const data = JSON.parse(raw);
const header = "ip_address,hw_address,hostname,description,option_data";
const rows = data.rows
.filter(r => r.type === "static")
.map(r => {
const ip = (r.address || "").trim();
const mac = (r.mac || "").trim();
const hostname = (r.hostname || r.descr || "").trim();
const description = (r.descr || "").trim();
return `${ip},${mac},${hostname},${description},`;
});
const csv = [header, ...rows].join("\n");
document.getElementById("outputCsv").value = csv;
} catch (err) {
alert("Invalid JSON: " + err.message);
}
}
function downloadCSV() {
const csv = document.getElementById("outputCsv").value;
if (!csv) {
alert("No CSV to download. Convert first.");
return;
}
const blob = new Blob([csv], { type: "text/csv" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "kea_import.csv";
a.click();
URL.revokeObjectURL(url);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment