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

56

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?

fl00r
la source
18
oh cher ... sudoça veut dire que tu as réfléchi à deux fois à ce que tu vas faire!
Antivirtel
2
Le plus simple est de le réinstaller. Mettez le LiveCD / USB, et à l'écran où il vous demande de partitionner votre disque, il devrait vous donner la possibilité de Upgrade from Ubuntu 11.04 to Ubuntu 11.04. Acceptez cette option, et cela réinstallera efficacement Ubuntu pour vous, de la manière la plus simple.
user4124
13
Tout à l'heure, vous avez appris une leçon. Vous n'avez pas besoin d'écrire /à la fin du nom du répertoire pour spécifier le répertoire en tant que cible. C'est une mauvaise habitude , ne le faites pas, jamais ! Le .nom de répertoire est par lui-même valide, il n'est pas nécessaire de l'ajouter /. Si tout le monde suivait cette règle, de nombreuses sudoopérations mal typées n'auraient aucun effet sur le répertoire racine et ne causeraient donc aucun dommage à leurs systèmes. Ne le fais pas!
ulidtko
3
@ fl00r, oui. C'est un nom de répertoire qui signifie ceci, ou le répertoire "courant". cd ., par exemple, ne fait rien. ls .est le même que ls. En outre, le ..est un nom de répertoire qui signifie "le parent de .", et vous le saviez probablement déjà.
Ulidtko
2
@ulidtko: Il existe une exception pour ne pas utiliser /à la fin. Si vous voulez développer le chemin d'accès uniquement pour les répertoires. Exemple de listage de répertoires dans le répertoire en cours:echo */
pabouk

Réponses:

57

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é en termes de sécurité ( /etc/ssh/ssh_host_rsa_key) alors qu'il semblait fonctionner correctement.

Par conséquent, une telle reprise est difficile à faire correctement. Manquer une chose - et vous bousiller. Vous avez déjà foiré votre sudo chmodcommande (si c'est votre amie plutôt que vous, elle pourrait aussi bien apprendre une leçon sur Linux) - et c'est une commande très simple. 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 configurez la/home prochaine fois sur une partition séparée . En fait, ils seront un jeu d'enfant.

Deuxièmement: envisagez de faire de la science folle sous Linux sur une machine virtuelle telle que la VirtualBox et réalisez vos instantanés.

Troisièmement: chmod -R .fonctionne. Un point seul .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;
simple chmod: missing operand after ‘755’VS un système en ruine.

Ulidtko
la source
1
Ahhh :) si triste.
fl00r à 13h21
14
Vous pouvez obtenir toutes les autorisations pour chaque fichier d'un autre système, mais cela représente tellement de travail qu'il serait probablement plus facile et plus sûr de le réinstaller.
Oli
2
Et ne sois pas triste! De grands pouvoirs
entraînent de
Oui, je viens de détruire mon ordinateur portable avec ça ... C'est incroyable de voir comment vous pouvez facilement détruire une machine sous Linux.
amanuel2
@ amanuel2 avec un grand pouvoir vient une grande responsabilité. Regardez ce que vous tapez. sudosignifie que vous devez vérifier deux fois.
ulidtko
26

J'ai écrit et utilise depuis plusieurs années deux ou trois scripts Ruby pour les rsyncpermissions et la propriété. Script get-filesystem-aclcollecte toutes les informations en parcourant tous les fichiers de manière récursive et les met toutes dans le fichier .acl. Le script .acl-restorelira .aclet appliquera tous les chown'et chmod'.

Vous pouvez exécuter get-filesystem-aclune installation Ubuntu similaire, puis copier le .aclfichier dans votre boîte endommagée par chmod, y mettre .aclet .acl-restoredans /, puis exécuter .acl-restore.

Vous aurez besoin de root pour corriger votre problème sudocomme l'a suggéré Marco Ceppi.

Je peux générer et vous donner le .aclfichier 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
Aleksandr Levchuk
la source
Ubuntu 11.04. Mais je l'ai déjà réinstallé. Merci!
fl00r
votre script échoue car il owner_idest indéfini
Eliran Malka
8
un peu exagéré ... la recherche ne le fait-elle pas très bien:find SOME_DIR -depth -printf 'chmod %m %p\n' > saved_permission
reflog
12

En long: tu peux. Vous devez monter le système de fichiers à partir d'un Live CD et commencer à rétablir les autorisations aux emplacements appropriés. Au moins pour récupérer sudo, vous voudrez vous lancer sudo chmod u+s /usr/bin/sudopendant la session LiveCD - cela corrigera le paramètre doit être setuid root.

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

Marco Ceppi
la source
4

J'essayerais de réinstaller tous les paquets avec apt-get install --reinstall, en utilisant éventuellement le résultat de dpkg --get-selections | grep installpour en obtenir une liste.

Adam Byrtek
la source
Ce n'est pas une mauvaise idée, mais vous devez exclure les éléments installés automatiquement ou vous retrouver définitivement avec ces packages (même si vous supprimez les packages dépendants) ... Mais ils ne seront pas réinstallés. Dur. Vous obtiendrez peut-être d'abord une liste des paquets automatiques, puis réinstallez chaque paquet, puis parcourez la liste des voitures en les marquant de nouveau comme étant auto.
Oli
@ Oli - (certains) problèmes ne seraient-ils pas résolus en courant sudo apt-get autoremove?
Wilf
@Wilf Non - autoremovesupprime uniquement les packages que vous n'avez pas installés manuellement.
Dmitry Grigoryev Le
Il existe apt-mark auto $pkg/ apt-mark manual $pkgqui vous permet de modifier le statut de "installé manuellement / installé automatiquement" par paquet.
Ulidtko
3

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 fait ce qui suit pour obtenir toutes les autorisations de fichiers d’une liste, en ignorant le /home/répertoire:

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 d'un \0caractère (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 $permet le nom du fichier en tant que $file, puis définira les autorisations du fichier (ou du répertoire) sur ce qui était répertorié dans la liste.fileper.log


Quelques points à noter ici:

  • Lors de la sortie dans le fichier:, /tmp/fileper.logvous 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 remplacera tout ce qui se trouve dans le /répertoire, MAIS ignorer le /home/répertoire. 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 chmodest réglé sur le numéro approprié.

lame19899
la source
1
Pourquoi chmod $(echo $LINE)au lieu de juste chmod $LINE? , Vous pouvez également utiliser simplement findsans stat: find … -printf "%#m %p\n". Mieux encore, vous pouvez créer la commande entière:, find … -printf "chmod %#m %p\n"puis exécutez le fichier en tant que script.
muru
La ligne de recherche ne fonctionne pas telle quelle, elle devrait l'être michael@NEXUS-TWO:~$ sudo find / -name '*' -exec stat -c "%a %n" {} \; >> /tmp/fileper.logmais elle passe également par-dessus /procet d'autres endroits que vous ne souhaitez peut-être pas inclure dans votre liste.
Videonauth
@muru a écrit ceci au milieu de la nuit. Va éditer le code ...
blade19899
Pas en mesure de tester, comptera sur l'utilisateur
blade19899
2

(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 a pour effet 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 
Marjan
la source
Si vous avez une sauvegarde des autorisations, pourquoi ne pas simplement faire une sauvegarde complète et la restaurer en cas de besoin? Cela vous épargnerait en cas d’exécution accidentelle d’une commande, et pas seulement chmod.
Dmitry Grigoryev Le
> ... effectively 777-ing /bin/bash- Nope; ça ne fonctionne pas comme ça. Voulez-vous dire que je peux remplacer /usr/bin/aptmon propre compte en tant qu'utilisateur non root , simplement en lui écrivant via un lien symbolique 777? :) Exercez un peu de pensée critique; Les liens symboliques ne peuvent pas fonctionner et ne fonctionnent pas de cette façon. 777 autorisations pour les liens symboliques sont communes et normales.
Ulidtko
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 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 -yet --force-yesoptions, qui arrêteront apt-getde vous demander encore et encore. Ce sont toujours des options amusantes, si vous êtes sûr de savoir ce que vous faites.

Panthère
la source
-3

J'ai eu le même problème, je peux le réparer. Dans mon cas Ubuntu 19.10

Ouvrez votre terminal et tapez ci-dessous un code simple

sudo -i

ouvrez un autre terminal et vérifiez la commande ci-dessous.

sudo apt update
Elavarasan r
la source
1
Comment cela aiderait-il l'utilisateur à résoudre son problème avec des autorisations? Veuillez modifier votre réponse et fournir plus de détails.
Kevin Bowen