{"id":9421,"date":"2026-08-10T13:37:13","date_gmt":"2026-08-10T11:37:13","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/"},"modified":"2026-08-10T13:45:05","modified_gmt":"2026-08-10T11:45:05","slug":"wireguard-allowedips-split-tunnel-calculator","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/","title":{"rendered":"WireGuard AllowedIPs- und Split-Tunnel-Rechner"},"content":{"rendered":"<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<p style=\"color: var(--text-secondary, #9aa0aa); margin-bottom: 20px;\">Jeder WireGuard-Peer beantwortet eine einzige Frage: welche Zieladressen in den Tunnel geh\u00f6ren. Stimmt AllowedIPs nicht, l\u00e4uft Verkehr am Tunnel vorbei oder verschwindet im falschen, meist ohne eine einzige Fehlermeldung. Dieser Rechner deckt die drei Teile dieser Aufgabe ab.<\/p>\n<h3 style=\"color: var(--text-primary, #e8e8ee); font-size: 1.1rem; margin: 0 0 8px 0;\">1. Split-Tunnel: Netze aus einem Bereich herausschneiden<\/h3>\n<p style=\"color: var(--text-secondary, #9aa0aa); margin-bottom: 15px; font-size: 0.9rem;\">Aus dem Bereich, den der Tunnel f\u00fchren soll, und den Netzen, die drau\u00dfen bleiben m\u00fcssen, entsteht die kleinstm\u00f6gliche Menge an CIDR-Bl\u00f6cken f\u00fcr alles \u00dcbrige \u2014 fertig zum Einsetzen hinter AllowedIPs.<\/p>\n<div style=\"display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 15px;\">\n<div style=\"flex: 1; min-width: 220px;\">\n            <label style=\"color: var(--text-secondary, #9aa0aa); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Gesamtbereich<\/label><br \/>\n            <input type=\"text\" id=\"wg-gesamt\" value=\"0.0.0.0\/0\" class=\"form-control\" style=\"width: 100%; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace;\">\n        <\/div>\n<div style=\"flex: 2; min-width: 260px;\">\n            <label style=\"color: var(--text-secondary, #9aa0aa); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Auszuschlie\u00dfende Netze, eines pro Zeile<\/label><br \/>\n            <textarea id=\"wg-ausnahmen\" rows=\"4\" class=\"form-control\" style=\"width: 100%; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; resize: vertical;\">10.0.0.0\/8<br \/>\n172.16.0.0\/12<br \/>\n192.168.0.0\/16<\/textarea>\n        <\/div>\n<\/p><\/div>\n<p>    <button id=\"wg-btn1\" class=\"button\" style=\"background: var(--accent, #4ade80); color: #0b1114; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">AllowedIPs berechnen<\/button><\/p>\n<div id=\"wg-ergebnis1\" style=\"margin-top: 20px;\"><\/div>\n<hr style=\"border: none; border-top: 1px solid var(--border, #2a2a35); margin: 30px 0;\">\n<h3 style=\"color: var(--text-primary, #e8e8ee); font-size: 1.1rem; margin: 0 0 8px 0;\">2. \u00dcberschneidungen zwischen Peers<\/h3>\n<p style=\"color: var(--text-secondary, #9aa0aa); margin-bottom: 15px; font-size: 0.9rem;\">Die AllowedIPs jedes Peers, ein Peer pro Zeile: Name, Doppelpunkt, dann die Netze durch Kommas getrennt.<\/p>\n<p>    <label style=\"color: var(--text-secondary, #9aa0aa); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Peers und ihre AllowedIPs<\/label><br \/>\n    <textarea id=\"wg-peers\" rows=\"5\" class=\"form-control\" style=\"width: 100%; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; resize: vertical; margin-bottom: 15px;\">office: 10.0.0.0\/8, 192.168.1.0\/24<br \/>\nhome: 192.168.0.0\/16<br \/>\ncloud: 172.16.0.0\/12, 10.10.0.0\/16<br \/>\nbackup: 203.0.113.0\/24<\/textarea><\/p>\n<p>    <button id=\"wg-btn2\" class=\"button\" style=\"background: var(--accent, #4ade80); color: #0b1114; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Auf \u00dcberschneidungen pr\u00fcfen<\/button><\/p>\n<div id=\"wg-ergebnis2\" style=\"margin-top: 20px;\"><\/div>\n<hr style=\"border: none; border-top: 1px solid var(--border, #2a2a35); margin: 30px 0;\">\n<h3 style=\"color: var(--text-primary, #e8e8ee); font-size: 1.1rem; margin: 0 0 8px 0;\">3. Tunnel-MTU<\/h3>\n<p style=\"color: var(--text-secondary, #9aa0aa); margin-bottom: 15px; font-size: 0.9rem;\">Der Tunnel verpackt jedes Paket in zus\u00e4tzliche Header. Ist die Tunnel-MTU zu hoch, werden Pakete fragmentiert oder stillschweigend verworfen \u2014 sichtbar meist als Seiten, die halb laden und dann stehen bleiben.<\/p>\n<div style=\"display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 15px;\">\n<div style=\"flex: 1; min-width: 180px;\">\n            <label style=\"color: var(--text-secondary, #9aa0aa); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Physische MTU der \u00e4u\u00dferen Verbindung<\/label><br \/>\n            <input type=\"text\" id=\"wg-mtu\" value=\"1500\" class=\"form-control\" style=\"width: 100%; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace;\">\n        <\/div>\n<div style=\"flex: 1; min-width: 180px;\">\n            <label style=\"color: var(--text-secondary, #9aa0aa); display: block; font-size: 0.85rem; margin-bottom: 5px;\">IP-Version der \u00e4u\u00dferen Verbindung<\/label><br \/>\n            <select id=\"wg-version\" class=\"form-control\" style=\"width: 100%; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace;\"><option value=\"ipv4\">IPv4<\/option><option value=\"ipv6\">IPv6<\/option><\/select>\n        <\/div>\n<p>        <button id=\"wg-btn3\" class=\"button\" style=\"background: var(--accent, #4ade80); color: #0b1114; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">MTU berechnen<\/button>\n    <\/div>\n<div id=\"wg-ergebnis3\"><\/div>\n<\/div>\n<p><script>\n(function () {\n    \/\/ --- reine Rechenlogik, ohne jeden DOM-Zugriff ---<\/p>\n<p>    function ipZuZahl(text) {\n        const teile = String(text).trim().split('.');\n        if (teile.length !== 4) { return null; }\n        let wert = 0;\n        for (let i = 0; i < 4; i++) {\n            if (!\/^\\d{1,3}$\/.test(teile[i])) { return null; }\n            const n = parseInt(teile[i], 10);\n            if (n > 255) { return null; }\n            wert = wert * 256 + n;\n        }\n        return wert >>> 0;\n    }<\/p>\n<p>    function zahlZuIp(n) {\n        const a = Math.floor(n \/ 16777216) % 256;\n        const b = Math.floor(n \/ 65536) % 256;\n        const c = Math.floor(n \/ 256) % 256;\n        const d = n % 256;\n        return a + '.' + b + '.' + c + '.' + d;\n    }<\/p>\n<p>    function cidrText(block) {\n        return zahlZuIp(block.basis) + '\/' + block.praefix;\n    }<\/p>\n<p>    function formatZahl(n) {\n        return String(Math.round(n)).replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, ',');\n    }<\/p>\n<p>    function parseCidr(text) {\n        const roh = String(text).trim();\n        if (roh.length === 0) { return { fehler: 'leer', roh: roh }; }\n        const teile = roh.split('\/');\n        if (teile.length > 2) { return { fehler: 'cidr', roh: roh }; }\n        const adresse = ipZuZahl(teile[0]);\n        if (adresse === null) { return { fehler: 'cidr', roh: roh }; }\n        let praefix = 32;\n        if (teile.length === 2) {\n            const p = teile[1].trim();\n            if (!\/^\\d{1,3}$\/.test(p)) { return { fehler: 'praefix', roh: roh }; }\n            praefix = parseInt(p, 10);\n            if (praefix > 32) { return { fehler: 'praefix', roh: roh }; }\n        }\n        const groesse = Math.pow(2, 32 - praefix);\n        const basis = Math.floor(adresse \/ groesse) * groesse;\n        return {\n            fehler: null,\n            roh: roh,\n            basis: basis,\n            praefix: praefix,\n            groesse: groesse,\n            ende: basis + groesse - 1,\n            normalisiert: basis !== adresse\n        };\n    }<\/p>\n<p>    \/\/ rekursives Halbieren: Haelfte ganz ausserhalb -> behalten,\n    \/\/ ganz innerhalb einer Ausnahme -> verwerfen, sonst weiter teilen\n    function subtrahiere(basis, praefix, ausnahmen) {\n        const ergebnis = [];\n        let zaehler = 0;\n        let abbruch = false;<\/p>\n<p>        function schritt(b, p) {\n            if (abbruch) { return; }\n            zaehler = zaehler + 1;\n            if (zaehler > 200000) { abbruch = true; return; }\n            const groesse = Math.pow(2, 32 - p);\n            const ende = b + groesse - 1;\n            let ueberlappt = false;\n            for (let i = 0; i < ausnahmen.length; i++) {\n                const a = ausnahmen[i];\n                if (b >= a.basis && ende <= a.ende) { return; }\n                if (b <= a.ende &#038;&#038; ende >= a.basis) { ueberlappt = true; }\n            }\n            if (!ueberlappt) { ergebnis.push({ basis: b, praefix: p }); return; }\n            if (p >= 32) { return; }\n            schritt(b, p + 1);\n            schritt(b + groesse \/ 2, p + 1);\n        }<\/p>\n<p>        schritt(basis, praefix);\n        return { bloecke: ergebnis, abbruch: abbruch };\n    }<\/p>\n<p>    \/\/ benachbarte gleich grosse Bloecke wieder zusammenfassen\n    function fasseZusammen(bloecke) {\n        let liste = bloecke.slice().sort(function (x, y) {\n            if (x.basis !== y.basis) { return x.basis - y.basis; }\n            return x.praefix - y.praefix;\n        });\n        let geaendert = true;\n        while (geaendert) {\n            geaendert = false;\n            const neu = [];\n            let i = 0;\n            while (i < liste.length) {\n                const a = liste[i];\n                const b = i + 1 < liste.length ? liste[i + 1] : null;\n                if (b &#038;&#038; a.praefix === b.praefix &#038;&#038; a.praefix > 0) {\n                    const groesse = Math.pow(2, 32 - a.praefix);\n                    if (a.basis % (groesse * 2) === 0 && b.basis === a.basis + groesse) {\n                        neu.push({ basis: a.basis, praefix: a.praefix - 1 });\n                        i = i + 2;\n                        geaendert = true;\n                        continue;\n                    }\n                }\n                neu.push(a);\n                i = i + 1;\n            }\n            liste = neu;\n        }\n        return liste;\n    }<\/p>\n<p>    function formatiere(bloecke) {\n        return bloecke.map(cidrText).join(', ');\n    }<\/p>\n<p>    function berechne(gesamtText, ausnahmenText) {\n        const g = parseCidr(gesamtText);\n        if (g.fehler === 'leer') { return { fehler: { typ: 'leer' } }; }\n        if (g.fehler === 'praefix') { return { fehler: { typ: 'praefix', wert: g.roh } }; }\n        if (g.fehler) { return { fehler: { typ: 'cidr', wert: g.roh } }; }<\/p>\n<p>        const zeilen = String(ausnahmenText === undefined || ausnahmenText === null ? '' : ausnahmenText)\n            .split(\/[\\n\\r,;]+\/)\n            .map(function (t) { return t.trim(); })\n            .filter(function (t) { return t.length > 0; });<\/p>\n<p>        const ausnahmen = [];\n        const ignoriert = [];\n        const normalisiert = [];\n        if (g.normalisiert) { normalisiert.push({ von: g.roh, nach: cidrText(g) }); }<\/p>\n<p>        for (let i = 0; i < zeilen.length; i++) {\n            const a = parseCidr(zeilen[i]);\n            if (a.fehler === 'praefix') { return { fehler: { typ: 'praefix', wert: a.roh } }; }\n            if (a.fehler) { return { fehler: { typ: 'cidr', wert: a.roh } }; }\n            if (a.normalisiert) { normalisiert.push({ von: a.roh, nach: cidrText(a) }); }\n            if (a.ende < g.basis || a.basis > g.ende) { ignoriert.push(cidrText(a)); continue; }\n            ausnahmen.push(a);\n        }<\/p>\n<p>        const roh = subtrahiere(g.basis, g.praefix, ausnahmen);\n        if (roh.abbruch) { return { fehler: { typ: 'zuviel' } }; }\n        const bloecke = fasseZusammen(roh.bloecke);<\/p>\n<p>        let abgedeckt = 0;\n        for (let k = 0; k < bloecke.length; k++) {\n            abgedeckt = abgedeckt + Math.pow(2, 32 - bloecke[k].praefix);\n        }\n\n        return {\n            fehler: null,\n            gesamt: cidrText(g),\n            bloecke: bloecke,\n            allowedIPs: formatiere(bloecke),\n            anzahl: bloecke.length,\n            abgedeckt: abgedeckt,\n            gesamtGroesse: g.groesse,\n            ignoriert: ignoriert,\n            normalisiert: normalisiert\n        };\n    }\n\n    function lesePeers(text) {\n        const zeilen = String(text === undefined || text === null ? '' : text)\n            .split(\/[\\n\\r]+\/)\n            .map(function (t) { return t.trim(); })\n            .filter(function (t) { return t.length > 0; });<\/p>\n<p>        const peers = [];\n        for (let i = 0; i < zeilen.length; i++) {\n            const zeile = zeilen[i];\n            const pos = zeile.indexOf(':');\n            if (pos < 1) { return { fehler: { typ: 'name', wert: zeile } }; }\n            const name = zeile.slice(0, pos).trim();\n            if (name.length === 0) { return { fehler: { typ: 'name', wert: zeile } }; }\n            const teile = zeile.slice(pos + 1).split(',')\n                .map(function (t) { return t.trim(); })\n                .filter(function (t) { return t.length > 0; });\n            if (teile.length === 0) { return { fehler: { typ: 'ohnebereich', wert: name } }; }\n            const bereiche = [];\n            for (let j = 0; j < teile.length; j++) {\n                const c = parseCidr(teile[j]);\n                if (c.fehler === 'praefix') { return { fehler: { typ: 'praefix', wert: c.roh } }; }\n                if (c.fehler) { return { fehler: { typ: 'cidr', wert: c.roh } }; }\n                bereiche.push(c);\n            }\n            peers.push({ name: name, bereiche: bereiche });\n        }\n        if (peers.length < 2) { return { fehler: { typ: 'wenigpeers' } }; }\n        return { fehler: null, peers: peers };\n    }\n\n    \/\/ zwei IPv4-Bloecke sind entweder verschachtelt oder disjunkt:\n    \/\/ die Schnittmenge ist immer der spezifischere Block\n    function ueberschneidungen(peers) {\n        const paare = [];\n        for (let i = 0; i < peers.length; i++) {\n            for (let j = i + 1; j < peers.length; j++) {\n                const teile = [];\n                for (let x = 0; x < peers[i].bereiche.length; x++) {\n                    for (let y = 0; y < peers[j].bereiche.length; y++) {\n                        const a = peers[i].bereiche[x];\n                        const b = peers[j].bereiche[y];\n                        if (a.basis <= b.ende &#038;&#038; b.basis <= a.ende) {\n                            const enger = a.praefix >= b.praefix ? a : b;\n                            const t = cidrText(enger);\n                            if (teile.indexOf(t) === -1) { teile.push(t); }\n                        }\n                    }\n                }\n                if (teile.length > 0) {\n                    paare.push({ a: peers[i].name, b: peers[j].name, teile: teile });\n                }\n            }\n        }\n        return paare;\n    }<\/p>\n<p>    function mtuBerechnung(physisch, version) {\n        const roh = String(physisch === undefined || physisch === null ? '' : physisch).trim();\n        if (!\/^\\d{1,5}$\/.test(roh)) { return { fehler: { typ: 'mtu' } }; }\n        const n = parseInt(roh, 10);\n        if (n < 576 || n > 9200) { return { fehler: { typ: 'mtu' } }; }\n        const ipKopf = version === 'ipv6' ? 40 : 20;\n        const overhead = ipKopf + 8 + 32;\n        return {\n            fehler: null,\n            physisch: n,\n            ipKopf: ipKopf,\n            overhead: overhead,\n            tunnel: n - overhead,\n            version: version === 'ipv6' ? 'IPv6' : 'IPv4'\n        };\n    }<\/p>\n<p>    \/\/ fuer die Pruefung von aussen erreichbar\n    if (typeof window !== 'undefined') {\n        window.LW_TEST = window.LW_TEST || {};\n        window.LW_TEST.wg = {\n            berechne: berechne,\n            formatiere: formatiere,\n            ipZuZahl: ipZuZahl,\n            zahlZuIp: zahlZuIp,\n            parseCidr: parseCidr,\n            subtrahiere: subtrahiere,\n            fasseZusammen: fasseZusammen,\n            lesePeers: lesePeers,\n            ueberschneidungen: ueberschneidungen,\n            mtuBerechnung: mtuBerechnung\n        };\n    }<\/p>\n<p>    \/\/ --- DOM-Anbindung, sauber abgesichert ---<\/p>\n<p>    function esc(t) {\n        return String(t)\n            .replace(\/&\/g, '&amp;')\n            .replace(\/<\/g, '&lt;')\n            .replace(\/>\/g, '&gt;')\n            .replace(\/\"\/g, '&quot;');\n    }<\/p>\n<p>    const KASTEN = 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-radius: 6px; padding: 15px; margin-bottom: 12px;';\n    const MONO = 'font-family: monospace; color: var(--text-primary, #e8e8ee); word-break: break-all; line-height: 1.7;';\n    const KLEIN = 'color: var(--text-secondary, #9aa0aa); font-size: 0.8rem; margin: 0 0 6px 0; text-transform: uppercase; letter-spacing: 0.05em;';<\/p>\n<p>    function meldung(text) {\n        return '<\/p>\n<div style=\"' + KASTEN + ' border-color: var(--accent, #4ade80);\">' +\n            '<\/p>\n<p style=\"margin: 0; color: var(--text-primary, #e8e8ee);\">' + esc(text) + '<\/p>\n<\/div>\n<p>';\n    }<\/p>\n<p>    function fehlerText(f) {\n        if (f.typ === 'leer') { return 'Ein Gesamtbereich ist erforderlich, zum Beispiel 0.0.0.0\/0.'; }\n        if (f.typ === 'cidr') { return 'Kein g\u00fcltiger IPv4-CIDR-Block:' + ' ' + f.wert; }\n        if (f.typ === 'praefix') { return 'Das Pr\u00e4fix muss eine Zahl zwischen 0 und 32 sein:' + ' ' + f.wert; }\n        if (f.typ === 'zuviel') { return 'Daraus entstehen zu viele Bl\u00f6cke f\u00fcr die Berechnung. Weniger oder gr\u00f6\u00dfere Ausschl\u00fcsse helfen.'; }\n        if (f.typ === 'name') { return 'Eine Zeile braucht einen Peer-Namen gefolgt von einem Doppelpunkt, zum Beispiel office: 10.0.0.0\/8. Dieser Zeile fehlt er:' + ' ' + f.wert; }\n        if (f.typ === 'ohnebereich') { return 'Dieser Peer hat keine Netze:' + ' ' + f.wert; }\n        if (f.typ === 'wenigpeers') { return 'Mindestens zwei Peers erforderlich, einer pro Zeile.'; }\n        if (f.typ === 'mtu') { return 'Die physische MTU muss eine ganze Zahl zwischen 576 und 9200 sein.'; }\n        return 'Kein g\u00fcltiger IPv4-CIDR-Block:';\n    }<\/p>\n<p>    const btn = document.getElementById('wg-btn1');\n    const out = document.getElementById('wg-ergebnis1');\n    if (!btn || !out) { return; }\n    const btn2 = document.getElementById('wg-btn2');\n    const out2 = document.getElementById('wg-ergebnis2');\n    if (!btn2 || !out2) { return; }\n    const btn3 = document.getElementById('wg-btn3');\n    const out3 = document.getElementById('wg-ergebnis3');\n    if (!btn3 || !out3) { return; }<\/p>\n<p>    const feldGesamt = document.getElementById('wg-gesamt');\n    const feldAusnahmen = document.getElementById('wg-ausnahmen');\n    const feldPeers = document.getElementById('wg-peers');\n    const feldMtu = document.getElementById('wg-mtu');\n    const feldVersion = document.getElementById('wg-version');\n    if (!feldGesamt || !feldAusnahmen || !feldPeers || !feldMtu || !feldVersion) { return; }<\/p>\n<p>    btn.addEventListener('click', function () {\n        const r = berechne(feldGesamt.value, feldAusnahmen.value);\n        if (r.fehler) { out.innerHTML = meldung(fehlerText(r.fehler)); return; }\n        if (r.anzahl === 0) { out.innerHTML = meldung('Die Ausschl\u00fcsse decken den gesamten Bereich ab. F\u00fcr AllowedIPs bleibt nichts \u00fcbrig.'); return; }<\/p>\n<p>        let html = '<\/p>\n<div style=\"' + KASTEN + '\">' +\n            '<\/p>\n<p style=\"' + KLEIN + '\">AllowedIPs<\/p>\n<p>' +\n            '<\/p>\n<div style=\"' + MONO + '\">' + esc(r.allowedIPs) + '<\/div>\n<\/div>\n<p>';<\/p>\n<p>        const anteil = (r.abgedeckt \/ r.gesamtGroesse) * 100;\n        html += '<\/p>\n<div style=\"display: flex; gap: 12px; flex-wrap: wrap;\">' +\n            '<\/p>\n<div style=\"' + KASTEN + ' flex: 1; min-width: 150px;\">' +\n            '<\/p>\n<p style=\"' + KLEIN + '\">Bl\u00f6cke<\/p>\n<p>' +\n            '<\/p>\n<div style=\"' + MONO + ' font-size: 1.4rem;\">' + r.anzahl + '<\/div>\n<\/div>\n<p>' +\n            '<\/p>\n<div style=\"' + KASTEN + ' flex: 2; min-width: 220px;\">' +\n            '<\/p>\n<p style=\"' + KLEIN + '\">Abgedeckte Adressen<\/p>\n<p>' +\n            '<\/p>\n<div style=\"' + MONO + '\">' + formatZahl(r.abgedeckt) + ' \/ ' + formatZahl(r.gesamtGroesse) +\n            ' (' + anteil.toFixed(2) + ' %)<\/div>\n<\/div>\n<\/div>\n<p>';<\/p>\n<p>        if (r.normalisiert.length > 0) {\n            let zeilen = '';\n            for (let i = 0; i < r.normalisiert.length; i++) {\n                zeilen += '\n\n<div style=\"' + MONO + '\">' + esc(r.normalisiert[i].von) + ' &rarr; ' +\n                    esc(r.normalisiert[i].nach) + '<\/div>\n<p>';\n            }\n            html += '<\/p>\n<div style=\"' + KASTEN + '\">\n<p style=\"' + KLEIN + '\">Hostbits auf null gesetzt<\/p>\n<p>' + zeilen + '<\/p><\/div>\n<p>';\n        }<\/p>\n<p>        if (r.ignoriert.length > 0) {\n            html += '<\/p>\n<div style=\"' + KASTEN + '\">\n<p style=\"' + KLEIN + '\">Ignoriert, au\u00dferhalb des Gesamtbereichs<\/p>\n<p>' +\n                '<\/p>\n<div style=\"' + MONO + '\">' + esc(r.ignoriert.join(', ')) + '<\/div>\n<\/div>\n<p>';\n        }<\/p>\n<p>        out.innerHTML = html;\n    });<\/p>\n<p>    btn2.addEventListener('click', function () {\n        const gelesen = lesePeers(feldPeers.value);\n        if (gelesen.fehler) { out2.innerHTML = meldung(fehlerText(gelesen.fehler)); return; }<\/p>\n<p>        const paare = ueberschneidungen(gelesen.peers);\n        if (paare.length === 0) { out2.innerHTML = meldung('Keine \u00dcberschneidungen. Jede Adresse passt auf h\u00f6chstens einen Peer.'); return; }<\/p>\n<p>        let html = '<\/p>\n<div style=\"' + KASTEN + '\">\n<p style=\"' + KLEIN + '\">\u00dcberschneidende Peers<\/p>\n<p>';\n        html += '<\/p>\n<div style=\"display: flex; gap: 12px; ' + KLEIN + ' margin-top: 12px;\">' +\n            '<\/p>\n<div style=\"flex: 1;\">Peer-Paar<\/div>\n<div style=\"flex: 1;\">Gemeinsame Netze<\/div>\n<\/div>\n<p>';\n        for (let i = 0; i < paare.length; i++) {\n            html += '\n\n<div style=\"display: flex; gap: 12px; flex-wrap: wrap; padding: 8px 0; border-top: 1px solid var(--border, #2a2a35);\">' +\n                '<\/p>\n<div style=\"flex: 1; min-width: 160px; ' + MONO + '\">' + esc(paare[i].a) + ' &harr; ' + esc(paare[i].b) + '<\/div>\n<p>' +\n                '<\/p>\n<div style=\"flex: 1; min-width: 160px; ' + MONO + ' color: var(--accent, #4ade80);\">' +\n                esc(paare[i].teile.join(', ')) + '<\/div>\n<\/div>\n<p>';\n        }\n        html += '<\/p><\/div>\n<p>';\n        html += '<\/p>\n<div style=\"' + KASTEN + ' border-color: var(--accent, #4ade80);\">' +\n            '<\/p>\n<p style=\"' + KLEIN + '\">Warum das wichtig ist<\/p>\n<p>' +\n            '<\/p>\n<p style=\"margin: 0; color: var(--text-secondary, #9aa0aa);\">WireGuard w\u00e4hlt den Peer, dessen AllowedIPs zuletzt passen, nicht den mit der genauesten \u00dcbereinstimmung. Beanspruchen zwei Peers dieselben Adressen, nimmt der Verkehr klammheimlich den falschen Tunnel, ohne dass etwas einen Fehler meldet. Die Bereiche m\u00fcssen \u00fcberschneidungsfrei sein.<\/p>\n<\/div>\n<p>';<\/p>\n<p>        out2.innerHTML = html;\n    });<\/p>\n<p>    btn3.addEventListener('click', function () {\n        const r = mtuBerechnung(feldMtu.value, feldVersion.value);\n        if (r.fehler) { out3.innerHTML = meldung(fehlerText(r.fehler)); return; }<\/p>\n<p>        const kopf = r.version === 'IPv6' ? '40 (IPv6) + 8 (UDP) + 32 (WireGuard)' : '20 (IPv4) + 8 (UDP) + 32 (WireGuard)';\n        let html = '<\/p>\n<div style=\"display: flex; gap: 12px; flex-wrap: wrap;\">' +\n            '<\/p>\n<div style=\"' + KASTEN + ' flex: 1; min-width: 180px;\">' +\n            '<\/p>\n<p style=\"' + KLEIN + '\">Empfohlene Tunnel-MTU<\/p>\n<p>' +\n            '<\/p>\n<div style=\"' + MONO + ' font-size: 1.4rem; color: var(--accent, #4ade80);\">' + r.tunnel + ' Byte<\/div>\n<\/div>\n<p>' +\n            '<\/p>\n<div style=\"' + KASTEN + ' flex: 2; min-width: 240px;\">' +\n            '<\/p>\n<p style=\"' + KLEIN + '\">So setzt es sich zusammen<\/p>\n<p>' +\n            '<\/p>\n<div style=\"' + MONO + '\">' + kopf + ' = ' + r.overhead + ' Byte<\/div>\n<p>' +\n            '<\/p>\n<div style=\"' + MONO + '\">' + r.physisch + ' &minus; ' + r.overhead + ' = ' + r.tunnel + ' Byte<\/div>\n<p>' +\n            '<\/p><\/div>\n<\/div>\n<p>' +\n            '<\/p>\n<div style=\"' + KASTEN + '\">\n<p style=\"' + KLEIN + '\">Zeile f\u00fcr den Interface-Abschnitt<\/p>\n<p>' +\n            '<\/p>\n<div style=\"' + MONO + '\">[Interface]<br \/>MTU = ' + r.tunnel + '<\/div>\n<\/div>\n<p>';<\/p>\n<p>        out3.innerHTML = html;\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jeder WireGuard-Peer beantwortet eine einzige Frage: welche Zieladressen in den Tunnel geh\u00f6ren. Stimmt AllowedIPs nicht, l\u00e4uft Verkehr am Tunnel vorbei oder verschwindet im falschen, meist ohne eine einzige Fehlermeldung. Dieser Rechner deckt die drei Teile dieser Aufgabe ab. 1. Split-Tunnel: Netze aus einem Bereich herausschneiden Aus dem Bereich, den der Tunnel f\u00fchren soll, und den [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":9283,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"class_list":["post-9421","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>WireGuard AllowedIPs- und Split-Tunnel-Rechner - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"WireGuard AllowedIPs- und Split-Tunnel-Rechner - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Jeder WireGuard-Peer beantwortet eine einzige Frage: welche Zieladressen in den Tunnel geh\u00f6ren. Stimmt AllowedIPs nicht, l\u00e4uft Verkehr am Tunnel vorbei oder verschwindet im falschen, meist ohne eine einzige Fehlermeldung. Dieser Rechner deckt die drei Teile dieser Aufgabe ab. 1. Split-Tunnel: Netze aus einem Bereich herausschneiden Aus dem Bereich, den der Tunnel f\u00fchren soll, und den [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-10T11:45:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wireguard-allowedips-split-tunnel-calculator\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wireguard-allowedips-split-tunnel-calculator\\\/\",\"name\":\"WireGuard AllowedIPs- und Split-Tunnel-Rechner - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-08-10T11:37:13+00:00\",\"dateModified\":\"2026-08-10T11:45:05+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wireguard-allowedips-split-tunnel-calculator\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wireguard-allowedips-split-tunnel-calculator\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/de\\\/werkzeuge\\\/wireguard-allowedips-split-tunnel-calculator\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/toolbox-2\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"WireGuard AllowedIPs- und Split-Tunnel-Rechner\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"WireGuard AllowedIPs- und Split-Tunnel-Rechner - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/","og_locale":"en_US","og_type":"article","og_title":"WireGuard AllowedIPs- und Split-Tunnel-Rechner - Lukas Wojcik - Blog","og_description":"Jeder WireGuard-Peer beantwortet eine einzige Frage: welche Zieladressen in den Tunnel geh\u00f6ren. Stimmt AllowedIPs nicht, l\u00e4uft Verkehr am Tunnel vorbei oder verschwindet im falschen, meist ohne eine einzige Fehlermeldung. Dieser Rechner deckt die drei Teile dieser Aufgabe ab. 1. Split-Tunnel: Netze aus einem Bereich herausschneiden Aus dem Bereich, den der Tunnel f\u00fchren soll, und den [&hellip;]","og_url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/","og_site_name":"Lukas Wojcik - Blog","article_modified_time":"2026-08-10T11:45:05+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/","url":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/","name":"WireGuard AllowedIPs- und Split-Tunnel-Rechner - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-08-10T11:37:13+00:00","dateModified":"2026-08-10T11:45:05+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/de\/werkzeuge\/wireguard-allowedips-split-tunnel-calculator\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/toolbox-2\/"},{"@type":"ListItem","position":3,"name":"WireGuard AllowedIPs- und Split-Tunnel-Rechner"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9421","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=9421"}],"version-history":[{"count":1,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9421\/revisions"}],"predecessor-version":[{"id":9439,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9421\/revisions\/9439"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9283"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=9421"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}