Eigenes Profil erstellen Beispiel ncat: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
| (94 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> | |
| − | + | == 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> | |
| − | |||
| − | = | + | = 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: | 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) |
| − | = | + | <span id="modul-konfigurieren"></span> |
| − | *./ | + | |
| − | < | + | = netzkatze.sh anpassen = |
| − | Building and Loading Policy | + | |
| − | + make -f /usr/share/selinux/devel/Makefile | + | * vim netzkatze.sh |
| − | Compiling | + | |
| − | Creating | + | ... |
| − | rm tmp/ | + | echo "Unloading Policy if present" |
| − | + /usr/sbin/semodule -i | + | set -x |
| − | + sepolicy manpage -p . -d | + | |
| − | ./ | + | semanage port -l | grep 8888 && semanage port -d -p tcp 8888 |
| − | + /sbin/restorecon -F -R -v /usr/local/ | + | semodule -l | grep netzkatze && semodule -r netzkatze |
| − | Relabeled /usr/local/ | + | |
| − | ... | + | echo "Building and Loading Policy" |
| − | </ | + | make -f /usr/share/selinux/devel/Makefile netzkatze.pp || exit |
| − | *cat | + | /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. | ||
| + | ** | ||
| + | <!-----> | ||
| + | <span id="permissive-für-das-modul-ausschalten"></span> | ||
| + | == 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; | ||
| + | <span id="attribute-und-klassen-laden"></span> | ||
| + | == 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) | ||
| + | <span id="einrichten-des-neuen-richtlinienmoduls-mithilfe-des-erzeugten-setup-skripts"></span> | ||
| + | |||
| + | = 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 | ||
| + | ... | ||
| + | <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> | ||
| + | ===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 | ||
| + | <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="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 | ||
| + | |||
| + | <!-----> | ||
| + | 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 | ||
| + | |||
| + | <!-----> | ||
| + | ● 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> | ||
| + | == 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 | ||
| + | <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->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 | ||
| + | <span id="modul-modifizieren"></span> | ||
| + | == Modul modifizieren == | ||
| + | |||
| + | * cat netzkatze.te | ||
| + | |||
<pre> | <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> | </pre> | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | = | + | == Modul neuinstallieren und Logdatei labeln == |
| − | *cat / | + | |
| + | * ./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> | <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> | </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