W2026-ITS: Difference between revisions
| (63 intermediate revisions by 4 users not shown) | |||
| Line 1: | Line 1: | ||
=Organisatorisches und Anmeldung für [https://sar.informatik.hu-berlin.de/teaching/2026-w/2026w_ITSecurityWorkshop/#plan IT-Security Workshop] vom 28. September bis 9. Oktober [https://sar.informatik.hu-berlin.de/teaching/2026-w/2026w_ITSecurityWorkshop/#plan 2026]= |
=Organisatorisches und Anmeldung für [https://sar.informatik.hu-berlin.de/teaching/2026-w/2026w_ITSecurityWorkshop/#plan IT-Security Workshop] vom 28. September bis 9. Oktober [https://sar.informatik.hu-berlin.de/teaching/2026-w/2026w_ITSecurityWorkshop/#plan 2026]= |
||
Wenn Sie die unten genannten Themen interessant finden und in den ersten beiden Oktoberwochen Lust und Zeit haben sich damit auseinanderzusetzen, so finden Sie hier den angestrebten [https://sar.informatik.hu-berlin.de/teaching/2026-w/2026w_ITSecurityWorkshop/#plan Zeitplan] sowie die Möglichkeit sich und (optional) ein spannendes eigenes Thema [https://sar.informatik.hu-berlin.de/teaching/2026-w/2026w_ITSecurityWorkshop/#anmeldung anzumelden]. |
Wenn Sie die unten genannten Themen interessant finden und in den ersten beiden Oktoberwochen Lust und Zeit haben sich damit auseinanderzusetzen, so finden Sie hier den angestrebten [https://sar.informatik.hu-berlin.de/teaching/2026-w/2026w_ITSecurityWorkshop/#plan Zeitplan] sowie die Möglichkeit sich und (optional) ein spannendes eigenes Thema [https://sar.informatik.hu-berlin.de/teaching/2026-w/2026w_ITSecurityWorkshop/#anmeldung anzumelden]. |
||
Exklusiv für die Kommunikation der Teilnehmenden untereinander gibt es einen zugehörigen [https://moodle.hu-berlin.de/course/view.php?id= |
Exklusiv für die Kommunikation der Teilnehmenden untereinander gibt es einen zugehörigen [https://moodle.hu-berlin.de/course/view.php?id=143832 Moodle-Kurs mit Forum]. |
||
=Vorträge= |
|||
'''Freitag 9.10. 2026,''' [https://www.openstreetmap.org/search?query=Rudower%20Chaussee%2025%2012489%20Berlin#map=19/52.42944/13.53060 Rudower Chaussee 25], [https://www.openstreetmap.org/way/164560677 Haus 3], '''Raum 3'328''' (dritte Etage) |
|||
{| class="wikitable" style="text-align: left; background: #cfc;" |
|||
|- style="background: #fee;vertical-align:top;" |
|||
|- style="background: #dfd;" |
|||
| 10:00-10:15 || '''meet & greet''' || || |
|||
|- style="background: #ddf;" |
|||
| 10:15-11:00 || '''[[W2026-ITS#KI-Sicherheitsanalyse|KI-Sicherheitsanalyse]]''' || Philipp || |
|||
|- style="background: #eef;" |
|||
| 11:00-11:45 || '''[[W2026-ITS#KI-Sicherheitsanalyse|KI-Sicherheitsanalyse]]''' || Gabriel|| [[Media:KI-Sicherheitsanalyse.pdf | pdf]] |
|||
|- style="background: #dfd;" |
|||
| 11:45-12:30 || '''Mittagspause''' || || |
|||
|- style="background: #eef;" |
|||
| 12:30-13:15 || '''[[W2026-ITS#Daten-_und_Computerstrafrecht|Daten- und Computerstrafrecht]]''' || Elias || |
|||
|- style="background: #ddf;" |
|||
| 13:15-14:00 || '''[[W2026-ITS#OpenVPN-DCO%40%7BOPNsense%2CpfSense_2.9.0_CE%7D|OpenVPN-DCO@{OPNsense,pfSense 2.9.0 CE}]]''' || Ole || |
|||
|- style="background: #dfd;" |
|||
| 14:00-14:15 || '''Pause: Snack & Schnack''' || || |
|||
|- style="background: #eef;" |
|||
| 14:15-15:00 || '''[[W2026-ITS#Krypto-Inventarisierung_für_TLS|Krypto-Inventarisierung für TLS]]''' || Akim || |
|||
|- style="background: #ddf;" |
|||
| 15:00-15:45 || '''[[W2026-ITS#Von_ECDSA_zu_PQC-Signaturen:_Kryptoagile_Migrationsstrategien_für_die_digitale_Signaturprüfung_von_sensiblen_Daten|Von ECDSA zu PQC-Signaturen]]''' || Nasser || |
|||
|- style="background: #fee;" |
|||
| 15:45-16:00 || '''Zusammenfassung & Dank''' || [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] || |
|||
|} |
|||
=Themen= |
|||
<!-- |
|||
==<span style="color:green">Eigene Idee</span>== |
|||
Wie in jedem Jahr lebt der Workshop von Ihrem Engagement. Auch wenn ich glaube einige spannende Themen zur Auswahl zu stellen, habe ich Ihr Interesse vielleicht noch nicht perfekt getroffen und Sie haben selbst eine Themenidee, die Sie einbringen und bearbeiten möchten. Dann schreiben Sie mich gerne an oder stellen Sie Ihre Gedanken zum Workshopstart vor. |
|||
--> |
|||
==<span style="background:greenyellow">Von ECDSA zu PQC-Signaturen: Kryptoagile Migrationsstrategien für die digitale Signaturprüfung von sensiblen Daten</span>== |
|||
[Nasser] |
|||
Im Rahmen meiner Arbeit in der Vertrauensstelle am Robert Koch-Institut werden Daten mit hohem Schutzbedarf verarbeitet. Derzeit ist ECDSA eingesetzt, um durch eine Signatur die Integrität der Daten zu gewährleisten. Mit der fortschreitenden Entwicklung von „Cryptographically Relevant Quantum Computers (CRQC)“ geraten etablierte asymmetrische Signaturverfahren wie ECDSA langfristig unter Druck. |
|||
Im Rahmen des Themas soll untersucht werden, welche technischen, sicherheitsrelevanten und organisatorischen Herausforderungen bei der Migration von ECDSA zu Post-Quantum-Signaturverfahren, wie ML-DSA entstehen. Ein besonderer Schwerpunkt liegt dabei auf dem Konzept der Kryptoagilität, also der Fähigkeit eines Systems, kryptografische Verfahren flexibel auszutauschen oder parallel zu betreiben. |
|||
Ergänzend zur theoretischen Analyse wird ein kleiner Proof of Concept entwickelt. Dieser demonstriert die Kryptoagilität anhand einer bestehenden Signaturarchitektur, die sowohl ECDSA als auch ML-DSA unterstützen und optional einen parallelen Übergangsbetrieb ermöglichen soll. Ziel ist es anhand des Prototyps unter anderem Signatur- und Schlüsselgrößen, Laufzeiten sowie der Integrationsaufwand von klassischer- und PQC-Kryptographie zu vergleichen. |
|||
Verwendete Technologien: |
|||
* MS SQL-Server |
|||
* Python |
|||
* Linux (Ubuntu 24.04) |
|||
* .Net10 (Bietet Post-Quanten Algorithmen an) |
|||
==<span style="background:greenyellow">Daten- und Computerstrafrecht</span>== |
|||
[Elias] |
|||
Wer in der IT-Sicherheit arbeitet, bewegt sich schneller in strafrechtlich relevantem Terrain, als vielen bewusst ist. Ein hartkodiertes Passwort im Binary, ein offener Datenbankport, ein kurzer Blick "nur zur Kontrolle": Wo endet legitime Sicherheitsforschung, und wo beginnt das Ausspähen von Daten? |
|||
Der Beitrag bietet eine Einführung in das materielle Strafrecht und stellt die Dogmatik der "computerspezifischen" Delikte des besonderen Teils des Strafgesetzbuchs vor, hier insbesondere: |
|||
* §§ 202a ff. StGB: Ausspähen und Abfangen von Daten, die Vorbereitung desselben (sog. "Hackerparagraf") und Datenhehlerei |
|||
* § 263a StGB: Computerbetrug |
|||
* §§ 269 f. StGB: Fälschung beweiserheblicher Daten und Täuschung im Rechtsverkehr bei Datenverarbeitung |
|||
* §§ 303a f. StGB: Datenveränderung und Computersabotage |
|||
Dabei geht es vor allem um die Frage, wie die Rechtsprechung und die Literatur Tatbestandsmerkmale wie "nicht für ihn bestimmt", "gegen unberechtigten Zugang besonders gesichert" oder "Überwindung der Zugangssicherung" auslegen und ob diese Auslegung mit dem intuitiven Verständnis von Informatikern (den Seminarteilnehmern) übereinstimmt. |
|||
Die Materie werden wir gemeinsam anhand von Fallbeispielen erarbeiten. |
|||
Schwerpunktmäßig wollen wir zudem die vielbeachtete Entscheidung des AG Jülich, 17 Cs-230 Js 99/21-55/23, besprechen. Im Mittelpunkt steht hier ein Verfahren, das die IT-Szene seit 2021 beschäftigt: Ein freiberuflicher IT-Dienstleister stieß bei der Analyse einer E-Commerce-Software auf ein im Programm im Klartext hinterlegtes Datenbankpasswort, über das Daten von rund 700.000 Endkunden erreichbar waren. Er meldete die Lücke und erhielt statt eines Dankes eine Strafanzeige samt Hausdurchsuchung. Wir werden in der Diskussion eine gutachterliche Lösung des Falls erarbeiten und uns hierzu mit den in der Literatur und Rechtsprechung vertretenen Ansichten auseinandersetzen. |
|||
Zusatzthema (praktischer Teil): Es werden Ansätze untersucht, mit denen die "Prüfprogramme" der oben genannten Tatbestände in eine für KI-Assistenten ausführbare Form gebracht werden kann. In Ergänzung zu dem Thema der Kommilitonen, die sich mit dem Aufspüren von Sicherheitslücken mittels KI beschäftigen, soll auf einer Meta-Ebene betrachtet werden, wie das System seinen eigenen "Plan" unter strafrechtlichen Gesichtspunkten reflektieren kann. |
|||
==<span style="background:greenyellow">PQC@OpenVPN</span>== |
|||
[Rafael] |
|||
=Themen <span style="color:red">(DRAFT)</span>= |
|||
==PQC@OpenVPN== |
|||
OpenVPN ist eine weit verbreitete Open-Source-Lösung für sichere, verschlüsselte VPNs. OpenVPN ist (anders als WireGuard) hinsichtlich vieler Aspekte konfigurierbar und bietet zahlreiche Optionen. Hier sind also bei der Administration einige Überlegungen nötig, um sichere und auch performante Einstellungen zu wählen. Hinsichtlich der Performance ist OpenVPN im Verbindungsaufbau und oft auch im Transport der eigentlichen Nutzdaten oft langsamer als WireGuard. Der Verbindungsaufbau ist in WireGuard sehr strikt spezifiziert und dadurch effizient. Dies bedeutet aber auch, dass ein Austausch der Kryptoalgorithmen in WireGuard nicht einfach möglich ist. Hier bietet OpenVPN mehr Kryptoagilität, auch wenn dies intrinsisch mit mehr Komplexität somit einer höheren Zahl an Roundtrips zum Verbindungsaufbau bezahlt wird. Häufig wird für den Aufbau des Kontrollkanals TLS verwendet, so dass zur Absicherung gegen Quantencomputer auf die ab OpenSSL >= 3.5 vorhandenen Mechanismen zurückgegriffen werden soll. OpenVPN unterstützt (derzeit bereits oder zukünftig) drei Mechanismen zur Quantensicherheit: |
OpenVPN ist eine weit verbreitete Open-Source-Lösung für sichere, verschlüsselte VPNs. OpenVPN ist (anders als WireGuard) hinsichtlich vieler Aspekte konfigurierbar und bietet zahlreiche Optionen. Hier sind also bei der Administration einige Überlegungen nötig, um sichere und auch performante Einstellungen zu wählen. Hinsichtlich der Performance ist OpenVPN im Verbindungsaufbau und oft auch im Transport der eigentlichen Nutzdaten oft langsamer als WireGuard. Der Verbindungsaufbau ist in WireGuard sehr strikt spezifiziert und dadurch effizient. Dies bedeutet aber auch, dass ein Austausch der Kryptoalgorithmen in WireGuard nicht einfach möglich ist. Hier bietet OpenVPN mehr Kryptoagilität, auch wenn dies intrinsisch mit mehr Komplexität somit einer höheren Zahl an Roundtrips zum Verbindungsaufbau bezahlt wird. Häufig wird für den Aufbau des Kontrollkanals TLS verwendet, so dass zur Absicherung gegen Quantencomputer auf die ab OpenSSL >= 3.5 vorhandenen Mechanismen zurückgegriffen werden soll. OpenVPN unterstützt (derzeit bereits oder zukünftig) drei Mechanismen zur Quantensicherheit: |
||
# "poor man's post-quantum cryptography" in Gestalt von preshared symmetrischen Schlüsseln mit den Optionen <code>tls-crypt</code>, <code>tls-crypt-v2</code>, auf deren Basis dann die TLS-Schlüsselaushandlung ihrerseits verschlüsselt wird (in Version 2 mit nutzerindividuellen Schlüsseln). Dieser Mechanismus ist aber nicht vorwärtssicher unter dem Angreifermodell "Quantencomputer", |
# "poor man's post-quantum cryptography" in Gestalt von preshared symmetrischen Schlüsseln mit den Optionen <code>tls-crypt</code>, <code>tls-crypt-v2</code>, auf deren Basis dann die TLS-Schlüsselaushandlung ihrerseits verschlüsselt wird (in Version 2 mit nutzerindividuellen Schlüsseln). Dieser Mechanismus ist aber nicht vorwärtssicher unter dem Angreifermodell "Quantencomputer", |
||
| Line 35: | Line 113: | ||
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
||
==OpenVPN-DCO@{OPNsense,pfSense 2.9.0 CE}== |
==<span style="background:greenyellow">OpenVPN-DCO@{OPNsense,pfSense 2.9.0 CE}</span>== |
||
[Ole] |
|||
Mit dem gerade frisch veröffentlichten pfSense 2.9.0 CE und OPNsense stehen hier zwei weit verbreitete Kandidaten für frei verfügbare auf FreeBSD-basierende Firewalllösungen mit Webkonfigurationsmöglichkeit zur Auswahl, die auch DHCP, DNS und VPN-Lösungen unterstützen. |
Mit dem gerade frisch veröffentlichten pfSense 2.9.0 CE und OPNsense stehen hier zwei weit verbreitete Kandidaten für frei verfügbare auf FreeBSD-basierende Firewalllösungen mit Webkonfigurationsmöglichkeit zur Auswahl, die auch DHCP, DNS und VPN-Lösungen unterstützen. |
||
An unserem Institut fand schon an einigen Stellen pfSense Anwendung. Allerdings bietet hier die CE (also community edition) keine Unterstützung für OpenVPN mit "data channel offload" in den Kernel, so dass die Effizienz nicht so gut ist, wie sie sein könnte. Konkret ist bei pfSense das nötige Kernelmodul <code>/boot/modules/if_ovpn.ko</code> nicht vorhanden. Um hier (ohne zusätzliche Kosten) weiterzukommen sehe ich die folgenden Möglichkeiten: |
An unserem Institut fand schon an einigen Stellen pfSense Anwendung. Allerdings bietet hier die CE (also community edition) keine Unterstützung für OpenVPN mit "data channel offload" in den Kernel, so dass die Effizienz nicht so gut ist, wie sie sein könnte. Konkret ist bei pfSense das nötige Kernelmodul <code>/boot/modules/if_ovpn.ko</code> nicht vorhanden. Um hier (ohne zusätzliche Kosten) weiterzukommen sehe ich die folgenden Möglichkeiten: |
||
| Line 73: | Line 153: | ||
--> |
--> |
||
==Krypto-Inventarisierung für TLS== |
|||
=== Überblick === |
|||
Es werden zwei VMs verwendet, beide im libvirt-NAT-Netz <code>default</code> (192.168.122.0/24): |
|||
{| class="wikitable" |
|||
|- |
|||
! VM |
|||
! System |
|||
! Zweck |
|||
|- |
|||
| '''Build-VM''' |
|||
| FreeBSD 15.1-RELEASE |
|||
| Kompiliert das Modul; dient später auch als OpenVPN-Testclient |
|||
|- |
|||
| '''Test-VM''' |
|||
| pfSense CE 2.9.0 |
|||
| Liefert Kernel-Informationen; dort wird das Modul getestet |
|||
|} |
|||
Ablauf: |
|||
# Build-VM aufsetzen |
|||
# pfSense-Test-VM aufsetzen |
|||
# Kernel-Informationen der pfSense auslesen |
|||
# Passenden FreeBSD-Quellstand bestimmen |
|||
# Modul bauen |
|||
# Modul auf der pfSense laden und prüfen |
|||
# OpenVPN-Server DCO-tauglich konfigurieren |
|||
# pfSense-Patch für das Interface-Problem einspielen |
|||
# Funktionstest mit Client |
|||
=== Referenzwerte für pfSense CE 2.9.0 === |
|||
{| class="wikitable" |
|||
|- |
|||
! Merkmal |
|||
! Wert |
|||
|- |
|||
| Kernel (<code>uname -a</code>) |
|||
| <code>FreeBSD 16.0-CURRENT #12 RELENG_2_9_0-n256132-d8e3138ecf52</code>, gebaut am 17.08.2026 |
|||
|- |
|||
| <code>kern.osreldate</code> |
|||
| <code>1600018</code> |
|||
|- |
|||
| Kernelkonfiguration |
|||
| <code>pfSense</code>, vollständig in <code>kern.conftxt</code> eingebettet (417 Zeilen) |
|||
|- |
|||
| FreeBSD-<code>main</code>-Fenster mit 1600018 |
|||
| <code>1569e2334ab</code> (30.04.2026) bis <code>255538cd906</code> (19.06.2026, Sprung auf 1600019) |
|||
|- |
|||
| Verwendeter Build-Stand |
|||
| <code>7386c0675c8</code> (= <code>255538cd906^</code>, letzter Commit mit 1600018) |
|||
|- |
|||
| Abweichung der Konfiguration zu <code>main</code> |
|||
| nur <code>options NETGRAPH_ETF</code> (für <code>if_ovpn</code> irrelevant) |
|||
|} |
|||
Bei einem pfSense-Update ändern sich diese Werte, die Schritte 3 bis 6 sind dann zu wiederholen. |
|||
----- |
|||
=== 1. Build-VM aufsetzen (FreeBSD 15.1) === |
|||
==== 1.1 Image und VM ==== |
|||
Von der FreeBSD-Downloadseite das '''VM-Image''' für amd64 laden (Spalte „VM“, Format <code>.qcow2</code> für virt-manager/KVM). Die UFS- oder ZFS-Variante ist gleichermaßen geeignet. |
|||
Platte '''vor dem ersten Start''' vergrößern, da das Image nur ca. 6 GB groß ist: |
|||
<pre>xz -d FreeBSD-15.1-RELEASE-amd64-ufs.qcow2.xz |
|||
qemu-img resize FreeBSD-15.1-RELEASE-amd64-ufs.qcow2 60G</pre> |
|||
In virt-manager: |
|||
* „Vorhandenes Laufwerksabbild importieren“ und das <code>.qcow2</code>-Image auswählen |
|||
* Betriebssystem: '''„Generic OS“''' bzw. '''„Unknown OS“''' wählen, da FreeBSD 15.1 in der Liste nicht vorhanden ist |
|||
* Speicher: '''8192 MB''', CPUs: 4–8 |
|||
* Vor dem letzten Schritt '''„Konfiguration vor der Installation bearbeiten“''' anhaken, dann: |
|||
** Festplatte → Erweiterte Optionen → Festplattenbus: '''VirtIO''' |
|||
** NIC → Gerätemodell: '''virtio''' |
|||
** „Übernehmen“, danach „Installation beginnen“ |
|||
==== 1.2 Erster Start ==== |
|||
Login: <code>root</code>, kein Passwort. Die Konsole hat US-Tastaturbelegung (Y/Z vertauscht), umstellen mit <code>kbdcontrol -l de</code> und dauerhaft mit <code>sysrc keymap=de</code>. |
|||
==== 1.3 SSH (für bequemes Kopieren von Befehlen) ==== |
|||
Nur für Labor-VMs im NAT-Netz geeignet: |
|||
<pre>passwd |
|||
sysrc sshd_enable=YES |
|||
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config |
|||
ssh-keygen -A # Hostschlüssel erzeugen, sonst startet sshd nicht |
|||
service sshd start |
|||
ifconfig vtnet0 | grep inet</pre> |
|||
Vom Host: <code>ssh root@<IP der Build-VM></code> |
|||
Hängt die VM nach einem Neustart im Single-User-Modus (Prompt <code>root@:~ #</code> ohne Hostnamen, kein Netz), mit <code>exit</code> den normalen Start fortsetzen, ggf. vorher <code>fsck -y /</code>. |
|||
==== 1.4 Werkzeuge ==== |
|||
<pre>pkg install -y git tmux</pre> |
|||
Lange Builds in <code>tmux</code> ausführen (<code>tmux new -s build</code>, lösen mit <code>Strg+b d</code>, zurück mit <code>tmux attach -t build</code>). |
|||
----- |
|||
=== 2. pfSense-Test-VM aufsetzen (pfSense CE 2.9.0) === |
|||
==== 2.1 Installer ==== |
|||
pfSense CE wird nur noch über den '''Netgate Installer''' verteilt: kostenlos im Netgate-Shop, Variante '''„AMD64 ISO IPMI/Virtual Machines“'''. Es ist ein Online-Installer, die VM braucht beim Installieren Internet. |
|||
Die Datei im Terminal entpacken, nicht mit dem Archivprogramm des Desktops (das versucht auch die ISO selbst auszupacken): |
|||
<pre>gunzip netgate-installer-v1.2-RELEASE-amd64.iso.gz</pre> |
|||
==== 2.2 VM ==== |
|||
* „Lokales Installationsmedium (ISO)“ und die entpackte ISO auswählen |
|||
* Betriebssystem: '''„Generic OS“''' bzw. '''„Unknown OS“''' |
|||
* Speicher: '''4096 MB''', CPUs: 2, Platte: 20 GB, '''eine''' NIC im Netz <code>default</code> |
|||
* '''„Konfiguration vor der Installation bearbeiten“''' anhaken und wie bei der Build-VM Festplattenbus '''VirtIO''' und NIC-Gerätemodell '''virtio''' einstellen |
|||
* Im Installer: pfSense CE, Version 2.9.0 |
|||
* WAN = <code>vtnet0</code> (DHCP), LAN überspringen |
|||
==== 2.3 Zugriff im Labor ==== |
|||
Konsolenmenü '''8 (Shell)'''. Für SSH und Webinterface über das WAN-Interface: |
|||
<pre>pfSsh.php playback enablesshd |
|||
pfctl -d # Firewall aus, bis zum nächsten Regel-Reload/Neustart</pre> |
|||
* SSH: <code>ssh admin@<WAN-IP></code>, danach Menüpunkt 8 |
|||
* Web: <code>https://<WAN-IP></code>, Login <code>admin</code> / <code>pfsense</code> |
|||
* Im Setup-Wizard unter „Configure WAN Interface“ '''„Block RFC1918 Private Networks“ abwählen''' |
|||
----- |
|||
=== 3. Kernel-Informationen der pfSense auslesen === |
|||
Die eingebettete Kernelkonfiguration der pfSense auf die Build-VM holen (nur lesend, auch auf Produktivsystemen unbedenklich): |
|||
<pre># auf der pfSense (Shell, Menüpunkt 8) |
|||
sysctl -n kern.conftxt > /tmp/pfSense.conf |
|||
# auf der Build-VM |
|||
scp admin@<pfSense-IP>:/tmp/pfSense.conf /root/pfSense.conf</pre> |
|||
----- |
|||
=== 4. Passenden FreeBSD-Quellstand bestimmen === |
|||
<blockquote>'''Alle Befehle in diesem Abschnitt auf der Build-VM''' (FreeBSD 15.1, als <code>root</code>). Der Quellbaum liegt danach unter <code>/usr/src-main</code>. |
|||
</blockquote> |
|||
<blockquote>'''Abkürzung für pfSense CE 2.9.0:''' Der passende Stand ist bekannt (<code>7386c0675c8</code>, siehe Referenzwerte). Dann genügt '''4.1 (Klonen)''', danach direkt weiter mit Abschnitt 5. Alle Blöcke, die mit <code># OPTIONAL</code> beginnen, dienen nur dazu, den Stand für eine neue pfSense-Version herzuleiten oder zu kontrollieren. |
|||
</blockquote> |
|||
==== 4.1 FreeBSD <code>main</code> klonen ==== |
|||
<pre># Build-VM |
|||
git clone --filter=blob:none https://github.com/freebsd/freebsd-src.git /usr/src-main |
|||
cd /usr/src-main</pre> |
|||
<code>--filter=blob:none</code> lädt Dateiinhalte erst bei Bedarf und spart mehrere GB. |
|||
==== 4.2 Zeitfenster der <code>__FreeBSD_version</code> finden ''(optional bei bekannter Version)'' ==== |
|||
<pre># OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle) |
|||
# Build-VM, in /usr/src-main |
|||
git --no-pager log --since=2026-01-01 --format='%h %cd %s' --date=short \ |
|||
-G'#define __FreeBSD_version 16000(18|19)' -- sys/sys/param.h</pre> |
|||
<code>--since</code> begrenzt die Suche auf neuere Commits. Ohne die Begrenzung durchsucht <code>-G</code> die gesamte Geschichte von <code>param.h</code>, und Git lädt wegen <code>--filter=blob:none</code> jede alte Version einzeln von GitHub nach; das kann mehrere Minuten dauern. Bei einer späteren pfSense-Version das Datum entsprechend anpassen (etwa ein halbes Jahr vor dem Build-Datum aus <code>uname -a</code>). |
|||
Das Ergebnis zeigt den Commit, der 1600018 setzt, und den, der auf 1600019 erhöht. Kontrolle: |
|||
<pre># OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle) |
|||
# Build-VM, in /usr/src-main |
|||
git --no-pager show 255538cd906 -- sys/sys/param.h | grep FreeBSD_version</pre> |
|||
Der pfSense-Zweig wurde innerhalb dieses Fensters von <code>main</code> abgezweigt (das Build-Datum liegt später, die Basis ist älter). |
|||
Den Hash des letzten Commits mit 1600018 liefert: |
|||
<pre># OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle) |
|||
# Build-VM, in /usr/src-main |
|||
git rev-parse --short 255538cd906^ # ergibt 7386c0675c8</pre> |
|||
<code>^</code> bedeutet in Git „der Commit direkt davor“. |
|||
==== 4.3 Prüfen, ob die Wahl des Commits im Fenster eine Rolle spielt ''(optional bei bekannter Version)'' ==== |
|||
<pre># OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle) |
|||
# Build-VM, in /usr/src-main |
|||
# Änderungen am Modul selbst |
|||
git --no-pager log --oneline 1569e2334ab..255538cd906 -- \ |
|||
sys/net/if_ovpn.c sys/net/if_ovpn.h sys/modules/if_ovpn |
|||
# Änderungen an Headern, auf die das Modul zugreift |
|||
git --no-pager log -p 1569e2334ab..255538cd906 -- \ |
|||
sys/net/if_var.h sys/net/if_private.h sys/sys/mbuf.h \ |
|||
sys/netinet/in_pcb.h sys/netinet/udp_var.h sys/opencrypto/cryptodev.h \ |
|||
sys/net/vnet.h sys/sys/nv.h</pre> |
|||
Kritisch wären neue oder entfernte Felder in Strukturen (z. B. <code>struct ifnet</code>, <code>struct mbuf</code>), weil sich dann Speicher-Offsets verschieben. Bei 2.9.0 gab es im Fenster keine Änderung am Modul und nur zwei harmlose Header-Commits (ein Kommentar in <code>struct ifnet</code>, eine neue Inline-Funktion in <code>mbuf.h</code>). |
|||
<blockquote>'''Restrisiko:''' Netgates nicht veröffentlichte Kerneländerungen können nicht geprüft werden. Ob das Modul binär passt, zeigt erst der Lade- und Lasttest. |
|||
</blockquote> |
|||
----- |
|||
=== 5. Modul bauen === |
|||
<blockquote>'''Alle Befehle in diesem Abschnitt auf der Build-VM''' (FreeBSD 15.1, als <code>root</code>), im Quellbaum <code>/usr/src-main</code>. |
|||
</blockquote> |
|||
<pre># Build-VM |
|||
cd /usr/src-main |
|||
git checkout 7386c0675c8 # = 255538cd906^, der Commit vor dem Sprung auf 1600019 |
|||
ls sys/net/if_ovpn.c sys/modules/if_ovpn # OPTIONAL: Kontrolle, ob die Modulquellen da sind |
|||
cp /root/pfSense.conf sys/amd64/conf/PFSENSE</pre> |
|||
Unbekannte Optionen/Geräte in der pfSense-Konfiguration finden ''(optional bei bekannter Version: für 2.9.0 ist das Ergebnis <code>NETGRAPH_ETF</code>)'': |
|||
<pre># OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle) |
|||
# Build-VM |
|||
cd /usr/src-main/sys |
|||
for o in $(awk '$1=="options"{sub(/=.*/,"",$2); print $2}' amd64/conf/PFSENSE); do |
|||
grep -qwE "^$o" conf/options conf/options.amd64 || echo "option: $o" |
|||
done |
|||
for d in $(awk '$1=="device"{print $2}' amd64/conf/PFSENSE); do |
|||
grep -qwE "$d" conf/files conf/files.amd64 conf/files.x86 || echo "device: $d" |
|||
done</pre> |
|||
<code>CONFIG_AUTOGENERATED</code> ist ein Fehlalarm (wird von <code>config(8)</code> akzeptiert). Bei 2.9.0 ist nur <code>NETGRAPH_ETF</code> unbekannt; auskommentieren: |
|||
<pre># Build-VM |
|||
cd /usr/src-main |
|||
sed -i '' 's/^options[[:space:]]*NETGRAPH_ETF/#&/' sys/amd64/conf/PFSENSE</pre> |
|||
Bauen (im <code>tmux</code>, damit der Build weiterläuft, falls die SSH-Verbindung abbricht): |
|||
<pre># Build-VM: tmux-Sitzung starten (oder mit "tmux attach -t build" wieder aufnehmen) |
|||
tmux new -s build</pre> |
|||
Lösen der Sitzung, ohne den Build abzubrechen: <code>Strg+b</code>, dann <code>d</code>. Wieder verbinden: <code>tmux attach -t build</code>. Alle Sitzungen anzeigen: <code>tmux ls</code>. |
|||
In der tmux-Sitzung: |
|||
<pre># Build-VM, in /usr/src-main |
|||
cd /usr/src-main |
|||
make -j$(sysctl -n hw.ncpu) kernel-toolchain 2>&1 | tee /root/toolchain.log |
|||
make -j$(sysctl -n hw.ncpu) buildkernel KERNCONF=PFSENSE MODULES_OVERRIDE=if_ovpn \ |
|||
2>&1 | tee /root/buildkernel.log</pre> |
|||
Nach dem Build die tmux-Sitzung beenden: |
|||
<pre># Build-VM, in der tmux-Sitzung |
|||
exit</pre> |
|||
<code>exit</code> schließt die Sitzung endgültig. Soll sie für spätere Builds erhalten bleiben, stattdessen mit <code>Strg+b</code>, dann <code>d</code> lösen. |
|||
<code>kernel-toolchain</code> baut den passenden Compiler aus dem Quellbaum (einmalig, 30–90 min). <code>buildkernel</code> baut den Kernel mit der pfSense-Konfiguration, damit das Modul mit identischen Optionen (<code>RSS</code>, <code>RATELIMIT</code>, <code>VIMAGE</code> …) kompiliert wird; mit vorhandener Toolchain dauert das wenige Minuten. |
|||
Ergebnis: |
|||
<pre># Build-VM |
|||
find /usr/obj/usr/src-main -name if_ovpn.ko -exec ls -l {} \; |
|||
# …/sys/PFSENSE/modules/usr/src-main/sys/modules/if_ovpn/if_ovpn.ko (ca. 90 KB)</pre> |
|||
----- |
|||
=== 6. Modul auf der pfSense laden === |
|||
<pre># Build-VM |
|||
scp /usr/obj/usr/src-main/amd64.amd64/sys/PFSENSE/modules/usr/src-main/sys/modules/if_ovpn/if_ovpn.ko \ |
|||
admin@<pfSense-IP>:/tmp/</pre> |
|||
<pre># pfSense |
|||
cp /tmp/if_ovpn.ko /boot/modules/ |
|||
kldload -v /boot/modules/if_ovpn.ko |
|||
kldstat | grep ovpn |
|||
dmesg | tail -20</pre> |
|||
'''Nicht in <code>/boot/loader.conf(.local)</code> eintragen.''' Nach einem Neustart oder Update startet das System so garantiert ohne das Modul. Nach einem Neustart bei Bedarf erneut <code>kldload if_ovpn</code>. |
|||
----- |
|||
=== 7. OpenVPN-Server DCO-tauglich konfigurieren === |
|||
Die CE-Oberfläche bietet '''keine DCO-Option'''. OpenVPN 2.7 nutzt DCO automatisch, sobald das Modul geladen ist und die Konfiguration verträglich ist; andernfalls schaltet es DCO still ab (<code>disable_dco = ENABLED</code> im Log, bei Verbosity ≥ 4). Mit dem Patch aus Abschnitt 8 trifft pfSense diese Entscheidung selbst nach denselben Regeln und schreibt sie eindeutig in die Konfiguration. |
|||
Voraussetzungen für DCO: |
|||
{| class="wikitable" |
|||
|- |
|||
! Einstellung |
|||
! Wert |
|||
|- |
|||
| Protocol |
|||
| UDP |
|||
|- |
|||
| Data Encryption Algorithms |
|||
| nur AES-GCM und/oder CHACHA20-POLY1305 |
|||
|- |
|||
| '''Fallback Data Encryption Algorithm''' |
|||
| '''AES-256-GCM''' (Standard ist AES-256-CBC, das '''verhindert DCO''') |
|||
|- |
|||
| Modus |
|||
| TLS-basiert (SSL/TLS, ggf. mit User Auth), kein Shared Key |
|||
|- |
|||
| Tunnelnetz |
|||
| z. B. <code>/24</code> mit Topology ''Subnet'', '''kein /30''' |
|||
|- |
|||
| Compression |
|||
| aus (''Refuse any non-stub compression'') |
|||
|- |
|||
| Client Specific Overrides |
|||
| '''keine <code>iroute</code>-Einträge''' (unter FreeBSD mit DCO nicht unterstützt) |
|||
|} |
|||
Der Fallback-Algorithmus wird automatisch in <code>data-ciphers</code> aufgenommen. Typische Logmeldung, wenn er falsch steht: |
|||
<pre>Note: --data-ciphers-fallback with cipher 'AES-256-CBC' disables data channel offload.</pre> |
|||
Kontrolle der erzeugten Konfiguration (wird aus der GUI generiert, nicht von Hand bearbeiten): |
|||
<pre>grep -iE 'cipher|topology|dev' /var/etc/openvpn/server1/config.ovpn |
|||
grep -iE 'disable_dco|offload|note|dco|error' /var/log/openvpn.log | tail -20</pre> |
|||
Optional, für einen hybriden Post-Quanten-Handshake im Kontrollkanal (unabhängig von DCO), unter ''Custom options'': |
|||
<pre>tls-version-min 1.3;tls-groups SecP384r1MLKEM1024:secp521r1</pre> |
|||
----- |
|||
=== 8. Interface-Problem und pfSense-Patch === |
|||
==== 8.1 Das Problem ==== |
|||
pfSense CE legt vor dem Start von OpenVPN ein klassisches '''<code>tun</code>-Interface''' an und benennt es in <code>ovpnsN</code> um (<code>dev-node /dev/tunN</code> in der Konfiguration). DCO benötigt aber ein <code>if_ovpn</code>-Interface. Ist das Modul geladen und die Konfiguration DCO-tauglich, übernimmt OpenVPN das vorhandene <code>tun</code>-Interface und scheitert: |
|||
<pre>dco_set_ifmode: failed to set ifmode=00008002: Invalid argument (errno=22) |
|||
DCO device ovpns1 already exists, won't be destroyed at shutdown</pre> |
|||
<code>ifconfig ovpns1</code> zeigt dann weiterhin <code>groups: tun openvpn</code>. '''Dieser Zustand ist defekt.''' OpenVPN läuft, kann aber keine Daten übertragen. |
|||
Unterscheidung der Modi am Interface: |
|||
{| class="wikitable" |
|||
|- |
|||
! Modus |
|||
! <code>ifconfig ovpnsN</code> |
|||
|- |
|||
| klassisch (<code>tun</code>) |
|||
| <code>groups: tun openvpn</code>, <code>Opened by PID …</code> |
|||
|- |
|||
| DCO (<code>if_ovpn</code>) |
|||
| <code>groups: openvpn</code> |
|||
|} |
|||
==== 8.2 Die Lösung: Patch für <code>/etc/inc/openvpn.inc</code> ==== |
|||
Die Datei <code>pfsense-openvpn-dco.patch</code> (vollständig im Anhang) erweitert die Funktion, in der pfSense die OpenVPN-Konfiguration schreibt und das Interface anlegt: |
|||
* <code>openvpn_dco_usable()</code> entscheidet pro Instanz, ob DCO genutzt wird. Bedingungen: <code>if_ovpn</code> geladen, Device-Mode <code>tun</code>, UDP, kein Shared-Key-Modus, alle Data-Ciphers '''und''' der Fallback aus AES-128-GCM / AES-256-GCM / CHACHA20-POLY1305, keine Kompression, Tunnelnetz größer als /30, und kein <code>disable-dco</code> (bzw. <code>fragment</code>, <code>comp-lzo</code>, <code>compress</code>) in den Custom options. |
|||
* Hat das vorhandene <code>ovpnsN</code> den falschen Typ, wird die Instanz beendet (mit Warten auf das Prozessende) und das Interface entfernt (mit Warten, bis es wirklich weg ist). <code>tap</code>-Interfaces werden nie angefasst. |
|||
* Mit DCO wird <code>ifconfig ovpn create</code> statt <code>tun</code> verwendet und <code>dev-node</code> weggelassen. Schlägt das Anlegen fehl, fällt der Code mit einer Warnung auf <code>tun</code> zurück. |
|||
* Ohne DCO wird explizit <code>disable-dco</code> in die Konfiguration geschrieben, damit OpenVPN nie eigenmächtig umschaltet. |
|||
Verhalten: |
|||
{| class="wikitable" |
|||
|- |
|||
! Situation |
|||
! Interface |
|||
! Konfiguration |
|||
|- |
|||
| Modul nicht geladen (z. B. nach Neustart) |
|||
| <code>tun</code> |
|||
| <code>dev-node</code> + <code>disable-dco</code> |
|||
|- |
|||
| Modul geladen, Instanz DCO-tauglich |
|||
| <code>ovpn</code> (DCO) |
|||
| ohne <code>dev-node</code>, ohne <code>disable-dco</code> |
|||
|- |
|||
| Modul geladen, aber <code>disable-dco</code> in Custom options |
|||
| <code>tun</code> |
|||
| <code>dev-node</code> + <code>disable-dco</code> |
|||
|- |
|||
| Modul geladen, Instanz nicht DCO-tauglich (z. B. CBC-Fallback, TCP) |
|||
| <code>tun</code> |
|||
| <code>dev-node</code> + <code>disable-dco</code> |
|||
|} |
|||
<code>disable-dco</code> in den Custom options dient damit als '''Notschalter pro Server''', ganz ohne Änderung an der Oberfläche. |
|||
Im Systemlog erscheint bei DCO der Hinweis: |
|||
<pre>php-cgi[…]: OpenVPN ovpns1: using data channel offload (if_ovpn)</pre> |
|||
==== 8.3 Einspielen über das Webinterface ==== |
|||
Das Paket ''System Patches'' ist in pfSense CE 2.9.0 '''vorinstalliert''' und taucht deshalb nicht unter „Available Packages“ auf. |
|||
# '''System → Patches → „+ Add New Patch“''' |
|||
#* Description: <code>OpenVPN DCO (if_ovpn)</code> |
|||
#* Patch Contents: kompletter Inhalt von <code>pfsense-openvpn-dco.patch</code> |
|||
#* '''Path Strip Count: <code>1</code>''', '''Base Directory: <code>/</code>''' |
|||
#* Auto Apply: vorerst nicht anhaken |
|||
# '''Save''', dann in der Liste '''Debug''' (Probelauf), danach '''Apply'''. |
|||
Eine neuere Fassung des Patches einspielen: zuerst '''Revert''', dann über das Bleistift-Symbol den Inhalt ersetzen, '''Save''', '''Debug''', '''Apply'''. |
|||
Alternativ in der Shell: <code>cd / && patch -p1 -b < /tmp/pfsense-openvpn-dco.patch</code> (zurück mit <code>patch -R -p1 < …</code>). |
|||
==== 8.4 Testen ==== |
|||
<pre>kldstat | grep ovpn || kldload if_ovpn |
|||
pfSsh.php playback svc restart openvpn server 1 |
|||
ifconfig ovpns1 | grep groups # openvpn |
|||
grep -E 'dev-node|disable-dco' /var/etc/openvpn/server1/config.ovpn # keine Ausgabe |
|||
grep 'if_ovpn' /var/log/system.log | tail -2</pre> |
|||
Laborergebnis mit pfSense CE 2.9.0 (Patch-Fassung v4): |
|||
{| class="wikitable" |
|||
|- |
|||
! Test |
|||
! Ergebnis |
|||
|- |
|||
| Neustart ohne Modul |
|||
| <code>tun openvpn</code>, <code>dev-node</code> + <code>disable-dco</code> ✔ |
|||
|- |
|||
| Modul laden, Dienst neu starten |
|||
| automatisch <code>openvpn</code> (DCO) ✔ |
|||
|- |
|||
| <code>disable-dco</code> eintragen → entfernen → wieder eintragen (je ''Save'') |
|||
| <code>tun</code> → <code>openvpn</code> → <code>tun</code> ✔, mehrfach wiederholt |
|||
|} |
|||
----- |
|||
=== 9. Funktionstest mit Client (Build-VM) === |
|||
FreeBSD 15.1 bringt <code>if_ovpn</code> im Standardkernel mit; die Build-VM nutzt als Client damit ebenfalls DCO. |
|||
<pre>pkg install -y openvpn iperf3 |
|||
kldload if_ovpn # dauerhaft: sysrc kld_list+=if_ovpn |
|||
mkdir -p /usr/local/etc/openvpn |
|||
cd /usr/local/etc/openvpn |
|||
scp admin@<pfSense-IP>:/var/etc/openvpn/server1/tls-auth ta.key |
|||
scp 'admin@<pfSense-IP>:/var/etc/openvpn/server1/ca/*.0' ca.crt</pre> |
|||
Client-Zertifikat und -Schlüssel im Webinterface exportieren (''System → Certificates → Certificates'', Symbole „Export Certificate“ und „Export Key“) und als <code>client.crt</code> / <code>client.key</code> ablegen; <code>chmod 600 client.key</code>. |
|||
<code>/usr/local/etc/openvpn/client.conf</code>: |
|||
<pre>client |
|||
dev tun |
|||
proto udp4 |
|||
remote <pfSense-IP> 1194 |
|||
nobind |
|||
ca /usr/local/etc/openvpn/ca.crt |
|||
cert /usr/local/etc/openvpn/client.crt |
|||
key /usr/local/etc/openvpn/client.key |
|||
tls-auth /usr/local/etc/openvpn/ta.key 1 |
|||
auth SHA256 |
|||
remote-cert-tls server |
|||
data-ciphers AES-256-GCM:CHACHA20-POLY1305 |
|||
tls-version-min 1.3 |
|||
tls-groups SecP384r1MLKEM1024:secp521r1 |
|||
explicit-exit-notify 1 |
|||
verb 4</pre> |
|||
Die Richtung bei <code>tls-auth</code> ist <code>1</code> (Server: <code>0</code>); <code>auth</code> muss zum Server passen. Verwendet der Server <code>tls-crypt</code>, entsprechend <code>tls-crypt …</code> ohne Richtung. |
|||
<pre>openvpn --config /usr/local/etc/openvpn/client.conf |
|||
# zweites tmux-Fenster: |
|||
ping -c 5 10.8.0.1</pre> |
|||
Erwartete Logzeilen: |
|||
<pre>Control Channel: TLSv1.3, … key agreement: SecP384r1MLKEM1024 |
|||
DCO device tun0 opened |
|||
Initialization Sequence Completed |
|||
Data Channel: cipher 'AES-256-GCM', peer-id: 0</pre> |
|||
'''Laborergebnis (pfSense CE 2.9.0):''' Tunnel aufgebaut, DCO auf Server und Client aktiv, hybrider PQ-Handshake, Ping ohne Verluste (ca. 1,5 ms). Kein Absturz. |
|||
----- |
|||
=== Wichtige Hinweise für den Betrieb === |
|||
* Nach '''jedem pfSense-Update''' muss das Modul neu gebaut werden. Ein unpassendes Modul kann den Kernel zum Absturz bringen. |
|||
* Modul und Patch gehören zusammen. Ohne Patch schaltet ein DCO-tauglicher Server (z. B. mit GCM-Fallback) beim Laden des Moduls in den defekten Zustand aus Abschnitt 8.1. |
|||
* Nach einem Update zuerst prüfen, ob der Patch noch angewendet werden kann (System → Patches → Debug). Ändert Netgate die betroffenen Codestellen, muss der Patch angepasst werden. |
|||
* Einzelne Server lassen sich jederzeit mit <code>disable-dco</code> in den Custom options vom DCO-Betrieb ausnehmen. |
|||
----- |
|||
=== Anhang: <code>pfsense-openvpn-dco.patch</code> === |
|||
<pre>--- a/etc/inc/openvpn.inc |
|||
+++ b/etc/inc/openvpn.inc |
|||
@@ -209,6 +209,134 @@ |
|||
return($list); |
|||
} |
|||
+/* |
|||
+ * DCO patch (local, not from Netgate): helpers for OpenVPN Data Channel |
|||
+ * Offload with a self-built if_ovpn.ko on pfSense CE. |
|||
+ */ |
|||
+ |
|||
+/* Is the if_ovpn kernel module loaded? */ |
|||
+function openvpn_dco_module_loaded() : bool { |
|||
+ $out = []; |
|||
+ $rc = 1; |
|||
+ exec('/sbin/kldstat -q -n if_ovpn', $out, $rc); |
|||
+ return ($rc === 0); |
|||
+} |
|||
+ |
|||
+/* |
|||
+ * Can this instance use DCO? Mirrors the restrictions of OpenVPN and the |
|||
+ * FreeBSD if_ovpn driver. If anything is unclear, answer "no" so the |
|||
+ * instance keeps working in classic tun mode. |
|||
+ */ |
|||
+function openvpn_dco_usable(string $mode, array $settings) : bool { |
|||
+ if (!openvpn_dco_module_loaded()) { |
|||
+ return false; |
|||
+ } |
|||
+ /* DCO only supports layer 3 (tun) */ |
|||
+ if (array_get_path($settings, 'dev_mode', 'tun') !== 'tun') { |
|||
+ return false; |
|||
+ } |
|||
+ /* DCO only supports UDP */ |
|||
+ if (strncasecmp(array_get_path($settings, 'protocol', ''), 'UDP', 3) !== 0) { |
|||
+ return false; |
|||
+ } |
|||
+ /* DCO requires a TLS-based mode, no static shared key */ |
|||
+ if (array_get_path($settings, 'mode', '') === 'p2p_shared_key') { |
|||
+ return false; |
|||
+ } |
|||
+ /* All data ciphers and the fallback cipher must be supported by DCO */ |
|||
+ $dco_ciphers = ['AES-128-GCM', 'AES-256-GCM', 'CHACHA20-POLY1305']; |
|||
+ $ciphers = preg_split('/[,:]/', array_get_path($settings, 'data_ciphers', ''), -1, PREG_SPLIT_NO_EMPTY); |
|||
+ $ciphers[] = array_get_path($settings, 'data_ciphers_fallback', ''); |
|||
+ foreach ($ciphers as $cipher) { |
|||
+ if (!in_array(strtoupper(trim($cipher)), $dco_ciphers, true)) { |
|||
+ return false; |
|||
+ } |
|||
+ } |
|||
+ /* No compression */ |
|||
+ if (array_get_path($settings, 'allow_compression', 'no') !== 'no') { |
|||
+ return false; |
|||
+ } |
|||
+ /* /30 or smaller peer-to-peer tunnel networks are not DCO compatible */ |
|||
+ $tunnel_network = array_get_path($settings, 'tunnel_network', ''); |
|||
+ if (!empty($tunnel_network)) { |
|||
+ list($ip, $cidr) = openvpn_gen_tunnel_network($tunnel_network); |
|||
+ if (is_numeric($cidr) && ((int)$cidr >= 30)) { |
|||
+ return false; |
|||
+ } |
|||
+ } |
|||
+ /* Per-instance opt-out and options that disable DCO anyway */ |
|||
+ if (preg_match('/(^|[;\s])(disable-dco|fragment|comp-lzo|compress)\b/', |
|||
+ array_get_path($settings, 'custom_options', ''))) { |
|||
+ return false; |
|||
+ } |
|||
+ return true; |
|||
+} |
|||
+ |
|||
+/* |
|||
+ * Does the interface exist right now? Asks the kernel directly instead of |
|||
+ * does_interface_exist(), which may answer from a cached interface list |
|||
+ * and then still reports an interface that was just destroyed. |
|||
+ */ |
|||
+function openvpn_dco_if_exists(string $ifname) : bool { |
|||
+ $out = []; |
|||
+ $rc = 1; |
|||
+ exec('/sbin/ifconfig ' . escapeshellarg($ifname) . ' >/dev/null 2>&1', $out, $rc); |
|||
+ return ($rc === 0); |
|||
+} |
|||
+ |
|||
+/* |
|||
+ * Stop the OpenVPN instance and remove its interface, waiting until both |
|||
+ * are really gone. Without waiting, the exiting process can still hold or |
|||
+ * remove the interface while the new one is being created. |
|||
+ */ |
|||
+function openvpn_dco_stop_and_destroy(string $ifname, string $pidfile) : void { |
|||
+ $pf = escapeshellarg($pidfile); |
|||
+ if (file_exists($pidfile)) { |
|||
+ mwexec("/bin/pkill -TERM -F {$pf}"); |
|||
+ /* wait up to 10 s for the process to exit */ |
|||
+ for ($i = 0; $i < 100; $i++) { |
|||
+ $out = []; |
|||
+ $rc = 1; |
|||
+ exec("/bin/pgrep -F {$pf}", $out, $rc); |
|||
+ if ($rc !== 0) { |
|||
+ break; |
|||
+ } |
|||
+ usleep(100000); |
|||
+ } |
|||
+ if ($rc === 0) { |
|||
+ mwexec("/bin/pkill -KILL -F {$pf}"); |
|||
+ usleep(500000); |
|||
+ } |
|||
+ } |
|||
+ /* remove the interface and wait up to 5 s until it is gone */ |
|||
+ for ($i = 0; $i < 50 && openvpn_dco_if_exists($ifname); $i++) { |
|||
+ if (($i % 10) == 0) { |
|||
+ exec("/sbin/ifconfig " . escapeshellarg($ifname) . " destroy >/dev/null 2>&1"); |
|||
+ } |
|||
+ usleep(100000); |
|||
+ } |
|||
+ if (openvpn_dco_if_exists($ifname)) { |
|||
+ syslog(LOG_WARNING, "OpenVPN {$ifname}: could not remove interface to switch DCO mode"); |
|||
+ } |
|||
+ /* refresh pfSense's cached interface list */ |
|||
+ does_interface_exist($ifname, true); |
|||
+} |
|||
+ |
|||
+/* Kind of an existing interface: 'tun', 'tap', 'ovpn' or null if missing */ |
|||
+function openvpn_if_kind(string $ifname) : ?string { |
|||
+ if (!openvpn_dco_if_exists($ifname)) { |
|||
+ return null; |
|||
+ } |
|||
+ foreach (['tun', 'tap'] as $group) { |
|||
+ $out = []; |
|||
+ exec('/sbin/ifconfig -g ' . escapeshellarg($group) . ' 2>/dev/null', $out); |
|||
+ if (in_array($ifname, array_map('trim', $out), true)) { |
|||
+ return $group; |
|||
+ } |
|||
+ } |
|||
+ return 'ovpn'; |
|||
+} |
|||
+ |
|||
function openvpn_name(string $mode, array $settings, string $type = 'if') : string { |
|||
switch ($type) { |
|||
case 'if': |
|||
@@ -836,16 +964,47 @@ |
|||
$tunname = openvpn_name($mode, $settings, 'dev'); |
|||
$devname = openvpn_name($mode, $settings); |
|||
- /* is our device already configured */ |
|||
- if (!does_interface_exist($devname)) { |
|||
+ /* DCO patch: decide between if_ovpn (DCO) and classic tun */ |
|||
+ $use_dco = openvpn_dco_usable($mode, $settings); |
|||
+ |
|||
+ /* |
|||
+ * DCO patch: if the existing interface has the wrong kind (tun while |
|||
+ * DCO is wanted, or if_ovpn while it is not), stop the instance and |
|||
+ * remove the interface so it is recreated below. tap is never touched. |
|||
+ */ |
|||
+ $cur_kind = openvpn_if_kind($devname); |
|||
+ if (($use_dco && ($cur_kind === 'tun')) || |
|||
+ (!$use_dco && ($cur_kind === 'ovpn'))) { |
|||
+ openvpn_dco_stop_and_destroy($devname, |
|||
+ g_get('varrun_path') . "/openvpn_{$mode_id}.pid"); |
|||
+ } |
|||
+ |
|||
+ /* is our device already configured (DCO patch: uncached check) */ |
|||
+ if (!openvpn_dco_if_exists($devname)) { |
|||
+ |
|||
+ $srcif = $tunname; |
|||
+ if ($use_dco) { |
|||
+ /* DCO patch: create an if_ovpn interface instead of tun */ |
|||
+ $out = []; |
|||
+ $rc = 1; |
|||
+ exec("/sbin/ifconfig ovpn create", $out, $rc); |
|||
+ $srcif = trim($out[0] ?? ''); |
|||
+ if (($rc !== 0) || empty($srcif)) { |
|||
+ syslog(LOG_WARNING, "OpenVPN {$devname}: could not create if_ovpn interface, falling back to tun (no DCO)"); |
|||
+ $use_dco = false; |
|||
+ $srcif = $tunname; |
|||
+ } |
|||
+ } |
|||
/* create the tap device if required */ |
|||
- if (!file_exists("/dev/{$tunname}")) { |
|||
+ if (!$use_dco && !file_exists("/dev/{$tunname}")) { |
|||
exec("/sbin/ifconfig " . escapeshellarg($tunname) . " create"); |
|||
} |
|||
/* rename the device */ |
|||
- mwexec("/sbin/ifconfig " . escapeshellarg($tunname) . " name " . escapeshellarg($devname)); |
|||
+ mwexec("/sbin/ifconfig " . escapeshellarg($srcif) . " name " . escapeshellarg($devname)); |
|||
+ /* DCO patch: refresh pfSense's cached interface list */ |
|||
+ does_interface_exist($devname, true); |
|||
/* add the device to the openvpn group */ |
|||
mwexec("/sbin/ifconfig " . escapeshellarg($devname) . " group openvpn"); |
|||
@@ -898,7 +1057,16 @@ |
|||
} |
|||
$conf .= "dev-type {$settings['dev_mode']}\n"; |
|||
- $conf .= "dev-node /dev/{$tunname}\n"; |
|||
+ if ($use_dco) { |
|||
+ /* DCO patch: OpenVPN takes over the existing if_ovpn interface */ |
|||
+ syslog(LOG_NOTICE, "OpenVPN {$devname}: using data channel offload (if_ovpn)"); |
|||
+ } else { |
|||
+ $conf .= "dev-node /dev/{$tunname}\n"; |
|||
+ /* DCO patch: never switch to DCO on its own on a tun interface */ |
|||
+ if (!preg_match('/(^|[;\s])disable-dco\b/', array_get_path($settings, 'custom_options', ''))) { |
|||
+ $conf .= "disable-dco\n"; |
|||
+ } |
|||
+ } |
|||
$conf .= "writepid {$pfile}\n"; |
|||
$conf .= "#user nobody\n"; |
|||
$conf .= "#group nobody\n";</pre> |
|||
==<span style="background:greenyellow">Krypto-Inventarisierung für TLS<span>== |
|||
[Akim] |
|||
Gegenstand vorangegangener Themen war oft eine Konfiguration quantensicherer Verfahren (zumindest für den genutzten vorwärtssicheren Schlüsselaustausch). Bei der Konfiguration von neu aufgesetzten Systemen ist es sicherlich zielführend mit einer engen und starken Konfiguration zu starten. Doch wie verhält es sich mit Diensten die bereits laufen und einer breiten Benutzerbasis angeboten werden? Es wäre also gut zu wissen, welche Dienste durch Server in der eigenen Infrastruktur angeboten werden und welche Kryptoprimitiven in der aktuellen Konfiguration nutzbar sind. Hier ist ein erster Anlaufpunkt, der Webservice [https://www.ssllabs.com/ssltest/ ssltest], der jedoch einige Einschränkungen hat. Detailliertere und vertraulichere Analysen können durch die Verwendung von [https://testssl.sh/ testssl.sh] gewonnen werden, welche auch die Analyse von Protokollen wie <code> SMTP, POP3, IMAP, XMPP, IRC, LDAP, PostgreSQL, MySQL, NNTP, FTP</code>... gestatten, welche den StartTLS-Mechanismus verwenden. |
Gegenstand vorangegangener Themen war oft eine Konfiguration quantensicherer Verfahren (zumindest für den genutzten vorwärtssicheren Schlüsselaustausch). Bei der Konfiguration von neu aufgesetzten Systemen ist es sicherlich zielführend mit einer engen und starken Konfiguration zu starten. Doch wie verhält es sich mit Diensten die bereits laufen und einer breiten Benutzerbasis angeboten werden? Es wäre also gut zu wissen, welche Dienste durch Server in der eigenen Infrastruktur angeboten werden und welche Kryptoprimitiven in der aktuellen Konfiguration nutzbar sind. Hier ist ein erster Anlaufpunkt, der Webservice [https://www.ssllabs.com/ssltest/ ssltest], der jedoch einige Einschränkungen hat. Detailliertere und vertraulichere Analysen können durch die Verwendung von [https://testssl.sh/ testssl.sh] gewonnen werden, welche auch die Analyse von Protokollen wie <code> SMTP, POP3, IMAP, XMPP, IRC, LDAP, PostgreSQL, MySQL, NNTP, FTP</code>... gestatten, welche den StartTLS-Mechanismus verwenden. |
||
| Line 80: | Line 858: | ||
<syntaxhighlight lang="sh"> |
<syntaxhighlight lang="sh"> |
||
tshark -i eth0 -f "tcp port 443" \ |
tshark -i eth0 -f "tcp port 443" \ |
||
-Y "tls.handshake.type == 1 |
-Y "tls.handshake.type == 1 && tls.handshake.extensions_supported_version == 0x0304" |
||
-T fields -e tls.handshake.extensions_key_share_group \ |
-T fields -e tls.handshake.extensions_key_share_group \ |
||
-e tls.handshake.extensions_key_share_key_exchange_length |
-e tls.handshake.extensions_key_share_key_exchange_length |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
Analoge Untersuchungen wären sicherlich auch für das SSH-Protokoll im Haus interessant, also welche Server / Clienten sind mit welcher Kryptografie unterwegs? |
|||
* [https://www.ssllabs.com/ssltest/ SSL Server Test (nur öffentlicher Port 443, TLS 1.2 erforderlich)] |
* [https://www.ssllabs.com/ssltest/ SSL Server Test (nur öffentlicher Port 443, TLS 1.2 erforderlich)] |
||
| Line 90: | Line 868: | ||
* [https://httpd.apache.org/docs/current/mod/mod_ssl.html#logformats CustomLog für mod_ssl] |
* [https://httpd.apache.org/docs/current/mod/mod_ssl.html#logformats CustomLog für mod_ssl] |
||
* [https://www.wireshark.org/docs/man-pages/tshark.html TShark] |
* [https://www.wireshark.org/docs/man-pages/tshark.html TShark] |
||
* [https://github.com/jtesta/ssh-audit SSH-Audit] |
|||
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
|||
==Krypto-Inventarisierung & CBOM== |
|||
Zukünftig werden Applikationen Quasi als Datenblatt ein CBOM (Cryptographic Bill of Material) bereitstellen, damit automatisiert bestimmt werden kann, welche Kryptoprimitiven darin potenziell genutzt werden und ob diese konform zu den gewünschten Vorgaben und Anforderungen sind. Wenn ein Anwendung neu geschrieben wird, kann das CBOM gleich mit erstellt werden und quasi als eine speziell fokussierte Dokumentation zur Applikation bereit gestellt werden. Was muss man hier beachten, wie kann es gelingen für bestehende (open source) Projekte nachträglich tool- oder auch KI-assistiert, so ein CBOM zu erstellen? |
|||
Versuchen Sie für ein OpenSource-Projekt ihrer Wahl hier weiterzukommen. Könnte man auch mit einer KI und Reverse-Engeneering zu Aussagen kommen, wenn man nur ein Binary zur Verfügung hat? |
|||
* [https://en.wikipedia.org/wiki/Cryptographic_bill_of_materials Wiki:CBOM] |
|||
* [https://github.com/cbomkit/cbomkit CBOMkit] |
|||
* [https://codeql.github.com/ CodeQL] |
|||
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
||
| Line 106: | Line 895: | ||
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
||
==FIDO2@USE== |
|||
==Umsetzung eines PQC-Verfahrens im Rahmen des CNG Frameworks== |
|||
Die Nutzung von WebAuthn und FIDO2 beginnt langsam bei der Authentifizierung gegenüber Webdiensten und auch Apps eine relevante Verbreitung zu erlangen. Eine Nutzung ist mit hardwarebasierten SekurityKeys, mit Softwarekeys und mit Plattformkeys möglich. Probieren Sie es aus. |
|||
(spannend, aber anspruchsvoll) |
|||
Wenn man eigene Dienste mit einem Securitykey nutzen möchte, gibt es bereits einige Snenarios, wo das in Linux möglich ist wie PAM, SSH, LUKS2 (Festplattenverschlüsselung) oder Datenbank von KeePassXC ≥ 2.7.7 entsperren. Probieren Sie diese aus und schauen Sie, welchen Komfort und welche Sicherheit diese bieten. |
|||
Die generische Nutzung ist natürlich innerhalb von HTTPS via Webauthn möglich. Doch wie kann ich diese starke Authentisierung auch für meinen eigenen Webserver erreichen? Ein möglicher Startpunkt könnte für den <code>nginx</code> die Verwendung von Authelia sein, die vielleicht in dieser (nicht verifizierten) Weise |
|||
<syntaxhighlight lang="nginx"> |
|||
server { |
|||
listen 443 ssl; |
|||
server_name app.example.com; |
|||
# ... SSL-Konfiguration ... |
|||
#Jeder Request wird vorab bei Authelia geprüft |
|||
Post-Quanten-Kryptografie befindet sich derzeit im Prozess der Standardisierung und es werden viele Demo-Anwendungen umgesetzt. Statt jede Anwendung einzeln zu modifizieren und Support für diese neuen Verfahren einzubauen, bietet das MS CNG Framework die Möglichkeit, Module global im Betriebssystem zu ergänzen. Anwendungen, die die entsprechenden System-Routinen verwenden, erhalten werden damit PQC-fähig ohne modifiziert werden zu müssen. |
|||
auth_request /authelia; |
|||
location /authelia { |
|||
Aufgaben: |
|||
internal; |
|||
* Einarbeitung in das CNG-Framework |
|||
proxy_pass http://127.0.0.1:9091/api/verify; |
|||
* Analyse des Beispielcodes (C++) |
|||
proxy_set_header X-Original-URL $scheme://$http_host$request_uri; |
|||
* Auswahl eines geeigneten PQC-Verfahrens (z.B. Dilithium https://pq-crystals.org/index.shtml) |
|||
proxy_set_header X-Forwarded-For $remote_addr; |
|||
* Implementierung von CNG Cryptographic Algorithm Provider sowie Signature/Encryption Provider |
|||
proxy_set_header Content-Length ""; |
|||
proxy_set_header Connection ""; |
|||
} |
|||
location / { |
|||
proxy_pass http://127.0.0.1:8080; |
|||
#User/Gruppen aus der Authelia-Antwort an das Backend durchreichen |
|||
auth_request_set $user $upstream_http_remote_user; |
|||
proxy_set_header Remote-User $user; |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
geschehen könnte. Probieren Sie es aus! Ist auch eine Prüfung der Attestation-Information beim Enrollment eines FIDO-Cerdentials möglich? Geht auch etwas für den Apache-Webserver? |
|||
Links: |
Links: |
||
* [https://webauthn.io/] |
|||
* [https://learn.microsoft.com/en-us/windows/win32/seccertenroll/understanding-cryptographic-providers Understanding Cryptographic Providers] |
|||
* [https://developers.yubico.com/pam-u2f/ PAM Doc] |
|||
* [https://www.microsoft.com/en-us/download/details.aspx?id=30688 SDK mit Dokumentation und Beispiel-Code] |
|||
* [https://github.com/Yubico/pam-u2f git pam-u2f] |
|||
* [https://csrc.nist.gov/publications/fips 2024 standardisierte PQC: FIPS 203, 204 und 205] |
|||
* [https://www.openssh.org/txt/release-8.2 ssh-sk-helper] |
|||
* [[File:Skizze_MS_CNG.png|32px |alt=Alt Skizze CNG|Skizze Microsoft CNG]] Skizze Microsoft CNG |
|||
* [https://wiki.archlinux.org/title/Systemd-cryptenroll ArchWiki LUKS2, FIDO] |
|||
* [https://www.heise.de/news/KeePassXC-Version-2-7-7-liefert-Passkey-Unterstuetzung-9653875.html KeePassXC 2.7.7 & Passkeys] |
|||
* [https://www.w3.org/TR/webauthn-2/ WebAuthn Level 2 (Standard)] |
|||
* [https://w3c.github.io/webauthn/ WebAuthn Level 3 (Standard)] |
|||
* [https://www.authelia.com/ Authelia] |
|||
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller |
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
||
==PQC@FIDO2== |
==PQC@FIDO2== |
||
| Line 158: | Line 973: | ||
==Krypto-Agilität@OpenLDAP== |
==Krypto-Agilität@OpenLDAP== |
||
Am Institut für Informatik, wird das <code>ldaps</code>-Protokoll verwendet, um Nutzer zu authentisieren. Die OpenLDAP-Server des Instituts sind redundant und synchronisieren die Nutzeraccounts untereinander. <code>ldaps</code> ist im Grunde ldap über TLS und wird in der Regel auf dem TCP-Port 636 bereitgestellt. Aktuell ist die TLS-Verbindung mit |
Am Institut für Informatik, wird das <code>ldaps</code>-Protokoll verwendet, um Nutzer zu authentisieren. Die OpenLDAP-Server des Instituts sind redundant und synchronisieren die Nutzeraccounts untereinander. <code>ldaps</code> ist im Grunde ldap über TLS und wird in der Regel auf dem TCP-Port 636 bereitgestellt. Aktuell ist die TLS-Verbindung mit ECDSA-Schlüsseln mit 384-Bit Länge (secp384r1) mit einem eigenen Trustanker serverseitig authentisiert. Für die Etablierung der ephemeren Sitzungsschlüssel werden ebenfalls elliptische Kurven (X25519) verwendet. Das ist prinzipiell aktuell konform zur BSI [https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR02102/BSI-TR-02102-2.html TR-02102-2]. Allerdings wäre es sinnvoll bereits jetzt über den Umstieg auf quantensichere Verfahren (insbesondere im Hybrid gepaart mit einem klassischen Verfahren) nachzudenken. Dabei ist es wünschenswert, dass ein Parallelbetrieb mit älteren Clienten, welche vielleicht eine elliptische Kurve mit großer Bitlänge unterstützen mit schon pqc-fähigen Clienten ermöglichen. Die Nutzung eines hybriden-pqc Verfahren für den Schlüsselaustausch, sollte nun erfolgreich "store now, decypt later" abwehren. Auch wenn das die dringendste Anforderung ist, ist der nächste Schritt, neben der Verwendung klassisch signierter Zertifikate zusätzlich für die Clienten, die diese Signaturen schon verifizieren können, auch hybride quantensichere Zertifikate zur Serverauthentifizierung anzubieten. Das beinhaltet einmal das Problem, wie mit solche Zertifikate erstellt werden können und welche Randbedingungen sich ergeben, wenn die Zertifikate und Signaturen von verschiedenen TLS-Clienten oder -Bibliotheken verifiziert werden sollen. Schauen Sie sich bitte insbesondere die Interoperabilität von <code>openssl</code> und <code>gnutls</code> an. Eine zusätzliche Herausforderung ist, sowohl pqc- als auch nichtpqcfähige Clienten zu unterstützen. Der TLS-Server muss dafür anhand der im "ClientHello" als unterstützt angegebenen Signaturverfahren richtig entscheiden, ob er das klassische ECDSA-Zertifikat oder ein hybrides PQC-Zertifikat für die Authentisierung verwendet. |
||
Herangehen: |
Herangehen: |
||
# Installieren Sie Ubuntu |
# Installieren Sie Ubuntu 26.04.1 LTS (als virtuelle Maschine) |
||
# Installieren Sie OpenLDAP@Ubuntu |
# Installieren Sie OpenLDAP@Ubuntu |
||
# Recherchieren Sie, welche {OpenSSL,GnuTLS}-Versionen welche Kryptoverfahren unterstützen. |
|||
# Erstellen Sie je einen Satz von {RSA,ed448}-basierten CA + Serverzertifikat |
|||
# Erstellen Sie je einen Satz von {secp384r1,hybrid(klassisch+PQC}}-selbst signiertes Serverzertifikat |
|||
# <code>slapd</code> ist unter Ubuntu gegen GnuTLS gelinkt. |
# <code>slapd</code> ist unter Ubuntu gegen GnuTLS gelinkt. |
||
## Versuchen Sie mit <code>gnutls-serv</code> einen TLS-Server im Parallelbetrieb aufzusetzen. |
## Versuchen Sie mit <code>gnutls-serv</code> einen TLS-Server im Parallelbetrieb aufzusetzen. |
||
## Versuchen Sie sich auf diesen Server mit <code>gnutls-cli</code> und <code>openssl s_client |
## Versuchen Sie sich auf diesen Server mit <code>gnutls-cli</code> und <code>openssl s_client</code> durch geeignete Wahl der Cipher als Parameter auf die eine als auch auf die andere Variante zu verbinden. |
||
# Passen Sie die Konfiguration für <code>slapd.conf</code> an, um den Parallelbetrieb für OpenLDAP zu ermöglichen. |
# Passen Sie die Konfiguration für <code>slapd.conf</code> an, um den Parallelbetrieb für OpenLDAP zu ermöglichen. |
||
# Versuchen Sie für die neue Variante einen möglichst sichern Handshake, TLS 1.3 mit starkem |
# Versuchen Sie für die neue Variante einen möglichst sichern Handshake, TLS 1.3 mit starkem Key-agreement zu konfigurieren. (Ist hier mit der in Ubuntu 26.04.1 bereitgestellten Version auch schon ein hybrides quantensicheres Key-agreement möglich?) |
||
Links: |
Links: |
||
* [[Media:Quantensicheres_Key_Agreement.pdf| Folien "HTTPS, OpenVPN, TLS? Quantensicheres Key Agreement" ]] |
|||
* [[Media:sslbench.c|sslbench.c]] |
|||
* [https://ubuntu.com/blog/tag/ubuntu-26-04-lts Ubuntu 26.04 LTS] |
* [https://ubuntu.com/blog/tag/ubuntu-26-04-lts Ubuntu 26.04 LTS] |
||
* [https://documentation.ubuntu.com/server/how-to/openldap/install-openldap/ Install OpenLDAP@Ubuntu] |
* [https://documentation.ubuntu.com/server/how-to/openldap/install-openldap/ Install OpenLDAP@Ubuntu] |
||
| Line 178: | Line 997: | ||
* [https://gnutls.org/manual/html_node/Priority-Strings.html GnuTLS: priority strings] |
* [https://gnutls.org/manual/html_node/Priority-Strings.html GnuTLS: priority strings] |
||
* [https://www.gnutls.org/manual/html_node/Supported-ciphersuites.html GnuTLS: ciphersuites] |
* [https://www.gnutls.org/manual/html_node/Supported-ciphersuites.html GnuTLS: ciphersuites] |
||
* [https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR02102/BSI-TR-02102-2.html TR-02102-2] |
|||
* [[P521_mldsa87-Zertifikat mit OpenSSL]] |
|||
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
|||
==<span style="background:greenyellow">[[KI-Sicherheitsanalyse-security-audit-skill|KI-Sicherheitsanalyse]]</span>== |
|||
[ Gabriel ] |
|||
Eine KI-assistierte oder KI-Agent-basierte Sicherheitsanalyse bietet ein großes Potenzial um Fehler in Software zu finden. Aber wie funktioniert das? |
|||
Finden Sie heraus, welche Werkzeuge verfügbar und geeignet sind. Wählen Sie ein oder mehrere OpenSource-Projekte (diese sollten eher klein sein) und versuchen Sie, diese einer KI-basierten Sicherheitsanalyse zu unterziehen. Lassen Sie uns teilhaben an Ihren Einsichten, wo liegen Schwächen. Stärken, Kosten bei diesem Ansatz. Können Sie die (potenziell) gefundenen Schwachstellen verstehen und verifizieren? |
|||
Startpunkt |
|||
* [https://github.com/cloudflare/security-audit-skill KI: security audit skill] |
|||
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
Mentoren: [https://sar.informatik.hu-berlin.de/people/wolf_mueller.htm Wolf Müller] |
||
Latest revision as of 20:59, 25 October 2026
Organisatorisches und Anmeldung für IT-Security Workshop vom 28. September bis 9. Oktober 2026
Wenn Sie die unten genannten Themen interessant finden und in den ersten beiden Oktoberwochen Lust und Zeit haben sich damit auseinanderzusetzen, so finden Sie hier den angestrebten Zeitplan sowie die Möglichkeit sich und (optional) ein spannendes eigenes Thema anzumelden. Exklusiv für die Kommunikation der Teilnehmenden untereinander gibt es einen zugehörigen Moodle-Kurs mit Forum.
Vorträge
Freitag 9.10. 2026, Rudower Chaussee 25, Haus 3, Raum 3'328 (dritte Etage)
| 10:00-10:15 | meet & greet | ||
| 10:15-11:00 | KI-Sicherheitsanalyse | Philipp | |
| 11:00-11:45 | KI-Sicherheitsanalyse | Gabriel | |
| 11:45-12:30 | Mittagspause | ||
| 12:30-13:15 | Daten- und Computerstrafrecht | Elias | |
| 13:15-14:00 | OpenVPN-DCO@{OPNsense,pfSense 2.9.0 CE} | Ole | |
| 14:00-14:15 | Pause: Snack & Schnack | ||
| 14:15-15:00 | Krypto-Inventarisierung für TLS | Akim | |
| 15:00-15:45 | Von ECDSA zu PQC-Signaturen | Nasser | |
| 15:45-16:00 | Zusammenfassung & Dank | Wolf Müller |
Themen
Von ECDSA zu PQC-Signaturen: Kryptoagile Migrationsstrategien für die digitale Signaturprüfung von sensiblen Daten
[Nasser]
Im Rahmen meiner Arbeit in der Vertrauensstelle am Robert Koch-Institut werden Daten mit hohem Schutzbedarf verarbeitet. Derzeit ist ECDSA eingesetzt, um durch eine Signatur die Integrität der Daten zu gewährleisten. Mit der fortschreitenden Entwicklung von „Cryptographically Relevant Quantum Computers (CRQC)“ geraten etablierte asymmetrische Signaturverfahren wie ECDSA langfristig unter Druck. Im Rahmen des Themas soll untersucht werden, welche technischen, sicherheitsrelevanten und organisatorischen Herausforderungen bei der Migration von ECDSA zu Post-Quantum-Signaturverfahren, wie ML-DSA entstehen. Ein besonderer Schwerpunkt liegt dabei auf dem Konzept der Kryptoagilität, also der Fähigkeit eines Systems, kryptografische Verfahren flexibel auszutauschen oder parallel zu betreiben. Ergänzend zur theoretischen Analyse wird ein kleiner Proof of Concept entwickelt. Dieser demonstriert die Kryptoagilität anhand einer bestehenden Signaturarchitektur, die sowohl ECDSA als auch ML-DSA unterstützen und optional einen parallelen Übergangsbetrieb ermöglichen soll. Ziel ist es anhand des Prototyps unter anderem Signatur- und Schlüsselgrößen, Laufzeiten sowie der Integrationsaufwand von klassischer- und PQC-Kryptographie zu vergleichen. Verwendete Technologien:
- MS SQL-Server
- Python
- Linux (Ubuntu 24.04)
- .Net10 (Bietet Post-Quanten Algorithmen an)
Daten- und Computerstrafrecht
[Elias]
Wer in der IT-Sicherheit arbeitet, bewegt sich schneller in strafrechtlich relevantem Terrain, als vielen bewusst ist. Ein hartkodiertes Passwort im Binary, ein offener Datenbankport, ein kurzer Blick "nur zur Kontrolle": Wo endet legitime Sicherheitsforschung, und wo beginnt das Ausspähen von Daten?
Der Beitrag bietet eine Einführung in das materielle Strafrecht und stellt die Dogmatik der "computerspezifischen" Delikte des besonderen Teils des Strafgesetzbuchs vor, hier insbesondere:
- §§ 202a ff. StGB: Ausspähen und Abfangen von Daten, die Vorbereitung desselben (sog. "Hackerparagraf") und Datenhehlerei
- § 263a StGB: Computerbetrug
- §§ 269 f. StGB: Fälschung beweiserheblicher Daten und Täuschung im Rechtsverkehr bei Datenverarbeitung
- §§ 303a f. StGB: Datenveränderung und Computersabotage
Dabei geht es vor allem um die Frage, wie die Rechtsprechung und die Literatur Tatbestandsmerkmale wie "nicht für ihn bestimmt", "gegen unberechtigten Zugang besonders gesichert" oder "Überwindung der Zugangssicherung" auslegen und ob diese Auslegung mit dem intuitiven Verständnis von Informatikern (den Seminarteilnehmern) übereinstimmt.
Die Materie werden wir gemeinsam anhand von Fallbeispielen erarbeiten.
Schwerpunktmäßig wollen wir zudem die vielbeachtete Entscheidung des AG Jülich, 17 Cs-230 Js 99/21-55/23, besprechen. Im Mittelpunkt steht hier ein Verfahren, das die IT-Szene seit 2021 beschäftigt: Ein freiberuflicher IT-Dienstleister stieß bei der Analyse einer E-Commerce-Software auf ein im Programm im Klartext hinterlegtes Datenbankpasswort, über das Daten von rund 700.000 Endkunden erreichbar waren. Er meldete die Lücke und erhielt statt eines Dankes eine Strafanzeige samt Hausdurchsuchung. Wir werden in der Diskussion eine gutachterliche Lösung des Falls erarbeiten und uns hierzu mit den in der Literatur und Rechtsprechung vertretenen Ansichten auseinandersetzen.
Zusatzthema (praktischer Teil): Es werden Ansätze untersucht, mit denen die "Prüfprogramme" der oben genannten Tatbestände in eine für KI-Assistenten ausführbare Form gebracht werden kann. In Ergänzung zu dem Thema der Kommilitonen, die sich mit dem Aufspüren von Sicherheitslücken mittels KI beschäftigen, soll auf einer Meta-Ebene betrachtet werden, wie das System seinen eigenen "Plan" unter strafrechtlichen Gesichtspunkten reflektieren kann.
PQC@OpenVPN
[Rafael]
OpenVPN ist eine weit verbreitete Open-Source-Lösung für sichere, verschlüsselte VPNs. OpenVPN ist (anders als WireGuard) hinsichtlich vieler Aspekte konfigurierbar und bietet zahlreiche Optionen. Hier sind also bei der Administration einige Überlegungen nötig, um sichere und auch performante Einstellungen zu wählen. Hinsichtlich der Performance ist OpenVPN im Verbindungsaufbau und oft auch im Transport der eigentlichen Nutzdaten oft langsamer als WireGuard. Der Verbindungsaufbau ist in WireGuard sehr strikt spezifiziert und dadurch effizient. Dies bedeutet aber auch, dass ein Austausch der Kryptoalgorithmen in WireGuard nicht einfach möglich ist. Hier bietet OpenVPN mehr Kryptoagilität, auch wenn dies intrinsisch mit mehr Komplexität somit einer höheren Zahl an Roundtrips zum Verbindungsaufbau bezahlt wird. Häufig wird für den Aufbau des Kontrollkanals TLS verwendet, so dass zur Absicherung gegen Quantencomputer auf die ab OpenSSL >= 3.5 vorhandenen Mechanismen zurückgegriffen werden soll. OpenVPN unterstützt (derzeit bereits oder zukünftig) drei Mechanismen zur Quantensicherheit:
- "poor man's post-quantum cryptography" in Gestalt von preshared symmetrischen Schlüsseln mit den Optionen
tls-crypt,tls-crypt-v2, auf deren Basis dann die TLS-Schlüsselaushandlung ihrerseits verschlüsselt wird (in Version 2 mit nutzerindividuellen Schlüsseln). Dieser Mechanismus ist aber nicht vorwärtssicher unter dem Angreifermodell "Quantencomputer", - Die stärkere und wünschenswertere Methode ist die Nutzung eines hybriden Verfahren mit PQC, die dann "Perfect Forward Secrecy" garantiert. Da OpenVPN in der Regel OpenSSL als TLS-Bibliothek verwendet (siehe W2025-ITS#PQC@TLS-Handshake-Thema), sind dann
X25519MLKEM768,SecP256r1MLKEM768undSecP384r1MLKEM1024denkbare Kandidaten, die dann mittls-groups X25519MLKEM768konfigurierbar sein sollen. - Auch eine auf PQC-basierende Authentisierung sowohl des Servers als auch der Clients in Gestalt von "Post-quantum signing/certificates" soll zukünftig möglich sein. Da aber in der Gegenwart noch keine Quantencomputer vorhanden sind die die klassischen Signaturen brechen können und eine Authentisierung nicht rückwirkend erfolgt, ist hier eher die Möglichkeit interessant, aber der Handlungsdruck nicht so immens wie bei dem Schutz der Vertraulichkeit.
Der eigentliche Transport der Nutzdaten erfolgt über den "data channel". Dieser nutzt symmetrische Kryptografie zur Verschlüsselung und Authentisierung. Wenn die Schlüsselübereinkunft quantensicher erfolgt und ausreichend starke (>= 256bit) Schlüssel genutzt werden, so ist der Datenkanal auch quantensicher. Hierbei sind sicher die AEAD-Chiffren CHACHA20-POLY1305 und AES-256-GCM eine solide Wahl. Während CHACHA20-POLY1305 in der Regel recht performant in Software umgesetzt werden kann und insbesondere gern auf ARM-Architekturen verwendet wird, kann AES-256-GCM seine Vorteile ausspielen, wenn AES hardwareunterstützt (z.B. durch die CPU) ist. WireGuard verwendet CHACHA20-POLY1305 für die Verschlüsselung der Nutzdaten, ist direkt im Kernel implementiert und bietet hervorragende Performance. Um hier etwas aufzuholen, hat OpenVPN das Konzept "Data Channel Offload (DCO)" an den Start gebracht, ein Kernelmodul bereitgestellt, das die Ver- und Entschlüsselung der Datenpakete direkt im Kernel-Space ermöglicht. Von dem DCO-Kernel-Modul werden CHACHA20-POLY1305 und AES-{128,256}-GCM als Chiffren unterstützt. Versuchen Sie, für Ihren OpenVPN-{Server,Clienten} auch DCO zu verwenden und messen Sie den Performanceunterschied.
Untersuchen Sie auch, ob auch mobile "OpenVPN Connect"-Clienten unterstützt werden und wie man eine ggf. nötige starke abwärtskompatible Konfiguration erreichen kann.
Links:
Mentoren: Wolf Müller
PQC@eduroam
Eduroam gestattet Mitarbeitenden an Bildungs- und Forschungseinrichtungen Zugang zu WLAN-Netzen der besuchten Einrichtungen und hat sich als ausgesprochen praktisch erwiesen. Um sich gegenüber dem besuchten Netzwerk als Nutzer zu authentisieren, wird in der Regel der WPA2 oder WPA3-Enterprise Mode verwendet. Insbesondere erfolgt die Authentisierung via EAP-TTLS gegenüber der Heimeinrichtung. Auch für diese Verbindung wäre ein quantensicherer Schlüsselaustausch wünschenswert. Schauen Sie sich an, auf welche Stellen man achten müsste, um WPA3-Enterprise quantensicher zu bekommen. Bauen Sie ein eigenes WPA3-Enterpreise-Netzwerk auf und sichern Sie es möglichst gut gegen Angriffe mit Quantencomputern ab. Orientieren Sie sich dabei an der Architektur von Eduroam an der HU, also nutzen Sie EAP-TTLS mit passwortbasierter Authentifizierung und FreeRADIUS. Inspizieren Sie Ihren Ansatz mit Wireshark.
Links:
- eduroam
- EAP-TTLS@HU
- WPA3 Specification
- Ausblick PQC, WPA4
- FreeRADIUS
- Wireshark
- Wireshark: IEEE 802.11 WLAN Decryption Keys
Mentoren: Wolf Müller
OpenVPN-DCO@{OPNsense,pfSense 2.9.0 CE}
[Ole]
Mit dem gerade frisch veröffentlichten pfSense 2.9.0 CE und OPNsense stehen hier zwei weit verbreitete Kandidaten für frei verfügbare auf FreeBSD-basierende Firewalllösungen mit Webkonfigurationsmöglichkeit zur Auswahl, die auch DHCP, DNS und VPN-Lösungen unterstützen.
An unserem Institut fand schon an einigen Stellen pfSense Anwendung. Allerdings bietet hier die CE (also community edition) keine Unterstützung für OpenVPN mit "data channel offload" in den Kernel, so dass die Effizienz nicht so gut ist, wie sie sein könnte. Konkret ist bei pfSense das nötige Kernelmodul /boot/modules/if_ovpn.ko nicht vorhanden. Um hier (ohne zusätzliche Kosten) weiterzukommen sehe ich die folgenden Möglichkeiten:
- Man versucht zum installierten Kernel
FreeBSD 16.0-CURRENT #12 RELENG_2_9_0-n256132-d8e3138ecf52aus den FreeBSD-Quellen ein passendes Modul selbst zu kompilieren. Allerdings ist nicht gleich offensichtlich, aus welchen Quellen das wie gelingen könnte. (Das installierte OpenVPN:OpenVPN 2.7.5 amd64-portbld-freebsd16.0 [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [MH/RECVDA] [AEAD] [DCO]scheint bereits mit DCO-Unterstützung kompiliert zu sein. Auch ist OpenSSL:OpenSSL 3.5.7 9 Jun 2026 (Library: OpenSSL 3.5.7 9 Jun 2026)ausreichend aktuell, um auch einen quantensicheren Handshake zu realisieren.) - Man versucht auf die vor geraumer Zeit geforkte OPNsense Variante zu wechseln und dort OpenVPN mit DCO umzusetzen.
- Man könnte auf WireGuard wechseln, welches in beiden *sense Varianten inzwischen konfigurierbar ist.
Schauen Sie sich die verschiedenen Ansätze an und stellen Sie diese gegenüber. Vielleicht haben Sie auch andere Ideen? Lassen Sie uns an Ihrem gewonnen Wissen teilhaben!
Links:
Mentoren: Wolf Müller
Überblick
Es werden zwei VMs verwendet, beide im libvirt-NAT-Netz default (192.168.122.0/24):
| VM | System | Zweck |
|---|---|---|
| Build-VM | FreeBSD 15.1-RELEASE | Kompiliert das Modul; dient später auch als OpenVPN-Testclient |
| Test-VM | pfSense CE 2.9.0 | Liefert Kernel-Informationen; dort wird das Modul getestet |
Ablauf:
- Build-VM aufsetzen
- pfSense-Test-VM aufsetzen
- Kernel-Informationen der pfSense auslesen
- Passenden FreeBSD-Quellstand bestimmen
- Modul bauen
- Modul auf der pfSense laden und prüfen
- OpenVPN-Server DCO-tauglich konfigurieren
- pfSense-Patch für das Interface-Problem einspielen
- Funktionstest mit Client
Referenzwerte für pfSense CE 2.9.0
| Merkmal | Wert |
|---|---|
Kernel (uname -a)
|
FreeBSD 16.0-CURRENT #12 RELENG_2_9_0-n256132-d8e3138ecf52, gebaut am 17.08.2026
|
kern.osreldate
|
1600018
|
| Kernelkonfiguration | pfSense, vollständig in kern.conftxt eingebettet (417 Zeilen)
|
FreeBSD-main-Fenster mit 1600018
|
1569e2334ab (30.04.2026) bis 255538cd906 (19.06.2026, Sprung auf 1600019)
|
| Verwendeter Build-Stand | 7386c0675c8 (= 255538cd906^, letzter Commit mit 1600018)
|
Abweichung der Konfiguration zu main
|
nur options NETGRAPH_ETF (für if_ovpn irrelevant)
|
Bei einem pfSense-Update ändern sich diese Werte, die Schritte 3 bis 6 sind dann zu wiederholen.
1. Build-VM aufsetzen (FreeBSD 15.1)
1.1 Image und VM
Von der FreeBSD-Downloadseite das VM-Image für amd64 laden (Spalte „VM“, Format .qcow2 für virt-manager/KVM). Die UFS- oder ZFS-Variante ist gleichermaßen geeignet.
Platte vor dem ersten Start vergrößern, da das Image nur ca. 6 GB groß ist:
xz -d FreeBSD-15.1-RELEASE-amd64-ufs.qcow2.xz qemu-img resize FreeBSD-15.1-RELEASE-amd64-ufs.qcow2 60G
In virt-manager:
- „Vorhandenes Laufwerksabbild importieren“ und das
.qcow2-Image auswählen - Betriebssystem: „Generic OS“ bzw. „Unknown OS“ wählen, da FreeBSD 15.1 in der Liste nicht vorhanden ist
- Speicher: 8192 MB, CPUs: 4–8
- Vor dem letzten Schritt „Konfiguration vor der Installation bearbeiten“ anhaken, dann:
- Festplatte → Erweiterte Optionen → Festplattenbus: VirtIO
- NIC → Gerätemodell: virtio
- „Übernehmen“, danach „Installation beginnen“
1.2 Erster Start
Login: root, kein Passwort. Die Konsole hat US-Tastaturbelegung (Y/Z vertauscht), umstellen mit kbdcontrol -l de und dauerhaft mit sysrc keymap=de.
1.3 SSH (für bequemes Kopieren von Befehlen)
Nur für Labor-VMs im NAT-Netz geeignet:
passwd sysrc sshd_enable=YES echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config ssh-keygen -A # Hostschlüssel erzeugen, sonst startet sshd nicht service sshd start ifconfig vtnet0 | grep inet
Vom Host: ssh root@<IP der Build-VM>
Hängt die VM nach einem Neustart im Single-User-Modus (Prompt root@:~ # ohne Hostnamen, kein Netz), mit exit den normalen Start fortsetzen, ggf. vorher fsck -y /.
1.4 Werkzeuge
pkg install -y git tmux
Lange Builds in tmux ausführen (tmux new -s build, lösen mit Strg+b d, zurück mit tmux attach -t build).
2. pfSense-Test-VM aufsetzen (pfSense CE 2.9.0)
2.1 Installer
pfSense CE wird nur noch über den Netgate Installer verteilt: kostenlos im Netgate-Shop, Variante „AMD64 ISO IPMI/Virtual Machines“. Es ist ein Online-Installer, die VM braucht beim Installieren Internet.
Die Datei im Terminal entpacken, nicht mit dem Archivprogramm des Desktops (das versucht auch die ISO selbst auszupacken):
gunzip netgate-installer-v1.2-RELEASE-amd64.iso.gz
2.2 VM
- „Lokales Installationsmedium (ISO)“ und die entpackte ISO auswählen
- Betriebssystem: „Generic OS“ bzw. „Unknown OS“
- Speicher: 4096 MB, CPUs: 2, Platte: 20 GB, eine NIC im Netz
default - „Konfiguration vor der Installation bearbeiten“ anhaken und wie bei der Build-VM Festplattenbus VirtIO und NIC-Gerätemodell virtio einstellen
- Im Installer: pfSense CE, Version 2.9.0
- WAN =
vtnet0(DHCP), LAN überspringen
2.3 Zugriff im Labor
Konsolenmenü 8 (Shell). Für SSH und Webinterface über das WAN-Interface:
pfSsh.php playback enablesshd pfctl -d # Firewall aus, bis zum nächsten Regel-Reload/Neustart
- SSH:
ssh admin@<WAN-IP>, danach Menüpunkt 8 - Web:
https://<WAN-IP>, Loginadmin/pfsense - Im Setup-Wizard unter „Configure WAN Interface“ „Block RFC1918 Private Networks“ abwählen
3. Kernel-Informationen der pfSense auslesen
Die eingebettete Kernelkonfiguration der pfSense auf die Build-VM holen (nur lesend, auch auf Produktivsystemen unbedenklich):
# auf der pfSense (Shell, Menüpunkt 8) sysctl -n kern.conftxt > /tmp/pfSense.conf # auf der Build-VM scp admin@<pfSense-IP>:/tmp/pfSense.conf /root/pfSense.conf
4. Passenden FreeBSD-Quellstand bestimmen
Alle Befehle in diesem Abschnitt auf der Build-VM (FreeBSD 15.1, als
root). Der Quellbaum liegt danach unter/usr/src-main.
Abkürzung für pfSense CE 2.9.0: Der passende Stand ist bekannt (
7386c0675c8, siehe Referenzwerte). Dann genügt 4.1 (Klonen), danach direkt weiter mit Abschnitt 5. Alle Blöcke, die mit# OPTIONALbeginnen, dienen nur dazu, den Stand für eine neue pfSense-Version herzuleiten oder zu kontrollieren.
4.1 FreeBSD main klonen
# Build-VM git clone --filter=blob:none https://github.com/freebsd/freebsd-src.git /usr/src-main cd /usr/src-main
--filter=blob:none lädt Dateiinhalte erst bei Bedarf und spart mehrere GB.
4.2 Zeitfenster der __FreeBSD_version finden (optional bei bekannter Version)
# OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle)
# Build-VM, in /usr/src-main
git --no-pager log --since=2026-01-01 --format='%h %cd %s' --date=short \
-G'#define __FreeBSD_version 16000(18|19)' -- sys/sys/param.h
--since begrenzt die Suche auf neuere Commits. Ohne die Begrenzung durchsucht -G die gesamte Geschichte von param.h, und Git lädt wegen --filter=blob:none jede alte Version einzeln von GitHub nach; das kann mehrere Minuten dauern. Bei einer späteren pfSense-Version das Datum entsprechend anpassen (etwa ein halbes Jahr vor dem Build-Datum aus uname -a).
Das Ergebnis zeigt den Commit, der 1600018 setzt, und den, der auf 1600019 erhöht. Kontrolle:
# OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle) # Build-VM, in /usr/src-main git --no-pager show 255538cd906 -- sys/sys/param.h | grep FreeBSD_version
Der pfSense-Zweig wurde innerhalb dieses Fensters von main abgezweigt (das Build-Datum liegt später, die Basis ist älter).
Den Hash des letzten Commits mit 1600018 liefert:
# OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle) # Build-VM, in /usr/src-main git rev-parse --short 255538cd906^ # ergibt 7386c0675c8
^ bedeutet in Git „der Commit direkt davor“.
4.3 Prüfen, ob die Wahl des Commits im Fenster eine Rolle spielt (optional bei bekannter Version)
# OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle)
# Build-VM, in /usr/src-main
# Änderungen am Modul selbst
git --no-pager log --oneline 1569e2334ab..255538cd906 -- \
sys/net/if_ovpn.c sys/net/if_ovpn.h sys/modules/if_ovpn
# Änderungen an Headern, auf die das Modul zugreift
git --no-pager log -p 1569e2334ab..255538cd906 -- \
sys/net/if_var.h sys/net/if_private.h sys/sys/mbuf.h \
sys/netinet/in_pcb.h sys/netinet/udp_var.h sys/opencrypto/cryptodev.h \
sys/net/vnet.h sys/sys/nv.h
Kritisch wären neue oder entfernte Felder in Strukturen (z. B. struct ifnet, struct mbuf), weil sich dann Speicher-Offsets verschieben. Bei 2.9.0 gab es im Fenster keine Änderung am Modul und nur zwei harmlose Header-Commits (ein Kommentar in struct ifnet, eine neue Inline-Funktion in mbuf.h).
Restrisiko: Netgates nicht veröffentlichte Kerneländerungen können nicht geprüft werden. Ob das Modul binär passt, zeigt erst der Lade- und Lasttest.
5. Modul bauen
Alle Befehle in diesem Abschnitt auf der Build-VM (FreeBSD 15.1, als
root), im Quellbaum/usr/src-main.
# Build-VM cd /usr/src-main git checkout 7386c0675c8 # = 255538cd906^, der Commit vor dem Sprung auf 1600019 ls sys/net/if_ovpn.c sys/modules/if_ovpn # OPTIONAL: Kontrolle, ob die Modulquellen da sind cp /root/pfSense.conf sys/amd64/conf/PFSENSE
Unbekannte Optionen/Geräte in der pfSense-Konfiguration finden (optional bei bekannter Version: für 2.9.0 ist das Ergebnis NETGRAPH_ETF):
# OPTIONAL bei bekannter Version (nur zur Herleitung/Kontrolle)
# Build-VM
cd /usr/src-main/sys
for o in $(awk '$1=="options"{sub(/=.*/,"",$2); print $2}' amd64/conf/PFSENSE); do
grep -qwE "^$o" conf/options conf/options.amd64 || echo "option: $o"
done
for d in $(awk '$1=="device"{print $2}' amd64/conf/PFSENSE); do
grep -qwE "$d" conf/files conf/files.amd64 conf/files.x86 || echo "device: $d"
done
CONFIG_AUTOGENERATED ist ein Fehlalarm (wird von config(8) akzeptiert). Bei 2.9.0 ist nur NETGRAPH_ETF unbekannt; auskommentieren:
# Build-VM cd /usr/src-main sed -i '' 's/^options[[:space:]]*NETGRAPH_ETF/#&/' sys/amd64/conf/PFSENSE
Bauen (im tmux, damit der Build weiterläuft, falls die SSH-Verbindung abbricht):
# Build-VM: tmux-Sitzung starten (oder mit "tmux attach -t build" wieder aufnehmen) tmux new -s build
Lösen der Sitzung, ohne den Build abzubrechen: Strg+b, dann d. Wieder verbinden: tmux attach -t build. Alle Sitzungen anzeigen: tmux ls.
In der tmux-Sitzung:
# Build-VM, in /usr/src-main
cd /usr/src-main
make -j$(sysctl -n hw.ncpu) kernel-toolchain 2>&1 | tee /root/toolchain.log
make -j$(sysctl -n hw.ncpu) buildkernel KERNCONF=PFSENSE MODULES_OVERRIDE=if_ovpn \
2>&1 | tee /root/buildkernel.log
Nach dem Build die tmux-Sitzung beenden:
# Build-VM, in der tmux-Sitzung exit
exit schließt die Sitzung endgültig. Soll sie für spätere Builds erhalten bleiben, stattdessen mit Strg+b, dann d lösen.
kernel-toolchain baut den passenden Compiler aus dem Quellbaum (einmalig, 30–90 min). buildkernel baut den Kernel mit der pfSense-Konfiguration, damit das Modul mit identischen Optionen (RSS, RATELIMIT, VIMAGE …) kompiliert wird; mit vorhandener Toolchain dauert das wenige Minuten.
Ergebnis:
# Build-VM
find /usr/obj/usr/src-main -name if_ovpn.ko -exec ls -l {} \;
# …/sys/PFSENSE/modules/usr/src-main/sys/modules/if_ovpn/if_ovpn.ko (ca. 90 KB)
6. Modul auf der pfSense laden
# Build-VM
scp /usr/obj/usr/src-main/amd64.amd64/sys/PFSENSE/modules/usr/src-main/sys/modules/if_ovpn/if_ovpn.ko \
admin@<pfSense-IP>:/tmp/
# pfSense cp /tmp/if_ovpn.ko /boot/modules/ kldload -v /boot/modules/if_ovpn.ko kldstat | grep ovpn dmesg | tail -20
Nicht in /boot/loader.conf(.local) eintragen. Nach einem Neustart oder Update startet das System so garantiert ohne das Modul. Nach einem Neustart bei Bedarf erneut kldload if_ovpn.
7. OpenVPN-Server DCO-tauglich konfigurieren
Die CE-Oberfläche bietet keine DCO-Option. OpenVPN 2.7 nutzt DCO automatisch, sobald das Modul geladen ist und die Konfiguration verträglich ist; andernfalls schaltet es DCO still ab (disable_dco = ENABLED im Log, bei Verbosity ≥ 4). Mit dem Patch aus Abschnitt 8 trifft pfSense diese Entscheidung selbst nach denselben Regeln und schreibt sie eindeutig in die Konfiguration.
Voraussetzungen für DCO:
| Einstellung | Wert |
|---|---|
| Protocol | UDP |
| Data Encryption Algorithms | nur AES-GCM und/oder CHACHA20-POLY1305 |
| Fallback Data Encryption Algorithm | AES-256-GCM (Standard ist AES-256-CBC, das verhindert DCO) |
| Modus | TLS-basiert (SSL/TLS, ggf. mit User Auth), kein Shared Key |
| Tunnelnetz | z. B. /24 mit Topology Subnet, kein /30
|
| Compression | aus (Refuse any non-stub compression) |
| Client Specific Overrides | keine iroute-Einträge (unter FreeBSD mit DCO nicht unterstützt)
|
Der Fallback-Algorithmus wird automatisch in data-ciphers aufgenommen. Typische Logmeldung, wenn er falsch steht:
Note: --data-ciphers-fallback with cipher 'AES-256-CBC' disables data channel offload.
Kontrolle der erzeugten Konfiguration (wird aus der GUI generiert, nicht von Hand bearbeiten):
grep -iE 'cipher|topology|dev' /var/etc/openvpn/server1/config.ovpn grep -iE 'disable_dco|offload|note|dco|error' /var/log/openvpn.log | tail -20
Optional, für einen hybriden Post-Quanten-Handshake im Kontrollkanal (unabhängig von DCO), unter Custom options:
tls-version-min 1.3;tls-groups SecP384r1MLKEM1024:secp521r1
8. Interface-Problem und pfSense-Patch
8.1 Das Problem
pfSense CE legt vor dem Start von OpenVPN ein klassisches tun-Interface an und benennt es in ovpnsN um (dev-node /dev/tunN in der Konfiguration). DCO benötigt aber ein if_ovpn-Interface. Ist das Modul geladen und die Konfiguration DCO-tauglich, übernimmt OpenVPN das vorhandene tun-Interface und scheitert:
dco_set_ifmode: failed to set ifmode=00008002: Invalid argument (errno=22) DCO device ovpns1 already exists, won't be destroyed at shutdown
ifconfig ovpns1 zeigt dann weiterhin groups: tun openvpn. Dieser Zustand ist defekt. OpenVPN läuft, kann aber keine Daten übertragen.
Unterscheidung der Modi am Interface:
| Modus | ifconfig ovpnsN
|
|---|---|
klassisch (tun)
|
groups: tun openvpn, Opened by PID …
|
DCO (if_ovpn)
|
groups: openvpn
|
8.2 Die Lösung: Patch für /etc/inc/openvpn.inc
Die Datei pfsense-openvpn-dco.patch (vollständig im Anhang) erweitert die Funktion, in der pfSense die OpenVPN-Konfiguration schreibt und das Interface anlegt:
openvpn_dco_usable()entscheidet pro Instanz, ob DCO genutzt wird. Bedingungen:if_ovpngeladen, Device-Modetun, UDP, kein Shared-Key-Modus, alle Data-Ciphers und der Fallback aus AES-128-GCM / AES-256-GCM / CHACHA20-POLY1305, keine Kompression, Tunnelnetz größer als /30, und keindisable-dco(bzw.fragment,comp-lzo,compress) in den Custom options.- Hat das vorhandene
ovpnsNden falschen Typ, wird die Instanz beendet (mit Warten auf das Prozessende) und das Interface entfernt (mit Warten, bis es wirklich weg ist).tap-Interfaces werden nie angefasst. - Mit DCO wird
ifconfig ovpn createstatttunverwendet unddev-nodeweggelassen. Schlägt das Anlegen fehl, fällt der Code mit einer Warnung auftunzurück. - Ohne DCO wird explizit
disable-dcoin die Konfiguration geschrieben, damit OpenVPN nie eigenmächtig umschaltet.
Verhalten:
| Situation | Interface | Konfiguration |
|---|---|---|
| Modul nicht geladen (z. B. nach Neustart) | tun
|
dev-node + disable-dco
|
| Modul geladen, Instanz DCO-tauglich | ovpn (DCO)
|
ohne dev-node, ohne disable-dco
|
Modul geladen, aber disable-dco in Custom options
|
tun
|
dev-node + disable-dco
|
| Modul geladen, Instanz nicht DCO-tauglich (z. B. CBC-Fallback, TCP) | tun
|
dev-node + disable-dco
|
disable-dco in den Custom options dient damit als Notschalter pro Server, ganz ohne Änderung an der Oberfläche.
Im Systemlog erscheint bei DCO der Hinweis:
php-cgi[…]: OpenVPN ovpns1: using data channel offload (if_ovpn)
8.3 Einspielen über das Webinterface
Das Paket System Patches ist in pfSense CE 2.9.0 vorinstalliert und taucht deshalb nicht unter „Available Packages“ auf.
- System → Patches → „+ Add New Patch“
- Description:
OpenVPN DCO (if_ovpn) - Patch Contents: kompletter Inhalt von
pfsense-openvpn-dco.patch - Path Strip Count:
1, Base Directory:/ - Auto Apply: vorerst nicht anhaken
- Description:
- Save, dann in der Liste Debug (Probelauf), danach Apply.
Eine neuere Fassung des Patches einspielen: zuerst Revert, dann über das Bleistift-Symbol den Inhalt ersetzen, Save, Debug, Apply.
Alternativ in der Shell: cd / && patch -p1 -b < /tmp/pfsense-openvpn-dco.patch (zurück mit patch -R -p1 < …).
8.4 Testen
kldstat | grep ovpn || kldload if_ovpn pfSsh.php playback svc restart openvpn server 1 ifconfig ovpns1 | grep groups # openvpn grep -E 'dev-node|disable-dco' /var/etc/openvpn/server1/config.ovpn # keine Ausgabe grep 'if_ovpn' /var/log/system.log | tail -2
Laborergebnis mit pfSense CE 2.9.0 (Patch-Fassung v4):
| Test | Ergebnis |
|---|---|
| Neustart ohne Modul | tun openvpn, dev-node + disable-dco ✔
|
| Modul laden, Dienst neu starten | automatisch openvpn (DCO) ✔
|
disable-dco eintragen → entfernen → wieder eintragen (je Save)
|
tun → openvpn → tun ✔, mehrfach wiederholt
|
9. Funktionstest mit Client (Build-VM)
FreeBSD 15.1 bringt if_ovpn im Standardkernel mit; die Build-VM nutzt als Client damit ebenfalls DCO.
pkg install -y openvpn iperf3 kldload if_ovpn # dauerhaft: sysrc kld_list+=if_ovpn mkdir -p /usr/local/etc/openvpn cd /usr/local/etc/openvpn scp admin@<pfSense-IP>:/var/etc/openvpn/server1/tls-auth ta.key scp 'admin@<pfSense-IP>:/var/etc/openvpn/server1/ca/*.0' ca.crt
Client-Zertifikat und -Schlüssel im Webinterface exportieren (System → Certificates → Certificates, Symbole „Export Certificate“ und „Export Key“) und als client.crt / client.key ablegen; chmod 600 client.key.
/usr/local/etc/openvpn/client.conf:
client dev tun proto udp4 remote <pfSense-IP> 1194 nobind ca /usr/local/etc/openvpn/ca.crt cert /usr/local/etc/openvpn/client.crt key /usr/local/etc/openvpn/client.key tls-auth /usr/local/etc/openvpn/ta.key 1 auth SHA256 remote-cert-tls server data-ciphers AES-256-GCM:CHACHA20-POLY1305 tls-version-min 1.3 tls-groups SecP384r1MLKEM1024:secp521r1 explicit-exit-notify 1 verb 4
Die Richtung bei tls-auth ist 1 (Server: 0); auth muss zum Server passen. Verwendet der Server tls-crypt, entsprechend tls-crypt … ohne Richtung.
openvpn --config /usr/local/etc/openvpn/client.conf # zweites tmux-Fenster: ping -c 5 10.8.0.1
Erwartete Logzeilen:
Control Channel: TLSv1.3, … key agreement: SecP384r1MLKEM1024 DCO device tun0 opened Initialization Sequence Completed Data Channel: cipher 'AES-256-GCM', peer-id: 0
Laborergebnis (pfSense CE 2.9.0): Tunnel aufgebaut, DCO auf Server und Client aktiv, hybrider PQ-Handshake, Ping ohne Verluste (ca. 1,5 ms). Kein Absturz.
Wichtige Hinweise für den Betrieb
- Nach jedem pfSense-Update muss das Modul neu gebaut werden. Ein unpassendes Modul kann den Kernel zum Absturz bringen.
- Modul und Patch gehören zusammen. Ohne Patch schaltet ein DCO-tauglicher Server (z. B. mit GCM-Fallback) beim Laden des Moduls in den defekten Zustand aus Abschnitt 8.1.
- Nach einem Update zuerst prüfen, ob der Patch noch angewendet werden kann (System → Patches → Debug). Ändert Netgate die betroffenen Codestellen, muss der Patch angepasst werden.
- Einzelne Server lassen sich jederzeit mit
disable-dcoin den Custom options vom DCO-Betrieb ausnehmen.
Anhang: pfsense-openvpn-dco.patch
--- a/etc/inc/openvpn.inc
+++ b/etc/inc/openvpn.inc
@@ -209,6 +209,134 @@
return($list);
}
+/*
+ * DCO patch (local, not from Netgate): helpers for OpenVPN Data Channel
+ * Offload with a self-built if_ovpn.ko on pfSense CE.
+ */
+
+/* Is the if_ovpn kernel module loaded? */
+function openvpn_dco_module_loaded() : bool {
+ $out = [];
+ $rc = 1;
+ exec('/sbin/kldstat -q -n if_ovpn', $out, $rc);
+ return ($rc === 0);
+}
+
+/*
+ * Can this instance use DCO? Mirrors the restrictions of OpenVPN and the
+ * FreeBSD if_ovpn driver. If anything is unclear, answer "no" so the
+ * instance keeps working in classic tun mode.
+ */
+function openvpn_dco_usable(string $mode, array $settings) : bool {
+ if (!openvpn_dco_module_loaded()) {
+ return false;
+ }
+ /* DCO only supports layer 3 (tun) */
+ if (array_get_path($settings, 'dev_mode', 'tun') !== 'tun') {
+ return false;
+ }
+ /* DCO only supports UDP */
+ if (strncasecmp(array_get_path($settings, 'protocol', ''), 'UDP', 3) !== 0) {
+ return false;
+ }
+ /* DCO requires a TLS-based mode, no static shared key */
+ if (array_get_path($settings, 'mode', '') === 'p2p_shared_key') {
+ return false;
+ }
+ /* All data ciphers and the fallback cipher must be supported by DCO */
+ $dco_ciphers = ['AES-128-GCM', 'AES-256-GCM', 'CHACHA20-POLY1305'];
+ $ciphers = preg_split('/[,:]/', array_get_path($settings, 'data_ciphers', ''), -1, PREG_SPLIT_NO_EMPTY);
+ $ciphers[] = array_get_path($settings, 'data_ciphers_fallback', '');
+ foreach ($ciphers as $cipher) {
+ if (!in_array(strtoupper(trim($cipher)), $dco_ciphers, true)) {
+ return false;
+ }
+ }
+ /* No compression */
+ if (array_get_path($settings, 'allow_compression', 'no') !== 'no') {
+ return false;
+ }
+ /* /30 or smaller peer-to-peer tunnel networks are not DCO compatible */
+ $tunnel_network = array_get_path($settings, 'tunnel_network', '');
+ if (!empty($tunnel_network)) {
+ list($ip, $cidr) = openvpn_gen_tunnel_network($tunnel_network);
+ if (is_numeric($cidr) && ((int)$cidr >= 30)) {
+ return false;
+ }
+ }
+ /* Per-instance opt-out and options that disable DCO anyway */
+ if (preg_match('/(^|[;\s])(disable-dco|fragment|comp-lzo|compress)\b/',
+ array_get_path($settings, 'custom_options', ''))) {
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Does the interface exist right now? Asks the kernel directly instead of
+ * does_interface_exist(), which may answer from a cached interface list
+ * and then still reports an interface that was just destroyed.
+ */
+function openvpn_dco_if_exists(string $ifname) : bool {
+ $out = [];
+ $rc = 1;
+ exec('/sbin/ifconfig ' . escapeshellarg($ifname) . ' >/dev/null 2>&1', $out, $rc);
+ return ($rc === 0);
+}
+
+/*
+ * Stop the OpenVPN instance and remove its interface, waiting until both
+ * are really gone. Without waiting, the exiting process can still hold or
+ * remove the interface while the new one is being created.
+ */
+function openvpn_dco_stop_and_destroy(string $ifname, string $pidfile) : void {
+ $pf = escapeshellarg($pidfile);
+ if (file_exists($pidfile)) {
+ mwexec("/bin/pkill -TERM -F {$pf}");
+ /* wait up to 10 s for the process to exit */
+ for ($i = 0; $i < 100; $i++) {
+ $out = [];
+ $rc = 1;
+ exec("/bin/pgrep -F {$pf}", $out, $rc);
+ if ($rc !== 0) {
+ break;
+ }
+ usleep(100000);
+ }
+ if ($rc === 0) {
+ mwexec("/bin/pkill -KILL -F {$pf}");
+ usleep(500000);
+ }
+ }
+ /* remove the interface and wait up to 5 s until it is gone */
+ for ($i = 0; $i < 50 && openvpn_dco_if_exists($ifname); $i++) {
+ if (($i % 10) == 0) {
+ exec("/sbin/ifconfig " . escapeshellarg($ifname) . " destroy >/dev/null 2>&1");
+ }
+ usleep(100000);
+ }
+ if (openvpn_dco_if_exists($ifname)) {
+ syslog(LOG_WARNING, "OpenVPN {$ifname}: could not remove interface to switch DCO mode");
+ }
+ /* refresh pfSense's cached interface list */
+ does_interface_exist($ifname, true);
+}
+
+/* Kind of an existing interface: 'tun', 'tap', 'ovpn' or null if missing */
+function openvpn_if_kind(string $ifname) : ?string {
+ if (!openvpn_dco_if_exists($ifname)) {
+ return null;
+ }
+ foreach (['tun', 'tap'] as $group) {
+ $out = [];
+ exec('/sbin/ifconfig -g ' . escapeshellarg($group) . ' 2>/dev/null', $out);
+ if (in_array($ifname, array_map('trim', $out), true)) {
+ return $group;
+ }
+ }
+ return 'ovpn';
+}
+
function openvpn_name(string $mode, array $settings, string $type = 'if') : string {
switch ($type) {
case 'if':
@@ -836,16 +964,47 @@
$tunname = openvpn_name($mode, $settings, 'dev');
$devname = openvpn_name($mode, $settings);
- /* is our device already configured */
- if (!does_interface_exist($devname)) {
+ /* DCO patch: decide between if_ovpn (DCO) and classic tun */
+ $use_dco = openvpn_dco_usable($mode, $settings);
+
+ /*
+ * DCO patch: if the existing interface has the wrong kind (tun while
+ * DCO is wanted, or if_ovpn while it is not), stop the instance and
+ * remove the interface so it is recreated below. tap is never touched.
+ */
+ $cur_kind = openvpn_if_kind($devname);
+ if (($use_dco && ($cur_kind === 'tun')) ||
+ (!$use_dco && ($cur_kind === 'ovpn'))) {
+ openvpn_dco_stop_and_destroy($devname,
+ g_get('varrun_path') . "/openvpn_{$mode_id}.pid");
+ }
+
+ /* is our device already configured (DCO patch: uncached check) */
+ if (!openvpn_dco_if_exists($devname)) {
+
+ $srcif = $tunname;
+ if ($use_dco) {
+ /* DCO patch: create an if_ovpn interface instead of tun */
+ $out = [];
+ $rc = 1;
+ exec("/sbin/ifconfig ovpn create", $out, $rc);
+ $srcif = trim($out[0] ?? '');
+ if (($rc !== 0) || empty($srcif)) {
+ syslog(LOG_WARNING, "OpenVPN {$devname}: could not create if_ovpn interface, falling back to tun (no DCO)");
+ $use_dco = false;
+ $srcif = $tunname;
+ }
+ }
/* create the tap device if required */
- if (!file_exists("/dev/{$tunname}")) {
+ if (!$use_dco && !file_exists("/dev/{$tunname}")) {
exec("/sbin/ifconfig " . escapeshellarg($tunname) . " create");
}
/* rename the device */
- mwexec("/sbin/ifconfig " . escapeshellarg($tunname) . " name " . escapeshellarg($devname));
+ mwexec("/sbin/ifconfig " . escapeshellarg($srcif) . " name " . escapeshellarg($devname));
+ /* DCO patch: refresh pfSense's cached interface list */
+ does_interface_exist($devname, true);
/* add the device to the openvpn group */
mwexec("/sbin/ifconfig " . escapeshellarg($devname) . " group openvpn");
@@ -898,7 +1057,16 @@
}
$conf .= "dev-type {$settings['dev_mode']}\n";
- $conf .= "dev-node /dev/{$tunname}\n";
+ if ($use_dco) {
+ /* DCO patch: OpenVPN takes over the existing if_ovpn interface */
+ syslog(LOG_NOTICE, "OpenVPN {$devname}: using data channel offload (if_ovpn)");
+ } else {
+ $conf .= "dev-node /dev/{$tunname}\n";
+ /* DCO patch: never switch to DCO on its own on a tun interface */
+ if (!preg_match('/(^|[;\s])disable-dco\b/', array_get_path($settings, 'custom_options', ''))) {
+ $conf .= "disable-dco\n";
+ }
+ }
$conf .= "writepid {$pfile}\n";
$conf .= "#user nobody\n";
$conf .= "#group nobody\n";
Krypto-Inventarisierung für TLS
[Akim]
Gegenstand vorangegangener Themen war oft eine Konfiguration quantensicherer Verfahren (zumindest für den genutzten vorwärtssicheren Schlüsselaustausch). Bei der Konfiguration von neu aufgesetzten Systemen ist es sicherlich zielführend mit einer engen und starken Konfiguration zu starten. Doch wie verhält es sich mit Diensten die bereits laufen und einer breiten Benutzerbasis angeboten werden? Es wäre also gut zu wissen, welche Dienste durch Server in der eigenen Infrastruktur angeboten werden und welche Kryptoprimitiven in der aktuellen Konfiguration nutzbar sind. Hier ist ein erster Anlaufpunkt, der Webservice ssltest, der jedoch einige Einschränkungen hat. Detailliertere und vertraulichere Analysen können durch die Verwendung von testssl.sh gewonnen werden, welche auch die Analyse von Protokollen wie SMTP, POP3, IMAP, XMPP, IRC, LDAP, PostgreSQL, MySQL, NNTP, FTP... gestatten, welche den StartTLS-Mechanismus verwenden.
Noch schwieriger ist es bei Protokollen, wie beispielsweise OpenVPN, wo der TLS-Handshake noch tiefer integriert und vielleicht auch selbst via "TLS-Crypt v2" verschlüsselt ist.
Die zweite Seite der Medaille sind die Clienten, die sich auf den Dienst verbinden. Wie kann man hier einen Überblick gewinnen, was diese kryptografisch bereits können, was sie im Handshake anbieten? Einen ersten Startpunkt bietet für den Apache-Webserver für mod_ssl die CustomLog-Variable. Allerdings wäre es interessant, insbesondere die vom Client angebotenen KeyShares zu analysieren, was bislang (meines Wissens) nicht unterstützt wird. Hier bestünde experimentell vielleicht die Möglichkeit, das Apache-Modul mod_ssl KI-assistiert dahingehend zu erweitern und es auf einem Testsystem mal auszuprobieren. Ernsthaft oder gar produktiv sollte das natürlich nicht verwendet werden. Ein erster generischer Ansatz könnte versuchen hier mit der Kommandozeilenversion von Wireshark tshark zu starten:
tshark -i eth0 -f "tcp port 443" \
-Y "tls.handshake.type == 1 && tls.handshake.extensions_supported_version == 0x0304"
-T fields -e tls.handshake.extensions_key_share_group \
-e tls.handshake.extensions_key_share_key_exchange_length
Analoge Untersuchungen wären sicherlich auch für das SSH-Protokoll im Haus interessant, also welche Server / Clienten sind mit welcher Kryptografie unterwegs?
- SSL Server Test (nur öffentlicher Port 443, TLS 1.2 erforderlich)
- Testing TLS/SSL encryption
- CustomLog für mod_ssl
- TShark
- SSH-Audit
Mentoren: Wolf Müller
Krypto-Inventarisierung & CBOM
Zukünftig werden Applikationen Quasi als Datenblatt ein CBOM (Cryptographic Bill of Material) bereitstellen, damit automatisiert bestimmt werden kann, welche Kryptoprimitiven darin potenziell genutzt werden und ob diese konform zu den gewünschten Vorgaben und Anforderungen sind. Wenn ein Anwendung neu geschrieben wird, kann das CBOM gleich mit erstellt werden und quasi als eine speziell fokussierte Dokumentation zur Applikation bereit gestellt werden. Was muss man hier beachten, wie kann es gelingen für bestehende (open source) Projekte nachträglich tool- oder auch KI-assistiert, so ein CBOM zu erstellen? Versuchen Sie für ein OpenSource-Projekt ihrer Wahl hier weiterzukommen. Könnte man auch mit einer KI und Reverse-Engeneering zu Aussagen kommen, wenn man nur ein Binary zur Verfügung hat?
Mentoren: Wolf Müller
SMB3@QUIC
(innovativ, herausfordernd)
Das Netzwerkprotokoll QUIC löst (für einige Anwendungsfälle z.B. HTTP/3) klassisches TCP ab, indem es im Userspace über UDP läuft und Verschlüsselung via TLS 1.3 erzwingt. Vorteile sind beschleunigter Verbindungsaufbau (0-RTT), Verhinderung von Head-of-Line-Blocking und damit parallel laufende Streams. Weiterhin bietet QUIC Verbindungs-Migration: Da QUIC Sitzungen über eine eindeutige ID statt über IP-Adressen identifiziert, bleibt eine aktive Verbindung selbst beim Netzwerkwechsel stabil. In Kombination mit SMB3 und Samba sollte QUIC also zu einem performanten Remotedateisystem beitragen. Da "SMB over QUIC" standardmäßig über den "sicheren Web-Port UDP 443" ist eine Passage durch viele Firewalls oft möglich. Für Administratoren bedeutet diese Symbiose, dass sie ihren Nutzern weltweit einen hochsicheren, performanten und nahtlosen Zugriff auf Unternehmensdaten bereitstellen können, der sich so unkompliziert wie eine HTTPS-Webseite verhält. Probieren Sie es aus.
- QUIC: A UDP-Based Multiplexed and Secure Transport
- Using TLS to Secure QUIC
- Samba+
- QUIC in Linux Kernel
Mentoren: Wolf Müller
FIDO2@USE
Die Nutzung von WebAuthn und FIDO2 beginnt langsam bei der Authentifizierung gegenüber Webdiensten und auch Apps eine relevante Verbreitung zu erlangen. Eine Nutzung ist mit hardwarebasierten SekurityKeys, mit Softwarekeys und mit Plattformkeys möglich. Probieren Sie es aus.
Wenn man eigene Dienste mit einem Securitykey nutzen möchte, gibt es bereits einige Snenarios, wo das in Linux möglich ist wie PAM, SSH, LUKS2 (Festplattenverschlüsselung) oder Datenbank von KeePassXC ≥ 2.7.7 entsperren. Probieren Sie diese aus und schauen Sie, welchen Komfort und welche Sicherheit diese bieten.
Die generische Nutzung ist natürlich innerhalb von HTTPS via Webauthn möglich. Doch wie kann ich diese starke Authentisierung auch für meinen eigenen Webserver erreichen? Ein möglicher Startpunkt könnte für den nginx die Verwendung von Authelia sein, die vielleicht in dieser (nicht verifizierten) Weise
server {
listen 443 ssl;
server_name app.example.com;
# ... SSL-Konfiguration ...
#Jeder Request wird vorab bei Authelia geprüft
auth_request /authelia;
location /authelia {
internal;
proxy_pass http://127.0.0.1:9091/api/verify;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Content-Length "";
proxy_set_header Connection "";
}
location / {
proxy_pass http://127.0.0.1:8080;
#User/Gruppen aus der Authelia-Antwort an das Backend durchreichen
auth_request_set $user $upstream_http_remote_user;
proxy_set_header Remote-User $user;
}
}
geschehen könnte. Probieren Sie es aus! Ist auch eine Prüfung der Attestation-Information beim Enrollment eines FIDO-Cerdentials möglich? Geht auch etwas für den Apache-Webserver?
Links:
- [1]
- PAM Doc
- git pam-u2f
- ssh-sk-helper
- ArchWiki LUKS2, FIDO
- KeePassXC 2.7.7 & Passkeys
- WebAuthn Level 2 (Standard)
- WebAuthn Level 3 (Standard)
- Authelia
Mentoren: Wolf Müller
PQC@FIDO2
Auch wenn FIDO2 ein Verfahren zur starken Authentisierung ist und somit nicht durch das "store now, decrypt later"-Szenario bedroht ist, so ist es sicher eine gute Idee auch an dieser Stelle bereits über die Verwendung von quantenresistenten verfahren nachzudenken. So sind ist der Plan ja die FIDO-Sticks eine lange Zeit als hardwaresichere Platform zu nutzen. Konkret wurde mit OpenSK einer in Rust geschriebenen Open-Source-Implementierung ein Prototyp vorgelegt, der die Signaturalgorithmen (klassisch) ECDSA und (PQC) Dilithium zu einer Hybridsignatur kombiniert, wobei die Signaturerstellung in einem akzeptablen Zeitrahmen auf dem FIDO-Stick erfolgt. Versuchen Sie diese Implementierung auf der Plattform Nordic nRF52840-DK zum laufen zu bringen, wie es in dem Abstract des Papers angeregt wird: "We publish an open-source implementation of our scheme at hybrid-pqc so that other researchers can reproduce our results on a nRF52840 development kit." Hierzu sollten Sie vielleicht erst einmal versuchen die klassische OpenSK-Version mit CTAP zu testen, um dann zu verstehen, wie man auf dem Stick das Erzeugen eines Schlüsselpaars anstößt. Erst im nächsten Schritt wird der Testaufbau dann auf die hybride Version erweitert.
Links:
Mentoren: Wolf Müller
Krypto-Agilität@OpenLDAP
Am Institut für Informatik, wird das ldaps-Protokoll verwendet, um Nutzer zu authentisieren. Die OpenLDAP-Server des Instituts sind redundant und synchronisieren die Nutzeraccounts untereinander. ldaps ist im Grunde ldap über TLS und wird in der Regel auf dem TCP-Port 636 bereitgestellt. Aktuell ist die TLS-Verbindung mit ECDSA-Schlüsseln mit 384-Bit Länge (secp384r1) mit einem eigenen Trustanker serverseitig authentisiert. Für die Etablierung der ephemeren Sitzungsschlüssel werden ebenfalls elliptische Kurven (X25519) verwendet. Das ist prinzipiell aktuell konform zur BSI TR-02102-2. Allerdings wäre es sinnvoll bereits jetzt über den Umstieg auf quantensichere Verfahren (insbesondere im Hybrid gepaart mit einem klassischen Verfahren) nachzudenken. Dabei ist es wünschenswert, dass ein Parallelbetrieb mit älteren Clienten, welche vielleicht eine elliptische Kurve mit großer Bitlänge unterstützen mit schon pqc-fähigen Clienten ermöglichen. Die Nutzung eines hybriden-pqc Verfahren für den Schlüsselaustausch, sollte nun erfolgreich "store now, decypt later" abwehren. Auch wenn das die dringendste Anforderung ist, ist der nächste Schritt, neben der Verwendung klassisch signierter Zertifikate zusätzlich für die Clienten, die diese Signaturen schon verifizieren können, auch hybride quantensichere Zertifikate zur Serverauthentifizierung anzubieten. Das beinhaltet einmal das Problem, wie mit solche Zertifikate erstellt werden können und welche Randbedingungen sich ergeben, wenn die Zertifikate und Signaturen von verschiedenen TLS-Clienten oder -Bibliotheken verifiziert werden sollen. Schauen Sie sich bitte insbesondere die Interoperabilität von openssl und gnutls an. Eine zusätzliche Herausforderung ist, sowohl pqc- als auch nichtpqcfähige Clienten zu unterstützen. Der TLS-Server muss dafür anhand der im "ClientHello" als unterstützt angegebenen Signaturverfahren richtig entscheiden, ob er das klassische ECDSA-Zertifikat oder ein hybrides PQC-Zertifikat für die Authentisierung verwendet.
Herangehen:
- Installieren Sie Ubuntu 26.04.1 LTS (als virtuelle Maschine)
- Installieren Sie OpenLDAP@Ubuntu
- Recherchieren Sie, welche {OpenSSL,GnuTLS}-Versionen welche Kryptoverfahren unterstützen.
- Erstellen Sie je einen Satz von {secp384r1,hybrid(klassisch+PQC}}-selbst signiertes Serverzertifikat
slapdist unter Ubuntu gegen GnuTLS gelinkt.- Versuchen Sie mit
gnutls-serveinen TLS-Server im Parallelbetrieb aufzusetzen. - Versuchen Sie sich auf diesen Server mit
gnutls-cliundopenssl s_clientdurch geeignete Wahl der Cipher als Parameter auf die eine als auch auf die andere Variante zu verbinden.
- Versuchen Sie mit
- Passen Sie die Konfiguration für
slapd.confan, um den Parallelbetrieb für OpenLDAP zu ermöglichen. - Versuchen Sie für die neue Variante einen möglichst sichern Handshake, TLS 1.3 mit starkem Key-agreement zu konfigurieren. (Ist hier mit der in Ubuntu 26.04.1 bereitgestellten Version auch schon ein hybrides quantensicheres Key-agreement möglich?)
Links:
- Folien "HTTPS, OpenVPN, TLS? Quantensicheres Key Agreement"
- sslbench.c
- Ubuntu 26.04 LTS
- Install OpenLDAP@Ubuntu
- man 5 slapd.conf
- gnutls-serv
- gnutls-cli
- openssl s_client
- GnuTLS: priority strings
- GnuTLS: ciphersuites
- TR-02102-2
- P521_mldsa87-Zertifikat mit OpenSSL
Mentoren: Wolf Müller
KI-Sicherheitsanalyse
[ Gabriel ]
Eine KI-assistierte oder KI-Agent-basierte Sicherheitsanalyse bietet ein großes Potenzial um Fehler in Software zu finden. Aber wie funktioniert das? Finden Sie heraus, welche Werkzeuge verfügbar und geeignet sind. Wählen Sie ein oder mehrere OpenSource-Projekte (diese sollten eher klein sein) und versuchen Sie, diese einer KI-basierten Sicherheitsanalyse zu unterziehen. Lassen Sie uns teilhaben an Ihren Einsichten, wo liegen Schwächen. Stärken, Kosten bei diesem Ansatz. Können Sie die (potenziell) gefundenen Schwachstellen verstehen und verifizieren?
Startpunkt
Mentoren: Wolf Müller