Eigenes Profil erstellen Beispiel ncat: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(95 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
=Kopieren der Netzkatze=
+
[[Kategorie:SELinux]]
*cp /usr/bin/ncat /usr/local/bin/netzkatze
+
<span id="vorbereitungen"></span>
=System Dienst=
+
=Installation=
*cat /etc/systemd/system/netzkatze.service
+
;Wenn noch nicht geschehen
<pre>
+
*[[SELinux unter Fedora]]
[Unit]
+
 
Description=Simple testing daemon
+
= Vorbereitungen =
 +
 
 +
Das Programm '''nc''' soll über systemd eingeschränkt auf einen Port ausgeführt werden.
  
[Service]
+
<span id="kopieren-der-netzkatze"></span>
Type=simple
+
== Kopieren der Netzkatze ==
ExecStart=/usr/local/bin/netzkatze -lp 8888 >> /tmp/netzkatze
 
  
[Install]
+
* cp /usr/bin/ncat /usr/local/bin/netzkatze
WantedBy=multi-user.target
 
  
</pre>
+
<!----->
 +
<span id="wir-erstellen-einen-arbeitsordner"></span>
 +
== Wir erstellen einen Arbeitsordner ==
  
==Temporäre Änderung des Kontexts==
+
* mkdir netzkatze
chcon -u system_u -t systemd_unit_t mydaemon.service
+
* cd netzkatze
  
==Permanente Änderung des Kontexts==
+
<!----->
*semanage fcontext -a -t systemd_unit_t mydaemon.service
+
<span id="benutzerdefiniert-richtlinie-für-das-programm-netzkatze-generieren"></span>
*restorecon -v mydaemon.service
 
  
=Systemctl status=
+
= Benutzerdefiniert Richtlinie für das Programm “netzkatze” generieren =
*systemctl start mydaemon
+
;--init bestimmt dass das Program von systemd aufgerufen wird.
*systemctl status mydaemon
+
;--application für normale Programme
=Check that the new daemon is confined by SELinux=
+
* sepolicy generate --init /usr/local/bin/netzkatze
*ps -efZ | grep mydaemon
 
system_u:system_r:unconfined_service_t:s0 root 5812    1  0 15:41 ?        00:00:00 /usr/local/bin/mydaemon
 
  
=Generieren Sie eine benutzerdefinierte Richtlinie für den Daemon=
+
<!----->
*sepolicy generate --init /usr/local/bin/mydaemon
+
Failed to retrieve rpm info for selinux-policy
 
  Created the following files:
 
  Created the following files:
  /etc/systemd/system/mydaemon.te # Type Enforcement file
+
  /root/selinux/modules/netzkatze/netzkatze.te # Typ-Enforcement-Datei (Hierstehen die Regeln drin)
  /etc/systemd/system/mydaemon.if # Interface file
+
  /root/selinux/modules/netzkatze/netzkatze.if # Schnittstellendatei ()
  /etc/systemd/system/mydaemon.fc # File Contexts file
+
  /root/selinux/modules/netzkatze/netzkatze.fc # Dateikontext-Datei (Dateien die vom Programm aufgerufen werden, werden gelabled)
  /etc/systemd/system/mydaemon_selinux.spec # Spec file
+
  /root/selinux/modules/netzkatze/netzkatze_selinux.spec # Spezifikationsdatei ()
  /etc/systemd/system/mydaemon.sh # Setup Script
+
/root/selinux/modules/netzkatze/netzkatze.sh # Einrichtungsskript (Kompilieren und Installieren)
=Erstellen Sie die Systemrichtlinie mit dem neuen Richtlinienmodul mithilfe des mit dem vorherigen Befehl erstellten Setup-Skripts neu=
+
<span id="modul-konfigurieren"></span>
*./mydaemon.sh  
+
 
<pre>
+
= netzkatze.sh anpassen =
Building and Loading Policy
+
 
+ make -f /usr/share/selinux/devel/Makefile mydaemon.pp
+
* vim netzkatze.sh
Compiling targeted mydaemon module
+
 
Creating targeted mydaemon.pp policy package
+
...
rm tmp/mydaemon.mod tmp/mydaemon.mod.fc
+
echo "Unloading Policy if present"
+ /usr/sbin/semodule -i mydaemon.pp
+
set -x
+ sepolicy manpage -p . -d mydaemon_t
+
./mydaemon_selinux.8
+
semanage port -l | grep 8888 && semanage port -d -p tcp 8888
+ /sbin/restorecon -F -R -v /usr/local/bin/mydaemon
+
semodule -l | grep netzkatze && semodule -r netzkatze
Relabeled /usr/local/bin/mydaemon from unconfined_u:object_r:bin_t:s0 to system_u:object_r:mydaemon_exec_t:s0
+
...
+
echo "Building and Loading Policy"
</pre>=Eigenes Programm=
+
make -f /usr/share/selinux/devel/Makefile netzkatze.pp || exit
*cat ~/mydaemon.c
+
/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 &quot;Hello, World!&quot; | 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>
#include <unistd.h>
 
#include <stdio.h>
 
  
FILE *f;
+
policy_module(netzkatze, 1.0.0)
  
int main(void)
+
require {
{
+
        type init_t;
while(1) {
+
        attribute port_type;
f = fopen("/var/log/messages","w");
+
         attribute file_type;
         sleep(5);
+
         class tcp_socket { name_bind };
         fclose(f);
+
        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>
=Kompilieren=
 
*gcc -o mydaemon mydaemon.c
 
=Kopieren=
 
*cp mydaemon /usr/local/sbin
 
  
=System Dienst=
+
== Modul neuinstallieren und Logdatei labeln ==
*cat /etc/systemd/system/mydaemon.service
+
 
 +
* ./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>
[Unit]
+
policy_module(netzkatze, 1.0.0)
Description=Simple testing daemon
+
 
 +
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;
  
[Service]
+
init_daemon_domain(netzkatze_t, netzkatze_exec_t)
Type=simple
+
typeattribute netzkatze_port_t port_type;
ExecStart=/usr/local/bin/mydaemon
+
typeattribute netzkatze_log_t  file_type;
 +
bool allow_netzkatze_log true;
 +
#permissive netzkatze_t;
  
[Install]
+
########################################
WantedBy=multi-user.target
+
#
 +
# netzkatze local policy
 +
#
 +
allow netzkatze_t self:fifo_file rw_fifo_file_perms;
 +
allow netzkatze_t self:unix_stream_socket create_stream_socket_perms;
  
</pre>
+
# 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)
  
==Temporäre Änderung des Kontexts==
+
files_manage_default_files(init_t)
chcon -u system_u -t systemd_unit_t mydaemon.service
+
files_read_etc_files(netzkatze_t)
  
==Permanente Änderung des Kontexts==
+
miscfiles_read_localization(netzkatze_t)
*semanage fcontext -a -t systemd_unit_t mydaemon.service
 
*restorecon -v mydaemon.service
 
  
=Systemctl status=
+
sysnet_dns_name_resolve(netzkatze_t)
*systemctl start mydaemon
 
*systemctl status mydaemon
 
=Check that the new daemon is confined by SELinux=
 
*ps -efZ | grep mydaemon
 
system_u:system_r:unconfined_service_t:s0 root 5812    1  0 15:41 ?        00:00:00 /usr/local/bin/mydaemon
 
  
=Generieren Sie eine benutzerdefinierte Richtlinie für den Daemon=
 
*sepolicy generate --init /usr/local/bin/mydaemon
 
Created the following files:
 
/etc/systemd/system/mydaemon.te # Type Enforcement file
 
/etc/systemd/system/mydaemon.if # Interface file
 
/etc/systemd/system/mydaemon.fc # File Contexts file
 
/etc/systemd/system/mydaemon_selinux.spec # Spec file
 
/etc/systemd/system/mydaemon.sh # Setup Script
 
=Erstellen Sie die Systemrichtlinie mit dem neuen Richtlinienmodul mithilfe des mit dem vorherigen Befehl erstellten Setup-Skripts neu=
 
*./mydaemon.sh
 
<pre>
 
Building and Loading Policy
 
+ make -f /usr/share/selinux/devel/Makefile mydaemon.pp
 
Compiling targeted mydaemon module
 
Creating targeted mydaemon.pp policy package
 
rm tmp/mydaemon.mod tmp/mydaemon.mod.fc
 
+ /usr/sbin/semodule -i mydaemon.pp
 
+ sepolicy manpage -p . -d mydaemon_t
 
./mydaemon_selinux.8
 
+ /sbin/restorecon -F -R -v /usr/local/bin/mydaemon
 
Relabeled /usr/local/bin/mydaemon from unconfined_u:object_r:bin_t:s0 to system_u:object_r:mydaemon_exec_t:s0
 
...
 
 
</pre>
 
</pre>
  
=Starten Sie den Daemon neu und überprüfen Sie, ob er jetzt von SELinux eingeschränkt ausgeführt wird=
 
*systemctl restart mydaemon
 
*ps -efZ | grep mydaemon
 
=Da der Daemon jetzt von SELinux eingeschränkt wird, verhindert SELinux auch den Zugriff auf /var/log/messages. Zeigen Sie die entsprechende Ablehnungsnachricht an=
 
*ausearch -m AVC -ts recent
 
=Weiter Informationen=
 
*sealert -l "*"
 
=Vorgeschlagene Änderungen=
 
*ausearch -m AVC -ts recent | audit2allow -R
 
=Da die von audit2allow vorgeschlagenen Regeln in bestimmten Fällen falsch sein können, verwenden Sie nur einen Teil der Ausgabe, um die entsprechende Richtlinienschnittstelle zu finden=
 
*grep -r "logging_write_generic_logs" /usr/share/selinux/devel/include/ | grep .if
 
/usr/share/selinux/devel/include/system/logging.if:interface(`logging_write_generic_logs',
 
  
=Links=
 
*https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/using_selinux/writing-a-custom-selinux-policy_using-selinux
 
  
 +
=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
  
=Starten Sie den Daemon neu und überprüfen Sie, ob er jetzt von SELinux eingeschränkt ausgeführt wird=
+
<!----->
*systemctl restart mydaemon
+
* setsebool allow_netzkatze_log 1
*ps -efZ | grep mydaemon
+
* systemctl restart netzkatze
=Da der Daemon jetzt von SELinux eingeschränkt wird, verhindert SELinux auch den Zugriff auf /var/log/messages. Zeigen Sie die entsprechende Ablehnungsnachricht an=
+
* echo “Wird geloggt” | nc localhost 8888
*ausearch -m AVC -ts recent
+
* cat /netzkatze/netzkatze.log
=Weiter Informationen=
 
*sealert -l "*"
 
=Vorgeschlagene Änderungen=
 
*ausearch -m AVC -ts recent | audit2allow -R
 
=Da die von audit2allow vorgeschlagenen Regeln in bestimmten Fällen falsch sein können, verwenden Sie nur einen Teil der Ausgabe, um die entsprechende Richtlinienschnittstelle zu finden=
 
*grep -r "logging_write_generic_logs" /usr/share/selinux/devel/include/ | grep .if
 
/usr/share/selinux/devel/include/system/logging.if:interface(`logging_write_generic_logs',
 
  
=Links=
+
<!----->
*https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/using_selinux/writing-a-custom-selinux-policy_using-selinux
+
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