Что делать, если я случайно запускаю команду «chmod -R» в системных каталогах (/, / etc, ...)

48

Я случайно побежал

sudo chmod 755 -R /

вместо

sudo chmod 755 -R ./

Я остановил его через несколько секунд, но теперь есть некоторые проблемы, такие как

sudo: must be setuid root

Как вернуть права?

    
задан fl00r 18.05.2011 в 15:15
источник

7 ответов

45

Короче: вы не можете, переустановите свою систему.

Я имею в виду, что разрешения Posix используются и сильно зависят от них; существует множество мест в файловой системе, где неправильные разрешения будут нарушать OS (флаги SUID) или даже хуже, сделать ее уязвимой ( /etc/ssh/ssh_host_rsa_key ), пока она работает нормально.

Следовательно, такое восстановление сложно сделать правильно. Мисс одна вещь - и вы ее испортите. Вы уже набрали команду sudo chmod (если это ваш друг , а не вы, она может также изучить урок Linux) - и это очень просто команда. Надлежащее восстановление потребует большего количества команд и более бдительности. Даже если вы используете скрипт какого-то парня.

Так что поверьте мне, просто переустановите. Это безопасная ставка и гарантированно избавит вас от неприятностей.

Наконец, некоторые полезные советы здесь.

Во-первых: переустановки будут менее болезненными, если вы установите ваш /home в отдельный раздел в следующий раз. На самом деле, они будут ветерок.

Во-вторых: рассмотрите сумасшедшую Linux-науку в виртуальной машине , например VirtualBox, и сделайте свои снимки.

В-третьих: работает chmod -R . . Нет необходимости добавлять эту косую черту. Вы могли бы избежать катастрофического риска проскальзывания точки в ожидании.
просто chmod: missing operand after ‘755’ VS разрушенная система.

    
ответ дан ulidtko 18.05.2011 в 15:19
источник
24

Я написал и несколько лет использовал несколько рубиновых скриптов для rsync прав и прав собственности. Скрипт get-filesystem-acl собирает всю информацию путем рекурсивного обхода всех файлов и помещает все это в файл .acl . Скрипт .acl-restore будет читать .acl и применить все chown и chmod .

Вы можете запустить get-filesystem-acl на аналогичной установке Ubuntu, а затем скопировать файл .acl в ваш поврежденный chmod ящик, поместите .acl и .acl-restore в /, и запустите .acl-restore .

Вам понадобится root, чтобы исправить ваш sudo , как предположил Марко Цеппи.

Я могу сгенерировать и предоставить файл .acl для моего 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 18.05.2011 в 16:13
12

Вдолго: вы можете. Вам нужно будет подключить файловую систему с Live CD и начать отмену разрешений в соответствующих местах. Как минимум, чтобы получить sudo назад, вы захотите запустить sudo chmod u+s /usr/bin/sudo , находясь в сеансе LiveCD, - который будет исправлять, должен быть установлен rootuid.

Однако было бы проще просто переустановить систему.

    
ответ дан Marco Ceppi 18.05.2011 в 15:50
3

(Я знаю, что не должен комментировать ответ, но недостаточно репутации для комментариев.)

Ответ на

blade19899 работал для меня, за исключением символических ссылок. Например. он применил 755 к / bin / bash, но затем применил 777 к symlink / bin / rbash, эффективно 777-ing / bin / bash.

Поскольку у меня уже был файл fileper.log, я просто изменил команду назначения-конца:

while IFS=: read -r -d '' perm file; do  
    if [[ ! -L "$file" ]]; then    
        chmod "$perm" "$file"
    fi
done < /tmp/fileper.log 
    
ответ дан Marjan 21.07.2016 в 12:38
3

Я попытался бы переустановить все пакеты с apt-get install --reinstall , возможно, используя вывод dpkg --get-selections | grep install , чтобы получить список из них.

    
ответ дан Adam Byrtek 18.05.2011 в 15:59
3

Хорошо, я не тестировал это (так используйте на свой страх и риск), но он все равно может работать. Я проведу это на виртуальной машине, когда у меня появится возможность:

Во-первых, в неподвижной рабочей системе я сделал следующее, чтобы получить все права доступа к файлам в списке, пропустив каталог /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

Это приведет к печати разрешений и имени файла для каждого файла или каталога в системе, за которым следует символ fileper.log (это необходимо позже, чтобы иметь дело с такими странными именами файлов, как те, которые содержат новые строки).

Затем в системе, где права доступа к файлу были скомпрометированы:

%pr_e%

Это будет читать каждую строку $perm , сохраняя разрешения как $file и имя файла как fileper.log , а затем установит разрешения файла (или каталога) на все, что было указано в /tmp/fileper.log

Несколько вещей, чтобы отметить здесь:

  • При выводе в файл: / вы можете указать пользовательские настройки, proc и т. д.
  • вы не сможете загружать или запускать команды,

Что я хотел бы предложить, загрузите LiveCD с версией Linux на вашем диске, запустите команду, измените путь туда, где у вас установлен локальный диск, и запустите вторую команду!

Я тестировал, что при загрузке с компакт-диска Ubuntu я могу выбрать не форматировать диск, то есть он заменит все в каталоге /home/ , НО пропустим каталог chmod , Это означает, что ваши пользователи будут иметь конфигурацию приложений / DATA (музыка, видео, документы), которые все еще не повреждены. И, заменив системные файлы, %co_de% установлено на нужный номер.

    
ответ дан blade19899 11.05.2016 в 22:37
2

Вы можете попробовать восстановить разрешения с помощью apt-get .

Если вы не можете запускать эти команды с помощью sudo, вам может потребоваться загрузить в режим восстановления и запустить их как root.

Для загрузки в режим восстановления см. Ссылка .

От Ссылка

Примечание. Это было первоначально опубликовано на форумах Ubuntu, но я не могу найти исходное сообщение.

Попробуйте, в порядке,

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

Если это не удается:

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

И наконец, в крайнем случае,

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

Использование apt-get

Вот соответствующий снип, EDITED FOR CORRECTNESS и переформатированный:

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.

    
ответ дан Panther 24.08.2017 в 20:42