Eigenes Profil erstellen Beispiel ncat: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Zeile 1: Zeile 1:
 +
<span id="vorbereitungen"></span>
 +
= 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>
=Vorbereitung=
+
== Kopieren der Netzkatze ==
*dnf install -y policycoreutils-devel rpm-build
+
 
 +
* cp /usr/bin/ncat /usr/local/bin/netzkatze
 +
 
 +
<!----->
 +
<span id="wir-erstellen-einen-arbeitsordner"></span>
 +
== Wir erstellen einen Arbeitsordner ==
 +
 
 +
* mkdir netzkatze
 +
* cd netzkatze
  
= Kopieren der Netzkatze =
 
*cp /usr/bin/nc /usr/local/bin/netzkatze
 
 
<!----->
 
<!----->
 
<span id="benutzerdefiniert-richtlinie-für-das-programm-netzkatze-generieren"></span>
 
<span id="benutzerdefiniert-richtlinie-für-das-programm-netzkatze-generieren"></span>
=Wir erstellen einen Arbeitsordner=
+
= Benutzerdefiniert Richtlinie für das Programm “netzkatze” generieren =
*mkdir netzkatze
 
*cd netzkatze/
 
  
= Benutzerdefiniert Richtlinie für das Programm “netzkatze” generieren =
 
Durch die Option --init werden die Policy auf das systemd ausgerichtet.
 
 
* sepolicy generate --init /usr/local/bin/netzkatze
 
* sepolicy generate --init /usr/local/bin/netzkatze
  
Zeile 24: Zeile 31:
 
  /root/selinux/modules/netzkatze/netzkatze.sh # Einrichtungsskript
 
  /root/selinux/modules/netzkatze/netzkatze.sh # Einrichtungsskript
 
<span id="modul-konfigurieren"></span>
 
<span id="modul-konfigurieren"></span>
 
 
= Modul konfigurieren =
 
= Modul konfigurieren =
  
Zeile 51: Zeile 57:
 
  require {
 
  require {
 
         attribute port_type;
 
         attribute port_type;
         class tcp_socket { recv_msg name_bind };
+
         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’’
 +
 
<span id="porttyp-deklarieren-und-typentransition-erlauben"></span>
 
<span id="porttyp-deklarieren-und-typentransition-erlauben"></span>
 
== 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 84:
 
   
 
   
 
  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 99:
 
  allow netzkatze_t self:unix_stream_socket create_stream_socket_perms;
 
  allow netzkatze_t self:unix_stream_socket create_stream_socket_perms;
 
   
 
   
  # allow port to receive things
+
  # Erlaube Typentransition zum gelabelten Port für name bind.
+
  '''allow netzkatze_t netzkatze_port_t:tcp_socket { 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 };
+
'''allow netzkatze_t node_t:tcp_socket { node_bind };'''
  allow netzkatze_t self:tcp_socket { listen accept };
+
# 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 98: Zeile 114:
 
  sysnet_dns_name_resolve(netzkatze_t)
 
  sysnet_dns_name_resolve(netzkatze_t)
 
<span id="einrichten-des-neuen-richtlinienmoduls-mithilfe-des-erzeugten-setup-skripts"></span>
 
<span id="einrichten-des-neuen-richtlinienmoduls-mithilfe-des-erzeugten-setup-skripts"></span>
 
 
= Einrichten des neuen Richtlinienmoduls mithilfe des erzeugten Setup-Skripts =
 
= Einrichten des neuen Richtlinienmoduls mithilfe des erzeugten Setup-Skripts =
  
Zeile 118: Zeile 133:
 
  + 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
 +
./netzkatze.sh: 52: rpmbuild: not found
 +
<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 9999 zu assozieren verwendet man '''semanage port''':
  
 +
<!----->
 +
semanage port -a -t netzkatze_port_t -p tcp 9999
 
<span id="systemd-dienst-erstellen"></span>
 
<span id="systemd-dienst-erstellen"></span>
 
=Der Port 9876 wird mit netzkatze_port_t gelabled=
 
*semanage port -a -t netzkatze_port_t -p tcp 9876
 
 
 
= Systemd-Dienst erstellen =
 
= Systemd-Dienst erstellen =
  
* cat /lib/systemd/system/netzkatze.service
+
* 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 /usr/lib/systemd/system/netzkatze.service
  
 
<!----->
 
<!----->
Zeile 134: Zeile 156:
 
  [Service]
 
  [Service]
 
  Type=simple
 
  Type=simple
  ExecStart=/usr/local/bin/netzkatze -lp 9876
+
  ExecStart=/usr/local/bin/netzkatze -lp 9999
 
  #StandardOutput=append:/tmp/netzkatze.log
 
  #StandardOutput=append:/tmp/netzkatze.log
 
  #Restart=always
 
  #Restart=always
Zeile 147: Zeile 169:
 
<!----->
 
<!----->
 
<span id="permanente-änderung-des-kontexts"></span>
 
<span id="permanente-änderung-des-kontexts"></span>
 +
== Permanente Änderung des Kontexts ==
  
== Permanente Änderung des Kontexts ==
 
Wir ändern hier den SELinux Typen der Datei
 
 
* semanage fcontext -a -t systemd_unit_t /usr/lib/systemd/system/netzkatze.service
 
* semanage fcontext -a -t systemd_unit_t /usr/lib/systemd/system/netzkatze.service
Wir ändern hier den SELinux User der Datei
+
* restorecon -Fv netzkatze.service
* restorecon -Fv /usr/lib/systemd/system/netzkatze.service
 
  
 
<!----->
 
<!----->
 
<span id="service-starten"></span>
 
<span id="service-starten"></span>
 
 
== Service starten ==
 
== Service starten ==
  
* systemctl enable --now netzkatze
+
* systemctl start netzkatze
 
* systemctl status netzkatze
 
* systemctl status netzkatze
  
 
<!----->
 
<!----->
 
<span id="einschränkung-überprüfen"></span>
 
<span id="einschränkung-überprüfen"></span>
 
+
== Einschränkung überprüfen ==
= Einschränkung überprüfen =
 
  
 
* ps -eZ | grep netzkatze
 
* ps -eZ | grep netzkatze
Zeile 175: Zeile 193:
 
<!----->
 
<!----->
 
  LISTEN 0      1            0.0.0.0:9999      0.0.0.0:*    users:(("netzkatze",pid=3598,proc_ctx=system_u:system_r:netzkatze_t:s0,fd=3))                                                                                                                         
 
  LISTEN 0      1            0.0.0.0:9999      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 9999
 +
* 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 9999 (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:/tmp/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>
=Hier kommt dan der Beweis rein das man den Port nicht ändern kann=
+
== Verstöße anzeigen ==
bla bla bla
+
 
=Wegen could not open interface info [/var/lib/sepolgen/interface_info]=
+
* ausearch -m AVC -ts recent
*sepolgen-ifgen
+
 
 +
<!----->
 +
----
 +
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!) ==
 +
 
 +
* ausearch -m AVC -ts recent | audit2allow -R
  
= Verstöße anzeigen =
+
<!----->
*ausearch -m AVC -ts recent
 
= Lösungsvorschlag=
 
*ausearch -m AVC -ts recent  | grep append | audit2allow  -R
 
 
  require {
 
  require {
type netzkatze_t;
+
        type netzkatze_t;
 +
        type unreserved_port_t;
 +
        class tcp_socket name_bind;
 
  }
 
  }
 
   
 
   
 
  #============= netzkatze_t ==============
 
  #============= netzkatze_t ==============
  files_manage_generic_tmp_files(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 /tmp/netzkatze.log schreiben.
 +
* Unter Debian lässt SELinux das aber nicht zu, weil netzkatze_t nicht in tmp_t transitieren darf.
 +
* Anstatt netzkatze in den kompletten Ordner schreiben zu lassen, erlauben wir netzkatze nur in /tmp/netzkatze.log ''append'' auszuführen.
 +
* 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 9999
 +
StandardOutput=append:/tmp/netzkatze.log
 +
Restart=always
 +
 +
[Install]
 +
WantedBy=default.target
 +
* systemd daemon-reload
 +
* systemctl start netzkatze
 +
* systemctl status netzkatze
 +
* 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
  
 +
<!----->
 +
policy_module(netzkatze, 1.0.0)
 +
 +
require {
 +
        attribute port_type;
 +
        '''attribute file_type;'''
 +
        class tcp_socket { name_bind };
 +
        '''class file { append };'''
 +
}
 +
########################################
 +
#
 +
# 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;
 +
 +
#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 };'''
 +
 +
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="modul-neuinstallieren-und-logdatei-labeln"></span>
 +
== Modul neuinstallieren und Logdatei labeln ==
 +
 +
* ./netzkatze.sh
 +
* touch /tmp/netzkatze.log
 +
* semanage fcontext -a -t netzkatze_log_t /tmp/netzkatze.log
 +
* restorecon -Fv /tmp/netzkatze.log
 +
 +
<!----->
 +
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>
time->Wed Nov 23 11:18:23 2022
+
== Berechtigung testen ==
type=AVC msg=audit(1669198703.130:210): avc:  denied  { name_bind } for  pid=3598 comm="netzkatze" src=9999 scontext=system_u:system_r:netzkatze_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=1
 
----
 
time->Wed Nov 23 11:18:23 2022
 
type=AVC msg=audit(1669198703.130:211): avc:  denied  { node_bind } for  pid=3598 comm="netzkatze" src=9999 scontext=system_u:system_r:netzkatze_t:s0 tcontext=system_u:object_r:node_t:s0 tclass=tcp_socket permissive=1
 
----
 
time->Wed Nov 23 11:18:23 2022
 
type=AVC msg=audit(1669198703.130:212): avc:  denied  { listen } for  pid=3598 comm="netzkatze" lport=9999 scontext=system_u:system_r:netzkatze_t:s0 tcontext=system_u:system_r:netzkatze_t:s0 tclass=tcp_socket permissive=1
 
----
 
time->Wed Nov 23 11:18:23 2022
 
type=AVC msg=audit(1669198703.130:213): avc:  denied  { accept } for  pid=3598 comm="netzkatze" lport=9999 scontext=system_u:system_r:netzkatze_t:s0 tcontext=system_u:system_r:netzkatze_t:s0 tclass=tcp_socket permissive=1
 
<span id="vorgeschlagene-änderungen"></span>
 
  
= Vorgeschlagene Änderungen =
+
* echo -e “Hello, World” | nc localhost 9999
 +
* cat /tmp/netzkatze.log
  
* ausearch -m AVC -ts recent | audit2allow -R
+
<!----->
 +
Hello, World

Version vom 28. November 2022, 07:10 Uhr

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

  • 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
/root/selinux/modules/netzkatze/netzkatze.if # Schnittstellendatei
/root/selinux/modules/netzkatze/netzkatze.fc # Dateikontext-Datei
/root/selinux/modules/netzkatze/netzkatze_selinux.spec # Spezifikationsdatei
/root/selinux/modules/netzkatze/netzkatze.sh # Einrichtungsskript

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
  • Das Programm muss die zu den nötigen 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 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 };

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

  • ./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
./netzkatze.sh: 52: rpmbuild: not found

den erlaubten Port labeln

  • Nachdem das Modul kompiliert und geladen ist, sollte SELinux den neuen Porttyp kennen
  • Um ihn mit den Port 9999 zu assozieren verwendet man semanage port:
semanage port -a -t netzkatze_port_t -p tcp 9999

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 /usr/lib/systemd/system/netzkatze.service
[Unit]
Description=Simple Enforcement test

[Service]
Type=simple
ExecStart=/usr/local/bin/netzkatze -lp 9999
#StandardOutput=append:/tmp/netzkatze.log
#Restart=always

[Install]
WantedBy=default.target

Temporäre Änderung des Kontexts

  • chcon -u system_u -t systemd_unit_t /usr/lib/systemd/system/netzkatze.service

Permanente Änderung des Kontexts

  • semanage fcontext -a -t systemd_unit_t /usr/lib/systemd/system/netzkatze.service
  • restorecon -Fv netzkatze.service

Service starten

  • systemctl start netzkatze
  • systemctl status netzkatze

Einschränkung überprüfen

  • ps -eZ | grep netzkatze
system_u:system_r:netzkatze_t:s0   3598 ?        00:00:00 netzkatze
  • ss -Zlt | grep netzkatze
LISTEN 0      1            0.0.0.0:9999      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 9999
  • 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 9999 (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:/tmp/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!)

  • 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 /tmp/netzkatze.log schreiben.
  • Unter Debian lässt SELinux das aber nicht zu, weil netzkatze_t nicht in tmp_t transitieren darf.
  • Anstatt netzkatze in den kompletten Ordner schreiben zu lassen, erlauben wir netzkatze nur in /tmp/netzkatze.log append auszuführen.
  • 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 9999
StandardOutput=append:/tmp/netzkatze.log
Restart=always

[Install]
WantedBy=default.target
  • systemd daemon-reload
  • systemctl start netzkatze
  • systemctl status netzkatze
  • 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 {
        attribute port_type;
        attribute file_type;
        class tcp_socket { name_bind };
        class file { append };
}
########################################
#
# 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;

#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 };

domain_use_interactive_fds(netzkatze_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 /tmp/netzkatze.log
  • semanage fcontext -a -t netzkatze_log_t /tmp/netzkatze.log
  • restorecon -Fv /tmp/netzkatze.log
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 9999
  • cat /tmp/netzkatze.log
Hello, World