'echo「基本侮辱」>>/etc/sudoers'は安全ですか?

'echo「基本侮辱」>>/etc/sudoers'は安全ですか?

これは安全ですか?

echo "Defaults    insults" >> /etc/sudoers

それでは、これを行うことはできますか?

echo "## First line" >> /etc/sudoers
echo "### Second line" >> /etc/sudoers
echo "Defaults    insults" >> /etc/sudoers
echo "### Totally the last line" >> /etc/sudoers

これを行うより良い方法はありますかvisudo

私はbashスクリプトを作成していますが、この部分では侮辱をオン/オフする必要があります。

答え1

これが危険な方法は少なくとも3つあります。

  1. /etc/sudoers改行文字で終わらない場合(sudo許可visudo)、たとえば#includedir /etc/sudoers.d終了しない行で終わる場合、コマンドは次のように作成します。

    #includedir /etc/sudoers.dDefaults insults
    

    これにより、そのファイルが破壊され、sudo使用できなくなります。

  2. echoたとえば、ファイルシステムがいっぱいになると、文字列全体が書き込まれない可能性があります。たとえば、書き込みのみ可能ですDefaults in。これによりsudoersファイルが破損します。
  3. 複数の管理者がいるシステムで/etc/sudoers2人が同時に変更しようとすると、それらが書き込むデータがインターリーブされる可能性があります。

visudo一時ファイル()を編集し、ファイルが変更されたかどうかを検出できるため、これらの問題を回避できます/etc/sudoers.tmp(残念ながら、ファイルが変更された場合は検出されません)。正常に修正(エディタの終了状態を確認しないようです)、構文を確認してrename(原子的タスク)を実行して、新しいファイルを所定の位置に移動します。したがって、ファイルが正常に更新された場合(エディタが新しいファイルを書き込めない場合でもファイルを変更せずに残した場合)、更新できない場合、または構文が無効な場合は失敗します。

visudosudoersまた、複数の人が同時にファイルを編集するのを防ぎます。

今、visudo自動化された方法で安定して使用するのも難しいです。このタスクにはいくつかの問題があります。

  • visudoVISUAL環境変数を使用してエディタコマンド(優先順位)を指定できますが、EDITORこのenv_editorオプションが無効になっていない場合にのみ可能です。
  • 私のバージョンは、visudo少なくとも特定の条件で/etc/sudoers含まれているすべてのファイルを編集します($VISUALすべてのファイルに対して実行)。したがって、$VISUAL修正のみを行ったことを確認する必要があります/etc/sudoers
  • 上記のようにエディタの終了ステータスを確認しません。したがって、エディタで保存したファイルが正常に作成されたこと、まったく変更されていないことを確認する必要があります。
  • 問題が発生すると、ユーザーにメッセージが表示されます。

これらすべての問題を解決するのは少し面倒です。次のことができます。

NEW_TEXT='Defaults insults' \
  CODE='
    if [ "$2" = /etc/sudoers.tmp ]; then
      printf >&2 "Editing %s\n" "$2"
      umask 077
      {
        cat /etc/sudoers.tmp && printf "\n%s\n" "$NEW_TEXT"
      } > /etc/sudoers.tmp.tmp &&
        mv -f /etc/sudoers.tmp.tmp /etc/sudoers.tmp
    else
      printf >&2 "Skipping %s\n" "$2"
    fi' \
  VISUAL='sh -fc IFS=:;$1 sh eval:eval:"$CODE"' visudo < /dev/null

env_editor設定しないと効果はありません。

GNUシステムでより良い選択肢はwhichを使うことです。最新バージョンを作成できない場合は、sed -i変更せずにそのままにしてください。sudoers.tmp

次に追加insults:

SED_CODE='
  /^[[:blank:]]*Defaults.*insults/,${
    /^[[:blank:]]*Default/s/!*\(insults\)/\1/g
    $q
  }
  $a\Defaults insults' \
CODE='
  if [ "$2" = /etc/sudoers.tmp ]; then
    printf >&2 "Editing %s\n" "$2"
    sed -i -- "$SED_CODE" "$2"
  else
    printf >&2 "Skipping %s\n" "$2"
  fi' \
VISUAL='sh -fc IFS=:;$1 sh eval:eval:"$CODE"' visudo < /dev/null

侮辱を取り除きなさい:

SED_CODE='
  /^[[:blank:]]*Defaults.*insults/,${
    /^[[:blank:]]*Defaults/s/!*\(insults\)/!\1/g
    $q
  }
  $a\Defaults !insults' \
CODE='
  if [ "$2" = /etc/sudoers.tmp ]; then
    printf >&2 "Editing %s\n" "$2"
    sed -i -- "$SED_CODE" "$2"
  else
    printf >&2 "Skipping %s\n" "$2"
  fi' \
VISUAL='sh -fc IFS=:;$1 sh eval:eval:"$CODE"' visudo < /dev/null

答え2

確認してみると、ずっと前(私の知る限り2001年ごろ)includedirサポートが可能だったようですので、RHEL 5でこれをサポートしなければなりません。sudo以下を含むsudoersでディレクティブを見つけます。

sudo grep '#includedir' /etc/sudoers

結果が得られたら、理想的にはそのディレクトリにファイルを追加して削除する必要があります/etc/sudoers.d。通常、シェルスクリプトでパスを決定するのは難しい場合があります。

とにかく、仮定的には、そのディレクトリに権限を持つファイルを追加するsudoers.d必要があります。0600それは次のとおりです。

sudo sh -c '
  umask 0177;
  filename="/etc/sudoers.d/$1";
  echo 'Defaults insults' > "$filename";
  visudo -cf "$filename" || rm "$filename"
' _ 99-insults

99-insults生成するファイル名はどこにありますか?sudoers.d)その後、設定を削除する方法は次のように簡単です。

sudo rm /etc/sudoers.d/99-insults

実際、これはsh -cコマンドの最後の部分が実行するアクションです。スキャンに失敗した場合は、このファイルを削除してvisudo破損していますsudoers


あなたはそれを使用することができますtee -aEDITOR

$ sudo VISUAL='tee -a' visudo <<<"Defaults insults"
Defaults insults
$ sudo tail /etc/sudoers
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d
Defaults insults

sudoEL5がサポートしているかどうかはわかりませんがincludedir、サポートしている場合はその中に新しいファイルを作成してくださいvisudo -f

関連情報