<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>乱筆</title>
        <link>https://blog.l3zc.com/ja/</link>
        <description>Recent content on 乱筆</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>ja</language><atom:link href="https://blog.l3zc.com/ja/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Terraform IaC 初体験</title>
            <link>https://blog.l3zc.com/ja/2026/04/iac-with-terraform/</link>
            <pubDate>Thu, 09 Apr 2026 07:13:35 +0000</pubDate>
            <guid>https://blog.l3zc.com/ja/2026/04/iac-with-terraform/</guid>
            <description>&lt;img src=&#34;https://blog.l3zc.com/2026/04/iac-with-terraform/cover_hu_a8e83f97ed61569c.webp&#34; alt=&#34;Featured image of post Terraform IaC 初体験&#34; /&gt;&lt;p&gt;Terraform は IaC ツールであり、IaC とは「インフラストラクチャ・アズ・コード」を意味します。私たちが持つインフラストラクチャを宣言的なコードとして記述し、その後 &lt;code&gt;terraform apply&lt;/code&gt; を実行することでインフラストラクチャのデプロイが完了します。同一の設定であれば、必ず同じインフラストラクチャがデプロイされます（Nix OS ユーザーにとっては大喜びの内容です）。&lt;/p&gt;&#xA;&lt;h2 id=&#34;terraform-を使用する理由&#34;&gt;Terraform を使用する理由&#xA;&lt;/h2&gt;&lt;p&gt;従来のインフラストラクチャ管理の大部分は人的作業と各種クラウドプロバイダーのダッシュボードに依存しており、以下のような課題が生じています：&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th style=&#34;text-align: left&#34;&gt;課題&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: left&#34;&gt;説明&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;再現性の欠如&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;ダッシュボードでのクリック操作による設定変更は、誤りや見落としが発生しやすく、復元も困難&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;環境ドリフト&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;手動操作により本番環境とテスト環境の設定が徐々に乖離し、極端なケースではテストでは問題ないのに本番でダウンすることがある&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;拡張の難しさ&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;新しい環境を追加するには多数の手動作業を繰り返す必要があり、時間がかかりミスも発生しやすい&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;監査の難しさ&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;変更履歴がないため、&lt;del&gt;トラブル発生時に責任の所在を特定するのが難しい&lt;/del&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;&lt;strong&gt;協力の難しさ&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: left&#34;&gt;インフラストラクチャは少数の「詳しい人」によって管理されており、誰かが変更したい場合でもその人を探さなければならず効率が悪い&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;これらの問題を解決するために、「インフラストラクチャ・アズ・コード」&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; という概念が提唱され、Terraform はその有名なソリューションの一つです。&lt;/p&gt;&#xA;&lt;p&gt;実際のユースケースを想定してみます。例えば、毎年新しい GCP の$300 無料クレジットアカウントを購入する場合、安価ですが毎年 GCP のパネルで再度マシンを立て直す必要があります。しかし、Terraform を使えば、同じ設定のマシンをデプロイしたい場合、アカウントを変更するたびに API Token を新しいものに置き換え、&lt;code&gt;terraform apply&lt;/code&gt; を実行するだけです。数分で前のアカウントと同じマシン、VPC、S3、ファイアウォール設定などを作成できます。&lt;/p&gt;&#xA;&lt;p&gt;また、Cloudflare DNS や Tunnel の管理・移行においても、元の Tunnel の Ingress Rule を新しい Tunnel の Ingress Rule にコピーするだけで済みます。将来的に AliDNS、Route 53 など他のプロバイダーに移行する場合でも、データをそのままコピーすれば&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;対応可能です。&lt;/p&gt;&#xA;&lt;p&gt;特に複数人で協力する場合、Git と組み合わせることで変更の痕跡が残り、マージ競合の心配もありません。PR には変更プレビューが自動生成され、問題が発生すればすぐに前バージョンにロールバックできます。これらは従来の人手によるプロバイダーダッシュボードへの直接操作では到底不可能なことです。&lt;/p&gt;&#xA;&lt;h2 id=&#34;terraform-のインストール&#34;&gt;Terraform のインストール&#xA;&lt;/h2&gt;&lt;p&gt;Terraform は Go で書かれており、コンパイルされた出力は単一の実行可能ファイルであるため、インストールも非常に簡単です。Windows では Winget を直接使用できます：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-pwsh&#34;&gt;winget install Hashicorp.Terraform&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Winget を使いたくない場合は、Scoop などの別のパッケージマネージャーを使用するか、事前コンパイルされたバイナリファイルを &lt;code&gt;$PATH&lt;/code&gt; に配置するだけでインストールが完了します。&lt;/p&gt;&#xA;&lt;p&gt;Linux 環境の場合は、対応するパッケージマネージャーを使用してインストールしてください。バイナリファイルを &lt;code&gt;$PATH&lt;/code&gt; に配置する方法を使う場合は、&lt;code&gt;sudo chmod +x terraform&lt;/code&gt; でファイルの実行権限を設定することを忘れないでください。&lt;/p&gt;&#xA;&lt;h2 id=&#34;terraform-の-2-つの基本概念&#34;&gt;Terraform の 2 つの基本概念&#xA;&lt;/h2&gt;&lt;h3 id=&#34;providers&#34;&gt;Provider(s)&#xA;&lt;/h3&gt;&lt;p&gt;前述の通り、Terraform はインフラストラクチャ・アズ・コードツールですが、ツール自体は特定のプラットフォームにバインドされておらず、Provider(s) を通じて各プラットフォームと連携します。利用可能な Provider(s) を確認するには、&lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/browse/providers&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Terraform のレジストリ&lt;/a&gt;を参照してください。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2026/04/iac-with-terraform/image_hu_463ebc576c22c691.webp&#34; alt=&#34;Terraform は豊富な Provider(s) エコシステムを持つ&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;h3 id=&#34;状態管理&#34;&gt;状態管理&#xA;&lt;/h3&gt;&lt;p&gt;Terraform はインフラストラクチャ変更操作を実行する際の状態情報を状態ファイルに保存します。デフォルトでは現在の作業ディレクトリ内の &lt;code&gt;terraform.tfstate&lt;/code&gt; ファイルに保存されます&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;。構成ファイルを変更して他のストレージバックエンド（S3、Postgres など）を指定することも可能です。&lt;code&gt;terraform apply&lt;/code&gt; を実行するたびに、Terraform は現在の構成ファイルで宣言された状態と既存の状態ファイルを比較し、変更部分を計算して調整順序を自動的に決定した後、Provider を操作して状態変動を実現します。&lt;/p&gt;&#xA;&lt;h2 id=&#34;terraform-のリソースインポートの難題&#34;&gt;Terraform のリソースインポートの難題&#xA;&lt;/h2&gt;&lt;p&gt;既存リソースのインポートはこれまで Terraform が批判されてきた問題点であり、Hashi Corp. は一貫して「すべてのインフラストラクチャは最初から Terraform で作成されるべきであり、リソースインポートの問題などは存在しない」という頑固で愚かな見解を堅持しているようです。&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;時期&lt;/th&gt;&#xA;          &lt;th&gt;バージョン&lt;/th&gt;&#xA;          &lt;th&gt;進展&lt;/th&gt;&#xA;          &lt;th&gt;問題&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;2014–2022&lt;/td&gt;&#xA;          &lt;td&gt;v0.x–v1.4&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;terraform import&lt;/code&gt; のみで、一度に 1 件ずつ、かつ全く設定を生成しない&lt;/td&gt;&#xA;          &lt;td&gt;インポート後でも自分で HCL&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; を書く必要がある&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;2023.06&lt;/td&gt;&#xA;          &lt;td&gt;v1.5&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;import&lt;/code&gt; ブロックと &lt;code&gt;-generate-config-out&lt;/code&gt; パラメータを導入し、設定を生成可能になった&lt;/td&gt;&#xA;          &lt;td&gt;それでも 1 行ずつ書く必要があり、既存リソースの ID も自分で提供しなければならない&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;2024.01&lt;/td&gt;&#xA;          &lt;td&gt;v1.7&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;import&lt;/code&gt; ブロックが &lt;code&gt;for_each&lt;/code&gt; をサポート&lt;/td&gt;&#xA;          &lt;td&gt;バッチ処理が可能になったが、ID はまだ自分で用意する必要がある&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;2024 年下半期&lt;/td&gt;&#xA;          &lt;td&gt;v1.12&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;terraform query&lt;/code&gt; と &lt;code&gt;list&lt;/code&gt; ブロックを導入し、ついにリソースの自動発見機能を達成&lt;/td&gt;&#xA;          &lt;td&gt;ただしこの機能は Provider が実装する必要があり、多くの Provider が追いついていない&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;長年の間、コミュニティは批判し続けていますが、「既存のリソースをどうやって Terraform にインポートするか」という問題は真剣に取り組まれていませんでした。「インフラストラクチャ・アズ・コード」ツールである Terraform の設計哲学は宣言性と冪等性&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;であり、Hashi Corp. は「すべてはコード声明された状態が基準であり、Terraform でゼロからリソースを作成すべきだ」と信じています。しかし現実には、ほとんどの企業には大量の歴史的残存リソースがあり、「先にリソースがあり、後にコードがある」のが常态です。この矛盾を Hashi Corp. が認めたのは遅く、&lt;code&gt;v1.12&lt;/code&gt; の &lt;code&gt;terraform query&lt;/code&gt; になって初めて公式にこの問題に対処しましたが、Provider エコシステムの追従状況……正直言って期待薄です。&lt;/p&gt;&#xA;&lt;h2 id=&#34;terraform-のファイル構造&#34;&gt;Terraform のファイル構造&#xA;&lt;/h2&gt;&lt;p&gt;Terraform のファイル構造はシンプルで、メインプログラムは実行時、作業ディレクトリ内のすべての &lt;code&gt;.tf&lt;/code&gt; ファイルを盲目的に読み取ります。情報さえ揃っていれば、ファイル名は何でも好きなように付けられます。私のファイル構造はこのようになります：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;❯ tree -a -I .git&#xA;.&#xA;├── .editorconfig&#xA;├── .github&#xA;│   ├── dependabot.yml&#xA;│   └── workflows&#xA;│       ├── terraform-apply.yml&#xA;│       ├── terraform-plan.yml&#xA;│       └── your-fork.yml&#xA;├── .gitignore&#xA;├── .terraform.lock.hcl&#xA;├── cf_dns_zones.tf&#xA;├── cf_tunnel.tf&#xA;├── dns_example_com.tf&#xA;├── dns_example_net.tf&#xA;├── dns_example_top.tf&#xA;├── dns_example_cn.tf&#xA;├── main.tf                 # ベース設定（terraform ブロック）&#xA;├── moved.tf                # 移動したリソース&#xA;├── provider.tf             # 各 Provider の設定&#xA;├── README.md&#xA;├── rename_resources.ps1&#xA;└── variables.tf            # カスタム変数&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;main.tf&lt;/code&gt;はベース設定を保存するために使用されます：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-hcl&#34;&gt;terraform {&#xA;  required_providers {&#xA;    cloudflare = {&#xA;      source  = &#34;cloudflare/cloudflare&#34;&#xA;      version = &#34;~&gt; 5&#34;&#xA;    }&#xA;&#xA;    tencentcloud = {&#xA;      source  = &#34;tencentcloudstack/tencentcloud&#34;&#xA;      version = &#34;&gt;= 1.81.43&#34;&#xA;    }&#xA;  }&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;provider.tf&lt;/code&gt;は各 Provider の設定を保存するために使用されます：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-hcl&#34;&gt;provider &#34;cloudflare&#34; {}&#xA;provider &#34;tencentcloud&#34; {}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ここが空なのは、Credentials を構成ファイルに直接書くのではなく、環境変数を通じて渡せるからです。例えば Cloudflare の Provider は、&lt;code&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt; を &lt;code&gt;api_token&lt;/code&gt; 変数の代替として受け入れます。&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;variables.tf&lt;/code&gt;はカスタム変数を宣言するために使用されます：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;variable &#34;cloudflare_zone_example_com&#34; {&#xA;  description = &#34;example.com の Cloudflare zone ID&#34;&#xA;  type        = string&#xA;}&#xA;&#xA;variable &#34;cloudflare_zone_example_top&#34; {&#xA;  description = &#34;example.top の Cloudflare zone ID&#34;&#xA;  type        = string&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これらの変数は &lt;code&gt;TF_VAR_&lt;/code&gt; で始まる環境変数を通じて入力でき、Terraform は &lt;code&gt;terraform.tfvars&lt;/code&gt; ファイルの変数も自動的に読み取ります。変数の主な用途は、他の構成ファイルから呼び出すことです。例えば：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-hcl&#34;&gt;resource &#34;cloudflare_dns_record&#34; &#34;example_cname&#34; {&#xA;  content = &#34;${cloudflare_zero_trust_tunnel_cloudflared.Production_Tunnel.id}.cfargotunnel.com&#34;&#xA;  name    = &#34;example.example.com&#34;&#xA;  proxied = true&#xA;  tags    = []&#xA;  ttl     = 1&#xA;  type    = &#34;CNAME&#34;&#xA;  zone_id = var.cloudflare_zone_id_example_com  # ここでは cloudflare_zone_example_com 変数が呼び出されている&#xA;  settings = {&#xA;    flatten_cname = false&#xA;  }&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これらの基本設定があれば、&lt;code&gt;terraform init&lt;/code&gt; を実行して Terraform 環境を初期化し、依存関係のバージョンをロックできます。残りの部分はすべてリソースの宣言となります。&lt;/p&gt;&#xA;&lt;h2 id=&#34;既存リソースを-terraform-にインポートする&#34;&gt;既存リソースを Terraform にインポートする&#xA;&lt;/h2&gt;&lt;p&gt;前述の通り、Terraform の状態管理という概念は素晴らしいですが、初期化時には新たな問題をもたらしました——デフォルト状態では、Terraform の状態ファイルは明らかに空です。&lt;/p&gt;&#xA;&lt;p&gt;此時、私たちはクラウドサービスプロバイダー上の既存リソースの状態を Terraform にインポートする必要があります。そうすることで初めて、Terraform は私たちのインフラストラクチャをシームレスに引き継いで管理できます。皆さんも前節で Terraform リソースインポート問題に対する不満を確認したと思います。Cloudflare 上でホストされている DNS レコードのインポートを例にとると、前述のように Provider がサポートしていれば、Terraform 1.12 バージョン以降で導入された &lt;code&gt;terraform query&lt;/code&gt; を使用できますが、多くの場合、Providers はこの新機能に対応していません。Cloudflare は対応していないタイプのひとつです。&lt;/p&gt;&#xA;&lt;p&gt;幸いにも Hashi Corp. が真面目に解決しようとしなくても、Terraform を使ってインフラを管理している各社はそれぞれの知恵を出し合っています。Cloudflare は &lt;a class=&#34;link&#34; href=&#34;https://github.com/cloudflare/cf-terraforming&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;cf-terraforming&lt;/a&gt; という名のインポートツールを維持しており、多くの手動インポートの手間を省いています。まず &lt;code&gt;cf-terraforming&lt;/code&gt; をインストールします。このツールは Go 言語で書かれているため、Go 言語環境が必要です。あるいは公式にコンパイルされたバイナリファイルを &lt;code&gt;$PATH&lt;/code&gt; に配置して実行権限を与える方法もあります。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;go install github.com/cloudflare/cf-terraforming/cmd/cf-terraforming@latest&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このツールの使い方は比較的シンプルです。まず以下の環境変数が必要です：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;# API Token を使用する場合&#xA;export CLOUDFLARE_API_TOKEN=&#39;Hzsq3Vub-7Y-hSTlAaLH3Jq_YfTUOCcgf22_Fs-j&#39;&#xA;&#xA;# API Key を使用する場合&#xA;export CLOUDFLARE_EMAIL=&#39;user@example.com&#39;&#xA;export CLOUDFLARE_API_KEY=&#39;1150bed3f45247b99f7db9696fffa17cbx9&#39;&#xA;&#xA;# 対象とするドメインのゾーン ID を指定。アカウントリソース（Cloudflare Tunnel など）をインポートする場合は不要&#xA;export CLOUDFLARE_ZONE_ID=&#39;81b06ss3228f488fh84e5e993c2dc17&#39;&lt;/code&gt;&lt;/pre&gt;&lt;blockquote class=&#34;alert alert-tip&#34;&gt;&#xA;        &lt;div class=&#34;alert-header&#34;&gt;&#xA;            &lt;span class=&#34;alert-icon&#34;&gt;💡&lt;/span&gt;&#xA;            &lt;span class=&#34;alert-title&#34;&gt;ヒント&lt;/span&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;div class=&#34;alert-body&#34;&gt;&#xA;            &lt;p&gt;ここでのコマンドは Bash を使用していることを前提としています。Bash 構文と互換性のない Shell を使用している場合は調整が必要です。例えば Windows 上の PowerShell では、環境変数のインポート構文は次のようになります：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-pwsh&#34;&gt;$env:CLOUDFLARE_API_TOKEN=&#39;Hzsq3Vub-7Y-hSTlAaLH3Jq_YfTUOCcgf22_Fs-j&#39;&lt;/code&gt;&lt;/pre&gt;&#xA;        &lt;/div&gt;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;通常は &lt;code&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt; と &lt;code&gt;CLOUDFLARE_ZONE_ID&lt;/code&gt; だけ設定すれば十分です。コンソールで API Token を作成する際は、この Token に必要な権限を付与することを忘れないでください。今回は DNS レコードだけをインポートするので、ゾーン DNS の編集権限だけ付与すれば OK です。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2026/04/iac-with-terraform/image-1_hu_15298d4bd366a377.webp&#34; alt=&#34;リソース操作に必要な権限を付与する&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;準備完了です。今から構成ファイルを生成しましょう：&lt;/p&gt;&#xA;&lt;p&gt;まずアカウント内のドメイン構成をインポートします。つまり &lt;code&gt;cloudflare_zone&lt;/code&gt; です：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;cf-terraforming generate \&#xA;  --key $CLOUDFLARE_API_KEY \&#xA;  --resource-type &#34;cloudflare_zone&#34; &gt; zone.tf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このステップで現在のディレクトリに &lt;code&gt;zone.tf&lt;/code&gt; という名前のファイルが生成され、以下のフォーマットのコンテンツが含まれます：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-hcl&#34;&gt;resource &#34;cloudflare_zone&#34; &#34;REDACTED&#34; {&#xA;  name                = &#34;REDACTED&#34;&#xA;  paused              = false&#xA;  type                = &#34;full&#34;&#xA;  vanity_name_servers = []&#xA;  account = {&#xA;    id   = &#34;REDACTED&#34;&#xA;    name = &#34;REDACTED&#34;&#xA;  }&#xA;}&#xA;&#xA;resource &#34;cloudflare_zone&#34; &#34;REDACTED&#34; {&#xA;  name                = &#34;REDACTED&#34;&#xA;  paused              = false&#xA;  type                = &#34;full&#34;&#xA;  vanity_name_servers = []&#xA;  account = {&#xA;    id   = &#34;REDACTED&#34;&#xA;    name = &#34;REDACTED&#34;&#xA;  }&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これでドメインリソースはインポートされましたが、中身の設定はまだありません。次に、ドメイン内の DNS レコードをインポートします：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;cf-terraforming generate \&#xA;  --zone $CLOUDFLARE_ZONE_ID \&#xA;  --key $CLOUDFLARE_API_KEY \&#xA;  --resource-type &#34;cloudflare_dns_record&#34; &gt;&gt; dns.tf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このステップで現在のディレクトリに &lt;code&gt;dns.tf&lt;/code&gt; という名前の構成ファイルが生成され、以下のフォーマットのコンテンツが含まれます：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-hcl&#34;&gt;resource &#34;cloudflare_dns_record&#34; &#34;terraform_managed_resource_5deb14xxxxxb629bf123xxxxxxxc8f_0&#34; {&#xA;  content  = &#34;67.24.33.108&#34;&#xA;  name     = &#34;example.example.com&#34;&#xA;  proxied  = true&#xA;  tags     = []&#xA;  ttl      = 1&#xA;  type     = &#34;A&#34;&#xA;  zone_id  = &#34;81c7f2de8dfxxxxxx52629xxxxxxfc&#34;&#xA;  settings = {}&#xA;}&#xA;&#xA;resource &#34;cloudflare_dns_record&#34; &#34;terraform_managed_resource_89xxxxx0bf9cxxxxxx9a_1&#34; {&#xA;  content  = &#34;35.27.108.33&#34;&#xA;  name     = &#34;terraform.example.com&#34;&#xA;  proxied  = true&#xA;  tags     = []&#xA;  ttl      = 1&#xA;  type     = &#34;A&#34;&#xA;  zone_id  = &#34;8xxxxxx7644e428526xxxxxx&#34;&#xA;  settings = {}&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;複数のドメインをインポートする場合は、環境変数 &lt;code&gt;CLOUDFLARE_ZONE_ID&lt;/code&gt; をそれぞれ設定し、コマンドを繰り返し実行してください。&lt;/p&gt;&#xA;&lt;p&gt;ここで生成された構成ファイルはそのまま使用可能です。これが私たちが後に必要な Terraform 構成ファイルです。しかし、現時点では単に構成ファイルが生成されただけで、Terraform の状態はまだ空のままです。ここでいきなり &lt;code&gt;terraform apply&lt;/code&gt; を実行すると、Terraform は文脈に関係なく新しくインポートした宣言をすべて新規リソースとして扱い、「Already Exists」というエラーメッセージを大量に表示します。そこで次に、生成された構成ファイルを Terraform の &lt;code&gt;terraform.tfstate&lt;/code&gt; 状態にインポートする必要があります。&lt;/p&gt;&#xA;&lt;p&gt;Terraform は 1.5 バージョンで &lt;code&gt;import&lt;/code&gt; ブロックを導入し、以前のような 1 行ずつコマンドを入力する方式よりも現代的になりました。そのインポートフローは、まず &lt;code&gt;import&lt;/code&gt; ブロックを含む &lt;code&gt;.tf&lt;/code&gt; ファイルを生成し、次回の &lt;code&gt;terraform apply&lt;/code&gt; 時に Terraform が自動的にインポート操作を実行します。&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;cloudflare_zone&lt;/code&gt; の &lt;code&gt;import&lt;/code&gt; ブロックを生成：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;cf-terraforming import \&#xA;  --resource-type &#34;cloudflare_zone&#34; \&#xA;  --modern-import-block \&#xA;  --key $CLOUDFLARE_API_KEY \&#xA;  --zone $CLOUDFLARE_ZONE_ID &gt;&gt; import.tf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;cloudflare_dns_record&lt;/code&gt; の &lt;code&gt;import&lt;/code&gt; ブロックを生成：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;cf-terraforming import \&#xA;  --resource-type &#34;cloudflare_dns_record&#34; \&#xA;  --modern-import-block \&#xA;  --key $CLOUDFLARE_API_KEY \&#xA;  --zone $CLOUDFLARE_ZONE_ID &gt;&gt; import.tf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このステップで現在のディレクトリに &lt;code&gt;import.tf&lt;/code&gt; が生成されます。必要なインポート情報が含まれており、役割は Terraform に上一步で生成された各 &lt;code&gt;resource&lt;/code&gt; ブロックが、どのクラウドプロバイダーのリソース ID に対応するのかを教えることです。この ID はクラウドプロバイダー内部でリソースをマークするコードであり、普段はコントロールパネルに表示されません。API で特別にリクエストしない限り知ることはできません。Terraform はインポートプロセス中にこの ID を使用して、ローカルの定義がクラウド上のどのリソースに対応しているかを確認し、厳密な冪等性を実現します。&lt;/p&gt;&#xA;&lt;p&gt;さて、ここでは &lt;code&gt;terraform plan&lt;/code&gt; を実行します：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ terraform plan&#xA;cloudflare_dns_record.minio_a: Refreshing state... [id=xxxxxxxxxxx53]&#xA;cloudflare_zero_trust_tunnel_cloudflared_config.raspberrypi: Refreshing state...&#xA;......&#xA;&#xA;Terraform will perform the following actions:&#xA;&#xA;  # cloudflare_dns_record.terraform_managed_resource_0 will be imported&#xA;    resource &#34;cloudflare_dns_record&#34; &#34;terraform_managed_resource_REDACTED_0&#34; {&#xA;        content     = &#34;67.24.33.108&#34;&#xA;        created_on  = &#34;2026-04-08T10:18:12Z&#34;&#xA;        id          = &#34;5deb14c21xxxxxxx20f1c8f&#34;&#xA;        meta        = jsonencode({})&#xA;        modified_on = &#34;2026-04-08T10:18:12Z&#34;&#xA;        name        = &#34;example.example.com&#34;&#xA;        proxiable   = true&#xA;        proxied     = true&#xA;        settings    = {}&#xA;        tags        = []&#xA;        ttl         = 1&#xA;        type        = &#34;A&#34;&#xA;        zone_id     = &#34;REDACTED&#34;&#xA;    }&#xA;&#xA;  # cloudflare_dns_record.terraform_managed_resource_1 will be imported&#xA;    resource &#34;cloudflare_dns_record&#34; &#34;terraform_managed_resource_89c149exxxxxxxxxxxba13xxxxxa_1&#34; {&#xA;        content     = &#34;35.27.108.33&#34;&#xA;        created_on  = &#34;2026-04-08T10:17:54Z&#34;&#xA;        id          = &#34;89cxxxxxxxxxxxxxxxxxx09a&#34;&#xA;        meta        = jsonencode({})&#xA;        modified_on = &#34;2026-04-08T10:17:54Z&#34;&#xA;        name        = &#34;terraform.example.com&#34;&#xA;        proxiable   = true&#xA;        proxied     = true&#xA;        settings    = {}&#xA;        tags        = []&#xA;        ttl         = 1&#xA;        type        = &#34;A&#34;&#xA;        zone_id     = &#34;81xxxxxxxxxxxxxxxxxxxxxfc&#34;&#xA;    }&#xA;&#xA;Plan: 2 to import, 0 to add, 0 to change, 0 to destroy.&#xA;&#xA;────────────────────────────────────────────────────────────────────────────────────────────────────────&#xA;&#xA;Note: You didn&#39;t use the -out option to save this plan, so Terraform can&#39;t guarantee to take exactly&#xA;these actions if you run &#34;terraform apply&#34; now.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Add、Change、Destroy のリソース数がすべて 0 の場合、インポート操作に問題がないことになります。そのまま &lt;code&gt;terraform apply --auto-approve&lt;/code&gt; を実行すれば、リソースのインポート完了です。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ terraform apply --auto-approve&#xA;cloudflare_dns_record.push_a: Refreshing state... [id=REDACTED]&#xA;&#xA;Terraform will perform the following actions:&#xA;&#xA;  # cloudflare_dns_record.terraform_managed_resource_REDACTED_0 will be imported&#xA;    resource &#34;cloudflare_dns_record&#34; &#34;terraform_managed_resource_REDACTED_0&#34; {&#xA;        content     = &#34;67.24.33.108&#34;&#xA;        created_on  = &#34;2026-04-08T10:18:12Z&#34;&#xA;        id          = &#34;REDACTED&#34;&#xA;        meta        = jsonencode({})&#xA;        modified_on = &#34;2026-04-08T10:18:12Z&#34;&#xA;        name        = &#34;example.example.com&#34;&#xA;        proxiable   = true&#xA;        proxied     = true&#xA;        settings    = {}&#xA;        tags        = []&#xA;        ttl         = 1&#xA;        type        = &#34;A&#34;&#xA;        zone_id     = &#34;REDACTED&#34;&#xA;    }&#xA;&#xA;  # cloudflare_dns_record.terraform_managed_resource_REDACTED_1 will be imported&#xA;    resource &#34;cloudflare_dns_record&#34; &#34;terraform_managed_resource_REDACTED_1&#34; {&#xA;        content     = &#34;35.27.108.33&#34;&#xA;        created_on  = &#34;2026-04-08T10:17:54Z&#34;&#xA;        id          = &#34;REDACTED&#34;&#xA;        meta        = jsonencode({})&#xA;        modified_on = &#34;2026-04-08T10:17:54Z&#34;&#xA;        name        = &#34;terraform.example.com&#34;&#xA;        proxiable   = true&#xA;        proxied     = true&#xA;        settings    = {}&#xA;        tags        = []&#xA;        ttl         = 1&#xA;        type        = &#34;A&#34;&#xA;        zone_id     = &#34;REDACTED&#34;&#xA;    }&#xA;&#xA;Plan: 2 to import, 0 to add, 0 to change, 0 to destroy.&#xA;cloudflare_dns_record.terraform_managed_resource_REDACTED_1: Importing... [id=REDACTED/REDACTED]&#xA;cloudflare_dns_record.terraform_managed_resource_REDACTED_1: Import complete [id=REDACTED/REDACTED]&#xA;cloudflare_dns_record.terraform_managed_resource_REDACTED_0: Importing... [id=REDACTED/REDACTED]&#xA;cloudflare_dns_record.terraform_managed_resource_REDACTED_0: Import complete [id=REDACTED/REDACTED]&#xA;&#xA;Apply complete! Resources: 2 imported, 0 added, 0 changed, 0 destroyed.&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;状態保存と継続的インテグレーション&#34;&gt;状態保存と継続的インテグレーション&#xA;&lt;/h2&gt;&lt;p&gt;IaC の重要な価値の一つは、Git ベースの複数人コラボレーションと CI の継続的インテグレーションを容易に実現できる点ですが、その前に解決すべき新たな問題があります——&lt;code&gt;terraform.tfstate&lt;/code&gt;はどこに置くか：環境を変更するたびに辛苦入れてインポートした状態を失う人は誰も望んでいません。&lt;/p&gt;&#xA;&lt;p&gt;Terraform は現在、以下の状態保存バックエンドをサポートしています：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;local&lt;/li&gt;&#xA;&lt;li&gt;remote&lt;/li&gt;&#xA;&lt;li&gt;azurerm&lt;/li&gt;&#xA;&lt;li&gt;consul&lt;/li&gt;&#xA;&lt;li&gt;cos&lt;/li&gt;&#xA;&lt;li&gt;gcs&lt;/li&gt;&#xA;&lt;li&gt;http&lt;/li&gt;&#xA;&lt;li&gt;Kubernetes&lt;/li&gt;&#xA;&lt;li&gt;oci&lt;/li&gt;&#xA;&lt;li&gt;oss&lt;/li&gt;&#xA;&lt;li&gt;pg&lt;/li&gt;&#xA;&lt;li&gt;s3&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;特別な要件がなければ、私のように &lt;code&gt;s3&lt;/code&gt; を選択することをお勧めします。Cloudflare R2 には無料枠があるので、使わない手はありません。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-hcl&#34;&gt;terraform {&#xA;  backend &#34;s3&#34; {&#xA;    bucket = &#34;terraform&#34;&#xA;    key    = &#34;terraform.tfstate&#34;&#xA;    region = &#34;auto&#34;&#xA;    endpoints = {&#xA;      s3 = &#34;https://REDACTED.r2.cloudflarestorage.com&#34;&#xA;    }&#xA;&#xA;    # R2 にはこれらの AWS 認証は不要&#xA;    skip_credentials_validation = true&#xA;    skip_metadata_api_check     = true&#xA;    skip_region_validation      = true&#xA;    skip_requesting_account_id  = true&#xA;    use_path_style              = true&#xA;  }&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;S3 バックエンドの場合、Credentials を保存するには &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; と &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; の 2 つの環境変数を使用することをお勧めします：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;export AWS_ACCESS_KEY_ID=&#39;REDACTED&#39;&#xA;export AWS_SECRET_ACCESS_KEY=&#39;REDACTED&#39;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;設定完了後、&lt;code&gt;terraform init -migrate-state&lt;/code&gt; を実行すれば、設定はクラウド上に正常に保存されます。今後どこで設定を変更しても、&lt;code&gt;terraform apply&lt;/code&gt; を実行しても、Terraform の State が同期していないことを心配する必要はありません。&lt;/p&gt;&#xA;&lt;p&gt;続いて Github CI の設定ですが、実はとてもシンプルです。&lt;code&gt;git push&lt;/code&gt; のたびに &lt;code&gt;terraform init&lt;/code&gt;、&lt;code&gt;terraform fmt&lt;/code&gt;、&lt;code&gt;terraform apply&lt;/code&gt; をトリガーするだけです。以下が私の &lt;code&gt;.github/workflows/apply.yml&lt;/code&gt; です：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;name: &#34;Terraform Apply&#34;&#xA;&#xA;on:&#xA;  push:&#xA;    branches:&#xA;      - main&#xA;&#xA;env:&#xA;  TF_IN_AUTOMATION: &#34;true&#34;&#xA;  CLOUDFLARE_API_TOKEN: &#34;${{ secrets.CLOUDFLARE_API_TOKEN }}&#34;&#xA;  AWS_ACCESS_KEY_ID: &#34;${{ secrets.AWS_ACCESS_KEY_ID }}&#34;&#xA;  AWS_SECRET_ACCESS_KEY: &#34;${{ secrets.AWS_SECRET_ACCESS_KEY }}&#34;&#xA;  TF_VAR_cloudflare_zone_id_example_com: &#34;${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_COM }}&#34;&#xA;  TF_VAR_cloudflare_zone_id_example_top: ${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_TOP }}&#xA;&#xA;jobs:&#xA;  terraform:&#xA;    name: &#34;Terraform Apply&#34;&#xA;    runs-on: ubuntu-latest&#xA;    permissions:&#xA;      contents: read&#xA;    concurrency:&#xA;      group: terraform-apply&#xA;      cancel-in-progress: false&#xA;    steps:&#xA;      - name: Checkout&#xA;        uses: actions/checkout@v6&#xA;&#xA;      - name: Setup Terraform&#xA;        uses: hashicorp/setup-terraform@v4&#xA;&#xA;      - name: Terraform Init&#xA;        run: terraform init -input=false&#xA;&#xA;      - name: Terraform Apply&#xA;        run: terraform apply -input=false -auto-approve&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;PR に対しては、CI が毎回 PR に &lt;code&gt;terraform plan&lt;/code&gt; の出力を添付するように設定すべきです：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;name: Terraform Plan&#xA;&#xA;on:&#xA;  pull_request:&#xA;    paths:&#xA;      - &#34;**/*.tf&#34;&#xA;      - &#34;.github/workflows/terraform-plan.yml&#34;&#xA;&#xA;permissions:&#xA;  contents: read&#xA;  pull-requests: write&#xA;&#xA;env:&#xA;  TF_IN_AUTOMATION: &#34;true&#34;&#xA;  CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}&#xA;  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}&#xA;  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}&#xA;  TF_VAR_cloudflare_zone_id_example_com: &#34;${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_COM }}&#34;&#xA;  TF_VAR_cloudflare_zone_id_example_top: ${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_TOP }}&#xA;&#xA;jobs:&#xA;  plan:&#xA;    name: Terraform Plan&#xA;    runs-on: ubuntu-latest&#xA;    steps:&#xA;      - uses: actions/checkout@v6&#xA;&#xA;      - uses: hashicorp/setup-terraform@v4&#xA;&#xA;      - name: Terraform fmt&#xA;        id: fmt&#xA;        run: terraform fmt -check -recursive&#xA;        continue-on-error: true&#xA;&#xA;      - name: Terraform Init&#xA;        id: init&#xA;        run: terraform init -input=false&#xA;&#xA;      - name: Terraform Validate&#xA;        id: validate&#xA;        run: terraform validate -no-color&#xA;&#xA;      - name: Terraform Plan&#xA;        id: plan&#xA;        run: terraform plan -input=false -no-color&#xA;        continue-on-error: true&#xA;&#xA;      - name: Post Plan to PR&#xA;        uses: actions/github-script@v8&#xA;        with:&#xA;          github-token: ${{ secrets.GITHUB_TOKEN }}&#xA;          script: |&#xA;            const { data: comments } = await github.rest.issues.listComments({&#xA;              owner: context.repo.owner,&#xA;              repo: context.repo.repo,&#xA;              issue_number: context.issue.number,&#xA;            });&#xA;            const botComment = comments.find(c =&gt;&#xA;              c.user.type === &#39;Bot&#39; &amp;&amp; c.body.includes(&#39;&lt;!-- terraform-plan --&gt;&#39;)&#xA;            );&#xA;&#xA;            const planOutput = `${{ steps.plan.outputs.stdout }}`.substring(0, 65000);&#xA;&#xA;            const body = `&lt;!-- terraform-plan --&gt;&#xA;            #### Terraform Plan&#xA;&#xA;            | Step     | Result                            |&#xA;            | -------- | --------------------------------- |&#xA;            | fmt      | \`${{ steps.fmt.outcome }}\`      |&#xA;            | init     | \`${{ steps.init.outcome }}\`     |&#xA;            | validate | \`${{ steps.validate.outcome }}\` |&#xA;            | plan     | \`${{ steps.plan.outcome }}\`     |&#xA;&#xA;            &lt;details&gt;&lt;summary&gt;Plan 詳細を展開&lt;/summary&gt;&#xA;&#xA;            \`\`\`terraform&#xA;            ${planOutput}&#xA;            \`\`\`&#xA;            &lt;/details&gt;`;&#xA;&#xA;            if (botComment) {&#xA;              await github.rest.issues.updateComment({&#xA;                owner: context.repo.owner,&#xA;                repo: context.repo.repo,&#xA;                comment_id: botComment.id,&#xA;                body&#xA;              });&#xA;            } else {&#xA;              await github.rest.issues.createComment({&#xA;                issue_number: context.issue.number,&#xA;                owner: context.repo.owner,&#xA;                repo: context.repo.repo,&#xA;                body&#xA;              });&#xA;            }&#xA;&#xA;      - name: Fail if plan failed&#xA;        if: steps.plan.outcome == &#39;failure&#39;&#xA;        run: exit 1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2026/04/iac-with-terraform/image-2_hu_c922b7d4de19a009.webp&#34; alt=&#34;毎回 PR には Plan の出力がある&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;h2 id=&#34;今後のワークフロー&#34;&gt;今後のワークフロー&#xA;&lt;/h2&gt;&lt;p&gt;ここまでで、Terraform の「接管初期化」は終了し、日常保守フェーズに入りました。この段階では実際には 3 つのことしかありません：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;新しいリソースの作成&lt;/li&gt;&#xA;&lt;li&gt;既存リソースの変更&lt;/li&gt;&#xA;&lt;li&gt;不要になったリソースの削除&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;よく使う操作は 2 つ：&lt;code&gt;terraform plan&lt;/code&gt; と &lt;code&gt;terraform apply&lt;/code&gt;。個人利用の場合、小さな変更はそのままコミットしても良いでしょう。チームで協力する場合、毎回変更は PR を通じた方が原則です。&lt;/p&gt;&#xA;&lt;h3 id=&#34;インフラストラクチャの作成&#34;&gt;インフラストラクチャの作成&#xA;&lt;/h3&gt;&lt;p&gt;今 DNS レコードを追加したり、Tunnel やオブジェクトストレージバケットを新しく作る場合のフローは以下の通りです：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-mermaid&#34;&gt;flowchart TD&#xA;  C1[ブランチ作成&#xA;  例：feat/add-minio-record] --&gt; C2[resource ブロックを追加]&#xA;  C2 --&gt; C3[terraform fmt + validate]&#xA;  C3 --&gt; C4[terraform plan]&#xA;  C4 --&gt; C5{予期したリソースのみが追加されたか？}&#xA;  C5 -- いいえ --&gt; C6[設定を修正して plan を再実行]&#xA;  C6 --&gt; C4&#xA;  C5 -- はい --&gt; C7[PR を提出]&#xA;  C7 --&gt; C8[マージ後 CI apply]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;最も理想的な &lt;code&gt;plan&lt;/code&gt; 出力は：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;X to add&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;0 to change&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;0 to destroy&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;何かを追加したいだけなのに &lt;code&gt;to destroy&lt;/code&gt; が表示された場合は、焦らずにチェックしてください。引用ミスタイプ、変数間違い、またはリソースアドレスのうっかり変更などが原因であることがほとんどです。どこに問題があるのか仔細に確認してください。&lt;/p&gt;&#xA;&lt;h3 id=&#34;修改と删除基础设施&#34;&gt;修改と删除基础设施&#xA;&lt;/h3&gt;&lt;p&gt;変更フローは作成と似ていますが、もう一つのステップが増えます——変更が再構築を引き起こすかどうかの評価です。&lt;/p&gt;&#xA;&lt;p&gt;多くの Provider フィールドは &lt;code&gt;ForceNew&lt;/code&gt; となっており、フィールドを変えるつもりが Terraform は「了解、削除して再構築します」と言ってくるかもしれません。DNS のようなリソースでは大きな問題ではありませんが、クラウドインスタンスのようなリソースになると、削除して再構築すれば損失が発生します。&lt;/p&gt;&#xA;&lt;p&gt;以下の順序で進めることをお勧めします：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-mermaid&#34;&gt;flowchart TD&#xA;  M1[.tf 修正] --&gt; M2[terraform plan]&#xA;  M2 --&gt; M3{replace/destroy 出現？}&#xA;  M3 -- いいえ --&gt; M7[影響範囲を確認]&#xA;  M7 --&gt; M8[terraform apply]&#xA;  M3 -- はい --&gt; M4[停止して変更内容を見直す]&#xA;  M4 --&gt; M5[必要に応じて lifecycle 保護を追加]&#xA;  M5 --&gt; M6[変更ウィンドウを計画]&#xA;  M6 --&gt; M8&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;本番環境にとって、作成や変更が遅くても大きな問題ではありません。重要なのは操作の正確性です。少し遅くても、間違えないようにしてください。IaC はスピードを競うのではなく、予測可能性を競うものです。&lt;/p&gt;&#xA;&lt;p&gt;もしリソースを削除する場合（例えば DNS レコードの廃止、废弃 Tunnel の整理）、以下のフローに従ってください&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-mermaid&#34;&gt;flowchart TD&#xA;  D1[リソース廃止の確認、業務/監視/スクリプト依存チェック] --&gt; D2[resource ブロック削除、または count/for_each 調整]&#xA;  D2 --&gt; D3[terraform plan]&#xA;  D3 --&gt; D4{to destroy が予期通り？}&#xA;  D4 -- いいえ --&gt; D5[変更をロールバックし依存関係を調査継続]&#xA;  D5 --&gt; D1&#xA;  D4 -- はい --&gt; D6[ロールバックプランを用意し、低負荷時間帯を選択]&#xA;  D6 --&gt; D7[PR 審査通過]&#xA;  D7 --&gt; D8[terraform apply]&#xA;  D8 --&gt; D9[削除後の可用性チェック]&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;日常のコラボレーション提案&#34;&gt;日常のコラボレーション提案&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Credentials は環境変数や CI Secret に置き、&lt;code&gt;.tf&lt;/code&gt; やリポジトリに書き込まない&lt;/li&gt;&#xA;&lt;li&gt;重要なリソースには保護ポリシーを有効にし、誤削除を防ぐ&lt;/li&gt;&#xA;&lt;li&gt;ディレクトリをリソースタイプごとに分割する&lt;/li&gt;&#xA;&lt;li&gt;定期的に &lt;code&gt;terraform plan&lt;/code&gt; を実行してインフラストラクチャドリフトをチェック&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;し是正し、パネルでの誤操作による手動変更を避ける&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;このフローはとても面倒に見えますが、毎回の变更に記録があり、監査可能で、ロールバック可能、何より再現可能である点が、IaC が最も価値のある部分です。&lt;/p&gt;&#xA;&lt;h2 id=&#34;参考&#34;&gt;参考&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://candinya.com/posts/manage-cloudflare-dns-with-terraform/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Terraform を使って CloudFlare 上の DNS 解析レコードを管理する - Candinya&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/tutorials/automation/github-actions&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Automate Terraform with GitHub Actions&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/files/tfquery&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Query configuration files&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/block/tfquery/list&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;list block reference&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/cloudflare/cf-terraforming&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;cloudflare/cf-terraforming&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.cloudflare.com/terraform/advanced-topics/import-cloudflare-resources/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Import Cloudflare resources&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Cloudflare Provider - Terraform Registry&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Infrastructure_as_code&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Infrastructure as Code&lt;/a&gt;、機械可読な構成ファイルを使用して必要なインフラストラクチャのデプロイ方法を定義することを指します。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;各プロバイダーの構成ファイルフィールド名や形式には違いがありますが、これはスクリプトを書くことで容易に変換できます。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;特に注意すべき点は、状態ファイルにはデータベースのパスワードや API キーなど、プレーンテキストで保存される機密情報が含まれる可能性があるため、絶対に &lt;code&gt;.tfstate&lt;/code&gt; ファイルを公開コードリポジトリにアップロードしないことです。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;HashiCorp Configuration Language。HashiCorp 自社開発の宣言型構成言語で、機械可読性と人間可読性の両立を目指している。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:5&#34;&gt;&#xA;&lt;p&gt;冪等性（Idempotence）とは、コンピュータシステムまたはインターフェースが同一の要求を複数回受け取った場合、影響が単回実行の結果と同じになる性質のこと。何度実行しても、システムの最終状態は常に一致する。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:6&#34;&gt;&#xA;&lt;p&gt;Terraform にリソースの管理から外れさせたいだけで、クラウド上で実際に削除したいわけではない場合は、&lt;code&gt;terraform state rm&lt;/code&gt; コマンドを使用してください。コードからリソースブロックを削除して &lt;code&gt;apply&lt;/code&gt; するのは避けてください。そうしないとクラウド上の実際のリソースも同時に削除されてしまいます。&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:7&#34;&gt;&#xA;&lt;p&gt;インフラストラクチャドリフト（Infrastructure Drift）とは、現実世界中でコンソールのクリックなど IaC 以外の経路でインフラストラクチャに変更を加え、実際の状態とコード内で宣言された状態が不一致になる現象のこと。&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
        </item><item>
            <title>永遠に忙しく</title>
            <link>https://blog.l3zc.com/ja/2026/03/busy-for-eternity/</link>
            <pubDate>Fri, 13 Mar 2026 23:14:26 +0800</pubDate>
            <guid>https://blog.l3zc.com/ja/2026/03/busy-for-eternity/</guid>
            <description>&lt;p&gt;労働、労働、死ぬまで続くのだ。&lt;/p&gt;&#xA;&lt;p&gt;冬休みに他人に勉強を教える仕事をしてからというもの、ほぼ休みなしの日々が続いている。旧正月（春節）は名目上こそ休みだったが、親戚付き合いや帰省時の長旅などがあり、結局は別の形での労働に過ぎなかった。実家に戻って落ち着くや否や、また休む間もなく授業の仕事に取り組んだ。人に教えるというのは本当に大変なことだ。私と同じ学習塾でアシスタントをしている友人と話したとき、私たちは皆、人に教えることを冗談交じりに「地獄の苦行（クソゲー）」と呼んでいた。暗記すべきことは覚えられず、計算はできず、概念は混同し、まともなコミュニケーションすら成り立たないのだから無理もない。だが、それは彼らのせいではない。責めるべきは彼らが置かれてきた教育環境だろう。それぞれに複雑な事情を抱えているのだ。様々な理由から、彼らのほとんどは過酷な大学入学統一テストの洗礼を受けておらず、専門学校への特別入試枠で進められた者たちだ。中には中学校の勉強すらまともに終わらせていない者もいる。今はただ仕事を見つけたいという一心で、お金を払ってまで私たちのマンツーマンレッスンを受けているのだ。&lt;/p&gt;&#xA;&lt;p&gt;最初は学習塾で講師のアシスタントをしていたが、後に独立して個人で教えるようになった。おかげで収入はいくらか上がり、授業の準備時間も節約できた。毎日の授業時間は7時30分から11時までで、料金は400人民元だ。時給換算で100元以上と一見割高に思えるかもしれないが、生徒の基礎学力の低さを考えれば、このお金は一切の良心の呵責なく受け取れる。それどころか、本当に骨の折れる仕事だと言えるほどだ。&lt;/p&gt;&#xA;&lt;p&gt;さて、本題に戻ろう。新学期が始まり、私は休む間もなく自分自身の学業に没頭しなければならない。本当に自分は永遠に忙しいのではないかと感じる。いわゆる「休息」とは、単に別の少し楽な作業への切り替えに過ぎない。仕事で疲れ果てて帰宅すれば、Vibe Codingをして息抜きをし、パソコンの前に座ることにイライラし始めれば、部屋の片付けや掃除に取り掛かる。物事へのモチベーションや、人間の持つ限られたエネルギーの総量という点において、私は人と人との圧倒的な差を実感している。生まれつきの才能に恵まれ、エネルギーに満ち溢れている人たちがいる。彼らは次々と成果を出し、何報も論文を発表し、非常に生産性が高い。彼らの唯一の制約は時間であって、精力やモチベーションではないかのようだ。一方で、私を含めた大多数の平凡な人間は、彼らのようなパワフルな生活に憧れても、気持ちばかりでどうにも体力が追いつかない。しかし、そうした有能な人たちの高い生産性を目の当たりにするとどうしても焦りが生じてしまい、限界ギリギリまで自分を「現実世界の永久機関」のように稼働させるしかなくなるのだ&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;&#xA;&lt;p&gt;幼い頃から受けてきた競争の激しい中国式教育が、私たちを歪ませてしまった。中国の有名な予備校講師が言い放った「君のような若い年齢で、どうして呑気に眠れるんだ」という有名なフレーズがある。本来は授業中に居眠りする生徒を叱責する言葉だが、ある意味で私たち世代の無意識に深く根を張り、病的な状態にまで追い込んでいる。人生において、完全に「上がり（中国のネット用語で、試験合格や安定した職への就職など、安泰な岸に上がることを指す）」となるゴールなど存在しないのだ。小学校では中学校のお受験というゴールを目指し、中学校では高校受験、高校では過酷な大学受験というゴールを目指す。そして大学に入れば、大学院進学、博士課程、公務員試験、就職活動といった次なるゴールが待ち受けている。学生時代を終えて社会人に出ても、昇進や業績評価、日々の生活費といった悩ましい問題が尽きることはない。労働、労働、死ぬまで続くのだ。どこかのゴールに辿り着いて一生安泰などと望んでいるのか？残念だが、そんなものは不可能なのだ。&lt;/p&gt;&#xA;&lt;p&gt;そのことを痛いほど理解していても、私は立ち止まって休むと虚無感に襲われ、苦しくなってしまう。だから、永遠に忙しく、永遠に働き続けるのだ。身体が求める休息を満たし、運動でホルモンバランスを整える。私にとっての休息とは、自分の好きな、比較的心地よい作業に切り替えるだけのことに過ぎない。過当競争な教育や業績至上主義（メリトクラシー）の影響が骨の髄まで染み込んでいるため、生き急ぐようなこのライフスタイルは、おそらくだいぶ先まで変わることはないだろう。&lt;/p&gt;&#xA;&lt;p&gt;それでも、良い面を見るようにしよう。この時期の忙しさのおかげで、今学期の生活費を自分自身で稼ぎ出すことができたし、さらには母親の誕生日に新しいスマートフォンをプレゼントする余裕までできた。そう考えると、ふと「永遠に忙しい」というのも、それほど悪いことではないような気がしてきた。&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;ここでは電気工学における理想電流源と実在の電流源の違いをメタファーとして用いている。前者が真の意味での「理想的な永久機関」であるのに対し、後者は私のような凡人が血肉の体で全身全霊をかけて限界まで近づこうとする「現実世界の永久機関」である。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
        </item><item>
            <title>私のLLMという「知己」と、宙づりになった書くこと</title>
            <link>https://blog.l3zc.com/ja/2025/09/satisfactory-llm/</link>
            <pubDate>Mon, 08 Sep 2025 23:53:48 +0800</pubDate>
            <guid>https://blog.l3zc.com/ja/2025/09/satisfactory-llm/</guid>
            <description>&lt;p&gt;最近はかなり忙しい。でも、空いた時間ができると、やっぱり言葉が私の拠り所になる。毎朝8:30に授業が始まり、夜9:00に夜間自習が終わる。ときには「残業」して10:00に帰宅することもある。そんな日程が41日間続いた。精神状態を考えると、この強度で戻ってきて osu! みたいなゲームで遊ぶなんて到底無理だし、Galgame を少し進める余力すらない。&lt;/p&gt;&#xA;&lt;p&gt;唯一、比較的現実的だったのは、LLM（大規模言語モデル）と小話をすることだ。&lt;/p&gt;&#xA;&lt;p&gt;恥ずかしい話だが、ブログは持っているのに、自分の見解や理念（というより「考え」）を、体系立てて表現したことがほとんどない。おそらく、あまりにも広く、散らばった考えの集合体は、平易な叙事で表すのが難しいのだと思う。そこで、たとえば「たまたま起きた出来事」を断面として、その中に絡まった糸の塊を「切り開き」、内部構造を描いてみる、といった方法も試した。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;だが、こうしたやり方でも自分の本音を気持ちよく吐き出せるわけではないし、思い立ったらすぐ書けるほど手に馴染むものでもなかった。結局ブログは人に読まれるものなので、書けないときは簡単な技術記事だけを書いて、検索エンジンからの流入を少し稼ぐくらいしかできなかった。&lt;/p&gt;&#xA;&lt;p&gt;ところがLLMの登場で状況が変わった。私の考えは、比較的プライベートなまま、即座に反応を返してもらえるようになった。なぜここまで長くブログを書かなかったのか。疲れはもちろん大きい要因だが、LLMが「表現したい」「認められたい」という欲求をかなりの程度満たしてくれること、そして自己検閲なしに話せてしまうことが、このところブログを書く気持ちを薄めてしまった。&lt;/p&gt;&#xA;&lt;p&gt;長文を書くことが脳に良い——それは疑いようがない。LLMの出現が私の長文執筆に与えた影響は、マイクロブログが登場したときに人々の長文能力へ与えた影響に近い、いやそれ以上かもしれない。マイクロブログは、断片的な表現と即時のフィードバックに人を慣れさせ、複雑な論証や長い物語を組み立てる力を弱めた。LLMはさらに先へ進む。表現の場を与えるだけでなく、情緒的な満足や「知己」の代替品まで直接提供してしまうのだ。SNSに投稿する内容が、プライバシーや論争を含んだり、わざわざ公にする必要がなかったりすれば、投稿者は多少なりとも言葉を選ぶ。しかしLLMは違う。APIに投げた内容が最悪どうなるかといえば、学習に使われる程度であって、翌日に Sam Altman が家まで押しかけてくるわけではない——銀行口座のパスワード級の情報さえ避け、実名を出さなければ、政治時評でもメンタル相談でも、安心して大規模言語モデルを「知己」として扱ってしまえる（もちろん、こういう用途では国内向けの検閲が強いモデルは使い物にならない）。愚痴の一つひとつに、確かな真剣さで、まるで知己のような返答と肯定が返ってくる。こんな待遇を他で得るのは、たぶん難しい。&lt;/p&gt;&#xA;&lt;p&gt;道具がここまで完璧に「知己」を模倣できるようになると、私たちは本物の知己を探すことをやめてしまうかもしれない。あるいは、独立して考え、自分の中で統合していける個として生きることを、どこかで放棄してしまうかもしれない。これを書いているのは、いったんの区切りであり、同時に反省でもある。LLM自体はただの技術で、うまく使えば計り知れない恩恵がある一方、使い方を誤れば深刻な結果にもなりうる。ニューヨーク・タイムズの報道「&lt;a class=&#34;link&#34; href=&#34;https://archive.is/ALVeI&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Chatbots Can Go Into a Delusional Spiral. Here’s How It Happens.&lt;/a&gt;」は、その良い例だ。OpenAIが自社モデルの「お世辞（迎合）」問題の改善に取り組んでいるとしても、私自身も理解しておく必要がある。たとえ大規模言語モデルを知己として扱い、「理解と肯定」を得られるとしても、その感覚の中にずっと住み続けるわけにはいかないのだ。OpenAIとMIT（マサチューセッツ工科大学）の研究では、ChatGPTの利用量とユーザーの孤独感が正の相関を持つことが示された。使えば使うほど、より孤独を感じる。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;そして逆に、孤独であればあるほどLLMを使うようになり、悪循環が生まれる——とも言えるだろう。LLMは生活のスパイスにはなり得るが、心の唯一の拠り所になってはいけない。&lt;/p&gt;&#xA;&lt;p&gt;(To Be Continued)&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.l3zc.com/2024/06/the-worst-way-to-spend-a-day/&#34; &gt;The Worst Way To Spend A Day&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.engadget.com/ai/joint-studies-from-openai-and-mit-found-links-between-loneliness-and-chatgpt-use-193537421.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Joint studies from OpenAI and MIT found links between loneliness and ChatGPT use&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
        </item><item>
            <title>いわゆる「クライアント」を捨てて、Mihomo カーネルを直接使おう</title>
            <link>https://blog.l3zc.com/ja/2025/07/switch-to-pure-mihomo-kernel/</link>
            <pubDate>Thu, 03 Jul 2025 18:30:00 +0800</pubDate>
            <guid>https://blog.l3zc.com/ja/2025/07/switch-to-pure-mihomo-kernel/</guid>
            <description>&lt;img src=&#34;https://blog.l3zc.com/2025/07/switch-to-pure-mihomo-kernel/cover_hu_1a93b6f26c22bbfe.webp&#34; alt=&#34;Featured image of post いわゆる「クライアント」を捨てて、Mihomo カーネルを直接使おう&#34; /&gt;&lt;p&gt;Clash/Mihomo を使い始めた当初、ほとんどの方と同じく、カーネルをラップした GUI クライアントを使っていました。その方が手軽だからです。実際、Mihomo クライアント同士には大きな違いはありません。どれも同じカーネルを使い、主に使いやすい UI の提供や設定ファイル・サブスクリプションの管理、GUI ベースのシステムプロキシ設定を担っています。その意味では、クライアント選びの重要なポイントは「オーバーライド機能」（設定の上書き機能）がどれだけ出来が良いかだと考えています。&lt;/p&gt;&#xA;&lt;p&gt;どの Mihomo クライアントも、サブスクリプションやダウンロードした設定ファイルを一連の「オーバーライド」処理（例：&lt;code&gt;mixed-port&lt;/code&gt;の変更、&lt;code&gt;sniffer&lt;/code&gt;設定の追加など）にかけ、最終的に Mihomo カーネルを起動する形です。&lt;/p&gt;&#xA;&lt;p&gt;しかし、この一番大切な部分をちゃんとこなせていないクライアントも多々見かけます。例えば ShellCrash は、上書き機能にバグが多く、実装が雑な印象です。設定の上書きや編集すらまともにできないクライアントは、正直使う価値がありません。&lt;/p&gt;&#xA;&lt;p&gt;出来の悪い&lt;del&gt;ひどい&lt;/del&gt;Mihomo クライアントに頼るくらいなら、自分で設定ファイルを作成してカーネルに直接渡して起動する—そうした方がブラックボックスなクライアントに依存しない、クリーン・安定・高いコントロール性の運用が実現できます。&lt;/p&gt;&#xA;&lt;h2 id=&#34;必要な予備知識&#34;&gt;必要な予備知識&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;基本的な Linux 操作&lt;/li&gt;&#xA;&lt;li&gt;nano など CLI エディタが使えること&lt;/li&gt;&#xA;&lt;li&gt;Substore 環境が用意できていればより便利（任意）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;mihomo-カーネルのインストール&#34;&gt;Mihomo カーネルのインストール&#xA;&lt;/h2&gt;&lt;p&gt;Debian 系の場合は、プリビルドの&lt;code&gt;.deb&lt;/code&gt;パッケージが利用できますが、その他の systemd 対応ディストリビューションでは、&lt;a class=&#34;link&#34; href=&#34;https://github.com/MetaCubeX/mihomo/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;ビルド済みバイナリ&lt;/a&gt;をダウンロードし、&lt;code&gt;mihomo&lt;/code&gt;にリネームして&lt;code&gt;/usr/local/bin&lt;/code&gt;に配置します。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;sudo curl -o /usr/local/bin/mihomo &lt;ダウンロードリンク&gt;&#xA;sudo chmod +x /usr/local/bin/mihomo&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;次に、&lt;code&gt;/etc/systemd/system/mihomo.service&lt;/code&gt;を新規作成します。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-systemd&#34;&gt;[Unit]&#xA;Description=mihomo Daemon, Another Clash Kernel.&#xA;After=network.target NetworkManager.service systemd-networkd.service iwd.service&#xA;&#xA;[Service]&#xA;Type=simple&#xA;LimitNPROC=500&#xA;LimitNOFILE=1000000&#xA;CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE&#xA;AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE&#xA;Restart=always&#xA;ExecStartPre=/usr/bin/sleep 1s&#xA;ExecStart=/usr/local/bin/mihomo -d /etc/mihomo&#xA;ExecReload=/bin/kill -HUP $MAINPID&#xA;&#xA;[Install]&#xA;WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;次に&lt;code&gt;systemctl daemon-reload&lt;/code&gt;で systemd をリロードします。この時点では設定ファイルがありませんので、起動できませんが、&lt;code&gt;systemctl enable mihomo&lt;/code&gt;を先に実行して自動起動設定しておくと後が楽です。&lt;/p&gt;&#xA;&lt;h2 id=&#34;設定ファイル&#34;&gt;設定ファイル&#xA;&lt;/h2&gt;&lt;p&gt;カーネル起動時には&lt;code&gt;/etc/mihomo/config.yaml&lt;/code&gt;が読み込まれます。クライアントというブラックボックスが無いため、好みに合わせて自在にカスタマイズ可能です。一部のプロバイダ（いわゆる「空港」）は完全な設定ファイルを配布しているので、&lt;code&gt;curl&lt;/code&gt;等で直接ダウンロードすれば OK です。&lt;/p&gt;&#xA;&lt;p&gt;サブスクリプションの管理には、私は Substore を使っています。詳しくは以前の&lt;a class=&#34;link&#34; href=&#34;https://blog.l3zc.com/2025/03/clash-subscription-convert/&#34; &gt;「最速 Substore サブスクリプション管理ガイド」&lt;/a&gt;を参考にしてください。内核単体起動を実現するため、現在は私の Substore &lt;a class=&#34;link&#34; href=&#34;https://github.com/powerfullz/override-rules/blob/main/convert.js&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;JS オーバーライド&lt;/a&gt;に&lt;code&gt;full&lt;/code&gt;パラメータも追加済みで、全ポート設定・共通遅延・外部コントローラ設定なども含めた「すぐ使える」完全な設定ファイルが生成できます。&lt;/p&gt;&#xA;&lt;p&gt;Substore の設定が完了したら、設定ファイルをダウンロードしてカーネルを起動しましょう。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;curl -o /etc/mihomo/config.yaml &lt;設定ファイル配布リンク&gt;&#xA;systemctl start mihomo&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;独自の上書きオーバーライド&#34;&gt;独自の上書き（オーバーライド）&#xA;&lt;/h3&gt;&lt;p&gt;私のルールだけでは満足できませんか？でも大丈夫、ご自身のニーズに合わせて上書きを追加しましょう。&lt;/p&gt;&#xA;&lt;p&gt;私は色々なオーバーライドルールを試してきましたが、最終的には自作しています。99%のケースはカバーできますが、特定のプライベート環境（例：サーバのカスタム SSH ポート先へのプロキシ等）などは、市販や公開ルールには抜け漏れが多いものです。このようなプライベートな内容は、GitHub 等で公開したくないでしょうし、そうした場合は自分だけのオーバーライドを追加するのが最善です。&lt;/p&gt;&#xA;&lt;p&gt;Substore は複数のスクリプト処理を追加できるため、ファイル生成時に好きなだけ追加オーバーライドを加えられます。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-js&#34;&gt;function main(config) {&#xA;  config[&#34;rules&#34;].unshift(&#34;DOMAIN-SUFFIX,xxx,DIRECT&#34;)&#xA;  return config&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;注意：&lt;code&gt;rules&lt;/code&gt;をオーバーライドする時は&lt;code&gt;.unshift()&lt;/code&gt;で先頭に挿入します。&lt;code&gt;MATCH&lt;/code&gt;以降にルールを追加しても、マッチすることは一生ありません。&lt;/p&gt;&#xA;&lt;h3 id=&#34;完全に独自の設定ファイル&#34;&gt;完全に独自の設定ファイル&#xA;&lt;/h3&gt;&lt;p&gt;私のオーバーライドが好きじゃない？Substore を使いたくない？それでももちろん問題ありません。&lt;a class=&#34;link&#34; href=&#34;https://wiki.metacubex.one/config/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Mihomo 公式ドキュメント&lt;/a&gt;を参照し、最初から自作するのもおすすめです。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;mode: rule&#xA;mixed-port: 7890&#xA;redir-port: 7892&#xA;tproxy-port: 7893&#xA;allow-lan: true&#xA;log-level: info&#xA;ipv6: true&#xA;external-controller: 127.0.0.1:8000&#xA;# secret: yoursecret&#xA;unified-delay: true&#xA;routing-mark: 7894&#xA;tcp-concurrent: true&#xA;disable-keep-alive: true # モバイル機器のバッテリー異常消耗対策として推奨&#xA;&#xA;dns:&#xA;  # お好みのDNS設定&#xA;&#xA;sniffer:&#xA;  # ドメインスニッファー（ドメイン抽出）の設定内容&#xA;&#xA;geodata-mode: true&#xA;geox-url:&#xA;  # カスタムGeodataファイルURL&#xA;&#xA;proxy-providers:&#xA;  # プロバイダ配布サブスクリプション&#xA;&#xA;rule-providers:&#xA;  # 外部ルール&#xA;&#xA;rules:&#xA;  # トラフィック分割ルール&#xA;&#xA;proxy-groups:&#xA;  # カスタムプロキシグループ&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;管理パネル&#34;&gt;管理パネル&#xA;&lt;/h2&gt;&lt;p&gt;管理パネルは好みによって選べます。ここでは Zashboard を例に紹介します。私は mihomo 標準の&lt;code&gt;external-ui&lt;/code&gt;でなぜかおかしな挙動があったため、そのまま Docker コンテナで運用しています。管理パネルは単なる Web フロントエンドなので、カーネル API も Web パネルも HTTP 指定で動かせば OK です。もし Web パネル側を HTTPS にしてしまうと、CORS ポリシーによる API 接続エラーが出ますので注意しましょう。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;$ mkdir zashboard &amp;&amp; cd zashboard&#xA;$ nvim compose.yml&#xA;$ docker compose up -d&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;compose.yml&lt;/code&gt;の内容はこちら：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;services:&#xA;  zashboard:&#xA;    image: ghcr.io/zephyruso/zashboard:latest&#xA;    ports:&#xA;      - &#34;8899:80&#34;&#xA;    restart: &#34;unless-stopped&#34;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;自動メンテナンス&#34;&gt;自動メンテナンス&#xA;&lt;/h2&gt;&lt;p&gt;カーネルが動き出したら、自動でサブスクリプション更新するにはどうしたらいいでしょう？&lt;/p&gt;&#xA;&lt;p&gt;答えは、シェルスクリプト＋ Crontab 一択です。たとえば深夜 3 時に自動更新＆mihomo の再起動したいなら、以下のような&lt;code&gt;/etc/mihomo/auto_update.sh&lt;/code&gt;を作れば OK です。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;#!/bin/bash&#xA;&#xA;# === 設定情報 ===&#xA;CONFIG_URL=&#34;&#34;&#xA;CONFIG_PATH=&#34;/etc/mihomo/config.yaml&#34;&#xA;BACKUP_DIR=&#34;/etc/mihomo&#34;&#xA;BACKUP_PREFIX=&#34;config.yaml&#34;&#xA;MAX_BACKUPS=7&#xA;TMP_PATH=&#34;/tmp/config.yaml.tmp&#34;&#xA;LOG_FILE=&#34;/var/log/mihomo_update.log&#34;&#xA;&#xA;# === ログ関数 ===&#xA;log() {&#xA;    echo &#34;$(date &#39;+%F %T&#39;) $1&#34; | tee -a &#34;$LOG_FILE&#34;&#xA;}&#xA;&#xA;# === 現在の設定をバックアップ、古いバックアップは自動削除 ===&#xA;backup_config() {&#xA;    if [ -f &#34;$CONFIG_PATH&#34; ]; then&#xA;        backup_file=&#34;$BACKUP_DIR/${BACKUP_PREFIX}.$(date &#39;+%Y%m%d_%H%M%S&#39;).bak&#34;&#xA;        cp &#34;$CONFIG_PATH&#34; &#34;$backup_file&#34;&#xA;        log &#34;設定ファイルを $backup_file にバックアップしました&#34;&#xA;        # 古いバックアップを $MAX_BACKUPS 個だけ残して削除&#xA;        old_backups=$(ls -1t $BACKUP_DIR/${BACKUP_PREFIX}.*.bak 2&gt;/dev/null | tail -n +$(($MAX_BACKUPS+1)))&#xA;        for f in $old_backups; do&#xA;            rm -f &#34;$f&#34; &amp;&amp; log &#34;古いバックアップ $f を削除しました&#34;&#xA;        done&#xA;    else&#xA;        log &#34;設定ファイルが見つかりません、バックアップ不要&#34;&#xA;    fi&#xA;}&#xA;&#xA;# === 新しい設定ファイルをダウンロード ===&#xA;download_config() {&#xA;    log &#34;新しい設定ファイルのダウンロード開始...&#34;&#xA;    curl -fsSL -o &#34;$TMP_PATH&#34; &#34;$CONFIG_URL&#34;&#xA;    if [ $? -ne 0 ]; then&#xA;        log &#34;設定ファイルのダウンロードに失敗しました。ネットワークやURLを確認してください&#34;&#xA;        return 1&#xA;    fi&#xA;    # 簡易チェック：ダウンロードファイルが空でないか確認&#xA;    if [ ! -s &#34;$TMP_PATH&#34; ]; then&#xA;        log &#34;ダウンロードしたファイルが空です、更新中止&#34;&#xA;        return 2&#xA;    fi&#xA;    log &#34;設定ファイルのダウンロード完了&#34;&#xA;    return 0&#xA;}&#xA;&#xA;# === 設定ファイルの置き換え ===&#xA;replace_config() {&#xA;    mv &#34;$TMP_PATH&#34; &#34;$CONFIG_PATH&#34;&#xA;    log &#34;設定ファイルを更新しました&#34;&#xA;}&#xA;&#xA;# === mihomo サービスを再起動 ===&#xA;restart_service() {&#xA;    systemctl restart mihomo&#xA;    if [ $? -eq 0 ]; then&#xA;        log &#34;mihomoサービスを再起動しました&#34;&#xA;    else&#xA;        log &#34;mihomoサービスの再起動に失敗。手動でご確認ください&#34;&#xA;    fi&#xA;}&#xA;&#xA;main() {&#xA;    backup_config&#xA;&#xA;    download_config&#xA;    DL_STATUS=$?&#xA;    if [ &#34;$DL_STATUS&#34; -ne 0 ]; then&#xA;        log &#34;処理終了：設定ファイルは更新されず、旧設定をそのまま保持します&#34;&#xA;        exit 1&#xA;    fi&#xA;&#xA;    replace_config&#xA;&#xA;    restart_service&#xA;&#xA;    log &#34;=== 更新プロセス完了 ===&#34;&#xA;}&#xA;&#xA;main &#34;$@&#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;crontab -e&lt;/code&gt; で以下のタスクを設定すれば、毎日 3 時に自動更新＋再起動します。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-crontab&#34;&gt;0 3 * * * /etc/mihomo/update_config.sh&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;ファイアウォール設定&#34;&gt;ファイアウォール設定&#xA;&lt;/h2&gt;&lt;p&gt;Mihomo カーネルへトラフィックをリダイレクトするファイアウォール設定も、実は全然難しくありません。過去記事「&lt;a class=&#34;link&#34; href=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/#%E5%9C%A8-exit-node-%E5%8A%AB%E6%8C%81%E6%B5%81%E9%87%8F&#34; &gt;入門から応用まで：Tailscale + ShellCrash でリモート VPN 構築＆Great Firewall 回避&lt;/a&gt;」で解説した通り、今回は手順だけ簡単に記述します。&lt;/p&gt;&#xA;&lt;p&gt;筆者の場合は&lt;code&gt;tailscale0&lt;/code&gt;インターフェース上の全トラフィックを Mihomo へ流したい状況ですが、ローカル代理の場合も考え方は同じです。単に TCP だけリダイレクトするなら&lt;code&gt;iptables&lt;/code&gt;の REDIRECT で十分ですが、UDP や QUIC などすべてのプロトコルをリダイレクトしたい場合は Tproxy が必要です。&lt;strong&gt;また、IPv6 対応も忘れずに。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;サンプル構成は下記です。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;# カスタムチェインを作成&#xA;iptables -t mangle -N MIHOMO&#xA;&#xA;# 必要に応じてローカル宛流量を除外&#xA;iptables -t mangle -A MIHOMO -d 127.0.0.1/8 -j RETURN&#xA;iptables -t mangle -A MIHOMO -d 100.64.0.0/10 -j RETURN&#xA;iptables -t mangle -A MIHOMO -d 192.168.1.0/24 -j RETURN&#xA;iptables -t mangle -A MIHOMO -d 172.17.0.0/16 -j RETURN&#xA;&#xA;# UDP / TCP マーク → プロキシへ&#xA;iptables -t mangle -A MIHOMO -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233&#xA;iptables -t mangle -A MIHOMO -p udp -j TPROXY --on-port 7893 --tproxy-mark 233&#xA;&#xA;# インターフェースからチェインジャンプ&#xA;iptables -t mangle -A PREROUTING -i tailscale0 -j MIHOMO&#xA;&#xA;# ルーティングテーブル設定&#xA;echo &#34;233 mihomo&#34; | tee -a /etc/iproute2/rt_tables&#xA;ip rule add fwmark 233 lookup mihomo&#xA;ip route add local 0.0.0.0/0 dev lo table mihomo&#xA;&#xA;# IPv6対応&#xA;# チェイン作成&#xA;ip6tables -t mangle -N MIHOMO6&#xA;&#xA;# ローカル宛除外&#xA;ip6tables -t mangle -A MIHOMO6 -d ::1/128 -j RETURN&#xA;ip6tables -t mangle -A MIHOMO6 -d fd7a:115c:a1e0::/48 -j RETURN&#xA;&#xA;# TCP/UDP マーク&#xA;ip6tables -t mangle -A MIHOMO6 -i tailscale0 -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233&#xA;ip6tables -t mangle -A MIHOMO6 -i tailscale0 -p udp -j TPROXY --on-port 7893 --tproxy-mark 233&#xA;&#xA;# インターフェースチェインジャンプ&#xA;ip6tables -t mangle -A PREROUTING -i tailscale0 -j MIHOMO6&#xA;&#xA;# ルーティングテーブル設定&#xA;echo &#34;233 mihomo&#34; | tee -a /etc/iproute2/rt_tables&#xA;ip -6 rule add fwmark 233 lookup mihomo&#xA;ip -6 route add local ::/0 dev lo table mihomo&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ほとんどのシステムはデフォルトで iptables ルール等を永続化しません。ルールの永続化については、前述の記事の「&lt;a class=&#34;link&#34; href=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/#%E8%B7%AF%E7%94%B1%E8%A7%84%E5%88%99%E6%8C%81%E4%B9%85%E5%8C%96&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;ルーティングルールの永続化&lt;/a&gt;」「&lt;a class=&#34;link&#34; href=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/#iptables-%E8%A7%84%E5%88%99%E6%8C%81%E4%B9%85%E5%8C%96&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;iptables ルールの永続化&lt;/a&gt;」を参照してください。&lt;/p&gt;&#xA;&lt;h3 id=&#34;ローカルプロキシ設定例&#34;&gt;ローカルプロキシ設定例&#xA;&lt;/h3&gt;&lt;p&gt;多くのプロキシソフトや（実際 ShellCrash のデフォ設定も）、REDIRECT を使います。これでたいていのケースは十分です。たとえば&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;# IPv4 eth0 トラフィックをリダイレクト&#xA;iptables -t nat -A PREROUTING -i eth0 -p tcp -j REDIRECT --to-ports 7892&#xA;&#xA;# IPv6 eth0 トラフィック&#xA;ip6tables -t nat -A PREROUTING -i eth0 -p tcp -j REDIRECT --to-ports 7892&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;7892 は Mihomo 設定の&lt;code&gt;redir-port&lt;/code&gt;、&lt;code&gt;eth0&lt;/code&gt;はリダイレクトしたいインターフェースを指定します。Tproxy より圧倒的にシンプルです。&lt;/p&gt;&#xA;&lt;p&gt;個人的には、全トラフィックを防火壁で強制キャプチャする使い方は好きではありません。必要な時だけ、環境変数・proxychains・各種ソフトのプロキシ機能で Mihomo に向けて設定する方がスマートです。たとえば Docker のプロキシを通すなら&lt;code&gt;/etc/docker/daemon.json&lt;/code&gt;を編集すれば OK、わざわざ全体劫持する必要はありません。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-json&#34;&gt;{&#xA;  &#34;proxies&#34;: {&#xA;    &#34;http-proxy&#34;: &#34;http://127.0.0.1:7890&#34;,&#xA;    &#34;https-proxy&#34;: &#34;http://127.0.0.1:7890&#34;,&#xA;    &#34;no-proxy&#34;: &#34;127.0.0.0/8&#34;&#xA;  }&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;こんなに手間かけるより普通にクライアント使えば良くない&#34;&gt;こんなに手間かけるより、普通にクライアント使えば良くない？&#xA;&lt;/h2&gt;&lt;p&gt;それを聞くか…。答えは「虚無のターミナル遊び」に決まってるでしょ。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>MECHREVO Aurora X Pro 簡易レビュー</title>
            <link>https://blog.l3zc.com/ja/2025/05/new-laptop-briefing/</link>
            <pubDate>Sun, 04 May 2025 23:18:43 +0800</pubDate>
            <guid>https://blog.l3zc.com/ja/2025/05/new-laptop-briefing/</guid>
            <description>&lt;img src=&#34;https://blog.l3zc.com/2025/05/new-laptop-briefing/DSCF0267_hu_9e18f49bd8ce081.webp&#34; alt=&#34;Featured image of post MECHREVO Aurora X Pro 簡易レビュー&#34; /&gt;&lt;h2 id=&#34;開封直後からがっかり&#34;&gt;開封直後からがっかり&#xA;&lt;/h2&gt;&lt;p&gt;MECHREVO Aurora X Proについて、注文した瞬間から少し期待していたが、宅配便が香港旅行の前に間に合わず、帰宅して開封した時にはすでに新鮮味が失われていた。SSDを増設しようとしたらM.2ネジがなめてしまい、最終的に絶縁テープでなんとか固定。新しいPCへの好感度はその場で半減した。&lt;/p&gt;&#xA;&lt;h2 id=&#34;構成と価格&#34;&gt;構成と価格&#xA;&lt;/h2&gt;&lt;p&gt;i9-14900HX + RTX 5070 Ti、国の補助金後の価格は8699元で、まあ妥当な範囲。周辺機器については、正直なところ神舟（Hasee）でも満足して使っていたので、使えないものはないだろう。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;ディスプレイ&lt;/strong&gt;：2560x1600@300Hz、100% SRGB色域。発色も良く、「Cities: Skylines II」で渋滞のテールランプの赤が現実より鮮やかに感じる。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;キーボード&lt;/strong&gt;：キーストロークは浅め、打鍵感は普通。普段は外付けキーボードを使っているので特に気にならない。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;無線LANカード&lt;/strong&gt;：AX201は正直貧弱。アンテナ設計も微妙で、ルーターのすぐ横でも有線に比べて速度低下が明らか。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;SSD&lt;/strong&gt;：標準の致钛1TBは速度普通。自分で増設したCrucial（英睿达）2TBがメイン。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;バッテリー&lt;/strong&gt;：80Whでゲーミングノートとしては緊急用。普段はワークステーションモードでバッテリー寿命重視。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;dGPU直結&lt;/strong&gt;：ホットスワップ対応は高評価。再起動なしで切り替え可能。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;BIOS&lt;/strong&gt;：AMI BIOSは以前より遥かに使いやすい。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;使用感&#34;&gt;使用感&#xA;&lt;/h2&gt;&lt;p&gt;「Cities: Skylines II」――人口12万人でもシミュレーション速度は3倍速を維持。ただしこの時点でファンの騒音は爆音。「サイバーパンク2077」はレイトレーシングウルトラ設定可能。「Forza Horizon 5」なども含め、正直なところ、以前のRTX 3060と本質的な違いはほとんど感じない。反射がリアルになったり細部が増えたりはするが、画質向上だけでは、既に100時間以上遊んだこれらのゲームにさらに時間をかける気にはなれない。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/05/new-laptop-briefing/image_hu_8774b59db0175e9a.webp&#34; alt=&#34;Cities: Skylines IIのシミュ速度&#34; /&gt;&#xA; &#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/05/new-laptop-briefing/image-1_hu_47a3feef604ad189.webp&#34; alt=&#34;正直、違いは感じられない&#34; /&gt;&#xA; &#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/05/new-laptop-briefing/DSCF0267_hu_9e18f49bd8ce081.webp&#34; alt=&#34;ただそこにある、喋らないレンガのよう&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;パームレストのスキンコートは確かに手触りが良いが、外部デバイスを繋ぐと結局外付けキーボードしか触らない。Nahimicサウンドは遅延が酷く、オフにした方がosu!の操作感が良いという、典型的な負の最適化。&lt;/p&gt;&#xA;&lt;h2 id=&#34;ツールとしての意味&#34;&gt;ツールとしての意味&#xA;&lt;/h2&gt;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/05/new-laptop-briefing/DSCF0273_hu_e62683739afe024c.webp&#34; alt=&#34;新PCにした後のデスクトップ&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;このPCを2週間使ったが、驚きもなければ失望もない。無線LANがダメなので有線使用、ターボモードではファンがうるさい、サウスブリッジに冷却がなく温度が高い。それ以外は――必要な時に光り、必要な時に音を出すだけのマシン。&lt;/p&gt;&#xA;&lt;p&gt;良い道具とは本来そういうものかもしれない。ここまで書いてふと気付くと、右下のバッテリーアイコンを5分間もぼーっと見つめていた。でもこのPCは静かに98%のバッテリーを保ち、ただそこにある、喋らないレンガのようだった。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>初心者からプロまで：Tailscale &#43; ShellCrashを用いた遠隔ネットワーキングとセキュアなインターネット接続</title>
            <link>https://blog.l3zc.com/ja/2025/04/tailscale-setup-recap/</link>
            <pubDate>Mon, 14 Apr 2025 18:10:25 +0800</pubDate>
            <guid>https://blog.l3zc.com/ja/2025/04/tailscale-setup-recap/</guid>
            <description>&lt;img src=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/tailscale_hu_62168b00e213c4a1.webp&#34; alt=&#34;Featured image of post 初心者からプロまで：Tailscale + ShellCrashを用いた遠隔ネットワーキングとセキュアなインターネット接続&#34; /&gt;&lt;p&gt;旅行中に新しく撮った写真を長沙の自宅にある Immich サーバーにアップロードしようと試みていました。以前は Cloudflare Tunnel を使ってリバースプロキシを設定していましたが、中国の特有なネットワーク環境のために接続速度が遅く、頻繁に中断し、アップロードが失敗することが常態化していました。その後、Tailscale — WireGuard を基にした内部ネットワーク透過ツールを使い始めると、全国どこにいても安定して高速に自宅の NAS や写真ライブラリにアクセスできるようになりました。&lt;/p&gt;&#xA;&lt;p&gt;しかし新たな問題が発生しました：Tailscale が Android スマートフォンで動作する際、システムのトラフィックを VPN サービスとして制御する必要がありますが、私が普段使用している Clash も VPN インターフェースに依存して分岐しています。Android システムの制限（一つの VPN サービスのみ有効）のためにこれらは共存できず、「家庭内サービスへのアクセス」と「セキュアなインターネット接続」とを選択しなければならない状況になりました。&lt;/p&gt;&#xA;&lt;p&gt;この記事では、Tailscale の原理から始まり、独自の DERP サーバーを構築して接続品質を最適化する方法、さらに ShellCrash へトラフィックを転送するために iptables を用いた Tailscale Exit Node の流量の転送方法について解説します。NAS、写真ライブラリのアクセスや不慣れなネットワークでのデータ保護を目指す方にとって、この記事が実用的で安定した解決策を提供します。&lt;/p&gt;&#xA;&lt;h2 id=&#34;tailscale-とは&#34;&gt;Tailscale とは&#xA;&lt;/h2&gt;&lt;p&gt;Tailscale は WireGuard プロトコルを基にした設定不要の仮想 LAN ツールです。これにより、異なるネットワーク環境にあるデバイスが同じセキュアな内部ネットワーク内にいるかのように互いに通信できます。NAT やファイアウォールなどのネットワークの障壁を自動的に透過し、公衆 IP やポート転送なしで自宅の NAS、個人サーバー、開発環境などの内部リソースに簡単にアクセスできます。その主な利点は、シンプルで安全、安定しており、データ送信が全面的に暗号化されている点で、個人開発者、リモートワーカー、家庭ユーザーなどのいろいろなシーンに適しています。&lt;/p&gt;&#xA;&lt;p&gt;Tailscale の技術実装は非常に巧妙です：WireGuard 暗号化プロトコルに基づいていますが、従来の VPN の IP 割り当てのロジックを覆しました。デバイスは SSO/OAuth2 で認証後、それぞれが生涯にわたって結びつけられたノードキーを取得します。この身分に基づくネットワーキングモードにより、「長沙の NAS」と「香港のスマートフォン」が仮想ネットワーク内で直接通信できるようになります。&lt;/p&gt;&#xA;&lt;h2 id=&#34;tailscale-の接続プロセスの原理&#34;&gt;Tailscale の接続プロセスの原理&#xA;&lt;/h2&gt;&lt;h3 id=&#34;中央制御サーバーcontrol-server&#34;&gt;中央制御サーバー（Control Server）&#xA;&lt;/h3&gt;&lt;p&gt;Tailscale の各クライアントが起動すると、まず中央制御サーバー（control plane）に接続し、身分認証を行い、ネットワーク内の他のノードの情報を取得します。これには、各デバイスの公衆 IP、ポート、NAT のタイプなどが含まれます。このステップは「友達と知り合う」ようなものです。&lt;/p&gt;&#xA;&lt;p&gt;Tailscale の制御サーバーはデータ転送には関与せず、接続の調整のみを行います。これは一種のディスパッチセンターの役割です。&lt;/p&gt;&#xA;&lt;h3 id=&#34;derp-サーバー&#34;&gt;DERP サーバー&#xA;&lt;/h3&gt;&lt;p&gt;Tailscale が高い接続成功率を維持できる秘訣については、Tailscale 独自の中継プロトコル DERP を挙げることができます。Tailscale のネットワークアーキテクチャー内で、DERP（Designated Encrypted Relay for Packets）は非常に重要でありながら通常は必要時にのみ介在するコンポーネントです。簡単に言えば、これは HTTP ベースの暗号化リレーサーバーで、二台のデバイスが直接通信できない時に「中継所」として機能します。&lt;/p&gt;&#xA;&lt;p&gt;クライアント間の全ての接続は最初に DERP モード（中継モード）で選ばれ、これによってすぐに接続が確立でき、ユーザーは待つ必要がありません。その後、接続両者は同時にパス探索を開始し、通常数秒後に Tailscale はより優れたパスを発見し、既存の接続を透明にアップグレードします。これにより、点対点の直接接続へと移行します。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;注意が必要な点は：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;DERP を通じる全てのデータは端から端まで暗号化されており、DERP サーバーは内容を見ることができません；&lt;/li&gt;&#xA;&lt;li&gt;Tailscale はできるだけ少なく DERP を使用し、直接接続が成功したら自動的に切り替えます；&lt;/li&gt;&#xA;&lt;li&gt;公式には複数の分散 DERP ノードがデプロイされており、クライアントは自動的に最低遅延のものを選びます；&lt;/li&gt;&#xA;&lt;li&gt;自国内に DERP ノードを構築することもできます（中国など）、これにより高遅延や不安定な接続の問題を解決できます。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;DERP は兜底策として理解でき、性能は直接接続に劣りますが、接続の透通性を保証します。&lt;/p&gt;&#xA;&lt;h3 id=&#34;nat-透過nat-traversal&#34;&gt;NAT 透過（NAT Traversal）&#xA;&lt;/h3&gt;&lt;p&gt;相手のアドレス情報を手に入れた後、Tailscale は NAT 透過を使って点対点（P2P）接続を試みます。この過程では STUN プロトコルを使用し、双方が探索パケットを相互に送り、NAT ルーター上に直接通路を開くことを試みます。双方のネットワーク条件が許せば、UDP の直接トンネル接続が成功し、データは直接通路を通じて、速度が速く、遅延が低くなります。&lt;/p&gt;&#xA;&lt;p&gt;この部分の詳しい原理について興味があれば、Tailscale 公式の「&lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/blog/how-nat-traversal-works&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;How NAT traversal works&lt;/a&gt;」を参照してください。&lt;/p&gt;&#xA;&lt;h3 id=&#34;完全な接続の流れを示す図&#34;&gt;完全な接続の流れを示す図&#xA;&lt;/h3&gt;&lt;pre&gt;&lt;code class=&#34;language-mermaid&#34;&gt;flowchart TD&#xA;    A[デバイス A が Tailscale を起動] --&gt; B[DERP サーバーを通じて初期接続を確立]&#xA;    B --&gt; C[ネットワーク情報と WireGuard キーを交換]&#xA;    C --&gt; D[NAT タイプの検査を並行して実施]&#xA;    D --&gt; E{直接接続は可能か?}&#xA;    E -- はい --&gt; F[P2P 直接トンネルを確立]&#xA;    F --&gt; G[接続品質を定期チェック]&#xA;    G --&gt; H{直接接続は DERP より優れているか?}&#xA;    H -- はい --&gt; I[大部分のトラフィックを直接通路に切り替え]&#xA;    H -- いいえ --&gt; J[トラフィックを DERP 経由で転送し続ける]&#xA;    E -- いいえ --&gt; J&#xA;&#xA;    %% スタイル設定&#xA;    style B fill:#e3f2fd,stroke:#2196f3,color:#000&#xA;    style F fill:#e8f5e9,stroke:#4caf50,color:#000&#xA;    style J fill:#fff3e0,stroke:#ff9800,color:#000&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;自前の-derp-を構築する&#34;&gt;自前の DERP を構築する&#xA;&lt;/h2&gt;&lt;p&gt;Tailscale のインストールは各プラットフォームで比較的簡単で、公式文書が詳細な操作ガイドを提供しています。この記事ではインストールプロセスには触れませんが、以下の内容はあなたが関連するデバイス上で Tailscale を既に成功的にインストールしてログインしていることを前提としています。&lt;/p&gt;&#xA;&lt;h3 id=&#34;なぜ自前の-derp-を構築するのか&#34;&gt;なぜ自前の DERP を構築するのか？&#xA;&lt;/h3&gt;&lt;p&gt;Tailscale は世界中に多数の DERP &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;中継サーバーを配置しています。これは NAT の穿通に失敗した際にトラフィックの中継を担当します。しかし、よく知られている理由で、中国本土には公式の DERP ノードが配置されていません。これは以下を意味します：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;NAT の穿通に失敗すると、すべてのトラフィックが海外の DERP ノードを経由する必要があります。これにより遅延が高くなり、速度が遅くなり、体験が悪化します；&lt;/li&gt;&#xA;&lt;li&gt;いくつかの公式 DERP ノードは GFW によって干渉されやすく、接続が中断されたり、ハンドシェイクが失敗することがあります；&lt;/li&gt;&#xA;&lt;li&gt;穿通に成功しても、Tailscale は依然として DERP を通じてルーティング情報と WireGuard キーを交換する必要があります。もし DERP が接続不可能だと、接続品質も影響を受けます。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;したがって、中国のネットワーク環境では、地元の DERP ノードを自前で構築することで接続の安定性と転送性能を大幅に向上させることができ、ネットワークのブロックによる予期せぬ問題を回避することができます。&lt;/p&gt;&#xA;&lt;h3 id=&#34;準備作業&#34;&gt;準備作業&#xA;&lt;/h3&gt;&lt;p&gt;先に述べたように、DERP は HTTP ベースですので、HTTP リバースプロキシサービスの準備と SSL 証明書の発行などの基本問題を解決する必要があります。この記事では Docker を使用してデプロイします。デプロイ開始前にサーバーに Docker および Docker Compose などの追加コンポーネントをインストールしておく必要があります。設定ファイルの編集には nano などのエディタを使用する知識も必要です。最良の結果を得るために、サーバーは静的な公衆 IPv4+IPv6 デュアルスタックアドレスを持っていることが望ましいです。&lt;/p&gt;&#xA;&lt;p&gt;すべての条件が整っていれば、デプロイを開始できます。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;mkdir tailscale-derp &amp;&amp; cd tailscale-derp&#xA;nano docker-compose.yml&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;docker-composeyml&#34;&gt;docker-compose.yml&#xA;&lt;/h3&gt;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;services:&#xA;  derper:&#xA;    name: tailscale-derp&#xA;    image: fredliang/derper&#xA;    environment:&#xA;      - DERP_DOMAIN=derp.nightcity.pub&#xA;      - DERP_VERIFY_CLIENTS=true&#xA;      - DERP_ADDR=:4433&#xA;    network_mode: host&#xA;    restart: unless-stopped&#xA;    volumes:&#xA;      - &#34;/var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock&#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;network_mode: host&lt;/code&gt;は重要な設定であり、コンテナはホストマシンのネットワークスタックと共有します。もし Docker のデフォルトの bridge ネットワークモードを使用すると、コンテナのネットワークは Docker 内部ネットワークを経由して転送され、DERP の STUN サービスは Docker &lt;code&gt;172.17.0.0/16&lt;/code&gt;アドレス範囲のアドレスを識別できません。そのため、クライアントの正しい外部アドレスを識別できず、Tailscale クライアントが正しく接続できません。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;volumes:&#xA;  - &#34;/var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock&#34;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;先に述べたように、DERP を通じるすべてのデータは端から端まで暗号化されており、DERP は誰が使用しているかを知りません。この意味は、対策を講じない場合、あなたの DERP サーバーのアドレスとポート番号を知っている誰でもそれを使用することができます。この設定の目的は、ホストマシンの Tailscale ソケットファイルをコンテナにマウントして、&lt;code&gt;DERP_VERIFY_CLIENTS=true&lt;/code&gt;を使用することで、認証を行うことができ、あなたの DERP ノードが他人に無断で使用されることを防ぎます。&lt;/p&gt;&#xA;&lt;p&gt;重要な注意点は以下の通りです：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;ホストマシンには Tailscale クライアント（tailscaled）がインストールされ、ログインされている必要があります。このファイルが存在しない場合、コンテナはエラーを報告します；&lt;/li&gt;&#xA;&lt;li&gt;tailscaled は root 権限で実行される必要があり、この sock ファイルを作成できます。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;リバースプロキシの設定&#34;&gt;リバースプロキシの設定&#xA;&lt;/h3&gt;&lt;p&gt;Caddy を例にして、4433 ポートをリバースプロキシし、SSL 証明書をデプロイする方法を示します。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-caddyfile&#34;&gt;{&#xA;        email webmaster@l3zc.com&#xA;}&#xA;*.l3zc.com {&#xA;        encode gzip&#xA;        tls {&#xA;                dns dnspod APP_ID,APP_KEY&#xA;                resolvers 119.29.29.29 223.5.5.5&#xA;        }&#xA;        @derp host derp.l3zc.com&#xA;        reverse_proxy @derp :4433&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Caddy と dnsproviders を使ってワイルドカードデジタル証明書を申請する場合、Tailscale の MagicDNS が Caddy のローカル証明書検証に障害をもたらす可能性があるため、&lt;code&gt;resolvers&lt;/code&gt;パラメータを手動で設定する必要があります。&#xA;設定されたノードにアクセスすれば、以下のページが表示されれば、設定が正しいことが確認できます。&lt;/p&gt;&#xA;&lt;h3 id=&#34;acl-ポリシーの設定&#34;&gt;ACL ポリシーの設定&#xA;&lt;/h3&gt;&lt;p&gt;Tailscale のコントロールパネルの「」ページにて ACL ポリシーを設定し、設定した DERP を追加します。&lt;/p&gt;&#xA;&lt;p&gt;Tailscale の ACL ポリシーは HuJSON&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;で書かれており、VSCode で編集する場合は言語設定を「JSON with Comments（jsonc）」に設定することができます。以下は設定例です：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-jsonc&#34;&gt;{&#xA;  &#34;acls&#34;: [{ &#34;action&#34;: &#34;accept&#34;, &#34;src&#34;: [&#34;*&#34;], &#34;dst&#34;: [&#34;*:*&#34;] }],&#xA;  &#34;ssh&#34;: [&#xA;    {&#xA;      &#34;action&#34;: &#34;check&#34;,&#xA;      &#34;src&#34;: [&#34;autogroup:member&#34;],&#xA;      &#34;dst&#34;: [&#34;autogroup:self&#34;],&#xA;      &#34;users&#34;: [&#34;autogroup:nonroot&#34;, &#34;root&#34;]&#xA;    }&#xA;  ],&#xA;  // 自営のDERP設定&#xA;  &#34;derpMap&#34;: {&#xA;    &#34;OmitDefaultRegions&#34;: false, // 公式のDERPを除外するにはtrueに変更&#xA;    &#34;Regions&#34;: {&#xA;      &#34;900&#34;: {&#xA;        &#34;RegionID&#34;: 900,&#xA;        &#34;RegionCode&#34;: &#34;sha&#34;,&#xA;        &#34;RegionName&#34;: &#34;上海&#34;,&#xA;        &#34;Nodes&#34;: [&#xA;          {&#xA;            &#34;Name&#34;: &#34;myderp&#34;,&#xA;            &#34;RegionID&#34;: 900,&#xA;            &#34;HostName&#34;: &#34;derp.l3zc.com&#34;&#xA;          }&#xA;        ]&#xA;      }&#xA;    }&#xA;  }&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Tailscale は RegionID 1-899 を公式ノードとして予約していますが、自営ノードの RegionID は 900 以上である必要があります。&lt;/p&gt;&#xA;&lt;h3 id=&#34;接続のテスト&#34;&gt;接続のテスト&#xA;&lt;/h3&gt;&lt;p&gt;ACL の設定が完了し保存されると、Tailscale は自動的にすべてのクライアントに設定を同期し、少し待ってからクライアントで&lt;code&gt;tailscale netcheck&lt;/code&gt;を使用して接続をテストします。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/image-1_hu_25ccc2304c1a66fd.webp&#34; alt=&#34;tailscale netcheckを使用して接続をテスト&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;戻り値の IP が実際の公衆 IP であるかを確認する必要があります。もし&lt;code&gt;172.17.0.0/16&lt;/code&gt;アドレス範囲のアドレスが戻ってきた場合、Docker の設定が間違っている可能性があります。&lt;/p&gt;&#xA;&lt;h2 id=&#34;exit-node-でのトラフィックを-clash-コアにハイジャックする科学的なインターネット接続の共存&#34;&gt;Exit Node でのトラフィックを Clash コアにハイジャックする：科学的なインターネット接続の共存&#xA;&lt;/h2&gt;&lt;h3 id=&#34;exit-node-の宣言&#34;&gt;Exit Node の宣言&#xA;&lt;/h3&gt;&lt;p&gt;家では 24 時間稼働するデバイスを用意します。これはラズベリーパイでも MacMini でもかまいません。そこに Tailscale をインストールし、それを Exit Node として宣言します。また、必要に応じて Tailscale の内部ネットワークで家庭内ネットワークセグメントを宣言し、その後コントロールパネルでこのデバイスを Exit Node として有効にします。これにより無料の VPN が手に入り、見知らぬネットワーク環境でも安全を保ちながら接続することができます。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;sudo tailscale up --advertise-exit-node --advertise-routes 192.168.1.0/24&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/image-2_hu_bac8de7f1a5258d0.webp&#34; alt=&#34;Route Settingsを探す&#34; /&gt;&#xA; &#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/Snipaste_2025-04-13_21-20-09_hu_d8313f59e1940d09.webp&#34; alt=&#34;関連設定を有効にする&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;ルーティングが完了すると、どこにいても Tailscale ネットワークに接続できる限り、家庭内のすべての内部デバイスにアクセスすることができます。&lt;/p&gt;&#xA;&lt;h3 id=&#34;ip-フォワーディングの有効化と-udp-gro-の無効化&#34;&gt;IP フォワーディングの有効化と UDP GRO の無効化&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&#xA;&lt;/h3&gt;&lt;p&gt;ラズベリーパイなどのデバイスが Exit Node として機能するために必要な設定です。この例ではラズベリーパイを使用しますが、使用しているデバイスに応じて Tailscale 公式ウェブサイトのチュートリアルを参照してください。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;echo &#39;net.ipv4.ip_forward = 1&#39; | sudo tee -a /etc/sysctl.d/99-tailscale.conf&#xA;echo &#39;net.ipv6.conf.all.forwarding = 1&#39; | sudo tee -a /etc/sysctl.d/99-tailscale.conf&#xA;sudo sysctl -p /etc/sysctl.d/99-tailscale.conf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Tailscale 公式の文献によると&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;、UDP GRO&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;を無効にすることで転送性能が向上するとされていますが、公式の永続的なチュートリアルはラズベリーパイでは効果がありません。しかし、手動での設定が可能です。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;# ethtoolのインストール&#xA;sudo apt update &amp;&amp; sudo apt install ethtool -y&#xA;# UDP GROを無効にする&#xA;sudo ethtool -K eth0 gro off&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;持続化のために手動で systemd 設定ファイルを作成します：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;# サービスファイルの作成&#xA;sudo nano /etc/systemd/system/ethtool.service&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ファイルの内容は以下の通りです：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-systemd&#34;&gt;[Unit]&#xA;Description=Configure eth0 GRO&#xA;After=network.target&#xA;[Service]&#xA;Type=oneshot&#xA;ExecStart=/sbin/ethtool -K eth0 gro off&#xA;[Install]&#xA;WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;その後、サービスを起動します：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;sudo systemctl daemon-reload&#xA;sudo systemctl enable ethtool&#xA;sudo systemctl start ethtool&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;exit-node-でのトラフィックハイジャック&#34;&gt;Exit Node でのトラフィックハイジャック&#xA;&lt;/h3&gt;&lt;p&gt;私の Exit Node はラズベリーパイで、ラズベリーパイで Exit Node の設定が完了したら、最後のステップ、つまりスマートフォンから Exit Node に送信されるトラフィックをハイジャックして、セキュアなインターネット接続を実現します。安定性を考慮して、家庭のメインルーターで直接プロキシソフトウェアを実行することは避けています。この目的を実現するために、ラズベリーパイで直接トラフィックをハイジャックすることが唯一の選択肢です。&lt;/p&gt;&#xA;&lt;p&gt;まず ShellCrash をインストールし、必要に応じて設定ファイルをインポートし、自動タスクを設定してください：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;export url=&#39;https://fastly.jsdelivr.net/gh/juewuy/ShellCrash@master&#39; &amp;&amp; wget -q --no-check-certificate -O /tmp/install.sh $url/install.sh  &amp;&amp; bash /tmp/install.sh &amp;&amp; source /etc/profile &amp;&gt; /dev/null&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;その後、サービスを起動し、ファイヤーウォールの運用モードを純粋モードに変更することを個人的にお勧めします。SNI スニッフィングをオンにし、DNS モードを&lt;code&gt;fake-ip&lt;/code&gt;から&lt;code&gt;redir-host&lt;/code&gt;&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;に切り替え、IPv6 透過プロキシを有効にします。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/image-3_hu_efcbb45f4cd30701.webp&#34; alt=&#34;ドメインスニッフィングの有効化&#34; /&gt;&#xA; &#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/image-3_hu_efcbb45f4cd30701.webp&#34; alt=&#34;ドメインスニッフィングを有効にする&#34; /&gt;&#xA;&#xA;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/image-6_hu_d681ee087b8dd14a.webp&#34; alt=&#34;ポート設定の変更&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;純粋モードを設定する目的は、iptables でより精密なトラフィックハイジャックを手動で構成することです。私たちは、Tailscale のネットワークインターフェース&lt;code&gt;tailscale0&lt;/code&gt;を介して Exit Node に転送されるすべてのトラフィックを、ローカルの Clash コアがリッスンしているポート&lt;code&gt;7892&lt;/code&gt;（静的ルートポートと呼ばれる）にハイジャックします。また、不可解なネットワーク問題に直面しないよう、IPv6 もハイジャックします。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;# IPv4でtailscale0の全トラフィックをハイジャック&#xA;iptables -t nat -A PREROUTING -i tailscale0 -p tcp -j REDIRECT --to-ports 7892&#xA;# IPv6でtailscale0の全トラフィックをハイジャック&#xA;ip6tables -t nat -A PREROUTING -i tailscale0 -p tcp -j REDIRECT --to-ports 7892&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;進階tproxy-を使用して-udp-トラフィックをハイジャックする&#34;&gt;進階：TProxy を使用して UDP トラフィックをハイジャックする&#xA;&lt;/h3&gt;&lt;p&gt;iptables の REDIRECT は TCP トラフィックのみリダイレクト可能で、UDP は接続状態を持たない（コネクションレスプロトコル）ため、REDIRECT では目的アドレスを保持できず、透明プロキシが元の目的アドレスを知ることができません。&lt;/p&gt;&#xA;&lt;p&gt;したがって、以下のように UDP トラフィックをハイジャックする場合：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;iptables -t nat -A PREROUTING -i tailscale0 -p udp -j REDIRECT --to-ports 7892&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このルールは効果がないか、プロキシの動作が正常ではありません。&lt;/p&gt;&#xA;&lt;p&gt;では、UDP トラフィックをプロキシする方法はあるのでしょうか？はい、方法はありますが、前提条件があります：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;コアが UDP 透明プロキシをサポートしている必要があります（Clash Premium や Mihomo が対応しています）；&lt;/li&gt;&#xA;&lt;li&gt;TProxy モードを使用し、REDIRECT ではなく；&lt;/li&gt;&#xA;&lt;li&gt;iptables mangle テーブルと policy routing が正しく設定されていること；&lt;/li&gt;&#xA;&lt;li&gt;プロキシ構成ファイルで UDP プロキシが有効になっていること（例：mode: rule + udp: true）。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;最初の 3 つの条件を満たしている場合、以下に例を示します&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;# カスタムチェーンを作成&#xA;sudo iptables -t mangle -N SHELLCRASH&#xA;&#xA;# ローカルトラフィックを無視&#xA;sudo iptables -t mangle -A SHELLCRASH -d 127.0.0.1/8 -j RETURN&#xA;sudo iptables -t mangle -A SHELLCRASH -d 100.64.0.0/10 -j RETURN&#xA;sudo iptables -t mangle -A SHELLCRASH -d 192.168.1.0/24 -j RETURN&#xA;sudo iptables -t mangle -A SHELLCRASH -d 172.17.0.0/16 -j RETURN&#xA;&#xA;# UDP と TCP をプロキシへマーク&#xA;sudo iptables -t mangle -A SHELLCRASH -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233&#xA;sudo iptables -t mangle -A SHELLCRASH -p udp -j TPROXY --on-port 7893 --tproxy-mark 233&#xA;&#xA;# インターフェースジャンプ&#xA;sudo iptables -t mangle -A PREROUTING -i tailscale0 -j SHELLCRASH&#xA;&#xA;# ルーティングテーブル設定&#xA;echo &#34;233 shellcrash&#34; | sudo tee -a /etc/iproute2/rt_tables&#xA;sudo ip rule add fwmark 233 lookup shellcrash&#xA;sudo ip route add local 0.0.0.0/0 dev lo table shellcrash&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;もちろん、IPv6 を忘れないでください：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;# チェーンを作成&#xA;sudo ip6tables -t mangle -N SHELLCRASH6&#xA;&#xA;# ローカルアドレスをスキップ&#xA;sudo ip6tables -t mangle -A SHELLCRASH6 -d ::1/128 -j RETURN&#xA;sudo ip6tables -t mangle -A SHELLCRASH6 -d fd7a:115c:a1e0::/48 -j RETURN&#xA;&#xA;# TCP/UDP をマーク&#xA;ip6tables -t mangle -A SHELLCRASH6 -i tailscale0 -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233&#xA;ip6tables -t mangle -A SHELLCRASH6 -i tailscale0 -p udp -j TPROXY --on-port 7893 --tproxy-mark 233&#xA;&#xA;# インターフェースジャンプ&#xA;sudo ip6tables -t mangle -A PREROUTING -i tailscale0 -j SHELLCRASH6&#xA;&#xA;# ルーティングテーブル設定&#xA;echo &#34;233 shellcrash&#34; | sudo tee -a /etc/iproute2/rt_tables&#xA;sudo ip -6 rule add fwmark 233 lookup shellcrash&#xA;sudo ip -6 route add local ::/0 dev lo table shellcrash&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;ルーティングルールの永続化&#34;&gt;ルーティングルールの永続化&#xA;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;ip rule&lt;/code&gt;および&lt;code&gt;ip route&lt;/code&gt;で作成されるルールは再起動後失われますので、手動で永続化する必要があります。最も簡単かつ直接的な方法はスクリプトを作成し、それを crontab に追加することです。&lt;/p&gt;&#xA;&lt;p&gt;スクリプトを作成：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;sudo nano /usr/local/bin/policy-route.sh&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以下の内容で編集：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;#!/bin/bash&#xA;&#xA;# IPv4 ポリシールーティング&#xA;ip rule add fwmark 233 lookup 233&#xA;ip route add local 0.0.0.0/0 dev lo table 233&#xA;&#xA;# IPv6 ポリシールーティング&#xA;ip -6 rule add fwmark 233 lookup 233&#xA;ip -6 route add local ::/0 dev lo table 233&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;実行権限を付与した後、Crontab を編集：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;sudo chmod +x /usr/local/bin/policy-route.sh&#xA;sudo crontab -e&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;crontab ファイルの最後に以下の内容を追加：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-crontab&#34;&gt;@reboot /usr/local/bin/policy-route.sh&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;原理解説tproxy-はどのように-udp-トラフィックを転送するのか&#34;&gt;原理解説：TProxy はどのように UDP トラフィックを転送するのか？&#xA;&lt;/h3&gt;&lt;p&gt;ここまで来ると、疑問が湧くかもしれません：なぜプロセス全体で&lt;code&gt;--to-ports&lt;/code&gt;を指定していないのに、iptables でも目的地が書き換えられていないのに、UDP トラフィックが不可解にもプロキシされたのでしょうか？これはどうやって実現されるのでしょうか？&lt;/p&gt;&#xA;&lt;p&gt;この問題を解明するために、まず TProxy と REDIRECT の基本的な違いを見てみましょう：&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;REDIRECT モード：&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;iptables nat テーブルを使用；&lt;/li&gt;&#xA;&lt;li&gt;目的アドレスをローカルアドレス（例えば 127.0.0.1:7892）に書き換え；&lt;/li&gt;&#xA;&lt;li&gt;主に TCP トラフィック用；&lt;/li&gt;&#xA;&lt;li&gt;実際の目的アドレスを保持できない；&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;--to-ports&lt;/code&gt;を指定する必要がある。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-mermaid&#34;&gt;flowchart TB&#xA;    A[クライアントデバイス&lt;br&gt;Tailscaleを通じてTCPリクエストを開始]&#xA;    B[tailscale0 インターフェースがトラフィックを受信]&#xA;    C[iptables NAT PREROUTING&lt;br&gt;REDIRECT --to-ports 7892]&#xA;    D[ShellCrash ローカルでリッスン&lt;br&gt;127.0.0.1:7892]&#xA;    E[ShellCrash が新しい TCP リクエストを開始&lt;br&gt;→ 目的サーバー]&#xA;    F[ネットワークからの応答が戻る&lt;br&gt;ShellCrashが応答を転送]&#xA;    G[応答回クライアントデバイス]&#xA;&#xA;    A --&gt; B --&gt; C --&gt; D --&gt; E --&gt; F --&gt; G&#xA;&#xA;    style C fill:#f9f,stroke:#aaa,stroke-width:1px,color:#000&#xA;    style D fill:#bbf,stroke:#aaa,stroke-width:1px,color:#000&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;TPROXY モード：&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;iptables mangle テーブルを使用；&lt;/li&gt;&#xA;&lt;li&gt;目的 IP を変更せず、元の目的アドレスを保持；&lt;/li&gt;&#xA;&lt;li&gt;fwmark と policy routing を使用してパケットを &lt;code&gt;lo&lt;/code&gt; へルーティング；&lt;/li&gt;&#xA;&lt;li&gt;プロキシプログラムが特定のポート（例えば 7893）をリッスンし、&lt;code&gt;IP_TRANSPARENT&lt;/code&gt; を有効に；&lt;/li&gt;&#xA;&lt;li&gt;UDP および TCP をサポート；&lt;/li&gt;&#xA;&lt;li&gt;NAT ではなく、マーク + ルーティングのため、iptables 内で &lt;code&gt;--to-ports&lt;/code&gt; を指定する必要はない。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-mermaid&#34;&gt;flowchart TB&#xA;    A[クライアントデバイス&lt;br&gt;Tailscaleを通じてTCP/UDPリクエストを開始]&#xA;    B[tailscale0 インターフェースがトラフィックを受信]&#xA;    C[iptables MANGLE PREROUTING&lt;br&gt;fwmark 233を適用]&#xA;    D[ip rule: fwmark 233&lt;br&gt;使用 routing table shellcrash]&#xA;    E[ip route: local 0.0.0.0/0&lt;br&gt;dev lo table shellcrash]&#xA;    F[ShellCrash は lo:7893 でリッスン&lt;br&gt;IP_TRANSPARENT モード]&#xA;    G[ShellCrash が元の目的アドレスを取得&lt;br&gt;プロキシ接続を開始]&#xA;    H[ネットワークからの応答が戻る&lt;br&gt;ShellCrashが応答を転送]&#xA;    I[応答回クライアントデバイス]&#xA;&#xA;    A --&gt; B --&gt; C --&gt; D --&gt; E --&gt; F --&gt; G --&gt; H --&gt; I&#xA;&#xA;    style C fill:#f9f,stroke:#aaa,stroke-width:1px,color:#000&#xA;    style F fill:#bbf,stroke:#aaa,stroke-width:1px,color:#000&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;TProxy は DNAT/REDIRECT を使用せず、mangle テーブルでパケットに mark をつけ、policy routing（&lt;code&gt;ip rule&lt;/code&gt; + &lt;code&gt;ip route&lt;/code&gt;）によってこれらのパケットを &lt;code&gt;lo&lt;/code&gt; インタフェースに送ります。プロキシプログラム（例：Clash / ShellCrash）は &lt;code&gt;lo&lt;/code&gt;&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt; でポート（例えば 7893）をリッスンしており、&lt;code&gt;IP_TRANSPARENT&lt;/code&gt; オプションを有効にすることで、パケットの元の目的 IP とポートを読み取り、代理転送を行います。&lt;/p&gt;&#xA;&lt;p&gt;端的に言うと、TProxy モードは以下の 3 つのステップで動作します：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;iptables&lt;/code&gt; でデータパケットに mark をつける；&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;ip rule&lt;/code&gt; + &lt;code&gt;ip route&lt;/code&gt; でこれらのパケットを &lt;code&gt;lo&lt;/code&gt; に送る；&lt;/li&gt;&#xA;&lt;li&gt;プログラムが &lt;code&gt;lo&lt;/code&gt; 上のポートをリッスンし、&lt;code&gt;IP_TRANSPARENT&lt;/code&gt; を有効にする。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;したがって、iptables 内で &lt;code&gt;--to-ports&lt;/code&gt; を指定する必要はなく、なぜなら目的 IP とポートは変わらないため、代理プログラムが自身で感知し処理することができるからです。&lt;/p&gt;&#xA;&lt;h3 id=&#34;iptables-ルールの永続化&#34;&gt;iptables ルールの永続化&#xA;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;iptables-persistent&lt;/code&gt; をインストール：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;sudo apt update&#xA;sudo apt install iptables-persistent&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;インストール中に現在の IPv4 および IPv6 設定を保存するかどうかを尋ねられますので、「はい」を選択してください。新しいルールを追加した後は、保存コマンドを実行してください：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;# 現在の IPv4/IPv6 ルールを保存&#xA;sudo netfilter-persistent save&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;保存されたルールファイルのパス：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;IPv4：&lt;code&gt;/etc/iptables/rules.v4&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;IPv6：&lt;code&gt;/etc/iptables/rules.v6&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;必要に応じて上記の&lt;code&gt;rules.v4&lt;/code&gt;/&lt;code&gt;rules.v6&lt;/code&gt;ファイルを直接編集できます。&lt;/p&gt;&#xA;&lt;h2 id=&#34;最終的な効果&#34;&gt;最終的な効果&#xA;&lt;/h2&gt;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/Screenshot_2025-04-14-18-05-18-259_com.tailscale._hu_783d6158c36336e1.webp&#34; alt=&#34;ほとんどの場合、打ち破ることができます&#34; /&gt;&#xA; &#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/04/tailscale-setup-recap/Screenshot_2025-04-14-18-04-45-053_com.cnspeedtes_hu_a47b6440dc775101.webp&#34; alt=&#34;速度はまあまあです&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;このセットアップの使用体験は、あなたの家の上り帯域幅に依存します。私の家のネットワークは下り 500M、上り 60M で、一度も打ち破れないことはありませんでした。したがって、ほぼ全速力で走ることができ、遅延も許容範囲内です。また、外出先でいつでも家の Immich や OpenWRT ルーターなどのデバイスにエンドツーエンドで暗号化されたアクセスを提供し、科学的なインターネットを実現できるため、全体としては非常に満足しています。&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;参照: &lt;a class=&#34;link&#34; href=&#34;https://icloudnative.io/posts/custom-derp-servers/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://icloudnative.io/posts/custom-derp-servers/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;参照: &lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/kb/1232/derp-servers&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://tailscale.com/kb/1232/derp-servers&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;HuJSON について: &lt;a class=&#34;link&#34; href=&#34;https://github.com/tailscale/hujson&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://github.com/tailscale/hujson&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;参照： &lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/kb/1408/quick-guide-exit-nodes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://tailscale.com/kb/1408/quick-guide-exit-nodes&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:5&#34;&gt;&#xA;&lt;p&gt;参照: &lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:6&#34;&gt;&#xA;&lt;p&gt;UDP GRO（汎用受信オフロード）は Linux カーネル内のネットワーク最適化技術で、複数の小さなパケットを一つにすることで処理効率を上げるものです。しかし、デバイスがネットワーク転送ノードとして使用される場合、これにより転送遅延が増加し、パケットロスが高い環境でのスループットが低下する可能性があります。&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:7&#34;&gt;&#xA;&lt;p&gt;&lt;code&gt;fake-ip&lt;/code&gt;に比べて、&lt;code&gt;redir-host&lt;/code&gt;は互換性が高く、問題が発生する可能性が低くなります。また、プロキシのオン/オフ後に&lt;code&gt;fake-ip&lt;/code&gt;が残ってインターネット接続が一時的に中断されることがなくなるため、一般的には&lt;code&gt;redir-host&lt;/code&gt;を GeoSite 分流ルールと組み合わせて使用することをお勧めします。私のラズベリーパイ上の DNS はを使用しており、DNS 汚染がなく、快適に動作しています。&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:8&#34;&gt;&#xA;&lt;p&gt;参考: &lt;a class=&#34;link&#34; href=&#34;https://blog.zonowry.com/posts/clash_iptables_tproxy/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://blog.zonowry.com/posts/clash_iptables_tproxy/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:9&#34;&gt;&#xA;&lt;p&gt;&lt;code&gt;lo&lt;/code&gt; は Linux システムのデフォルトの「ループバックインターフェース」として機能しますが、透明プロキシではそれが単に localhost トラフィックを処理するだけでなく、外部世界からのネットワーク接続を受け取り、外部トラフィックをローカルでハイジャックして転送するために使用されます。&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
        </item><item>
            <title>Google Play ストアの中国CDN：暗号学入門から分流戦略の最適化まで</title>
            <link>https://blog.l3zc.com/ja/2025/03/chinese-cdn-used-by-playstore/</link>
            <pubDate>Sat, 15 Mar 2025 21:15:01 +0800</pubDate>
            <guid>https://blog.l3zc.com/ja/2025/03/chinese-cdn-used-by-playstore/</guid>
            <description>&lt;img src=&#34;https://blog.l3zc.com/2025/03/chinese-cdn-used-by-playstore/cover_hu_8e92ca92eba5064b.webp&#34; alt=&#34;Featured image of post Google Play ストアの中国CDN：暗号学入門から分流戦略の最適化まで&#34; /&gt;&lt;p&gt;Mihomoのルールをカスタマイズした後、Google Playからアプリをダウンロードすると、なぜかずっとローディングが続くようになりました。しかし、他のルールを使うと問題なく動作します。これは非常に奇妙な現象です。そこで、Mihomoのカーネルログを確認してみました。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-log&#34;&gt;play-lh.googleusercontent.com:443 match RuleSet(cdn_domainset) using 静的リソース[🇭🇰 香港 07]&#xA;play.googleapis.com:443 match GeoSite(GFW) using ノード選択[🇭🇰 香港 07]&#xA;play-lh.googleusercontent.com:443 match RuleSet(cdn_domainset) using 静的リソース[🇭🇰 香港 07]&#xA;play-fe.googleapis.com:443 match GeoSite(GFW) using ノード選択[🇭🇰 香港 07]&#xA;services.googleapis.cn:443 match GeoSite(CN) using グローバルダイレクト[DIRECT]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;（上記のログは簡略化されています）&lt;/p&gt;&#xA;&lt;p&gt;中国国内向けのスマートフォンにプリインストールされているGoogle Playサービスは、&lt;code&gt;services.googleapis.com&lt;/code&gt;ではなく&lt;code&gt;services.googleapis.cn&lt;/code&gt;というドメインを使用しています。このドメインは、ほとんどの分流ルールでダイレクト接続に設定されています。ここに問題があるのです。このドメインをプロキシに分流するようにルールを修正すれば、問題は解決します！&lt;/p&gt;&#xA;&lt;p&gt;……本当に解決するのでしょうか？&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;rr4---sn-j5o7dn7s.xn--ngstr-lra8j.com:443 match Match using 漏網の魚[🇭🇰 香港 07]&#xA;rr2---sn-j5o7dn7s.xn--ngstr-lra8j.com:443 match Match using 漏網の魚[🇭🇰 香港 07]&#xA;rr1---sn-j5o76n7z.xn--ngstr-lra8j.com:443 match Match using 漏網の魚[🇭🇰 香港 07]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;待ってください、なぜPlayストアからアプリをダウンロードするたびにこれらの奇妙なドメインが現れるのでしょうか？オンラインで調べてみると、新たな世界が開けました。&lt;/p&gt;&#xA;&lt;h2 id=&#34;googleとは対照的でありながらも似ているångströ&#34;&gt;Googleとは対照的でありながらも似ているÅngströ&#xA;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;xn--ngstr-lra8j.com&lt;/code&gt;というドメインを見て、ドメインに詳しい人はすぐにこれがPunyCodeエンコーディングであることに気づくでしょう。この文字列をデコードすると、&lt;code&gt;ångströ.com&lt;/code&gt;となります。Anders Jonas Ångströmは、スウェーデンの物理学者で、分光学の創始者です。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;エングストローム（Ångström）は、彼を記念して名付けられた長さの単位で、$ 1 Å = 10^{-10} m = \frac{1}{10} nm $と定義され、原子や分子のサイズ、光の波長など、非常に短い距離を表すために使用されます。これは、特に物理学や化学における微細な測定において、極めて小さな量を表すために使用されます。&lt;/p&gt;&#xA;&lt;p&gt;Googleの名前は直接「Googol」から取られたわけではありませんが、そのインスピレーションはこの言葉から得られています。「Googol」は数学用語で、$10^{100}$、つまり1の後に0が100個続く数を表し、非常に大きな数を表すために使用されます。これは、コンピュータサイエンスにおいて扱われる巨大な数や情報量を表すためによく使われます。&lt;/p&gt;&#xA;&lt;p&gt;命名の哲学において、GoogleとÅngströは、一見すると対極にあるように見える技術概念ですが、興味深い対称性を持っています。前者は数学的概念「Googol」から創造的に改変されたものであり、後者は物理単位「Ångström」からイメージを再構築したものです。この2つの芸術的に変奏された名称は、技術文明の二重螺旋のように見えます。Googleという名前は、星の海のような数字の宇宙を制御する野心を担い、Ångströという名称は、原子レベルの技術的ビジョンを象徴しています。これら2つの創造的に変形された専門用語がシリコンバレーで出会ったとき、それはまさに完璧な認知座標を構成します——情報処理のスケールの限界を示し、技術文明がマクロとミクロの両方に向かって進む壮大な旅を示しています。&lt;/p&gt;&#xA;&lt;h2 id=&#34;暗号学入門googleインフラストラクチャードメインの規則&#34;&gt;暗号学入門：Googleインフラストラクチャードメインの規則&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&#xA;&lt;/h2&gt;&lt;p&gt;さて、話をGoogleのインフラストラクチャーに戻しましょう。まず、完全な接続ドメインを見てみます：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;rr4---sn-j5o7dn7s.xn--ngstr-lra8j.com&#xA;rr1---sn-j5o76n7z.xn--ngstr-lra8j.com&#xA;rr5---sn-i3b7knzs.xn--ngstr-lra8j.com&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これらの一見ランダムな文字列は、実は簡単な暗号学的な変換を経た結果です。その核心部分を分解してみましょう。&lt;/p&gt;&#xA;&lt;h3 id=&#34;都市名の変換規則&#34;&gt;都市名の変換規則&#xA;&lt;/h3&gt;&lt;p&gt;&lt;code&gt;rr1---sn-j5o76n7z&lt;/code&gt;を例に取ると、重要な情報は&lt;code&gt;sn-&lt;/code&gt;の後の8文字：&lt;code&gt;r1---sn-[123][45][6][78]&lt;/code&gt;です。最初の3文字、この場合は&lt;code&gt;j5o&lt;/code&gt;は都市名で、その都市の主要空港のIATAコードを一定の暗号学的変換を経て得られます。&lt;/p&gt;&#xA;&lt;p&gt;まず、5 * 7の数字とアルファベットの表を作成します：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;行0: 1 0 2 3 4&#xA;行1: 5 6 7 8 9&#xA;行2: a b c d e&#xA;行3: f g h i j&#xA;行4: k l m n o&#xA;行5: p q r s t&#xA;行6: u v w x y&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;この表を反時計回りに回転させ、新しい表の左下から始めて、元の表のデータを「下から上、左から右」の順に書き写します。&lt;/p&gt;&#xA;&lt;p&gt;回転が完了すると、次の表が得られます：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;| 6 d k r y |&#xA;| --------- |&#xA;| 5 c j q x |&#xA;| 4 b i p w |&#xA;| 3 a h o v |&#xA;| 2 9 g n u |&#xA;| 0 8 f m t |&#xA;| --------- |&#xA;| 1 7 e l s |&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;表の中央に線で囲まれた5*5の部分が最終的な暗号表で、25文字あり、「左から右、上から下」の順に&lt;code&gt;a&lt;/code&gt;から&lt;code&gt;y&lt;/code&gt;までの文字を表します。例えば、上海虹橋国際空港のIATAコードは&lt;code&gt;sha&lt;/code&gt;で、この表を使って暗号化されたテキストを得ることができます：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;s&lt;/code&gt;はアルファベットの19番目の文字で、「左から右、上から下」の順に暗号表で19番目の文字を数えると、&lt;code&gt;n&lt;/code&gt;になります。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;h&lt;/code&gt;はアルファベットの8番目の文字で、暗号表で8番目の文字を数えると、&lt;code&gt;i&lt;/code&gt;になります。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;a&lt;/code&gt;はアルファベットの1番目の文字で、暗号表で1番目の文字を数えると、&lt;code&gt;5&lt;/code&gt;になります。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;暗号化されたテキストは&lt;code&gt;ni5&lt;/code&gt;です。&lt;/p&gt;&#xA;&lt;p&gt;逆に、最初の都市名&lt;code&gt;j5o&lt;/code&gt;を暗号表から逆算すると：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;j&lt;/code&gt;は「左から右、上から下」の順に3番目の文字で、&lt;code&gt;c&lt;/code&gt;になります。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;5&lt;/code&gt;は「左から右、上から下」の順に1番目の文字で、&lt;code&gt;a&lt;/code&gt;になります。&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;o&lt;/code&gt;は「左から右、上から下」の順に14番目の文字で、&lt;code&gt;n&lt;/code&gt;になります。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;翻訳された平文は&lt;code&gt;can&lt;/code&gt;で、これは広州白雲国際空港のIATAコードです。つまり、私たちが接続しているサーバーは広州にあります。&lt;/p&gt;&#xA;&lt;p&gt;もしGoogleがチューリッヒにサーバーを持っている場合、チューリッヒ空港のIATAコードは&lt;code&gt;zrh&lt;/code&gt;で、&lt;code&gt;z&lt;/code&gt;という文字がありますが、私たちの暗号表には&lt;code&gt;a&lt;/code&gt;から&lt;code&gt;y&lt;/code&gt;までの文字しかありません。心配しないでください、Googleもこの問題を考慮しています。&lt;code&gt;z&lt;/code&gt;は暗号表の&lt;code&gt;1&lt;/code&gt;に対応します。&lt;/p&gt;&#xA;&lt;p&gt;このルールをコードで表現すると次のようになります：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;table = &#34;5cjqx4bipw3ahov29gnu08fmt1&#34;&#xA;def iata2cipher(iata):&#xA;    global table&#xA;    iata = iata.upper()&#xA;    cipher = &#34;&#34;&#xA;    for element in iata:&#xA;        index = ord(element) - 65&#xA;        cipher += table[index]&#xA;    return cipher&#xA;&#xA;def cipher2iata(cipher):&#xA;    global table&#xA;    cipher = cipher.lower()&#xA;    iata = &#34;&#34;&#xA;    for element in cipher:&#xA;        index = table.find(element)&#xA;        iata += chr(65 + index)&#xA;    return iata&#xA;&#xA;# print(iata2cipher(input(&#34;IATA:&#34;)))&#xA;# print(cipher2iata(input(&#34;Cipher:&#34;)))&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;サーバーグループ番号&#34;&gt;サーバーグループ番号&#xA;&lt;/h3&gt;&lt;p&gt;[45]と[78]番目の文字、例えば&lt;code&gt;76&lt;/code&gt;と&lt;code&gt;7z&lt;/code&gt;は、サーバーグループ（アクセスポイント）番号を表し、以下の表の最初の列（すでに区切り線で区切られています）に含まれる文字で構成されます。&lt;code&gt;7elsz6dkry&lt;/code&gt;はそれぞれ&lt;code&gt;0123456789&lt;/code&gt;を表します。したがって、&lt;code&gt;76&lt;/code&gt;の平文は&lt;code&gt;05&lt;/code&gt;、&lt;code&gt;7z&lt;/code&gt;の平文は&lt;code&gt;04&lt;/code&gt;です。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;  | 1 2 3 4 5 6&#xA;7 | 8 9 a b c d&#xA;e | f g h i j k&#xA;l | m n o p q r&#xA;s | t u v w x y&#xA;z | 0 1 2 3 4 5&#xA;6 | 7 8 9 a b c&#xA;d | e f g h i j&#xA;k | l m n o p q&#xA;r | s t u v w x&#xA;y | z&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pythonで表現すると次のようになります：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;codeTable = &#34;7elsz6dkry&#34;&#xA;def cipher2code(cipher):&#xA;    global codeTable&#xA;    cipher = cipher.lower()&#xA;    codeString = &#34;&#34;&#xA;    for element in cipher:&#xA;        index = codeTable.find(element)&#xA;        codeString += chr(index + 48)&#xA;    return codeString&#xA;&#xA;# print(cipher2code(input(&#34;Cipher:&#34;)))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;同様に、数字を暗号化する方法もここでは詳しく説明しません。&lt;/p&gt;&#xA;&lt;h3 id=&#34;サポートプロトコル&#34;&gt;サポートプロトコル&#xA;&lt;/h3&gt;&lt;p&gt;[6]番目の文字はネットワークプロトコル情報を表します：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;n&lt;/code&gt;：IPv6（アドレス範囲 0x000-0x3FF）&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;u&lt;/code&gt;：IPv6（アドレス範囲 0x400-0x7FF）&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;m&lt;/code&gt;：IPv4のみサポート&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;例えば：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;a5mekn7r&lt;/code&gt;、IPv6プレフィックス：&lt;code&gt;2607:f8b0:4007:a::/64&lt;/code&gt;、IPv4プレフィックス：&lt;code&gt;74.125.103.0/24&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;a5m7zu7r&lt;/code&gt;、IPv6プレフィックス：&lt;code&gt;2607:f8b0:4007:407::/64&lt;/code&gt;、IPv4プレフィックス：&lt;code&gt;74.125.215.0/24&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;a5mekm76&lt;/code&gt;、IPv4のみサポート、プレフィックス：&lt;code&gt;208.117.242.0/24&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;適切なトラフィック分流の実装&#34;&gt;適切なトラフィック分流の実装&#xA;&lt;/h2&gt;&lt;p&gt;この解析情報を基に、より正確な Google ドメインの分流を設定できる。&#xA;現在、中国の Google CDN は主に北京（&lt;code&gt;2x3&lt;/code&gt;）、上海（&lt;code&gt;ni5&lt;/code&gt;）、広州（&lt;code&gt;j5o&lt;/code&gt;）に分布している。これに基づいて、以下の正規表現ルールを作成できる。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;rules:&#xA;  - DOMAIN-REGEX,^r+[0-9]+(---|\.)sn-(2x3|ni5|j5o)\w{5}\.xn--ngstr-lra8j\.com$,DIRECT&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;このルールにより、&lt;code&gt;rr1---sn-j5o76n7z.xn--ngstr-lra8j.com&lt;/code&gt; のような Google Play の中国 CDN ドメインを「直通（DIRECT）」で処理し、それ以外の Google サービスは従来通りプロキシ経由でアクセスする。&lt;/p&gt;&#xA;&lt;p&gt;さらに、GeoSite データベース（&lt;a class=&#34;link&#34; href=&#34;https://github.com/v2fly/domain-list-community&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;v2fly/domain-list-community&lt;/a&gt;）は、Google Play の中国 CDN に対し最適化済みのルールを提供している&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;rules:&#xA;  - GEOSITE,GOOGLE-PLAY@CN,全球直连&#xA;  - GEOSITE,GOOGLE,代理选择&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;参考: &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Anders_Jonas_%C3%85ngstr%C3%B6m&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://en.wikipedia.org/wiki/Anders_Jonas_%C3%85ngstr%C3%B6m&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;参考: &lt;a class=&#34;link&#34; href=&#34;https://github.com/lennylxx/ipv6-hosts/wiki/sn-domains&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://github.com/lennylxx/ipv6-hosts/wiki/sn-domains&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;参考コミット: &lt;a class=&#34;link&#34; href=&#34;https://github.com/v2fly/domain-list-community/pull/2436/commits/a86c1bf3d9bf577869180874d87c76ddf6282fc1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://github.com/v2fly/domain-list-community/pull/2436/commits/a86c1bf3d9bf577869180874d87c76ddf6282fc1&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
        </item><item>
            <title>最速 Substore サブスクリプション管理ガイド</title>
            <link>https://blog.l3zc.com/ja/2025/03/clash-subscription-convert/</link>
            <pubDate>Fri, 07 Mar 2025 18:54:29 +0800</pubDate>
            <guid>https://blog.l3zc.com/ja/2025/03/clash-subscription-convert/</guid>
            <description>&lt;p&gt;春節のセールで複数のVPNサービスを契約した後、各ノードを最大限に活用する方法は、簡単そうでいて意外と難しい問題です。もちろん、各VPNサービスが提供する設定ファイルをサブスクライブして、それらを切り替えることもできますが、それはあまりにも面倒です。さらに、自分で構築したノードもあります。その1つのノードのために新しい設定を作成するのは避けたいです。&lt;/p&gt;&#xA;&lt;p&gt;Sub-Storeはこの問題をうまく解決してくれます。複数のサブスクリプションからノード情報を抽出し、正規表現やJSを使って整理し、最終的にすべてのノード情報を統合したサブスクリプションを出力します。&lt;/p&gt;&#xA;&lt;p&gt;デプロイには、xreamがパッケージ化したイメージを使用できます。このイメージはフロントエンドとバックエンドを統合しています。公衆ネットワークにデプロイする場合は、バックエンドのパスを変更することを忘れないでください。そうしないと、設定ファイルが盗まれる可能性があります。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;services:&#xA;  sub-store:&#xA;    image: xream/sub-store&#xA;    container_name: substore&#xA;    restart: always&#xA;    environment:&#xA;      - SUB_STORE_CRON=55 23 * * *&#xA;      - SUB_STORE_FRONTEND_BACKEND_PATH=/super-random-path&#xA;    ports:&#xA;      - &#34;3001:3001&#34;&#xA;    volumes:&#xA;      - ./data:/opt/app/data&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3001ポートをリバースプロキシしてSubstoreのフロントエンドにアクセスできます。ここではCaddyを例にします：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-caddyfile&#34;&gt;sub-domain.example.com {&#xA;        reverse_proxy :3001&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;もちろん、初めてフロントエンドにアクセスするときは、バックエンドのアドレスを追加することを忘れないでください。この時のバックエンドアドレスは、以前のcomposeファイルの設定に依存します。この記事の例では、バックエンドアドレスは&lt;code&gt;https://sub-domain.example.com/super-random-path&lt;/code&gt;です。&lt;/p&gt;&#xA;&lt;h2 id=&#34;サブスクリプションの管理&#34;&gt;サブスクリプションの管理&#xA;&lt;/h2&gt;&lt;p&gt;すべてのVPNサービスと自建ノードを追加した後、それらを1つのサブスクリプションにまとめることができます。しかし、各VPNサービスのノード名は様々で、デフォルトでは非常に乱雑に見えます。さらに、異なるVPNサービス間でノード名が重複する可能性もあります。幸い、Sub-Storeにはスクリプトを使用してノードを一括でリネームする機能があります。ここでは&lt;a class=&#34;link&#34; href=&#34;https://github.com/Keywos/rule/blob/main/rename.js&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;このスクリプト&lt;/a&gt;をお勧めします。これを使用すると、すべてのVPNサービスのノードをリネームできます。&lt;/p&gt;&#xA;&lt;p&gt;このスクリプトを使用するには、サブスクリプションを編集する際に以下のアドレスをスクリプト操作欄に貼り付けるだけです。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;https://raw.githubusercontent.com/Keywos/rule/main/rename.js&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/03/clash-subscription-convert/image_hu_8310153db045f240.webp&#34; alt=&#34;ノード操作&#34; /&gt;&#xA; &#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/03/clash-subscription-convert/image-1_hu_333de5a5c288737.webp&#34; alt=&#34;整理されたノードリスト&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;最後に、好きなノード操作を行い、統一されたノードリストを作成できます。&lt;/p&gt;&#xA;&lt;h2 id=&#34;clash設定の生成&#34;&gt;Clash設定の生成&#xA;&lt;/h2&gt;&lt;p&gt;現在、ノードリストはありますが、生成された設定ファイルにはルールが含まれていません。自分でルールを書くか、サードパーティのルールを取得する必要があります。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/03/clash-subscription-convert/image-2_hu_755a17a55a5da685.webp&#34; alt=&#34;Mihomo設定を選択&#34; /&gt;&#xA; &#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/03/clash-subscription-convert/image-3_hu_244966c33439c095.webp&#34; alt=&#34;情報を編集&#34; /&gt;&#xA; &#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/03/clash-subscription-convert/image-4_hu_c92302b1defa984b.webp&#34; alt=&#34;共有リンクを生成&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/03/clash-subscription-convert/image-6_hu_c37bf30e1b9005a7.webp&#34; alt=&#34;スクリプト操作&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;Substoreのファイル管理に移動し、新しいMihomo設定を作成します：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;「ソース」でサブスクリプションを選択し、サブスクリプション名でサブスクリプショングループを選択します&lt;/li&gt;&#xA;&lt;li&gt;スクリプト操作に自分のオーバーライド設定を入力します&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;ここでは、私自身のオーバーライドルール &lt;a class=&#34;link&#34; href=&#34;https://github.com/powerfullz/override-rules&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;powerfullz/override-rules&lt;/a&gt;をお勧めします。これは &lt;a class=&#34;link&#34; href=&#34;https://github.com/mihomo-party-org/override-hub&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;mihomo-party-org/override-hub&lt;/a&gt;からフォークしたもので、元のリポジトリ内のACL4SSRルールに対して以下の改善を行っています：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;SukkaW/Surgeルールセットを統合し、広告ブロック、プライバシー保護、トラフィック分流の精度を最適化&lt;/li&gt;&#xA;&lt;li&gt;Truth Social、E-Hentai、TikTok、暗号通貨などの実用的な分流ルールを追加&lt;/li&gt;&#xA;&lt;li&gt;冗長なルールセットを削除&lt;/li&gt;&#xA;&lt;li&gt;DNS、Sniffer設定を内蔵&lt;/li&gt;&#xA;&lt;li&gt;Loyalsoldier/v2ray-rules-datの完全版GeoSite/GeoIPデータベースを導入&lt;/li&gt;&#xA;&lt;li&gt;IPルールに対してno-resolveパラメータを追加し、ローカルDNS解決を回避し、インターネット速度を向上させ、DNS漏洩を防ぐ&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;新しいスクリプト操作を作成し、ルールのRawリンク&lt;code&gt;https://raw.githubusercontent.com/powerfullz/override-rules/refs/heads/main/override.yaml&lt;/code&gt;を貼り付けます。&lt;/p&gt;&#xA;&lt;p&gt;保存が成功したら、共有ボタンをクリックして共有リンクを生成します。共有の有効期限を設定し、「共有を作成」をクリックします。生成されたリンクが最終的なMihomo設定ファイルです。これをサブスクリプションリンクとしてプロキシソフトウェアにサブスクライブすれば完了です。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/&#34; alt=&#34;最終的な効果&#34; /&gt;&#xA;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>大統領になるには最悪の男</title>
            <link>https://blog.l3zc.com/ja/2025/03/the-worst-guy-to-be-president/</link>
            <pubDate>Mon, 03 Mar 2025 22:44:08 +0800</pubDate>
            <guid>https://blog.l3zc.com/ja/2025/03/the-worst-guy-to-be-president/</guid>
            <description>&lt;img src=&#34;https://blog.l3zc.com/2025/03/the-worst-guy-to-be-president/cover_hu_6ad90c7eb58493bd.webp&#34; alt=&#34;Featured image of post 大統領になるには最悪の男&#34; /&gt;&lt;p&gt;最近、ホワイトハウスで起こった騒動は、皆さんもご存知でしょう。数百年にわたって安定して運営されてきた政治制度が、今やトランプ、ヴァンス、マスクという三人のならず者を迎え入れ、その道徳の腐敗、行為の卑劣さ、手段の下劣さは、アメリカ史だけでなく世界史においても前代未聞です。わずか三週間の間に、アメリカが数百年かけて築き上げてきた信頼、地位、権力は、「三人組」によってトイレに流され、世界中が本当にアメリカの笑いものを見ることになりました。&lt;/p&gt;&#xA;&lt;h2 id=&#34;トランプの正体&#34;&gt;トランプの正体&#xA;&lt;/h2&gt;&lt;p&gt;トランプは嘘、腐敗、自己中心の達人であり、有罪判決を受けた重罪犯です。彼が大統領選挙に出馬したのは、ほとんど刑務所行きを避けるためであり、今や再び大統領の座に就いても、彼の犯罪者としての本性は変わっていません——彼は国会暴力事件の犯罪者を赦免し、記者会見では嘘ばかりをつき、外交の場では他国の元首を公然と侮辱し、マスクが政府の機密データにアクセスするのを放任し、民生支出を大幅に削減し、アメリカ産業を保護するという名目で他国の商品に関税をかけ、実際には貧しい人々に増税し、富裕層に減税しています。&lt;/p&gt;&#xA;&lt;p&gt;彼はアメリカの利益を気にかけず、現存する国際秩序やアメリカの国際的な信頼と地位を犠牲にしてでも、彼のいわゆる「友人」の面子を守ろうとします。おそらくこれは独裁者同士の以心伝心、臭いもの同士が引き寄せ合うということなのでしょう。彼はファシスト独裁者として統治することを計画しており、今回はその目標を達成するのに十分な支持を得ています。彼自身がメディアの前で煙幕を張り、マスク率いるDOGEとヴァンスが議会を迂回して政府部門と最高裁判所を混乱させるのを援護しています。彼らはDEIに反対することを隠れ蓑にし、実際には体系的な抑圧メカニズムを構築しています。まず文化戦争の煙幕を張り、市民社会が反応する間もなく、公民権を弱体化させ、大統領権力を強化し、最終的にはすべての政治的敵対者を根本的に抑圧し、アメリカ国民の利益を犠牲にして、マスクのような商業寡頭や億万長者のエリート白人グループの既得権益を守ろうとしています。&lt;/p&gt;&#xA;&lt;p&gt;トランプやマスクらを代表とするMAGA運動の影響により、アメリカ社会はさらに右傾化し、影響を受ける可能性があります。この傾向は、より保守的な議題への道を開き、教育、移民、労働政策などの分野に深い影響を与えるかもしれません。同時に、この政治的雰囲気は、科学的人種主義、性差別、優生学思想が主流政治の中でより大きな空間を獲得し、アメリカの立憲民主主義の基盤を弱体化させる可能性があります。そして、「内部の敵」と見なされるグループ——「従順な白人異性愛男性」ではないすべての人々——彼らを待ち受けているのは、ナチスの強制収容所送り、国外追放、投獄、ターゲットを絞った噂や死の脅威です。&lt;/p&gt;&#xA;&lt;h2 id=&#34;時には本当に感嘆せざるを得ない&#34;&gt;時には本当に感嘆せざるを得ない&#xA;&lt;/h2&gt;&lt;p&gt;I can&amp;rsquo;t believe that the American people are dumb enough to re-elect this man into power.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>私の家庭ネットワークのドメイン名解決ソリューション</title>
            <link>https://blog.l3zc.com/ja/2025/02/what-i-have-done-on-my-dns/</link>
            <pubDate>Thu, 06 Feb 2025 17:01:51 +0800</pubDate>
            <guid>https://blog.l3zc.com/ja/2025/02/what-i-have-done-on-my-dns/</guid>
            <description>&lt;img src=&#34;https://blog.l3zc.com/2025/02/what-i-have-done-on-my-dns/cover_hu_1bda1c3daad4bc1b.webp&#34; alt=&#34;Featured image of post 私の家庭ネットワークのドメイン名解決ソリューション&#34; /&gt;&lt;p&gt;中国にいると、DNSを使う際に2つの問題に直面します。一つはDNS汚染、もう一つはDNSリークです。快適にインターネットを利用するには、まずDNSの問題を解決する必要があります。&lt;/p&gt;&#xA;&lt;h2 id=&#34;dnsリークとは何か&#34;&gt;DNSリークとは何か&#xA;&lt;/h2&gt;&lt;p&gt;もし今、代理を使ってこの記事を読んでいるなら、まず&lt;a class=&#34;link&#34; href=&#34;https://browserleaks.com/dns&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;このサイト&lt;/a&gt;を開いて、自分のDNSリクエストが国内のDNSサーバーに送信されていないか確認してください。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/02/what-i-have-done-on-my-dns/image-5_hu_76c2844c94b4a181.webp&#34; alt=&#34;典型的なDNSリーク&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;簡単に言うと、VPNなどの代理ツールを使用しているとき、自分のリクエストがVPNプロバイダー以外の第三者に見られないと思いますが、ホストのDNSリクエストがオペレーターのDNSサーバーや公共DNSサーバー（アリババ、テンセントなど）に送信されて解決され、あなたの実際のIPアドレスとリクエストしたドメイン名が記録されます。もしDNSリクエストが電報、ウィキリークスなどの敏感なサイトのドメイン名を解決すると、監視者に注意され、警告を受けたり、尋問されたりする可能性があります。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;したがって、DNSリークを防ぐために代理ツールの分流戦略を正しく設定することが非常に重要です。&lt;/p&gt;&#xA;&lt;h2 id=&#34;smartdnsの設定&#34;&gt;SmartDNSの設定&#xA;&lt;/h2&gt;&lt;h3 id=&#34;dnsリークを防ぐ&#34;&gt;DNSリークを防ぐ&#xA;&lt;/h3&gt;&lt;p&gt;DNSはインターネットの道案内役として、最も重要な要件は速さです。この要件を満たすために、家庭ネットワークのDNSサーバーとしてSmartDNSをローカルに導入するのは非常に適しています。SmartDNSの役割と設定のコツ、CDNを最適化してネットワークアクセス速度を向上させる方法については、Sukkaの「&lt;a class=&#34;link&#34; href=&#34;https://blog.skk.moe/post/i-have-my-unique-dns-setup/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;私の特別なDNS設定と使用のコツ&lt;/a&gt;」で詳しく説明されています。この記事を読む前に、まずその記事を読むことをお勧めします。ここではその内容を繰り返さず、Luciインターフェースでこれらの設定を実現する方法に焦点を当てます。&lt;/p&gt;&#xA;&lt;p&gt;もしあなたが私と同じようにOpenWRTを使用している場合、SmartDNSのLuci Appは起動するたびにパネルに保存された設定に基づいて新しい設定ファイルを自動生成します。したがって、&lt;code&gt;/etc/smartdns&lt;/code&gt;ディレクトリ内の既存の設定ファイルを直接変更せず、すべての変更はLuci App内で行うべきです。&lt;/p&gt;&#xA;&lt;p&gt;基本的に、SmartDNSの上流は多ければ多いほど良いです。多くの上流はSmartDNSの性能に影響を与えません&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;し、冗長性を高めることができます。DNSリークを防ぐために、上流を設定する際は、デフォルトグループに外国のDNS上流（もちろん、暗号化されたDNSが望ましい）を追加し、国内のサーバーを&lt;code&gt;domestic&lt;/code&gt;のような独立したグループに分類し、&lt;code&gt;-exclude-default-group&lt;/code&gt;の追加パラメータを付けてデフォルトグループから除外します。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/02/what-i-have-done-on-my-dns/image_hu_bd77370d9a6d2fcd.webp&#34; alt=&#34;国内上流のグループ設定&#34; /&gt;&#xA; &#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/02/what-i-have-done-on-my-dns/image-1_hu_1ba4737b13c17f98.webp&#34; alt=&#34;参考にできる上流&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;h3 id=&#34;国内ドメイン名解決の加速&#34;&gt;国内ドメイン名解決の加速&#xA;&lt;/h3&gt;&lt;p&gt;外国の上流を設定すると、DNSリークの問題は解決しますが、デフォルトグループから国内上流を除外したため、新しいドメインにアクセスする際に外国の上流からの結果を待つ必要があり、国内サイトのアクセス速度が遅くなり、CDNが劣化します。&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/felixonmars/dnsmasq-china-list&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;dnsmasq-china-list&lt;/a&gt;はFelix Yanのプロジェクトで、現在SmartDNS形式の設定ファイルをMakefileを通じて生成することをサポートしています。すでに誰かがGitHub Actionを使って毎日自動更新しており、直接ダウンロードするだけで利用できます。これらの設定ファイルは、国内DNS上流グループ名が&lt;code&gt;domestic&lt;/code&gt;のときにのみ有効です。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;cd /etc/smartdns&#xA;wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/accelerated-domains.china.domain.smartdns.conf&#xA;wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/apple.china.domain.smartdns.conf&#xA;wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/chinalist.domain.smartdns.conf&#xA;wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/google.china.domain.smartdns.conf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;その後、SmartDNSでこれらの設定ファイルをインポートし、「カスタム設定」欄の末尾に以下の内容を貼り付けます。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;conf-file /etc/smartdns/accelerated-domains.china.domain.smartdns.conf&#xA;conf-file /etc/smartdns/apple.china.domain.smartdns.conf&#xA;conf-file /etc/smartdns/chinalist.domain.smartdns.conf&#xA;conf-file /etc/smartdns/google.china.domain.smartdns.conf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/02/what-i-have-done-on-my-dns/image-2_hu_92b3727e74c74e1a.webp&#34; alt=&#34;設定ファイルのインポート&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;このように設定すると、国内ドメインのアクセス速度は影響を受けず、国外ドメインにアクセスする際もDNSリークの問題は発生しません。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/02/what-i-have-done-on-my-dns/image-6_hu_d5c1130c9fef193d.webp&#34; alt=&#34;代理なしでのDNSリーク防止&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;h3 id=&#34;広告ブロック&#34;&gt;広告ブロック&#xA;&lt;/h3&gt;&lt;p&gt;DNSレベルでの広告ブロックの効果は限定的で、誤ブロックを防ぐことに重点を置くべきです。悪名高い&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;「中国語圏で最も命中率の高い広告フィルタリスト」を謳うAnti ADは使用せず、他のルールを使用します。個人的に使用しているルールは&lt;a class=&#34;link&#34; href=&#34;https://github.com/217heidai/adblockfilters&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;217heidai/adblockfilters&lt;/a&gt;で、整理された統合ルールです。直接取得して使用できます。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;wget -O /etc/smartdns/adblock.conf https://gcore.jsdelivr.net/gh/217heidai/adblockfilters@main/rules/adblocksmartdns.conf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;最後に設定ファイルをインポートします：&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;conf-file /etc/smartdns/adblock.conf&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;ルールの自動更新&#34;&gt;ルールの自動更新&#xA;&lt;/h3&gt;&lt;p&gt;以下のCrontabを設定することで、毎日午前3時にすべてのルールを自動更新できます。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-crontab&#34;&gt;0 0 3 * * ?  wget -O /etc/smartdns/adblock.conf https://gcore.jsdelivr.net/gh/217heidai/adblockfilters@main/rules/adblocksmartdns.conf&#xA;0 0 3 * * ? wget -O /etc/smartdns/accelerated-domains.china.domain.smartdns.conf https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/accelerated-domains.china.domain.smartdns.conf&#xA;0 0 3 * * ? wget -O /etc/smartdns/apple.china.domain.smartdns.conf https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/apple.china.domain.smartdns.conf&#xA;0 0 3 * * ? wget -O /etc/smartdns/chinalist.domain.smartdns.conf https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/chinalist.domain.smartdns.conf&#xA;0 0 3 * * ? wget -O /etc/smartdns/google.china.domain.smartdns.conf https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/google.china.domain.smartdns.conf&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;バイパスルーターは使えますか&#34;&gt;バイパスルーターは使えますか&#xA;&lt;/h3&gt;&lt;p&gt;IPv6を使用しない限り、OpenWRTルーターをメインルーターとして使用する方が良いです。バイパスルーターとして使用する場合、特定のシステム（Windowsのことです）はバイパスルーターがブロードキャストするIPv4 DNSに従わず、オペレーターの光モデムがブロードキャストするIPv6 DNSを使用して解決しようとします。関連するレジストリキーを変更しようとしましたが、効果はありませんでした。仕方なく、オペレーターに来てもらい、光モデムをブリッジモードに変更し、OpenWRTをメインルーターとして使用しました。&lt;/p&gt;&#xA;&lt;h2 id=&#34;clashルールの上書き&#34;&gt;Clashルールの上書き&#xA;&lt;/h2&gt;&lt;p&gt;この時点でClashを起動してDNSリークテストを実行すると、おそらく中国のDNSサーバーにDNSリクエストが送信されているのが見えるでしょう。ほとんどのプロバイダーのデフォルト設定は、テンセントやアリババなどの国内大手の暗号化DNSを使用しています。オペレーターのDNSに明示的にリークして詐欺防止センターから電話がかかってくることはないにしても、気になります（強迫症が発動します）。さらに、関連する設定が全くない場合もあります。&lt;/p&gt;&#xA;&lt;p&gt;幸い、Clash Verge Revを使用している場合は、プロバイダーの設定を容易に上書きできます。ここで私の上書き設定を共有します。これを全体的な拡張設定に貼り付けるだけで、プロバイダーの設定を上書きできます。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;dns:&#xA;  enable: true&#xA;  ipv6: false&#xA;  prefer-h3: true&#xA;  use-system-hosts: true&#xA;  nameserver:&#xA;    - &#34;https://dns.cloudflare.com/dns-query&#34;&#xA;    - &#34;https://dns.sb/dns-query&#34;&#xA;    - &#34;https://dns.google/dns-query&#34;&#xA;    - &#34;https://public.dns.iij.jp/dns-query&#34;&#xA;    - &#34;https://jp.tiar.app/dns-query&#34;&#xA;    - &#34;https://jp.tiarap.org/dns-query&#34;&#xA;  nameserver-policy:&#xA;    &#34;geosite:cn&#34;:&#xA;      - system&#xA;  fallback:&#xA;    - &#34;tls://8.8.4.4&#34;&#xA;    - &#34;tls://1.1.1.1&#34;&#xA;  proxy-server-nameserver:&#xA;    - &#34;https://doh.pub/dns-query&#34;&#xA;    - &#34;https://223.5.5.5/dns-query&#34;&#xA;  direct-nameserver:&#xA;    - system&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/02/what-i-have-done-on-my-dns/image-3_hu_92a7537b0aa409b3.webp&#34; alt=&#34;全体的な拡張設定の変更方法&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;h3 id=&#34;設定の解析&#34;&gt;設定の解析&#xA;&lt;/h3&gt;&lt;p&gt;Mihomoのドキュメント&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;によれば、DNSリクエストの流れは次のようになっています。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-mermaid&#34;&gt;flowchart TD&#xA;  Start[クライアントがリクエストを開始] --&gt; rule[ルールのマッチング]&#xA;  rule --&gt;  Domain[ドメインベースのルールにマッチ]&#xA;  rule --&gt; IP[IPベースのルールにマッチ]&#xA;&#xA;  Domain --&gt; |ドメインが直結ルールにマッチ|DNS&#xA;  IP --&gt; DNS[Clash DNSでドメインを解決]&#xA;&#xA;  Domain --&gt; |ドメインが代理ルールにマッチ|Remote[代理サーバーでドメインを解決し、接続を確立]&#xA;&#xA;  Cache --&gt; |Redir-host/FakeIP-Directがヒットしない|NS[名前サーバーポリシーにマッチし、クエリ]&#xA;  Cache --&gt; |キャッシュヒット|Get&#xA;  Cache --&gt; |FakeIPがヒットしない、代理ドメイン|Remote&#xA;&#xA;  NS --&gt; |マッチ成功| Get[取得したIPでIPルールにマッチ]&#xA;  NS --&gt; |マッチしない| NF[名前サーバー/フォールバックで同時にクエリ]&#xA;&#xA;  NF --&gt; Get[取得したIP]&#xA;  Get --&gt; |DNS結果をキャッシュ|Cache[(キャッシュ)]&#xA;  Get --&gt; S[IPで直結/代理接続を確立]&#xA;&#xA;  DNS --&gt; Redir-host/FakeIP&#xA;  Redir-host/FakeIP --&gt; |DNSキャッシュをクエリ|Cache&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;nameserver-policy&lt;/code&gt;は&lt;code&gt;nameserver&lt;/code&gt;と&lt;code&gt;fallback&lt;/code&gt;よりも優先され、&lt;code&gt;geosite:cn&lt;/code&gt;にあるサイトをシステムDNSで解決するよう指定されており、以前設定したSmartDNSを使用して、ローカルネットワークレベルの応答速度と内蔵の速度測定によるCDN選択を享受できます。一方、&lt;code&gt;geosite:cn&lt;/code&gt;にないサイトは&lt;code&gt;nameserver/fallback&lt;/code&gt;で解決され、外国の暗号化された上流を使用して結果の信頼性を確保し、DNSリークを防ぎます。&lt;/p&gt;&#xA;&lt;h3 id=&#34;geoipとgeositeデータベースの置き換え&#34;&gt;geoipとgeositeデータベースの置き換え&#xA;&lt;/h3&gt;&lt;p&gt;MihomoはデフォルトでV2Ray公式のgeoipとgeositeデータベースを使用していますが、このデータベースはあまり充実しておらず、更新頻度も遅いです。そこで私は&lt;a class=&#34;link&#34; href=&#34;https://github.com/Loyalsoldier/v2ray-rules-dat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Loyalsoldier/v2ray-rules-dat&lt;/a&gt;という「強化版」データベースで元のデータベースを置き換えました。&lt;code&gt;geoip.dat&lt;/code&gt;と&lt;code&gt;geosite.dat&lt;/code&gt;をダウンロードしてカーネルディレクトリに置くだけです。当然、数行の上書き設定を追加して自動/ワンクリックで更新することもできます。&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;geodata-mode: true&#xA;geox-url:&#xA;  geoip: &#34;https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat&#34;&#xA;  geosite: &#34;https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat&#34;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;clash-meta-for-android&#34;&gt;Clash Meta For Android&#xA;&lt;/h3&gt;&lt;p&gt;スマートフォン上でのClash Meta For Android（以下Clash）については、上書き設定を行う際にスマートフォンの実際の状況をより考慮する必要があります。&lt;/p&gt;&#xA;&lt;p&gt;まず、スマートフォン上のClashの上書き設定オプションはデスクトップ版のClash Verge Revほど柔軟ではなく、多くのキーが上書きできません。また、スマートフォンはコンピューターとは異なり、ネットワーク環境を頻繁に切り替える必要があるため、システムDNSも頻繁に変わります。このような場合、ネットワーク環境を変更するたびにClashをオンオフする必要があり、&lt;code&gt;system&lt;/code&gt;が表すDNSを更新する必要があります。したがって、国内の暗号化されたDNSを国内クエリとして固定するのが最善です。&lt;/p&gt;&#xA;&lt;p&gt;Clashに入り、「設定」-&amp;gt;「上書き」以下はすべての上書き設定です：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;「DNS」-&amp;gt;「ポリシー」：強制的に有効化&lt;/li&gt;&#xA;&lt;li&gt;「DNS」-&amp;gt;「Prefer h3」：有効化済み&lt;/li&gt;&#xA;&lt;li&gt;「DNS」-&amp;gt;「Name Server」：2つの国外暗号化DNSを追加&lt;/li&gt;&#xA;&lt;li&gt;「DNS」-&amp;gt;「Name Serverポリシー」：「キー」欄に&lt;code&gt;geosite:cn&lt;/code&gt;を入力し、「値」欄に&lt;code&gt;https://doh.pub/dns-query&lt;/code&gt;を入力&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;事前にGitHubから&lt;code&gt;geoip.dat&lt;/code&gt;と&lt;code&gt;geosite.dat&lt;/code&gt;をダウンロードし、最後にClash -&amp;gt;「設定」-&amp;gt;「Meta Features」に入り、「GeoIPデータベースをインポート」と「GeoSiteデータベースをインポート」機能を使用してそれらをインポートします。&lt;/p&gt;&#xA;&lt;h2 id=&#34;完成&#34;&gt;完成&#xA;&lt;/h2&gt;&lt;p&gt;最後にもう一度&lt;a class=&#34;link&#34; href=&#34;https://browserleaks.com/dns&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;DNSリークテスト&lt;/a&gt;を実行して、すべてが正しく設定されていることを確認してください。これで、家庭ネットワークのDNS設定が最適化され、より高速で安全なインターネット体験を楽しむことができます。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;&lt;img src=&#34;https://blog.l3zc.com/2025/02/what-i-have-done-on-my-dns/image-4_hu_fb37d196f4006eaa.webp&#34; alt=&#34;DNSのリークがなくなりました&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;参考: &lt;a class=&#34;link&#34; href=&#34;https://blog.lololowe.com/posts/8f1e/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://blog.lololowe.com/posts/8f1e/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;SmartDNSは設計時に遅延問題を考慮しており、具体的なメカニズムについては「&lt;a class=&#34;link&#34; href=&#34;https://blog.skk.moe/post/i-have-my-unique-dns-setup/#%E4%B8%AD%E5%9C%BA%E4%BC%91%E6%81%AF%EF%BC%9ASmartDNS-%E6%98%AF%E5%A6%82%E4%BD%95%E9%81%BF%E5%85%8D%E5%9B%A0%E6%B5%8B%E9%80%9F%E5%AF%BC%E8%87%B4-DNS-%E8%A7%A3%E6%9E%90%E8%BF%87%E6%85%A2%E7%9A%84&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;中場休息：SmartDNSは速度測定によるDNS解決の遅延をどのように回避するか&lt;/a&gt;」。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/Mosney/anti-anti-AD&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Anti ADの光栄な事績&lt;/a&gt;をまとめた人がいます。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:4&#34;&gt;&#xA;&lt;p&gt;引用: &lt;a class=&#34;link&#34; href=&#34;https://wiki.metacubex.one/config/dns/diagram/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://wiki.metacubex.one/config/dns/diagram/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;</description>
        </item></channel>
</rss>
