E se avessi accidentalmente eseguito il comando "chmod -R" sulle directory di sistema (/, / etc, ...)


56

Ho corso per caso

sudo chmod 755 -R /

invece di

sudo chmod 755 -R ./

L'ho fermato dopo pochi secondi, ma ora ci sono alcuni problemi come

sudo: must be setuid root

Come posso ripristinare le autorizzazioni?


18
oh caro ... sudosignifica che hai pensato due volte a quello che farai!
antivirtel,

2
Il più semplice è reinstallare. Inserisci LiveCD / USB e nella schermata in cui ti viene chiesto di partizionare il disco, dovrebbe darti la possibilità di farlo Upgrade from Ubuntu 11.04 to Ubuntu 11.04. Accetta questa opzione e reinstalla efficacemente Ubuntu per te, nel modo più indolore.
user4124,

13
Proprio ora hai imparato una lezione. Non è necessario scrivere /alla fine del nome della directory per specificare la directory come destinazione. È una cattiva abitudine , non farlo, mai ! Il .nome della directory è di per sé valido, non è necessario accodarlo /. Se tutti seguissero questa regola, allora molte sudooperazioni errate non avrebbero alcun effetto sulla directory root, quindi nessun danno sarebbe stato fatto ai loro sistemi. Non farlo!
Ulidtko,

3
@ fl00r, sì. È un nome di directory che significa questo, o directory "corrente". cd ., ad esempio, non fa nulla. ls .è lo stesso di ls. Inoltre, ..è un nome di directory che significa "il genitore di ." e probabilmente lo sapevi già.
Ulidtko,

2
@ulidtko: c'è un'eccezione al non utilizzo /alla fine. Se si desidera eseguire l'espansione del nome percorso solo per le directory. Esempio di elenco di directory all'interno della directory corrente:echo */
pabouk,

Risposte:


57

In breve: non è possibile reinstallare il sistema.

Voglio dire, le autorizzazioni Posix sono utilizzate e invocate pesantemente; c'è una moltitudine di posti nel filesystem in cui permessi errati rompono il sistema operativo (flag SUID) o, peggio ancora, lo rendono esposto in termini di sicurezza ( /etc/ssh/ssh_host_rsa_key) mentre sembra funzionare correttamente.

Quindi, un tale recupero è difficile da fare correttamente. Manca una cosa e tu la rovini. Hai già rovinato il tuo sudo chmodcomando (se è la tua amica piuttosto che te, potrebbe anche imparare qualche lezione su Linux) - e questo è un comando molto semplice. Un corretto recupero richiederebbe molti più comandi e molta più vigilanza. Anche se usi la sceneggiatura di qualcuno.

Quindi fidati di me, basta reinstallare. È una scommessa sicura e garantita per tenerti fuori dai guai.


Infine, alcuni suggerimenti rilevanti qui.

Primo: la reinstallazione sarà meno dolorosa se la/home prossima volta configurerai il tuo su una partizione separata . In realtà, saranno un gioco da ragazzi.

Secondo: prendi in considerazione la pazza scienza di Linux in una macchina virtuale come VirtualBox e fai le tue istantanee.

Terzo: chmod -R .funziona. Un punto da solo .è un nome di directory valido. Non è necessario aggiungere quella barra. Avresti potuto evitare il rischio catastrofico di saltare il punto completamente;
semplice chmod: missing operand after ‘755’VS un sistema in rovina.


1
Ahhh :) così triste.
fl00r,

14
Ebbene si poteva da ottenere tutte le autorizzazioni per ogni file da un altro sistema, ma farlo è tanto lavoro che probabilmente sarebbe più facile e sicura solo per reinstallare.
Oli

2
E non essere triste! Da un grande potere derivano grandi responsabilità
ulidtko,

Sì, ho appena distrutto il mio laptop con questo ... Incredibile come puoi facilmente distruggere una macchina basata su Linux.
amanuel2

@ amanuel2 con grande potenza derivano grandi responsabilità. Guarda cosa digiti; sudosignifica che devi controllare due volte.
Ulidtko,

26

Ho scritto e ho usato per diversi anni un paio di script di Ruby per rsyncpermessi e proprietà. Script get-filesystem-aclraccoglie tutte le informazioni attraversando ricorsivamente tutti i file e inserendole tutte nel file .acl. Lo script .acl-restoreleggerà .acle applicherà tutti gli chown"e chmod".

È possibile eseguire get-filesystem-aclun'installazione Ubuntu simile e quindi copiare il .aclfile nella casella danneggiata da chmod, inserire .acle .acl-restorein /, ed eseguire .acl-restore.

Dovrai avere root, quindi aggiusta il tuo sudocome suggeriva Marco Ceppi.

Posso generare e darti il .aclfile per il mio Ubuntu.

get-filesystem-acl

#!/usr/bin/ruby

RM   = "/bin/rm"
SORT = "/usr/bin/sort"
TMP  = "/tmp/get_acl_#{Time.now.to_i}_#{rand * 899 + 100}"

require 'find'

IGNORE = [".git"]

def numeric2human(m)
  return sprintf("%c%c%c%c%c%c%c%c%c",
            (m & 0400 == 0 ? ?- : ?r),
            (m & 0200 == 0 ? ?- : ?w),
            (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
                             (m & 04000 == 0 ? ?x : ?s)),
            (m & 0040 == 0 ? ?- : ?r),
            (m & 0020 == 0 ? ?- : ?w),
            (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
                             (m & 02000 == 0 ? ?x : ?s)),
            (m & 0004 == 0 ? ?- : ?r),
            (m & 0002 == 0 ? ?- : ?w),
            (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
                             (m & 01000 == 0 ? ?x : ?t)))
end


File.open(TMP, "w") do |acl_file|

  # TODO: Instead of the current dir, find the .git dir, which could be
  #       the same or outside of the current dir
  Find.find(".") do |path|

    next if IGNORE.collect {|ig| !!(path[2..-1] =~ /\A#{ig}/)}.include? true
    next if File.symlink?(path)

    stat = File.lstat(path)
    group_id = stat.gid
    rules    = "#{type}#{numeric2human(stat.mode)}" 

    acl_file.puts "#{path} #{rules} #{owner_id} #{group_id}"
  end
end

`#{SORT} #{TMP} > .acl`
`#{RM}   #{TMP}`

.acl-restore

#!/usr/bin/ruby

# This script will only work with .acl_ids

# Restore from...
FROM  = ".acl"

MKDIR = "/bin/mkdir"
CHMOD = "/bin/chmod"
CHOWN = "/bin/chown"
known_content_missing = false


def numeric2human(m)
  return sprintf("%c%c%c%c%c%c%c%c%c",
            (m & 0400 == 0 ? ?- : ?r),
            (m & 0200 == 0 ? ?- : ?w),
            (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
                             (m & 04000 == 0 ? ?x : ?s)),
            (m & 0040 == 0 ? ?- : ?r),
            (m & 0020 == 0 ? ?- : ?w),
            (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
                             (m & 02000 == 0 ? ?x : ?s)),
            (m & 0004 == 0 ? ?- : ?r),
            (m & 0002 == 0 ? ?- : ?w),
            (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
                             (m & 01000 == 0 ? ?x : ?t)))
end

def human2chmod(mode)
  raise unless mode =~ /([r-][w-][xtsTS-])([r-][w-][xtsTS-])([r-][w-][xtsTS-])/
  triple = [$1, $2, $3]
  u,g,o = triple.collect do |i|
    i.sub('s', 'sx').sub('t', 'tx').downcase.gsub('-', '')
  end

  return "u=#{u},g=#{g},o=#{o}" 
end



File.open(FROM).each do |acl|
  raise unless acl =~ /\A(([^ ]*? )+)([^ ]+) ([^ ]+) ([^ ]+)\Z/
  path, rules, owner_id, group_id = $1, $3, $4, $5
  path = path.strip
  owner_id = owner_id.to_i
  group_id = group_id.to_i

  if !File.exists?(path) and !File.symlink?(path)
    if rules =~ /\Ad/
      STDERR.puts "Restoring a missing directory: #{path}"
      STDERR.puts "Probably it was an empty directory. Git goes not track them."
      `#{MKDIR} -p '#{path}'` # Creating the any parents
    else
      known_content_missing = true
      STDERR.puts "ERROR: ACL is listed but the file is missing: #{path}"
      next
    end
  end

  s = File.lstat(path)
  t = s.ftype[0..0].sub('f', '-') # Single character for the file type
                                  # But a "-" istead of "f"

  # Actual, but not neccesarely Desired 
  actual_rules    = "#{t}#{numeric2human(s.mode)}"
  actual_owner_id = s.uid 
  actual_group_id = s.gid 

  unless [actual_rules, actual_owner_id, actual_group_id] ==
    [rules, owner_id, group_id]

    chmod_argument = human2chmod(rules)

    # Debug
    #p chmod_argument
    #p s.mode

    ## Verbose
    puts path
    puts "Wrong: #{[actual_rules, actual_owner_id, actual_group_id].inspect}"
    puts "Fixed: #{[rules, owner_id, group_id].inspect}"
    `#{CHMOD} #{chmod_argument} '#{path}'`

    #puts
  end

end

if known_content_missing
  STDERR.puts "-" * 80 
  STDERR.puts "Some files that are listed in #{FROM.inspect} are missing in " +
              "the current directory."
  STDERR.puts
  STDERR.puts "Is #{FROM.inspect} outdated?"
  STDERR.puts "(Try retrograding the current directory to an earlier version)"
  STDERR.puts
  STDERR.puts "Or is the current directory incomplete?"
  STDERR.puts "(Try to recover the current directory)"
  STDERR.puts "-" * 80 
end

Ubuntu 11.04. Ma l'ho già reinstallato. Grazie!
fl00r,

la tua sceneggiatura fallisce perché non owner_idè definita
Eliran Malka,

8
un po 'eccessivo ... trovare lo fa abbastanza bene:find SOME_DIR -depth -printf 'chmod %m %p\n' > saved_permission
reflog

12

A lungo: puoi. Dovrai montare il file system da un Live CD e iniziare a ripristinare le autorizzazioni nei punti appropriati. Come minimo per riavere sudo ti consigliamo di eseguire sudo chmod u+s /usr/bin/sudomentre sei nella sessione LiveCD - questo risolverà il setuid root necessario.

Tuttavia, sarebbe probabilmente più semplice reinstallare semplicemente il sistema.


4

Vorrei provare a reinstallare tutti i pacchetti con apt-get install --reinstall, possibilmente utilizzando l'output di dpkg --get-selections | grep installper ottenere un elenco di essi.


Questa non è una cattiva idea, ma dovresti escludere le cose che vengono installate automaticamente o finiresti in modo permanente con quei pacchetti (anche se rimossi i pacchetti dipendenti) ... Ma non verrebbero reinstallati. Una difficile. Forse ottenere prima un elenco dei pacchetti automatici, quindi reinstallare ogni pacchetto, quindi scorrere l'elenco delle auto, contrassegnandole nuovamente come auto.
Oli

@Oli - (alcuni) non sarebbero risolti correndo sudo apt-get autoremove?
Wilf,

@Wilf No: autoremoverimuove solo i pacchetti che non sono stati installati manualmente.
Dmitry Grigoryev,

Esistono apt-mark auto $pkg/ apt-mark manual $pkgche consentono di modificare lo stato del pacchetto "installato manualmente / autoinstallato".
Ulidtko,

3

Va bene, non l'ho provato (quindi usalo a tuo rischio e pericolo), ma potrebbe comunque funzionare. Lo testerò in una macchina virtuale quando avrò la possibilità di:

Innanzitutto, in un sistema ancora funzionante, ho fatto quanto segue per ottenere tutte le autorizzazioni per i file in un elenco, saltando la /home/directory:

sudo find / -not -path /home -printf "%m:%p\0" > /tmp/fileper.log

Questo stamperà le autorizzazioni e il nome del file per ciascun file o directory sul sistema, seguito da un \0carattere (questo è necessario in seguito per gestire nomi di file strani come quelli che contengono newline).

Quindi, su un sistema in cui le autorizzazioni dei file sono state compromesse:

while IFS=: read -r -d '' perm file; do  
    chmod "$perm" "$file"
done < /tmp/fileper.log 

Questo leggerà ogni riga di fileper.log, salvando le autorizzazioni come $perme il nome del file come $filee quindi imposterà le autorizzazioni del file (o della directory) su qualsiasi cosa sia elencata nellafileper.log


Alcune cose da notare qui:

  • Durante l'output nel file:, /tmp/fileper.logpotresti elencare le impostazioni personalizzate, proc, ecc.
  • potresti non essere in grado di avviare o eseguire comandi,

Quello che suggerirei è di avviare un LiveCD con la versione di Linux che hai sul tuo disco, eseguire il comando, modificare il percorso in cui hai montato il disco locale ed eseguire il secondo comando!


Ho provato che quando avviato da un CD / USB Ubuntu, posso scegliere di non formattare il disco, il che significa che sostituirà tutto nella /directory, MA salterà la /home/directory. Ciò significa che i tuoi utenti avranno ancora intatta la configurazione di app / DATI (musica, video, documenti). E sostituendo i file di sistema, chmodviene impostato il numero corretto.


1
Perché chmod $(echo $LINE)invece di solo chmod $LINE? Inoltre, è possibile utilizzare solo findsenza stat: find … -printf "%#m %p\n". Meglio ancora, puoi creare l'intero comando find … -printf "chmod %#m %p\n":, quindi eseguire il file come script.
muru,

La linea di ricerca non funziona così com'è, dovrebbe essere, michael@NEXUS-TWO:~$ sudo find / -name '*' -exec stat -c "%a %n" {} \; >> /tmp/fileper.logma anche così passa sopra /proce in altri posti che potresti non desiderare nella tua lista.
Videonauth,

@muru ha scritto questo nel cuore della notte. Modifica il codice ...
blade19899,

Non in grado di testare, si baserà sull'input dell'utente
blade19899,

2

(So ​​che non dovrei commentare in una risposta, ma non abbastanza reputazione per commentare.)

La risposta di blade19899 ha funzionato per me, tranne per i collegamenti simbolici. Ad esempio, ha applicato 755 a / bin / bash, ma poi ha applicato 777 al symlink / bin / rbash, in effetti 777-ing / bin / bash.

Dato che avevo già il file fileper.log, ho appena modificato il comando destination-end:

while IFS=: read -r -d '' perm file; do  
    if [[ ! -L "$file" ]]; then    
        chmod "$perm" "$file"
    fi
done < /tmp/fileper.log 

Se si dispone di un backup delle autorizzazioni, perché non eseguire semplicemente un backup completo e ripristinarlo quando necessario? Ciò ti salverebbe in caso di qualsiasi comando eseguito accidentalmente, non solo chmod.
Dmitry Grigoryev,

> ... effectively 777-ing /bin/bash- no; non è così che funziona. Stai dicendo che posso sostituire le /usr/bin/aptmie cose come utente non root , semplicemente scrivendoci tramite un link simbolico 777? :) Esercita un pensiero critico; i link simbolici non possono e non funzionano in questo modo. 777 autorizzazioni per i collegamenti simbolici sono comuni e normali.
Ulidtko,

2

Puoi provare a ripristinare le autorizzazioni con apt-get.

Se non è possibile eseguire questi comandi con sudo, potrebbe essere necessario avviare la modalità di ripristino ed eseguirli come root.

Per l'avvio in modalità di ripristino, consultare https://wiki.ubuntu.com/RecoveryMode .

Da http://hyperlogos.org/page/Restoring-Permissions-Debian-System

Nota: questo è stato originariamente pubblicato sui forum di Ubuntu ma non riesco a trovare il post originale.

Prova, in ordine,

sudo apt-get --reinstall install `dpkg --get-selections | grep install | grep -v deinstall | cut -f1`

Se fallisce:

sudo apt-get --reinstall install `dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | egrep -v '(package1|package2)'`

E infine, come ultima risorsa,

sudo dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | xargs apt-get --reinstall -y --force-yes install

Usando apt-get

Ecco lo snip pertinente, EDITED FOR CORRECTNESS e riformattato:

sudo apt-get --reinstall install `dpkg --get-selections | grep install | grep -v deinstall | cut -f1`

Supponiamo che tu riceva messaggi su alcuni pacchetti che non possono essere reinstallati e il comando ha esito negativo. Ecco un modo per risolverlo saltando i pacchetti in questione:

sudo apt-get --reinstall install `dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | egrep -v '(package1|package2)'`

E infine, se in qualche modo dovessi aver installato così tante cose che il comando sopra non riesce a dire che l'elenco degli argomenti è troppo lungo, ecco la correzione, che verrà eseguita apt-get molte più volte di quanto potresti desiderare:

sudo dpkg --get-selections | grep install | grep -v deinstall | cut -f1 | xargs apt-get --reinstall -y --force-yes install

Nota le opzioni -ye --force-yes, che non ti apt-getchiederanno più e più volte. Queste sono sempre opzioni divertenti, se sei sicuro di sapere cosa stai facendo.


-3

Ho avuto lo stesso problema, posso risolverlo. Nel mio caso Ubuntu 19.10

Apri il tuo terminale e digita sotto il semplice codice

sudo -i

aprire un altro terminale e controllare sotto il comando.

sudo apt update

1
In che modo ciò aiuterebbe l'utente a risolvere il problema con le autorizzazioni? Modifica la tua risposta e fornisci maggiori dettagli.
Kevin Bowen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.