web-dev-qa-db-ja.com

システムディレクトリ(/、/ etc、...)でコマンド "chmod -R"を誤って実行した場合

偶然走った

Sudo chmod 755 -R /

の代わりに

Sudo chmod 755 -R ./

数秒後に停止しましたが、次のような問題があります。

Sudo: must be setuid root

許可を元に戻すにはどうすればよいですか?

56
fl00r

要するに:システムを再インストールすることはできません。

つまり、Posixアクセス許可が使用され、大きく依存しています。間違ったアクセス許可がOSを破壊する(SUIDフラグ)、さらに悪いことに、正常に動作しているように見えてもセキュリティ面(/etc/ssh/ssh_Host_rsa_key)を公開するファイルシステムの場所が多数あります。

したがって、このような回復を適切に行うことは困難です。ミス1つのこと —それを台無しにします。 alreadySudo chmodコマンドを台無しにしました(それがyour friendである場合、彼女よりもLinuxのレッスンを学ぶかもしれません)—それは非常にシンプルなコマンド。適切に回復するには、より多くのコマンドとより多くの警戒が必要です。誰かのスクリプトを使用しても。

だから私を信じて、再インストールするだけです。それは安全な賭けであり、トラブルからあなたを守ることが保証されています。


最後に、ここで関連するいくつかのヒント。

最初に: 別のパーティションに/homeをセットアップする 次回の場合、再インストールの苦痛は少なくなります。実際には、彼らは簡単になります。

2番目:クレイジーLinuxサイエンス VirtualBoxのように 仮想マシン で行うことを検討し、スナップショットを作成します。

3番目:chmod -R .は機能します。単独のドット.は有効なディレクトリ名です。そのスラッシュを追加する必要はありません。ドットを完全にスキップする壊滅的なリスクを回避できたはずです。
単なるchmod: missing operand after ‘755’ VS荒廃したシステム。

56
ulidtko

私は数年、Rubyスクリプトを作成し、rsyncパーミッションと所有権に使用してきました。スクリプトget-filesystem-aclは、すべてのファイルを再帰的に走査してすべての情報を収集し、それをすべて.aclに入れます。スクリプト.acl-restore.aclを読み取り、すべてのchownchmodを適用します。

同様のUbuntuインストールでget-filesystem-aclを実行し、.aclファイルをchmodで損傷したボックスにコピーし、.acl.acl-restoreを/に入れて、.acl-restore

Rootが必要なので、Marco Ceppiが提案したようにSudoを修正してください。

Ubuntuの.aclファイルを生成して提供できます。

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

長く:できます。 Live CDからファイルシステムをマウントし、適切な場所で権限の復帰を開始する必要があります。少なくともSudoを元に戻すには、LiveCDセッション中にSudo chmod u+s /usr/bin/Sudoを実行する必要があります-これはsetuid rootでなければならない問題を修正します。

ただし、システムを単純に再インストールする方が簡単です。

12
Marco Ceppi

すべてのパッケージをapt-get install --reinstallで再インストールし、おそらくdpkg --get-selections | grep installの出力を使用してそれらのリストを取得しようとします。

4
Adam Byrtek

申し分なく、私はこれをテストしていません(あなた自身の責任で使用してください)が、それでもまだ動作するかもしれません。次の機会が得られたら、仮想マシンでこれをテストします。

最初に、まだ動作しているシステムで、リスト内のすべてのファイル許可を取得するために、/home/ディレクトリーをスキップして次のことを行いました。

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

これにより、システム上の各ファイルまたはディレクトリのアクセス許可とファイル名が表示され、その後に\0文字が続きます(これは、改行を含むなどの奇妙なファイル名を処理するために後で必要です)。

次に、ファイルのアクセス権が侵害されたシステムで:

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

これにより、fileper.logの各行が読み取られ、アクセス許可as$permとファイル名が$fileとして保存され、ファイル(またはディレクトリ)のアクセス許可がfileper.logにリストされているものに設定されます。


ここで注意すべき点がいくつかあります。

  • ファイル:/tmp/fileper.logへの出力中に、カスタム設定やprocなどをリストする場合があります。
  • 起動またはコマンドを実行できない場合があります。

私がお勧めするのは、ディスクにあるLinuxバージョンでLiveCDを起動し、コマンドを実行し、ローカルディスクをマウントした場所へのパスを変更し、2番目のコマンドを実行することです。


Ubuntu CD/USBから起動するとき、ディスクをフォーマットしないことを選択できることをテストしました。つまり、/ディレクトリ内のすべてを置き換えます。BUT/home/ディレクトリをスキップします。ユーザーの意味するところは、apps/DATA(Music、Video、Documents)の構成はそのままです。また、システムファイルを置き換えることにより、chmodが適切な数に設定されます。

3
blade19899

(回答にコメントするべきではありませんが、コメントするのに十分な評判はありません。)

blade19899の答えは、シンボリックリンクを除いて、私にとってはうまくいきました。例えば。 755を/ bin/bashに適用しましたが、777をシンボリックリンク/ bin/rbashに適用し、事実上/ bin/bashを777します。

Fileper.logファイルがすでにあるので、destination-endコマンドを変更しました。

while IFS=: read -r -d '' perm file; do  
    if [[ ! -L "$file" ]]; then    
        chmod "$perm" "$file"
    fi
done < /tmp/fileper.log 
3
Marjan

apt-getを使用して権限を復元してみてください。

Sudoでこれらのコマンドを実行できない場合は、リカバリモードで起動し、rootとして実行する必要があります。

復旧モードで起動するには、 https://wiki.ubuntu.com/RecoveryMode を参照してください。

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

注:これは元々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の使用

関連する切り抜きは、正確に編集され、再フォーマットされています。

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

再インストールできない一部のパッケージに関するメッセージが表示され、コマンドが失敗したとします。問題のパッケージをスキップして修正する方法の1つを次に示します。

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

最後に、引数リストが長すぎるという理由で上記のコマンドが失敗するほど多くのものをインストールする必要がある場合は、修正があります。これは、apt-getを何度も実行します。

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

-yおよび--force-yesオプションに注意してください。これらのオプションは、apt-getが繰り返しプロンプトを表示するのを停止します。自分が何をしているのかわかっているなら、これらは常に楽しい選択肢です。

2
Panther

回答の多くはSudoを必要とするため問題がありますが、Sudoは壊れています。 Sudoを使用してSudoを修正することはできません。他の回答では、Live CDまたはリカバリモードを使用してコンピューターを再起動する必要がありますが、これは不便です。

別のオプションはpkexecを使用して、ルート権限でシェルにアクセスします。

  1. ターミナルでpkexec bashを実行して、ルート権限を持つシェルを取得します。

  2. Setuidビットを設定します。

    chmod u+s /usr/bin/Sudo
    
  3. Sudoは、今後必要になる可能性のある修理のために利用可能になります。

0
xiota