権限管理入門

Linux Permission 1/N

公開日: 2021-05-05
更新日: 2023-08-08
所要時間: 10 min

Table of Contents

What is “Permission”?

Def: Permission

ファイルやディレクトリには「誰に」「どのような操作を」許可するのか, それを個別に設定することができ, これをPermissionという.

Linux環境では複数のユーザーで利用することが前提となっています. このようなシステム設計思想をマルチユーザーといいます. マルチユーザーシステムでは, 一つのコンピューター上に, 複数のアカウントが存在し得ます. 「アカウント」とは, 「ユーザー名とパスワードで管理されるコンピューター使用権」とここでは理解しときます.

複数のユーザーが一つのコンピューター上に存在し得る以上, どのユーザーがどのディレクトリ, ファイルに対して所有権やアクセス権を有しているのか?定義する必要があります. この「(ユーザー, ファイル)ごとのアクセス権の管理」という概念がPermissionで, Linuxでは許可されたユーザーのみがファイルにアクセスできる「アクセス制御」が実装されています.

「コマンドや設定が正しいはずなのになぜか動かない」というトラブルに直面する時の多くのケースにおいて, このPermissionの不整合が原因となります. こういった意味でも, Permissionがどんな仕組みなのか?を学ぶ価値はあります.

Column: Permissionによるアクセス制御のメリットの紹介

システムには/lib/libc.so.6(共有ライブラリの一つ)のように重要なものもあれば, memo.txtのような些細なメモ書きのファイルもあります. この両者に対するアクセス権は同レベルのものではなく, 前者のほうが厳格に取り扱われるべきと考えられます. 後者は, うっかり消してもそのシステムのユーザーの大半には影響を与えませんが, 前者を消去した場合は多くのユーザーが困ってしまいます. そのため, メモは各一般ユーザーレベルのアクセスを共用する一方, /lib/libc.so.6は普段は編集できないように設定するべきとなります.

この設定を実現するために, マルチユーザーシステムとPermissionが存在します. マルチユーザーシステムによって, システム内部に複数のユーザーを設定できるようにし, Permissionによって限られたユーザーのみが/lib/libc.so.6にアクセスできるように設定することができます.

Permissionの確認

上述の権限は ls -l コマンドで確認することができます. -a.で始まるファイルも含めカレントディレクトリに存在するすべてのファイルを表示するオプション. -lはPermissionやサイズ, 更新タイムスタンプといった情報を出力するために用いられるコマンドです.

表示される項目としては

  • ファイルの種類とPermission(所有ユーザー, 所有者のプライマリグループ, その他のグループの順番でPermissionが記載)
  • ハードリンク数
  • 所有ユーザーと所有グループ

Permissionの表記の意味

種類 意味 ファイルの場合 ディレクトリの場合
r Readable ファイルの内容を読むことができる ディレクトリの内容が表示可能になる(lsコマンドが使える)
w Writable 編集が可能になる ディレクトリ内のファイルやディレクトリの作成/削除ができる(rm, touch, mkdirが使用可能)
x eXecutable 実行ファイルとして実行できる ディレクトリへ移動できるようになる
- 不許可    

ファイルタイプの種類

上ではファイルタイプについてd-のみ紹介しましたが, 知っておくべきファイルタイプは8個あります.

文字 ファイルタイプ
- ファイル  
b ブロックファイル SSDやHDDなどのブロックデバイスをファイルとして扱かったもの
c キャラクタファイル ファイルシステム上であたかも通常のファイルのような形で提示されるデバイスドライバのインタフェース
d ディレクトリ  
l シンボリックリンク  
p FIFO(名前付きパイプ) FIFOを用いたプロセス間通信に利用するファイル
s Unixドメインソケット ソケットを用いたプロセス間通信に利用するファイル
? その他 判断しにくいファイル(壊れている場合が大半)

What is “Group”?

Linuxでは, 「グループ」というユーザーカテゴリでPermissionを管理することができます. このグループとは「ユーザーの集合」のことです. Linuxではユーザー作成時に, ユーザー名と同名の新しいグループが作られ, それが新規作成したユーザーに割り当てられます. ユーザー名と同じ名前のグループが設定される管理方式をユーザープライベートグループ(UPG)と呼びます.

一つのLinuxコンピューターにユーザーが100人とかいるケースでは, 1人づつリソース管理するよりもグループ単位で管理したほうが簡単なケースは多々あります.

Column: Group単位での権限管理のメリット

例えば, 会社で一つのLinuxサーバーを共有している時, 管理職グループには売上帳票関連ディレクトリのアクセス権を付与するが, それ以外のユーザーにはアクセスを禁じたい時を考えます.

この時, 一人ひとりのユーザーにディレクトリのアクセス権を設定すると, 管理職人数のオーダーで設定工数が発生しますが, 一旦管理職グループを定義して管理職グループのみにディレクトリのアクセス権を付与するという形にすると工数のオーダーが$O(1)$になることからもわかります.

1
2
% sudo chgrp -R 管理職グループ <directory-path>
% sudo chmod 770 <directory-path>

グループの情報は/etc/groupファイルに保存されています. catコマンドで確認することができますが, password箇所は暗号化の関係でxと表示されます:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
### 書式
group-name:password:group-id:user-list

### /etc/group
% cat /etc/group     
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:syslog,ryo
tty:x:5:
disk:x:6:
lp:x:7:
....

グループの種類: プライマリーグループ & セカンダリーグループ

Def: グループの種類

ユーザーは必ず1つ以上のグループに所属します. グループにはプライマリーグループとセカンダリーグループの2種類があります:

プライマリーグループ ログイン直後の作業グループ
ファイルやディレクトリを新規作成した際にグループとして使用される
セカンダリーグループ それ以外のグループ, 必要に応じて使用される

グループ情報を確認する場合は, groupsまたはidコマンドを利用します

groups command

current userや指定したユーザーのグループリストのみを確認したい場合はgroups commandを用います:

1
2
3
4
5
6
7
### カレントユーザーのグループリスト
% groups
ryo study futsal arsenal utecon

### 指定したユーザーのグループリスト
% groups haaland
haaland : haaland city striker manchester

この出力の元情報は上で紹介したように/etc/groupに格納されています.

id command

現在のユーザーでプライマリグループや, セカンダリーグループリストをUIDとGIDと共に出力したい場合はidコマンドで確認します.

1
2
 % id
uid=1000(ryonak) gid=1000(ryonak) groups=1000(ryonak),4(adm),10(arsenal)
  • uid: 現在のUser名 & user IDを表示, User名はwhoamiコマンドで出力されるユーザー名と同一のもの
  • gid:プライマリーグループのGroup IDとGroup名を表示
  • groups: セカンダリーグループを表示

Permissionの設定

Def: だれがPermissionを設定できるのか?

ファイルやディレクトリのパーミッションはrootと対象オブジェクトに対して所有権を持っているユーザーとrootユーザーが設定できます.

設定可能権限は「READ, WRITE, EXEWCUTE」の3つの権限属性を設定できます.

READ 4 読み込み権限
WRITE 2 書き込み権限
EXECUTE 1 実行権限

設定対象については, 次のユーザーカテゴリ単位で権限設定することができます.

User ファイルの所有者
Group 所有者グループ(同じ権限をもっているユーザーの集合)のユーザー
Other その他のユーザーグループ

chmod: Permissionコマンド

Permissionを設定する場合は以下のコマンドを用います

1
% chmod [option] mode file

test.shというファイルを例にPermission設定例を確認してみます

1
2
3
4
% chmod a+rx test.sh  #すべてのユーザーにread, execute権限付与
% chmod a-rx test.sh  #すべてのユーザーからread, execute権限剥奪
% chmod u+rx test.sh  #所有ユーザーにread, execute権限付与
% chmod g+rx test.sh  #所有グループにread, execute権限付与

userの指定

u owner user
g group
o other
a すべてのユーザー

シンボリックモードでの権限の変更

+ 権限追加付与
- 権限剥奪
= 権限指定

数値によるPermissionの指定=オクタルモード

r Reable 4
w Writable 2
x eXecutable 1
- 不許可 0
s SUID/SGID 4000/2000
t スティッキービット 1000
1
% chmod 755 test.sh  ##所有者:rwx,所有グループ:r-x,Others:r-x

Permissionの再帰的処理

ディレクトリ内のファイルすべてを再帰的に変更したい場合はoption -Rを用います:

1
2
#ディレクトリとディレクトリ内のファイル全ての権限を(再帰的に)変更する
% chmod -R 766 dir

Problem: シンボリックモードとオクタルモードでのPermission設定

1
2
% ls -l
-rw-rw-r-- 1 ryonak ryonak   90 Aug  4 19:50 fileA

以下のような条件を満たす形でPermissionを変更してください

  • 所有者: Readable, Writable, Executable
  • 所有者以外: Reable, Executable

シンボリックモードで記載する際は, カンマ区切りを用いて定義します.

1
2
3
4
5
# シンボリックモード
% chmod a+x,g-w fileA

# オクタルモード
% chmod 755 fileA

umaskを用いたDefault Permissionフラグの管理

Def: デフォルトのPermission

ユーザーがファイルやディレクトリを新規作成した際にはデフォルトのPermissionが付与されます. デフォルトのPermissionの値はシェルに設定されたumask値で決まります.

なおumaskが影響を与えるのは, 新規ファイル・ディレクトリの作成時だけであって, 既に存在するファイルのパーミッションには全く影響を与えません.

LinuxではファイルとディレクトリのPermission初期値は以下のようになっています.

ファイル 666 -rw-rw-rw-
ディレクトリ 777 drwxrwxrwx

このままではだれでも少なくともファイルが編集できてしまうので, セキュリティ対策の観点から調整が必要です. この時用いるコマンドがumaskです.

umaskはシェルに組み込まれたコマンドで設定したumask値をPermission初期値から引き算した値でファイル, ディレクトリを作成するようになります. 以下のlineを.zshrcに書き込むことを推奨します.

1
% umask 022 #groupとotherからwritableの権限を除去する

初期設定値をTerminalから確認したい場合はumaskと入力すれば確認できます.

Example: デフォルトパーミッション

  ファイル ディレクトリ
初期値Permission 666 777
umask 022 022
Default Permission 644 755

umaskで所有者以外の2 = Writableをmaskするという意味なので, Default PermissionではWritableが取り除かれた値が設定される.

chown: 所有者の変更

Def: chwonコマンド

  • chownコマンドは指定されたファイルやディレクトの所有者とグループを変更する
  • グループも合わせて変更する場合はグループ名の前に. または : を指定する
  • このコマンドを実行できるのはrootユーザーのみ
1
% chown [option] user-name[:group-name] file-name

システム管理の場面以外では, Dockerfileの設定において, rootユーザーで必要なパッケージインストールと環境準備を実行した後に, adduserからそのユーザーに対して権限を与えるという処理をする際に使用されます. 例として,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
ARG BASE_IMAGE=wolframresearch/wolframengine
FROM ${BASE_IMAGE} as base

USER root

SHELL [ "/bin/bash", "-c" ]
ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
    apt-get -qq -y update && \
    apt-get -qq -y install \
      software-properties-common \
      wget curl make nodejs build-essential libssl-dev zlib1g-dev libbz2-dev \
      libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev \
      libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev git && \
    apt-get -y autoclean && \
    apt-get -y autoremove && \
    rm -rf /var/lib/apt/lists/*

# Create non-root user "docker" with uid 1000
RUN adduser \
      --shell /bin/bash \
      --gecos "default user" \
      --uid 1000 \
      --disabled-password \
      docker && \
    chown -R docker /home/docker && \
    mkdir -p /home/docker/work && \
    chown -R docker /home/docker/work && \
    mkdir /work && \
    chown -R docker /work && \
    chmod -R 777 /work && \
    mkdir /docker && \
    printf '#!/bin/bash\n\njupyter lab --no-browser --ip 0.0.0.0 --port 8888\n' > /docker/entrypoint.sh && \
    chown -R docker /docker && \
    cp /root/.bashrc /etc/.bashrc && \
    echo 'if [ -f /etc/.bashrc ]; then . /etc/.bashrc; fi' >> /etc/profile && \
    echo "SHELL=/bin/bash" >> /etc/environment

References



Share Buttons
Share on:

Feature Tags
Leave a Comment
(注意:GitHub Accountが必要となります)