0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ansibleが理解できない理由はLinuxにあった【OS編】第4回:【Permission deniedの正体】Linuxユーザーと権限の仕組み

0
Last updated at Posted at 2026-03-23

📚 連載:Ansibleが理解できない理由はLinuxにあった【OS編】第4回:【Permission deniedの正体】Linuxユーザーと権限の仕組み

Linuxの仕組みからAnsibleを理解するシリーズです。

0️⃣ Ansibleの仕組み
1️⃣ Linuxの構造(Kernel / Shell / Filesystem)
2️⃣ command not foundの原因:PATH
3️⃣ SSH接続できない理由:鍵認証とポート
4️⃣ Permission deniedの原因:ユーザーと権限
5️⃣ サービスが起動しない理由:systemd
6️⃣ cronが動かない理由:PATH問題
7️⃣ ディスク満杯になる理由
8️⃣ サーバーが遅くなる理由


🗺️ 初めての方・シリーズの全体像を知りたい方はこちら

本記事は、OSの仕組みからAnsible設計までを繋ぐ連載シリーズの一部です。
「どこから読み始めればいいか」あるいは、「OS/Shell/Ansible編の関係性」 について把握されたい場合は、以下の統合ガイドで整理しています。

→ Ansibleが理解できない理由はLinuxにあった|統合ガイド


📑 【OS編】全体のまとめはこちら

→ Ansibleが理解できない理由はLinuxにあった【OS編】まとめ


📑 連載の移動
前の記事:【OS編】第3回 | 次の記事:【OS編】第5回


:map: シリーズ全体構造(学習 × 問題解決)

本シリーズは
「理解(各記事)」と「問題解決(逆引き辞典)」を組み合わせて
スキルを身につける構成になっています。

この図は、どこから学び、どこに進めばよいかを示した“ロードマップ”です。


📍 現在の位置

現在はこの図の「OS編 第4回」になります


📍 はじめに:この記事のスタンス

SSHの壁を突破し、サーバーに入った後に直面するのが次のエラーです。

  • 「ログインはできているのに、ファイルの編集で Permission denied になる」

  • 「手動で sudo すれば動くのに、Ansible経由だと失敗する」

  • 「とりあえず become: yes を付けているが、裏で何が起きているか説明できない」


⚠️ 注意事項

この記事は、Linuxの権限(パーミッション)やユーザー管理を学術的に網羅する「教科書」ではありません。

目的はただひとつです。

Ansibleで Permission denied が出たとき、
「どのユーザーの、どの権限が足りないのか」を即座に特定することです。

「ログインには成功している。だが、操作が制限される」

この実務上の壁を突破するために、Linuxの「ユーザー・所有者・権限」という3つの属性と、Ansibleの become の挙動を紐解いていきます。


📋 目次

  1. 前回の振り返り(第3回)
  2. 逆引き辞典との連動
  3. Linuxのユーザー:全ての操作は「誰か」に紐付く
  4. パーミッション構造:アクセス制御リストの解析
  5. なぜ Permission denied が起きるのか
  6. sudo とは何か:一時的な権限昇格の仕組み
  7. Ansibleの become:sudo 操作の自動化
  8. Ansibleと権限:実務における定義の整理
  9. 実務における権限管理の典型的な課題
  10. まとめ:事実に基づく「調査の原則」
  11. 次回予告
  12. 連載一覧:Ansibleが理解できない理由はLinuxにあった

1. 前回の振り返り(第3回)

前回の記事では、サーバーまでの通信経路である SSH接続 について解説しました。
UNREACHABLE は、「ネットワーク・設定・認証」のいずれかで通信が止まっている状態でした。

今回は、その先のステップです。サーバー内部に入った後、「特定のファイルやコマンドを触る権利」 があるかどうかの問題を整理します。


↑ 目次に戻る


2. 逆引き辞典との連動

具体的なエラー名から原因を特定したい場合は、以下の逆引き辞典を活用してください。

Ansibleが理解できない理由はLinuxにあった :【保存版】Ansibleトラブル逆引き辞典|エラー別の原因と解決フローまとめ

  • まず「逆引き辞典」で該当ステップを特定する
  • 次に「本編(各連載記事)」で仕組みを理解する

↑ 目次に戻る


3. Linuxのユーザー:全ての操作は「誰か」に紐付く

Linuxにおける「ユーザー」は、操作を行う主体を定義するものです。これらは全て /etc/passwd という構成ファイル(ユーザー定義リスト)によって一元管理されています。

実務上、パーミッションを理解するために整理すべきユーザーは以下の3種類です。

ユーザー種別 主な役割 特徴
root 管理者 全てのファイルに対して「rwx」を無視して操作できる最強の権限。
ログインユーザー 人間がSSH接続する用 ubuntu や ansibleuser 等。通常は自身のホームディレクトリ以外の操作権限が制限されている。
システムユーザー サービス実行用 nginx, postgres 等。特定のミドルウェアを動作させるために定義され、通常は直接ログインを行わない。

🔗 Ansibleとの関係

Ansibleがどのユーザーコンテキストで処理を行うかは、以下の2段階で決定されます。

  1. 接続フェーズ: ansible_user(例: ansibleuser)としてSSHセッションを確立する。

  2. 実行フェーズ: become: yes の指定により、root 等の別ユーザーへと特権昇格(Privilege Escalation)を行う。

Permission denied の多くは、この「実行主体のユーザー」と、次章で解説する「対象ファイルの所有属性」の不一致に起因します。


↑ 目次に戻る


4. パーミッション構造:アクセス制御リストの解析

Linuxの全てのファイルおよびディレクトリには、「どの主体に対し、いかなる操作を許可するか」 を定義した属性が付随しています。Ansibleによる操作が拒否された際、最初に行うべきはこの属性情報の確認です。

ls -l /etc/nginx/nginx.conf
  • 出力結果の構造解析
    ls -l の出力には、アクセス可否を決定する「3つの属性区分」と「3つの権限種別」が定義されています。
- rw- r-- r--  1  root  root  1200 nginx.conf
  ^^^ ^^^ ^^^     ^^^^  ^^^^
  (A) (B) (C)     (1)   (2)   (3)その他

① 3つの属性(誰が)

項目 意味 実務での見方
(1) 所有者 (Owner) ファイルの権限保持者 プログラムの実行ユーザーや root が設定される。
(2) 所有グループ (Group) 権限を共有するグループ 複数ユーザー間で共通の操作権限を付与する際に利用される。
(3) その他 (Others) 上記(1)(2)以外の全員 Ansible(特権昇格なしの状態)は、通常ここに含まれる。

② 3つの権限種別(操作内容)

上記(1)〜(3)の各区分に対し、以下の権限(Permission)が割り当てられます。

  • r (read): ファイルの読み取り許可。

  • w (write): ファイルの書き込み・編集許可。

  • x (execute): プログラムとしての実行許可。


↑ 目次に戻る


5. なぜ Permission denied が起きるのか

このエラーが起きる理由は、第3回の「鍵リスト(authorized_keys)」と同じロジックです。
「属性リストのどこにAnsibleの実行ユーザーが該当し、何の権利が載っているか」 をチェックすれば、原因は自ずと見えてきます。

5-1. 判定のメカニズム

例えば、Ansibleの copy モジュール等で /etc/nginx/nginx.conf を編集しようとした場合、Linux内部では以下の 「優先順位に基づいた照合」 が行われています。

判定ステップ 対象(リスト) 許可内容 (rwx) あなた(Ansible)の結果
Step 1 (A) 所有者(root) rw- (読み書き可) Ansibleは root ではない → 次へ
Step 2 (B) グループ(root) r-- (読み取りのみ) Ansibleはグループ外 → 次へ
Step 3 (C) その他(Ansible) r-- (読み取りのみ) ここに該当!

💡 結論:なぜ制限されたのか

  1. Ansible(ansible_user: ubuntuなど) は、(1)所有者でも(2)グループメンバーでもないため、自動的に 「(3)その他」 として扱われます。
  2. しかし「その他」のリストには r-- しか許可が載っていません。
  3. 結果:Ansibleが書き込み(w)をしようとした瞬間に、Linux側から制限(Permission denied)されます。

5-2. 【検証】あえて「特権なし」で実行する

まず、何の対策もしていない状態のプレイブックで実行してみます。

修正前:特権指定なし(fail_copy.yml)

- name: 権限エラーを発生させる実験
  hosts: test_servers
  # become: yes がないため、一般ユーザー権限で動作する
  tasks:
    - name: 管理者権限が必要な場所にファイルをコピーする
      ansible.builtin.copy:
        src: ./nginx.conf
        dest: /etc/nginx/nginx.conf

出力結果:

(ansible) [ansible@localhost ansible-test]$ ansible-playbook -i ../inventory.ini fail_copy.yml

TASK [管理者権限なしでNginxの設定ファイルをコピーする] ****************************************
fatal: [192.168.1.21]: FAILED! => {
    "ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},
    "changed": false,
    "checksum": "68e3f2711ad342e0eab8fd6a0f53c8c08bc09111",
    "msg": "Destination /etc/nginx not writable"
}

このように、Linuxのパーミッション制限によって書き込みが拒否されます。
このログから、以下の技術的な事実が確認できます。

  1. メッセージ(msg)の定義
    表示されている "msg": "Destination /etc/nginx not writable" は、Ansibleが対象パスへの書き込み権限を確認し、制限されたことを示す定義済みのメッセージです。OSが返却する Permission denied(Errno 13)を、Ansibleが「宛先が書き込み不可の状態である」と具体的なステータスに変換して出力しています。
  2. 処理の進行状況(checksum)
    checksum が表示されていることは、コントロールノード側でのファイル読み取りおよびハッシュ計算、そしてリモートノードへのデータ転送までは正常に完了していることを示しています。
  3. エラー発生のフェーズ
    ステータスが UNREACHABLE ではなく FAILED であることから、SSH認証によるログインは成功しています。最終フェーズである「/etc/nginx へのファイル配置(書き込み操作)」において、Linuxのパーミッション制限により処理が停止したことが確定できます。

結論として、このエラーの原因は「SSH認証の失敗」ではなく、「実行ユーザーの権限と対象ディレクトリのパーミッション設定の不一致」にあります。


↑ 目次に戻る


6. sudo とは何か:一時的な権限昇格の仕組み

「(3)その他」の立場では、システム設定の変更(w)やインストール(x)ができません。しかし、すべてのファイルの所有者を自分に変えるのは、セキュリティ上も運用上も現実的ではありません。

そこで、自分のユーザーのまま 「一時的に root(特権ユーザー)の権限を借りて実行する」 仕組みが sudo です。

  • sudo なし: あなた(一般ユーザー)の権限で実行 → 制限

  • sudo あり: あなたが root に「なり代わって」実行 → 許可

この「なり代わり」ができるかどうかは、/etc/sudoers という 「昇格許可リスト」 にあなたの名前が載っているかどうかで決まります。Linuxはここでも「リスト照合」を行っています。


↑ 目次に戻る


7. Ansibleの become:sudo 操作の自動化

Ansibleで Permission denied を回避するために使う become: yes は、内部的に sudo 操作を自動化するスイッチです。

7-1. 処理フローの全体像

Ansibleが裏側で行っているステップを分解します。


[コントロールノード]
    ↓
SSH接続(ansible_user: ansibleuser)
    ↓
一般ユーザーとしてログイン(この時点では権限不足)
    ↓
(タスク実行)
    ↓
become: yes を検知 → 内部で sudo コマンドを発行
    ↓
root(特権ユーザー)へ昇格
    ↓
ファイルの配置(書き込み)に成功

  • 重要な事実: Ansibleは独自の特殊な通信を行っているわけではなく、「SSHでログインした後に、人間と同じように sudo を叩く」 という手順を自動で行っているだけです。

7-2. 【検証】become: yes を記述して再実行

第5セクションでエラーになったプレイブックに対し、become: yes を記述して、特権昇格を伴う実行へと構成を変更します。

修正後:特権昇格を有効化(fail_copy.yml)


- name: 権限エラーを解消する実験
  hosts: test_servers
  become: yes  # ここで特権昇格を有効化
  tasks:
    - name: 管理者権限でNginxの設定ファイルをコピーする
      ansible.builtin.copy:
        src: ./nginx.conf
        dest: /etc/nginx/nginx.conf

実行結果:

(ansible) [ansible@localhost ansible-test]$ ansible-playbook -i ../inventory.ini fail_copy.yml

TASK [管理者権限でNginxの設定ファイルをコピーする] ****************************************
changed: [192.168.1.21]

PLAY RECAP ********************************************************************************
192.168.1.21               : ok=1    changed=1    unreachable=0    failed=0 ...

先ほどは FAILED で停止していましたが、今回は changed となり、正常にファイルが配置されました。

💡 なぜ成功したのか

  1. 昇格の実行: become: yes により、Ansibleがリモート先で sudo を実行しました。

  2. 権限の充足: ansibleuser が一時的に root(所有者)の権限で動作したため、判定メカニズムの Step 1(所有者判定) において書き込み許可(w)が得られました。

  3. 状態の変更: その結果、OSによる制限を受けることなく、/etc/nginx/nginx.conf の更新が完了しました。


7-3. リモートノード側での最終確認

処理の結果、リモートサーバー内の状態がどう変化したかを物理的に確認します。

[root@localhost ~]# ls -l /etc/nginx/
合計 4
-rw-r--r--. 1 root root 2334  4月 25 13:19 nginx.conf

ファイルの所有者が root になっている点に注目してください。
一般ユーザーでログインしても、become: yes を介することで、最終的に root 権限でファイルが書き込まれたことが、この属性表示からも裏付けられます。


↑ 目次に戻る


8. Ansibleと権限:実務における定義の整理

実務において、Ansibleの変数とLinuxのシステム構成がどのように紐付いているかを整理します

Linuxの概念 Ansibleの変数名 役割
リモートログインユーザー ansible_user SSH認証を行い、セッションを開始するユーザー
特権昇格(Privilege Escalation) become: yes ログイン後に特定の権限への昇格を試行する設定
昇格先のユーザー become_user 昇格後の実行コンテキストとなるユーザー(デフォルトは root)

💡 実行ユーザーとシステムユーザーの分離

実務上の誤解として、「Nginxの設定ファイルを操作するために ansible_user: nginx を指定する」というケースが見受けられますが、これは技術的に以下の理由で推奨されません。

  • SSHログインの可否:
    nginx や apache といったシステムユーザーは、セキュリティ上の観点から「ログインシェルを持たない(/sbin/nologin 等)」設定となっており、外部からのSSH接続自体が制限されているのが一般的です。

  • 適切な運用フロー:
    まずはSSH接続権限を持つ一般ユーザー(ansible_user)としてセッションを確立し、その後にAnsibleの become プロセスを通じて、必要な権限(root または特定のシステムユーザー)へと処理を移行させるのが正しい構成となります。


↑ 目次に戻る


9. 実務における権限管理の典型的な課題

Ansibleを用いた自動化において、権限設定に起因する代表的な構成ミスとその対策を整理します

1. 特権昇格指定(become)の欠落

/etc ディレクトリ配下の設定ファイル変更や、パッケージマネージャーによるインストール等、root権限を要するタスクにおいて become: yes の記述が漏れているケースです。

  • 技術的影響: 第5セクションで詳述した通り、OSによる書き込み制限(Permission denied)が発生し、タスクが異常終了します。

  • 対策: 管理者権限を必要とするタスク、あるいはプレイ全体に対して、明示的に become: yes を定義し、適切な実行コンテキストを確保してください。

2. ファイル属性(所有者・グループ)の定義不足

copy モジュール等でファイルを配置した際、明示的な指定がないと所有者が root(昇格後のユーザー)となります。これにより、アプリケーション実行ユーザー(nginx 等)がファイルを読み込めなくなる事象が発生します。

  • 技術的影響: 配置されたファイルのパーミッションにおいて、実行ユーザーが「その他(Others)」に分類され、読み取り権限(r)が不足している場合にアプリケーションが正常に動作しません。

  • 対策: タスク内で owner および group パラメーターを用い、対象ユーザー・グループを明示的に指定してください。

3. 不適切なパーミッション設定(chmod 777)

権限エラーの回避を目的として、ディレクトリやファイルに 777(すべてのユーザーに全権限を付与)を設定する運用です。

  • 技術的影響: 第3セクションで解説したLinuxのセキュリティモデルを無効化する行為であり、重大な脆弱性に繋がります。

  • 対策: 最小権限の原則(Principle of Least Privilege)に基づき、所有者・グループの属性を正しく定義した上で、必要最小限の権限(例:ファイルは 644、ディレクトリは 755)を設定してください。


↑ 目次に戻る


10. まとめ:事実に基づく「調査の原則」

Permission denied に直面した際、Ansibleのパラメーターを場当たり的に変更するのではなく、まずは以下の3ステップでOS側の「事実」を特定してください。

これは第4セクションで解説したパーミッションの判定構造(誰が・何を・どの権限で)を、そのまま調査手順へと落とし込んだものです。

【Permission denied の調査手順】

  1. プロセスの実行主体(誰)を特定する

    • ansible_user および become の有無から、リモート側での実効ユーザーを確定させる。
  2. 対象オブジェクトの属性(何に)を確認する

    • ls -l コマンドにより、対象の所有者・グループ・パーミッション設定を物理的に確認する。
  3. 権限の不整合(なぜ)を解消する

    • 実行主体が属性リストの認可範囲に含まれていない場合、以下のいずれか、または両方を選択する。
      ・become による適切な権限への昇格。
      ・owner / group / mode による対象の属性修正。

調査の原則

Permission denied は、Ansibleというツールのエラーではなく、「Linuxカーネルによる正当なアクセス制限」 です。

第2回のPATH、第3回の鍵リストの検証と同様に、「ls -l という属性リストにおいて、自身がどの階層に該当し、いかなる権限を付与されているか」。この一点を事実として確認することが、解決への最短経路となります。

「Ansibleの設定を疑う前に、Linuxの属性リストを確認する」

この原則を徹底することで、権限に関するトラブルシューティングの精度は飛躍的に向上します。


↑ 目次に戻る


📚 シリーズを順番に読む

このシリーズでは Linuxの仕組みからAnsibleを理解する ことを目的にしています。

回 内容
第0回 Ansibleの仕組み
第1回 Linuxの構造(Kernel / Shell / Filesystem)
第2回 command not foundの原因:PATH
第3回 SSH
第4回 Permission deniedの原因
第5回 systemd
第6回 cron
第7回 ディスク容量
第8回 サーバーが遅い原因

11. 次回予告

権限設定(Privilege Escalation)の課題を解消し、次なるステップはアプリケーションサービスの起動です。
しかし、正常に構成されたプレイブックであっても、実行時に以下のエラーに直面するケースが多々あります。

"FAILED! => msg: Job for nginx.service failed because the control process exited with error code."

Ansibleにはサービス制御を司る以下のモジュールが存在します。

  • ansible.builtin.service

  • ansible.builtin.systemd

「適切な権限を付与し、become: yes も定義した。それにもかかわらず、なぜサービスユニットの起動に失敗するのか?」

次回は、Linuxにおけるサービス管理の標準アーキテクチャである 「systemd」 の構造と、Ansibleによる制御メカニズムを詳述します。OS側のサービス管理の「裏側」を理解し、トラブルシューティングの精度をさらに高めていきましょう。

次回:【第5回】サービスが起動しない理由:systemdの仕組みを理解する


↑ 目次に戻る


📑 連載の移動
前の記事:【OS編】第3回 | 次の記事:【OS編】第5回


📑 【OS編】全体のまとめはこちら

→ Ansibleが理解できない理由はLinuxにあった【OS編】まとめ


🗺️ 初めての方・シリーズの全体像を知りたい方はこちら

本記事は、OSの仕組みからAnsible設計までを繋ぐ連載シリーズの一部です。
「どこから読み始めればいいか」あるいは、「OS/Shell/Ansible編の関係性」 について把握されたい場合は、以下の統合ガイドで整理しています。

→ Ansibleが理解できない理由はLinuxにあった|統合ガイド


12. 連載一覧:Ansibleが理解できない理由はLinuxにあった

回数とタイトル 内容(概要)
Ansibleが理解できない理由はLinuxにあった【OS編】:【保存版】Ansibleトラブル逆引き辞典(Linux / SSH / Shellエラー対応 Ansibleで発生するエラー(UNREACHABLE / Permission denied / command not found など)を「エラーから逆引き」で調べられる実務向け記事。各回の内容と対応しており、トラブル時の入口として使える。
第0回:【なぜAnsibleは理解できないのか】仕組みを分解してみる Ansibleは「Linux操作の自動化」ツール。Ansible → SSH → Shell → Linux の構造を理解し、シリーズ全体の土台を作る。
第1回:【なぜLinuxが分からないと詰むのか】Kernel / Shell / Filesystemの全体像 Linuxの基本構造を理解することで、Ansibleが内部で何をしているのか(Shell実行・プロセス・ファイル操作)を把握できるようになる。
第2回:【Ansibleでハマる】command not foundの原因はPATHだった(環境変数の正体) Ansible実行時に発生する「command not found」の原因はPATHにある。環境変数の仕組みを理解しないとエラーを解決できない。
第3回:AnsibleのSSH接続が失敗すると UNREACHABLE エラーになる。(Connection refused / Permission denied / Timeout など) AnsibleのSSH接続が失敗すると UNREACHABLE エラーになる。SSH(鍵認証・ポート・Firewall)を理解することで原因を特定できる。
第4回:【Permission deniedの正体】Linuxユーザーと権限の仕組み Ansibleのbecome(sudo)で発生する Permission denied の原因はLinux権限にある。ユーザー・グループ・権限の仕組みを理解する。
第5回:【サービスが起動しない理由】systemdの仕組みを理解する Ansibleのservice / systemdタスクが失敗する原因はLinux側にある。systemdの仕組みを理解することで原因を特定できる。
第6回:【cronが動かない理由】手動では動くのに失敗する原因 Ansibleで設定したcronが動かない原因は環境差分(PATHなど)にある。cron特有の実行環境を理解することで解決できる。
第7回:【No space left on device】ディスク容量不足の原因と調査方法(df / du / log) Ansible実行時のディスク不足エラーはLinuxのログ肥大化や容量管理が原因。df / duを使った調査方法を解説する。
第8回:【サーバーが遅い】原因の見つけ方(CPU / メモリ / プロセス) Ansible実行が遅い・失敗する原因はサーバー負荷の可能性がある。CPU・メモリ・プロセスの見方を理解して原因を特定する。

↑ 目次に戻る

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?