web-dev-qa-db-fra.com

Et si j'exécute accidentellement la commande "chmod -R" sur les répertoires du système (/, / etc, ...)

J'ai couru accidentellement

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?

56
fl00r

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

Je veux dire, les autorisations Posix sont utilisées et sont largement utilisées; il existe une multitude d'emplacements dans le système de fichiers où de mauvaises autorisations briseraient le système d'exploitation (indicateurs SUID) ou, pire, exposer le système à la sécurité (/etc/ssh/ssh_Host_rsa_key) alors qu'il semble fonctionner correctement.

Par conséquent, une telle reprise est difficile à faire correctement. Mlle une chose - et vous la bousillez. Vous déjà avez foiré votre commande Sudo chmod (si c'est votre ami plutôt que vous, elle pourrait tout aussi bien apprendre une leçon sur Linux ) - et c'est un très simple d'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 de quelqu'un.

Alors faites-moi confiance, il suffit de réinstaller. C'est un pari sûr et garanti pour vous éviter des ennuis.


Enfin, quelques conseils pertinents ici.

Premièrement: les réinstallations seront moins pénibles si vous installez 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 effectuez vos instantanés.

Troisièmement: chmod -R . fonctionne. Un point en lui-même . est un nom de répertoire valide. 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;
pure chmod: missing operand after ‘755’ VS un système en ruine.

56
ulidtko

J'ai écrit et utilise depuis plusieurs années un couple de Ruby scripts pour rsyncpermissions et propriété. 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 chownname __ 'et chmodname __'.

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

Vous aurez besoin de root pour corriger votre Sudocomme Marco Ceppi l’a suggéré.

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
26

En long: tu peux. Vous devez monter le système de fichiers à partir du 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 au cours de la session LiveCD - cela résoudra le doit être setuid root.

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

12
Marco Ceppi

J'essayerais 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 une liste.

4
Adam Byrtek

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

Premièrement, dans un système qui fonctionne toujours, 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\0" > /tmp/fileper.log

Ceci imprimera les permissions et le nom de fichier pour chaque fichier ou répertoire du système, suivis du caractère \0 (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:

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

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


Quelques points à noter ici:

  • Lors de la sortie dans le fichier: /tmp/fileper.log, vous pouvez peut-être lister les paramètres personnalisés, proc, etc.
  • vous pourriez ne pas être en mesure de démarrer ou d'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 à l'emplacement où vous avez le disque local monté et exécutez la deuxième commande!


J'ai testé que lorsque je suis démarré à partir d'un CD/USB Ubuntu, je peux choisir de ne pas formater le disque, ce qui signifie qu'il va tout remplacer dans le répertoire /, MAIS ignorer le répertoire /home/. 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, le chmod est défini sur son numéro approprié.

3
blade19899

(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 est bien 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 
3
Marjan

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 https://wiki.ubuntu.com/RecoveryMode .

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

Note: 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 snip pertinent, édité pour la correction et reformaté:

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

Supposons que vous recevez des messages sur certains packages qui ne peuvent pas être réinstallés et que la commande échoue. Voici un moyen de résoudre ce problème en ignorant les packages en question:

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

Et enfin, si vous avez tellement de choses installées que la commande ci-dessus ne dit pas que votre liste d'arguments est trop longue, voici le correctif, qui lancera apt-get bien plus que vous ne le voudriez:

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

Notez les options -y et --force-yes, qui empêchent apt-get de vous inviter encore et encore. Ce sont toujours des options amusantes, si vous êtes sûr de savoir ce que vous faites.

2
Panther

Beaucoup de réponses sont problématiques car elles nécessitent Sudoname__, mais Sudoest cassé. Vous ne pouvez pas utiliser Sudopour corriger Sudoname__. D'autres réponses nécessitent de redémarrer l'ordinateur à l'aide d'un Live CD ou d'un mode de récupération, ce qui est peu pratique.

Une autre option consiste à utiliser pkexecpour accéder à un shell avec des droits root.

  1. Exécutez pkexec bash dans un terminal pour obtenir un shell avec des autorisations root.

  2. Définissez le bit setuid:

    chmod u+s /usr/bin/Sudo
    
  3. Sudodevrait maintenant être disponible pour toute réparation supplémentaire éventuellement nécessaire.

0
xiota