※当サイトの記事には、広告・プロモーションが含まれます。

ansible.builtin.templateでリモートのファイルの内容を利用するには

gigazine.net

オープンソースのウェブ開発フレームワークである「Next.js」に、重大な脆弱(ぜいじゃく)性が存在したことが発見されました。この脆弱性を使用すれば攻撃者が認証チェックを回避することが可能であったことが明らかになっています。

数年前からNext.jsに存在していた重大な脆弱性によりハッカーがミドルウェアベースの認証を回避できていたことが明らかに、Vercelは3月18日に脆弱性を修正 - GIGAZINE

ミドルウェアコンポーネント自身が再トリガーする無限ループを防ぐため、Next.jsはミドルウェア関数を適用するかどうかを指定する「x-middleware-subrequest」というヘッダーを採用しています。

数年前からNext.jsに存在していた重大な脆弱性によりハッカーがミドルウェアベースの認証を回避できていたことが明らかに、Vercelは3月18日に脆弱性を修正 - GIGAZINE

「x-middleware-subrequest」は受信リクエストの処理を担当する「runMiddleware」関数によって取得されるのですが、特定の値を持つ「x-middleware-subrequest」が検出されると、ミドルウェア実行チェーン全体がバイパスされ、リクエストが宛先に転送されてしまいます。

数年前からNext.jsに存在していた重大な脆弱性によりハッカーがミドルウェアベースの認証を回避できていたことが明らかに、Vercelは3月18日に脆弱性を修正 - GIGAZINE

つまり、攻撃者は正しい値を持つヘッダーを含むリクエストを手動で送信することで、保護メカニズムをバイパスすることができてしまうわけです。

数年前からNext.jsに存在していた重大な脆弱性によりハッカーがミドルウェアベースの認証を回避できていたことが明らかに、Vercelは3月18日に脆弱性を修正 - GIGAZINE

「CVE-2025-29927」を発見したのは、研究者のAllam Rachid氏とAllam Yasser氏です。両氏は「ヘッダーとその値は、ルールを上書きできるユニバーサルキーとして機能します」と発言しています。

数年前からNext.jsに存在していた重大な脆弱性によりハッカーがミドルウェアベースの認証を回避できていたことが明らかに、Vercelは3月18日に脆弱性を修正 - GIGAZINE

なお、「CVE-2025-29927」に対処するため、Vercelは2025年3月18日にNext.jsの修正バージョンとして15.2.3をリリースしました。この修正パッチを適用できない場合、「x-middleware-subrequest」を含む外部ユーザーリクエストをブロックすることが推奨されています。

数年前からNext.jsに存在していた重大な脆弱性によりハッカーがミドルウェアベースの認証を回避できていたことが明らかに、Vercelは3月18日に脆弱性を修正 - GIGAZINE

フレームワーク内で隠蔽されて、仕組みがブラックボックス化しているからなのか、脆弱性の存在を発見できたのが研究者という...

フレームワーク内で良しなに処理して、フレームワークを利用する開発者が仕組みを意識しないで済むように隠蔽しているのならば、確実に機能を担保して欲しい気はするが...

一応、

nextjs.org

⇧「Next.js」の公式のブログで対応方法などが公開されてはいますが、「認証」周りのセキュリティリスクを潰すのは大変ですな...

ansible.builtin.templateでリモートのファイルの内容を利用するには

無茶苦茶に泥沼にハマったので、備忘録として。

実現したかったことは、ローカル以外に配置されているYAMLファイルに定義していた内容を、「ansible.builtin.template」が参照する「variable」として追加したかったということです。

ネットの情報を漁ってみた感じ、全くもってヒットしなかったのと、ChatGPT氏も全く役に立たなかったので、愚直に試行錯誤した結果、解決方法に辿り着いたのだが、普通に考えて外部から取得した情報を、「Jinja2 テンプレート」で利用したいケースあるあるだと思うのだが、公式のドキュメントに使用例を載せて欲しいと思う今日この頃です...

不毛に消費させられた時間を返して欲しいのと、解決策が見つからずに迷宮入りになったらどうしてくれるんじゃ、というストレスによる精神的苦痛をどうしてくれようか...

「ファインダビリティ(Findability)」の低いドキュメントが、如何に我々にストレスを与えるものかは言わずもがなでしょうか...

と、ボヤきが止まることを知らない感じになってしまうので、備忘録に移ります。

 

とりあえず、

  1. ansible.builtin.fetchでリモートのファイル(Jinja2 テンプレートで参照する値が定義されたJSON、または、YAML)をローカルにコピーする
  2. rolesのタスクでは、vars_files使えないのでansible.builtin.include_varsでファイルを読み込もう
  3. roles/templates/*.j2の中身は用意しておこう
  4. ansible.builtin.fetchでコピーしたファイルは不要になったら削除しよう

という注意点がありますと。

公式のドキュメントを確認すると、

docs.ansible.com

テンプレート作成 (Jinja2)

Ansible は Jinja2 テンプレートを使用して動的な式を有効にし、variables および facts へのアクセスを有効にします。template module でテンプレートを使用できます。たとえば、設定ファイルのテンプレートを作成してから、その設定ファイルを複数の環境にデプロイし、各環境に対して適切なデータ(IP アドレス、ホスト名、バージョン)を指定できます。

https://docs.ansible.com/ansible-core/2.15_ja/playbook_guide/playbooks_templating.html#templating-jinja2

⇧ 上記の説明が分り辛いのだが、「ansible.builtin.include_vars」でYAMLファイルを指定すると、「Ansible」の中ではYAMLファイルのkey: valueの「key」を変数名とした「variables」と解釈されるらしい、多分...

「ansible.builtin.include_vars」の説明を見た感じでは、

docs.ansible.com

⇧『Loads YAML/JSON variables dynamically from a file or directory, recursively, during task runtime.』とあるので、「ansible.builtin.include_vars」が良しなに「Ansible」の「variables」として参照できる形にしてくれるらしい。

実現したい機能で逆引きとかできないから、「ansible.builtin.include_vars」が要件を満たすモジュールであることが分かるまでに時間がかかりましたな...

見つけられたのは、ほぼ、偶然に近い...

■リモート

■Jinja2で参照する変数を定義したファイル

spring_datasource_url: "jdbc:mysql://localhost/test"
spring_datasource_user: "username"
spring_datasource_pass: "dbpass"

■ローカル

■jinja2で置換されるファイル

spring:
  datasource:
    url: {{ spring_datasource_url }}
    username: {{ spring_datasource_user }}
    password: {{ spring_datasource_pass }}

■ローカル

■ロールのタスク

---
- name: Deploy db server
  block:
    - name: Get database connection info from remote
      ansible.builtin.fetch:
        src: /home/remote_user/work/application.yml
        dest: "{{ playbook_dir }}"
    
    - name: Load deploy info
      ansible.builtin.include_vars:
        file: "{{ playbook_dir }}/application.yml"
    
    - name: Setting variable
      ansible.builtin.template:
        src: deploy_info.j2
        dest: /tmp/application.yml

    - name: Remove file in local
      file: 
        path: "{{ playbook_dir }}/application.yml"
        state: absent
      delegate_to: localhost

■ローカル

■プレイブック

---
- hosts: dbservers
  roles:
    - role: deploy_db_server   

⇧ といった感じで、リモートのファイルの値を参照する必要がある場合は、煩雑になってしまいますと...

「インベントリ」を割愛していますが、勿論、「プレイブック」を実行するには「インベントリ」でSSH接続するための情報が必要です。

ちなみに、「ansible.builtin.template」の結果ファイルをリモートではなく、ローカルに配置したい場合は、

stackoverflow.com

⇧「delegate_to:」とか利用する感じになるらしい。

ローカルのファイル削除したい場合なんかも、「delegate_to:」を利用するしか無さそう...

stackoverflow.com

 

stackoverflowではなく、公式ドキュメントで使用例を載せてくれていれば良いのだが、

docs.ansible.com

⇧ 載せてくれていないのよね...

う~む、「Ansible」使い辛過ぎるんだが...

実用的なサンプルが少ないというのが大きいと思うが、公式のドキュメントの情報が微妙なのよね...

少なくとも、「ansible.builtin.template」に必要な情報は外部から取得する形になると思うので、公式のサンプルも実用的なものにしてくれるとありがたいですかね...

docs.ansible.com

docs.ansible.com

ちなみに、

docs.ansible.com

⇧「include_vars」は中々に、「優先順位」が高い。

「ansible-playbook」コマンドの実行時のオプションの「-e」が最強らしい。

上書きされるとしたら、

  1. set_facts / 登録変数
  2. 追加の変数 (例: -e "user=my_user")(常に優先されます)

あたりが起こりがちな気はしますかね。

そして、

docs.ansible.com

⇧「vars_files」は、「プレイ」でしか利用できないから、「ロール」の「タスク」で利用しようとしたらエラーになったということですな...

とりあえず、

automation.ap-com.co.jp

⇧ 上記サイト様の「プレイブックの構成」には出てこないのだけど、「roles:」という「セクション」になるのかは分からないのだが、「vars」や「vars_files」は、「roles/tasks/*.yml」の「タスク」内では利用できないので要注意ですかね...

求める情報に辿り着くまでが毎回綱渡り状態なのがストレスですな...

毎度モヤモヤ感が半端ない…

今回はこのへんで。