Et si j'exécutais accidentellement la commande “chmod -R” sur les répertoires système (/, / etc,…)

49

J'ai accidentellement couru

sudo chmod 755 -R /

au lieu de

sudo chmod 755 -R ./

Je l'ai arrêté après quelques secondes, mais il y a maintenant des problèmes tels que

sudo: must be setuid root

Comment puis-je rétablir les autorisations?

    
posée fl00r 18.05.2011 - 15:15
la source

7 réponses

47

En bref: vous ne pouvez pas, réinstallez votre système.

Je veux dire, les autorisations Posix sont utilisées et sont largement utilisées; Il existe une multitude d'endroits dans le système de fichiers où de mauvaises autorisations briseraient le système d'exploitation (indicateurs SUID) ou, pire encore, le rendraient exposé du point de vue de la sécurité ( /etc/ssh/ssh_host_rsa_key ) alors qu'il semblait fonctionner correctement.

Par conséquent, une telle récupération est difficile à réaliser correctement. Mlle une chose - et vous la ratez. Vous avez déjà foiré votre commande sudo chmod (si c'est votre ami plutôt que vous, elle pourrait aussi bien apprendre une leçon sur Linux) - et c'est très simple: une commande. Une récupération adéquate exigerait beaucoup plus de commandes et beaucoup plus de vigilance. Même si vous utilisez le script d'un type.

Alors faites-moi confiance, réinstallez-le simplement. C’est une valeur sûre et une garantie de vous éviter des ennuis.

Enfin, quelques conseils pertinents ici.

Premièrement: les réinstallations seront moins pénibles si vous configurez votre /home sur une partition séparée la prochaine fois. En fait, ils seront un jeu d'enfant.

Deuxièmement: envisagez de faire une folle science Linux dans une machine virtuelle comme la VirtualBox, et faites vos clichés.

Troisième: chmod -R . fonctionne. Il n'y a pas vraiment besoin d'ajouter cette barre oblique. Vous auriez pu éviter le risque catastrophique de sauter le point complètement;
simple chmod: missing operand after ‘755’ VS un système en ruine.

    
réponse donnée ulidtko 18.05.2011 - 15:19
la source
24

J'ai écrit et utilise depuis plusieurs années deux scripts Ruby pour rsync les autorisations et la propriété. Le script get-filesystem-acl collecte toutes les informations en parcourant tous les fichiers de manière récursive et les met toutes dans le fichier .acl . Le script .acl-restore lira .acl et appliquera tous les chown et chmod .

Vous pouvez exécuter get-filesystem-acl sur une installation similaire sous Ubuntu, puis copier le fichier .acl dans votre boîte endommagée par chmod, insérer .acl et .acl-restore dans / et exécuter .acl-restore .

Vous aurez besoin de root pour corriger votre sudo comme suggéré par Marco Ceppi.

Je peux générer et vous donner le fichier .acl pour mon 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
    
réponse donnée Aleksandr Levchuk 18.05.2011 - 16:13
la source
12

En long: vous pouvez. Vous devez monter le système de fichiers à partir d'un Live CD et commencer à rétablir les autorisations aux emplacements appropriés. Au minimum, pour récupérer sudo, vous voudrez exécuter sudo chmod u+s /usr/bin/sudo lorsque vous êtes dans la session LiveCD - cela résoudra le problème doit être setuid root.

Cependant, il serait probablement plus facile de réinstaller simplement le système.

    
réponse donnée Marco Ceppi 18.05.2011 - 15:50
la source
3

Je voudrais essayer de réinstaller tous les paquets avec apt-get install --reinstall , en utilisant éventuellement la sortie de dpkg --get-selections | grep install pour en obtenir la liste.

    
réponse donnée Adam Byrtek 18.05.2011 - 15:59
la source
3

D'accord, je n'ai pas testé cela (utilisez-le à vos risques et périls), mais cela pourrait quand même fonctionner. Je vais tester cela sur une machine virtuelle lorsque je pourrai:

Tout d'abord, dans un système toujours en activité, j'ai procédé comme suit pour obtenir toutes les autorisations de fichiers d'une liste, en ignorant le répertoire /home/ :

sudo find / -not -path /home -printf "%m:%p
while IFS=: read -r -d '' perm file; do  
    chmod "$perm" "$file"
done < /tmp/fileper.log 
" > /tmp/fileper.log

Ceci imprimera les permissions et le nom de fichier de chaque fichier ou répertoire du système, suivis du caractère fileper.log (requis ultérieurement pour traiter les noms de fichiers étranges tels que ceux contenant des nouvelles lignes).

Ensuite, sur un système où les autorisations de fichiers ont été compromises:

sudo find / -not -path /home -printf "%m:%p
while IFS=: read -r -d '' perm file; do  
    chmod "$perm" "$file"
done < /tmp/fileper.log 
" > /tmp/fileper.log

Ceci lira chaque ligne de $perm , en enregistrant les autorisations en tant que $file et le nom du fichier en tant que fileper.log , puis définira les autorisations du fichier (ou du répertoire) sur celles répertoriées dans la liste /tmp/fileper.log

Quelques points à noter ici:

  • Lors de la sortie dans le fichier: / , vous pouvez peut-être lister les paramètres personnalisés, proc, etc.
  • vous ne pourrez peut-être pas démarrer ou exécuter des commandes,

Ce que je suggérerais est de démarrer un LiveCD avec la version Linux que vous avez sur votre disque, exécutez la commande, modifiez le chemin d'accès sur lequel vous avez monté le disque local et exécutez la deuxième commande!

J'ai testé le fait que, une fois démarré à partir d'un CD / USB Ubuntu, je peux choisir de ne pas formater le disque, ce qui signifie qu'il remplacera tout le répertoire /home/ . BUT ignore le répertoire chmod . . Cela signifie que la configuration des applications / DATA (musique, vidéo, documents) de vos utilisateurs sera toujours intacte. Et en remplaçant les fichiers système, %code% est défini sur le numéro approprié.

    
réponse donnée blade19899 11.05.2016 - 22:37
la source
3

(Je sais que je ne devrais pas commenter dans une réponse, mais pas assez de réputation pour commenter.)

La réponse de blade19899 a fonctionné pour moi à l'exception des liens symboliques. Par exemple. il a appliqué 755 à / bin / bash, mais a ensuite appliqué 777 au lien symbolique / bin / rbash, ce qui signifie 777-ing / bin / bash.

Comme j'avais déjà le fichier fileper.log, je viens de modifier la commande destination-end:

while IFS=: read -r -d '' perm file; do  
    if [[ ! -L "$file" ]]; then    
        chmod "$perm" "$file"
    fi
done < /tmp/fileper.log 
    
réponse donnée Marjan 21.07.2016 - 12:38
la source
2

Vous pouvez essayer de restaurer les autorisations avec apt-get .

Si vous ne pouvez pas exécuter ces commandes avec sudo, vous devrez peut-être démarrer en mode de récupération et les exécuter en tant que root.

Pour démarrer en mode de récupération, voir le lien .

De lien

Remarque: ceci a été initialement publié sur les forums Ubuntu mais je ne trouve pas le message original.

Essayez, dans l'ordre,

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

Si cela échoue:

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

Et enfin, en dernier recours,

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

Utiliser apt-get

Voici le morceau pertinent, édité pour une correction et reformaté:

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

Let's say you get messages about some packages that can't be reinstalled, and the command fails. Here's one way to fix it by skipping the packages in question:

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

And finally, if you should somehow have so many things installed that the above command fails saying your argument list is too long, here's the fix, which will run apt-get many more times than you might like:

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

Note the -y and --force-yes options, which will stop apt-get from prompting you over and over again. These are always fun options, if you're sure you know what you're doing.

    
réponse donnée Panther 24.08.2017 - 20:42
la source

Lire d'autres questions sur les étiquettes