日曜日, 7月 13, 2025
日曜日, 7月 13, 2025
- Advertisment -
ホームニューステックニュース【Linux】変な パーミッション【Ansible】 #YAML - Qiita

【Linux】変な パーミッション【Ansible】 #YAML – Qiita



【Linux】変な パーミッション【Ansible】 #YAML - Qiita

  • YAMLで8進数を書くときは、クォーテーションをしよう!
  • クォーテーションしないと、こういう意味のわからんパーミッションが急に出てきて、死ぬぞ
user@deskmeetserver:/tmp$ ls -ld test_dir/
d-wxrw--wt 2 user user 4096 May 17 09:41 test_dir/
登場人物

・インフラ園児 ニアちゃん
 ・Linuxを中心に触っているインフラエンジニア。
  3歳児だと自分のことを思い込んでいる。
・現場のおねえさん
 ・現場のおねえさん。やさしい。

※パーミッションが変だったのはホントですが、ほかは全部フィクションです。フィクションなんだってば。

ある日の昼下がりのこと。
おねえさん「あのー……」
ニアちゃん「なぁに?」
おねえさん「ニアちゃんが作ったこのディレクトリ、パーミッションおかしくない…………?」

user@deskmeetserver:/tmp$ ls -ld test_dir/
d-wxrw--wt 2 user user 4096 May 17 09:41 test_dir/

ニアちゃん「なにこれ」

おかしいですね。奇っ怪なパーミッションです。
数字にすると1363でしょうか。

いくら経験の浅いニアちゃんといえど、chmod 1363なんて打ったら違和感を感じるはずです。

こんな変なパーミッション、設定したらどうなるんでしょうか?ちょっと見てみましょうか。

ニアちゃん「中のファイルとかもどうなってるんだろう、これ」
ニアちゃん「lsでディレクトリの中身を見ることは…できないね」
おねえさん「ユーザに読み取り権限がないものね」
ニアちゃん「だけどグループには読み取り権限があるから、見られそうな気もするけど」
おねえさん「所有ユーザの場合は、そもそもグループの読み取り権限を参照しないのね。普通ユーザのほうが狭いパーミッションなんてつけないから、おねえさんも知らなかったな」

user@deskmeetserver:/tmp$ ls -la test_dir/
ls: cannot open directory 'test_dir/': Permission denied

ニアちゃん「あっ、中には入れるんだね」
おねえさん「実行権限があるからね」
ニアちゃん「でも読み取り権限はないから、cdしたあとでもやっぱりファイルの一覧は見れないんだね」

user@deskmeetserver:~$ cd test_dir/

user@deskmeetserver:~/test_dir$ ls -la
ls: cannot open directory '.': Permission denied

ニアちゃん「ディレクトリ内にファイルの作成・削除は…できる。書き込み権限はあるからね」
おねえさん「あの、ちょっと勝手に変なファイル作らないで……」

user@deskmeetserver:~/test_dir$ echo hoge > hoge

user@deskmeetserver:~/test_dir$ ls -l hoge
-rw-rw-r-- 1 user user 5 May 17 10:52 hoge

user@deskmeetserver:~/test_dir$ cat hoge
hoge

user@deskmeetserver:~/test_dir$ rm hoge

user@deskmeetserver:~/test_dir$ ls -l hoge
ls: cannot access 'hoge': No such file or directory

ニアちゃん「中にいるファイルは…見れないけど、書き込めるんだね」
おねえさん「ファイルにも書き込み権限がついているみたい」

user@deskmeetserver:~/test_dir$ ll test.txt
--w----r-T 1 user user 21 Jul  7 12:27 test.txt
user@deskmeetserver:~/test_dir$ cat test.txt
cat: test.txt: Permission denied

user@deskmeetserver:~/test_dir$ sudo cat test.txt
test file

user@deskmeetserver:~/test_dir$ cat test.txt
cat: test.txt: Permission denied

user@deskmeetserver:~/test_dir$ sudo cat test.txt
test file
write test

ニアちゃん「削除もできる」
ニアちゃん「ファイルの削除は、ディレクトリの書き込み権限に依存するからね」
おねえさん「あの……勝手にいじらないで……」

user@deskmeetserver:~/test_dir$ rm test.txt

user@deskmeetserver:~/test_dir$ ll test.txt
ls: cannot access 'test.txt': No such file or directory

閑話休題。

問題を起こしたのは、ざっくり下記みたいなPlaybookでした。
(記憶をもとに雑に再現しています)

- hosts: servers
  tasks:
    - name: directory creation
      file:
        path: /tmp/test_dir
        state: directory
        owner: user
        group: user
        mode: 755
    - name: copy test1
      copy:
        src: test.txt
        dest: /tmp/test_dir/test.txt
        owner: user
        group: user
        mode: 644
    - name: copy test2
      copy:
        src: test.txt
        dest: /tmp/test_dir/test2.txt
        owner: user
        group: user
        mode: 600

まずいのはmode: 755の部分。
YAMLの仕様で、0始まりでなくクオートされていない数字は、10進数として解釈されてしまうようです。
そしてこの現象が起こると、かなりの確率で、ユーザに読み取りを許可していない謎のパーミッション状態が誕生します……
755(10進数)=1363(8進数) d-wxrw–wt
644(10進数)=1204(8進数) –w—-r-t
600(10進数)=1130(8進数) —x-wx–t

ひどい罠かと思いきゃ、公式ドキュメントにも、この仕様はちゃんと載っています。

For consistent results, quote octal numbers (for example, ‘644’ or ‘1777’) so Ansible receives a string and can do its own conversion from string into number. Adding a leading zero (for example, 0755) works sometimes, but can fail in loops and some other circumstances.
Giving Ansible a number without following either of these rules will end up with a decimal number which will have unexpected results.

(参考訳)
意図した通りの結果を得るためには、8進数はクォートされなくてはなりません(‘644’や’1777’のように)。これにより、Ansibleは値を文字列として受け取り、Ansible自身で(8進数として)変換されます。
先頭にゼロを付与する方法(0755のように)は、ときに機能しますが、ループやその他の状況下では失敗する可能性があります。
これらのいずれの方法にもよらずに、Ansibleに数値を与えた場合、10進数として解釈され、意図しない結果をもたらします。

上記に則って修正すると……

- hosts: servers
  tasks:
    - name: directory creation
      file:
        path: /home/user/test_dir
        state: directory
        owner: user
        group: user
        mode: '0755'
    - name: copy test1
      copy:
        src: test.txt
        dest: /home/user/test_dir/test.txt
        owner: user
        group: user
        mode: '0644'
    - name: copy test2
      copy:
        src: test.txt
        dest: /home/user/test_dir/test2.txt
        owner: user
        group: user
        mode: '0600'
user@deskmeetserver:~$ ls -ld test_dir/
drwxr-xr-x 2 user user 4096 Jul  7 12:39 test_dir

user@deskmeetserver:~$ ls -l test_dir/
total 8
-rw------- 1 user user 10 Jul  7 12:39 test2.txt
-rw-r--r-- 1 user user 10 Jul  7 12:39 test.txt

想定通りのパーミッションでファイルを作ることができました!

  • YAMLに10進数以外の数字を渡すときには、クォーテーションが必要
    • この問題を踏みやすいものの一つに、ファイルパーミッションの指定がある
  • 騒ぐ前にドキュメントを読もう(自戒)





Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -