Netzwerksicherheit Linuxhotel Dezember 2019 (Debian)

1 Informationen zum Kurs

3 Forwarding und Routing unter Linux

  • Debian 10 VMs
  • Benutzer: nutzer, Password: villa
  • Root-Shell per su - und dem Passwort vogelsang
  • IP Adressen der Router
    • 01: 192.168.1.131 (Mario)
    • 02: 192.168.1.172 (James)
    • 03: 192.168.1.82 (Marcel Richter)
    • 04: 192.168.1.152 (Bernd Kohler)
    • 05: 192.168.1.190 (Marcel Fischer)
    • 06: 192.168.1.85 (Etienne)
    • 07: 192.168.1.182 (Sascha)
    • 08: 192.168.1.97 (Andy)
    • 09: 192.168.1.106 (Bernd Reinecke)
    • 0A: 192.168.1.166 (Carsten)
+--------+	       	  +--------+
| Client |	   	  | Server |
|        |	   	  |        |
| enp0s3 | 	   	  | enp0s3 |
+---+----+		  +----+---+
    |        Router	       |
    |       +------+       |
    | enp0s8|      | enp0s9|
    +-------+      +-------+
	    +---+--+
		|enp0s3 (externe Netze/Laptops)
  • MAC Adresse des Client: 08:00:00:00:0C:XX
  • MAC Adresse des Servers: 08:00:00:00:0F:XX
ssh nutzer@<ip-adresse>
su -
ip address show

3.1 Editoren auf den virtuellen Maschinen

  • emacs
  • vi (vim)
  • mg (Micro Emacs)
  • jove
  • nano
  • joe
  • weitere Editoren können/dürfen nachinstalliert werden

4 TMUX - terminal multiplexer

  • Beispiel: tmux auf dem Router/Server/Client starten
tmux
Aktion Tastaturkombination
Neues Terminal CTRL+B C
nächstes Terminal CTRL+B N
voheriges Terminal CTRL+B P
Terminal horizontal teilen CTRL+B "
Terminal vertikal teilen CTRL+B %
zwischen geteilten Terminals wechseln CTRL+B <cursor>
zwischen geteilten Terminals wechseln CTRL+B O
Terminal schliessen CTRL+B x
Tmux abhängen (detach) CTRL+B d
Tmux anhängen tmux attach
TMUX Kommandozeile CTRL+B :
Scrollen (mit Cursor-Tasten, Abbrechen mit CTRL+C) CTRL+[
Tastenkommandos in alle Fenster (Kommandozeile) set synchronize-panes

5 Einrichtung von Quagga auf dem Router

  • Zeit: 10 Minuten
  • wir arbeiten auf dem Router-VM Rechner
  • Empfehlung: tmux starten und in tmux arbeiten
  • auf dem Router Server den Hostnamen aendern (als root)
hostnamectl set-hostname router0X
  • um den neuen Hostnamen zu sehen, die Root-Shell beenden und per sudo -s eine neuen Root-Shell öffnen (oder mit bash eine neue Shell starten)
  • die Routing-Software quagga installieren (auf dem Router)
apt install quagga
  • Rechte auf dem Konfigurationsverzeichnis anpassen und den Quagga-Dienst starten
touch /etc/quagga/zebra.conf
touch /etc/quagga/vtysh.conf
systemctl enable --now zebra
systemctl status zebra
ps aux | grep quagga
quagga    3214  0.0  0.0  24712   732 ?        Ss   21:58   0:00 /usr/lib/quagga/zebra --daemon -A 127.0.0.1
root      3232  0.0  0.1  14228   976 pts/1    S+   21:58   0:00 grep --color=auto quagga
  • IPv6 und IPv4 Konfiguration der Netzwerkschnittstellen enp0s8 (Client-Netz) und enp0s9 (Server-Netz) von der Quagga Kommanozeile (auf dem Router)
vtysh
router0X#
router0x# conf terminal
router0x(config)# interface enp0s8
router0x(config-if)# ipv6 address fd0x::1/64
router0x(config-if)# ipv6 nd prefix fd0x::/64 900 300
router0x(config-if)# no ipv6 nd suppress-ra
router0x(config-if)# no shutdown
router0x(config-if)# exit
router0x(config)# interface enp0s9
router0x(config-if)# ipv6 address 2001:db8:x::1/64
router0x(config-if)# ipv6 nd prefix 2001:db8:x::/64 900 300
router0x(config-if)# no ipv6 nd suppress-ra
router0x(config-if)# no shutdown
router0x(config-if)# exit
router0x(config)# exit
router0x# write
router0x# conf terminal
router0x(config)# interface enp0s8
router0x(config-if)# ip address 172.16.x.1/24
router0x(config-if)# exit
router0x(config)# interface enp0s9
router0x(config-if)# ip address 100.64.x.1/24
router0x(config-if)# exit
router0x(config)# exit
router0x# write

5.1 Zugang vom Router zum Server und zum Client

  • Zeit: 15 Minuten
  • Server und Client VM sind nicht direkt vom Laptop erreichbar
  • auf dem Router läuft kein DHCP-Server, d.h. Server and Client bekommen keine IPv4-Adresse per DHCP
  • wir haben auf dem Router IPv6 Router-Advertisements angeschaltet, der Router "ruft" nun in das Nettzwerk-Segment des Servers und des Clients die jeweilige IPv6-Netzwerk-Adresse
  • IPv6-fähige Betriebssysteme konfiguieren automatisch eine IPv6 Adresse aus diesen Adressbereichen (SLAAC Stateless Address Auto-Configuration)
  • von einer MAC-Adresse zu einer IPv6 Adresse: wie aus der Ethernet-MAC-Adresse unter IPv6 mit SLAAC eine IPv6-Adresse entsteht
08:00:27:ff:e8:ae
  • von 48bit auf 64bit erweitern per "FFFE"
08:00:27:FF:FE:ff:e8:ae
  • Bit 7 invertieren
0A:00:27:FF:FE:ff:e8:ae
  • Link-Lokaler IPv6 Prefix anfügen und als IPv6 Adresse schreiben
fe80::a27:ff:feff:e8ae
  • vollständige IPv6 Adresse
fe80:0000:0000:0000:0a27:00ff:feff:e8ae
  • MAC Adresse des Client: 08:00:00:00:0C:XX
  • MAC Adresse des Servers: 08:00:00:00:0F:XX

5.1.1 Konfiguration der Server VM

  • vom Router SSH auf den Server (neues TMUX Fenster öffnen)
ssh nutzer@2001:db8:x::a00:ff:fe00:f0x
  • manuelle IPv4 Konfiguration auf dem Server
su -
hostnamectl set-hostname server0X
ip addr add 100.64.x.2/24 dev enp0s3
ip route add default via 100.64.x.1
  • IP Konfiguration fest einstellen in der Datei /etc/network/interfaces
auto enp0s3
iface enp0s3 inet static
        address 100.64.x.2
        netmask 255.255.255.0
        gateway 100.64.x.1

5.1.2 Konfiguration der Client VM

  • vom Router per SSH auf den Client (neues TMUX Fenster öffnen)
ssh nutzer@fd0x::a00:ff:fe00:c0x
  • manuelle IPv4 Konfiguration auf dem Client
su -
hostnamectl set-hostname client0X
ip addr add 172.16.x.2/24 dev enp0s3
ip route add default via 172.16.x.1
  • IP Konfiguration fest einstellen in der Datei /etc/network/interfaces
auto enp0s3
iface enp0s3 inet static
        address 172.16.x.2
        netmask 255.255.255.0
        gateway 172.16.x.1

5.1.3 Testen der Verbindungen

  • vom Server zum Router (auf dem Server):
ping 100.64.x.1
ping 172.16.x.1
ping6 2001:db8:x::1
ping6 fd0x::1
  • vom Client zum Router (auf dem Client):
ping 172.16.x.1
ping 100.64.x.1
ping6 fd0x::1
ping6 2001:db8:x::1
  • Geht ein 'ping' vom Server zum Client?

5.2 Routing (Forwarding)

  • Zeit: 5 Minuten
  • Geht ein 'ping' vom Server zum Client?
  • Antwort: ohne IP-Forwarding - nein
  • Forwarding anschalten (in der Quagga Shell auf dem Router)
vtysh
router0x# conf terminal
router0x(config)# ip forwarding
router0x(config)# ipv6 forwarding
router0x(config)# exit
route0x# write
  • ping vom Client zum Server testen, sollte nun funktionieren

5.3 Verbindung in das Internet

  • Zeit: 10 Minuten
  • Geht ein 'ping' von Router ins Internet (1.0.0.1)? (auf dem Router ausführen)
ping 1.1
  • geht ein 'ping' vom Server oder Client ins Internet (1.0.0.1)? (auf dem Server oder dem Client ausführen)
ping 1.1
  • Lösung: iptables Masquerading NAT (auch Cone-NAT oder NATPT/NAT-Port-Translation oder NAT44/NAT-IPv4-zu-IPv4 genannt)
  • auf dem Router in einer BASH-Shell (nicht im Quagga)
iptables -A POSTROUTING -t nat -o enp0s3 -j MASQUERADE
  • nach dem Eintragen des NAT nochmals Testen, ob ein 'ping' vom Client und Server in das Internet funktioniert

6 iptables/nftables Firewall

6.1 iptables

6.1.1 Chains

  • prerouting
  • input
  • output
  • forward
  • postrouting

6.1.2 Tables

  • filter (default)
  • nat
  • mangle
  • raw

6.1.3 Befehle

  1. Regeln auflisten
    iptables -L <chain> [-t <table>]
    iptables -L <chain> [-t <table>] -v -n
    
  2. Regeln einer Chain/Tabelle loeschen
    iptables -F <chain> [-t <table>]
    
  3. Default Policy setzen
    iptables -P <chain> [DROP|ACCEPT]
    
  4. Chain anlegen/loeschen
    iptables -N <chainname>
    iptables -X <chainname>
    
  5. Regeln anlegen/einfuegen/loeschen
    iptables -A <chain> <Regel>
    iptables -I <chain> <pos> <Regel>
    iptables -R <chain> <pos> <Regel>
    iptables -D <chain> <pos>/<Regel>
    

6.1.4 Regeln

ein "!" vor einem Regelelement negiert das Regelelement

-i <interface> # Eingangs-Interface
-o <interface> # Ausgangs-Interface
-s <ipaddr>    # Quelladresse
-d <ipaddr>    # Zieladresse
-p <protocol>  # tcp, udp, icmp ...
-dport <port>  # Zielport
-sport <port>  # Quellport
-m <modul> <modulparameter> # Modul laden und benutzen
-j <target>    # Ziel der Regel (ACCEPT, DROP, REJECT ...)

6.1.5 Targets

-j RETURN # back to calling chain
-j LOG # syslog
-j REJECT [--reject-with <icmp-error-type>]
-j SNAT --to-source <addr>[-addr][:port-port] # nur POSTROUTING, Table "nat"
-j DNAT --to-destination <addr>[-addr][:port-port] # nur PREROUTING und OUTPUT, Table "nat"
-j REDIRECT --to-ports port[-port]
-j MASQUERADE --to-ports port[-port]
-j chain-name

6.1.6 Protokoll "tcp"

--syn # Verbindungsaufbau
--tcp-flags <mask> <active> # SYN,ACK,FIN,RST,URG,PSH,ALL,NONE
--tcp-flags SYN,RST,ACK SYN

6.1.7 Protokoll "icmp"

--icmp-type <icmp-type>
iptables -p icmp -h  # lists icmp types

6.1.8 Modul "state"

  • NEW
  • ESTABLISHED
  • RELATED
  • INVALID
-m state --state <state1[,state2,...]>

6.1.9 Modul 'recent'

  • Nur 3 SSH Anmeldeversuche per 15 Minuten
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 900 --hitcount 3 -j DROP

6.1.10 Logging

-j LOG --log-level <num>
-j LOG --log-prefix <prefix> # 14 chars
-j LOG --log-tcp-options
-j LOG --log-ip-options

6.1.11 Masqerading

// masquerading auf dem Router anschalten, server und client kommen nun ins Internet
iptables -A POSTROUTING -t nat -o enp0s3 -j MASQUERADE
iptables -L -t nat

6.1.12 Beispiel einer 'iptables' Script Preamble

#!/bin/sh

# default policy
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# bestehene Regeln löschen (Firewall Reset)
iptables -F
iptables -F -t nat

# Loopback Interface erlauben
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

6.1.13 Beispiel eines Firewall-Stopp-Script

#!/bin/sh

iptables -P INPUT   ACCEPT
iptables -P OUTPUT  ACCEPT
iptables -P FORWARD ACCEPT

# bestehene Regeln löschen (Firewall Reset)
iptables -F
iptables -F -t nat

6.1.14 Firewall Regeln testen mit "Sicherheitsnetz"

  • Firewall-Regeln nach 1 Minute zurücksetzen
(sleep 60 && ./firewall-stopp.sh) &
./firewall.sh

6.2 Aufgabe Host-Firewall mit iptables

  • BIND 9 auf dem Router installieren, um eine Server Anwendung auf dem Router zu haben
apt install bind9 dnsutils
systemctl start bind9
  • Erstelle eine Host-Firewall-Regeln für den Router
  • Log-Ausgaben anschauen
journalctl -e  # an das Ende des Journal-Log springen
journalctl -f  # an das Ende des Journals springen und neue Einträge sofort anzeigen (wie tail -f)

6.2.1 Tests

  • Diese Tests sollen funktionieren
    • SSH vom Laptop zum Router
    • "ping" vom Router zum Internet-GW 192.168.1.5
    • "ping" vom Laptop zum Router
  • dieser Test sollten nicht funktionieren
    • DNS Anfrage von Laptop zum Router (auf dem Router läuft ein BIND 9 DNS Server) dig @<ip-des-routers> chaos txt authors.bind. Diese Anfrage sollte ein Timeout ergeben, das Paket an Port 53 der Firewall sollte verworfen werden (im Journal nachschauen)

6.2.2 eine mögliche Lösung

#!/bin/sh

# default policy
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# bestehene Regeln loeschen (Firewall Reset)
iptables -F
iptables -F -t nat

# Loopback Interface erlauben
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# bestehende eingehende Verbindungen aus dem Internet erlauben
iptables -A INPUT  -i enp0s3 -m state --state RELATED,ESTABLISHED -j ACCEPT
# bestehende eingehende Verbindungen aus dem Client/Server-Netz erlauben
iptables -A INPUT  -i enp0s8 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT  -i enp0s9 -m state --state RELATED,ESTABLISHED -j ACCEPT

# bestehende ausgehende Verbindungen erlauben
iptables -A OUTPUT  -m state --state RELATED,ESTABLISHED -j ACCEPT

# neue ausgehende Verbindungen erlauben
iptables -A OUTPUT  -m state --state NEW -j ACCEPT

# NATPT fuer ausgehende Verbindungen
iptables -A POSTROUTING -t nat -o enp0s3 -j MASQUERADE

# SSH eingehend erlauben
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

# icmp eingehend erlauben
iptables -A INPUT -p icmp -j ACCEPT

# Pakete verwerfen und ins Syslog schreiben
iptables -A INPUT -j LOG --log-prefix "FW Drop:"
iptables -A INPUT -j DROP
  • aktives (Filter-Tabelle-) Regelwerk mit Regel-Nummern, Zählern und Interface-Abhängigkeiten anzeigen
iptables -L -v -n --line-numbers

6.3 Uhrzeit auf dem Router korrigieren

  • Zeitzone anpassen
timedatectl set-timezone Europe/Berlin
  • Programm ntpdate installieren
apt install ntpdate
  • Uhrzeit und Datum via NTP setzen
ntpdate pool.ntp.org

6.4 Aufgabe: DNS Anfragen zum BIND 9 DNS-Server erlauben

  • Zeit: 10 Minuten
  • Erweitere die Firewall, so das DNS-Anfragen (Port 53 UDP und TCP) vom Laptop zum Router möglich sind
  • Firewall-Regeln neu laden und dann die Firewall testen (UDP und TCP Transport, vom Laptop aus)
apt install dnsutils
dig @<ip-des-routers> txt chaos authors.bind
dig +tcp @<ip-des-routers> txt chaos version.bind

6.4.1 Lösung

[...]
# DNS eingehend erlauben
iptables -A INPUT -p tcp --dport 53 -m state --state NEW -j ACCEPT
iptables -A INPUT -p udp --dport 53 -m state --state NEW -j ACCEPT
[...]

6.5 Firewall testen mit "nmap"

  • Test der Firewall vom Laptop aus (d.h. diese Befehle direkt auf dem Laptop ausführen)
apt install nmap
nmap -sT -v -A 192.168.1.yyy # <ip-der-firewall>
  • Route für das Client-Segment dem Laptop hinzufügen, dann ein Scan des Client-Netzes hinter der Firewall
ip route add 172.16.x.0/24 via <ip-des-Firewall-Routers>
nmap -sT -v -A 172.16.x.0/24 # <ip-netz-hinter-der-firewall>

6.6 iptables Regeln sichern

  • iptables Regeln im Linux-Kernel können mit dem Befehl iptables-save in eine (Text-)Datei gesichert werden. Die Regeln aus einer Sicherungs-Datei können über den Befehl iptables-restore wieder hergestellt werden
router0x$ iptables-save > /etc/iptables.rules

6.7 iptables Systemd Unit

  • Datei /usr/local/sbin/iptables-flush
#!/bin/sh

iptables -P INPUT   ACCEPT
iptables -P OUTPUT  ACCEPT
iptables -P FORWARD ACCEPT

# bestehene Regeln löschen (Firewall Reset)
iptables -F
iptables -F -t nat
  • Datei ausführbar machen
chmod +x /usr/local/sbin/iptables-flush
  • Datei /etc/systemd/system/iptables.service
[Unit]
Description=IPTables Packet Filtering Framework
DefaultDependencies=no
After=systemd-sysctl.service
Before=sysinit.target
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables.rules
ExecReload=/sbin/iptables-restore /etc/iptables.rules
ExecStop=/usr/local/sbin/iptables-flush
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
  • Systemd-Unit-Dateien neu laden
systemctl daemon-reload
  • iptables Unit ausprobieren
systemctl start iptables
iptables -L
systemctl stop iptables
iptables -L
  • Firewall beim Neustart anschalten
systemctl enable iptables

6.8 Optional: Anpassung des Firewall-Flush-Skripts

  • Firewall-Regeln aus dem Speicher sichern. Hiermit werden manuelle Änderungen an den Firewall-Regeln permanent gespeichert. Dies ist optional und nicht in allen Fällen erwünscht!
  • Datei /usr/local/sbin/iptables-flush
#!/bin/sh
# Firewall-Regeln sichern
iptables-save > /etc/iptables.rules

# Default-Policy öffnen
iptables -P INPUT   ACCEPT
iptables -P OUTPUT  ACCEPT
iptables -P FORWARD ACCEPT

# bestehene Regeln löschen (Firewall Reset)
iptables -F
iptables -F -t nat

6.9 Anpassung: vom Client zum Linuxhotel DNS-Resolver

  • Zeit: 15 Minuten
  • Neue Verbindungen auf allen Netzwerkschnittstellen des Routers erlauben
# bestehende eingehende Verbindungen aus dem Internet erlauben
iptables -A INPUT  -i enp0s3 -m state --state RELATED,ESTABLISHED -j ACCEPT
  • ersetzen durch
# bestehende eingehende Verbindungen erlauben
iptables -A INPUT  -m state --state RELATED,ESTABLISHED -j ACCEPT
  • Erstelle Regeln, welche dem Client erlauben, per DNS Port 53 (UDP/TCP) auf den DNS-Resolver im Linuxhotel (192.168.1.5) zuzugreifen
[...]
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 172.16.x.0/24 -d 192.168.1.5 -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -s 172.16.x.0/24 -d 192.168.1.5 -p tcp --dport 53 -j ACCEPT
[...]
  • DNS-Resolver in der /etc/resolv.conf auf der Client VM eintragen
client0x$ echo "nameserver 192.168.1.5" > /etc/resolv.conf
  • Test der Namensauflösung (Name des DNS-Servers auf der IP-Adresse 1.1.1.1)
ping one.one.one.one
  • eine Regel in der Chain FORWARD für icmp (IPv4) hinzufügen, damit der ping auch das Internet erreicht
iptables -A FORWARD -m state --state ESTABISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state NEW -s 172.16.x.0/24 -p icmp -j ACCEPT
iptables -A FORWARD -m state --state NEW -d 172.16.x.0/24 -p icmp -j ACCEPT

6.10 Optional Aufgabe: SSH direkt vom Laptop auf Client und Server

  • Zeit: 10 Minuten
  • erweitere die Firewallregeln um neue Regeln in der FORWARD chain, so das direkte SSH-Verbindungen vom Laptop zur Client-VM und zur Server-VM möglich sind.

6.10.1 Lösung:

iptables -A FORWARD -i enp0s3 -p tcp --dport 22 -m state --state NEW -j ACCEPT

6.11 Aufgabe - Regeln für Paket-Installation:

  • Zeit: 15 Minuten
  • welche weiteren Regeln müssen in der Firewall eingetragen werden, um Paketinstallationen auf dem Client per apt install zu erlauben?
  • erstelle die Regeln und teste die Pakete dnsutils und links zu installieren (ein Text-Webbrowser) (apt install links dnsutils)
  • Testen, ob die DNS-Namensauflösung von der Client (VM) über den DNS-Resolver im Linuxhotel-Netzwerk funktioniert
  • SSH vom Router zum Server
ssh nutzer@172.16.x.2
  • DNS Abfrage testen
client0x$ dig @192.168.1.5 linuxhotel.de A
; <<>> DiG 9.9.6-P1 <<>> @192.168.1.5 linuxhotel.de
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12224
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;linuxhotel.de.                 IN      A

;; ANSWER SECTION:
linuxhotel.de.          3599    IN      A       217.69.87.63

;; Query time: 47 msec
;; SERVER: 192.168.1.5#53(192.168.1.17)
;; WHEN: Tue Jan 19 04:38:16 CET 2016
;; MSG SIZE  rcvd: 58

6.11.1 Lösung - Regeln für Paket-Installation:

[...]
iptables -A FORWARD -s 172.16.x.0/24  -p tcp --dport 80  -j ACCEPT
[...]

6.12 Verbindungen auf dem Router anschauen per iftop

router0x$ apt install iftop
router0x$ iftop -i enp0s3
  • Taste p schaltet die Anzeige der UDP/TCP Ports an
  • Taste n schaltet DNS-Rückwärtsauflösung für IP-Adressen aus

6.13 Aufgabe: Routing-Firewall

  • Zeit: 30 Minuten
  • Erstelle erweiterte Regeln für das Routing des Router
    • SSH von Client/Firewall zum Server erlauben
    • HTTP (Port 80) vom Client zum Server erlauben
    • DNS von Client und vom Server ins Internet erlauben
    • HTTP(s) (80/443) vom Client/Server ins Internet zulassen (für Software Updates)
    • Masquerading NAT für Verbindungen ins 'Internet'
    • vom Router DHCP ins Linuxhotel-Netz erlauben (Port 67/68 UDP)
    • keine anderen ausgehenden Verbindungen erlauben

6.13.1 Tests

  • SSH vom Client zum Server
client0x# ssh root@100.64.x.2
  • HTTP vom Client zum Server testen
    • auf dem Server einen Webserver-Prozess starten
server0x# python -m SimpleHTTPServer 80
  • auf dem Client einen Text-Modus Browser starten
    • die Dateien im Heimverzeichnis des Benutzers "root" auf dem Server sollten angezeigt werden (wenn keine Datei "index.html" vorliegt)
client0x# links 100.64.x.2
  • DNS vom Server ins Internet testen
server0x# dig @192.168.1.5 kernel.org a
  • http/https vom Server/Client ins Internet testen
echo "nameserver 192.168.1.5" > /etc/resolv.conf
links www.linuxhotel.de
links https://notes.defaultroutes.de
  • auf dem Server/Client "nmap" installieren und von dort den Router und das Linuxhotel GW scannen (was laesst die Firewall von innen nach aussen durch)
apt install nmap
nmap -sT 172.16.x.1
nmap -sT 172.16.x.2
nmap -sT 100.64.x.1
nmap -sT 100.64.x.2
nmap -sT 192.168.1.5
  • bei einem Scan vom Server/Client oder von der Firewall in das Linuxhotel Netz oder ins Internet dürfen nur die Ports 53, 80 und 443 als offen angezeigt werden. Rechner in den Client und Server Netzen dürfen nur über diese Ports mit der Aussenwelt kommunizieren. Ein SSH vom Server ins Internet darf nicht möglich sein.

6.13.2 Eine mögliche Lösung

#!/bin/sh

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# bestehene Regeln löschen (Firewall Reset)
iptables -F
iptables -F -t nat

# Loopback Interface erlauben
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# bestehende ausgehende Verbindungen erlauben
iptables -A OUTPUT  -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

# bestehende eingehende Verbindungen erlauben
iptables -A INPUT  -m state --state RELATED,ESTABLISHED -j ACCEPT

# NATPT fuer ausgehende Verbindungen
iptables -A POSTROUTING -t nat -o enp0s3 -j MASQUERADE

# DHCPv4 ausgehen erlauben
iptables -A OUTPUT -p udp --dport 68 -m state --state NEW -j ACCEPT

# SSH eingehend erlauben
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

# SSH vom Router zum Server erlauben
iptables -A OUTPUT -o enp0s9 -p tcp --dport 22 -j ACCEPT

# SSH vom Router zum Client erlauben
iptables -A OUTPUT -o enp0s8 -p tcp --dport 22 -j ACCEPT

# SSH vom Client-Netz zum Server erlauben
iptables -A FORWARD -i enp0s9 -p tcp --dport 22 -j ACCEPT

# HTTP vom Client zum Server
iptables -A FORWARD -s 172.16.x.2 -d 100.64.x.2 -p tcp --dport 80 -j ACCEPT

# DNS ausgehend zulassen
iptables -A OUTPUT -o enp0s3 -m state --state NEW -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -o enp0s3 -m state --state NEW -p tcp --dport 53 -j ACCEPT

# DNS vom Client/Server zulassen
iptables -A FORWARD -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -p tcp --dport 53 -j ACCEPT

# HTTP/HTTPS vom Router/Client/Server zulassen
iptables -A FORWARD -o enp0s3 -m state --state new -p tcp --dport 80  -j ACCEPT
iptables -A FORWARD -o enp0s3 -m state --state new -p tcp --dport 443 -j ACCEPT
iptables -A OUTPUT  -o enp0s3 -m state --state new -p tcp --dport 80  -j ACCEPT
iptables -A OUTPUT  -o enp0s3 -m state --state new -p tcp --dport 443 -j ACCEPT

# icmp erlauben
iptables -A INPUT -p icmp -j ACCEPT

# Pakete verwerfen
iptables -A INPUT   -j LOG --log-prefix "FW INP Drop:"
iptables -A FORWARD -j LOG --log-prefix "FW FRW Drop:"
iptables -A OUTPUT  -j LOG --log-prefix "FW OUT Drop:"
iptables -A INPUT -j DROP
iptables -A FORWARD -j DROP
iptables -A OUTPUT -j DROP

6.14 Firewall Unittest und Dokumentation mit Emacs-Org-Mode und Babel

apt install emacs-nox ruby
  • Org-Babel-Dokument (, am Anfang der Zeilen entfernen, sind notwendig um Org-Mode innerhalb von einem Org-Mode Dokument einzubetten)
#+Title: Firewall-Dokumentation
#+Language: de

* Babel anschalten                                                 :noexport:
#+BEGIN_EXAMPLE                                                                                          
(org-babel-do-load-languages 'org-babel-load-languages                                                   
  '((ruby . t)                                                                                           
))                                                                                                       
#+END_EXAMPLE                                                                                            

#+BEGIN_SRC ruby :exports results
require 'time'
"Dieser Firewalltest wurde am #{Time.now}
 auf Rechner #{`hostname`} erstellt"
#+END_SRC

#+RESULTS:
: Dieser Firewalltest wurde am 2016-11-30 09:10:09 +0100
:  auf Rechner csmobile4.home.strotmann.de
:  erstellt

* Firewall Regeln

Dies sind unsere aktuellen Firewall Regeln

** INPUT Chain

*** Filter Tabelle

#+BEGIN_SRC ruby :exports results
`sudo iptables -L INPUT -t filter -v -n --line-numbers`
#+END_SRC

#+RESULTS:
#+begin_example
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
2        0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
3        0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:67
4        0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:67
5    63268   28M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
6      591 41163 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
7     2655  631K INPUT_direct  all  --  *      *       0.0.0.0/0            0.0.0.0/0
8     2655  631K INPUT_ZONES_SOURCE  all  --  *      *       0.0.0.0/0            0.0.0.0/0
9     2655  631K INPUT_ZONES  all  --  *      *       0.0.0.0/0            0.0.0.0/0
10       0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID
11     516 84169 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited
#+end_example

* Firewall Tests

 * Können wir das Internet über Port 80 erreichen?

#+BEGIN_SRC ruby :exports both
`nmap -sT linuxhotel.de -p 80`
#+END_SRC

#+RESULTS:
:
: Starting Nmap 7.12 ( https://nmap.org ) at 2016-11-30 09:16 CET
: Nmap scan report for linuxhotel.de (217.69.87.63)
: Host is up (0.030s latency).
: rDNS record for 217.69.87.63: namebased-hostings.villa-vogelsang.de
: PORT   STATE SERVICE
: 80/tcp open  http
:
: Nmap done: 1 IP address (1 host up) scanned in 0.53 seconds

6.15 ICMP Filter

  • Firewall-Regeln für ICMPv6 werden in RFC 4820: "Recommendations for Filtering ICMPv6 Messages in Firewalls" beschrieben
  • Unbedingt benötigte ICMPv6 Kommunikation
    • Destination Unreachable (Type 1) - All codes
    • Packet Too Big (Type 2)
    • Time Exceeded (Type 3) - Code 0 only
    • Parameter Problem (Type 4) - Codes 1 and 2 only
    • Echo request / Echo reply (needed for Teredo)
  • oft benötigte ICMPv6 Meldungen
    • Time Exceeded (Type 3) - Code 1
    • Parameter Problem (Type 4) - Code 0
    • Mobile IPv6 (nur wenn eingesetzt)
      • Home Agent Address Discovery Request (Type 144)
      • Home Agent Address Discovery Reply (Type 145)
      • Mobile Prefix Solicitation (Type 146)
      • Mobile Prefix Advertisement (Type 147)
  • selektiv Filtern (nur erlauben wenn diese Funktionen benutzt werden)
    • Node Information Query (Type 139)
    • Node Information Response (Type 140)
    • Router Renumbering (Type 138)
    • ICMPv6 mit experimentellen Nachrichten-Typen (100, 101, 200, and 201)
    • Erweiterungs-Nachrichten-Typen (Types 127 and 255)
  • alles andere Blocken, insbesondere
    • Seamoby Experimental (Type 150)
    • Unallocated Error messages (Types 5-99 inclusive and 102-126 inclusive)
    • Unallocated Informational messages (Types 154-199 inclusive and 202-254 inclusive)
  • Liste der ip6tables ICMPv6 Codes
ip6tables -p ipv6-icmp -h

6.16 Beispiel IPv6 Firewall

#!/bin/sh

# default policy
ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
ip6tables -P FORWARD DROP

# bestehene Regeln löschen (Firewall Reset)
ip6tables -F
ip6tables -F -t nat

# Loopback Interface erlauben
ip6tables -A INPUT  -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT

# Pakete mit RH0 (Routing Header 0, Source Routing) blocken
ip6tables -A INPUT -m rt --rt-type 0 -j DROP
ip6tables -A FORWARD -m rt --rt-type 0 -j DROP
ip6tables -A OUTPUT -m rt --rt-type 0 -j DROP

# bestehende eingehende Verbindungen aus dem Internet erlauben
ip6tables -A INPUT  -i enp0s3 -m state --state RELATED,ESTABLISHED -j ACCEPT

# bestehende eingehende Verbindungen aus dem Client-Netz erlauben
ip6tables -A INPUT  -i enp0s8 -m state --state RELATED,ESTABLISHED -j ACCEPT

# bestehende ausgehende Verbindungen erlauben
ip6tables -A OUTPUT  -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

# neue ausgehende Verbindungen erlauben
ip6tables -A OUTPUT  -m state --state NEW -j ACCEPT

# Link-Lokaler Multicast eingehend erlauben
ip6tables -A INPUT -s ff02::/16 -j ACCEPT

# Link-Lokale Kommunikation im Subnet erlauben
ip6tables -A INPUT -s fe80::/10 -j ACCEPT

# ICMPv6
ip6tables -A INPUT -p icmpv6 --icmpv6-type 1 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type 2 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type 3/0 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type 4/1 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type 4/2 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -m limit --limit 900/minute -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-reply   -m limit --limit 900/minute -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT
# ICMPv6 redirect erlauben (notwendig fuer Router-Fallback)
ip6tables -A INPUT -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j LOG --log-prefix "ICMPv6:"

6.17 Beispiel Destination-NAT (DNAT)

  • Zugriff vom Laptop zum Webserver auf der Server VM (in das Firewall-Skript an passender Stelle einbauen)
# HTTP vom Internet auf Server zulassen
iptables -A FORWARD -i enp0s3 -m state --state new -p tcp --dport 80 -j ACCEPT
  • Auf dem Server eine kleine Webseite erzeugen und den Webserver starten
echo "dies ist der Server" > ~/index.html
cd ~
python -m SimpleHTTPServer 80
  • Auf dem Laptop eine Route auf den Server setzen und dann per Firefox auf die URL http://100.64.x.2 gehen
ip route add 100.64.x.0/24 via 192.168.1.xxx
  • Auf dem Client (der hier die Rolle eines Backup-Webserver einnimmt) eine kleine Webseite erzeugen und den Webserver starten
echo "dies ist der Client" > ~/index.html
cd ~
python -m SimpleHTTPServer 80
  • Backup DNAT um Anfragen an den Webserver 100.64.x.2 auf den Client "umzuleiten"
# HTTP per DNAT von Server auf den Client "umbiegen"
iptables -A PREROUTING -t nat -i enp0s3 -p tcp --dport 80 \
    -j DNAT --to-destination 172.16.x.2
  • Alternative, wenn das Ziel eine Anwendung auf der Firewall-Maschine ist (z.B. für einen "stealth" reverse Proxy)
iptables -A PREROUTING -t nat -i enp0s3 -p tcp --dport 80 \
    -j REDIRECT --to-port 3128

6.18 Shorewall

  • ShoreWall ist ein Wrapper um iptables. Mit ShoreWall ist es möglich, auch komplexte Firewall-Regelwerke übersichtlich(er) zu verwalten
  • Webseite: http://www.shorewall.net
  • es ist sehr unwarscheinlich, das ShoreWall für das neue nftables angepasst wird
  • iptables Firewall stoppen (über das eigene Firewall-Stop Skript)
systemctl stop iptables
systemctl disable iptables
  • Installation von ShoreWall unter Debian
apt install shorewall
  • Definition der Firewall-Zonen in der Datei /etc/shorewall/zones - firewall "zonen" (max. 5 Zeichen)
#ZONE   TYPE    OPTIONS                 IN                      OUT
#                                       OPTIONS                 OPTIONS
fw      firewall
net     ipv4
loc     ipv4
dmz     ipv4
  • /etc/shorewall/interfaces - Interface zu Host Zuordnung
?FORMAT 2
###############################################################################
#ZONE           INTERFACE               OPTIONS
net             enp0s3                    dhcp
loc             enp0s8
dmz             enp0s9
  • /etc/shorewall/masq - Masquerading und SNAT
#INTERFACE:DEST         SOURCE          ADDRESS         PROTO   PORT(S) IPSEC   MARK    USER/   SWITCH  ORIGINAL
#                                                                                       GROUP           DEST
enp0s3:                 100.64.x.0/24,172.16.x.0/24
  • /etc/shorewall/policy - generische Policy zwischen Zonen
#SOURCE         DEST            POLICY          LOG LEVEL       LIMIT:BURST
loc             net             ACCEPT
net             all             DROP            info
# THE FOLLOWING POLICY MUST BE LAST
all             all             REJECT          info
  • /etc/shorewall/rules - Ausnahmen zu der Policy zwischen Zonen (Firewallregeln)
#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINAL        RATE          USER/   MARK    CONNLIMIT       TIME            HEADERS         SWITCH          HELPER
#                                                       PORT    PORT(S)         DEST            LIMIT           GROUP
?SECTION ALL
?SECTION ESTABLISHED
?SECTION RELATED
?SECTION INVALID
?SECTION UNTRACKED
?SECTION NEW
# Kaputte Pakete stoppen
#
Invalid(DROP)   net             all             tcp

# DNS Firewall -> Internet
#
DNS(ACCEPT)     $FW             net
#
#
# SSH von Lokal zu DMZ, Firewall
#
SSH(ACCEPT)     loc             $FW
SSH(ACCEPT)     loc             dmz
#
# SSH von der Firewall zum Client, Server
##
SSH(ACCEPT)     $FW             loc
SSH(ACCEPT)     $FW             dmz
#
#
# SSH von Internet zu Firewall
#
SSH(ACCEPT)     net             $FW
#
# DNS aus der DMZ ins Internet
#
DNS(ACCEPT)     dmz             net
# Kein "ping" auf die Firewall
#
Ping(DROP)      net             $FW
#
# ping zwischen loc, firewall, dmz
#
Ping(ACCEPT)    loc             $FW
Ping(ACCEPT)    dmz             $FW
Ping(ACCEPT)    loc             dmz
Ping(ACCEPT)    dmz             loc
Ping(ACCEPT)    dmz             net
ACCEPT          $FW             net             icmp
ACCEPT          $FW             loc             icmp
ACCEPT          $FW             dmz             icmp
  • /etc/shorewall/stoppedrules - Regeln aktiv wenn die Firewall gestoppt wird/ist
ACCEPT          enp0s3            -
ACCEPT          -               enp0s3
ACCEPT          enp0s8            -
ACCEPT          -               enp0s8
ACCEPT          enp0s9            -
ACCEPT          -               enp0s9
  • /etc/shorewall/shorewall.conf - Globale Konfiguration des Shorewall Programms
  • wir ändern hier die ShoreWall Log-Datei in eine eigene, dedizierte Log-Datei unter /var/log/shorewall. Diese Log-Datei sollte per log-rotate überwacht und rotiert werden (dafür ist eine Konfiguration des Programms logrotate notwendig)
[...]
STARTUP_ENABLED=yes

LOGFILE=/var/log/shorewall
[...]
  • Shorewall Start erlauben in der Datei /etc/default/shorewall.
[..]
startup=1
[..]
  • Shorewall Regeln und Konfiguration prüfen
shorewall check
  • Shorewall starten
touch /var/log/shorewall
shorewall start
  • die von Shorewall erzeugten iptables Regeln anzeigen
iptables -L
iptables -L -t nat 
  • Shorewall stoppen (ACHTUNG! Stoprules sind aktiv)
shorewall stop
  • Shorewall Regeln löschen (Firewall wird ausgeschaltet)
shorewall clear
  • Shorewall Regeln/Verbindungen anzeigen
shorewall ls
shorewall ls connections
shorewall ls policies
shorewall ls routing
  • Shorewall über Systemd starten/anschalten/stoppen
systemctl enable shorewall
systemctl start shorewall
systemctl stop shorewall

6.19 nftables Firewall

systemctl stop shorewall
systemctl disable shorewall
shorewall clear
iptables -L
iptables -L -t nat
  • "nftables" auf dem Router installieren (bei Debian 10 ist "nftables" schon installiert und aktiv)
apt install nftables
  • root-Shell öffnen, ntf Version abfragen
nft -v
  • das nftables Ruleset auflisten (sollte am Anfang leer sein)
nft list ruleset
  • ein nft Ruleset für eine Host-Firewall, per Editor in die Datei /etc/nftables.conf schreiben
# Regelsatz löschen
flush ruleset

# Variable "any" definieren
define any = 0::0/0

table inet filter {
        chain input {
                type filter hook input priority 0;

		# set default policy to "drop"
		policy drop;

                # accept any localhost traffic
                iif lo accept

                # accept traffic originated from us
                ct state established,related accept

                # activate the following line to accept common local services
                tcp dport { 22, 80, 443 } ct state new accept

                # NTP multicast
                ip6 daddr ff02::1010 udp dport 123 accept

                # mDNS (avahi)
                ip6 daddr ff02::fb udp dport 5353 accept
                ip  daddr 224.0.0.251 udp dport 5353 accept

                # DHCPv6
                ip6 saddr $any udp dport 546 accept

                # IPP (CUPS)
                tcp dport 631 accept

                # Accept neighbour discovery otherwise IPv6 connectivity breaks.
                ip6 saddr $any icmpv6 type { nd-neighbor-solicit,  
                                             nd-router-advert, 
                                             nd-neighbor-advert }  accept

                # Accept essential icmpv6
                ip6 saddr $any icmpv6 type { echo-reply, 
                                             echo-request, 
                                             packet-too-big, 
                                             destination-unreachable, 
                                             time-exceeded, 
                                             parameter-problem } accept

                # count and drop any other traffic
                counter log prefix "nftables drop: " drop
        }
}
  • nftables Firewall laden
systemctl start nftables
  • Regelwerk anzeigen
nft list ruleset
  • Log-Ausgaben anzeigen, es sollten nun Pakete mit dem Log-Prefix "nftables drop:" im Log erscheinen
journalctl -f | grep nftables
  • eigenen Router vom Laptop aus mit nmap scannen (einmal mit nftables Firewall eingeschaltet, danach mit der nftables Firewall ausgeschaltet. Gibt es einen Unterschied?)
nmap -sT 192.168.1.xxx # <--- IP Adresse des Routers
  • Beipsiel der nmap Ausgabe
Starting Nmap 7.70 ( https://nmap.org ) at 2019-12-10 11:31 CET
Nmap scan report for 192.168.1.166
Host is up (0.00048s latency).
Not shown: 996 filtered ports
PORT    STATE  SERVICE
22/tcp  open   ssh
80/tcp  closed http
443/tcp closed https
631/tcp closed ipp
MAC Address: 08:00:00:00:00:0A (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 5.08 seconds

7 Debian VPS im Internet (für Wireguard und HTTPS-Webserver Kapitel)

  • Namen vm0X.defaultroutes.de
  • Benutzer nutzer, Passwort villa, Root-Shell per sudo -s

8 WireGuard

  • Wir haben virtuelle Maschinen im Internet (vm01-vm10.defaultroutes.de)
  • Plan: VPN vom Laptop zur VM im Internet, alle Pakete vom Laptop sollen über das VPN und die VM im Internet gesendet werden

8.1 Wireguard Debian Installation (VPN-Client/VPN-Server)

  • Installationsinformationen für Wireguard https://www.wireguard.com/install/
  • Derzeit ist Wireguard noch nicht in den Linux-Kernel eingezogen, soll aber in Version ~5.6 in den Kernel kommen
  • der Laptop ist unser Wireguard-Client
  • auf dem Laptop und auf dem VPS Server im Internet das Wireguard Repository hinzufügen, Paketlisten updaten und Wireguard-Pakete installieren
echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list
printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable
apt update
apt upgrade
reboot
apt install wireguard linux-headers-$(uname -r)

8.2 Konfiguration Wireguard auf dem VPN-Server (Gateway)

  • User-Mask für neue Dateien und Verzeichnisse setzen, ein Verzeichnis für die Wireguard-Dateien erstellen
umask 077
mkdir -p /etc/wireguard
cd /etc/wireguard
  • einen privaten Schlüssel für den Wireguard-Dienst erstellen
wg genkey > private.key
  • Wireguard-Interface erstellen
ip link add dev wg0 type wireguard
  • IP-Adresse auf dem neuen Wireguard-Interface wg0 setzen
ip addr add 10.0.0.2/24 dev wg0
  • Privaten Schlüssel in das wg0 Interface laden
wg set wg0 private-key ./private.key
  • Interface wg0 aktivieren
ip link set wg0 up
  • Konfiguration der Schnittstelle anzeigen
wg show wg0

8.3 Konfiguration Wireguard auf dem VPN-Client

  • der Laptop ist unser VPN-Client
  • Wireguard installieren. Wurde ein neuer Linux-Kernel installiert, dann nach der Installation von Wireguard den Rechner neu starten, denn die Wireguard-Kernel-Module wurden schon für die neue Kernel-Version gebaut
echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list
printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable
apt update
apt install wireguard
  • Verzeichnis für die Wireguard-Dateien erstellen
umask 077
mkdir /etc/wireguard
cd /etc/wireguard
  • einen privaten Schlüssel für den Wireguard-Dienst erstellen
wg genkey > private.key
  • Wireguard-Interface erstellen
ip link add dev wg0 type wireguard
  • IP-Adresse auf dem neuen Wireguard-Interface wg0 setzen
ip addr add 10.0.0.1/24 dev wg0
  • Privaten Schlüssel in das wg0 Interface laden
wg set wg0 private-key ./private.key
  • Interface wg0 aktivieren
ip link set wg0 up
  • öffentlicher Schlüssel, erlaubte IP-Adressen und IP/Port des VPN-Servers eintragen
wg set wg0 peer <schlüssel> allowed-ips 0.0.0.0/0 endpoint <vpn-server>:<port>
  • Konfiguration der Schnittstelle anzeigen
wg show wg0
  • Konfiguration in die Konfigurationsdatei speichern
wg showconf wg0 > /etc/wireguard/wg0.conf
chmod 0600 /etc/wireguard/wg0.conf
  • Konfigurationsdatei anpassen, Address einfügen und Abschnitt Peer
[Interface]
ListenPort = <port>
PrivateKey = <private-key>
Address = 10.0.0.1/24

[Peer]
PublicKey = <public-key-of-vpn-server>
AllowedIPs = 0.0.0.0/0
Endpoint = <ip-of-vpn-server>:<port>

8.4 Client auf dem Server erlauben

  • auf dem VPN-Server, die Wireguard-Configuration speichern
wg showconf wg0 > /etc/wireguard/wg0.conf
chmod 0600 /etc/wireguard/wg0.conf
  • Konfigurationsdatei anpassen (Address und Abschnitt Peer)
[Interface]
ListenPort = <port>
PrivateKey = <private-key>
Address = 10.0.0.2/24

[Peer]
PublicKey = <public-key-of-client>
AllowedIPs = 10.0.0.1/32

8.5 IP-NATPT auf dem Server und IPv4-Forwarding anschalten

iptables -A POSTROUTING -t nat -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf

8.6 Wireguard manuell aktivieren

  • auf dem VPN-Gateway
root@vm0X:/etc/wireguard# wg-quick down wg0
[#] ip link delete dev wg0
root@vm0X:/etc/wireguard# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip link set mtu 1420 up dev wg0
[#] ip route add 10.0.0.1/32 dev wg0
  • auf dem VPN-Client
root@router05:/etc/wireguard# wg-quick down wg0
[#] ip link delete dev wg0
root@router05:/etc/wireguard# wg-quick up wg0                                                                   
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip link set mtu 1420 up dev wg0
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0

8.7 VPN Test

  • Ping vom VPN-Client Wireguard-IP zum VPN-Server
ping 10.0.0.2

8.8 DNS Resolver auf einen Resolver im Internet setzen

  • der DNS-Resolver des Linuxhotels ist über den Tunnel nicht erreichbar, daher müssen wir einen DNS-Resolver im Internet benuzten (oder, besser, einen eigenen DNS-Resolver auf dem VPN-Gateway-Server).
echo "nameserver 1.1.1.1" > /etc/resolv.conf

8.9 Tests der Wireguard-Verbindung

  • Sichtbare IP-Adresse des Client mit und ohne Wireguard prüfen, z.B. per Firefox auf der Seite https://ripe.net
  • Route zu einem Host im Internet per mtr testen, mit und ohne Wireguard
  • Wireguard aktivieren, mtr auf einen Server im Internet laufen lassen. Dann von Ethernet (Kabel) auf WLAN umschalten, der mtr Trace darf nicht abbrechen, der Wireguard Tunnel überlebt das umschalten
apt install mtr
mtr -t google.com

8.10 Wireguard per systemd

  • die folgenden Schritte sowohl auf dem VPN-Gateway, als auch auf dem Client ausführen
  • manuell gestartetes Wireguard beenden
wg-quick down wg0
  • Wireguard per Systemd aktivieren
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
systemctl status wg-quick@wg0
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
   Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; vendor preset: enabled)
   Active: active (exited) since Mon 2019-05-06 16:18:02 EDT; 1s ago
     Docs: man:wg-quick(8)
	   man:wg(8)
	   https://www.wireguard.com/
	   https://www.wireguard.com/quickstart/
	   https://git.zx2c4.com/WireGuard/about/src/tools/man/wg-quick.8
	   https://git.zx2c4.com/WireGuard/about/src/tools/man/wg.8
  Process: 13492 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)
 Main PID: 13492 (code=exited, status=0/SUCCESS)

May 06 16:18:02 router05 systemd[1]: Starting WireGuard via wg-quick(8) for wg0...
May 06 16:18:02 router05 wg-quick[13492]: [#] ip link add wg0 type wireguard
May 06 16:18:02 router05 wg-quick[13492]: [#] wg setconf wg0 /dev/fd/63
May 06 16:18:02 router05 wg-quick[13492]: [#] ip address add 10.0.0.1/24 dev wg0
May 06 16:18:02 router05 wg-quick[13492]: [#] ip link set mtu 1420 up dev wg0
May 06 16:18:02 router05 wg-quick[13492]: [#] wg set wg0 fwmark 51820
May 06 16:18:02 router05 wg-quick[13492]: [#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
May 06 16:18:02 router05 wg-quick[13492]: [#] ip -4 rule add not fwmark 51820 table 51820
May 06 16:18:02 router05 wg-quick[13492]: [#] ip -4 rule add table main suppress_prefixlength 0
May 06 16:18:02 router05 systemd[1]: Started WireGuard via wg-quick(8) for wg0.

8.11 Optional: Alternatives Routing auf dem Client ohne wg-quick

  • Alle Pakete (mit Aussnahme der Wireguard Pakete) sollen durch den VPN-Tunnel gesendet werden. Eine Split-Default-Route sorgt dafür, das wir die original Default-Route nicht verlieren
ip route add <ip-des-VPN-servers>/32 via 192.168.1.5 dev eth0
ip route add  0.0.0.0/1 via 10.0.0.2 dev wg0
ip route add  128.0.0.0/1 via 10.0.0.2 dev wg0
  • Test
# tracepath google.com
 1?: [LOCALHOST]                                         pmtu 1420
 1:  10.0.0.2                                             15.453ms 
 1:  10.0.0.2                                             15.446ms 
 2:  no reply
 3:  45.63.118.33                                         18.164ms 
 4:  no reply
 5:  ffm-b12-link.telia.net                               20.718ms 
 6:  ffm-bb4-link.telia.net                               15.889ms 
 7:  ffm-b1-link.telia.net                                16.062ms 
 8:  google-ic-319727-ffm-b1.c.telia.net                  15.997ms asymm 10
[...]

8.12 Optional: Wireguard mit alternativen Routing auf dem Client ausschalten

  • Routen löschen
ip r del 0.0.0.0/1 via 10.0.0.2 dev wg0
ip r del 128.0.0.0/1 via 10.0.0.2 dev wg0
ip r del <ip-des-vpn-servers> via 192.168.1.5 dev eth0
  • Wireguard Interface ausschalten
ip link set dev wg0 down

8.13 Links

9 OpenVPN

  • wir arbeiten wieder auf den Client/Server VMs
  • sicherstellen das die Firewall-Filter-Regeln auf dem Router nicht aktiv ist, das Masquerading nach außen in die Linuxhotel Netz aber aktiv ist (wird für die Installation von OpenVPN über den Paketmanager benötigt)
  • OpenVPN kann verschiedene Arten der Authifizierung verwenden, in unserem Beispiel benutzen wir einfache kryptografische Schlüssel (PSK oder Pre-Shared-Keys)
  • in unserem Beispiel werden die IP-Adressen der OpenVPN Teilnehmer manuell verteilt. Es ist möglich die IP-Adressen der VPN-Clients über das OpenVPN-Gateway zu verteilen.
  • OpenVPN auf dem Client und auf dem Server installieren
apt install openvpn
  • Schlüssel erzeugen und per gesicherten Kanal auf beide Endpunkte des VPN-Tunnels bringen (z.B. per Secure Copy "scp")
client0x# cd /etc/openvpn
client0x# openvpn --genkey --secret static.key
client0x# scp static.key nutzer@100.64.x.2:/tmp
  • Server-Konfiguration /etc/openvpn/server.conf (auf dem Server-Rechner)
dev tun
ifconfig 10.0.x.1 10.0.x.2
secret /etc/openvpn/static.key
  • auf dem Client den geheimen Schlüssel aus dem Verzeichnis /tmp in das OpenVPN Verzeichnis verschieben
mv /tmp/secret.key /etc/openvpn/
  • Client-Konfiguration /etc/openvpn/client.conf (auf dem Client-Rechner)
remote 100.64.x.2
dev tun
ifconfig 10.0.x.2 10.0.x.1
secret /etc/openvpn/static.key
  • Treiber für Tunnel-Interface laden und OpenVPN start (Server)
modprobe tun
openvpn /etc/openvpn/server.conf &
  • Auf dem Server einen Webserver (Port 8000) starten
python -m SimpleHTTPServer 8000
  • OpenVPN start (Client)
modprobe tun
openvpn /etc/openvpn/client.conf &
  • Tunnel-Interfaces anzeigen
ip a
  • OpenVPN testen (mit tcpdump auf dem Router die Pakete anschauen tcpdump -i enp0s8 port 80 und tcpdump -i enp0s8 icmp )
client0x# ping 10.0.x.1
client0x# links http://10.0.x.1:8000

10 Extra Inhalt: Logdateien auswerten

  • Artificial Ignorance: bei diesem von Marcus Ranum beschriebenen Konzept werden Filter aufgebaut durch welche die Log-Ausgaben gefiltert werden. Log-Ausgaben werden in zwei Kategorien eingeteilt:
    • Meldung beschreibt eine kritische Fehlfunktion im System. Die Ursache der Fehlfunktion muss beseitigt werden, damit die Log-Ausgaben nicht mehr angezeigt werden
    • Meldung beschreibt eine unkritische Situation im System. Die Filter werden erweitert, um die Log-Meldung in Zukunft zu unterdrücken

    Ziel von AI-Logauswertung ist es, das die Log-Dateien nach dem Filtern leer sind. Alle neuen Log-Meldungen, welche in den Log-Dateien auftauchen, müssen entweder bereinigt werden oder durch einen Filter unterdrückt werden: http://www.ranum.com/security/computer_security/papers/ai/

10.1 NSB - Never Before Seen

  • Berkeley-DB Development-Dateien laden
yum install libdb-devel
  • NBS Quellcode laden und auspacken
cd ~/src
wget http://www.ranum.com/security/computer_security/code/nbs.tar
tar xvf nbs.tar
cd nbs
  • NBS Quellcode patchen
sed -i 's/.*extern\tint\terrno;.*/#include <errno.h>/' nbspreen.c
  • NBS Quellcode bauen und Programm-Dateien installieren
make
cp nbs nbsmk nbspreen nbsdump /usr/local/bin
  • Verzeichnis für NBS Dateien anlegen
mkdir /var/db/nbs
  • Datenbank für NBS anlegen
cd /var/db/nbs
nbsmk -d messages.nbs
  • Datenbank mit Log-Daten anlernen
nbs -d messages.nbs -i /var/log/messages -s
[...]
NBS completed run (0 sec)
9567 never before seen entries
13630 lines of input processed (70.19% NBS)
9567 total entries in database
  • Neuen Log-Eintrag simulieren
logger -t nbstest "Hallo, dies ist ein Test"
  • NBS Lauf
nbs -d messages.nbs -i /var/log/messages -s
  • Ausgabe
nbs -d messages.nbs -i /var/log/messages -s
Aug 30 08:17:48 notebook32 nbstest: Hallo, dies ist ein Test
NBS completed run (0 sec)
1 never before seen entries
13631 lines of input processed (0.01% NBS)
9568 total entries in database
  • die NBS Ausgabe kann auch in eine Datei geschrieben oder angehangen werden
nbs -d /var/db/nbs/messages.nbs -i /var/log/messages -a /var/log/nbs.log

10.2 Log-Templater

mkdir ~/src
cd ~/src
yum -y install git automake autoconf gcc make
git clone https://github.com/rondilley/tmpltr.git
cd tmpltr
./bootstrap
autoreconf -i
./configure
make
make install
export PATH=$PATH:/usr/local/bin
  • Systemd-Journal für den Dienst sshd mit tmpltr auswerten
journalctl -u sshd | tmpltr - | sort -n |  sed -e 's/%s.*||//'
  • Templates abspeichern, dann ignore Datei bearbeiten
journalctl -u sshd | tmpltr -w /var/log/sshd.ignore -
  • Log mit ignore Datei auswerten
journalctl -u sshd | tmpltr -t /var/log/sshd.ignore - | sort -n |  sed -e 's/%s.*||//'
  • SSH-Fehler produzieren (z.B. Anmeldeversuch mit falschem Passwort) und Log-Datei neu auswerten
ssh bar@localhost
bar@localhost's password:
Permission denied, please try again.
bar@localhost's password:
  • Log-Auswerten
[bar@notebook32 tmpltr]# journalctl -u sshd | tmpltr -t /var/log/sshd.ignore - | sort -n |  sed -e 's/%s.*||//'
Opening [-] for read
           1 Aug 31 12:29:25 notebook32 sshd[24691]: Connection closed by ::1 port 40372 [preauth]
           1 Aug 31 12:29:25 notebook32 sshd[24691]: Failed password for bar from ::1 port 40372 ssh2
           1 Aug 31 12:29:23 notebook32 sshd[24691]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "bar"
           1 Aug 31 12:29:23 notebook32 sshd[24691]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=localhost  user=bar
  • Neue Log-Einträge in die Ignore-Datei aufnehmen
journalctl -u sshd | tmpltr -t /var/log/sshd.ignore -w /var/log/sshd.ignore.new - && \
  cat /var/log/sshd.ignore.new >> /var/log/sshd.ignore

11 Schlüssellängen und Algorithmen

  • Die Nachfolgende Tabelle gibt eine Übersicht über die heute benutzten Verschlüsselungs-Algorithmen und Schlüssellängen
Ziel Krypto-Verfahren Schlüssellängen
symmetrische Verschlüsselung AES 128/256
asymmetrische Verschlüsselung RSA 3072-4096
asymmetrische Signaturen RSA/ECC 1536-2048/256-384
kryptografischer Hash SHA2/SHA3 256/384

12 SSL/TLS/HTTPS

12.1 Von SSL zu TLS

12.2 CAA Record

  • der CAA-DNS-Record (RFC 6844) beschreibt, welche Zertifizierungsstelle (CA) für eine Domain x509 Zertifikate ausstellen darf
  • der CAA-Record listet den Namen der CA für "normale" und für Wildcard Zertifikate
; <<>> DiG 9.11.11-RedHat-9.11.11-1.fc31 <<>> defaultroutes.de caa
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64650
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;defaultroutes.de.                  IN      CAA

;; ANSWER SECTION:
defaultroutes.de.           0       IN      CAA     128 issue "letsencrypt.org"
defaultroutes.de.           0       IN      CAA     128 issuewild ";"
defaultroutes.de.           0       IN      CAA     128 iodef "mailto:security@defaultroutes.de"

;; Query time: 35 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Free Dez 06 07:26:59 CET 2019
;; MSG SIZE  rcvd: 146

  • der CAA-Record wird von der CA zum Zeitpunkt des Austellen des Zertifikats geprüft
  • Goolge hat die Prüfung des CAA-Records für CAs ab September 2017 für verbindlich erklärt
  • Mit dem IODEF Parameter können verstösse gegen die Policy an den Besitzer der Domain gemeldet werden, dies ist jedoch bei den meisten CAs nicht implementiert
  • Existiert kein CAA-Record im DNS, so darf jede CA ein x509 Zertifikat für die Domain ausstellen
  • ein CAA-Record verhindert, das Zertifikate von unbefugten Personen oder von Zertifizierungstsellen mit schlechter Identitätsprüfung des Domain-Besitzers ein Zertifikat austellen kann
  • die Domain mit CAA-Records sollte mit DNSSEC abgesichert sein

12.3 Aufgabe: NGINX Webserver mit SSL

  • NGINX installieren (Debian VPS), Passwort villa (Benutzer: nutzer)
ssh nutzer@vm0X.defaultroutes.de
  • NGINX Webserver installieren
apt install nginx
  • OpenSSL Schlüssel erstellen und selbst signieren, als Common-Name den Namen des Servers eintragen vm0x.defaultroutes.de
  • RSA-Privaten Schlüssel erstellen (2048 bit)
openssl genrsa -out vm0X.defaultroutes.de.private 2048
  • öffentlichen RSA-Schluessel erzeugen
openssl rsa -in vm0X.defaultroutes.de.private -pubout -out vm0X.defaultroutes.de.public
openssl rsa -text -pubin -in vm0X.defaultroutes.de.public | less
  • OpenSSL Konfigurationsdatei für Zertifikatserstellung vm0X.defaultroutes.de.conf
[req]
prompt = no
distinguished_name = dn
req_extensions = SAN

[dn]
CN = vm0X.defaultroutes.de
emailAddress = teilnehmer@example.com
O = Linuxhotel
L = Essen
C = DE

[SAN]
subjectAltName = DNS:vm0X.defaultroutes.de,DNS:www.vm0X.defaultroutes.de
  • Self-Signed-Cert ohne den Zwischenschritt CSR (Certificate Signing Request) erzeugen
openssl req -new -x509 -config vm0X.defaultroutes.de.conf -days 365 \
     -key vm0X.defaultroutes.de.private -out vm0X.defaultroutes.de.crt
  • Zertifikat und privaten Schlüssel in das Verzeichnis /etc/tls kopieren (Verzeichnis ggf. erstellen) und die Berechtigungen anpassen
sudo cp vm0X.defaultroutes.de.crt vm0X.defaultroutes.de.private /etc/tls
  • SSL/TLS Konfiguration, Datei /etc/nginx/sites-enabled/default
[...]
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        #
        listen 443 ssl;
        listen [::]:443 ssl;
        ssl_certificate    /etc/tls/vm0X.defaultroutes.de.crt;
        ssl_certificate_key /etc/tls/vm0X.defaultroutes.de.private;
[...]
  • NGINX-Konfiguration testen
sudo nginx -t
  • NGINX Webserver neu starten
nginx -s reload
netstat -tulpen # <-- nginx Prozess sollte auf Port 80 und 443 lauschen
lsof -Poni :443 # <-- Alternative zu "netstat -tulpen"
  • Mit den Firefox des Laptops auf die Webseite https://vm0X.defaultroutes.de gehen. Es sollte eine Zertifikatswarnung angezeigt werden (weil das Zertifikat über keines der Root-CAs im Browser prüfbar ist). Schaut Euch im Browser die Informationen über das Zertifikat an.
  • Benutze openssl s_client auf dem Laptop um das Server-Zertifikat aus dem Webserver zu lesen und lokal zu speichern. Benutze openssl x509 um den Inhalt des Zertifikats anzuzeigen
openssl s_client -connect vm0X.defaultroutes.de:443
  • Beipspiel: X509 Zertifikat von einem TLS Server mit SNI (Server Name Indication) abrufen
openssl s_client -connect www.linuxhotel.de:443 -servername www.linuxhotel.de

12.4 NGINX und TLS 1.3

  • Seit Version 1.13 unterstützt NGINX das neue TLS Protokoll 1.3. Die modernen Web-Browser unterstützen ebenfalls TLS 1.3. TLS 1.3 ist ab Version 1.13 aktiviert.
  • In der Datei /etc/nginx/nginx.conf
    ssl_protocols             TLSv1.3 TLSv1.2;
    
  • Link: Test TLS Versionen https://gf.dev/tls-test
  • Middlebox Test https://tls13.mitm.watch/

12.4.1 Test mit testssl.sh

  • TestSSL ist ein Test-Script, welches mittels OpenSSL die Protokolle und Krypto-Algorithmen eines TLS-Servers testen kann
apt install testssl.sh
  • aktuelle Version des testssl Scripts aus dem Github Repo laden (danke Bernd)
git clone https://github.com/drwetter/testssl.sh.git testssl
cd testssl
./testssl.sh -p  vm0X.defaultroutes.de
  • Protokollunterstützung des Servers testen
testssl -p vm10.defaultroutes.de

12.5 HTTP/2 anschalten

  • in der Datei /etc/nginx/sites-enabled/default
listen 443 ssl http2;
listen [::]:443 ssl http2;
  • Test HTTP/2 mit testssl
apt install curl
curl --insecure --tlsv1.3 --http2 https://vm04.defaultroutes.de
  • Gegenprobe
curl --verbose --insecure --tls-max 1.1 --tlsv1.1  https://vm04.defaultroutes.de

12.6 HTTP zu HTTPS Redirect

  • Um alle Anfragen auf Port 80 (ohne Verschlüsselung) auf eine verschlüsselte Verbindung (Port 443) umzulenken, konfigurieren wir in der NGINX-Konfiguration (Datei /etc/nginx/sites-enabled/default) ein Redirect von HTTP auf HTTPS
server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name vm0X.defaultroutes.de;

        # redirect zum HTTPS Server
        return 301 https://$server_name/$request_uri;
}

server {
        # SSL configuration
        #
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name vm0X.defaultroutes.de;
        ssl_certificate    /etc/tls/vm0X.defaultroutes.de.crt;
        ssl_certificate_key /etc/tls/vm0X.defaultroutes.de.private;
	[...]
}
  • NGINX Konfiguration testen und neu Laden
nginx -t
nginx -s reload

12.7 Let's Encrypt und das ACME Protokoll

12.7.1 Aufgabe: Let's Encrypt Zertifikate mit acme.sh

  • Wir arbeiten auf der Debian VPS im Internet
  • acme.sh per git aus dem Repository laden
mkdir ~/src
cd ~/src
git clone https://github.com/Neilpang/acme.sh
  • acme.sh installieren
cd acme.sh
./acme.sh --install --cert-home /etc/tls --home /etc/acme
  • NGINX Vorbereiten. acme.sh wird die Daten für die Authentisierung in einem Pfad des Webservers ablegen. Hier benutzen wir den Pfad /srv/nginx/site1/le
mkdir -p /srv/nginx/site1/le
  • die NGINX Konfiguration mit einer location für die ACME-Challenge einrichten (Datei /etc/nginx/sites-enabled/default):
location ^~ /.well-known/acme-challenge {
     default_type text/plain;
     root /srv/nginx/site1/le;
}
  • Konfiguration speichern, testen und Konfiguration in den NGINX neu laden
  • Test: ein Zertifikat für den Namen vm0X.defaultroutes.de Webservice anfordern sein)
cd ~
source ~/.bashrc
acme.sh  --issue  -d vm0X.defaultroutes.de  -w /srv/nginx/site1/le --cert-home /etc/tls
[Thu Dec  5 17:37:25 UTC 2019] Single domain='vm0X.defaultroutes.de'
[Thu Dec  5 17:37:25 UTC 2019] Getting domain auth token for each domain
[Thu Dec  5 17:37:27 UTC 2019] Getting webroot for domain='vm0X.defaultroutes.de'
[Thu Dec  5 17:37:27 UTC 2019] Verifying: vm0X.defaultroutes.de
[Thu Dec  5 17:37:30 UTC 2019] Success
[Thu Dec  5 17:37:30 UTC 2019] Verify finished, start to sign.
[Thu Dec  5 17:37:30 UTC 2019] Lets finalize the order, Le_OrderFinalize: https://acme-v02.api.letsencrypt.org/acme/finalize/73196223/1679858441
[Thu Dec  5 17:37:31 UTC 2019] Download cert, Le_LinkCert: https://acme-v02.api.letsencrypt.org/acme/cert/03351def6b13c45899ea520f8bddf25f5676
[Thu Dec  5 17:37:32 UTC 2019] Cert success.
-----BEGIN CERTIFICATE-----
MIIFaDCCBFCgAwIBAgISAzUd72sTxFiZ6lIPi93yX1Z2MA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
[...]
xtdPmO2bLQhSgJ/yhpXOdGDEs2d6OeKXO+mIxd507IcSO0sFgMsN7Kxs+8vGtXa0
p+Jc4ii+eSx8kGyiyylIcI6/I+JZb7RheXml234DFIMI9kn93DuDYFp7+/g=
-----END CERTIFICATE-----
[Thu Dec  5 17:37:32 UTC 2019] Your cert is in  /etc/tls/vm0X.defaultroutes.de/vm0X.defaultroutes.de.cer
[Thu Dec  5 17:37:32 UTC 2019] Your cert key is in  /etc/tls/vm0X.defaultroutes.de/vm0X.defaultroutes.de.key
[Thu Dec  5 17:37:32 UTC 2019] The intermediate CA cert is in  /etc/tls/vm0X.defaultroutes.de/ca.cer
[Thu Dec  5 17:37:32 UTC 2019] And the full chain certs is there:  /etc/tls/vm0X.defaultroutes.de/fullchain.cer
  • die Pfade zu den ACME-Zertifikaten in der NGINX-Configuration /etc/nginx/sites-enabled/default anpassen
# SSL configuration
#
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate    /etc/tls/vm0X.defaultroutes.de/fullchain.cer;
ssl_certificate_key /etc/tls/vm0X.defaultroutes.de/vm0X.defaultroutes.de.key;
  • Konfiguration testen
nginx -t
  • NGINX neu starten
systemctl restart nginx

12.7.2 Zertifikate (automatisch) erneuern

  • der Befehl acme.sh --renew-all kann in einen Cron-Job (oder, moderner, in einen Systemd-Timer) eingebaut werden und periodisch aufgerufen werden. Nach ca. 60 Tagen werden die Zertifikate vor Ablauf erneuert.
# acme.sh --renew-all
[Thu Dec  5 17:42:41 UTC 2019] Renew: 'nginxXX.defaultroutes.de'
[Thu Dec  5 17:42:41 UTC 2019] Skip, Next renewal time is: Mon Feb  3 17:37:32 UTC 2020
[Thu Dec  5 17:42:41 UTC 2019] Add '--force' to force to renew.
[Thu Dec  5 17:42:41 UTC 2019] Skipped nginxXX.defaultroutes.de

12.8 Qualität der SSL/TLS Konfiguration eines Webservers testen

12.9 TLS Crypto hardening

  • TLS Protokoll Unterstützung testen
openssl s_client -connect www.example.com:443 -tls1_2
  • TLS Cipher Untertützung testen
openssl ciphers
openssl s_client -connect www.example.com:443 -cipher RC4-SHA
  • TLS Protokoll Auswahl bei Nginx
ssl_protocols TLSv1.2 TLSv1.3;
  • Cipher Auswahl vom Webserver vorgeben
ssl_prefer_server_ciphers on;
  • die erlaubten krypto Algorithmen
ssl_ciphers 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA:AES128-SHA';

12.10 TLS mit dem Caddy Webserver

  • Webseite des Caddy Webserver https://caddyserver.com
  • wir arbeiten auf dem Debian VPS im Internet
  • NGINX (und andere Server auf Port 80/443) stoppen
systemctl stop nginx
  • Vorbereitetes Caddy-Paket vom Schulungsserver laden
sudo -s
cd /srv
wget https://notes.defaultroutes.de/caddy.tgz
  • Caddy auspacken (Caddy ist in Go geschrieben, ist ein statisches Programm und muss nicht "installiert" werden)
tar xvfz caddy.tgz
rm caddy.tgz
mv caddy /usr/local/bin
  • Caddy Konfigurationsdatei vi Caddyfile
vm0x.defaultroutes.de {
        gzip
        tls nutzerXX@linuxhotel.de
        root /srv/website
}
  • Webseite erstellen
mkdir /srv/website
echo "Meine erste Caddy-Webseite" > /srv/website/index.html
  • Caddy Konfiguration prüfen und bei erfolgreicher Prüfung den Caddy mit HTTP/3 (QUIC) Protokoll starten (danke an Bernd)
caddy -validate  -conf /etc/caddy/Caddyfile && caddy -quic -conf /etc/caddy/Caddyfile
  • Caddy starten
caddy -conf /srv/Caddyfile
  • Webseite im Firefox testen https://vm0x.defaultroutes.de/ Zertifikat anschauen

12.10.1 Optionale Aufgabe:

  • eine Systemd-Unit für den Caddy-Server schreiben

12.10.2 Caddy Server aus den Quellen aktualisieren

  • ein Beispiel Script (ohne Fehlerbehandlung) zum Update des Caddy-Servers aus den Quellen (sollte auf einem Test-System ausgeführt werden und das Caddy Programm nach erfolgreichem Test auf die Produktions-Maschinen übertragen werden)

export GOPATH=/srv/go
rm -rf /srv/go/src
export PATH=$PATH:/usr/local/go/bin
go get github.com/mholt/caddy/caddy
systemctl stop caddy
cp caddy /usr/local/sbin
systemctl start caddy

12.11 Security Header

12.11.1 Feature Policy

  • der Feature-Policy Header beschreibt, welche APIs und Funktionen moderner Browser die Webseite benutzen darf. Schafft es ein Angreifer, eigenen HTML/JacaScript/CSS Code in die Webseite einzuschleusen, so können diese APIs nicht mehr ausgenutzt werden
    Feature Beschreibung
    geolocation Auslesen der GPS Koordinaten
    midi MIDI-Schnittstelle
    notifications Webseite darf Notifications senden
    push Webserver darf Inhalte ohne Anfrage "pushen"
    sync-xhr synchroner XMLHttpRequest
    microphone Mikrofon
    camera Kamera
    magnetometer Magnetometer
    gyroscope Lagesensor
    speaker Lautsprecher
    vibrate Vibration
    fullscreen Vollbild
    payment (PaymentRequest) Bezahlschnittstelle
add_header Feature-Policy "fullscreen 'none'; geolocation 'none'";

12.11.2 Referrer Policy

  • der Header referrer-policy bestimmt, ob ein Web-Browser bei einem Link von dieser Seite (und diesem Webserver) dem Ziel-Webserver sagen darf, von welcher Seite der Link gekommen ist
add_header referrer-policy "no-referrer";

12.11.3 Content Security Policy Header

  • der CSP Header bestimmt, aus welchen (externen) Quellen die Webseite weitere Ressourcen nachladen darf (JavaScript, CSS, Bilder etc)
  • CSP kann bestimmte Arten von XSS (Cross-Site-Scripting) Angriffen abwehren
add_header content-security-policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'";

12.11.4 X-Content-Type-Options

  • der Header X-Content-Type-Options verhindert das Browser am vom Webserver gesendeten MIME-Type vorbei selbst versuchen das Dateiformat einer Datei zu "erschnüffeln".
add_header X-Content-Type-Options "nosniff" always;

12.11.5 X-Frame-Options (RFC 7034)

  • der Header X-Frame-Options bestimmt, ob eine Webseite in ein Frame einer anderen Webseite eingebettet werden darf
  • RFC 7034 "HTTP Header Field X-Frame-Options" https://tools.ietf.org/html/rfc7034
add_header X-Frame-Options "SAMEORIGIN" always;

12.11.6 HSTS - HTTP Strict Transport Security (RFC 6797)

  • Signalisiert zum Browser das dieser Server für eine Zeitspanne TLS unterstützen wird
  • Browser 'lernen' und speichern die HSTS-Informationen
  • erster Besuch auf einer TLS-gesicherten Seite ist noch nicht durch HSTS geschützt
  • HSTS Zertifikatsfehler sind fatal (der Benutzer hat keine Möglichkeit des 'click-through' um den Zertifikatsfehler zu umgehen und die Seite trotzdem zu laden)
  • Beispiel-Konfiguration für NGINX
add_header Strict-Transport-Security max-age=15768000; # HSTS fuer 6 Monate

12.11.7 Vorlage Sicherheitsheader für den NGINX Webserver:

add_header Feature-Policy "fullscreen 'none'; geolocation 'none'";
add_header referrer-policy "no-referrer";
add_header content-security-policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'";
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;

12.11.8 Vorlage Sicherheitsheader für den Caddy Webserver

vm03.defaultroutes.de {
        gzip
        tls nutzer03@linuxhotel.de
        root /srv/website
	header / {
	   Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
           X-Xss-Protection "1; mode=block"
           X-Content-Type-Options "nosniff"
           X-Frame-Options "DENY"
           Content-Security-Policy "default-src none"
           Referrer-Policy "strict-origin-when-cross-origin"
           Cache-Control "public, max-age=15, must-revalidate"
           Feature-Policy "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'self'; camera 'none'; encrypted-media 'none'; fullscreen 'self'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; picture-in-picture *; speaker 'none'; sync-xhr 'none'; usb 'none'; vr 'none'"
           -Server # das Senden der Server-Identifikation unterdrücken
        }
}

13 Ethernet EAP Authentisierung unter Linux

14 Content-Filter Proxy privoxy

  • Auf dem Laptop arbeiten
  • Privoxy Homepage http://privoxy.org
  • Privoxy horcht auf Port 8118
  • "action" –> was soll mit einer URL passieren (blocken, filtern etc)?
  • "filter" –> wie soll Inhalte umgeschrieben werden?
apt install privoxy
  • Konfiguration
$EDITOR /etc/privoxy/config
$EDITOR /etc/privoxy/default.action
$EDITOR /etc/privoxy/user.action
$EDITOR /etc/privoxy/default.filter
$EDITOR /etc/privoxy/user.filter

14.0.1 Aufgabe 1

  • Erstelle eine Action in der Datei /etc/privoxy/user.action, welche alle Bilder einer Webseite ohne HTTPs "undeadly.org" blockt

14.0.2 Lösung 1

{+block{Spiegel Bilder}}                                                                                $
.undeadly.org/images

14.0.3 Aufgabe

  • Erstelle ein Skript, welches eine "action" Datei aus einer der Hosts-Dateien von der unten angebenen Webseite erstellt
  • Webseite mit Ad-Block Hosts-Dateien https://github.com/StevenBlack/hosts

14.0.4 Lösung 2

echo "{+block{Host Liste}}" > /etc/privoxy/adblock.action
# mit awk (schneller und schoener)
cat hosts | awk '{print "."$2}' >> /etc/privoxy/adblock.action
# mit sed
cat hosts | cut -f2 | sed 's/^\(.*\)$/\.\1/g' >> /etc/privoxy/adblock.action
  • die Datei /etc/privoxy/mooab.action in die Datei /etc/privoxy/config eintragen und per Web-Browser testen

15 IPSec mit StrongSWAN

15.1 Installation

  • für die Übung die IPTables Firewall auf dem router ausschalten, Masquerading NAT für die Paketinstallation aber angeschaltet lassen
  • in einem separaten Terminal-Fenster auf dem Router ein tcpdump für icmp laufen lassen, um die Kommunikation zwischen Client und Server zu beobachten
router# tcpdump -i enp0s8 icmp
  • auf dem Client und auf dem Server das Paket strongswan installieren
apt install strongswan

15.2 Konfiguration auf dem Client

  • Host-to-Host Tunnel Mode (Client) /etc/ipsec.conf
config setup

conn %default
     ikelifetime=60m
     keylife=20m
     rekeymargin=3m
     keyingtries=1
     keyexchange=ikev2
     authby=secret

conn host-host
     left=172.16.x.2
     right=100.64.x.2
     auto=add
  • Passwort (PSK) Client /etc/ipsec.secrets
: PSK 'sharedsecret'

15.3 Konfiguration auf dem Server

  • Host-to-Host Tunnel Mode (Server) /etc/ipsec.conf
config setup

conn %default
     ikelifetime=60m
     keylife=20m
     rekeymargin=3m
     keyingtries=1
     keyexchange=ikev2
     authby=secret

conn host-host
     left=100.64.x.2  # Konfig auf dem Server
     right=172.16.x.2 # Konfig auf dem Server
     auto=add
  • Passwort (PSK) Server /etc/ipsec.secrets
: PSK 'sharedsecret'

15.4 IPSec starten

  • IPSec Daemon starten (auf beiden Rechnern Server/Client)
ipsec restart
  • Status der Verbindungen abfragen (derzeit ist noch keine Verbindung aktiv)
ipsec status
ipsec statusall
  • IPSec Verbindung starten
ipsec up host-host
ipsec status
ipsec statusall
  • ein ping zwischen Client und Server VM sollte weiterhin möglich sein, jetzt aber auf dem Router mit tcpdump nicht mehr sichtbar sein
  • IPSec Status aus dem Linux-Kernel anzeigen
ip xfrm state

15.5 ESP Pakete anschauen

  • auf dem Router sollten wir nun ESP (IPSec Encasulated Security Payload) sehen
# tcpdump -i enp0s8  not port ssh

15.6 IPSec mit Wireshark prüfen

  • vom Laptop per SSH X11 Tunnel auf den Router verbinden
ssh -Y nutzer@192.168.1.xxx <-- IP des Routers
  • Wireshark installieren und den Benutzer nutzer der Gruppe wireshark hinzufügen, so das der Benutzer das Recht hat, per Sniffing Netzwerkpakete abzuhören
su -
apt install wireshark
usermod -a -G wireshark nutzer
exit
  • SSH Verbindung beenden, neu einloggen (damit die neue Gruppenzugehörigkeit aktiv wird) und Wireshark starten
router0x$ wireshark
  • Im Wireshark auf Interface enp0s8/enp0s9 sniffen
  • auf dem Server einen Webserver starten
server0$ python -m SimpleHTTPServer
  • auf dem Client die Webseite aufrufen
client0x$ links http://100.64.x.2:8000
  • Im Wireshark sollten wir zwischen der Client-IP und Server-IP nur ESP-, aber keine HTTP-Pakete
  • IPSec stoppen (ipsec down host-host), dann das Experiment ohne IPSec wiederholen. Es sollten nun die HTTP-Pakete im Wireshark sichtbar sein

15.7 IPSec Daten im Wireshark entschlüsseln

  • um per IPSec geschützte Daten im Wireshark entschlüsseln zu können, werden für jede Richtung (Security Association) benötigt: Quell-Adresse, Ziel-Adresse, SPI, Verschlüsselungs-Algorithmus, Verschlüsselungs-Schlüssel, Authentisierungs-Algorithmus und Schlüssel für die Authentisierung. Diese Daten werden auf einem Linux-Rechner mit aktiver IPSec Verbindung mit dem Befehl ip xfrm state angezeigt:
root@client05:~# ip xfr state
src 172.16.5.2 dst 100.64.5.2
        proto esp spi 0xc3d57e0e reqid 3 mode tunnel
        replay-window 0 flag af-unspec
        auth-trunc hmac(sha256) 0xebd9e051b05a07c89e51d4840ab2df87d8ca107385cee1bc291d0dd442293dd3 128
        enc cbc(aes) 0xd5719f2b10cd766bb7562099c0ee4bb5
        anti-replay context: seq 0x0, oseq 0x5, bitmap 0x00000000
src 100.64.5.2 dst 172.16.5.2
        proto esp spi 0xcf12dd2b reqid 3 mode tunnel
        replay-window 32 flag af-unspec
        auth-trunc hmac(sha256) 0xc82360181bc299d6931cc8061508740d5d25216f6b31ca93c436b65d27072c2e 128
        enc cbc(aes) 0x4e8a18060003b6727d8f8509e98310c5
        anti-replay context: seq 0x5, oseq 0x0, bitmap 0x0000001f
  • Diese Daten im Wireshark unter Edit -> Preferences -> Protocols -> ESP -> ESP SAs -> Edit eintragen. Alle Felder müssen gefüllt werden. Die Schlüssel werden in der Hexadezimalen Schreibweise mit vorangestelltem 0x (wie vom ip xfrm state Befehl ausgegeben) eingetragen.
  • Der Packet Trace im Wireshark wird nun dekodiert, die verschlüsselten Protokolle (z.B. HTTP) können analysiert werden.

16 STunnel

  • mit der Software STunnel können beliebige TCP-Verbindungen mit TLS Verschlüsselung "nachgerüstet" werden, auch wenn die Software selbst kein TLS spricht
  • STunnel Homepage: http://stunnel.org

16.1 Tunnel, wenn sowohl Client als auch Server kein TLS sprechen

  • Installation (auf Client und Server)
apt install stunnel
  • Client stunnel Konfiguration in /etc/stunnel/stunnel.conf
client  = yes
debug   = info
output  = /var/log/stunnel.log

; These options provide additional security at some performance degradation
options = SINGLE_ECDH_USE
options = SINGLE_DH_USE

[http-to-https]
accept  = 80
connect = 100.64.x.2:8000
cert    = /etc/stunnel/stunnel.pem
  • Server stunnel Konfiguration in /etc/stunnel/stunnel.conf
debug = info
output = /var/log/stunnel.log

; These options provide additional security at some performance degradation
options = SINGLE_ECDH_USE
options = SINGLE_DH_USE
[https-8000]
accept  = 8000
connect = localhost:8001
cert = /etc/stunnel/stunnel.pem
  • systemd unit in /etc/systemd/system/stunnel.service on the server
### stunnel.service

[Unit]
Description=Stunnel service
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/stunnel /etc/stunnel/stunnel.conf
Restart=always

[Install]
WantedBy=Default.target
  • x509 Zertifikat erstellen
$ openssl req -new -nodes -x509 -out /etc/stunnel/stunnel.pem \
  -keyout /etc/stunnel/stunnel.pem
$ chmod 400 /etc/stunnel/stunnel.pem
  • Systemd Unit auf dem Server starten
$ systemctl daemon-reload
$ systemctl enable --now stunnel
  • Webserver auf dem Server auf Port 8001 starten
server0x$ python -m SimpleHTTPServer 8001
  • Start des stunnel auf dem Client
$ stunnel
$ tail /var/log/stunnel.log
$ lsof -i | grep stunnel
  • Test der Verbindung, links verbindet sich per HTTP unverschlüsselt, stunnel bietet die TLS Verschlüsselung (per tcpdump auf dem Router schauen das die Pakete SSL/TLS verschlüsselt sind)
$ links http://localhost
  • per tcpdump auf dem Router testen, das kein HTTP oder HTTPS Verkehr zu sehen ist
tcpdump -nn -i enp0s8 port 80 or 443 or 8000

16.2 Tunnel, wenn der Client TLS spricht, der Server aber nicht

  • Server stunnel Konfiguration in /etc/stunnel/stunnel.conf anpassen (Abschnitt [https])
debug = info
output = /var/log/stunnel.log

; These options provide additional security at some performance degradation
options = SINGLE_ECDH_USE
options = SINGLE_DH_USE
[https-8000]
accept  = 8000
connect = localhost:8001
cert = /etc/stunnel/stunnel.pem
[https]
accept  = 443
connect = localhost:8001
cert = /etc/stunnel/stunnel.pem
  • stunnel auf dem Server neu starten
systemctl restart stunnel
  • mit dem links Webbrowser testen (Protokoll HTTPS/TLS). Hier gibt es eine Zertifikats-Warnung, da der stunnel auf dem Server ein Self-Signed Zertifikat verwendet
links https://100.64.x.2

16.3 Einsatzbeispiel für STunnel

17 Kommerzielle VPN Dienste

18 Aktuelle VPN Sicherheitsproblematik

19 SSH VPN

  • ein SSH VPN eignet sich als Ad-Hoc VPN zwischen Systemen, bei denen nur der SSH Port offen ist
  • wir erstellen ein SSH-VPN zwischen der Client-VM und der Server-VM
  • Auf dem Client/Server andere VPN Lösungen (OpenVPN/IPSec etc) stoppen
  • SSH-VPN Tunnel auf dem Server erlauben
server0x# $EDITOR /etc/ssh/sshd_config
---
PermitTunnel yes
---
systemctl restart sshd
  • auf dem Server Anmeldung per Passwort für Root freischalten
$EDITOR /etc/ssh/sshd_config
---
[...]
PermitRootLogin yes
[...]
---
systemctl restart sshd
  • auf dem Client ein SSH-VPN Tunnel zum Server (-N kein Befehl am Ziel ausführen, -T kein Terminal auf dem Ziel öffnen, -C Komprimierung einschalten (optional), -f- sende SSH in den Hintergrund, -w 0:0 Nummer des lokalen TUN Netzwerkinterface und des entfernten Netzwerkinterface)
client0x$ sudo ssh -NTCf -w 0:0 100.64.x.2
  • auf dem Server geben wir dem Tunnel eine IP-Adresse aus dem Server-Segment
sudo ip link set tun0 up
sudo ip addr add 100.64.1x.100/32 peer 100.64.1x.200 dev tun0
  • auf dem Client auch (IP Adressen gegenüber dem Server vertauscht)
sudo ip link set tun0 up
sudo ip addr add 100.64.1x.200/32 peer 100.64.1x.100 dev tun0
  • nun sollten wir die jeweilige Gegenseite per ping erreichen
  • über Routing kann nun, ähnlich wie in der Wireguard-Übung, die IP-Kommunikation eines der Rechner (oder eines Netzes) über den SSH-VPN-Tunnel gesendet werden.
  • Alternative für die Einrichtung eines SSH-VPN: sshuttle https://github.com/sshuttle/sshuttle. SSHuttle ist auch als Debian Paket verfügbar:
apt install sshuttle

20 OSPF Routing mit Quagga

  • für die initiale Konfiguration des OSPF bitte die Firewall abschalten. Wir erstellen später Regeln für OSPF in unserer Firewall
  • OSPF Quagga Daemon starten
touch /etc/quagga/ospfd.conf
systemctl enable --now ospfd
  • Ordner für das Quagga Log anlegen
mkdir /var/log/quagga
chown quagga /var/log/quagga
  • OSPF Konfiguration
router0x$ vtysh
router0x# conf terminal
router0x(config)# log file /var/log/quagga/quagga.log
router0x(config)# router ospf
router0x(config-router)# network 192.168.1.0/24 area 0
router0x(config-router)# network 172.16.x.0/24 area 0
router0x(config-router)# network 100.64.x.0/24 area 0
router0x(config-router)# redistribute connected
router0x(config-router)# redistribute static
router0x(config-router)# router-id 192.168.1.yyy <-- IP Adresse auf enp0s3 des Routers
router0x(config-router)# end
router0x# write
Building Configuration...
Configuration saved to /etc/quagga/zebra.conf
Configuration saved to /etc/quagga/ospfd.conf
[OK]
router0x# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, A - Babel,
       > - selected route, * - FIB route

K>* 0.0.0.0/0 via 192.168.1.5, enp0s3
C>* 100.64.x.0/24 is directly connected, enp0s9
C>* 127.0.0.0/8 is directly connected, lo
C>* 172.16.x.0/24 is directly connected, enp0s8
O   192.168.1.0/24 [110/10] is directly connected, enp0s3, 00:04:32
C>* 192.168.1.0/24 is directly connected, enp0s3
  • OSPF 'neighbors' anzeigen
router0x# show ip ospf neighbor
  • Traceroute vom eigenen Client auf einen Server eines andern Teilnehmers
traceroute 172.16.x.2
apt install mtr
mtr 172.16.x.2

20.1 OSPF mit Authentisierung

  • HMAC-MD5 Authentisierung der OSPF-Kommunikation einschalten. Es wird ein "Shared-Secret" verwendet, hier das Wort "VILLA". Aus dem Wort und den Daten wird eine Signatur für die OSPF Pakete erzeugt. Auf allen OSPF-Routern (einer Area) muss das gleiche Secret konfiguriert werden.
router0x$ vtysh
router0x# conf terminal
router0x(config)# interface enp0s3
router0x(config-if)# ip ospf authentication message-digest
router0x(config-if)# ip ospf message-digest-key 1 md5 VILLA
router0x(config-if)# exit
router0x# router ospf
router0x(config-router)# area 0 authentication message-digest
router0x(config-router)# exit
router0x(config)# exit
router0x# write
router0x# debug ospf packet all
  • Test: einen Server oder Router eines der anderen Teilnehmer per 'ping' erreichen (oder SSH).

20.2 OSPF in der Firewall

  • OSPF ist ein eigenes IP Protokoll (wie UDP oder TCP). Die Protokollnummer ist 89, der Protokoll-Name kann in der Datei /etc/protcols gefunden werden
grep ospf /etc/protocols
  • Beispiel OSPF Regel
iptables -A INPUT  -p ospf -s <Quell-Netzwerk> -j ACCEPT
iptables -A OUTPUT -p ospf -d 224.0.0.0/24     -j ACCEPT
  • Erweitere das IPTables Firewall Regelwerk für OSPF, starte danach den OSPFd Dienst auf dem Router neu un prüfe, ob der Routing-Dienst weiterhin die anderen Router "sehen" kann. Prüfe die Firewall-Logs auf neue Block-Meldungen.

21 TOR - The Onion Router

21.1 TOR Installieren

  • auf dem Router und auf dem Laptop die Tor-Software installieren
apt install tor

21.2 TOR-Browser

  • auf dem Laptop bei installiertem Tor-Dienst den Socksv5-Proxy im Browser auf Port 9050 einstellen
  • Alternativ kann der Tor-Browser des Tor-Projekt installiert werden ( http://www.torproject.org ). Der Tor-Browser hat den Tor-Daemon schon eingebaut, dieser muss dann nicht extra installiert sein

21.3 TOR-Onion-Services

  • auf dem Router in der Tor-Konfiguration einen Onion Hidden-Service auf Localhost Port 8000 einrichten
$EDITOR /etc/tor/torrc
[...]
HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServicePort 80 127.0.0.1:8000
[...]
  • Tor neu starten
systemctl restart tor
systemctl status tor
  • auf dem Router einen Webserver Service starten (einfacher Python Webserver auf Port 8000)
python -m SimpleHTTPServer
  • auf dem Router den Onion-Namen herausfinden (Datei /var/lib/tor/hidden_service/hostname) und an einen der Teilnehmer weitergeben oder selbst im Firefox (bei eingeschaltetem Socks5-Proxy auf Port 9050)
  • den Onion-Dienst mit diesem "Domain"-Namen ansprechen, per Socks-Proxy aus dem Firefox oder mit dem Tor-Browser

21.4 Programme ohne Socks-Support mit Tor benutzen

  • einige Programme (wie ssh oder links) haben keinen Support für Socks5 Proxies
  • mit dem Programm torify können Programm für Tor eingerichtet werden
torify links http://<onion-adresse>.onion

21.5 Sicherheit

  • Einige Server-Dienste schalten spezielle Admin-Funktionen frei, wenn der Server über eine Loopback-Adresse (127.0.0.1) angesprochen wird (z.B. der Apache Webserver –> https://www.heise.de/security/meldung/Apache-verpetzt-moeglicherweise-Tor-Hidden-Services-3090218.html). Bei Bennutzung als Tor-Dienst auf einer Loopback-Adresse sind diese Admin-Funktionen von aussen über das Tor-Netzwerk erreichbar. Lösung: den Dienst auf einer nicht-Loopback Adresse konfigurieren, oder die speziellen Admin-Funktionen in der Server-Konfiguration ausschalten.

21.6 Client-Authentisierung mit Tor Onion Service V3

  • seit Version 0.3.5 der Tor-Software wird ein neues, sicheres Protokoll für die Onion-Services verwendet. Die Konfiguration der Authentisierung von Tor-Clients mit der Version 3 der Onion-Services wird im folgenden beschrieben

21.6.1 Schlüssel erstellen

  • es gibt mehrere Wege, ein Schlüsselpaar (ED25519) für einen Onion-Service zu erstellen
  1. per Python Programm
    • wir installieren python-nacl, eine Python-Bibliothek mit Krypto-Funktionen und laden dann von Github ein kleines Python-Script, welches eine Schlüssel-Paar für einen V3 Onion-Service erstellt:
    apt install python-nacl
    
    #!/usr/bin/env python3
    import base64
    try:
        import nacl.public
    except ImportError:
        print('PyNaCl is required: "pip install pynacl" or similar')
        exit(1)
    
    
    def key_str(key):
        # bytes to base 32
        key_bytes = bytes(key)
        key_b32 = base64.b32encode(key_bytes)
        # strip trailing ====
        assert key_b32[-4:] == b'===='
        key_b32 = key_b32[:-4]
        # change from b'ASDF' to ASDF
        s = key_b32.decode('utf-8')
        return s
    
    
    def main():
        priv_key = nacl.public.PrivateKey.generate()
        pub_key = priv_key.public_key
        print('public:  %s' % key_str(pub_key))
        print('private: %s' % key_str(priv_key))
    
    
    if __name__ == '__main__':
        exit(main())
    
    • ein Aufruf dieses Programms erstellt ein Schlüsselpaar und gibt dieses auf den Bildschirm aus
    # python x25519-gen.py
    public:  5U3RTWSB2BVYSC5UQTNRYHH5COACEJJLNCMDZBETEGGFZZFHIAPQ
    private: KRPY7WFH322QJL4KC3WHXDGV7WAMNVYLIUA65GUEWOOLMUHEIJIA
    

21.6.2 per OpenSSL

  • alternativ kann ein Schlüsselpaar mit OpenSSL erstellt werden
  • zuerst der private Schlüssel
openssl genpkey -algorithm x25519 -out key.private.pem
cat key.private.pem | grep -v " PRIVATE KEY" | base64 -d | tail --bytes=32 | base32 | sed 's/=//g' > private.key
  • und dann der öffentliche Schlüssel
openssl pkey -in key.private.pem -pubout | grep -v " PUBLIC KEY" | base64 -d | tail --bytes=32 | base32 | sed 's/=//g' > public.key

21.6.3 Authentisierung auf der Server-Seite einrichten

  • auf der Seite des Tor-Onion-Dienstes, im Unterverzeichnis authorized_clients des Dienstes eine Datei mit der Endung .auth anlegen. In unserem Beispiel wir die Datei /var/lib/tor/hidden_service/authorized_clients/nutzer.auth angelegt
cd /var/lib/tor/hidden_service/authorized_clients/
$EDITOR nutzer.auth
  • diese Datei enthält des öffentlichen Schlüssel des Clients im Format descriptor:x25519:<public-key>
  • den Tor-Dienst neu starten
systemctl restart tor
  • Nun kann nur noch ein Client, welcher den entsprechenden privaten Schlüssel zu den öffentlichen Schlüsseln des Dienstes hat, auf den Dienst zugreifen. Alle anderen Clients können nicht sehen, ob der Dienst existiert.

21.6.4 Authentisierung auf der Client-Seite einrichten

  • auf dem Tor-Client ein Verzeichnis für die Client-Schlüssel anlegen (hier /var/lib/tor/auth) und die Rechte für die Tor-Software setzen
mkdir /var/lib/tor/auth
chmod 700 /var/lib/tor/auth
chown toranon /var/lib/tor/auth/
  • in diesem Verzeichnis eine Text-Datei mit der Endung .auth_private anlegen. In diese Datei den privaten Schlüsseln für jeden Tor-Dienst eintragen (je eine Zeile pro Dienst). Jeder Eintrag hat das Format <onion-address>:descriptor:x25519:<base32-encoded-private-key>
$EDITOR /var/lib/tor/auth/nutzer.auth_private
  • das Verzeichnis mit den Authentisierungs-Datei(en) auf dem Client in die Konfiguration der Tor-Software eintragen. Datei /etc/tor/torrc:
ClientOnionAuthDir /var/lib/tor/auth

21.7 Vor- und Nachteile von Tor-Onion-Diensten

21.7.1 Vorteile

  • keine Änderungen an der (Heim-)Firewall notwendig. Keine Port-Forwardings etc.
  • kein DynDNS notwendig, um eine wechselne IP-Adresse mit einen Namen zu verbinden. Der Onion-Name wird immer im Tor-Netz gefunden
  • Datenverkehr ist verschlüsselt (Curve25519)
  • Datenverkehr ist anonymisiert

21.7.2 Nachteile

  • Client muss die Tor-Software als Proxy benutzen
  • hohe Latenz (Verzögerung) bei den Paketlaufzeiten

21.8 Links

22 DNSSEC Einführung

22.1 BIND 9 als DNS-Cache mit DNSSEC

  • BIND 9 Installation pruefen
apt install bind9
named -V
  • Konfiguration anpassen
vi /etc/bind/named.conf
---
options {
  dnssec-enable yes;
  dnssec-validation auto;
};
  • BIND 9 neu starten
systemctl restart bind9
systemctl status bind9
  • Testen (AD-Flag muss erscheinen)
router0x# dig @localhost dnssec.works +dnssec +m

23 HTTP/3 und QUIC

  • HTTP/3 ist der designierte Nachfolder des HTTP/2 Protokolls
  • HTTP/3 basiert auf QUIC von Google
  • QUIC wird schon einige Jahre zwischen dem Chrome-Browser, Android und Google Diensten getestet
  • HTTP/3 basiert auf UDP statt TCP und implementiert ein TCP-ähnliches Protokoll oberhalb von UDP

23.1 Links / Videos

24 XDP / eBPF / bpfilter

24.1 Bücher

24.1.1 Linux Observability with BPF

  • by Lorenzo Fontana, David Calavera
  • Publisher: O'Reilly Media, Inc.
  • Release Date: November 2019
  • ISBN: 9781492050209

24.1.2 BPF Performance Tools: Linux System and Application Observability

25 OpenVAS

25.1 OpenVAS über Docker installieren

  • Docker installieren (auf dem Laptop)
apt install docker.io
  • Docker starten
systemctl enable --now docker
  • OpenVAS laden und starten
docker run -d -p 127.0.0.1:443:443 --name openvas mikesplain/openvas
  • Logs anzeigen bis OpenVAS geladen ist und die Meldung openvassd 5.1.2 started angezeigt wird:
docker logs -f openvas
  • Mit dem Firefox Browser auf https://localhost (Benutzer admin, Passwort admin) am OpenVAS anmelden.
  • Mit dem Task Wizard einen neuen Scan starten (unter Scans). IP-Adresse des Laptops des Trainers (192.168.1.213) angeben. Der Scan dauert mehrere Minuten.

26 Anhang

26.1 Literaturliste

26.2 Referenzen:

26.2.1 Linux Zufallszahlen

26.2.2 SSL/TLS

26.2.3 Webserver Sicherheit

26.2.4 Wireguard