sudo のセキュリティ(ごく一部CentOS7対応)

見失うと、結構たどりつくのに時間がかかるのでメモ

参考サイト：
[ユーザの実行権限を柔軟に割り当てるsudoのリスクとメリット](http://sourceforge.jp/magazine/08/02/13/0246250)
[sudoで実施した操作をログに残す](http://d.hatena.ne.jp/beatspace9/20081027/1225116724)
[sudo 時に root のパスワードを使う](http://blog.amedama.jp/entry/2015/09/14/213846)


## sudoとは
>
ユーザーが別のユーザーの権限レベルでプログラムを実行するためのコマンドである。一般的に、ユーザーがスーパーユーザー（superuser、すなわちroot）の特権レベルを利用する際に用いられることが多い。
>
（[Wikipedia](https://ja.wikipedia.org/wiki/Sudo)より）

### 注意点
盲目的にsudoを使えるようにすると、以下の様なセキュリティの穴にもなってしまいます。

- 「ログインできるユーザ全員」がroot権限を持つ
- 「rootユーザのパスワードを知らなくても」root権限のコマンドが実行できる
　（ユーザのパスワードがクラックされる＝root権限のコマンドも実行可能となる。）
- 2019.10.15以前のシステムは必ずsudoのアップデートを行いましょう。
    - 詳細->（[Linuxの「sudo」コマンドにroot権限奪取の脆弱性。ユーザーID処理のバグで制限無効化](https://japanese.engadget.com/2019/10/14/linux-sudo-root-id/)）

## コマンドにALLを割り当てない（必須）
（4/18追記　qnighyさんありがとうございます。）

これからコマンドに対してブラックリストで設定していきますが、コマンドでALLを許してしまうと抜け穴がいくらでも転がってるそうです。
例えば以下の様に設定していたとします。

```text:visudo
Cmnd_Alias VISUDO = visudo
%wheel ALL = (ALL) ALL, !VISUDO
```

一見```visudo```は実行できない様に見えます。

```bash:実行例
$ sudo visudo
ユーザー hogehoge は'/sbin/visudo' を root として hostname 上で実行することは許可されていません。すみません。
```

ですが以下の様にやると実行できてしまいます。

```bash:抜け穴
$ echo visudo > /tmp/example
$ chmod a+x /tmp/example
$ sudo /tmp/example
## Sudoers allows particular users to run various commands as
## the root user, without needing the root password.
##
## Examples are provided at the bottom of the file for collections
## of related commands, which can then be delegated out to particular
....
```

対策として一番いいのはホワイトリストで全コマンドを以下のように指定する事ですが、

```text:visudo
Cmnd_Alias ALLOWCMND = ip, route, service, .....
%wheel ALL = (ALL) ALLOWCMND
```

全コマンドをあげれる程精通していませんし、メンテナンスにも負担が大きいのでこの方法は力一杯全力で避けたいです。
なので、ディレクトリ指定することで実行可能なコマンドを絞りました。

```text:visudo
Cmnd_Alias ALLOWCMND = /usr/sbin/
%wheel ALL = (ALL) ALLOWCMND
```
この設定を行うと先ほどの抜け穴は実行できなくなります。

```bash:抜け穴対策後
$ sudo /tmp/example
ユーザー hogehoge は'/tmp/example' を root として hostname 上で実行することは許可されていません。すみません。
```

先ほどの抜け穴の出力先を/usr/sibn/配下に変更すればいいのでは？
と思う方もいると思いますが、一応パーミッションが無いので少しセキュアになります。

```bash:簡単には抜けれないよ
$ echo visudo > /usr/sbin/hoge
-bash: /usr/sbin/hoge: 許可がありません
$ sudo echo visudo > /usr/sbin/hoge
-bash: /usr/sbin/hoge: 許可がありません
```

参考サイト；[How to prevent sudo users from running specific commands?](http://superuser.com/questions/735172/how-to-prevent-sudo-users-from-running-specific-commands)　


## sudo -s （sudoからのシェル実行）の禁止
#### 設定目的
```$ sudo -s```等を実行すると１回パスワードを入力するだけで、```$ exit```するまで
rootユーザで実行可能となり、実質root権限が奪われることになってしまうため、
そういう事が出来ない様回避する。

#### 設定内容
```text:visudoによる設定内容
Cmnd_Alias SHELLS = /bin/sh, /bin/csh, /bin/tcsh, /bin/bash, /usr/local/bin/bash
Cmnd_Alias SHELLS_NONINTERACTIVE = /bin/sh -c *, /bin/csh -c *, /bin/tcsh -c *, /bin/bash -c *
Cmnd_Alias SU = /bin/su, /usr/sbin/visudo
%wheel ALL=(ALL)       ALLOWCMND, !SU, !SHELLS, SHELLS_NONINTERACTIVE
```
基本wheelグループに/usr/sbin/配下のコマンドを実行できる様にしています。
が、SU(su)やSHELLS(/bin/sh,/bin/csh...)はsudoから実行できない様に制限しています。
それでも例外として、１回だけ実行したい場合（-cオプション）はSHELLS_NONINTERACTIVE(/bin/sh -c *,...)の設定を入れることで実行可能なようにしています。

#### 備考
上記万全ではありません。

* 上記の設定内容に無いシェル（zsh等)を使っている環境だとか、
その辺も考慮して自身の環境に合わせて禁止するシェルやPathを変えてください。
* この設定では```sh -c sh```みたいな事をされると防げません。
設定を強固にするのであれば、```SHELLS_NONINTERACTIVE``` の設定は外してください。
* 他にも思いもしない抜け穴があるかもしれません

## sudoの環境変数を限定する
#### 設定目的
環境変数を固定値で持つことで、ユーザ側で書き換えることを防ぎます。
何が問題になるのかというと以下例で記述している様な事が可能になります。

例）とあるbashのプログラムが以下の様になっていたとします。

```
#!/bin/bash
PATH=${GZIP_BINDIR-'/usr/bin'}:$PATH
exec gzip -cd "$@"
```
悪意ある者がGZIP_BINDIRを/path/to/Akuiに書き換え、悪意にまみれたgzipを/path/to/Akui/gzip に配置しておくことで、
ユーザがこのbashを使うたびに悪意にまみれたgzipを実行させる事が出来てしまいます。

#### 設定内容
```
Defaults        env_reset
Defaults      secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
```


## sudo時にrootのパスワードを求める
#### 設定目的
ユーザのパスワードクラックされても、sudoを実行できない様にする。
（rootのパスワードを渡すことになりますので、内部犯のことも考えると```su```コマンドを
 実行された場合の対応を考えておく必要があります。）


#### 設定内容
```
hogehoge ALL=(ALL) ALL
Defaults:hogehoge  rootpw
```
hogehogeユーザに限り、全コマンドの権限を与えるが、
```Defaults:hogehoge ```の行の設定によりsudo実行時にはrootのパスワードを求めるようにしています。


----
他にもCentOSのvisudoに最初から記載のあったコメントの紹介と
その設定目的を自分の解釈で記述します。
ちょこっとです。全コマンドに対してではありませんのであしからず。

----

## NetWork設定
#### 設定目的
* インターネットの接続先を悪意のある場所へ誘導できない様にする。
* バックドアの通信ポートを開放させない様にする。

#### 設定内容
```bash:Network設定
## Networking
Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool
Cmnd_Alias NETWORKING_CENTOS7 = /bin/nmtui, /bin/nmcli, /sbin/ip
Cmnd_Alias NETWORKING_CENTOS7_SHOW = /bin/nmcli * show, /sbin/ip * show
```
#### 備考
```NETWORKING_CENTOS7``` と　```NETWORKING_CENTOS7_SHOW``` がCentOS7用に追加しました。
私の独断ですので、網羅できている自信はありません。
ipアドレス等の情報の参照は可能ですが、変更はできない様に設定する場合、下記のようになります。

```text:設定例
%wheel ALL=(ALL) ALLOWCMND, !NETWORKING_CENTOS7, NETWORKING_CENTOS7_SHOW
```

コマンドの詳細は[UnixPower on Networking](http://www.unix-power.net/centos7/network.html)等　参照してください。

## ソフトウェアの管理
#### 設定目的
* 悪意あるソフトウェアをお手軽にインストールされることを禁止する

#### 設定内容
```bash:Install_and_Management
## Installation and management of software
Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
```

## 常駐プロセスの変更禁止
#### 設定目的
* 悪意のあるソフト（バックドア、キーロガー等）を常駐する設定をさせない様禁止する。

#### 設定内容
```bash:常駐プロセス
## Services
Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig
```


## ストレージ
#### 設定目的
* マウントした時点で悪意のあるソフトが自動実行されないようにする。

#### 設定内容

```bash:Storage
## Storage
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount
```
## 権限昇格の禁止
* 権限設定の変更を禁止する
* chown等でroot以外の権限の低いユーザーIDにファイルのパーミッションを変更できないようする

```bash:権限昇格
## Delegating permissions
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp
```

## プロセス
#### 設定目的
* 稼働中のプロセスを停止できないようにする

#### 設定内容
```bash:Processes
## Processes
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall
```

## ドライバーの変更禁止
#### 設定目的
* 好き勝手にドライバを許可なく追加できないようにする。

#### 設定内容
```bash:カーネル変更
## Drivers
Cmnd_Alias DRIVERS = /sbin/modprobe
```

## まとめ
ここで紹介した権限を全部適用すると不便になることもあると思います。
面倒ですが各自でご使用になっている環境に合わせてカスタマイズされることをお勧めします。
またユーザ毎に実行可能なコマンドも制限していくとよりセキュアになってくると思いますが、
十人十色な設定項目になってくると思いますので、十分に検討されることお勧めします。

また、長々と書きましたが、あくまでsudoコマンドの実行制限の設定です。
これらのコマンドをsudoで制限していても一般ユーザで実行可能なコマンドもあるかもしれません。
その場合は、せっかくここで設定した内容も全くの無駄ですので、
一般ユーザでも実行権限があったりしないか確認されることをお勧めします。

sudoコマンドのセキュリティの紹介をさせていただきましたが、
考え方的に他のコマンドや環境にも通じるところがあると思います。
皆様の何かの参考になれば幸いです。