mv vs. cp: Was ist an der resultierenden Datei anders?

mv vs. cp: Was ist an der resultierenden Datei anders?

Bei mir trat ein Fehler auf, bei dem eine Konfigurationsdatei für eine Anwendung nicht richtig eingebunden wurde. Um die problematische Zeile der Datei zu isolieren, habe ich den alten Inhalt zeilenweise in eine neue Datei kopiert.

Am Ende hatte ich eine exakte Kopie der Datei erstellt, die alte funktionierte jedoch noch immer nicht, während die neue einwandfrei funktionierte.

Genauer gesagt: Wenn ich den mvBefehl verwende, um die Datei von meinem Speicherort an den gewünschten Ort zu verschieben, treten Fehler auf. Wenn ich cpdie Datei an den gewünschten Ort kopiere, treten keine Fehler auf.

Offensichtlich zeigen Dinge wie diff, file, oder ls -l, keine Unterschiede zwischen den beiden Dateien, da die eine eine Kopie der anderen ist.insofern cpeine exakte Kopie der Datei erstellt wird.

Ich kann nicht zu viele Informationen über die Datei weitergeben, da es sich um eine Arbeitssache handelt. Unterm Strich erzeugen die Befehle cp fileA fileBund mv fileA fileBeine „andere“ Datei B. Meine beste Vermutung ist, dass währenddessen ein sehr niedrigstufiges Attribut aus Datei B zurückbleibt cp(und sogar cp -pdasselbe Verhalten erzeugt).

Was macht mv anders als cp im Hinblick auf den genauen Inhalt der resultierenden Datei?

BEARBEITEN: Mit ls -l:

-rw-r--r--. 1 root root 3389 Aug  8 22:53 fileA
-rw-r--r--. 1 root root 3389 Aug  8 23:03 fileB

BEARBEITEN: Die Anwendung ist MySQL und die Datei ist eine .cnf-Datei. Das Element in dieser Konfigurationsdatei, das besonders interessant war, ist der Name des Binärprotokolls, das bei der Master-Slave-Datenbankreplikation verwendet wird. Der „Fehler“ lautet „Sie verwenden kein Binärprotokoll“, weil es kein Binärprotokoll gibt, da dieses Element nie von MySQL „gelesen“ wurde.

Mein erster Gedanke war, dass es einen Syntaxfehler in der Konfigurationsdatei gab, der dazu führte, dass das Ganze nicht gelesen wurde, was mich dazu veranlasste, es manuell neu zu erstellen, indem ich Textblöcke kopierte

EDIT: Ich komme voran ... Endlich mal etwas anderes bezüglich der Dateien.

ls -lZ

-rw-r--r--. root root unconfined_u:object_r:user_home_t:s0 server.cnf.bad
-rw-r--r--. root root unconfined_u:object_r:mysqld_etc_t:s0 server.cnf.good

Antwort1

TL;DR: in einem System, in demSELinuxverwendet wird, sollten vom System verwendete Dateien (z. B. Daemons) mit cp -aZund mv -Zanstelle von cp -aund kopiert oder verschoben werden mv. Wenn dies nicht getan wurde, sollte man einfach restorecon -v -roder restorecon -v -F -ram Ziel verwenden, um das System aufzufordern, die Standard-SELinux-Kontexte wiederherzustellen. Es ist immer eine gute Idee,restoreconam Ende eines Skripts, das mit wichtigen Konfigurationsdateien gearbeitet hat.

RHEL und damit die meisten seiner Derivatestandardmäßig SELinux verwenden.

Um Ihr Problem zu lösen, wenn Ihr System RHEL-basiert ist und das mariadb-serverPaket verwendet, führen Sie einfach im letzten Schritt aus, wenn sich die Datei imRichtiger Platz:

# restorecon -v -F /etc/my.cnf.d/server.cnf
Relabeled /etc/my.cnf.d/server.cnf from unconfined_u:object_r:user_home_t:s0 to system_u:object_r:mysqld_etc_t:s0

(Beachten Sie, dass ohne -Fdies kein Wechsel unconfined_uzu konfiguriert erfolgen würde system_u. Für gängige Systeme wäre dies bedeutungslos. So weit reicht mein Wissen über den Unterschied und warum er bedeutungslos ist nicht.)

Es wäre nur mehr Arbeit, der Datei den richtigen Kontext zu geben in einemandereOrt.chconkönnen Sie dies tun (entweder indem Sie es mit -u -tusw. angeben, oder einfacher, indem Sie den Kontext aus einer anderen Datei mit kopieren --reference):

# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root unconfined_u:object_r:user_home_t:s0 744 Apr 30  2017 /home/test/server.cnf.bad
# chcon -v -u system_u -t mysqld_etc_t /home/test/server.cnf.bad 
changing security context of '/home/test/server.cnf.bad'
# ls -lZ /home/test/server.cnf.bad
-rw-r--r--. 1 root root system_u:object_r:mysqld_etc_t:s0 744 Apr 30  2017 /home/test/server.cnf.bad

Wenn Sie SELinux-Probleme vermuten, suchen Sie /var/log/audit/audit.lognach Einträgen mit dem Wort, denieddas sich auf Ihren Prozess oder Ihre Datei bezieht. Sie können SELinux jederzeit vorübergehend auffordern, Vorgänge zuzulassen und sie dann mit „respective“ setenforce Permissiveund „ setenforce Enforcingcompare behavior“ wiederherzustellen. Belassen Sie es nicht bei „ Permissivespeziell für die Produktion“.

Nachfolgend finden Sie verschiedene Erklärungen.

Beispiel und was bei der Arbeit an Konfigurationsdateien zu tun ist

Beispiel für Verhalten mit verschiedenen cpOptionen und mvauf einem SELinux-fähigen System:

$ id
uid=1034(test) gid=1034(test) groups=1034(test)
$ pwd
/home/test
test@glasswalker:~$ ls -lZ foo
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:25 foo
$ cp foo /tmp/foo1
$ cp --preserve=context foo /tmp/foo2
$ cp -a foo /tmp/foo3
$ cp -aZ foo /tmp/foo4
$ mv foo /tmp/foo5
$ ls -lZ /tmp/foo?
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo1
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo2
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo3
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:25 /tmp/foo4
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0  0 Aug 11 11:25 /tmp/foo5
$ touch bar
$ ls -lZ bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_home_t:s0 0 Aug 11 11:49 bar
$ mv -Z bar /tmp
$ ls -lZ /tmp/bar
-rw-r--r--. 1 test test unconfined_u:object_r:user_tmpfs_t:s0 0 Aug 11 11:49 /tmp/bar

cp -aZDie Verwendung von oder funktioniert also mv -Zgut, wenn Sicherheitskontexte wichtig sind und trotzdem andere Attribute erhalten bleiben. Ein Skript, das Systemdateien verschiebt, sollte immer die -ZOption für jeden beliebigen cpoder mv-Befehl verwenden, oder andernfalls nur restoreconim letzten Schritt, um unerwartete Probleme zu vermeiden.

Warum diese Unterschiede?

Der mvBefehl behält ein konsistentes Verhalten bei. Wenn es im selben Dateisystem passieren würde, würde natürlich nichts geändert, was an eine Datei angehängt ist, einschließlich ihres Sicherheitskontexts, da es sich nur um eine „Umbenennung“ handelt. Über zwei Dateisysteme hinweg, wo es sich eigentlich um ein Kopieren und dann Löschen handelt, kopiert es aus Konsistenzgründen auch unverändert alles, was an die Datei angehängt ist und was es kennt, einschließlich ihres Sicherheitskontexts.

Der cpBefehl wird standardmäßig nurschaffteine neue Datei, sodass diese Datei wie üblich den Selinux-Kontext des übergeordneten Elements erbt, sofern natürlich nichts anderes mit angegeben wird, --preserve=contextdas in enthalten ist -a. --preserve=contextkann -amit der Option subtrahiert werden -Z, sodass beim Kopieren ganzer Arboreszenzen die beste Option die Verwendung -aZanstelle von ist -a, wenn SELinux eine Rolle spielt.

Standardmäßig erbt diese neue Datei beim Erstellen einer Datei, was der Normalfall ist, ihren Verzeichnis-SELinux-Kontext, deshalb funktioniert alles einwandfrei (Off-Topic: In dem seltenen Fall, dass der Dateikontext sich nur aufgrund einer Regel für seinen Namen vom Kontext seines Verzeichnisses unterscheiden sollte, ist dem Kernel das egal, Programme wie der Daemonrestorecondwird benötigt, um damit umzugehen).

Was ist SELinux

SELinux ist ein obligatorischer Zugriffskontrollmechanismus (auch bekannt alsMAC) wird zusätzlich zu allen anderen Mechanismen verwendet (Unix-Berechtigungen, auch bekannt alsDAC, Zugriffskontrolllisten akaACLusw.). Wenn ein Prozess in einem Prozesssicherheitskontext ausgeführt wird, gibt es eine „Regelmatrix“, um zu überprüfen, ob dieserVerfahrenKontext kann die gewünschte Operation (Öffnen, Lesen, Schreiben, mmap,...) auf demDateiKontext, an dem es zu arbeiten versucht.

Beispiel für den Fall des OP: Wenn dem mysqldProzesskontext nur der Zugriff auf wenige Dateikontexttypen gestattet ist (einschließlich, mysqld_etc_taber nicht ), schlägt user_home_tder Start mysqldfehl, da die Konfigurationsdatei mit dem falschen user_home_tTyp nicht gelesen werden konnte.

Auf normalen Systemen spielt dies für den interaktiven/angemeldeten Benutzer keine Rolle, da sein normaler Prozesskontext nicht eingeschränkt ist und daher keine SELinux-Regel gilt. Jeder Daemon, der von systemdoder anderen ähnlichen Mechanismen gestartet wirdWilleerhält einen Prozesskontext, der mit psder -ZOption von überprüft werden kann. Beispiel auf einem Debian-System mit SELinux:

# ps -Z -p $$
LABEL                             PID TTY          TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 22498 pts/7 00:00:00 bash
# ps -Z -p $(pidof /sbin/getty)
LABEL                             PID TTY      STAT   TIME COMMAND
system_u:system_r:getty_t:s0     6158 tty1     Ss+    0:00 /sbin/getty 38400 tty1
system_u:system_r:getty_t:s0     6159 tty2     Ss+    0:00 /sbin/getty 38400 tty2
system_u:system_r:getty_t:s0     6160 tty3     Ss+    0:00 /sbin/getty 38400 tty3
system_u:system_r:getty_t:s0     6161 tty4     Ss+    0:00 /sbin/getty 38400 tty4
system_u:system_r:getty_t:s0     6162 tty5     Ss+    0:00 /sbin/getty 38400 tty5
system_u:system_r:getty_t:s0     6163 tty6     Ss+    0:00 /sbin/getty 38400 tty6

Antwort2

Ja, es gibt einen grundsätzlichen Unterschied:

  • cp macht eine Kopie der Datei
  • mv (wenn Sie innerhalb des Dateisystems bleiben) verschiebt nur einige Zeiger auf der Festplatte.

Versuche Folgendes:

touch a
ls -i a
cp a b
ls -i a b
mv a c
ls -i b c

Sie werden sehen, dass b eine neue Datei mit einer neuen Inode-Nummer ist, während c lediglich dieselbe Datei mit der Inode-Nummer des alten a ist.

Das erklärt jedoch nicht Ihr seltsames Verhalten.

Antwort3

Das ist wasMaipassieren könnte (Sie geben nur sehr wenige Informationen über die Anwendung oder diese Fehler weiter, daher kann ich nur raten).

Unter Linuxobligatorische Dateisperre ist ungewöhnlich. Anrufe wieflock(2)verwaltenberatendSperren. Das bedeutet, dass der Kernel die Sperren verfolgt, sie aber nicht erzwingt. Es ist Sache der Anwendungen, sie zu befolgen.

Wenn etwas gesperrt wird fileAund Ihre Anwendung die Sperre beachtet, kann sie den Dienst verweigern. Nehmen wir an, dass dies der Fall ist.

Die Sperre betrifft den Inode und nicht den Pfad oder Namen. Das Verschieben (Umbenennen) der gesperrten fileADatei fileBinnerhalb eines einzelnen Dateisystems hat keine Auswirkungen auf den Inode. Die Datei ist weiterhin gesperrt und die Anwendung weigert sich weiterhin, damit zu arbeiten. Durch das Kopieren der Datei wird ein separater fileBInode mit eigenem, nicht gesperrtem Inode erstellt. Die Anwendung funktioniert.

(Hinweis: Das Verschieben einer Datei in ein anderes Dateisystem ist tatsächlich ein Kopieren+Löschen und sollte daher die Sperre (sofern vorhanden) aufheben.)

verwandte Informationen