Co jeśli przypadkowo uruchomię polecenie „chmod -R” w katalogach systemowych (/, / etc,…)

56

Przypadkowo pobiegłem

sudo chmod 755 -R /

zamiast

sudo chmod 755 -R ./

Zatrzymałem go po kilku sekundach, ale teraz są pewne problemy, takie jak

sudo: must be setuid root

Jak mogę przywrócić uprawnienia z powrotem?

fl00r
źródło
18
o mój drogi ... sudooznacza, że dwukrotnie zastanowiłeś się, co zrobisz!
antivirtel
2
Najłatwiej jest ponownie zainstalować. Umieść LiveCD / USB, a na ekranie, na którym pojawi się prośba o podzielenie dysku, powinna dać ci taką możliwość Upgrade from Ubuntu 11.04 to Ubuntu 11.04. Zaakceptuj tę opcję, aby skutecznie i bezboleśnie ponownie zainstalować dla ciebie Ubuntu.
user4124
13
Właśnie nauczyłeś się lekcji. Nie musisz pisać /na końcu nazwy katalogu, aby określić katalog jako cel. To zły nawyk , nie rób tego, nigdy ! Jest .to sama poprawna nazwa katalogu, nie ma potrzeby dołączania /do niej. Gdyby wszyscy przestrzegali tej zasady, wówczas bardzo źle wpisane sudooperacje nie miałyby wpływu na katalog główny, więc ich systemy nie wyrządziłyby szkody. Nie rób tego!
ulidtko
3
@ fl00r, tak. Jest to nazwa katalogu, co oznacza ten lub „bieżący” katalog. cd .na przykład nic nie robi. ls .jest taki sam jak ls. Ponadto, ..jest to nazwa katalogu, co oznacza „rodzica .”, i prawdopodobnie znał go już.
ulidtko
2
@ulidtko: Istnieje wyjątek od nieużywania /na końcu. Jeśli chcesz zrobić rozszerzenie nazwy ścieżki tylko dla katalogów. Przykład umieszczenia katalogów w bieżącym katalogu:echo */
pabouk

Odpowiedzi:

57

Krótko mówiąc: nie możesz ponownie zainstalować systemu.

Mam na myśli, że uprawnienia Posix są używane i są w dużej mierze oparte; w systemie plików jest wiele miejsc, w których nieprawidłowe uprawnienia mogłyby uszkodzić system operacyjny (flagi SUID) lub, co gorsza, spowodować, że będzie narażony na bezpieczeństwo ( /etc/ssh/ssh_host_rsa_key), podczas gdy wydaje się, że działa poprawnie.

Dlatego takie odzyskanie jest trudne do prawidłowego wykonania. Tęsknisz za jedną rzecz - a ty spieprzysz to. Ty już nie przejmował się swoją sudo chmodkomendę (jeśli to twój przyjaciel raczej niż ty, może ona także nauczyć się lekcji Linux, zbyt) - i to jest bardzo proste polecenia. Prawidłowe wyleczenie wymagałoby znacznie większej liczby poleceń i większej czujności. Nawet jeśli używasz czyjś skrypt.

Zaufaj mi, po prostu zainstaluj ponownie. Jest to bezpieczny zakład, który gwarantuje, że unikniesz kłopotów.


Na koniec kilka istotnych wskazówek tutaj.

Po pierwsze: ponowna instalacja będzie mniej bolesna, jeśli następnym razem skonfigurujesz swoją /homepartycję na osobnej partycji . W rzeczywistości będą łatwe.

Po drugie: rozważ zrobienie szalonej nauki o Linuksie na maszynie wirtualnej, takiej jak VirtualBox, i rób migawki.

Po trzecie: chmod -R .działa. Sama kropka .jest prawidłową nazwą katalogu. Nie ma potrzeby dołączania tego slasha. Mogłeś uniknąć katastrofalnego ryzyka pominięcia kropki w całości;
zwykły chmod: missing operand after ‘755’VS zrujnowany system.

ulidtko
źródło
1
Ahhh :) takie smutne.
fl00r
14
Dobrze mógł dostając wszystkie uprawnienia dla każdego pliku z innego systemu, ale robi to tak dużo pracy, że że to prawdopodobnie łatwiej i bezpieczniej po prostu przeinstalować.
Oli
2
I nie smuć się! Z wielką mocą wiąże się wielka odpowiedzialność
ulidtko
Tak, właśnie zniszczyłem mojego laptopa tym ... Niesamowite, jak możesz łatwo zniszczyć maszynę z systemem Linux.
amanuel2
@ amanuel2 z wielką mocą wiąże się z wielką odpowiedzialnością. Zobacz, co piszesz; sudooznacza, że ​​musisz sprawdzić dwa razy.
ulidtko
26

Napisałem i używam od kilku lat kilku skryptów Ruby do rsyncuprawnień i własności. Skrypt get-filesystem-aclzbiera wszystkie informacje, rekurencyjnie przechodząc przez wszystkie pliki i umieszczając je w pliku .acl. Skrypt .acl-restoreodczyta .acli zastosuje wszystkie chown„i chmod”.

Możesz uruchomić get-filesystem-aclpodobną instalację Ubuntu, a następnie skopiować .aclplik do skrzynki uszkodzonej przez chmod, umieścić .acli .acl-restorew /, i uruchomić .acl-restore.

Musisz mieć root, więc napraw swoje, sudojak sugerował Marco Ceppi.

Mogę wygenerować i dać .aclplik dla mojego 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
źródło
Ubuntu 11.04. Ale już go przeinstalowałem. Dzięki!
fl00r
twój skrypt kończy się niepowodzeniem, ponieważ nie owner_idjest zdefiniowany
Eliran Malka
8
trochę przesada ... znalezisko robi to całkiem ładnie:find SOME_DIR -depth -printf 'chmod %m %p\n' > saved_permission
reflog
12

W dłuższej perspektywie: możesz. Musisz zamontować system plików z Live CD i zacząć cofać uprawnienia w odpowiednich miejscach. Przynajmniej, aby odzyskać sudo, będziesz chciał uruchomić sudo chmod u+s /usr/bin/sudopodczas sesji LiveCD - to naprawi roota setuid.

Prawdopodobnie łatwiej byłoby po prostu ponownie zainstalować system.

Marco Ceppi
źródło
4

Spróbowałbym ponownie zainstalować wszystkie pakiety za pomocą apt-get install --reinstall, prawdopodobnie używając danych wyjściowych z, dpkg --get-selections | grep installaby uzyskać ich listę.

Adam Byrtek
źródło
To nie jest zły pomysł, ale musisz wykluczyć rzeczy, które są automatycznie instalowane lub na stałe skończysz z tymi pakietami (nawet jeśli usuniesz pakiety zależne) ... Ale wtedy nie zostaną ponownie zainstalowane. Trudny. Być może najpierw otrzymam listę automatycznych pakietów, następnie ponownie zainstaluj każdy pakiet, a następnie przejrzyj listę aut, oznaczając je ponownie jako automatyczne.
Oli
@Oli - czy (niektórych) nie można rozwiązać, uruchamiając sudo apt-get autoremove?
Wilf
@Wilf Nie - autoremoveusuwa tylko pakiety, które nie zostały zainstalowane ręcznie.
Dmitrij Grigoriew
Istnieją apt-mark auto $pkg/, apt-mark manual $pkgktóre pozwalają modyfikować status „ręcznie zainstalowanego / automatycznie zainstalowanego” dla pakietu.
ulidtko
3

W porządku, nie testowałem tego (więc używaj na własne ryzyko), ale nadal może działać. Przetestuję to na maszynie wirtualnej, gdy mam szansę:

Po pierwsze, w wciąż działającym systemie zrobiłem następujące czynności, aby uzyskać wszystkie uprawnienia do plików na liście, pomijając /home/katalog:

sudo find / -not -path /home -printf "%m:%p\0" > /tmp/fileper.log

Spowoduje to wydrukowanie uprawnień i nazwy pliku dla każdego pliku lub katalogu w systemie, a następnie \0znaku (jest to potrzebne później, aby poradzić sobie z dziwnymi nazwami plików, takimi jak te zawierające nowe wiersze).

Następnie w systemie, w którym naruszono uprawnienia do plików:

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

Spowoduje to odczytanie każdego wiersza fileper.log, zapisanie uprawnień jako $permi nazwy pliku jako, $filea następnie ustawi uprawnienia pliku (lub katalogu) na wszystko, co było wymienione wfileper.log


Kilka rzeczy do odnotowania tutaj:

  • Podczas wysyłania do pliku: /tmp/fileper.logmożesz wyświetlać ustawienia niestandardowe, proc itp.
  • możesz nie być w stanie uruchomić lub uruchomić poleceń,

Sugeruję, aby uruchomić LiveCD z wersją Linuksa, którą masz na dysku, uruchomić polecenie, zmodyfikować ścieżkę do miejsca, w którym jest podłączony dysk lokalny, i uruchomić drugie polecenie!


Przetestowałem, że po uruchomieniu z Ubuntu CD / USB mogę nie formatować dysku, co oznacza, że ​​zastąpi wszystko w /katalogu, ALE pominie /home/katalog. Oznacza to, że użytkownicy będą mieć nienaruszoną konfigurację aplikacji / danych (muzyka, wideo, dokumenty). I zastępując pliki systemowe, chmodustawia się tam odpowiedni numer.

blade19899
źródło
1
Dlaczego chmod $(echo $LINE)zamiast tylko chmod $LINE? Ponadto, można użyć tylko findbez stat: find … -printf "%#m %p\n". Jeszcze lepiej, możesz utworzyć całe polecenie find … -printf "chmod %#m %p\n":, a następnie wykonać plik jako skrypt.
muru
Linia wyszukiwania nie działa tak, jak jest, powinna być, michael@NEXUS-TWO:~$ sudo find / -name '*' -exec stat -c "%a %n" {} \; >> /tmp/fileper.logale równie dobrze biegnie /proci inne miejsca, których możesz nie chcieć na liście.
Videonauth,
@muru napisał to w środku nocy.
Zmodyfikuje
Nie można przetestować, będzie polegać na danych wejściowych użytkownika
blade19899
2

(Wiem, że nie powinienem komentować odpowiedzi, ale nie mam wystarczającej reputacji, aby komentować).

Odpowiedź blade19899 działała dla mnie z wyjątkiem dowiązań symbolicznych. Np. Zastosował 755 do / bin / bash, ale następnie zastosował 777 do dowiązania symbolicznego / bin / rbash, skutecznie 777-ing / bin / bash.

Ponieważ miałem już plik fileper.log, właśnie zmodyfikowałem polecenie destination-end:

while IFS=: read -r -d '' perm file; do  
    if [[ ! -L "$file" ]]; then    
        chmod "$perm" "$file"
    fi
done < /tmp/fileper.log 
Marjan
źródło
Jeśli masz kopię zapasową uprawnień, dlaczego nie zrobić pełnej kopii zapasowej i przywrócić ją w razie potrzeby? To by cię uratowało w przypadku przypadkowego uruchomienia polecenia, nie tylko chmod.
Dmitrij Grigoriew
> ... effectively 777-ing /bin/bash- nie; nie tak to działa. Czy mówisz, że mogę zastąpić /usr/bin/aptwłasną rzeczą jako użytkownik inny niż root , pisząc do niej za pomocą dowiązania symbolicznego 777? :) Ćwicz krytyczne myślenie; dowiązania symboliczne nie mogą i nie działają w ten sposób. 777 uprawnień do dowiązań symbolicznych jest wspólne i normalne.
ulidtko
2

Możesz spróbować przywrócić uprawnienia za pomocą apt-get.

Jeśli nie możesz uruchomić tych poleceń za pomocą sudo, może być konieczne uruchomienie systemu w trybie odzyskiwania i uruchomienie ich jako root.

Aby uruchomić system w trybie odzyskiwania, zobacz https://wiki.ubuntu.com/RecoveryMode .

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

Uwaga: pierwotnie został opublikowany na forach Ubuntu, ale nie mogę znaleźć oryginalnego postu.

Spróbuj w kolejności

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

Jeśli to się nie powiedzie:

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

I wreszcie, w ostateczności

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

Korzystanie z apt-get

Oto odpowiedni fragment, ZMIENIONO DLA POPRAWNOŚCI i sformatowany:

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

Załóżmy, że otrzymujesz wiadomości o niektórych pakietach, których nie można ponownie zainstalować, a polecenie nie powiedzie się. Oto jeden ze sposobów, aby to naprawić, pomijając sporne pakiety:

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

I na koniec, jeśli powinieneś jakoś zainstalować tak wiele rzeczy, że powyższe polecenie nie powie, że twoja lista argumentów jest za długa, oto poprawka, która uruchomi apt-get wiele razy, niż możesz:

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

Zwróć uwagę na opcje -yi --force-yes, które przestaną apt-getCię powtarzać. Są to zawsze zabawne opcje, jeśli jesteś pewien, że wiesz, co robisz.

Pantera
źródło