一般ユーザで管理者権限を使うsudoコマンドの設定と使い方, 環境変数

Last modified: 2020-10-18

実行方法と引数

sudoは特定のユーザやグループに対して、特定(もしくは全て)のコマンドを管理者権限(もしくは別のユーザ権限)で実行するためのコマンド。

管理者権限でコマンドを実行するには、実行したいコマンド行の先頭にsudoを付ける。

$ sudo [コマンド] ([引数...])

実行したいコマンドにオプションや引数を付けるには、そのまま後ろに付ける。sudoの後ろをまとめてクォートで囲むと正常に動作しない。

sudoを使用して実行したコマンドの履歴は/var/log/以下のファイルに記録される。

インストール状況の確認とインストール

端末内でsudoと入力した後Enterを押したときに

$ sudo
usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
usage: sudo [-AbEHknPS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] file ...

上のように使用法が出るならインストール済みだが、もし、 “command not found” と出てしまうのであれば、各ディストリのパッケージマネージャでsudoという名前のパッケージをインストールする。

本サイトに記事を移動した段階では標準でインストールされているディストリが多い。ディストリによってはインストール時の設定でsudoの実行が可能になっていることもある。
Ubuntuはインストール時にrootアカウントのパスワードを設定せずに一般ユーザからsudoを使用する形がずっと続いており、特にsudoを使用するために追加のインストールや設定は必要ない。

設定

Ubuntuではインストール後すぐに使える状態になっているが、その他のディストリでは、基本的にsudoには、(運用ポリシーに基づいた)事前設定が必要。

設定編集の開始

一度rootになって、sudoの設定を行う。下のgedit部分は好みのテキストエディタのコマンド名で置き換える。

$ su -
[ここでrootのパスワードを入れる]
# EDITOR=gedit visudo

テキストエディタ(上の例ではgedit)が起動するので、設定ファイルを編集する。

visudoはエディタの終了時に文法チェックを行い、エラーがあった場合にはファイルを更新せず、再度編集に戻る。設定ファイルはチェックに通った場合にのみ更新される。

コマンドエイリアスの定義

複数のコマンドをグループ化することで、設定/管理をしやすくする。複数でなくても、名前を付けて意味を持たせることで分かりやすくなる。

# Cmnd alias specification
Cmnd_Alias MOUNT=/bin/mount,/bin/umount

この例では、/bin/mount/bin/umountのコマンドをMOUNTというエイリアスとして定義している。

ユーザやグループに対してsudoの使用を許可

許可設定されていないユーザはsudoが使えないため、ユーザやグループに対して許可する設定をする。

# User privilege specification
root    ALL=(ALL) ALL

と書かれている下あたりに

user_name	ALL=(ALL)	ALL

を書く(user_nameは実際のユーザ名に置き換える)と、そのユーザは、sudoで全てのコマンドを管理者権限で使用できるようになる。一番右のALLの部分は、コマンドのパス名(例:/sbin/shutdown)や、Cmnd_Aliasで指定したエイリアスによる指定をすることもできる。
一番左のユーザ名の部分は

%wheel	ALL=(ALL)	ALL

のように、 “パーセント記号の後ろにグループ名” の形でも指定可能。

パスワード入力不要の有効時間

sudoは、コマンド実行時に自分のパスワードを入力するが、一度入力すると、しばらく(既定値は5分)はパスワード無しでコマンドが実行できる。その時間は

# Defaults specification
Defaults timestamp_timeout=10

Defaults timestamp_timeout=の値に分単位の値を指定する。0にすると毎回パスワードを入力するようにできる。

これは同一の(仮想)端末についてのみ有効なもので、端末ソフトの新しいタブやtmuxなどの新しいウィンドウを開いてその中でsudoを実行するとパスワードの入力が必要となる。

パスワードを入力しないでコマンドを実行する

user_name	ALL = NOPASSWD: MOUNT

のようにNOPASSWD指定を記述すると、上で定義したエイリアスMOUNTに含まれるコマンド(mountumount)を<sudoで実行するときに自分のパスワードを入力する必要がなくなる。

コマンド部分(一番右)をALLにすると全てのコマンドでパスワード不要になるが、使用には十分注意する必要がある。

設定の詳細についてはUNIXの部屋 検索: sudoなどが詳しい。書式に関しての詳細な説明や引数に関しての注意なども書かれている。

/etc/sudoers.d/ ディレクトリ

ディストリによっては設定の記述を任意の名前(設定の目的などに合わせたもの)のファイルにして/etc/sudoers.d/以下に保存したものが設定として読み込まれる。

ずっと前から同じ設定を使い続けていて、OSのアップグレードをクリーンインストールで行った後などには便利だが、設定を新しく追加する際には文法エラーがあると面倒なことになるため、ファイル名指定ありでvisudoを実行することが推奨されている。

$ visudo -f /etc/sudoers.d/myconfig

ディレクトリの中に配置するファイルのアクセス権は0440(-r--r-----)にするべきとされており、visudoで編集した場合はアクセス権操作は不要。

実行時の環境変数

sudoでは

  • これを実行したユーザで設定されている環境変数をリセットする
  • 指定されている環境変数だけは別ユーザに渡せるようにする
  • 特別なユーザもしくはグループのメンバのみ全ての環境変数を渡せるようにする

といった設定ができる。

  • env_reset: 環境変数をリセットする
  • !env_reset: 環境変数のリセットをしない
  • env_keep: 環境変数をリセットするときにここに並べた名前の環境変数のみを通す

下は設定例。

# 既定で環境変数をリセット
Defaults    env_reset

### wheelグループのメンバーのみ環境変数を通す
Defaults:%wheel    !env_reset

### usersグループは、指定した環境変数のみ通す
Defaults:%users env_keep="TZ LANG DISPLAY XMODIFIERS GTK_IM_MODULE QT_IM_MODULE"

### 特定のユーザだけ、指定した環境変数を通す
Defaults:user_name env_keep="TZ LANG DISPLAY XAUTHORITY XMODIFIERS \
GTK_IM_MODULE QT_IM_MODULE \
CFLAGS CXXFLAGS CC CXX HOSTCC HOSTCXX CCACHE_DIR PKG_CONFIG_PATH"

使用上のヒント

“sudoコマンドに関する追加メモ” として別の記事にしていた内容を本記事に統合し、使用上のヒントとしてまとめた。

sudoを用いる複数のコマンド行を1回のコマンド入力で実行したい場合

別のユーザで実行したい複数のコマンド行を1回のsudoの実行で処理するには

  • 複数のコマンド行を実行する記述をシェルへの(-c)オプションとしてsudoからシェルを実行
  • 実行する内容をシェルスクリプトに記述したものをsudoで実行

などの方法が考えられるが、いずれも複数ユーザで用いているシステムでは管理者の立場からみると任意のコマンドの実行を許可するのと同じになるため、セキュリティ的に問題となることがある。
そのため、一般ユーザ権限でシェルやシェルスクリプトを用いて連続したコマンド実行を記述するのが現実的。

$ sh -c 'sudo /path/to/command1 -opt1 && sudo /path/to/command2; ...'

sudoはパスワードの入力を一度行った後は決められた時間以内の次回実行時にパスワードの入力が不要になる仕組みのため、順番が最後以外のsudoを用いた処理の時間が短ければこの形で問題はない。

自分しか使っていないマシンでsudoによるシェルの実行を許可している場合は

$ sudo sh -c '[cmdline1 ...]; [cmdline2 ...]; ...'

のようにすることも可能。

管理者権限で標準出力をファイルに書き出す

下のコマンドは実行は管理者権限だが、出力の書き出しは一般ユーザ権限となる。

$ sudo /path/to/command1 > text.txt

コマンドの出力を>でファイルに書き出す操作を管理者権限で行う場合には

$ sudo sh -c 'echo test > test.txt'

のようにするが、sudoによるシェル(つまりは任意のコマンド)の実行を許可している必要がある。
teeコマンドが設定によって許可されていれば

$ echo test | sudo tee test.txt > /dev/null

のようにファイルに書き出すことはできるが、これも任意の場所にファイルを書き出せるものなので、注意して使う必要がある。

root以外のユーザとしてコマンドを実行

sudoは、既定ではroot(管理者)ユーザとしてコマンドを実行するが、-uオプションを付けて任意のユーザとしてコマンドを実行することができる。

$ sudo -u [ユーザ名] [コマンド] ([引数...])

visudoでのアクセス許可の設定としては “一般ユーザuser_nameが別のユーザfooの権限で/path/to/command1/path/to/command2を実行できるようにする” ものとすると

user_name ALL=(foo) /path/to/command1,/path/to/command2

となり、パスワード入力の省略の許可を追加すると(上の代わりに)

user_name ALL=(foo) NOPASSWD: /path/to/command1,/path/to/command2

のようになる。