sudo -e は便利ですが、最近の sudo では安全策として制限が強めです。とくに、呼び出しユーザーが書き込み可能なディレクトリ配下のファイルは sudoedit で拒否されることがあります。これは sudoers の sudoedit_checkdir が既定で有効だからです。sudoedit は一時ファイル経由で編集し、SUDO_EDITOR / VISUAL / EDITOR を使ってエディタを起動します。 (man7.org)
この記事では、次の 2 つを整理します。
sudoersを調整してsudo -eを使い続ける方法- Emacs の TRAMP
/sudo::を使って、ユーザー権限のemacs -daemon+emacsclientで編集する方法
背景: なぜ sudo -e が止めるのか
sudoedit は、対象ファイルを直接 root でエディタに渡すのではなく、一時コピーを作ってユーザー権限のエディタで編集し、最後に元へ戻す仕組みです。そのうえで、追加の保護として次の制限があります。
- シンボリックリンクを既定では開かない
- パス途中にユーザー書き込み可能ディレクトリがある場合はリンク追跡を拒否する
- ユーザー書き込み可能ディレクトリ内のファイル編集を拒否する
これらは sudoedit の安全策として documented されています。 (man7.org)
方法1: sudoers を編集して sudo -e の制限を緩める
何を変えるのか
対象は sudoers の sudoedit_checkdir です。これが有効だと、sudoedit はパス中のディレクトリの書き込み可否を検査し、ユーザーが書き込めるディレクトリ内のファイル編集を拒否します。既定値は on です。 (Ubuntu Manpages)
編集手順
sudoers は直接編集せず、visudo を使います。sudo の公式 man page でも、構文エラーを避けるため visudo の利用が推奨されています。 (man7.org)
全体に適用するなら:
Defaults !sudoedit_checkdir
ユーザー限定にするなら:
Defaults:yourname !sudoedit_checkdir
分離ファイルにするなら:
sudo visudo -f /etc/sudoers.d/sudoedit
中身:
Defaults:yourname !sudoedit_checkdir
併せて知っておくべき設定
シンボリックリンクの扱いは別設定の sudoedit_follow です。既定では off で、必要なときだけ明示的に有効化する設計です。 (Ubuntu Manpages)
利点
- 既存の
sudoeditワークフローを維持できる SUDO_EDITOR=emacsclientと組み合わせやすい- 一時ファイル経由という
sudoedit本来の流儀を保てる
欠点
- 安全策を弱める
- マシン全体、または対象ユーザーの
sudoポリシーを変更する必要がある - 管理者権限が必要
emacsclient を sudoedit から使う
sudoedit はエディタとして SUDO_EDITOR、次いで VISUAL、EDITOR を参照します。したがって、ユーザー権限で起動した Emacs デーモンをそのまま使えます。 (man7.org)
GUI フレームを開くなら:
export SUDO_EDITOR='emacsclient -c'
sudoedit /etc/hosts
端末内で開くなら:
export SUDO_EDITOR='emacsclient -t'
sudoedit /etc/hosts
この方式は、sudoedit の制約はそのまま受ける点が重要です。つまり、sudoedit_checkdir に引っかかるなら、SUDO_EDITOR を emacsclient にしても解決しません。根本の判定は sudoers 側だからです。 (man7.org)
方法2: Emacs TRAMP の /sudo:: で編集する
もうひとつの実践的な方法が、Emacs の TRAMP を使うやり方です。TRAMP の sudo メソッドは sudo を使って別ユーザーとしてシェルを開始し、適切な権限でファイルにアクセスします。TRAMP マニュアルでは、sudo メソッドは sudo を使い、「shell を開始する十分な権限が必要」と説明されています。 (gnu.org)
たとえば:
emacsclient /sudo::/etc/hosts
あるいは Emacs 内で:
C-x C-f /sudo::/etc/hosts
さらに TRAMP には、今のバッファや Dired 項目を sudo 付きで開き直す支援コマンドもあります。tramp-revert-buffer-with-sudo と tramp-dired-find-file-with-sudo が用意されており、既定メソッドは sudo です。 (gnu.org)
利点
sudoersを変えなくてよい- ユーザー権限の
emacs -daemonをそのまま使える emacsclientから自然に扱えるsudoedit_checkdirのようなsudoedit固有の制約に縛られない
欠点
- これは
sudoeditではなく、sudoメソッドでの編集 sudoers全体の許可ルールを回避するわけではない- root で開いたバッファとして扱うので、
sudoeditと同じ安全モデルではない
/sudo:: は sudoedit の代替になるのか
実務上は、かなり代替になります。理由は単純で、sudoedit_checkdir は sudoedit 専用フラグだからです。sudoers(5) でも、その設定は sudoedit が書き込み可能ディレクトリや経路上のリンクをどう扱うか、という文脈で定義されています。 (Ubuntu Manpages)
一方で TRAMP の /sudo:: は sudoedit ではなく sudo メソッドです。したがって、sudoedit 固有の拒否に悩んでいるなら、/sudo:: は現実的な逃げ道になります。TRAMP 公式にも sudo メソッドと sudoedit メソッドは明確に分けて記述されています。 (gnu.org)
では /sudoedit:: はどうか
TRAMP には sudoedit メソッドもあります。マニュアルでは、これは TRAMP による sudoedit 実装であり、sudo メソッドとは異なり、各操作を単発の sudo ... で実行して、Emacs 背後にセッションを残さないようにしている、と説明されています。目的は「可能な限り安全に編集すること」で、外部プロセスは実装されません。 (gnu.org)
つまり、sudoedit 的な安全モデルを保ちたいなら /sudoedit::、制約を避けて編集したいなら /sudo:: という使い分けになります。
相対パスは使えるか
TRAMP では相対パスも使えますが、基準は Emacs の default-directory です。実用上は、先にディレクトリを sudo 付きで開いておくのが簡単です。
C-x C-f /sudo::/etc/
その後で:
C-x C-f hosts
のように相対指定できます。普段の操作では、Dired から @ で sudo 付きに切り替える流れも扱いやすいです。TRAMP には Dired/バッファを sudo で開き直す専用コマンドが用意されています。 (gnu.org)
どちらを選ぶべきか
sudoers を編集するべきケース
sudo -eのワークフローを維持したい- 一時ファイル経由の
sudoeditを使い続けたい - 管理者として、その制限を緩める判断ができる
この場合は visudo で sudoedit_checkdir を調整するのが筋です。 (man7.org)
TRAMP /sudo:: を選ぶべきケース
- ユーザー権限の
emacs -daemonを使いたい emacsclientで自然に編集したいsudoedit_checkdirに引っかかるが、sudoersは触りたくない
この場合は /sudo:: が最も実用的です。TRAMP 側でも sudo メソッドを使うための支援コマンドが整備されています。 (gnu.org)
最小構成のおすすめ
運用としては、まずこれで十分です。
alias ec='emacsclient -c'
必要なときだけ:
ec /sudo::/etc/hosts
sudoedit を残したいなら:
export SUDO_EDITOR='emacsclient -c'
そのうえで、本当に必要な場合だけ sudoers の sudoedit_checkdir を見直します。sudoedit は既定で保護寄り、TRAMP /sudo:: は運用寄り、という整理にしておくと迷いません。 (man7.org)
まとめ
sudo -e で困る原因が sudoedit_checkdir なら、解決策は 2 つです。
- 管理側で直す:
visudoでsudoedit_checkdirを無効化する - 編集側で回避する: Emacs TRAMP の
/sudo::を使う
前者は sudoedit の流儀を保ち、後者は Emacs 運用に自然に馴染みます。emacs -daemon と emacsclient を中心に使うなら、多くの環境では TRAMP /sudo:: のほうが実践的です。一方で、組織や端末のポリシーとして sudoedit を標準にしたいなら、sudoers の明示的な管理が必要です。 (man7.org)