Eigenes Profil erstellen Beispiel ncat: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
| (62 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
| + | [[Kategorie:SELinux]] | ||
| + | <span id="vorbereitungen"></span> | ||
| + | =Installation= | ||
| + | ;Wenn noch nicht geschehen | ||
| + | *[[SELinux unter Fedora]] | ||
| + | |||
| + | = Vorbereitungen = | ||
| + | |||
| + | Das Programm '''nc''' soll über systemd eingeschränkt auf einen Port ausgeführt werden. | ||
| + | |||
<span id="kopieren-der-netzkatze"></span> | <span id="kopieren-der-netzkatze"></span> | ||
| − | = | + | == Kopieren der Netzkatze == |
| − | * | + | |
| + | * cp /usr/bin/ncat /usr/local/bin/netzkatze | ||
| + | |||
| + | <!-----> | ||
| + | <span id="wir-erstellen-einen-arbeitsordner"></span> | ||
| + | == Wir erstellen einen Arbeitsordner == | ||
| + | |||
| + | * mkdir netzkatze | ||
| + | * cd netzkatze | ||
| − | |||
| − | |||
<!-----> | <!-----> | ||
<span id="benutzerdefiniert-richtlinie-für-das-programm-netzkatze-generieren"></span> | <span id="benutzerdefiniert-richtlinie-für-das-programm-netzkatze-generieren"></span> | ||
| − | |||
| − | |||
| − | |||
= Benutzerdefiniert Richtlinie für das Programm “netzkatze” generieren = | = Benutzerdefiniert Richtlinie für das Programm “netzkatze” generieren = | ||
| − | + | ;--init bestimmt dass das Program von systemd aufgerufen wird. | |
| + | ;--application für normale Programme | ||
* sepolicy generate --init /usr/local/bin/netzkatze | * sepolicy generate --init /usr/local/bin/netzkatze | ||
| Zeile 18: | Zeile 32: | ||
Failed to retrieve rpm info for selinux-policy | Failed to retrieve rpm info for selinux-policy | ||
Created the following files: | Created the following files: | ||
| − | /root/selinux/modules/netzkatze/netzkatze.te # Typ-Enforcement-Datei | + | /root/selinux/modules/netzkatze/netzkatze.te # Typ-Enforcement-Datei (Hierstehen die Regeln drin) |
| − | /root/selinux/modules/netzkatze/netzkatze.if # Schnittstellendatei | + | /root/selinux/modules/netzkatze/netzkatze.if # Schnittstellendatei () |
| − | /root/selinux/modules/netzkatze/netzkatze.fc # Dateikontext-Datei | + | /root/selinux/modules/netzkatze/netzkatze.fc # Dateikontext-Datei (Dateien die vom Programm aufgerufen werden, werden gelabled) |
| − | /root/selinux/modules/netzkatze/netzkatze_selinux.spec # Spezifikationsdatei | + | /root/selinux/modules/netzkatze/netzkatze_selinux.spec # Spezifikationsdatei () |
| − | /root/selinux/modules/netzkatze/netzkatze.sh # Einrichtungsskript | + | /root/selinux/modules/netzkatze/netzkatze.sh # Einrichtungsskript (Kompilieren und Installieren) |
<span id="modul-konfigurieren"></span> | <span id="modul-konfigurieren"></span> | ||
| + | |||
| + | = netzkatze.sh anpassen = | ||
| + | |||
| + | * vim netzkatze.sh | ||
| + | |||
| + | ... | ||
| + | echo "Unloading Policy if present" | ||
| + | set -x | ||
| + | |||
| + | semanage port -l | grep 8888 && semanage port -d -p tcp 8888 | ||
| + | semodule -l | grep netzkatze && semodule -r netzkatze | ||
| + | |||
| + | echo "Building and Loading Policy" | ||
| + | make -f /usr/share/selinux/devel/Makefile netzkatze.pp || exit | ||
| + | /usr/sbin/semodule -i netzkatze.pp | ||
| + | |||
| + | # Generate a man page off the installed module | ||
| + | sepolicy manpage -p . -d netzkatze_t | ||
| + | # Fixing the file context on /usr/local/bin/netzkatze and label port | ||
| + | /sbin/restorecon -F -R -v /usr/local/bin/netzkatze | ||
| + | semanage port -a -t netzkatze_port_t -p tcp 8888 | ||
| + | ... | ||
= Modul konfigurieren = | = Modul konfigurieren = | ||
| Zeile 30: | Zeile 66: | ||
* Es muss noch ein Porttyp für das Programm definiert werden. | * Es muss noch ein Porttyp für das Programm definiert werden. | ||
* Ein Port muss über '''semanage port''' mit den benutzerdefinierten Porttype gelabelt werden | * Ein Port muss über '''semanage port''' mit den benutzerdefinierten Porttype gelabelt werden | ||
| − | * | + | * Ein User muss zu den nötigen Prozess Typen transitieren dürfen. |
| − | + | ** | |
<!-----> | <!-----> | ||
<span id="permissive-für-das-modul-ausschalten"></span> | <span id="permissive-für-das-modul-ausschalten"></span> | ||
| Zeile 48: | Zeile 84: | ||
* Für unseren Fall benötigen wir folgendes: | * Für unseren Fall benötigen wir folgendes: | ||
| − | |||
require { | require { | ||
attribute port_type; | attribute port_type; | ||
| − | class tcp_socket { | + | class tcp_socket { name_bind }; |
} | } | ||
| − | + | * Liste der Attribute (erforderlich, um später die Dateilabels zuweisen zu können): | |
| + | ** seinfo -a | grep ''your_attribute'' | ||
| + | * Liste der Klassen und deren Permissions (erforderlich, um Permissions zuweisen zu können): | ||
| + | ** seinfo -x -a | grep ''your_class'' | ||
| + | * Liste der Commons und deren Permissions (Klassen erben Permissions von diesen): | ||
| + | ** seinfo --commmon | ||
| + | ** seinfo -x common ''your_common'' | ||
| + | |||
== Porttyp deklarieren und Typentransition erlauben == | == Porttyp deklarieren und Typentransition erlauben == | ||
| − | Vollständige Konfiguration: | + | Vollständige Konfiguration zum freischalten eines Ports: |
policy_module(netzkatze, 1.0.0) | policy_module(netzkatze, 1.0.0) | ||
| − | require { | + | '''require {''' |
| − | attribute port_type; | + | '''attribute port_type;''' |
| − | class tcp_socket { name_bind }; | + | '''class tcp_socket { name_bind };''' |
} | } | ||
######################################## | ######################################## | ||
| Zeile 70: | Zeile 112: | ||
type netzkatze_t; | type netzkatze_t; | ||
| − | type netzkatze_port_t; | + | '''type netzkatze_port_t;''' |
type netzkatze_exec_t; | type netzkatze_exec_t; | ||
| + | |||
init_daemon_domain(netzkatze_t, netzkatze_exec_t) | init_daemon_domain(netzkatze_t, netzkatze_exec_t) | ||
| − | typeattribute netzkatze_port_t port_type; | + | '''typeattribute netzkatze_port_t port_type;''' |
| − | #permissive netzkatze_t; | + | '''#permissive netzkatze_t;''' |
######################################## | ######################################## | ||
| Zeile 84: | Zeile 127: | ||
allow netzkatze_t self:unix_stream_socket create_stream_socket_perms; | allow netzkatze_t self:unix_stream_socket create_stream_socket_perms; | ||
| − | # | + | # Erlaube eine named_bind an den netzkatze_port_t. |
| − | + | # Die zuordnung für welchen Port es gilt, erfolgt später. | |
| − | allow netzkatze_t netzkatze_port_t:tcp_socket { name_bind }; | + | '''allow netzkatze_t netzkatze_port_t:tcp_socket { name_bind };''' |
| − | allow netzkatze_t node_t:tcp_socket { node_bind }; | + | # Erlaube generell ein node bind. |
| − | allow netzkatze_t self:tcp_socket { listen accept }; | + | '''allow netzkatze_t node_t:tcp_socket { node_bind };''' |
| + | # Erlaube netzkatze das Akzeptieren und Hören von Datenströmen | ||
| + | '''allow netzkatze_t self:tcp_socket { listen accept };''' | ||
domain_use_interactive_fds(netzkatze_t) | domain_use_interactive_fds(netzkatze_t) | ||
| Zeile 100: | Zeile 145: | ||
= Einrichten des neuen Richtlinienmoduls mithilfe des erzeugten Setup-Skripts = | = Einrichten des neuen Richtlinienmoduls mithilfe des erzeugten Setup-Skripts = | ||
| + | ; Es wird kompliert, installiert und relabled | ||
* ./netzkatze.sh | * ./netzkatze.sh | ||
| Zeile 118: | Zeile 164: | ||
+ pwd=/root/selinux/modules/netzkatze | + pwd=/root/selinux/modules/netzkatze | ||
+ rpmbuild --define _sourcedir /root/selinux/modules/netzkatze --define _specdir /root/selinux/modules/netzkatze --define _builddir /root/selinux/modules/netzkatze --define _srcrpmdir /root/selinux/modules/netzkatze --define _rpmdir /root/selinux/modules/netzkatze --define _buildrootdir /root/selinux/modules/netzkatze/.build -ba netzkatze_selinux.spec | + rpmbuild --define _sourcedir /root/selinux/modules/netzkatze --define _specdir /root/selinux/modules/netzkatze --define _builddir /root/selinux/modules/netzkatze --define _srcrpmdir /root/selinux/modules/netzkatze --define _rpmdir /root/selinux/modules/netzkatze --define _buildrootdir /root/selinux/modules/netzkatze/.build -ba netzkatze_selinux.spec | ||
| + | ... | ||
| + | <span id="den-erlaubten-port-labeln"></span> | ||
| + | = den erlaubten Port labeln = | ||
| + | |||
| + | * Nachdem das Modul kompiliert und geladen ist, sollte SELinux den neuen Porttyp kennen | ||
| + | * Um ihn mit den Port 8888 zu assozieren, verwendet man '''semanage port''': | ||
| + | |||
| + | <!-----> | ||
| + | *semanage port -a -t netzkatze_port_t -p tcp 8888 | ||
<span id="systemd-dienst-erstellen"></span> | <span id="systemd-dienst-erstellen"></span> | ||
| − | + | ===Check=== | |
| − | = | + | *semanage port -l | grep netzkatze |
| − | *semanage port - | + | netzkatze_port_t tcp 8888 |
= Systemd-Dienst erstellen = | = Systemd-Dienst erstellen = | ||
| − | * cat / | + | * Für die erste Version soll netzkatze nach der ersten Nachricht stoppen und noch '''keine''' Logdatei schreiben. |
| + | * Die erhaltene Nachricht soll einzusehen sein über: | ||
| + | * systemctl status netzkatze | ||
| + | * cat /etc/systemd/system/netzkatze.service | ||
| − | |||
[Unit] | [Unit] | ||
Description=Simple Enforcement test | Description=Simple Enforcement test | ||
| Zeile 134: | Zeile 191: | ||
[Service] | [Service] | ||
Type=simple | Type=simple | ||
| − | ExecStart=/usr/local/bin/netzkatze -lp | + | ExecStart=/usr/local/bin/netzkatze -lp 8888 |
| − | #StandardOutput=append:/ | + | #StandardOutput=append:/netzkatze/netzkatze.log |
#Restart=always | #Restart=always | ||
| Zeile 141: | Zeile 198: | ||
WantedBy=default.target | WantedBy=default.target | ||
<span id="temporäre-änderung-des-kontexts"></span> | <span id="temporäre-änderung-des-kontexts"></span> | ||
| − | == | + | == Permanente Änderung des Kontexts == |
| + | *[[SELinux Permanente Änderung des Kontexts]] | ||
| + | |||
| + | == Service starten == | ||
| − | * | + | * systemctl start netzkatze |
| + | * systemctl status netzkatze | ||
<!-----> | <!-----> | ||
| − | <span id=" | + | <span id="einschränkung-überprüfen"></span> |
| + | == Einschränkung überprüfen == | ||
| + | Man sieht an anhand von netzkatze_t das von init_t richtig tranistiert wurde. | ||
| + | * ps -eZ | grep netzkatze | ||
| − | + | <!-----> | |
| − | + | system_u:system_r:netzkatze_t:s0 3598 ? 00:00:00 netzkatze | |
| − | + | * ss -Znlt | grep netzkatze | |
| − | |||
| − | * | ||
<!-----> | <!-----> | ||
| − | <span id=" | + | LISTEN 0 1 0.0.0.0:8888 0.0.0.0:* users:(("netzkatze",pid=3598,proc_ctx=system_u:system_r:netzkatze_t:s0,fd=3)) |
| + | <span id="einschränkungen-testen"></span> | ||
| − | = | + | = Einschränkungen testen = |
| − | * | + | * echo -e "Hello, World!" | nc localhost 8888 |
* systemctl status netzkatze | * systemctl status netzkatze | ||
<!-----> | <!-----> | ||
| − | <span id=" | + | ● netzkatze.service - Netzkatze-Kontext Test |
| − | + | Loaded: loaded (/lib/systemd/system/netzkatze.service; enabled; vendor preset: enabled) | |
| − | = | + | Active: inactive (dead) since Fri 2022-11-25 09:57:07 CET; 3s ago |
| + | Process: 8878 ExecStart=/usr/local/sbin/netzkatze -l -p 8888 (code=exited, status=0/SUCCESS) | ||
| + | Main PID: 8878 (code=exited, status=0/SUCCESS) | ||
| + | CPU: 4ms | ||
| + | |||
| + | Nov 25 09:56:50 se-debian systemd[1]: Started Netzkatze-Kontext Test. | ||
| + | Nov 25 09:57:06 se-debian netzkatze[8878]: Hello, World! | ||
| + | Nov 25 09:57:07 se-debian systemd[1]: netzkatze.service: Succeeded. | ||
| + | <span id="systemd-darf-keinen-nicht-gelabelten-port-benutzen"></span> | ||
| + | = Systemd darf keinen nicht gelabelten Port benutzen = | ||
| − | * | + | * vim /usr/lib/systemd/system/netzkatze.service |
<!-----> | <!-----> | ||
| − | + | [Unit] | |
| − | * | + | Description=Netzkatze-Kontext Test |
| + | |||
| + | [Service] | ||
| + | Type=simple | ||
| + | ExecStart=/usr/local/sbin/netzkatze -l -p '''9998''' | ||
| + | #StandardOutput=append:/netzkatze/netzkatze.log | ||
| + | |||
| + | [Install] | ||
| + | WantedBy=default.target | ||
| + | * systemctl daemon-reload | ||
| + | * systemctl start netzkatze | ||
| + | * systemctl status netzkatze | ||
<!-----> | <!-----> | ||
| − | + | ● netzkatze.service - Netzkatze-Kontext Test | |
| + | Loaded: loaded (/lib/systemd/system/netzkatze.service; enabled; vendor preset: enabled) | ||
| + | Active: failed (Result: exit-code) since Fri 2022-11-25 10:15:23 CET; 2s ago | ||
| + | Process: 8964 ExecStart=/usr/local/sbin/netzkatze -l -p 9998 (code=exited, status=1/FAILURE) | ||
| + | Main PID: 8964 (code=exited, status=1/FAILURE) | ||
| + | CPU: 4ms | ||
| + | |||
| + | Nov 25 10:15:23 se-debian systemd[1]: Started Netzkatze-Kontext Test. | ||
| + | Nov 25 10:15:23 se-debian netzkatze[8964]: Can't grab 0.0.0.0:9998 with bind : Permission denied | ||
| + | Nov 25 10:15:23 se-debian systemd[1]: netzkatze.service: Main process exited, code=exited, status=1/FAILURE | ||
| + | Nov 25 10:15:23 se-debian systemd[1]: netzkatze.service: Failed with result 'exit-code'. | ||
<span id="verstöße-anzeigen"></span> | <span id="verstöße-anzeigen"></span> | ||
| − | = Verstöße anzeigen = | + | == Verstöße anzeigen == |
* ausearch -m AVC -ts recent | * ausearch -m AVC -ts recent | ||
| Zeile 182: | Zeile 275: | ||
<!-----> | <!-----> | ||
---- | ---- | ||
| − | time-> | + | time->Fri Nov 25 10:15:23 2022 |
| − | type=AVC msg=audit( | + | type=AVC msg=audit(1669367723.907:425): avc: denied { name_bind } for pid=8964 comm="netzkatze" src=9998 scontext=system_u:system_r:netzkatze_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0 |
| + | <span id="von-audit2allow-vorgeschlagene-änderungen-nicht-übernehmen"></span> | ||
| + | == von audit2allow Vorgeschlagene Änderungen (nicht übernehmen!) == | ||
| + | Mit audit2allow kann man sich Vorschläge machen lassen um Einstellungen zu ändern. | ||
| + | In diesem Fall wäre es eine Erlaubnis '''unreserved_ports''' zu nutzen. Wir wollen dies aber nicht. | ||
| + | Wir wollen den jeweiligen Port dediziert zuordnen. | ||
| + | * ausearch -m AVC -ts recent | audit2allow -R | ||
| + | |||
| + | <!-----> | ||
| + | require { | ||
| + | type netzkatze_t; | ||
| + | type '''unreserved_port_t'''; | ||
| + | class tcp_socket name_bind; | ||
| + | } | ||
| + | |||
| + | #============= netzkatze_t ============== | ||
| + | allow netzkatze_t '''unreserved_port_t''':tcp_socket name_bind; | ||
| + | <span id="netzkatze-loggen"></span> | ||
| + | |||
| + | = netzkatze loggen = | ||
| + | |||
| + | * systemd soll nun alles, was netzkatze erhält in die Logdatei /netzkatze/netzkatze.log schreiben. | ||
| + | * mkdir /netzkatze | ||
| + | * Dies sieht man auch, wenn wir die .service Datei verändern: | ||
| + | * cat /usr/lib/systemd/system/netzkatze.service | ||
| + | |||
| + | <!-----> | ||
| + | [Unit] | ||
| + | Description=Simple Enforcement test | ||
| + | |||
| + | [Service] | ||
| + | Type=simple | ||
| + | ExecStart=/usr/local/bin/netzkatze -lp 8888 | ||
| + | StandardOutput=append:/netzkatze/netzkatze.log | ||
| + | Restart=always | ||
| + | |||
| + | [Install] | ||
| + | WantedBy=default.target | ||
| + | * systemctl daemon-reload | ||
| + | * systemctl start netzkatze | ||
| + | * systemctl status netzkatze | ||
| + | * echo -e "Hello, World" | nc localhost 8888 | ||
| + | * ausearch -m AVC -ts recent | ||
| + | |||
| + | <!-----> | ||
---- | ---- | ||
| − | time-> | + | time->Fri Nov 25 12:45:56 2022 |
| − | type=AVC msg=audit( | + | type=AVC msg=audit(1669376756.023:446): avc: denied { '''append''' } for pid=9347 comm="netzkatze" path="/tmp/netzkatze.log" dev="sda1" ino=655791 scontext=system_u:system_r:netzkatze_t:s0 tcontext=system_u:object_r:'''tmp_t''':s0 tclass=file permissive=0 |
| − | + | <span id="modul-modifizieren"></span> | |
| − | + | == Modul modifizieren == | |
| − | + | ||
| − | + | * cat netzkatze.te | |
| − | + | ||
| − | + | <pre> | |
| − | < | + | |
| − | + | policy_module(netzkatze, 1.0.0) | |
| + | |||
| + | require { | ||
| + | type init_t; | ||
| + | attribute port_type; | ||
| + | attribute file_type; | ||
| + | class tcp_socket { name_bind }; | ||
| + | class file { append open }; | ||
| + | class dir { write create }; | ||
| + | } | ||
| + | ######################################## | ||
| + | # | ||
| + | # Declarations | ||
| + | # | ||
| + | |||
| + | type netzkatze_t; | ||
| + | type netzkatze_port_t; | ||
| + | type netzkatze_exec_t; | ||
| + | type netzkatze_log_t; | ||
| + | |||
| + | init_daemon_domain(netzkatze_t, netzkatze_exec_t) | ||
| + | typeattribute netzkatze_port_t port_type; | ||
| + | typeattribute netzkatze_log_t file_type; | ||
| + | #permissive netzkatze_t; | ||
| + | |||
| + | ######################################## | ||
| + | # | ||
| + | # netzkatze local policy | ||
| + | # | ||
| + | allow netzkatze_t self:fifo_file rw_fifo_file_perms; | ||
| + | allow netzkatze_t self:unix_stream_socket create_stream_socket_perms; | ||
| + | |||
| + | # Erlaube Typentransition zum gelabelten Port für name bind. | ||
| + | allow netzkatze_t netzkatze_port_t:tcp_socket { name_bind }; | ||
| + | # Erlaube generell ein node bind. | ||
| + | allow netzkatze_t node_t:tcp_socket { node_bind }; | ||
| + | # Erlaube netzkatze das Akzeptieren und Hören von Datenströmen | ||
| + | allow netzkatze_t self:tcp_socket { listen accept }; | ||
| + | # Erlaube netzkatze das Anhängen in netzkatze_log_t markierte Dateien | ||
| + | allow netzkatze_t netzkatze_log_t:file { append }; | ||
| + | allow init_t netzkatze_log_t:file { append open}; | ||
| + | allow init_t netzkatze_log_t:dir { create write }; | ||
| + | |||
| + | domain_use_interactive_fds(netzkatze_t) | ||
| + | |||
| + | files_manage_default_files(init_t) | ||
| + | files_read_etc_files(netzkatze_t) | ||
| + | |||
| + | miscfiles_read_localization(netzkatze_t) | ||
| + | |||
| + | sysnet_dns_name_resolve(netzkatze_t) | ||
| + | </pre> | ||
| + | |||
| + | == Modul neuinstallieren und Logdatei labeln == | ||
| + | |||
| + | * ./netzkatze.sh | ||
| + | * touch /netzkatze/netzkatze.log | ||
| + | *semanage fcontext -a -t netzkatze_log_t "/netzkatze(/.*)?" | ||
| + | *restorecon -R /netzkatze | ||
| + | |||
| + | <!-----> | ||
| + | Relabeled /tmp/netzkatze.log from system_u:object_r:tmp_t:s0 to system_u:object_r:netzkatze_log_t:s0 | ||
| + | * systemctl daemon-reload | ||
| + | * systemctl stop netzkatze | ||
| + | * systemctl start netzkatze | ||
| + | |||
| + | <!-----> | ||
| + | <span id="berechtigung-testen"></span> | ||
| + | |||
| + | == Berechtigung testen == | ||
| + | |||
| + | * echo -e “Hello, World” | nc localhost 8888 | ||
| + | * cat /netzkatze/netzkatze.log | ||
| + | |||
| + | <!-----> | ||
| + | Hello, World | ||
| + | <span id="netzkatze-logging-über-einen-boolean-an-ausschalten"></span> | ||
| + | |||
| + | = netzkatze-Logging über einen Boolean an-/ausschalten = | ||
| + | |||
| + | * cat netzkatze.te | ||
| + | <pre> | ||
| + | policy_module(netzkatze, 1.0.0) | ||
| + | |||
| + | require { | ||
| + | type init_t; | ||
| + | attribute port_type; | ||
| + | attribute file_type; | ||
| + | class tcp_socket { name_bind }; | ||
| + | class file { append open }; | ||
| + | class dir { write create }; | ||
| + | } | ||
| + | ######################################## | ||
| + | # | ||
| + | # Declarations | ||
| + | # | ||
| + | |||
| + | type netzkatze_t; | ||
| + | type netzkatze_port_t; | ||
| + | type netzkatze_exec_t; | ||
| + | type netzkatze_log_t; | ||
| + | |||
| + | init_daemon_domain(netzkatze_t, netzkatze_exec_t) | ||
| + | typeattribute netzkatze_port_t port_type; | ||
| + | typeattribute netzkatze_log_t file_type; | ||
| + | bool allow_netzkatze_log true; | ||
| + | #permissive netzkatze_t; | ||
| + | |||
| + | ######################################## | ||
| + | # | ||
| + | # netzkatze local policy | ||
| + | # | ||
| + | allow netzkatze_t self:fifo_file rw_fifo_file_perms; | ||
| + | allow netzkatze_t self:unix_stream_socket create_stream_socket_perms; | ||
| + | |||
| + | # Erlaube Typentransition zum gelabelten Port für name bind. | ||
| + | allow netzkatze_t netzkatze_port_t:tcp_socket { name_bind }; | ||
| + | # Erlaube generell ein node bind. | ||
| + | allow netzkatze_t node_t:tcp_socket { node_bind }; | ||
| + | # Erlaube netzkatze das Akzeptieren und Hören von Datenströmen | ||
| + | allow netzkatze_t self:tcp_socket { listen accept }; | ||
| + | # Erlaube netzkatze das Anhängen in netzkatze_log_t markierte Dateien | ||
| + | if (allow_netzkatze_log) { | ||
| + | allow netzkatze_t netzkatze_log_t:file { append }; | ||
| + | allow init_t netzkatze_log_t:file { append open}; | ||
| + | allow init_t netzkatze_log_t:dir { create write }; | ||
| + | } | ||
| + | domain_use_interactive_fds(netzkatze_t) | ||
| + | |||
| + | files_manage_default_files(init_t) | ||
| + | files_read_etc_files(netzkatze_t) | ||
| + | |||
| + | miscfiles_read_localization(netzkatze_t) | ||
| + | |||
| + | sysnet_dns_name_resolve(netzkatze_t) | ||
| + | |||
| + | </pre> | ||
| + | |||
| + | |||
| + | |||
| + | =Schauen ob der Boolean gesetzt ist= | ||
| + | * getsebool allow_netzkatze_log | ||
| + | |||
| + | <!-----> | ||
| + | allow_netzkatze_log --> on | ||
| + | * setsebool allow_netzkatze_log 0 | ||
| + | * echo “Wird nicht geloggt” | nc localhost 8888 | ||
| + | * cat /tmp/netzkatze.log | ||
| + | |||
| + | <!-----> | ||
| + | * setsebool allow_netzkatze_log 1 | ||
| + | * systemctl restart netzkatze | ||
| + | * echo “Wird geloggt” | nc localhost 8888 | ||
| + | * cat /netzkatze/netzkatze.log | ||
| − | + | <!-----> | |
| + | Wird geloggt | ||
Aktuelle Version vom 11. Oktober 2024, 07:47 Uhr
Installation
- Wenn noch nicht geschehen
Vorbereitungen
Das Programm nc soll über systemd eingeschränkt auf einen Port ausgeführt werden.
Kopieren der Netzkatze
- cp /usr/bin/ncat /usr/local/bin/netzkatze
Wir erstellen einen Arbeitsordner
- mkdir netzkatze
- cd netzkatze
Benutzerdefiniert Richtlinie für das Programm “netzkatze” generieren
- --init bestimmt dass das Program von systemd aufgerufen wird.
- --application für normale Programme
- sepolicy generate --init /usr/local/bin/netzkatze
Failed to retrieve rpm info for selinux-policy Created the following files: /root/selinux/modules/netzkatze/netzkatze.te # Typ-Enforcement-Datei (Hierstehen die Regeln drin) /root/selinux/modules/netzkatze/netzkatze.if # Schnittstellendatei () /root/selinux/modules/netzkatze/netzkatze.fc # Dateikontext-Datei (Dateien die vom Programm aufgerufen werden, werden gelabled) /root/selinux/modules/netzkatze/netzkatze_selinux.spec # Spezifikationsdatei () /root/selinux/modules/netzkatze/netzkatze.sh # Einrichtungsskript (Kompilieren und Installieren)
netzkatze.sh anpassen
- vim netzkatze.sh
... echo "Unloading Policy if present" set -x semanage port -l | grep 8888 && semanage port -d -p tcp 8888 semodule -l | grep netzkatze && semodule -r netzkatze echo "Building and Loading Policy" make -f /usr/share/selinux/devel/Makefile netzkatze.pp || exit /usr/sbin/semodule -i netzkatze.pp # Generate a man page off the installed module sepolicy manpage -p . -d netzkatze_t # Fixing the file context on /usr/local/bin/netzkatze and label port /sbin/restorecon -F -R -v /usr/local/bin/netzkatze semanage port -a -t netzkatze_port_t -p tcp 8888 ...
Modul konfigurieren
- Die Grundeinstellung der .te Datei erlaubt lediglich den Start des Dienstes über systemd.
- Es muss noch ein Porttyp für das Programm definiert werden.
- Ein Port muss über semanage port mit den benutzerdefinierten Porttype gelabelt werden
- Ein User muss zu den nötigen Prozess Typen transitieren dürfen.
Permissive für das Modul ausschalten
- Standardmäßig ist das Modul auf permissive gestellt, d.h. SELinux schränkt das Programm nicht ein.
- Um das zu ändern muss diese Zeile auskommentiert werden:
# permissive netzkatze_t;
Attribute und Klassen laden
- Um die Standardregeln von SELinux benutzen zu dürfen, müssen diese mit require im Skript geladen werden
- Die Listen der Standardobjekte und -assoziationen kann man sich mit seinfo -x … anzeigen
- Für unseren Fall benötigen wir folgendes:
require {
attribute port_type;
class tcp_socket { name_bind };
}
- Liste der Attribute (erforderlich, um später die Dateilabels zuweisen zu können):
- seinfo -a | grep your_attribute
- Liste der Klassen und deren Permissions (erforderlich, um Permissions zuweisen zu können):
- seinfo -x -a | grep your_class
- Liste der Commons und deren Permissions (Klassen erben Permissions von diesen):
- seinfo --commmon
- seinfo -x common your_common
Porttyp deklarieren und Typentransition erlauben
Vollständige Konfiguration zum freischalten eines Ports:
policy_module(netzkatze, 1.0.0)
require {
attribute port_type;
class tcp_socket { name_bind };
}
########################################
#
# Declarations
#
type netzkatze_t;
type netzkatze_port_t;
type netzkatze_exec_t;
init_daemon_domain(netzkatze_t, netzkatze_exec_t)
typeattribute netzkatze_port_t port_type;
#permissive netzkatze_t;
########################################
#
# netzkatze local policy
#
allow netzkatze_t self:fifo_file rw_fifo_file_perms;
allow netzkatze_t self:unix_stream_socket create_stream_socket_perms;
# Erlaube eine named_bind an den netzkatze_port_t.
# Die zuordnung für welchen Port es gilt, erfolgt später.
allow netzkatze_t netzkatze_port_t:tcp_socket { name_bind };
# Erlaube generell ein node bind.
allow netzkatze_t node_t:tcp_socket { node_bind };
# Erlaube netzkatze das Akzeptieren und Hören von Datenströmen
allow netzkatze_t self:tcp_socket { listen accept };
domain_use_interactive_fds(netzkatze_t)
files_read_etc_files(netzkatze_t)
miscfiles_read_localization(netzkatze_t)
sysnet_dns_name_resolve(netzkatze_t)
Einrichten des neuen Richtlinienmoduls mithilfe des erzeugten Setup-Skripts
- Es wird kompliert, installiert und relabled
- ./netzkatze.sh
Building and Loading Policy + make -f /usr/share/selinux/devel/Makefile netzkatze.pp Compiling default netzkatze module Creating default netzkatze.pp policy package rm tmp/netzkatze.mod tmp/netzkatze.mod.fc + /usr/sbin/semodule -i netzkatze.pp libsemanage.add_user: user sddm not in password file + sepolicy manpage -p . -d netzkatze_t ./netzkatze_selinux.8 + /sbin/restorecon -F -R -v /usr/local/sbin/netzkatze Relabeled /usr/local/sbin/netzkatze from unconfined_u:object_r:bin_t:s0 to system_u:object_r:netzkatze_exec_t:s0 + pwd + pwd=/root/selinux/modules/netzkatze + rpmbuild --define _sourcedir /root/selinux/modules/netzkatze --define _specdir /root/selinux/modules/netzkatze --define _builddir /root/selinux/modules/netzkatze --define _srcrpmdir /root/selinux/modules/netzkatze --define _rpmdir /root/selinux/modules/netzkatze --define _buildrootdir /root/selinux/modules/netzkatze/.build -ba netzkatze_selinux.spec ...
den erlaubten Port labeln
- Nachdem das Modul kompiliert und geladen ist, sollte SELinux den neuen Porttyp kennen
- Um ihn mit den Port 8888 zu assozieren, verwendet man semanage port:
- semanage port -a -t netzkatze_port_t -p tcp 8888
Check
- semanage port -l | grep netzkatze
netzkatze_port_t tcp 8888
Systemd-Dienst erstellen
- Für die erste Version soll netzkatze nach der ersten Nachricht stoppen und noch keine Logdatei schreiben.
- Die erhaltene Nachricht soll einzusehen sein über:
- systemctl status netzkatze
- cat /etc/systemd/system/netzkatze.service
[Unit] Description=Simple Enforcement test [Service] Type=simple ExecStart=/usr/local/bin/netzkatze -lp 8888 #StandardOutput=append:/netzkatze/netzkatze.log #Restart=always [Install] WantedBy=default.target
Permanente Änderung des Kontexts
Service starten
- systemctl start netzkatze
- systemctl status netzkatze
Einschränkung überprüfen
Man sieht an anhand von netzkatze_t das von init_t richtig tranistiert wurde.
- ps -eZ | grep netzkatze
system_u:system_r:netzkatze_t:s0 3598 ? 00:00:00 netzkatze
- ss -Znlt | grep netzkatze
LISTEN 0 1 0.0.0.0:8888 0.0.0.0:* users:(("netzkatze",pid=3598,proc_ctx=system_u:system_r:netzkatze_t:s0,fd=3))
Einschränkungen testen
- echo -e "Hello, World!" | nc localhost 8888
- systemctl status netzkatze
● netzkatze.service - Netzkatze-Kontext Test
Loaded: loaded (/lib/systemd/system/netzkatze.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Fri 2022-11-25 09:57:07 CET; 3s ago
Process: 8878 ExecStart=/usr/local/sbin/netzkatze -l -p 8888 (code=exited, status=0/SUCCESS)
Main PID: 8878 (code=exited, status=0/SUCCESS)
CPU: 4ms
Nov 25 09:56:50 se-debian systemd[1]: Started Netzkatze-Kontext Test.
Nov 25 09:57:06 se-debian netzkatze[8878]: Hello, World!
Nov 25 09:57:07 se-debian systemd[1]: netzkatze.service: Succeeded.
Systemd darf keinen nicht gelabelten Port benutzen
- vim /usr/lib/systemd/system/netzkatze.service
[Unit] Description=Netzkatze-Kontext Test [Service] Type=simple ExecStart=/usr/local/sbin/netzkatze -l -p 9998 #StandardOutput=append:/netzkatze/netzkatze.log [Install] WantedBy=default.target
- systemctl daemon-reload
- systemctl start netzkatze
- systemctl status netzkatze
● netzkatze.service - Netzkatze-Kontext Test
Loaded: loaded (/lib/systemd/system/netzkatze.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2022-11-25 10:15:23 CET; 2s ago
Process: 8964 ExecStart=/usr/local/sbin/netzkatze -l -p 9998 (code=exited, status=1/FAILURE)
Main PID: 8964 (code=exited, status=1/FAILURE)
CPU: 4ms
Nov 25 10:15:23 se-debian systemd[1]: Started Netzkatze-Kontext Test.
Nov 25 10:15:23 se-debian netzkatze[8964]: Can't grab 0.0.0.0:9998 with bind : Permission denied
Nov 25 10:15:23 se-debian systemd[1]: netzkatze.service: Main process exited, code=exited, status=1/FAILURE
Nov 25 10:15:23 se-debian systemd[1]: netzkatze.service: Failed with result 'exit-code'.
Verstöße anzeigen
- ausearch -m AVC -ts recent
----
time->Fri Nov 25 10:15:23 2022
type=AVC msg=audit(1669367723.907:425): avc: denied { name_bind } for pid=8964 comm="netzkatze" src=9998 scontext=system_u:system_r:netzkatze_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0
von audit2allow Vorgeschlagene Änderungen (nicht übernehmen!)
Mit audit2allow kann man sich Vorschläge machen lassen um Einstellungen zu ändern. In diesem Fall wäre es eine Erlaubnis unreserved_ports zu nutzen. Wir wollen dies aber nicht. Wir wollen den jeweiligen Port dediziert zuordnen.
- ausearch -m AVC -ts recent | audit2allow -R
require {
type netzkatze_t;
type unreserved_port_t;
class tcp_socket name_bind;
}
#============= netzkatze_t ==============
allow netzkatze_t unreserved_port_t:tcp_socket name_bind;
netzkatze loggen
- systemd soll nun alles, was netzkatze erhält in die Logdatei /netzkatze/netzkatze.log schreiben.
- mkdir /netzkatze
- Dies sieht man auch, wenn wir die .service Datei verändern:
- cat /usr/lib/systemd/system/netzkatze.service
[Unit] Description=Simple Enforcement test [Service] Type=simple ExecStart=/usr/local/bin/netzkatze -lp 8888 StandardOutput=append:/netzkatze/netzkatze.log Restart=always [Install] WantedBy=default.target
- systemctl daemon-reload
- systemctl start netzkatze
- systemctl status netzkatze
- echo -e "Hello, World" | nc localhost 8888
- ausearch -m AVC -ts recent
----
time->Fri Nov 25 12:45:56 2022
type=AVC msg=audit(1669376756.023:446): avc: denied { append } for pid=9347 comm="netzkatze" path="/tmp/netzkatze.log" dev="sda1" ino=655791 scontext=system_u:system_r:netzkatze_t:s0 tcontext=system_u:object_r:tmp_t:s0 tclass=file permissive=0
Modul modifizieren
- cat netzkatze.te
policy_module(netzkatze, 1.0.0)
require {
type init_t;
attribute port_type;
attribute file_type;
class tcp_socket { name_bind };
class file { append open };
class dir { write create };
}
########################################
#
# Declarations
#
type netzkatze_t;
type netzkatze_port_t;
type netzkatze_exec_t;
type netzkatze_log_t;
init_daemon_domain(netzkatze_t, netzkatze_exec_t)
typeattribute netzkatze_port_t port_type;
typeattribute netzkatze_log_t file_type;
#permissive netzkatze_t;
########################################
#
# netzkatze local policy
#
allow netzkatze_t self:fifo_file rw_fifo_file_perms;
allow netzkatze_t self:unix_stream_socket create_stream_socket_perms;
# Erlaube Typentransition zum gelabelten Port für name bind.
allow netzkatze_t netzkatze_port_t:tcp_socket { name_bind };
# Erlaube generell ein node bind.
allow netzkatze_t node_t:tcp_socket { node_bind };
# Erlaube netzkatze das Akzeptieren und Hören von Datenströmen
allow netzkatze_t self:tcp_socket { listen accept };
# Erlaube netzkatze das Anhängen in netzkatze_log_t markierte Dateien
allow netzkatze_t netzkatze_log_t:file { append };
allow init_t netzkatze_log_t:file { append open};
allow init_t netzkatze_log_t:dir { create write };
domain_use_interactive_fds(netzkatze_t)
files_manage_default_files(init_t)
files_read_etc_files(netzkatze_t)
miscfiles_read_localization(netzkatze_t)
sysnet_dns_name_resolve(netzkatze_t)
Modul neuinstallieren und Logdatei labeln
- ./netzkatze.sh
- touch /netzkatze/netzkatze.log
- semanage fcontext -a -t netzkatze_log_t "/netzkatze(/.*)?"
- restorecon -R /netzkatze
Relabeled /tmp/netzkatze.log from system_u:object_r:tmp_t:s0 to system_u:object_r:netzkatze_log_t:s0
- systemctl daemon-reload
- systemctl stop netzkatze
- systemctl start netzkatze
Berechtigung testen
- echo -e “Hello, World” | nc localhost 8888
- cat /netzkatze/netzkatze.log
Hello, World
netzkatze-Logging über einen Boolean an-/ausschalten
- cat netzkatze.te
policy_module(netzkatze, 1.0.0)
require {
type init_t;
attribute port_type;
attribute file_type;
class tcp_socket { name_bind };
class file { append open };
class dir { write create };
}
########################################
#
# Declarations
#
type netzkatze_t;
type netzkatze_port_t;
type netzkatze_exec_t;
type netzkatze_log_t;
init_daemon_domain(netzkatze_t, netzkatze_exec_t)
typeattribute netzkatze_port_t port_type;
typeattribute netzkatze_log_t file_type;
bool allow_netzkatze_log true;
#permissive netzkatze_t;
########################################
#
# netzkatze local policy
#
allow netzkatze_t self:fifo_file rw_fifo_file_perms;
allow netzkatze_t self:unix_stream_socket create_stream_socket_perms;
# Erlaube Typentransition zum gelabelten Port für name bind.
allow netzkatze_t netzkatze_port_t:tcp_socket { name_bind };
# Erlaube generell ein node bind.
allow netzkatze_t node_t:tcp_socket { node_bind };
# Erlaube netzkatze das Akzeptieren und Hören von Datenströmen
allow netzkatze_t self:tcp_socket { listen accept };
# Erlaube netzkatze das Anhängen in netzkatze_log_t markierte Dateien
if (allow_netzkatze_log) {
allow netzkatze_t netzkatze_log_t:file { append };
allow init_t netzkatze_log_t:file { append open};
allow init_t netzkatze_log_t:dir { create write };
}
domain_use_interactive_fds(netzkatze_t)
files_manage_default_files(init_t)
files_read_etc_files(netzkatze_t)
miscfiles_read_localization(netzkatze_t)
sysnet_dns_name_resolve(netzkatze_t)
Schauen ob der Boolean gesetzt ist
- getsebool allow_netzkatze_log
allow_netzkatze_log --> on
- setsebool allow_netzkatze_log 0
- echo “Wird nicht geloggt” | nc localhost 8888
- cat /tmp/netzkatze.log
- setsebool allow_netzkatze_log 1
- systemctl restart netzkatze
- echo “Wird geloggt” | nc localhost 8888
- cat /netzkatze/netzkatze.log
Wird geloggt