¿Qué pasa si ejecuto accidentalmente el comando "chmod -R" en los directorios del sistema (/, / etc, ...)

49

Corrí accidentalmente

sudo chmod 755 -R /

en lugar de

sudo chmod 755 -R ./

Lo detuve después de unos segundos, pero ahora hay algunos problemas como

sudo: must be setuid root

¿Cómo puedo revertir los permisos?

    
pregunta fl00r 18.05.2011 - 13:15

7 respuestas

47

En resumen: no puedes, reinstala tu sistema.

Quiero decir, los permisos de Posix se utilizan y se basan en gran medida; hay una multitud de lugares en el sistema de archivos donde los permisos incorrectos romperían el sistema operativo (indicadores SUID) o, lo que es peor, lo expondrían en términos de seguridad ( /etc/ssh/ssh_host_rsa_key ) mientras parece funcionar bien.

Por lo tanto, tal recuperación es difícil de hacer correctamente. Señorita una cosa - y la arruinas. Ya ya arruinó su comando sudo chmod (si ese es su amigo en lugar de usted, ella también podría aprender alguna lección de Linux), y eso es muy simple un comando. La recuperación adecuada exigiría mucho más comandos y más vigilancia. Incluso si usas el guión de un chico.

Así que confía en mí, simplemente reinstala. Es una apuesta segura y garantizada para mantenerlo fuera de problemas.

Finalmente, algunos consejos relevantes aquí.

Primero: las reinstalaciones serán menos dolorosas si configura tu /home en una partición separada la próxima vez. En realidad, serán una brisa.

Segundo: considera hacer ciencia loca de Linux en una máquina virtual como VirtualBox, y haz tus instantáneas.

Tercero: chmod -R . funciona. No hay necesidad real de añadir esa barra. Podrías haber evitado el catastrófico riesgo de saltear el punto de forma intrínseca; mero chmod: missing operand after ‘755’ VS un sistema arruinado.

    
respondido por el ulidtko 18.05.2011 - 13:19
24

Escribí y he estado utilizando durante varios años un par de scripts de Ruby para rsync de permisos y propiedad. El script get-filesystem-acl recopila toda la información al recorrer recursivamente todos los archivos y la coloca en el archivo .acl . El script .acl-restore leerá .acl y aplicará todos los chown 's y chmod ' s.

Puedes ejecutar get-filesystem-acl en una instalación de Ubuntu similar y luego copiar sobre el archivo .acl a tu caja dañada por chmod, poner .acl y .acl-restore en /, y ejecutar .acl-restore .

Necesitará tener root, así que arregle su sudo como sugirió Marco Ceppi.

Puedo generar y darte el archivo .acl para mi 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
    
respondido por el Aleksandr Levchuk 18.05.2011 - 14:13
12

En largo: puedes. Deberá montar el sistema de archivos desde un Live CD y comenzar a revertir los permisos en los lugares apropiados. Como mínimo, para recuperar sudo, querrá ejecutar sudo chmod u+s /usr/bin/sudo mientras esté en la sesión de LiveCD, lo que solucionará la raíz debe ser setuid.

Sin embargo, es probable que sea más fácil volver a instalar el sistema.

    
respondido por el Marco Ceppi 18.05.2011 - 13:50
3

Intentaría reinstalar todos los paquetes con apt-get install --reinstall , posiblemente utilizando la salida de dpkg --get-selections | grep install para obtener una lista de ellos.

    
respondido por el Adam Byrtek 18.05.2011 - 13:59
3

Está bien, no he probado esto (así que úsalo bajo tu propio riesgo), pero aún así podría funcionar. Voy a probar esto en una máquina virtual cuando tenga la oportunidad de:

Primero, en un sistema que aún funciona, hice lo siguiente para obtener todos los permisos de archivo en una lista, omitiendo el directorio /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

Esto imprimirá los permisos y el nombre de archivo para cada archivo o directorio en el sistema, seguido de un carácter fileper.log (esto se necesitará más adelante para tratar nombres de archivos extraños, como los que contienen nuevas líneas).

Luego, en un sistema donde los permisos de los archivos se han comprometido:

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

Esto leerá cada línea de $perm , guardando los permisos como $file y el nombre del archivo como fileper.log y luego configurará los permisos del archivo (o del directorio) a lo que estaba en la lista en /tmp/fileper.log

Algunas cosas a tener en cuenta aquí:

  • Mientras se envía al archivo: / , es posible que esté enumerando configuraciones personalizadas, y proc, etc.
  • es posible que no puedas iniciar o ejecutar comandos,

Lo que sugiero es que inicie un LiveCD con la versión de Linux que tiene en su disco, ejecute el comando, modifique la ruta donde tiene el disco local montado y ejecute el segundo comando.

He probado que al arrancar desde un CD / USB de Ubuntu, puedo elegir no formatear el disco, lo que significa que reemplazará todo en el directorio /home/ , PERO omita el directorio chmod . Lo que significa que sus usuarios tendrán la configuración de aplicaciones / DATOS (Música, Video, Documentos) aún intacta. Y al reemplazar los archivos del sistema, %code% se establece en el número correcto.

    
respondido por el blade19899 11.05.2016 - 20:37
3

(Sé que no debería comentar en una respuesta, pero no tengo suficiente reputación para comentar).

La respuesta de

blade19899 funcionó para mí a excepción de los enlaces simbólicos. P.ej. aplicó 755 a / bin / bash, pero luego aplicó 777 al enlace simbólico / bin / rbash, efectivamente a 777-ing / bin / bash.

Como ya tenía el archivo fileper.log, acabo de modificar el comando de destino final:

while IFS=: read -r -d '' perm file; do  
    if [[ ! -L "$file" ]]; then    
        chmod "$perm" "$file"
    fi
done < /tmp/fileper.log 
    
respondido por el Marjan 21.07.2016 - 10:38
2

Puedes intentar restaurar los permisos con apt-get .

Si no puede ejecutar estos comandos con sudo, es posible que deba iniciar el modo de recuperación y ejecutarlos como root.

Para iniciar el modo de recuperación, consulte enlace .

De enlace

Nota: Esto se publicó originalmente en los foros de Ubuntu, pero no puedo encontrar la publicación original.

Prueba, en orden,

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

Si eso falla:

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

Y finalmente, como último recurso,

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

Utilizando apt-get

Aquí está el recorte relevante, EDITADO PARA CORREGIR Y reformateado:

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

Supongamos que recibe mensajes sobre algunos paquetes que no se pueden reinstalar, y el comando falla. Aquí hay una forma de solucionarlo omitiendo los paquetes en cuestión:

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

Y finalmente, si de alguna manera debería tener instaladas tantas cosas que el comando anterior falla diciendo que su lista de argumentos es demasiado larga, aquí está la solución, que se ejecutará en apt-get muchas más veces de las que le gustaría:

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

Tenga en cuenta las opciones -y y --force-yes , que detendrán a apt-get para que no se le pregunte una y otra vez. Estas siempre son opciones divertidas, si estás seguro de que sabes lo que estás haciendo.

    
respondido por el Panther 24.08.2017 - 18:42

Lea otras preguntas en las etiquetas