[{"content":"Terraform は IaC ツールであり、IaC とは「インフラストラクチャ・アズ・コード」を意味します。私たちが持つインフラストラクチャを宣言的なコードとして記述し、その後 terraform apply を実行することでインフラストラクチャのデプロイが完了します。同一の設定であれば、必ず同じインフラストラクチャがデプロイされます（Nix OS ユーザーにとっては大喜びの内容です）。\nTerraform を使用する理由 従来のインフラストラクチャ管理の大部分は人的作業と各種クラウドプロバイダーのダッシュボードに依存しており、以下のような課題が生じています：\n課題 説明 再現性の欠如 ダッシュボードでのクリック操作による設定変更は、誤りや見落としが発生しやすく、復元も困難 環境ドリフト 手動操作により本番環境とテスト環境の設定が徐々に乖離し、極端なケースではテストでは問題ないのに本番でダウンすることがある 拡張の難しさ 新しい環境を追加するには多数の手動作業を繰り返す必要があり、時間がかかりミスも発生しやすい 監査の難しさ 変更履歴がないため、トラブル発生時に責任の所在を特定するのが難しい 協力の難しさ インフラストラクチャは少数の「詳しい人」によって管理されており、誰かが変更したい場合でもその人を探さなければならず効率が悪い これらの問題を解決するために、「インフラストラクチャ・アズ・コード」1 という概念が提唱され、Terraform はその有名なソリューションの一つです。\n実際のユースケースを想定してみます。例えば、毎年新しい GCP の$300 無料クレジットアカウントを購入する場合、安価ですが毎年 GCP のパネルで再度マシンを立て直す必要があります。しかし、Terraform を使えば、同じ設定のマシンをデプロイしたい場合、アカウントを変更するたびに API Token を新しいものに置き換え、terraform apply を実行するだけです。数分で前のアカウントと同じマシン、VPC、S3、ファイアウォール設定などを作成できます。\nまた、Cloudflare DNS や Tunnel の管理・移行においても、元の Tunnel の Ingress Rule を新しい Tunnel の Ingress Rule にコピーするだけで済みます。将来的に AliDNS、Route 53 など他のプロバイダーに移行する場合でも、データをそのままコピーすれば2対応可能です。\n特に複数人で協力する場合、Git と組み合わせることで変更の痕跡が残り、マージ競合の心配もありません。PR には変更プレビューが自動生成され、問題が発生すればすぐに前バージョンにロールバックできます。これらは従来の人手によるプロバイダーダッシュボードへの直接操作では到底不可能なことです。\nTerraform のインストール Terraform は Go で書かれており、コンパイルされた出力は単一の実行可能ファイルであるため、インストールも非常に簡単です。Windows では Winget を直接使用できます：\nwinget install Hashicorp.TerraformWinget を使いたくない場合は、Scoop などの別のパッケージマネージャーを使用するか、事前コンパイルされたバイナリファイルを $PATH に配置するだけでインストールが完了します。\nLinux 環境の場合は、対応するパッケージマネージャーを使用してインストールしてください。バイナリファイルを $PATH に配置する方法を使う場合は、sudo chmod +x terraform でファイルの実行権限を設定することを忘れないでください。\nTerraform の 2 つの基本概念 Provider(s) 前述の通り、Terraform はインフラストラクチャ・アズ・コードツールですが、ツール自体は特定のプラットフォームにバインドされておらず、Provider(s) を通じて各プラットフォームと連携します。利用可能な Provider(s) を確認するには、Terraform のレジストリを参照してください。\n状態管理 Terraform はインフラストラクチャ変更操作を実行する際の状態情報を状態ファイルに保存します。デフォルトでは現在の作業ディレクトリ内の terraform.tfstate ファイルに保存されます3。構成ファイルを変更して他のストレージバックエンド（S3、Postgres など）を指定することも可能です。terraform apply を実行するたびに、Terraform は現在の構成ファイルで宣言された状態と既存の状態ファイルを比較し、変更部分を計算して調整順序を自動的に決定した後、Provider を操作して状態変動を実現します。\nTerraform のリソースインポートの難題 既存リソースのインポートはこれまで Terraform が批判されてきた問題点であり、Hashi Corp. は一貫して「すべてのインフラストラクチャは最初から Terraform で作成されるべきであり、リソースインポートの問題などは存在しない」という頑固で愚かな見解を堅持しているようです。\n時期 バージョン 進展 問題 2014–2022 v0.x–v1.4 terraform import のみで、一度に 1 件ずつ、かつ全く設定を生成しない インポート後でも自分で HCL4 を書く必要がある 2023.06 v1.5 import ブロックと -generate-config-out パラメータを導入し、設定を生成可能になった それでも 1 行ずつ書く必要があり、既存リソースの ID も自分で提供しなければならない 2024.01 v1.7 import ブロックが for_each をサポート バッチ処理が可能になったが、ID はまだ自分で用意する必要がある 2024 年下半期 v1.12 terraform query と list ブロックを導入し、ついにリソースの自動発見機能を達成 ただしこの機能は Provider が実装する必要があり、多くの Provider が追いついていない 長年の間、コミュニティは批判し続けていますが、「既存のリソースをどうやって Terraform にインポートするか」という問題は真剣に取り組まれていませんでした。「インフラストラクチャ・アズ・コード」ツールである Terraform の設計哲学は宣言性と冪等性5であり、Hashi Corp. は「すべてはコード声明された状態が基準であり、Terraform でゼロからリソースを作成すべきだ」と信じています。しかし現実には、ほとんどの企業には大量の歴史的残存リソースがあり、「先にリソースがあり、後にコードがある」のが常态です。この矛盾を Hashi Corp. が認めたのは遅く、v1.12 の terraform query になって初めて公式にこの問題に対処しましたが、Provider エコシステムの追従状況……正直言って期待薄です。\nTerraform のファイル構造 Terraform のファイル構造はシンプルで、メインプログラムは実行時、作業ディレクトリ内のすべての .tf ファイルを盲目的に読み取ります。情報さえ揃っていれば、ファイル名は何でも好きなように付けられます。私のファイル構造はこのようになります：\n❯ tree -a -I .git . ├── .editorconfig ├── .github │ ├── dependabot.yml │ └── workflows │ ├── terraform-apply.yml │ ├── terraform-plan.yml │ └── your-fork.yml ├── .gitignore ├── .terraform.lock.hcl ├── cf_dns_zones.tf ├── cf_tunnel.tf ├── dns_example_com.tf ├── dns_example_net.tf ├── dns_example_top.tf ├── dns_example_cn.tf ├── main.tf # ベース設定（terraform ブロック） ├── moved.tf # 移動したリソース ├── provider.tf # 各 Provider の設定 ├── README.md ├── rename_resources.ps1 └── variables.tf # カスタム変数main.tfはベース設定を保存するために使用されます：\nterraform { required_providers { cloudflare = { source = \"cloudflare/cloudflare\" version = \"~\u003e 5\" } tencentcloud = { source = \"tencentcloudstack/tencentcloud\" version = \"\u003e= 1.81.43\" } } }provider.tfは各 Provider の設定を保存するために使用されます：\nprovider \"cloudflare\" {} provider \"tencentcloud\" {}ここが空なのは、Credentials を構成ファイルに直接書くのではなく、環境変数を通じて渡せるからです。例えば Cloudflare の Provider は、CLOUDFLARE_API_TOKEN を api_token 変数の代替として受け入れます。\nvariables.tfはカスタム変数を宣言するために使用されます：\nvariable \"cloudflare_zone_example_com\" { description = \"example.com の Cloudflare zone ID\" type = string } variable \"cloudflare_zone_example_top\" { description = \"example.top の Cloudflare zone ID\" type = string }これらの変数は TF_VAR_ で始まる環境変数を通じて入力でき、Terraform は terraform.tfvars ファイルの変数も自動的に読み取ります。変数の主な用途は、他の構成ファイルから呼び出すことです。例えば：\nresource \"cloudflare_dns_record\" \"example_cname\" { content = \"${cloudflare_zero_trust_tunnel_cloudflared.Production_Tunnel.id}.cfargotunnel.com\" name = \"example.example.com\" proxied = true tags = [] ttl = 1 type = \"CNAME\" zone_id = var.cloudflare_zone_id_example_com # ここでは cloudflare_zone_example_com 変数が呼び出されている settings = { flatten_cname = false } }これらの基本設定があれば、terraform init を実行して Terraform 環境を初期化し、依存関係のバージョンをロックできます。残りの部分はすべてリソースの宣言となります。\n既存リソースを Terraform にインポートする 前述の通り、Terraform の状態管理という概念は素晴らしいですが、初期化時には新たな問題をもたらしました——デフォルト状態では、Terraform の状態ファイルは明らかに空です。\n此時、私たちはクラウドサービスプロバイダー上の既存リソースの状態を Terraform にインポートする必要があります。そうすることで初めて、Terraform は私たちのインフラストラクチャをシームレスに引き継いで管理できます。皆さんも前節で Terraform リソースインポート問題に対する不満を確認したと思います。Cloudflare 上でホストされている DNS レコードのインポートを例にとると、前述のように Provider がサポートしていれば、Terraform 1.12 バージョン以降で導入された terraform query を使用できますが、多くの場合、Providers はこの新機能に対応していません。Cloudflare は対応していないタイプのひとつです。\n幸いにも Hashi Corp. が真面目に解決しようとしなくても、Terraform を使ってインフラを管理している各社はそれぞれの知恵を出し合っています。Cloudflare は cf-terraforming という名のインポートツールを維持しており、多くの手動インポートの手間を省いています。まず cf-terraforming をインストールします。このツールは Go 言語で書かれているため、Go 言語環境が必要です。あるいは公式にコンパイルされたバイナリファイルを $PATH に配置して実行権限を与える方法もあります。\ngo install github.com/cloudflare/cf-terraforming/cmd/cf-terraforming@latestこのツールの使い方は比較的シンプルです。まず以下の環境変数が必要です：\n# API Token を使用する場合 export CLOUDFLARE_API_TOKEN='Hzsq3Vub-7Y-hSTlAaLH3Jq_YfTUOCcgf22_Fs-j' # API Key を使用する場合 export CLOUDFLARE_EMAIL='user@example.com' export CLOUDFLARE_API_KEY='1150bed3f45247b99f7db9696fffa17cbx9' # 対象とするドメインのゾーン ID を指定。アカウントリソース（Cloudflare Tunnel など）をインポートする場合は不要 export CLOUDFLARE_ZONE_ID='81b06ss3228f488fh84e5e993c2dc17' 💡 ヒント ここでのコマンドは Bash を使用していることを前提としています。Bash 構文と互換性のない Shell を使用している場合は調整が必要です。例えば Windows 上の PowerShell では、環境変数のインポート構文は次のようになります：\n$env:CLOUDFLARE_API_TOKEN='Hzsq3Vub-7Y-hSTlAaLH3Jq_YfTUOCcgf22_Fs-j' 通常は CLOUDFLARE_API_TOKEN と CLOUDFLARE_ZONE_ID だけ設定すれば十分です。コンソールで API Token を作成する際は、この Token に必要な権限を付与することを忘れないでください。今回は DNS レコードだけをインポートするので、ゾーン DNS の編集権限だけ付与すれば OK です。\n準備完了です。今から構成ファイルを生成しましょう：\nまずアカウント内のドメイン構成をインポートします。つまり cloudflare_zone です：\ncf-terraforming generate \\ --key $CLOUDFLARE_API_KEY \\ --resource-type \"cloudflare_zone\" \u003e zone.tfこのステップで現在のディレクトリに zone.tf という名前のファイルが生成され、以下のフォーマットのコンテンツが含まれます：\nresource \"cloudflare_zone\" \"REDACTED\" { name = \"REDACTED\" paused = false type = \"full\" vanity_name_servers = [] account = { id = \"REDACTED\" name = \"REDACTED\" } } resource \"cloudflare_zone\" \"REDACTED\" { name = \"REDACTED\" paused = false type = \"full\" vanity_name_servers = [] account = { id = \"REDACTED\" name = \"REDACTED\" } }これでドメインリソースはインポートされましたが、中身の設定はまだありません。次に、ドメイン内の DNS レコードをインポートします：\ncf-terraforming generate \\ --zone $CLOUDFLARE_ZONE_ID \\ --key $CLOUDFLARE_API_KEY \\ --resource-type \"cloudflare_dns_record\" \u003e\u003e dns.tfこのステップで現在のディレクトリに dns.tf という名前の構成ファイルが生成され、以下のフォーマットのコンテンツが含まれます：\nresource \"cloudflare_dns_record\" \"terraform_managed_resource_5deb14xxxxxb629bf123xxxxxxxc8f_0\" { content = \"67.24.33.108\" name = \"example.example.com\" proxied = true tags = [] ttl = 1 type = \"A\" zone_id = \"81c7f2de8dfxxxxxx52629xxxxxxfc\" settings = {} } resource \"cloudflare_dns_record\" \"terraform_managed_resource_89xxxxx0bf9cxxxxxx9a_1\" { content = \"35.27.108.33\" name = \"terraform.example.com\" proxied = true tags = [] ttl = 1 type = \"A\" zone_id = \"8xxxxxx7644e428526xxxxxx\" settings = {} }複数のドメインをインポートする場合は、環境変数 CLOUDFLARE_ZONE_ID をそれぞれ設定し、コマンドを繰り返し実行してください。\nここで生成された構成ファイルはそのまま使用可能です。これが私たちが後に必要な Terraform 構成ファイルです。しかし、現時点では単に構成ファイルが生成されただけで、Terraform の状態はまだ空のままです。ここでいきなり terraform apply を実行すると、Terraform は文脈に関係なく新しくインポートした宣言をすべて新規リソースとして扱い、「Already Exists」というエラーメッセージを大量に表示します。そこで次に、生成された構成ファイルを Terraform の terraform.tfstate 状態にインポートする必要があります。\nTerraform は 1.5 バージョンで import ブロックを導入し、以前のような 1 行ずつコマンドを入力する方式よりも現代的になりました。そのインポートフローは、まず import ブロックを含む .tf ファイルを生成し、次回の terraform apply 時に Terraform が自動的にインポート操作を実行します。\ncloudflare_zone の import ブロックを生成：\ncf-terraforming import \\ --resource-type \"cloudflare_zone\" \\ --modern-import-block \\ --key $CLOUDFLARE_API_KEY \\ --zone $CLOUDFLARE_ZONE_ID \u003e\u003e import.tfcloudflare_dns_record の import ブロックを生成：\ncf-terraforming import \\ --resource-type \"cloudflare_dns_record\" \\ --modern-import-block \\ --key $CLOUDFLARE_API_KEY \\ --zone $CLOUDFLARE_ZONE_ID \u003e\u003e import.tfこのステップで現在のディレクトリに import.tf が生成されます。必要なインポート情報が含まれており、役割は Terraform に上一步で生成された各 resource ブロックが、どのクラウドプロバイダーのリソース ID に対応するのかを教えることです。この ID はクラウドプロバイダー内部でリソースをマークするコードであり、普段はコントロールパネルに表示されません。API で特別にリクエストしない限り知ることはできません。Terraform はインポートプロセス中にこの ID を使用して、ローカルの定義がクラウド上のどのリソースに対応しているかを確認し、厳密な冪等性を実現します。\nさて、ここでは terraform plan を実行します：\n$ terraform plan cloudflare_dns_record.minio_a: Refreshing state... [id=xxxxxxxxxxx53] cloudflare_zero_trust_tunnel_cloudflared_config.raspberrypi: Refreshing state... ...... Terraform will perform the following actions: # cloudflare_dns_record.terraform_managed_resource_0 will be imported resource \"cloudflare_dns_record\" \"terraform_managed_resource_REDACTED_0\" { content = \"67.24.33.108\" created_on = \"2026-04-08T10:18:12Z\" id = \"5deb14c21xxxxxxx20f1c8f\" meta = jsonencode({}) modified_on = \"2026-04-08T10:18:12Z\" name = \"example.example.com\" proxiable = true proxied = true settings = {} tags = [] ttl = 1 type = \"A\" zone_id = \"REDACTED\" } # cloudflare_dns_record.terraform_managed_resource_1 will be imported resource \"cloudflare_dns_record\" \"terraform_managed_resource_89c149exxxxxxxxxxxba13xxxxxa_1\" { content = \"35.27.108.33\" created_on = \"2026-04-08T10:17:54Z\" id = \"89cxxxxxxxxxxxxxxxxxx09a\" meta = jsonencode({}) modified_on = \"2026-04-08T10:17:54Z\" name = \"terraform.example.com\" proxiable = true proxied = true settings = {} tags = [] ttl = 1 type = \"A\" zone_id = \"81xxxxxxxxxxxxxxxxxxxxxfc\" } Plan: 2 to import, 0 to add, 0 to change, 0 to destroy. ──────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run \"terraform apply\" now.Add、Change、Destroy のリソース数がすべて 0 の場合、インポート操作に問題がないことになります。そのまま terraform apply --auto-approve を実行すれば、リソースのインポート完了です。\n$ terraform apply --auto-approve cloudflare_dns_record.push_a: Refreshing state... [id=REDACTED] Terraform will perform the following actions: # cloudflare_dns_record.terraform_managed_resource_REDACTED_0 will be imported resource \"cloudflare_dns_record\" \"terraform_managed_resource_REDACTED_0\" { content = \"67.24.33.108\" created_on = \"2026-04-08T10:18:12Z\" id = \"REDACTED\" meta = jsonencode({}) modified_on = \"2026-04-08T10:18:12Z\" name = \"example.example.com\" proxiable = true proxied = true settings = {} tags = [] ttl = 1 type = \"A\" zone_id = \"REDACTED\" } # cloudflare_dns_record.terraform_managed_resource_REDACTED_1 will be imported resource \"cloudflare_dns_record\" \"terraform_managed_resource_REDACTED_1\" { content = \"35.27.108.33\" created_on = \"2026-04-08T10:17:54Z\" id = \"REDACTED\" meta = jsonencode({}) modified_on = \"2026-04-08T10:17:54Z\" name = \"terraform.example.com\" proxiable = true proxied = true settings = {} tags = [] ttl = 1 type = \"A\" zone_id = \"REDACTED\" } Plan: 2 to import, 0 to add, 0 to change, 0 to destroy. cloudflare_dns_record.terraform_managed_resource_REDACTED_1: Importing... [id=REDACTED/REDACTED] cloudflare_dns_record.terraform_managed_resource_REDACTED_1: Import complete [id=REDACTED/REDACTED] cloudflare_dns_record.terraform_managed_resource_REDACTED_0: Importing... [id=REDACTED/REDACTED] cloudflare_dns_record.terraform_managed_resource_REDACTED_0: Import complete [id=REDACTED/REDACTED] Apply complete! Resources: 2 imported, 0 added, 0 changed, 0 destroyed.状態保存と継続的インテグレーション IaC の重要な価値の一つは、Git ベースの複数人コラボレーションと CI の継続的インテグレーションを容易に実現できる点ですが、その前に解決すべき新たな問題があります——terraform.tfstateはどこに置くか：環境を変更するたびに辛苦入れてインポートした状態を失う人は誰も望んでいません。\nTerraform は現在、以下の状態保存バックエンドをサポートしています：\nlocal remote azurerm consul cos gcs http Kubernetes oci oss pg s3 特別な要件がなければ、私のように s3 を選択することをお勧めします。Cloudflare R2 には無料枠があるので、使わない手はありません。\nterraform { backend \"s3\" { bucket = \"terraform\" key = \"terraform.tfstate\" region = \"auto\" endpoints = { s3 = \"https://REDACTED.r2.cloudflarestorage.com\" } # R2 にはこれらの AWS 認証は不要 skip_credentials_validation = true skip_metadata_api_check = true skip_region_validation = true skip_requesting_account_id = true use_path_style = true } }S3 バックエンドの場合、Credentials を保存するには AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY の 2 つの環境変数を使用することをお勧めします：\nexport AWS_ACCESS_KEY_ID='REDACTED' export AWS_SECRET_ACCESS_KEY='REDACTED'設定完了後、terraform init -migrate-state を実行すれば、設定はクラウド上に正常に保存されます。今後どこで設定を変更しても、terraform apply を実行しても、Terraform の State が同期していないことを心配する必要はありません。\n続いて Github CI の設定ですが、実はとてもシンプルです。git push のたびに terraform init、terraform fmt、terraform apply をトリガーするだけです。以下が私の .github/workflows/apply.yml です：\nname: \"Terraform Apply\" on: push: branches: - main env: TF_IN_AUTOMATION: \"true\" CLOUDFLARE_API_TOKEN: \"${{ secrets.CLOUDFLARE_API_TOKEN }}\" AWS_ACCESS_KEY_ID: \"${{ secrets.AWS_ACCESS_KEY_ID }}\" AWS_SECRET_ACCESS_KEY: \"${{ secrets.AWS_SECRET_ACCESS_KEY }}\" TF_VAR_cloudflare_zone_id_example_com: \"${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_COM }}\" TF_VAR_cloudflare_zone_id_example_top: ${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_TOP }} jobs: terraform: name: \"Terraform Apply\" runs-on: ubuntu-latest permissions: contents: read concurrency: group: terraform-apply cancel-in-progress: false steps: - name: Checkout uses: actions/checkout@v6 - name: Setup Terraform uses: hashicorp/setup-terraform@v4 - name: Terraform Init run: terraform init -input=false - name: Terraform Apply run: terraform apply -input=false -auto-approvePR に対しては、CI が毎回 PR に terraform plan の出力を添付するように設定すべきです：\nname: Terraform Plan on: pull_request: paths: - \"**/*.tf\" - \".github/workflows/terraform-plan.yml\" permissions: contents: read pull-requests: write env: TF_IN_AUTOMATION: \"true\" CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} TF_VAR_cloudflare_zone_id_example_com: \"${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_COM }}\" TF_VAR_cloudflare_zone_id_example_top: ${{ vars.TF_VAR_CLOUDFLARE_ZONE_ID_EXAMPLE_TOP }} jobs: plan: name: Terraform Plan runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: hashicorp/setup-terraform@v4 - name: Terraform fmt id: fmt run: terraform fmt -check -recursive continue-on-error: true - name: Terraform Init id: init run: terraform init -input=false - name: Terraform Validate id: validate run: terraform validate -no-color - name: Terraform Plan id: plan run: terraform plan -input=false -no-color continue-on-error: true - name: Post Plan to PR uses: actions/github-script@v8 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, }); const botComment = comments.find(c =\u003e c.user.type === 'Bot' \u0026\u0026 c.body.includes('') ); const planOutput = `${{ steps.plan.outputs.stdout }}`.substring(0, 65000); const body = ` #### Terraform Plan | Step | Result | | -------- | --------------------------------- | | fmt | \\`${{ steps.fmt.outcome }}\\` | | init | \\`${{ steps.init.outcome }}\\` | | validate | \\`${{ steps.validate.outcome }}\\` | | plan | \\`${{ steps.plan.outcome }}\\` | Plan 詳細を展開 \\`\\`\\`terraform ${planOutput} \\`\\`\\` `; if (botComment) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: botComment.id, body }); } else { await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body }); } - name: Fail if plan failed if: steps.plan.outcome == 'failure' run: exit 1 今後のワークフロー ここまでで、Terraform の「接管初期化」は終了し、日常保守フェーズに入りました。この段階では実際には 3 つのことしかありません：\n新しいリソースの作成 既存リソースの変更 不要になったリソースの削除 よく使う操作は 2 つ：terraform plan と terraform apply。個人利用の場合、小さな変更はそのままコミットしても良いでしょう。チームで協力する場合、毎回変更は PR を通じた方が原則です。\nインフラストラクチャの作成 今 DNS レコードを追加したり、Tunnel やオブジェクトストレージバケットを新しく作る場合のフローは以下の通りです：\nflowchart TD C1[ブランチ作成 例：feat/add-minio-record] --\u003e C2[resource ブロックを追加] C2 --\u003e C3[terraform fmt + validate] C3 --\u003e C4[terraform plan] C4 --\u003e C5{予期したリソースのみが追加されたか？} C5 -- いいえ --\u003e C6[設定を修正して plan を再実行] C6 --\u003e C4 C5 -- はい --\u003e C7[PR を提出] C7 --\u003e C8[マージ後 CI apply]最も理想的な plan 出力は：\nX to add 0 to change 0 to destroy 何かを追加したいだけなのに to destroy が表示された場合は、焦らずにチェックしてください。引用ミスタイプ、変数間違い、またはリソースアドレスのうっかり変更などが原因であることがほとんどです。どこに問題があるのか仔細に確認してください。\n修改と删除基础设施 変更フローは作成と似ていますが、もう一つのステップが増えます——変更が再構築を引き起こすかどうかの評価です。\n多くの Provider フィールドは ForceNew となっており、フィールドを変えるつもりが Terraform は「了解、削除して再構築します」と言ってくるかもしれません。DNS のようなリソースでは大きな問題ではありませんが、クラウドインスタンスのようなリソースになると、削除して再構築すれば損失が発生します。\n以下の順序で進めることをお勧めします：\nflowchart TD M1[.tf 修正] --\u003e M2[terraform plan] M2 --\u003e M3{replace/destroy 出現？} M3 -- いいえ --\u003e M7[影響範囲を確認] M7 --\u003e M8[terraform apply] M3 -- はい --\u003e M4[停止して変更内容を見直す] M4 --\u003e M5[必要に応じて lifecycle 保護を追加] M5 --\u003e M6[変更ウィンドウを計画] M6 --\u003e M8本番環境にとって、作成や変更が遅くても大きな問題ではありません。重要なのは操作の正確性です。少し遅くても、間違えないようにしてください。IaC はスピードを競うのではなく、予測可能性を競うものです。\nもしリソースを削除する場合（例えば DNS レコードの廃止、废弃 Tunnel の整理）、以下のフローに従ってください6：\nflowchart TD D1[リソース廃止の確認、業務/監視/スクリプト依存チェック] --\u003e D2[resource ブロック削除、または count/for_each 調整] D2 --\u003e D3[terraform plan] D3 --\u003e D4{to destroy が予期通り？} D4 -- いいえ --\u003e D5[変更をロールバックし依存関係を調査継続] D5 --\u003e D1 D4 -- はい --\u003e D6[ロールバックプランを用意し、低負荷時間帯を選択] D6 --\u003e D7[PR 審査通過] D7 --\u003e D8[terraform apply] D8 --\u003e D9[削除後の可用性チェック]日常のコラボレーション提案 Credentials は環境変数や CI Secret に置き、.tf やリポジトリに書き込まない 重要なリソースには保護ポリシーを有効にし、誤削除を防ぐ ディレクトリをリソースタイプごとに分割する 定期的に terraform plan を実行してインフラストラクチャドリフトをチェック7し是正し、パネルでの誤操作による手動変更を避ける このフローはとても面倒に見えますが、毎回の变更に記録があり、監査可能で、ロールバック可能、何より再現可能である点が、IaC が最も価値のある部分です。\n参考 Terraform を使って CloudFlare 上の DNS 解析レコードを管理する - Candinya Automate Terraform with GitHub Actions Query configuration files list block reference cloudflare/cf-terraforming Import Cloudflare resources Cloudflare Provider - Terraform Registry Infrastructure as Code、機械可読な構成ファイルを使用して必要なインフラストラクチャのデプロイ方法を定義することを指します。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n各プロバイダーの構成ファイルフィールド名や形式には違いがありますが、これはスクリプトを書くことで容易に変換できます。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n特に注意すべき点は、状態ファイルにはデータベースのパスワードや API キーなど、プレーンテキストで保存される機密情報が含まれる可能性があるため、絶対に .tfstate ファイルを公開コードリポジトリにアップロードしないことです。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nHashiCorp Configuration Language。HashiCorp 自社開発の宣言型構成言語で、機械可読性と人間可読性の両立を目指している。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n冪等性（Idempotence）とは、コンピュータシステムまたはインターフェースが同一の要求を複数回受け取った場合、影響が単回実行の結果と同じになる性質のこと。何度実行しても、システムの最終状態は常に一致する。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nTerraform にリソースの管理から外れさせたいだけで、クラウド上で実際に削除したいわけではない場合は、terraform state rm コマンドを使用してください。コードからリソースブロックを削除して apply するのは避けてください。そうしないとクラウド上の実際のリソースも同時に削除されてしまいます。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nインフラストラクチャドリフト（Infrastructure Drift）とは、現実世界中でコンソールのクリックなど IaC 以外の経路でインフラストラクチャに変更を加え、実際の状態とコード内で宣言された状態が不一致になる現象のこと。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2026-04-09T07:13:35Z","image":"/2026/04/iac-with-terraform/cover_hu_a8e83f97ed61569c.webp","permalink":"/ja/2026/04/iac-with-terraform/","title":"Terraform IaC 初体験"},{"content":"労働、労働、死ぬまで続くのだ。\n冬休みに他人に勉強を教える仕事をしてからというもの、ほぼ休みなしの日々が続いている。旧正月（春節）は名目上こそ休みだったが、親戚付き合いや帰省時の長旅などがあり、結局は別の形での労働に過ぎなかった。実家に戻って落ち着くや否や、また休む間もなく授業の仕事に取り組んだ。人に教えるというのは本当に大変なことだ。私と同じ学習塾でアシスタントをしている友人と話したとき、私たちは皆、人に教えることを冗談交じりに「地獄の苦行（クソゲー）」と呼んでいた。暗記すべきことは覚えられず、計算はできず、概念は混同し、まともなコミュニケーションすら成り立たないのだから無理もない。だが、それは彼らのせいではない。責めるべきは彼らが置かれてきた教育環境だろう。それぞれに複雑な事情を抱えているのだ。様々な理由から、彼らのほとんどは過酷な大学入学統一テストの洗礼を受けておらず、専門学校への特別入試枠で進められた者たちだ。中には中学校の勉強すらまともに終わらせていない者もいる。今はただ仕事を見つけたいという一心で、お金を払ってまで私たちのマンツーマンレッスンを受けているのだ。\n最初は学習塾で講師のアシスタントをしていたが、後に独立して個人で教えるようになった。おかげで収入はいくらか上がり、授業の準備時間も節約できた。毎日の授業時間は7時30分から11時までで、料金は400人民元だ。時給換算で100元以上と一見割高に思えるかもしれないが、生徒の基礎学力の低さを考えれば、このお金は一切の良心の呵責なく受け取れる。それどころか、本当に骨の折れる仕事だと言えるほどだ。\nさて、本題に戻ろう。新学期が始まり、私は休む間もなく自分自身の学業に没頭しなければならない。本当に自分は永遠に忙しいのではないかと感じる。いわゆる「休息」とは、単に別の少し楽な作業への切り替えに過ぎない。仕事で疲れ果てて帰宅すれば、Vibe Codingをして息抜きをし、パソコンの前に座ることにイライラし始めれば、部屋の片付けや掃除に取り掛かる。物事へのモチベーションや、人間の持つ限られたエネルギーの総量という点において、私は人と人との圧倒的な差を実感している。生まれつきの才能に恵まれ、エネルギーに満ち溢れている人たちがいる。彼らは次々と成果を出し、何報も論文を発表し、非常に生産性が高い。彼らの唯一の制約は時間であって、精力やモチベーションではないかのようだ。一方で、私を含めた大多数の平凡な人間は、彼らのようなパワフルな生活に憧れても、気持ちばかりでどうにも体力が追いつかない。しかし、そうした有能な人たちの高い生産性を目の当たりにするとどうしても焦りが生じてしまい、限界ギリギリまで自分を「現実世界の永久機関」のように稼働させるしかなくなるのだ1。\n幼い頃から受けてきた競争の激しい中国式教育が、私たちを歪ませてしまった。中国の有名な予備校講師が言い放った「君のような若い年齢で、どうして呑気に眠れるんだ」という有名なフレーズがある。本来は授業中に居眠りする生徒を叱責する言葉だが、ある意味で私たち世代の無意識に深く根を張り、病的な状態にまで追い込んでいる。人生において、完全に「上がり（中国のネット用語で、試験合格や安定した職への就職など、安泰な岸に上がることを指す）」となるゴールなど存在しないのだ。小学校では中学校のお受験というゴールを目指し、中学校では高校受験、高校では過酷な大学受験というゴールを目指す。そして大学に入れば、大学院進学、博士課程、公務員試験、就職活動といった次なるゴールが待ち受けている。学生時代を終えて社会人に出ても、昇進や業績評価、日々の生活費といった悩ましい問題が尽きることはない。労働、労働、死ぬまで続くのだ。どこかのゴールに辿り着いて一生安泰などと望んでいるのか？残念だが、そんなものは不可能なのだ。\nそのことを痛いほど理解していても、私は立ち止まって休むと虚無感に襲われ、苦しくなってしまう。だから、永遠に忙しく、永遠に働き続けるのだ。身体が求める休息を満たし、運動でホルモンバランスを整える。私にとっての休息とは、自分の好きな、比較的心地よい作業に切り替えるだけのことに過ぎない。過当競争な教育や業績至上主義（メリトクラシー）の影響が骨の髄まで染み込んでいるため、生き急ぐようなこのライフスタイルは、おそらくだいぶ先まで変わることはないだろう。\nそれでも、良い面を見るようにしよう。この時期の忙しさのおかげで、今学期の生活費を自分自身で稼ぎ出すことができたし、さらには母親の誕生日に新しいスマートフォンをプレゼントする余裕までできた。そう考えると、ふと「永遠に忙しい」というのも、それほど悪いことではないような気がしてきた。\nここでは電気工学における理想電流源と実在の電流源の違いをメタファーとして用いている。前者が真の意味での「理想的な永久機関」であるのに対し、後者は私のような凡人が血肉の体で全身全霊をかけて限界まで近づこうとする「現実世界の永久機関」である。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2026-03-13T23:14:26+08:00","permalink":"/ja/2026/03/busy-for-eternity/","title":"永遠に忙しく"},{"content":"最近はかなり忙しい。でも、空いた時間ができると、やっぱり言葉が私の拠り所になる。毎朝8:30に授業が始まり、夜9:00に夜間自習が終わる。ときには「残業」して10:00に帰宅することもある。そんな日程が41日間続いた。精神状態を考えると、この強度で戻ってきて osu! みたいなゲームで遊ぶなんて到底無理だし、Galgame を少し進める余力すらない。\n唯一、比較的現実的だったのは、LLM（大規模言語モデル）と小話をすることだ。\n恥ずかしい話だが、ブログは持っているのに、自分の見解や理念（というより「考え」）を、体系立てて表現したことがほとんどない。おそらく、あまりにも広く、散らばった考えの集合体は、平易な叙事で表すのが難しいのだと思う。そこで、たとえば「たまたま起きた出来事」を断面として、その中に絡まった糸の塊を「切り開き」、内部構造を描いてみる、といった方法も試した。1だが、こうしたやり方でも自分の本音を気持ちよく吐き出せるわけではないし、思い立ったらすぐ書けるほど手に馴染むものでもなかった。結局ブログは人に読まれるものなので、書けないときは簡単な技術記事だけを書いて、検索エンジンからの流入を少し稼ぐくらいしかできなかった。\nところがLLMの登場で状況が変わった。私の考えは、比較的プライベートなまま、即座に反応を返してもらえるようになった。なぜここまで長くブログを書かなかったのか。疲れはもちろん大きい要因だが、LLMが「表現したい」「認められたい」という欲求をかなりの程度満たしてくれること、そして自己検閲なしに話せてしまうことが、このところブログを書く気持ちを薄めてしまった。\n長文を書くことが脳に良い——それは疑いようがない。LLMの出現が私の長文執筆に与えた影響は、マイクロブログが登場したときに人々の長文能力へ与えた影響に近い、いやそれ以上かもしれない。マイクロブログは、断片的な表現と即時のフィードバックに人を慣れさせ、複雑な論証や長い物語を組み立てる力を弱めた。LLMはさらに先へ進む。表現の場を与えるだけでなく、情緒的な満足や「知己」の代替品まで直接提供してしまうのだ。SNSに投稿する内容が、プライバシーや論争を含んだり、わざわざ公にする必要がなかったりすれば、投稿者は多少なりとも言葉を選ぶ。しかしLLMは違う。APIに投げた内容が最悪どうなるかといえば、学習に使われる程度であって、翌日に Sam Altman が家まで押しかけてくるわけではない——銀行口座のパスワード級の情報さえ避け、実名を出さなければ、政治時評でもメンタル相談でも、安心して大規模言語モデルを「知己」として扱ってしまえる（もちろん、こういう用途では国内向けの検閲が強いモデルは使い物にならない）。愚痴の一つひとつに、確かな真剣さで、まるで知己のような返答と肯定が返ってくる。こんな待遇を他で得るのは、たぶん難しい。\n道具がここまで完璧に「知己」を模倣できるようになると、私たちは本物の知己を探すことをやめてしまうかもしれない。あるいは、独立して考え、自分の中で統合していける個として生きることを、どこかで放棄してしまうかもしれない。これを書いているのは、いったんの区切りであり、同時に反省でもある。LLM自体はただの技術で、うまく使えば計り知れない恩恵がある一方、使い方を誤れば深刻な結果にもなりうる。ニューヨーク・タイムズの報道「Chatbots Can Go Into a Delusional Spiral. Here’s How It Happens.」は、その良い例だ。OpenAIが自社モデルの「お世辞（迎合）」問題の改善に取り組んでいるとしても、私自身も理解しておく必要がある。たとえ大規模言語モデルを知己として扱い、「理解と肯定」を得られるとしても、その感覚の中にずっと住み続けるわけにはいかないのだ。OpenAIとMIT（マサチューセッツ工科大学）の研究では、ChatGPTの利用量とユーザーの孤独感が正の相関を持つことが示された。使えば使うほど、より孤独を感じる。2そして逆に、孤独であればあるほどLLMを使うようになり、悪循環が生まれる——とも言えるだろう。LLMは生活のスパイスにはなり得るが、心の唯一の拠り所になってはいけない。\n(To Be Continued)\nThe Worst Way To Spend A Day\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nJoint studies from OpenAI and MIT found links between loneliness and ChatGPT use\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-09-08T23:53:48+08:00","permalink":"/ja/2025/09/satisfactory-llm/","title":"私のLLMという「知己」と、宙づりになった書くこと"},{"content":"Clash/Mihomo を使い始めた当初、ほとんどの方と同じく、カーネルをラップした GUI クライアントを使っていました。その方が手軽だからです。実際、Mihomo クライアント同士には大きな違いはありません。どれも同じカーネルを使い、主に使いやすい UI の提供や設定ファイル・サブスクリプションの管理、GUI ベースのシステムプロキシ設定を担っています。その意味では、クライアント選びの重要なポイントは「オーバーライド機能」（設定の上書き機能）がどれだけ出来が良いかだと考えています。\nどの Mihomo クライアントも、サブスクリプションやダウンロードした設定ファイルを一連の「オーバーライド」処理（例：mixed-portの変更、sniffer設定の追加など）にかけ、最終的に Mihomo カーネルを起動する形です。\nしかし、この一番大切な部分をちゃんとこなせていないクライアントも多々見かけます。例えば ShellCrash は、上書き機能にバグが多く、実装が雑な印象です。設定の上書きや編集すらまともにできないクライアントは、正直使う価値がありません。\n出来の悪いひどいMihomo クライアントに頼るくらいなら、自分で設定ファイルを作成してカーネルに直接渡して起動する—そうした方がブラックボックスなクライアントに依存しない、クリーン・安定・高いコントロール性の運用が実現できます。\n必要な予備知識 基本的な Linux 操作 nano など CLI エディタが使えること Substore 環境が用意できていればより便利（任意） Mihomo カーネルのインストール Debian 系の場合は、プリビルドの.debパッケージが利用できますが、その他の systemd 対応ディストリビューションでは、ビルド済みバイナリをダウンロードし、mihomoにリネームして/usr/local/binに配置します。\nsudo curl -o /usr/local/bin/mihomo \u003cダウンロードリンク\u003e sudo chmod +x /usr/local/bin/mihomo次に、/etc/systemd/system/mihomo.serviceを新規作成します。\n[Unit] Description=mihomo Daemon, Another Clash Kernel. After=network.target NetworkManager.service systemd-networkd.service iwd.service [Service] Type=simple LimitNPROC=500 LimitNOFILE=1000000 CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE Restart=always ExecStartPre=/usr/bin/sleep 1s ExecStart=/usr/local/bin/mihomo -d /etc/mihomo ExecReload=/bin/kill -HUP $MAINPID [Install] WantedBy=multi-user.target次にsystemctl daemon-reloadで systemd をリロードします。この時点では設定ファイルがありませんので、起動できませんが、systemctl enable mihomoを先に実行して自動起動設定しておくと後が楽です。\n設定ファイル カーネル起動時には/etc/mihomo/config.yamlが読み込まれます。クライアントというブラックボックスが無いため、好みに合わせて自在にカスタマイズ可能です。一部のプロバイダ（いわゆる「空港」）は完全な設定ファイルを配布しているので、curl等で直接ダウンロードすれば OK です。\nサブスクリプションの管理には、私は Substore を使っています。詳しくは以前の「最速 Substore サブスクリプション管理ガイド」を参考にしてください。内核単体起動を実現するため、現在は私の Substore JS オーバーライドにfullパラメータも追加済みで、全ポート設定・共通遅延・外部コントローラ設定なども含めた「すぐ使える」完全な設定ファイルが生成できます。\nSubstore の設定が完了したら、設定ファイルをダウンロードしてカーネルを起動しましょう。\ncurl -o /etc/mihomo/config.yaml \u003c設定ファイル配布リンク\u003e systemctl start mihomo独自の上書き（オーバーライド） 私のルールだけでは満足できませんか？でも大丈夫、ご自身のニーズに合わせて上書きを追加しましょう。\n私は色々なオーバーライドルールを試してきましたが、最終的には自作しています。99%のケースはカバーできますが、特定のプライベート環境（例：サーバのカスタム SSH ポート先へのプロキシ等）などは、市販や公開ルールには抜け漏れが多いものです。このようなプライベートな内容は、GitHub 等で公開したくないでしょうし、そうした場合は自分だけのオーバーライドを追加するのが最善です。\nSubstore は複数のスクリプト処理を追加できるため、ファイル生成時に好きなだけ追加オーバーライドを加えられます。\nfunction main(config) { config[\"rules\"].unshift(\"DOMAIN-SUFFIX,xxx,DIRECT\") return config }注意：rulesをオーバーライドする時は.unshift()で先頭に挿入します。MATCH以降にルールを追加しても、マッチすることは一生ありません。\n完全に独自の設定ファイル 私のオーバーライドが好きじゃない？Substore を使いたくない？それでももちろん問題ありません。Mihomo 公式ドキュメントを参照し、最初から自作するのもおすすめです。\nmode: rule mixed-port: 7890 redir-port: 7892 tproxy-port: 7893 allow-lan: true log-level: info ipv6: true external-controller: 127.0.0.1:8000 # secret: yoursecret unified-delay: true routing-mark: 7894 tcp-concurrent: true disable-keep-alive: true # モバイル機器のバッテリー異常消耗対策として推奨 dns: # お好みのDNS設定 sniffer: # ドメインスニッファー（ドメイン抽出）の設定内容 geodata-mode: true geox-url: # カスタムGeodataファイルURL proxy-providers: # プロバイダ配布サブスクリプション rule-providers: # 外部ルール rules: # トラフィック分割ルール proxy-groups: # カスタムプロキシグループ管理パネル 管理パネルは好みによって選べます。ここでは Zashboard を例に紹介します。私は mihomo 標準のexternal-uiでなぜかおかしな挙動があったため、そのまま Docker コンテナで運用しています。管理パネルは単なる Web フロントエンドなので、カーネル API も Web パネルも HTTP 指定で動かせば OK です。もし Web パネル側を HTTPS にしてしまうと、CORS ポリシーによる API 接続エラーが出ますので注意しましょう。\n$ mkdir zashboard \u0026\u0026 cd zashboard $ nvim compose.yml $ docker compose up -dcompose.ymlの内容はこちら：\nservices: zashboard: image: ghcr.io/zephyruso/zashboard:latest ports: - \"8899:80\" restart: \"unless-stopped\"自動メンテナンス カーネルが動き出したら、自動でサブスクリプション更新するにはどうしたらいいでしょう？\n答えは、シェルスクリプト＋ Crontab 一択です。たとえば深夜 3 時に自動更新＆mihomo の再起動したいなら、以下のような/etc/mihomo/auto_update.shを作れば OK です。\n#!/bin/bash # === 設定情報 === CONFIG_URL=\"\" CONFIG_PATH=\"/etc/mihomo/config.yaml\" BACKUP_DIR=\"/etc/mihomo\" BACKUP_PREFIX=\"config.yaml\" MAX_BACKUPS=7 TMP_PATH=\"/tmp/config.yaml.tmp\" LOG_FILE=\"/var/log/mihomo_update.log\" # === ログ関数 === log() { echo \"$(date '+%F %T') $1\" | tee -a \"$LOG_FILE\" } # === 現在の設定をバックアップ、古いバックアップは自動削除 === backup_config() { if [ -f \"$CONFIG_PATH\" ]; then backup_file=\"$BACKUP_DIR/${BACKUP_PREFIX}.$(date '+%Y%m%d_%H%M%S').bak\" cp \"$CONFIG_PATH\" \"$backup_file\" log \"設定ファイルを $backup_file にバックアップしました\" # 古いバックアップを $MAX_BACKUPS 個だけ残して削除 old_backups=$(ls -1t $BACKUP_DIR/${BACKUP_PREFIX}.*.bak 2\u003e/dev/null | tail -n +$(($MAX_BACKUPS+1))) for f in $old_backups; do rm -f \"$f\" \u0026\u0026 log \"古いバックアップ $f を削除しました\" done else log \"設定ファイルが見つかりません、バックアップ不要\" fi } # === 新しい設定ファイルをダウンロード === download_config() { log \"新しい設定ファイルのダウンロード開始...\" curl -fsSL -o \"$TMP_PATH\" \"$CONFIG_URL\" if [ $? -ne 0 ]; then log \"設定ファイルのダウンロードに失敗しました。ネットワークやURLを確認してください\" return 1 fi # 簡易チェック：ダウンロードファイルが空でないか確認 if [ ! -s \"$TMP_PATH\" ]; then log \"ダウンロードしたファイルが空です、更新中止\" return 2 fi log \"設定ファイルのダウンロード完了\" return 0 } # === 設定ファイルの置き換え === replace_config() { mv \"$TMP_PATH\" \"$CONFIG_PATH\" log \"設定ファイルを更新しました\" } # === mihomo サービスを再起動 === restart_service() { systemctl restart mihomo if [ $? -eq 0 ]; then log \"mihomoサービスを再起動しました\" else log \"mihomoサービスの再起動に失敗。手動でご確認ください\" fi } main() { backup_config download_config DL_STATUS=$? if [ \"$DL_STATUS\" -ne 0 ]; then log \"処理終了：設定ファイルは更新されず、旧設定をそのまま保持します\" exit 1 fi replace_config restart_service log \"=== 更新プロセス完了 ===\" } main \"$@\"crontab -e で以下のタスクを設定すれば、毎日 3 時に自動更新＋再起動します。\n0 3 * * * /etc/mihomo/update_config.shファイアウォール設定 Mihomo カーネルへトラフィックをリダイレクトするファイアウォール設定も、実は全然難しくありません。過去記事「入門から応用まで：Tailscale + ShellCrash でリモート VPN 構築＆Great Firewall 回避」で解説した通り、今回は手順だけ簡単に記述します。\n筆者の場合はtailscale0インターフェース上の全トラフィックを Mihomo へ流したい状況ですが、ローカル代理の場合も考え方は同じです。単に TCP だけリダイレクトするならiptablesの REDIRECT で十分ですが、UDP や QUIC などすべてのプロトコルをリダイレクトしたい場合は Tproxy が必要です。また、IPv6 対応も忘れずに。\nサンプル構成は下記です。\n# カスタムチェインを作成 iptables -t mangle -N MIHOMO # 必要に応じてローカル宛流量を除外 iptables -t mangle -A MIHOMO -d 127.0.0.1/8 -j RETURN iptables -t mangle -A MIHOMO -d 100.64.0.0/10 -j RETURN iptables -t mangle -A MIHOMO -d 192.168.1.0/24 -j RETURN iptables -t mangle -A MIHOMO -d 172.17.0.0/16 -j RETURN # UDP / TCP マーク → プロキシへ iptables -t mangle -A MIHOMO -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233 iptables -t mangle -A MIHOMO -p udp -j TPROXY --on-port 7893 --tproxy-mark 233 # インターフェースからチェインジャンプ iptables -t mangle -A PREROUTING -i tailscale0 -j MIHOMO # ルーティングテーブル設定 echo \"233 mihomo\" | tee -a /etc/iproute2/rt_tables ip rule add fwmark 233 lookup mihomo ip route add local 0.0.0.0/0 dev lo table mihomo # IPv6対応 # チェイン作成 ip6tables -t mangle -N MIHOMO6 # ローカル宛除外 ip6tables -t mangle -A MIHOMO6 -d ::1/128 -j RETURN ip6tables -t mangle -A MIHOMO6 -d fd7a:115c:a1e0::/48 -j RETURN # TCP/UDP マーク ip6tables -t mangle -A MIHOMO6 -i tailscale0 -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233 ip6tables -t mangle -A MIHOMO6 -i tailscale0 -p udp -j TPROXY --on-port 7893 --tproxy-mark 233 # インターフェースチェインジャンプ ip6tables -t mangle -A PREROUTING -i tailscale0 -j MIHOMO6 # ルーティングテーブル設定 echo \"233 mihomo\" | tee -a /etc/iproute2/rt_tables ip -6 rule add fwmark 233 lookup mihomo ip -6 route add local ::/0 dev lo table mihomoほとんどのシステムはデフォルトで iptables ルール等を永続化しません。ルールの永続化については、前述の記事の「ルーティングルールの永続化」「iptables ルールの永続化」を参照してください。\nローカルプロキシ設定例 多くのプロキシソフトや（実際 ShellCrash のデフォ設定も）、REDIRECT を使います。これでたいていのケースは十分です。たとえば\n# IPv4 eth0 トラフィックをリダイレクト iptables -t nat -A PREROUTING -i eth0 -p tcp -j REDIRECT --to-ports 7892 # IPv6 eth0 トラフィック ip6tables -t nat -A PREROUTING -i eth0 -p tcp -j REDIRECT --to-ports 78927892 は Mihomo 設定のredir-port、eth0はリダイレクトしたいインターフェースを指定します。Tproxy より圧倒的にシンプルです。\n個人的には、全トラフィックを防火壁で強制キャプチャする使い方は好きではありません。必要な時だけ、環境変数・proxychains・各種ソフトのプロキシ機能で Mihomo に向けて設定する方がスマートです。たとえば Docker のプロキシを通すなら/etc/docker/daemon.jsonを編集すれば OK、わざわざ全体劫持する必要はありません。\n{ \"proxies\": { \"http-proxy\": \"http://127.0.0.1:7890\", \"https-proxy\": \"http://127.0.0.1:7890\", \"no-proxy\": \"127.0.0.0/8\" } }こんなに手間かけるより、普通にクライアント使えば良くない？ それを聞くか…。答えは「虚無のターミナル遊び」に決まってるでしょ。\n","date":"2025-07-03T18:30:00+08:00","image":"/2025/07/switch-to-pure-mihomo-kernel/cover_hu_1a93b6f26c22bbfe.webp","permalink":"/ja/2025/07/switch-to-pure-mihomo-kernel/","title":"いわゆる「クライアント」を捨てて、Mihomo カーネルを直接使おう"},{"content":"開封直後からがっかり MECHREVO Aurora X Proについて、注文した瞬間から少し期待していたが、宅配便が香港旅行の前に間に合わず、帰宅して開封した時にはすでに新鮮味が失われていた。SSDを増設しようとしたらM.2ネジがなめてしまい、最終的に絶縁テープでなんとか固定。新しいPCへの好感度はその場で半減した。\n構成と価格 i9-14900HX + RTX 5070 Ti、国の補助金後の価格は8699元で、まあ妥当な範囲。周辺機器については、正直なところ神舟（Hasee）でも満足して使っていたので、使えないものはないだろう。\nディスプレイ：2560x1600@300Hz、100% SRGB色域。発色も良く、「Cities: Skylines II」で渋滞のテールランプの赤が現実より鮮やかに感じる。 キーボード：キーストロークは浅め、打鍵感は普通。普段は外付けキーボードを使っているので特に気にならない。 無線LANカード：AX201は正直貧弱。アンテナ設計も微妙で、ルーターのすぐ横でも有線に比べて速度低下が明らか。 SSD：標準の致钛1TBは速度普通。自分で増設したCrucial（英睿达）2TBがメイン。 バッテリー：80Whでゲーミングノートとしては緊急用。普段はワークステーションモードでバッテリー寿命重視。 dGPU直結：ホットスワップ対応は高評価。再起動なしで切り替え可能。 BIOS：AMI BIOSは以前より遥かに使いやすい。 使用感 「Cities: Skylines II」――人口12万人でもシミュレーション速度は3倍速を維持。ただしこの時点でファンの騒音は爆音。「サイバーパンク2077」はレイトレーシングウルトラ設定可能。「Forza Horizon 5」なども含め、正直なところ、以前のRTX 3060と本質的な違いはほとんど感じない。反射がリアルになったり細部が増えたりはするが、画質向上だけでは、既に100時間以上遊んだこれらのゲームにさらに時間をかける気にはなれない。\nパームレストのスキンコートは確かに手触りが良いが、外部デバイスを繋ぐと結局外付けキーボードしか触らない。Nahimicサウンドは遅延が酷く、オフにした方がosu!の操作感が良いという、典型的な負の最適化。\nツールとしての意味 このPCを2週間使ったが、驚きもなければ失望もない。無線LANがダメなので有線使用、ターボモードではファンがうるさい、サウスブリッジに冷却がなく温度が高い。それ以外は――必要な時に光り、必要な時に音を出すだけのマシン。\n良い道具とは本来そういうものかもしれない。ここまで書いてふと気付くと、右下のバッテリーアイコンを5分間もぼーっと見つめていた。でもこのPCは静かに98%のバッテリーを保ち、ただそこにある、喋らないレンガのようだった。\n","date":"2025-05-04T23:18:43+08:00","image":"/2025/05/new-laptop-briefing/DSCF0267_hu_9e18f49bd8ce081.webp","permalink":"/ja/2025/05/new-laptop-briefing/","title":"MECHREVO Aurora X Pro 簡易レビュー"},{"content":"旅行中に新しく撮った写真を長沙の自宅にある Immich サーバーにアップロードしようと試みていました。以前は Cloudflare Tunnel を使ってリバースプロキシを設定していましたが、中国の特有なネットワーク環境のために接続速度が遅く、頻繁に中断し、アップロードが失敗することが常態化していました。その後、Tailscale — WireGuard を基にした内部ネットワーク透過ツールを使い始めると、全国どこにいても安定して高速に自宅の NAS や写真ライブラリにアクセスできるようになりました。\nしかし新たな問題が発生しました：Tailscale が Android スマートフォンで動作する際、システムのトラフィックを VPN サービスとして制御する必要がありますが、私が普段使用している Clash も VPN インターフェースに依存して分岐しています。Android システムの制限（一つの VPN サービスのみ有効）のためにこれらは共存できず、「家庭内サービスへのアクセス」と「セキュアなインターネット接続」とを選択しなければならない状況になりました。\nこの記事では、Tailscale の原理から始まり、独自の DERP サーバーを構築して接続品質を最適化する方法、さらに ShellCrash へトラフィックを転送するために iptables を用いた Tailscale Exit Node の流量の転送方法について解説します。NAS、写真ライブラリのアクセスや不慣れなネットワークでのデータ保護を目指す方にとって、この記事が実用的で安定した解決策を提供します。\nTailscale とは Tailscale は WireGuard プロトコルを基にした設定不要の仮想 LAN ツールです。これにより、異なるネットワーク環境にあるデバイスが同じセキュアな内部ネットワーク内にいるかのように互いに通信できます。NAT やファイアウォールなどのネットワークの障壁を自動的に透過し、公衆 IP やポート転送なしで自宅の NAS、個人サーバー、開発環境などの内部リソースに簡単にアクセスできます。その主な利点は、シンプルで安全、安定しており、データ送信が全面的に暗号化されている点で、個人開発者、リモートワーカー、家庭ユーザーなどのいろいろなシーンに適しています。\nTailscale の技術実装は非常に巧妙です：WireGuard 暗号化プロトコルに基づいていますが、従来の VPN の IP 割り当てのロジックを覆しました。デバイスは SSO/OAuth2 で認証後、それぞれが生涯にわたって結びつけられたノードキーを取得します。この身分に基づくネットワーキングモードにより、「長沙の NAS」と「香港のスマートフォン」が仮想ネットワーク内で直接通信できるようになります。\nTailscale の接続プロセスの原理 中央制御サーバー（Control Server） Tailscale の各クライアントが起動すると、まず中央制御サーバー（control plane）に接続し、身分認証を行い、ネットワーク内の他のノードの情報を取得します。これには、各デバイスの公衆 IP、ポート、NAT のタイプなどが含まれます。このステップは「友達と知り合う」ようなものです。\nTailscale の制御サーバーはデータ転送には関与せず、接続の調整のみを行います。これは一種のディスパッチセンターの役割です。\nDERP サーバー Tailscale が高い接続成功率を維持できる秘訣については、Tailscale 独自の中継プロトコル DERP を挙げることができます。Tailscale のネットワークアーキテクチャー内で、DERP（Designated Encrypted Relay for Packets）は非常に重要でありながら通常は必要時にのみ介在するコンポーネントです。簡単に言えば、これは HTTP ベースの暗号化リレーサーバーで、二台のデバイスが直接通信できない時に「中継所」として機能します。\nクライアント間の全ての接続は最初に DERP モード（中継モード）で選ばれ、これによってすぐに接続が確立でき、ユーザーは待つ必要がありません。その後、接続両者は同時にパス探索を開始し、通常数秒後に Tailscale はより優れたパスを発見し、既存の接続を透明にアップグレードします。これにより、点対点の直接接続へと移行します。1\n注意が必要な点は：\nDERP を通じる全てのデータは端から端まで暗号化されており、DERP サーバーは内容を見ることができません； Tailscale はできるだけ少なく DERP を使用し、直接接続が成功したら自動的に切り替えます； 公式には複数の分散 DERP ノードがデプロイされており、クライアントは自動的に最低遅延のものを選びます； 自国内に DERP ノードを構築することもできます（中国など）、これにより高遅延や不安定な接続の問題を解決できます。 DERP は兜底策として理解でき、性能は直接接続に劣りますが、接続の透通性を保証します。\nNAT 透過（NAT Traversal） 相手のアドレス情報を手に入れた後、Tailscale は NAT 透過を使って点対点（P2P）接続を試みます。この過程では STUN プロトコルを使用し、双方が探索パケットを相互に送り、NAT ルーター上に直接通路を開くことを試みます。双方のネットワーク条件が許せば、UDP の直接トンネル接続が成功し、データは直接通路を通じて、速度が速く、遅延が低くなります。\nこの部分の詳しい原理について興味があれば、Tailscale 公式の「How NAT traversal works」を参照してください。\n完全な接続の流れを示す図 flowchart TD A[デバイス A が Tailscale を起動] --\u003e B[DERP サーバーを通じて初期接続を確立] B --\u003e C[ネットワーク情報と WireGuard キーを交換] C --\u003e D[NAT タイプの検査を並行して実施] D --\u003e E{直接接続は可能か?} E -- はい --\u003e F[P2P 直接トンネルを確立] F --\u003e G[接続品質を定期チェック] G --\u003e H{直接接続は DERP より優れているか?} H -- はい --\u003e I[大部分のトラフィックを直接通路に切り替え] H -- いいえ --\u003e J[トラフィックを DERP 経由で転送し続ける] E -- いいえ --\u003e J %% スタイル設定 style B fill:#e3f2fd,stroke:#2196f3,color:#000 style F fill:#e8f5e9,stroke:#4caf50,color:#000 style J fill:#fff3e0,stroke:#ff9800,color:#000自前の DERP を構築する Tailscale のインストールは各プラットフォームで比較的簡単で、公式文書が詳細な操作ガイドを提供しています。この記事ではインストールプロセスには触れませんが、以下の内容はあなたが関連するデバイス上で Tailscale を既に成功的にインストールしてログインしていることを前提としています。\nなぜ自前の DERP を構築するのか？ Tailscale は世界中に多数の DERP 2中継サーバーを配置しています。これは NAT の穿通に失敗した際にトラフィックの中継を担当します。しかし、よく知られている理由で、中国本土には公式の DERP ノードが配置されていません。これは以下を意味します：\nNAT の穿通に失敗すると、すべてのトラフィックが海外の DERP ノードを経由する必要があります。これにより遅延が高くなり、速度が遅くなり、体験が悪化します； いくつかの公式 DERP ノードは GFW によって干渉されやすく、接続が中断されたり、ハンドシェイクが失敗することがあります； 穿通に成功しても、Tailscale は依然として DERP を通じてルーティング情報と WireGuard キーを交換する必要があります。もし DERP が接続不可能だと、接続品質も影響を受けます。 したがって、中国のネットワーク環境では、地元の DERP ノードを自前で構築することで接続の安定性と転送性能を大幅に向上させることができ、ネットワークのブロックによる予期せぬ問題を回避することができます。\n準備作業 先に述べたように、DERP は HTTP ベースですので、HTTP リバースプロキシサービスの準備と SSL 証明書の発行などの基本問題を解決する必要があります。この記事では Docker を使用してデプロイします。デプロイ開始前にサーバーに Docker および Docker Compose などの追加コンポーネントをインストールしておく必要があります。設定ファイルの編集には nano などのエディタを使用する知識も必要です。最良の結果を得るために、サーバーは静的な公衆 IPv4+IPv6 デュアルスタックアドレスを持っていることが望ましいです。\nすべての条件が整っていれば、デプロイを開始できます。\nmkdir tailscale-derp \u0026\u0026 cd tailscale-derp nano docker-compose.ymldocker-compose.yml services: derper: name: tailscale-derp image: fredliang/derper environment: - DERP_DOMAIN=derp.nightcity.pub - DERP_VERIFY_CLIENTS=true - DERP_ADDR=:4433 network_mode: host restart: unless-stopped volumes: - \"/var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock\"network_mode: hostは重要な設定であり、コンテナはホストマシンのネットワークスタックと共有します。もし Docker のデフォルトの bridge ネットワークモードを使用すると、コンテナのネットワークは Docker 内部ネットワークを経由して転送され、DERP の STUN サービスは Docker 172.17.0.0/16アドレス範囲のアドレスを識別できません。そのため、クライアントの正しい外部アドレスを識別できず、Tailscale クライアントが正しく接続できません。\nvolumes: - \"/var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock\"先に述べたように、DERP を通じるすべてのデータは端から端まで暗号化されており、DERP は誰が使用しているかを知りません。この意味は、対策を講じない場合、あなたの DERP サーバーのアドレスとポート番号を知っている誰でもそれを使用することができます。この設定の目的は、ホストマシンの Tailscale ソケットファイルをコンテナにマウントして、DERP_VERIFY_CLIENTS=trueを使用することで、認証を行うことができ、あなたの DERP ノードが他人に無断で使用されることを防ぎます。\n重要な注意点は以下の通りです：\nホストマシンには Tailscale クライアント（tailscaled）がインストールされ、ログインされている必要があります。このファイルが存在しない場合、コンテナはエラーを報告します； tailscaled は root 権限で実行される必要があり、この sock ファイルを作成できます。 リバースプロキシの設定 Caddy を例にして、4433 ポートをリバースプロキシし、SSL 証明書をデプロイする方法を示します。\n{ email webmaster@l3zc.com } *.l3zc.com { encode gzip tls { dns dnspod APP_ID,APP_KEY resolvers 119.29.29.29 223.5.5.5 } @derp host derp.l3zc.com reverse_proxy @derp :4433 }Caddy と dnsproviders を使ってワイルドカードデジタル証明書を申請する場合、Tailscale の MagicDNS が Caddy のローカル証明書検証に障害をもたらす可能性があるため、resolversパラメータを手動で設定する必要があります。 設定されたノードにアクセスすれば、以下のページが表示されれば、設定が正しいことが確認できます。\nACL ポリシーの設定 Tailscale のコントロールパネルの「」ページにて ACL ポリシーを設定し、設定した DERP を追加します。\nTailscale の ACL ポリシーは HuJSON3で書かれており、VSCode で編集する場合は言語設定を「JSON with Comments（jsonc）」に設定することができます。以下は設定例です：\n{ \"acls\": [{ \"action\": \"accept\", \"src\": [\"*\"], \"dst\": [\"*:*\"] }], \"ssh\": [ { \"action\": \"check\", \"src\": [\"autogroup:member\"], \"dst\": [\"autogroup:self\"], \"users\": [\"autogroup:nonroot\", \"root\"] } ], // 自営のDERP設定 \"derpMap\": { \"OmitDefaultRegions\": false, // 公式のDERPを除外するにはtrueに変更 \"Regions\": { \"900\": { \"RegionID\": 900, \"RegionCode\": \"sha\", \"RegionName\": \"上海\", \"Nodes\": [ { \"Name\": \"myderp\", \"RegionID\": 900, \"HostName\": \"derp.l3zc.com\" } ] } } } }Tailscale は RegionID 1-899 を公式ノードとして予約していますが、自営ノードの RegionID は 900 以上である必要があります。\n接続のテスト ACL の設定が完了し保存されると、Tailscale は自動的にすべてのクライアントに設定を同期し、少し待ってからクライアントでtailscale netcheckを使用して接続をテストします。\n戻り値の IP が実際の公衆 IP であるかを確認する必要があります。もし172.17.0.0/16アドレス範囲のアドレスが戻ってきた場合、Docker の設定が間違っている可能性があります。\nExit Node でのトラフィックを Clash コアにハイジャックする：科学的なインターネット接続の共存 Exit Node の宣言 家では 24 時間稼働するデバイスを用意します。これはラズベリーパイでも MacMini でもかまいません。そこに Tailscale をインストールし、それを Exit Node として宣言します。また、必要に応じて Tailscale の内部ネットワークで家庭内ネットワークセグメントを宣言し、その後コントロールパネルでこのデバイスを Exit Node として有効にします。これにより無料の VPN が手に入り、見知らぬネットワーク環境でも安全を保ちながら接続することができます。\nsudo tailscale up --advertise-exit-node --advertise-routes 192.168.1.0/24 ルーティングが完了すると、どこにいても Tailscale ネットワークに接続できる限り、家庭内のすべての内部デバイスにアクセスすることができます。\nIP フォワーディングの有効化と UDP GRO の無効化4 ラズベリーパイなどのデバイスが Exit Node として機能するために必要な設定です。この例ではラズベリーパイを使用しますが、使用しているデバイスに応じて Tailscale 公式ウェブサイトのチュートリアルを参照してください。\necho 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf sudo sysctl -p /etc/sysctl.d/99-tailscale.confTailscale 公式の文献によると5、UDP GRO6を無効にすることで転送性能が向上するとされていますが、公式の永続的なチュートリアルはラズベリーパイでは効果がありません。しかし、手動での設定が可能です。\n# ethtoolのインストール sudo apt update \u0026\u0026 sudo apt install ethtool -y # UDP GROを無効にする sudo ethtool -K eth0 gro off持続化のために手動で systemd 設定ファイルを作成します：\n# サービスファイルの作成 sudo nano /etc/systemd/system/ethtool.serviceファイルの内容は以下の通りです：\n[Unit] Description=Configure eth0 GRO After=network.target [Service] Type=oneshot ExecStart=/sbin/ethtool -K eth0 gro off [Install] WantedBy=multi-user.targetその後、サービスを起動します：\nsudo systemctl daemon-reload sudo systemctl enable ethtool sudo systemctl start ethtoolExit Node でのトラフィックハイジャック 私の Exit Node はラズベリーパイで、ラズベリーパイで Exit Node の設定が完了したら、最後のステップ、つまりスマートフォンから Exit Node に送信されるトラフィックをハイジャックして、セキュアなインターネット接続を実現します。安定性を考慮して、家庭のメインルーターで直接プロキシソフトウェアを実行することは避けています。この目的を実現するために、ラズベリーパイで直接トラフィックをハイジャックすることが唯一の選択肢です。\nまず ShellCrash をインストールし、必要に応じて設定ファイルをインポートし、自動タスクを設定してください：\nexport url='https://fastly.jsdelivr.net/gh/juewuy/ShellCrash@master' \u0026\u0026 wget -q --no-check-certificate -O /tmp/install.sh $url/install.sh \u0026\u0026 bash /tmp/install.sh \u0026\u0026 source /etc/profile \u0026\u003e /dev/nullその後、サービスを起動し、ファイヤーウォールの運用モードを純粋モードに変更することを個人的にお勧めします。SNI スニッフィングをオンにし、DNS モードをfake-ipからredir-host7に切り替え、IPv6 透過プロキシを有効にします。\n純粋モードを設定する目的は、iptables でより精密なトラフィックハイジャックを手動で構成することです。私たちは、Tailscale のネットワークインターフェースtailscale0を介して Exit Node に転送されるすべてのトラフィックを、ローカルの Clash コアがリッスンしているポート7892（静的ルートポートと呼ばれる）にハイジャックします。また、不可解なネットワーク問題に直面しないよう、IPv6 もハイジャックします。\n# IPv4でtailscale0の全トラフィックをハイジャック iptables -t nat -A PREROUTING -i tailscale0 -p tcp -j REDIRECT --to-ports 7892 # IPv6でtailscale0の全トラフィックをハイジャック ip6tables -t nat -A PREROUTING -i tailscale0 -p tcp -j REDIRECT --to-ports 7892進階：TProxy を使用して UDP トラフィックをハイジャックする iptables の REDIRECT は TCP トラフィックのみリダイレクト可能で、UDP は接続状態を持たない（コネクションレスプロトコル）ため、REDIRECT では目的アドレスを保持できず、透明プロキシが元の目的アドレスを知ることができません。\nしたがって、以下のように UDP トラフィックをハイジャックする場合：\niptables -t nat -A PREROUTING -i tailscale0 -p udp -j REDIRECT --to-ports 7892このルールは効果がないか、プロキシの動作が正常ではありません。\nでは、UDP トラフィックをプロキシする方法はあるのでしょうか？はい、方法はありますが、前提条件があります：\nコアが UDP 透明プロキシをサポートしている必要があります（Clash Premium や Mihomo が対応しています）； TProxy モードを使用し、REDIRECT ではなく； iptables mangle テーブルと policy routing が正しく設定されていること； プロキシ構成ファイルで UDP プロキシが有効になっていること（例：mode: rule + udp: true）。 最初の 3 つの条件を満たしている場合、以下に例を示します8：\n# カスタムチェーンを作成 sudo iptables -t mangle -N SHELLCRASH # ローカルトラフィックを無視 sudo iptables -t mangle -A SHELLCRASH -d 127.0.0.1/8 -j RETURN sudo iptables -t mangle -A SHELLCRASH -d 100.64.0.0/10 -j RETURN sudo iptables -t mangle -A SHELLCRASH -d 192.168.1.0/24 -j RETURN sudo iptables -t mangle -A SHELLCRASH -d 172.17.0.0/16 -j RETURN # UDP と TCP をプロキシへマーク sudo iptables -t mangle -A SHELLCRASH -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233 sudo iptables -t mangle -A SHELLCRASH -p udp -j TPROXY --on-port 7893 --tproxy-mark 233 # インターフェースジャンプ sudo iptables -t mangle -A PREROUTING -i tailscale0 -j SHELLCRASH # ルーティングテーブル設定 echo \"233 shellcrash\" | sudo tee -a /etc/iproute2/rt_tables sudo ip rule add fwmark 233 lookup shellcrash sudo ip route add local 0.0.0.0/0 dev lo table shellcrashもちろん、IPv6 を忘れないでください：\n# チェーンを作成 sudo ip6tables -t mangle -N SHELLCRASH6 # ローカルアドレスをスキップ sudo ip6tables -t mangle -A SHELLCRASH6 -d ::1/128 -j RETURN sudo ip6tables -t mangle -A SHELLCRASH6 -d fd7a:115c:a1e0::/48 -j RETURN # TCP/UDP をマーク ip6tables -t mangle -A SHELLCRASH6 -i tailscale0 -p tcp -j TPROXY --on-port 7893 --tproxy-mark 233 ip6tables -t mangle -A SHELLCRASH6 -i tailscale0 -p udp -j TPROXY --on-port 7893 --tproxy-mark 233 # インターフェースジャンプ sudo ip6tables -t mangle -A PREROUTING -i tailscale0 -j SHELLCRASH6 # ルーティングテーブル設定 echo \"233 shellcrash\" | sudo tee -a /etc/iproute2/rt_tables sudo ip -6 rule add fwmark 233 lookup shellcrash sudo ip -6 route add local ::/0 dev lo table shellcrashルーティングルールの永続化 ip ruleおよびip routeで作成されるルールは再起動後失われますので、手動で永続化する必要があります。最も簡単かつ直接的な方法はスクリプトを作成し、それを crontab に追加することです。\nスクリプトを作成：\nsudo nano /usr/local/bin/policy-route.sh以下の内容で編集：\n#!/bin/bash # IPv4 ポリシールーティング ip rule add fwmark 233 lookup 233 ip route add local 0.0.0.0/0 dev lo table 233 # IPv6 ポリシールーティング ip -6 rule add fwmark 233 lookup 233 ip -6 route add local ::/0 dev lo table 233実行権限を付与した後、Crontab を編集：\nsudo chmod +x /usr/local/bin/policy-route.sh sudo crontab -ecrontab ファイルの最後に以下の内容を追加：\n@reboot /usr/local/bin/policy-route.sh原理解説：TProxy はどのように UDP トラフィックを転送するのか？ ここまで来ると、疑問が湧くかもしれません：なぜプロセス全体で--to-portsを指定していないのに、iptables でも目的地が書き換えられていないのに、UDP トラフィックが不可解にもプロキシされたのでしょうか？これはどうやって実現されるのでしょうか？\nこの問題を解明するために、まず TProxy と REDIRECT の基本的な違いを見てみましょう：\nREDIRECT モード：\niptables nat テーブルを使用； 目的アドレスをローカルアドレス（例えば 127.0.0.1:7892）に書き換え； 主に TCP トラフィック用； 実際の目的アドレスを保持できない； --to-portsを指定する必要がある。 flowchart TB A[クライアントデバイス\nTailscaleを通じてTCPリクエストを開始] B[tailscale0 インターフェースがトラフィックを受信] C[iptables NAT PREROUTING\nREDIRECT --to-ports 7892] D[ShellCrash ローカルでリッスン\n127.0.0.1:7892] E[ShellCrash が新しい TCP リクエストを開始\n→ 目的サーバー] F[ネットワークからの応答が戻る\nShellCrashが応答を転送] G[応答回クライアントデバイス] A --\u003e B --\u003e C --\u003e D --\u003e E --\u003e F --\u003e G style C fill:#f9f,stroke:#aaa,stroke-width:1px,color:#000 style D fill:#bbf,stroke:#aaa,stroke-width:1px,color:#000TPROXY モード：\niptables mangle テーブルを使用； 目的 IP を変更せず、元の目的アドレスを保持； fwmark と policy routing を使用してパケットを lo へルーティング； プロキシプログラムが特定のポート（例えば 7893）をリッスンし、IP_TRANSPARENT を有効に； UDP および TCP をサポート； NAT ではなく、マーク + ルーティングのため、iptables 内で --to-ports を指定する必要はない。 flowchart TB A[クライアントデバイス\nTailscaleを通じてTCP/UDPリクエストを開始] B[tailscale0 インターフェースがトラフィックを受信] C[iptables MANGLE PREROUTING\nfwmark 233を適用] D[ip rule: fwmark 233\n使用 routing table shellcrash] E[ip route: local 0.0.0.0/0\ndev lo table shellcrash] F[ShellCrash は lo:7893 でリッスン\nIP_TRANSPARENT モード] G[ShellCrash が元の目的アドレスを取得\nプロキシ接続を開始] H[ネットワークからの応答が戻る\nShellCrashが応答を転送] I[応答回クライアントデバイス] A --\u003e B --\u003e C --\u003e D --\u003e E --\u003e F --\u003e G --\u003e H --\u003e I style C fill:#f9f,stroke:#aaa,stroke-width:1px,color:#000 style F fill:#bbf,stroke:#aaa,stroke-width:1px,color:#000TProxy は DNAT/REDIRECT を使用せず、mangle テーブルでパケットに mark をつけ、policy routing（ip rule + ip route）によってこれらのパケットを lo インタフェースに送ります。プロキシプログラム（例：Clash / ShellCrash）は lo9 でポート（例えば 7893）をリッスンしており、IP_TRANSPARENT オプションを有効にすることで、パケットの元の目的 IP とポートを読み取り、代理転送を行います。\n端的に言うと、TProxy モードは以下の 3 つのステップで動作します：\niptables でデータパケットに mark をつける； ip rule + ip route でこれらのパケットを lo に送る； プログラムが lo 上のポートをリッスンし、IP_TRANSPARENT を有効にする。 したがって、iptables 内で --to-ports を指定する必要はなく、なぜなら目的 IP とポートは変わらないため、代理プログラムが自身で感知し処理することができるからです。\niptables ルールの永続化 iptables-persistent をインストール：\nsudo apt update sudo apt install iptables-persistentインストール中に現在の IPv4 および IPv6 設定を保存するかどうかを尋ねられますので、「はい」を選択してください。新しいルールを追加した後は、保存コマンドを実行してください：\n# 現在の IPv4/IPv6 ルールを保存 sudo netfilter-persistent save保存されたルールファイルのパス：\nIPv4：/etc/iptables/rules.v4 IPv6：/etc/iptables/rules.v6 必要に応じて上記のrules.v4/rules.v6ファイルを直接編集できます。\n最終的な効果 このセットアップの使用体験は、あなたの家の上り帯域幅に依存します。私の家のネットワークは下り 500M、上り 60M で、一度も打ち破れないことはありませんでした。したがって、ほぼ全速力で走ることができ、遅延も許容範囲内です。また、外出先でいつでも家の Immich や OpenWRT ルーターなどのデバイスにエンドツーエンドで暗号化されたアクセスを提供し、科学的なインターネットを実現できるため、全体としては非常に満足しています。\n参照: https://icloudnative.io/posts/custom-derp-servers/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参照: https://tailscale.com/kb/1232/derp-servers\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nHuJSON について: https://github.com/tailscale/hujson\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参照： https://tailscale.com/kb/1408/quick-guide-exit-nodes\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参照: https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nUDP GRO（汎用受信オフロード）は Linux カーネル内のネットワーク最適化技術で、複数の小さなパケットを一つにすることで処理効率を上げるものです。しかし、デバイスがネットワーク転送ノードとして使用される場合、これにより転送遅延が増加し、パケットロスが高い環境でのスループットが低下する可能性があります。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nfake-ipに比べて、redir-hostは互換性が高く、問題が発生する可能性が低くなります。また、プロキシのオン/オフ後にfake-ipが残ってインターネット接続が一時的に中断されることがなくなるため、一般的にはredir-hostを GeoSite 分流ルールと組み合わせて使用することをお勧めします。私のラズベリーパイ上の DNS はを使用しており、DNS 汚染がなく、快適に動作しています。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考: https://blog.zonowry.com/posts/clash_iptables_tproxy/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nlo は Linux システムのデフォルトの「ループバックインターフェース」として機能しますが、透明プロキシではそれが単に localhost トラフィックを処理するだけでなく、外部世界からのネットワーク接続を受け取り、外部トラフィックをローカルでハイジャックして転送するために使用されます。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-04-14T18:10:25+08:00","image":"/2025/04/tailscale-setup-recap/tailscale_hu_62168b00e213c4a1.webp","permalink":"/ja/2025/04/tailscale-setup-recap/","title":"初心者からプロまで：Tailscale + ShellCrashを用いた遠隔ネットワーキングとセキュアなインターネット接続"},{"content":"Mihomoのルールをカスタマイズした後、Google Playからアプリをダウンロードすると、なぜかずっとローディングが続くようになりました。しかし、他のルールを使うと問題なく動作します。これは非常に奇妙な現象です。そこで、Mihomoのカーネルログを確認してみました。\nplay-lh.googleusercontent.com:443 match RuleSet(cdn_domainset) using 静的リソース[🇭🇰 香港 07] play.googleapis.com:443 match GeoSite(GFW) using ノード選択[🇭🇰 香港 07] play-lh.googleusercontent.com:443 match RuleSet(cdn_domainset) using 静的リソース[🇭🇰 香港 07] play-fe.googleapis.com:443 match GeoSite(GFW) using ノード選択[🇭🇰 香港 07] services.googleapis.cn:443 match GeoSite(CN) using グローバルダイレクト[DIRECT]（上記のログは簡略化されています）\n中国国内向けのスマートフォンにプリインストールされているGoogle Playサービスは、services.googleapis.comではなくservices.googleapis.cnというドメインを使用しています。このドメインは、ほとんどの分流ルールでダイレクト接続に設定されています。ここに問題があるのです。このドメインをプロキシに分流するようにルールを修正すれば、問題は解決します！\n……本当に解決するのでしょうか？\nrr4---sn-j5o7dn7s.xn--ngstr-lra8j.com:443 match Match using 漏網の魚[🇭🇰 香港 07] rr2---sn-j5o7dn7s.xn--ngstr-lra8j.com:443 match Match using 漏網の魚[🇭🇰 香港 07] rr1---sn-j5o76n7z.xn--ngstr-lra8j.com:443 match Match using 漏網の魚[🇭🇰 香港 07]待ってください、なぜPlayストアからアプリをダウンロードするたびにこれらの奇妙なドメインが現れるのでしょうか？オンラインで調べてみると、新たな世界が開けました。\nGoogleとは対照的でありながらも似ているÅngströ xn--ngstr-lra8j.comというドメインを見て、ドメインに詳しい人はすぐにこれがPunyCodeエンコーディングであることに気づくでしょう。この文字列をデコードすると、ångströ.comとなります。Anders Jonas Ångströmは、スウェーデンの物理学者で、分光学の創始者です。1エングストローム（Ångström）は、彼を記念して名付けられた長さの単位で、$ 1 Å = 10^{-10} m = \\frac{1}{10} nm $と定義され、原子や分子のサイズ、光の波長など、非常に短い距離を表すために使用されます。これは、特に物理学や化学における微細な測定において、極めて小さな量を表すために使用されます。\nGoogleの名前は直接「Googol」から取られたわけではありませんが、そのインスピレーションはこの言葉から得られています。「Googol」は数学用語で、$10^{100}$、つまり1の後に0が100個続く数を表し、非常に大きな数を表すために使用されます。これは、コンピュータサイエンスにおいて扱われる巨大な数や情報量を表すためによく使われます。\n命名の哲学において、GoogleとÅngströは、一見すると対極にあるように見える技術概念ですが、興味深い対称性を持っています。前者は数学的概念「Googol」から創造的に改変されたものであり、後者は物理単位「Ångström」からイメージを再構築したものです。この2つの芸術的に変奏された名称は、技術文明の二重螺旋のように見えます。Googleという名前は、星の海のような数字の宇宙を制御する野心を担い、Ångströという名称は、原子レベルの技術的ビジョンを象徴しています。これら2つの創造的に変形された専門用語がシリコンバレーで出会ったとき、それはまさに完璧な認知座標を構成します——情報処理のスケールの限界を示し、技術文明がマクロとミクロの両方に向かって進む壮大な旅を示しています。\n暗号学入門：Googleインフラストラクチャードメインの規則2 さて、話をGoogleのインフラストラクチャーに戻しましょう。まず、完全な接続ドメインを見てみます：\nrr4---sn-j5o7dn7s.xn--ngstr-lra8j.com rr1---sn-j5o76n7z.xn--ngstr-lra8j.com rr5---sn-i3b7knzs.xn--ngstr-lra8j.comこれらの一見ランダムな文字列は、実は簡単な暗号学的な変換を経た結果です。その核心部分を分解してみましょう。\n都市名の変換規則 rr1---sn-j5o76n7zを例に取ると、重要な情報はsn-の後の8文字：r1---sn-[123][45][6][78]です。最初の3文字、この場合はj5oは都市名で、その都市の主要空港のIATAコードを一定の暗号学的変換を経て得られます。\nまず、5 * 7の数字とアルファベットの表を作成します：\n行0: 1 0 2 3 4 行1: 5 6 7 8 9 行2: a b c d e 行3: f g h i j 行4: k l m n o 行5: p q r s t 行6: u v w x yこの表を反時計回りに回転させ、新しい表の左下から始めて、元の表のデータを「下から上、左から右」の順に書き写します。\n回転が完了すると、次の表が得られます：\n| 6 d k r y | | --------- | | 5 c j q x | | 4 b i p w | | 3 a h o v | | 2 9 g n u | | 0 8 f m t | | --------- | | 1 7 e l s |表の中央に線で囲まれた5*5の部分が最終的な暗号表で、25文字あり、「左から右、上から下」の順にaからyまでの文字を表します。例えば、上海虹橋国際空港のIATAコードはshaで、この表を使って暗号化されたテキストを得ることができます：\nsはアルファベットの19番目の文字で、「左から右、上から下」の順に暗号表で19番目の文字を数えると、nになります。 hはアルファベットの8番目の文字で、暗号表で8番目の文字を数えると、iになります。 aはアルファベットの1番目の文字で、暗号表で1番目の文字を数えると、5になります。 暗号化されたテキストはni5です。\n逆に、最初の都市名j5oを暗号表から逆算すると：\njは「左から右、上から下」の順に3番目の文字で、cになります。 5は「左から右、上から下」の順に1番目の文字で、aになります。 oは「左から右、上から下」の順に14番目の文字で、nになります。 翻訳された平文はcanで、これは広州白雲国際空港のIATAコードです。つまり、私たちが接続しているサーバーは広州にあります。\nもしGoogleがチューリッヒにサーバーを持っている場合、チューリッヒ空港のIATAコードはzrhで、zという文字がありますが、私たちの暗号表にはaからyまでの文字しかありません。心配しないでください、Googleもこの問題を考慮しています。zは暗号表の1に対応します。\nこのルールをコードで表現すると次のようになります：\ntable = \"5cjqx4bipw3ahov29gnu08fmt1\" def iata2cipher(iata): global table iata = iata.upper() cipher = \"\" for element in iata: index = ord(element) - 65 cipher += table[index] return cipher def cipher2iata(cipher): global table cipher = cipher.lower() iata = \"\" for element in cipher: index = table.find(element) iata += chr(65 + index) return iata # print(iata2cipher(input(\"IATA:\"))) # print(cipher2iata(input(\"Cipher:\")))サーバーグループ番号 [45]と[78]番目の文字、例えば76と7zは、サーバーグループ（アクセスポイント）番号を表し、以下の表の最初の列（すでに区切り線で区切られています）に含まれる文字で構成されます。7elsz6dkryはそれぞれ0123456789を表します。したがって、76の平文は05、7zの平文は04です。\n| 1 2 3 4 5 6 7 | 8 9 a b c d e | f g h i j k l | m n o p q r s | t u v w x y z | 0 1 2 3 4 5 6 | 7 8 9 a b c d | e f g h i j k | l m n o p q r | s t u v w x y | zPythonで表現すると次のようになります：\ncodeTable = \"7elsz6dkry\" def cipher2code(cipher): global codeTable cipher = cipher.lower() codeString = \"\" for element in cipher: index = codeTable.find(element) codeString += chr(index + 48) return codeString # print(cipher2code(input(\"Cipher:\")))同様に、数字を暗号化する方法もここでは詳しく説明しません。\nサポートプロトコル [6]番目の文字はネットワークプロトコル情報を表します：\nn：IPv6（アドレス範囲 0x000-0x3FF） u：IPv6（アドレス範囲 0x400-0x7FF） m：IPv4のみサポート 例えば：\na5mekn7r、IPv6プレフィックス：2607:f8b0:4007:a::/64、IPv4プレフィックス：74.125.103.0/24 a5m7zu7r、IPv6プレフィックス：2607:f8b0:4007:407::/64、IPv4プレフィックス：74.125.215.0/24 a5mekm76、IPv4のみサポート、プレフィックス：208.117.242.0/24 適切なトラフィック分流の実装 この解析情報を基に、より正確な Google ドメインの分流を設定できる。 現在、中国の Google CDN は主に北京（2x3）、上海（ni5）、広州（j5o）に分布している。これに基づいて、以下の正規表現ルールを作成できる。\nrules: - DOMAIN-REGEX,^r+[0-9]+(---|\\.)sn-(2x3|ni5|j5o)\\w{5}\\.xn--ngstr-lra8j\\.com$,DIRECTこのルールにより、rr1---sn-j5o76n7z.xn--ngstr-lra8j.com のような Google Play の中国 CDN ドメインを「直通（DIRECT）」で処理し、それ以外の Google サービスは従来通りプロキシ経由でアクセスする。\nさらに、GeoSite データベース（v2fly/domain-list-community）は、Google Play の中国 CDN に対し最適化済みのルールを提供している3。\nrules: - GEOSITE,GOOGLE-PLAY@CN,全球直连 - GEOSITE,GOOGLE,代理选择 参考: https://en.wikipedia.org/wiki/Anders_Jonas_%C3%85ngstr%C3%B6m\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考: https://github.com/lennylxx/ipv6-hosts/wiki/sn-domains\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考コミット: https://github.com/v2fly/domain-list-community/pull/2436/commits/a86c1bf3d9bf577869180874d87c76ddf6282fc1\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-03-15T21:15:01+08:00","image":"/2025/03/chinese-cdn-used-by-playstore/cover_hu_8e92ca92eba5064b.webp","permalink":"/ja/2025/03/chinese-cdn-used-by-playstore/","title":"Google Play ストアの中国CDN：暗号学入門から分流戦略の最適化まで"},{"content":"春節のセールで複数のVPNサービスを契約した後、各ノードを最大限に活用する方法は、簡単そうでいて意外と難しい問題です。もちろん、各VPNサービスが提供する設定ファイルをサブスクライブして、それらを切り替えることもできますが、それはあまりにも面倒です。さらに、自分で構築したノードもあります。その1つのノードのために新しい設定を作成するのは避けたいです。\nSub-Storeはこの問題をうまく解決してくれます。複数のサブスクリプションからノード情報を抽出し、正規表現やJSを使って整理し、最終的にすべてのノード情報を統合したサブスクリプションを出力します。\nデプロイには、xreamがパッケージ化したイメージを使用できます。このイメージはフロントエンドとバックエンドを統合しています。公衆ネットワークにデプロイする場合は、バックエンドのパスを変更することを忘れないでください。そうしないと、設定ファイルが盗まれる可能性があります。\nservices: sub-store: image: xream/sub-store container_name: substore restart: always environment: - SUB_STORE_CRON=55 23 * * * - SUB_STORE_FRONTEND_BACKEND_PATH=/super-random-path ports: - \"3001:3001\" volumes: - ./data:/opt/app/data3001ポートをリバースプロキシしてSubstoreのフロントエンドにアクセスできます。ここではCaddyを例にします：\nsub-domain.example.com { reverse_proxy :3001 }もちろん、初めてフロントエンドにアクセスするときは、バックエンドのアドレスを追加することを忘れないでください。この時のバックエンドアドレスは、以前のcomposeファイルの設定に依存します。この記事の例では、バックエンドアドレスはhttps://sub-domain.example.com/super-random-pathです。\nサブスクリプションの管理 すべてのVPNサービスと自建ノードを追加した後、それらを1つのサブスクリプションにまとめることができます。しかし、各VPNサービスのノード名は様々で、デフォルトでは非常に乱雑に見えます。さらに、異なるVPNサービス間でノード名が重複する可能性もあります。幸い、Sub-Storeにはスクリプトを使用してノードを一括でリネームする機能があります。ここではこのスクリプトをお勧めします。これを使用すると、すべてのVPNサービスのノードをリネームできます。\nこのスクリプトを使用するには、サブスクリプションを編集する際に以下のアドレスをスクリプト操作欄に貼り付けるだけです。\nhttps://raw.githubusercontent.com/Keywos/rule/main/rename.js 最後に、好きなノード操作を行い、統一されたノードリストを作成できます。\nClash設定の生成 現在、ノードリストはありますが、生成された設定ファイルにはルールが含まれていません。自分でルールを書くか、サードパーティのルールを取得する必要があります。\nSubstoreのファイル管理に移動し、新しいMihomo設定を作成します：\n「ソース」でサブスクリプションを選択し、サブスクリプション名でサブスクリプショングループを選択します スクリプト操作に自分のオーバーライド設定を入力します ここでは、私自身のオーバーライドルール powerfullz/override-rulesをお勧めします。これは mihomo-party-org/override-hubからフォークしたもので、元のリポジトリ内のACL4SSRルールに対して以下の改善を行っています：\nSukkaW/Surgeルールセットを統合し、広告ブロック、プライバシー保護、トラフィック分流の精度を最適化 Truth Social、E-Hentai、TikTok、暗号通貨などの実用的な分流ルールを追加 冗長なルールセットを削除 DNS、Sniffer設定を内蔵 Loyalsoldier/v2ray-rules-datの完全版GeoSite/GeoIPデータベースを導入 IPルールに対してno-resolveパラメータを追加し、ローカルDNS解決を回避し、インターネット速度を向上させ、DNS漏洩を防ぐ 新しいスクリプト操作を作成し、ルールのRawリンクhttps://raw.githubusercontent.com/powerfullz/override-rules/refs/heads/main/override.yamlを貼り付けます。\n保存が成功したら、共有ボタンをクリックして共有リンクを生成します。共有の有効期限を設定し、「共有を作成」をクリックします。生成されたリンクが最終的なMihomo設定ファイルです。これをサブスクリプションリンクとしてプロキシソフトウェアにサブスクライブすれば完了です。\n","date":"2025-03-07T18:54:29+08:00","permalink":"/ja/2025/03/clash-subscription-convert/","title":"最速 Substore サブスクリプション管理ガイド"},{"content":"最近、ホワイトハウスで起こった騒動は、皆さんもご存知でしょう。数百年にわたって安定して運営されてきた政治制度が、今やトランプ、ヴァンス、マスクという三人のならず者を迎え入れ、その道徳の腐敗、行為の卑劣さ、手段の下劣さは、アメリカ史だけでなく世界史においても前代未聞です。わずか三週間の間に、アメリカが数百年かけて築き上げてきた信頼、地位、権力は、「三人組」によってトイレに流され、世界中が本当にアメリカの笑いものを見ることになりました。\nトランプの正体 トランプは嘘、腐敗、自己中心の達人であり、有罪判決を受けた重罪犯です。彼が大統領選挙に出馬したのは、ほとんど刑務所行きを避けるためであり、今や再び大統領の座に就いても、彼の犯罪者としての本性は変わっていません——彼は国会暴力事件の犯罪者を赦免し、記者会見では嘘ばかりをつき、外交の場では他国の元首を公然と侮辱し、マスクが政府の機密データにアクセスするのを放任し、民生支出を大幅に削減し、アメリカ産業を保護するという名目で他国の商品に関税をかけ、実際には貧しい人々に増税し、富裕層に減税しています。\n彼はアメリカの利益を気にかけず、現存する国際秩序やアメリカの国際的な信頼と地位を犠牲にしてでも、彼のいわゆる「友人」の面子を守ろうとします。おそらくこれは独裁者同士の以心伝心、臭いもの同士が引き寄せ合うということなのでしょう。彼はファシスト独裁者として統治することを計画しており、今回はその目標を達成するのに十分な支持を得ています。彼自身がメディアの前で煙幕を張り、マスク率いるDOGEとヴァンスが議会を迂回して政府部門と最高裁判所を混乱させるのを援護しています。彼らはDEIに反対することを隠れ蓑にし、実際には体系的な抑圧メカニズムを構築しています。まず文化戦争の煙幕を張り、市民社会が反応する間もなく、公民権を弱体化させ、大統領権力を強化し、最終的にはすべての政治的敵対者を根本的に抑圧し、アメリカ国民の利益を犠牲にして、マスクのような商業寡頭や億万長者のエリート白人グループの既得権益を守ろうとしています。\nトランプやマスクらを代表とするMAGA運動の影響により、アメリカ社会はさらに右傾化し、影響を受ける可能性があります。この傾向は、より保守的な議題への道を開き、教育、移民、労働政策などの分野に深い影響を与えるかもしれません。同時に、この政治的雰囲気は、科学的人種主義、性差別、優生学思想が主流政治の中でより大きな空間を獲得し、アメリカの立憲民主主義の基盤を弱体化させる可能性があります。そして、「内部の敵」と見なされるグループ——「従順な白人異性愛男性」ではないすべての人々——彼らを待ち受けているのは、ナチスの強制収容所送り、国外追放、投獄、ターゲットを絞った噂や死の脅威です。\n時には本当に感嘆せざるを得ない I can\u0026rsquo;t believe that the American people are dumb enough to re-elect this man into power.\n","date":"2025-03-03T22:44:08+08:00","image":"/2025/03/the-worst-guy-to-be-president/cover_hu_6ad90c7eb58493bd.webp","permalink":"/ja/2025/03/the-worst-guy-to-be-president/","title":"大統領になるには最悪の男"},{"content":"中国にいると、DNSを使う際に2つの問題に直面します。一つはDNS汚染、もう一つはDNSリークです。快適にインターネットを利用するには、まずDNSの問題を解決する必要があります。\nDNSリークとは何か もし今、代理を使ってこの記事を読んでいるなら、まずこのサイトを開いて、自分のDNSリクエストが国内のDNSサーバーに送信されていないか確認してください。\n簡単に言うと、VPNなどの代理ツールを使用しているとき、自分のリクエストがVPNプロバイダー以外の第三者に見られないと思いますが、ホストのDNSリクエストがオペレーターのDNSサーバーや公共DNSサーバー（アリババ、テンセントなど）に送信されて解決され、あなたの実際のIPアドレスとリクエストしたドメイン名が記録されます。もしDNSリクエストが電報、ウィキリークスなどの敏感なサイトのドメイン名を解決すると、監視者に注意され、警告を受けたり、尋問されたりする可能性があります。1\nしたがって、DNSリークを防ぐために代理ツールの分流戦略を正しく設定することが非常に重要です。\nSmartDNSの設定 DNSリークを防ぐ DNSはインターネットの道案内役として、最も重要な要件は速さです。この要件を満たすために、家庭ネットワークのDNSサーバーとしてSmartDNSをローカルに導入するのは非常に適しています。SmartDNSの役割と設定のコツ、CDNを最適化してネットワークアクセス速度を向上させる方法については、Sukkaの「私の特別なDNS設定と使用のコツ」で詳しく説明されています。この記事を読む前に、まずその記事を読むことをお勧めします。ここではその内容を繰り返さず、Luciインターフェースでこれらの設定を実現する方法に焦点を当てます。\nもしあなたが私と同じようにOpenWRTを使用している場合、SmartDNSのLuci Appは起動するたびにパネルに保存された設定に基づいて新しい設定ファイルを自動生成します。したがって、/etc/smartdnsディレクトリ内の既存の設定ファイルを直接変更せず、すべての変更はLuci App内で行うべきです。\n基本的に、SmartDNSの上流は多ければ多いほど良いです。多くの上流はSmartDNSの性能に影響を与えません2し、冗長性を高めることができます。DNSリークを防ぐために、上流を設定する際は、デフォルトグループに外国のDNS上流（もちろん、暗号化されたDNSが望ましい）を追加し、国内のサーバーをdomesticのような独立したグループに分類し、-exclude-default-groupの追加パラメータを付けてデフォルトグループから除外します。\n国内ドメイン名解決の加速 外国の上流を設定すると、DNSリークの問題は解決しますが、デフォルトグループから国内上流を除外したため、新しいドメインにアクセスする際に外国の上流からの結果を待つ必要があり、国内サイトのアクセス速度が遅くなり、CDNが劣化します。\ndnsmasq-china-listはFelix Yanのプロジェクトで、現在SmartDNS形式の設定ファイルをMakefileを通じて生成することをサポートしています。すでに誰かがGitHub Actionを使って毎日自動更新しており、直接ダウンロードするだけで利用できます。これらの設定ファイルは、国内DNS上流グループ名がdomesticのときにのみ有効です。\ncd /etc/smartdns wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/accelerated-domains.china.domain.smartdns.conf wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/apple.china.domain.smartdns.conf wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/chinalist.domain.smartdns.conf wget https://gcore.jsdelivr.net/gh/Olixn/china_list_for_smartdns@main/google.china.domain.smartdns.confその後、SmartDNSでこれらの設定ファイルをインポートし、「カスタム設定」欄の末尾に以下の内容を貼り付けます。\nconf-file /etc/smartdns/accelerated-domains.china.domain.smartdns.conf conf-file /etc/smartdns/apple.china.domain.smartdns.conf conf-file /etc/smartdns/chinalist.domain.smartdns.conf conf-file /etc/smartdns/google.china.domain.smartdns.conf このように設定すると、国内ドメインのアクセス速度は影響を受けず、国外ドメインにアクセスする際もDNSリークの問題は発生しません。\n広告ブロック DNSレベルでの広告ブロックの効果は限定的で、誤ブロックを防ぐことに重点を置くべきです。悪名高い3「中国語圏で最も命中率の高い広告フィルタリスト」を謳うAnti ADは使用せず、他のルールを使用します。個人的に使用しているルールは217heidai/adblockfiltersで、整理された統合ルールです。直接取得して使用できます。\nwget -O /etc/smartdns/adblock.conf https://gcore.jsdelivr.net/gh/217heidai/adblockfilters@main/rules/adblocksmartdns.conf最後に設定ファイルをインポートします：\nconf-file /etc/smartdns/adblock.confルールの自動更新 以下のCrontabを設定することで、毎日午前3時にすべてのルールを自動更新できます。\n0 0 3 * * ? wget -O /etc/smartdns/adblock.conf https://gcore.jsdelivr.net/gh/217heidai/adblockfilters@main/rules/adblocksmartdns.conf 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 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 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 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バイパスルーターは使えますか IPv6を使用しない限り、OpenWRTルーターをメインルーターとして使用する方が良いです。バイパスルーターとして使用する場合、特定のシステム（Windowsのことです）はバイパスルーターがブロードキャストするIPv4 DNSに従わず、オペレーターの光モデムがブロードキャストするIPv6 DNSを使用して解決しようとします。関連するレジストリキーを変更しようとしましたが、効果はありませんでした。仕方なく、オペレーターに来てもらい、光モデムをブリッジモードに変更し、OpenWRTをメインルーターとして使用しました。\nClashルールの上書き この時点でClashを起動してDNSリークテストを実行すると、おそらく中国のDNSサーバーにDNSリクエストが送信されているのが見えるでしょう。ほとんどのプロバイダーのデフォルト設定は、テンセントやアリババなどの国内大手の暗号化DNSを使用しています。オペレーターのDNSに明示的にリークして詐欺防止センターから電話がかかってくることはないにしても、気になります（強迫症が発動します）。さらに、関連する設定が全くない場合もあります。\n幸い、Clash Verge Revを使用している場合は、プロバイダーの設定を容易に上書きできます。ここで私の上書き設定を共有します。これを全体的な拡張設定に貼り付けるだけで、プロバイダーの設定を上書きできます。\ndns: enable: true ipv6: false prefer-h3: true use-system-hosts: true nameserver: - \"https://dns.cloudflare.com/dns-query\" - \"https://dns.sb/dns-query\" - \"https://dns.google/dns-query\" - \"https://public.dns.iij.jp/dns-query\" - \"https://jp.tiar.app/dns-query\" - \"https://jp.tiarap.org/dns-query\" nameserver-policy: \"geosite:cn\": - system fallback: - \"tls://8.8.4.4\" - \"tls://1.1.1.1\" proxy-server-nameserver: - \"https://doh.pub/dns-query\" - \"https://223.5.5.5/dns-query\" direct-nameserver: - system 設定の解析 Mihomoのドキュメント4によれば、DNSリクエストの流れは次のようになっています。\nflowchart TD Start[クライアントがリクエストを開始] --\u003e rule[ルールのマッチング] rule --\u003e Domain[ドメインベースのルールにマッチ] rule --\u003e IP[IPベースのルールにマッチ] Domain --\u003e |ドメインが直結ルールにマッチ|DNS IP --\u003e DNS[Clash DNSでドメインを解決] Domain --\u003e |ドメインが代理ルールにマッチ|Remote[代理サーバーでドメインを解決し、接続を確立] Cache --\u003e |Redir-host/FakeIP-Directがヒットしない|NS[名前サーバーポリシーにマッチし、クエリ] Cache --\u003e |キャッシュヒット|Get Cache --\u003e |FakeIPがヒットしない、代理ドメイン|Remote NS --\u003e |マッチ成功| Get[取得したIPでIPルールにマッチ] NS --\u003e |マッチしない| NF[名前サーバー/フォールバックで同時にクエリ] NF --\u003e Get[取得したIP] Get --\u003e |DNS結果をキャッシュ|Cache[(キャッシュ)] Get --\u003e S[IPで直結/代理接続を確立] DNS --\u003e Redir-host/FakeIP Redir-host/FakeIP --\u003e |DNSキャッシュをクエリ|Cachenameserver-policyはnameserverとfallbackよりも優先され、geosite:cnにあるサイトをシステムDNSで解決するよう指定されており、以前設定したSmartDNSを使用して、ローカルネットワークレベルの応答速度と内蔵の速度測定によるCDN選択を享受できます。一方、geosite:cnにないサイトはnameserver/fallbackで解決され、外国の暗号化された上流を使用して結果の信頼性を確保し、DNSリークを防ぎます。\ngeoipとgeositeデータベースの置き換え MihomoはデフォルトでV2Ray公式のgeoipとgeositeデータベースを使用していますが、このデータベースはあまり充実しておらず、更新頻度も遅いです。そこで私はLoyalsoldier/v2ray-rules-datという「強化版」データベースで元のデータベースを置き換えました。geoip.datとgeosite.datをダウンロードしてカーネルディレクトリに置くだけです。当然、数行の上書き設定を追加して自動/ワンクリックで更新することもできます。\ngeodata-mode: true geox-url: geoip: \"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat\" geosite: \"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat\"Clash Meta For Android スマートフォン上でのClash Meta For Android（以下Clash）については、上書き設定を行う際にスマートフォンの実際の状況をより考慮する必要があります。\nまず、スマートフォン上のClashの上書き設定オプションはデスクトップ版のClash Verge Revほど柔軟ではなく、多くのキーが上書きできません。また、スマートフォンはコンピューターとは異なり、ネットワーク環境を頻繁に切り替える必要があるため、システムDNSも頻繁に変わります。このような場合、ネットワーク環境を変更するたびにClashをオンオフする必要があり、systemが表すDNSを更新する必要があります。したがって、国内の暗号化されたDNSを国内クエリとして固定するのが最善です。\nClashに入り、「設定」-\u0026gt;「上書き」以下はすべての上書き設定です：\n「DNS」-\u0026gt;「ポリシー」：強制的に有効化 「DNS」-\u0026gt;「Prefer h3」：有効化済み 「DNS」-\u0026gt;「Name Server」：2つの国外暗号化DNSを追加 「DNS」-\u0026gt;「Name Serverポリシー」：「キー」欄にgeosite:cnを入力し、「値」欄にhttps://doh.pub/dns-queryを入力 事前にGitHubからgeoip.datとgeosite.datをダウンロードし、最後にClash -\u0026gt;「設定」-\u0026gt;「Meta Features」に入り、「GeoIPデータベースをインポート」と「GeoSiteデータベースをインポート」機能を使用してそれらをインポートします。\n完成 最後にもう一度DNSリークテストを実行して、すべてが正しく設定されていることを確認してください。これで、家庭ネットワークのDNS設定が最適化され、より高速で安全なインターネット体験を楽しむことができます。\n参考: https://blog.lololowe.com/posts/8f1e/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nSmartDNSは設計時に遅延問題を考慮しており、具体的なメカニズムについては「中場休息：SmartDNSは速度測定によるDNS解決の遅延をどのように回避するか」。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nAnti ADの光栄な事績をまとめた人がいます。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n引用: https://wiki.metacubex.one/config/dns/diagram/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2025-02-06T17:01:51+08:00","image":"/2025/02/what-i-have-done-on-my-dns/cover_hu_1bda1c3daad4bc1b.webp","permalink":"/ja/2025/02/what-i-have-done-on-my-dns/","title":"私の家庭ネットワークのドメイン名解決ソリューション"},{"content":"「疲れた。少し休ませてほしい。」\n休学手続きを終え、煩雑な手続きに疲れ果てた体を引きずりながら学校の事務棟を出た。そして正式に、9か月間の休学生活が始まった。2週間前、私はまだルームメイトと一緒に焼肉バイキングを楽しんでいた。その時の私には、精神状態がこんなにも悪化するとは思ってもみなかった。筆舌に尽くしがたい苦痛が私を襲い始め、病院で処方箋をもらい、休学を決断するまでの過程は、わずか2週間しかかからなかった。その上、休学手続きを行う2日前には、1年分の生活用品を購入していた。だが、引っ越しの際、その荷物の重さは想像以上だった。\n寮を片付けたその日、外は土砂降りの雨。寮に入ると、机の上ではルーターのランプが点滅し、飲みかけのコーラがまだ置かれ、デリバリーで頼んだケチャップがいつものように机に散らばっていた。「しばらく戻ってこないだろうな……」、そうだ、この机はきっと二度とこの光景を取り戻せないだろう。\n偶然にも休暇を取ったルームメイトと残りのコーラを分け合い、新しく買ったばかりのエルゴノミクスチェアを解体し、様々な雑貨を箱詰めして雨の中車に運び込んだ。自分のベッドスペースが徐々に空っぽになっていくのを見て、私は一瞬「やっぱり休学せず、このまま続けてもいいんじゃないか」という考えが頭をよぎった。出発直前、空になったベッドをぼんやりと見つめていた私に、ルームメイトが肩を軽く叩いたことにも気づかなかった。3年以上共に過ごしたルームメイトとの別れ、寮の鍵と図書館で借りた本を返却し、ついに家へ帰る道に立った。\nそれでも、たまには集まるのが大事 たとえ休学しても、友達と一緒にご飯を食べる伝統は絶対に捨てない。薬の副作用で食欲が減退していた体を克服しつつある中、友達との食事会は今でも断ることはない。みんなで一緒に食べたり飲んだり、最近の生活をシェアし、お互い情報を交換する。そして最後に割り勘で支払いを済ませる。なんて素晴らしい時間だろう。唯一の問題は、かつてアルコール依存気味だった私が、医師から禁酒を厳しく指導されたことだ。そのため、外出して食事をする時は、西瓜ジュースくらいしか飲むことができない。\n23時就寝、8時起床 クエチアピンの効き目は限定的だったものの、それでも私の5時就寝、9時起床という生活リズムを改め、医師が勧める23時就寝、8時起床の生活に変えることができた。少なくとも最初の1か月はそうだった。そして私はジム通いも始めた。筋トレというものは本当に不思議な体験だ。炭水化物とタンパク質を大量に摂取しながら、重りをどんどん増やしていく。2か月も経たないうちに、体重は10キロも増加した。そのうち9キロは筋肉、1キロは脂肪。初心者特有の恩恵を享受した形だ。\nただ、筋トレが過ぎて興奮しすぎると、睡眠に直接影響が出る。特に足のトレーニングをした夜は、一晩中眠れないほどだ。そのため、トレーニングの頻度を減らさざるを得なかった。私の状況では、精神的健康に良い睡眠が何よりも優先されるべきだからだ。\n遠くても近くても旅行は旅行 旅行は生活の中で欠かせない彩りだ。今年9月の香港旅行と10月の桂林旅行は、数少ない遠出の旅だった。一方で、例えば芦渓村の七仙殿のような近場の旅行は数え切れないほどあった。遠くても近くても、旅行は旅行だ。「万巻の書を読み、万里の道を行く」とよく言われるが、書物から得た知識が現実の中で参照や実践に繋がるとき、心の中に湧き上がる満足感と安らぎは、自己と世界が確かに存在することを実感させてくれる最高の慰めだ。\n空から餅は降ってこない、でも子猫は降ってくる 空から餅が降ってくることはないだろう。でも、小さな茶トラ猫が降ってくることはある。あの日、ジムへ向かう途中、消防通路から聞こえた猫の鳴き声が私の注意を引いた。そして中に入ると、この子猫と出会った。\n今ではこの子を飼い始めて半年近くになる。たくさんの楽しさをもたらしてくれただけでなく、数多くの引っかき傷とボロボロになった本革ソファもくれた。小動物は人間の言葉を理解できないので、何度も「もう外に放り出してやろう」と思ったことがある。それでも結局はこの子を手放せなかった。猫を飼うというのはそういうものだろう。時にその厄介さに1万回も手放したくなるが、最終的にはその代えがたい感情的な価値のために、手元に置いておくことを選ぶのだ。\n観葉植物は現代人の生活必需品 観葉植物は見た目が美しいだけでなく、ホルムアルデヒドを吸収し、ほこりを吸着する。何よりも、室内に自然の要素を取り入れることで、心身の健康に多くの恩恵をもたらす。だから私は、観葉植物は現代人の生活必需品だと思う。\n今年、私の机は大きく変わった。ハードウェアのアップグレードだけでなく（例えば新しいモニターやモニター用ライトを購入）、観葉植物も取り入れた。私が選んだのはサンセベリアだ。手入れが簡単で、薄暗い環境でも正常に成長することができる。適切な肥料を与えた結果、私の2つのサンセベリアは新しい芽を出した。多肉植物はさらに手入れが楽で、水やりの頻度が少なくて済む。ただ、「金のなる木」という種類だけは少し困った。水を多く与えても少なくても上手くいかず、肥料もほとんど効果がない。園芸にはまだまだ学ぶべきことがたくさんあると感じている。\n私のオンラインプレゼンス 私はブログの「運営」をアクセス数のために行っているわけではなく、単純に自分が書きたいことを書いているだけなので、私のブログを読む人は多くない。それでも、検索エンジンのおかげで完全に無人というわけでもない。今年はライブ配信も始めたが、主な目的はゲームの録画を保存するためのもので、観客はほとんどいない。無名の配信者が単調なゲームをプレイするのを見たい人はそう多くないだろうからだ。\nosu!は今年中に300ppから3439ppまで成長した。現在ペンタブレットに変更し、まだ慣れている最中なので、この数値はしばらく伸びないだろう。\n生活への欲望 ずっと前から、私は生活の中の何事にも徐々に興味を失い始めていた。その一つの表れが「何も欲しくない」「何も買いたくない」ということだ。服は破れない限り新しいものを買わないし、髪は目にかからない限り切らない。新しい製品にも全く興味が湧かない。そして最近では、性的欲求すら失われつつある。欲望というものは本当に不思議だ。強すぎてもいけないし、弱すぎてもいけない。欲望のない人間は生き延びることができない。たとえ人間の生存本能が安全ネットとして、過早に深淵に落ちるのを防いだとしても、その人生は無意味で、生きるに値しないものになる。\n欲望が弱すぎると、何事にも興味が湧かず、一日中ぼんやりと過ごしてしまう。そしてその状態はかえって苦痛を伴う。適度な欲望を持ち、日々それに向かって努力し、自分がやりたいことをすることで、健康的なサイクルが生まれる。それがむしろ良いのではないだろうか。\n欲望をうまく扱えれば、人を前進させる原動力になる。「ストレスが動力に変わるなんて信じるな。ストレスは病歴にしか変わらない。人間の本当の原動力は、内なる喜びや興味への追求から生まれるのだ。」そうだ、今の私の状況を考えると、ストレスはすでに消え去った。しかし、そのストレスはすでに病歴に変わってしまった。私の心の奥底では、もう喜びや興味を追求していない。この数年間、その感覚はますます鮮明になってきた——何をしても深い、癒されない疲労感を覚える。肉体は健康であったとしても、心はすでに傷だらけで、虚弱極まりない。欲望が加速的に失われていくことが、本当に恐ろしい。同年代の人々が持つ情熱や、恋愛への憧れ、美しい生活への追求——私はそれらをすでに失ってしまった。\n2024年も終わりに近づいた。今年は私の大学生活、さらには人生全体において特別な一年となるだろう。この一年、私は生活への欲望を再び取り戻し、未来への自信を再燃させた。この一年間の試みは、すべて「生活への欲望を取り戻す」ということに向けた努力に他ならない——誰もが「やりたいことをやり、好きなことをする」べきだと知っている。それでも欲望と原動力の枯渇は意志の力だけでは補えない。「やりたいこと」や「好きなこと」が欠けている時に、どれだけの人が本当に意味のある解決策を見つけられるだろうか。\n","date":"2024-12-26T17:57:10+08:00","image":"/2024/12/2024-end-of-the-year-summary-public/image-13_hu_5d398f1badf5ff5d.webp","permalink":"/ja/2024/12/2024-end-of-the-year-summary-public/","title":"2024年の生活"},{"content":"5berのSIMカードを購入したものの、意外にも端末を選ぶことに気づきました。手元にあるAndroid端末はどれも対応していませんでした。以前からサブ機として使っていたRedmi Note 9 5Gには不満を感じていたので、この機会にそれを売却し、新たにXiaomi 10を購入しました。\nなぜXiaomi 10を選んだのか特に深い理由はありません。一つ目は5berの対応機種リストに明記されていたこと、二つ目は価格が安いこと。500～600元の予算で簡単に手に入ります。三つ目は自宅で使用しているMijiaデバイスとの互換性。そして最後に、「新世代の名機」としてバランスが良いことが挙げられます。\n特に深く考えず、適当に中古市場（闲鱼）で注文しました。しかし、今振り返ると、こんなに軽率に購入したのは失敗だったかもしれません。まずは受け取った端末の外観ですが、一言で言えば「傷だらけでボロボロ」。この端末は裏蓋が交換されており、フレームは前の所有者により何度も落とされてボロボロ、充電ポートには明らかな摩耗の痕跡があり、画面の隅には取れない汚れがついていました。この8GB+256GBのXiaomi 10を619元で購入したのは、少し高かったと感じています。\nサブ機に求める条件 私がサブ機に求める条件を考えてみると、実はそんなに多くありません。まずはスマホの基本機能である通信機能：5G対応であり、5berカードの書き込みができることが必要です。次にバッテリー持ちが良いこと。外出時にテザリング用途として使用するため、バッテリーは長持ちするに越したことはありません。そして、たまにカスタマイズや改造を楽しみたいので、カスタマイズのリソースが豊富でコミュニティが活発であること。これについては「新世代の名機」としてのXiaomi 10が十分に条件を満たしています。最後に、高リフレッシュレートのディスプレイが必須です。iPhone 12シリーズの60Hzにはもう耐えられません。\nバッテリー交換 購入した端末のバッテリーはかなり劣化しており、Battery Guruが推定する容量は3100mAh/4780mAh、つまり健康度は65%しかありません。「なぜそんなバッテリーが劣化した端末を買ったのか？」と聞かれるかもしれませんが、それは「验货宝」の「バッテリー」欄が一見問題なさそうに見えたからです。しかし、実際にはAndroid機のバッテリー状態は「Android端末では検出不可」と表示されることが多いのです。この端末のバッテリー状態では、SNSアプリを少し使っただけで4時間以内に電池切れになり、待機時間もひどいもので、外出時に持ち歩くのもためらうほどでした。この端末をテザリング用に使う予定だったので、これでは話になりません。そこで、バッテリー交換が必要だと判断しました。\n最初は公式サポートでバッテリー交換をしようと考えましたが、オンラインで価格を調べると159元（工賃込み）とのこと。端末自体が619元なのに、これは割に合いません。そこで、自分でバッテリーを購入して交換することにしました。\n6～7年前、私が酷安で活動していた頃、ちょうど初代Xiaomi 6がバッテリー交換時期を迎えており、その時に「中電（ZMI）」というブランドが流行しているのを目にしました。そこで中電の増量バッテリーを89元で購入し、自分で交換しました。\n交換手順はBilibiliで見つけた動画1を参考にしました。その手順に従うだけです。交換中に気づいたのは、この端末が以前に分解された形跡があり、しかもかなり雑に扱われていたことです。防水シールはすでに剥がされており、ネジがすべて揃っていない状態でした。この端末が裏蓋を交換していることは購入時に知っていましたが、内部の雑な作業の割に機能には全く影響がないことには驚きました。\nさて、バッテリー交換自体はスムーズに進み、増量バッテリーを装着しても裏蓋が浮くことはなく、保護ケースを付ければ全く気になりません。交換後、バッテリー持ちは劇的に改善され、一日中使用しても問題ありません。これでようやく外出時にこの端末を持ち歩けるようになりました。\nBootloaderのアンロック 現在のXiaomiは、もはやかつてのような「ギーク精神」にあふれたメーカーではありません。\nBootloaderアンロックのような基本的な操作でさえ、Hyper OSでは大きな障害が設けられています。システムの規定によれば、まずXiaomiコミュニティでレベル5に到達し、その後アンロックのベータテスト資格を申請し、テストに合格してからデバイスをXiaomiアカウントに紐づけ、さらにSIMカードを挿した状態で168時間待つ必要があります。\nいやいや、冗談ですか？？\n幸い、Xiaomi 10は元々MIUIを搭載していたため、Hyper OSがMIUIに追加したアンロック制限を迂回する方法があります2。MIUIの168時間待機は回避できないため、1週間待つ必要があります。その間に、事前準備を進める予定です。\n広告の削除 以前は「大圣净化」や「李跳跳」を使って広告を削除していましたが、これらはTencentの法的措置により更新が停止されました。そこで新たに「GKD」という完全オープンソースのツールを見つけました。以前購入した「大圣净化」のライセンスが無駄になったのは少し残念ですが、今回はShizukuを利用して広告を削除しました。Shizukuのエコシステムは、7～8年前と比べて大幅に改善されています。\neSIM もちろん、Xiaomi 10はeSIMをサポートしていませんが、以前から5berのSIMカードを用意していました。現在、eSIMの機能は非常に便利で、データローミングも問題ありません。保番号用のプランも順調に利用できています。これらのeSIMを開通させるには、VISAまたはMasterCardを用意し、ネット上に多数あるチュートリアルを参考にしてください。\n個人的におすすめなのはClubSIMで、年間わずか6HKDで電話番号を維持できます。一方、ネットでよく見かけるウクライナのLifeCellはあまりおすすめしません。理由は、TelegramのSMS認証が音声通話認証に強制変更されるなど、謎の制限がかかることが多いためです。特に国際電話の受信が必要になる場合、LifeCellのローミング料金は高額です。制限が少ないClubSIMの方が適しています。\nデータローミングの使用量が多い場合は、3HKのローミングプランを検討するのも良いでしょう。私の場合、基本的にはSMS受信ができれば十分なので、ClubSIMを選びました。\n満足のいく性能とバッテリー持ち ここ数年、私はもともとあまりやらなかったスマホゲームから徐々に離れていきました。今では、スマホは外出時の空き時間を補う程度で十分です。唯一の性能要件は、日常使用がスムーズであること。ゲームについては、王者荣耀（Arena of Valor）レベルの軽負荷ゲームが動けば問題ありません。この程度の要求なら、約5年前に発売されたXiaomi 10でも簡単に満たせます。ベンチマークテストについては、この古い端末でスコアを披露するのはやめておきます。\nバッテリーを交換したXiaomi 10は、外出時のバッテリー需要を十分に満たしてくれます。一日中ナビゲーションを使っても全く問題なく、テザリングをしてもバッテリー切れの心配はありません。このバッテリー性能には概ね満足しています。\n「使えないわけではない」 次に、満足していない点について触れます。まず、8GBのメモリです。この容量は数年前なら問題ありませんでしたが、現在では少し物足りなく感じます。バックグラウンドでのアプリ保持能力は期待できず、日常使用がスムーズであれば御の字です。そのため、こまめにバックグラウンドを手動でクリアする必要があります。\n次に、ひどいアンロックプロセス。Hyper OSを名指しで批判します。自分の端末をアンロックするために、コミュニティでレベル5になるまで活動し、さらにテストを受ける必要があるなんて、冗談でしょうか？ こうしたユーザーの権利をメーカーが奪うようなやり方には、Xiaomiへの印象が悪くなりました。\n最後に、ひどい充電ポートの設計。通常のスマホではモジュール化された充電ポートが採用されていますが、Xiaomi 10では充電ポートが基板に直接ハンダ付けされています。このため、長期間使用すると摩耗が進み、接触不良や充電不能になることがよくあります。修理するには充電ポートを再度ハンダ付けする必要があり、非常に手間がかかります。現在、私の端末でも充電ポートが少し緩んできており、将来的に交換が必要になるかもしれません。これもまた余計な手間です。\n最後に…… 総じて、Xiaomi 10は悪くありません。サブ機に求めるすべての要件を満たしており、全体的にバランスが取れた端末です。前述したような小さな問題はありますが、それでも良いスマホだと思います。今回のサブ機への買い替えには概ね満足しており、このXiaomi 10が売却される日まで、良い時間を共に過ごせることを願っています。3\nこちらの動画を参考にしました。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考：Githubプロジェクト：MlgmXyysd/Xiaomi-HyperOS-BootLoader-Bypass\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nトップ画像の出典は透かしをご覧ください。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-12-05T19:56:29+08:00","image":"/2024/12/umi-experience/cover_hu_d7a8279c694f004e.webp","permalink":"/ja/2024/12/umi-experience/","title":"2024年末にXiaomi 10をサブ機として購入"},{"content":"何が問題なのか分かりませんが、私のコンピュータの時間は決してNTPサーバーと自動的に同期されません。短期的には使用に大きな影響はありませんが、放置しておくと時計のずれが大きくなり、SSLやTOTPなどのタイムスタンプに依存するアプリケーションに問題を引き起こす可能性があります。また、手動で同期ボタンを押すのも非常に不便です。今日はこの問題を解決することに決めました。\nSpecialPollInterval ネットで検索したところ、SpecialPollIntervalというレジストリキーがあることがわかりました。具体的な位置はHKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\W32Time\\TimeProviders\\NtpClientです。Microsoftの公式ドキュメントでは次のように説明されています：\nこのエントリは、手動のピアのための特別なポーリング間隔を秒単位で指定します。SpecialInterval 0x1 フラグが有効になっている場合、W32Timeはオペレーティングシステムによって決定されたポーリング間隔の代わりにこのポーリング間隔を使用します。ドメインメンバーのデフォルト値は3,600秒です。スタンドアロンのクライアントおよびサーバーのデフォルト値は604,800秒です。\n一般的なクライアントの場合、このキーのデフォルト値は604800、つまり1週間に1回の同期です。この間隔は明らかに長すぎるので、私はこれを3600に設定し、1時間ごとに同期することにしました。\nw32tm 数日後、再度時間を確認したところ、時間はまだ自動的に同期されておらず、今回は15.8秒のずれがありました。\nそこで「SpecialPollInterval」の具体的な役割と期待した結果が得られなかった理由を調べたところ、Microsoftのトラブルシューティングガイドにたどり着きました。このトラブルシューティングガイドでは、「クライアントがNTPサーバーに時間サンプルをポーリングするたびに、NTPクライアントはSPIKE状態に入ります。時間サービスは内部状態を管理しており、クライアントがSPIKE状態に入ると、クライアントは時間を同期しません。」と指摘しています。\nこの問題を解決するためには、Windows時間をMinPollInterval/MaxPollIntervalを使用してポーリング間隔を設定する必要があります。\nw32tm /config /update /manualpeerlist:cn.pool.ntp.org /syncfromflags:MANUALサービスが起動していない この設定を実行すると「サービスが起動していない」というメッセージが表示されました。これは、時間同期に使用されるサービスがまったく起動していないことを意味します。このような基本的なサービスが自動的に起動しないとは、これはWindowsのバグなのか、私が後に無意識に作った問題なのか分かりませんが、とにかくまずこのサービスを起動します：\nnet start w32time w32tm /register # 基本的なレジストリキーと関連サービスを登録しますその後、Win + Rでservices.mscを実行してサービス管理パネルを開き、「Windows Time」サービスを見つけ、その起動タイプを「自動」に設定すれば、次回の起動時に自動的に起動します。\n再度コンピュータを再起動し、「設定」→「時間と言語」→「日付と時刻」→「追加の時計」に移動し、「インターネット時間」タブに切り替えます。「次回同期」の文字が表示された場合、このシステムはついに正常に動作していることを示しています。\n","date":"2024-11-18T18:03:47+08:00","image":"/2024/11/windows-ntp-hiccup/cover_hu_e196169a0c972a34.webp","permalink":"/ja/2024/11/windows-ntp-hiccup/","title":"Windows Hiccup 小日常：NTPサーバーと自動的に同期しない時間の問題を解決する"},{"content":"銀行カード HSBCブルーライオン これは、HSBC銀行のMasterCardデビットカード（中国本土では通常「借記カード」や「貯蓄カード」と呼ばれるもの）です。香港で口座を開設した後、アプリから簡単に申し込むことができます。申し込む前に、ユーザープロフィールの中国語住所を変更することを忘れないでください。カードは1～2週間後に郵送されてきます。\nこのカードはHSBCの銀聯カード（レッドライオン）と残高が共有されており、各取引で0.4％のキャッシュバックが得られます。上限のないキャッシュバックの特典は、多くの中国国内のクレジットカードを上回るほどです。世界中のATMで手数料無料で現金引き出しができ、年会費もありません。消費に非常に適したデビットカードです。\n工銀星座カード 工銀が海外通販を必要とする学生向けに特別に設計したカードで、クレジット限度額は0です。クレジットカードとデビットカードの中間に位置するカードで、VISAマークが魅力です。しかし、このカードにはVISAマークが付いているものの、使い勝手はあまり良くありません。海外決済の前に手動で外貨購入を行う必要があり、通貨が正しくなければ、取引が失敗する可能性があります。\nカードデザインは比較的良いですが、非常に傷つきやすく、塗装が剥げやすいです。購入後は基本的に家で飾るだけになるでしょうが、幸いにもATMに頻繁に行く必要はありません。\n興業寰宇人生 \u0026amp; 無界カード 銀聯デビットカードで、名前からして、このカードは主にクロスボーダー金融ニーズを持つ人々向けに提供されています。最初の30回の国際送金手数料を免除し、海外ATMでの現金引き出し手数料も免除されます。クロスボーダー送金を頻繁に行う人にとって、このカードは多くの節約が可能です。\n無界カードは寰宇人生の特典を持っていると言われていますが、カードのデザインは透明で、見た目が面白いです。この外観については好みが分かれますが、実用的であれば何でも良いでしょう。\n5ber SIMカード 数年前に話題になったSIMカードで、eSIMに対応していない携帯電話にeSIMを対応させることができます。最近ようやく手に入れました。5berの操作は、すべてのeSIM物理SIMカード変換の中で最も簡単で、通常はeSIMのQRコードをスキャンするだけです。手に入れた後、ウクライナのlifecellと香港のClubSIMをダウンロードしましたが、どちらも番号保持用の神カードです。\n世界中がeSIMを普及させている中、中国の通信事業者は相次いでeSIMサービスを停止しており、非常に理解に苦しむところです。実名制の問題は香港の方法を参考にすれば解決できるはずですが、中国は逆行して「スーパーSIMカード」と呼ばれるものを導入しています。中国国内でいつになれば便利で安価なeSIMが提供されるのか、さっぱりわかりません。\nWacom ペンタブレット ペンタブレットを買って絵を描く？冗談でしょう。真面目な人はペンタブを買って絵を描くなんて考えませんよ。もちろん、osu!をプレイするためです。最近、マウスでのプレイが3000ppを超えたので、ペンタブレットを買って試してみることにしました。osu!をプレイするなら、もちろん安いものを選びます。そこで、Wacom CTL-472という入門用ペンタブレットを無条件で購入しました。\n実際に使ってみると、マウスからペンタブレットへの移行にはかなりの慣れが必要で、プレイできる曲の難易度にギャップが生じるだけでなく、手の筋肉痛の位置も異なります。2日間試してみた結果、しばらくはマウスに戻ることにしました……\nXiaomi 10 数年前、父に勧めたXiaomi 10 Proが4年間も問題なく使えているので、自分用にXiaomi 10を予備機として購入しました。Xiaomi 10は、ある意味で「新世代の頑丈なスマホ」と言えます。性能、バッテリー持ち、画面品質など、すべてがバランス良く、しばらく使ってみて、主力機にしたいと思うほどです。\nXiaomi 10を購入した主な理由は、前述の5berです。本当に「一碟の醤油を買うために一皿の餃子を包んだ」ようなものです。 5berの対応機種には奇妙な点があり、多くのAndroid機種が対応していないため、元の予備機を売却してXiaomi 10を購入することにしました。\nカスタムROMを導入するかどうかについては、まだ悩んでいます。一方で、HyperOSは十分に優れており、機能が豊富で使いやすいです。しかし、プライバシーの問題があるため、このスマホをLineageに変更するべきかどうか考えています。とりあえず、今はこのまま使ってみるつもりです。ある意味では、プライバシーについての「妥協」とも言えます。\n仮想サーバー（VPS） 最近、私のサーバーの契約がもうすぐ切れるので、新しいマシンを探す必要があります。現在はContaboとHetznerを試しており、Netcupも試す予定です。新しいマシンを購入するたびに、システムを再インストールして、増え続けるIceshrimpサービスを正常に動かせるかどうかテストしています。現在、Cloudconeのパフォーマンスが非常に悪いと感じているため、安定したマシンを見つける必要があります。\nその中でHetznerは個人的に非常に良いと感じています。マシンのパフォーマンスが強力で、SLAも保証されており、自社開発のコントロールパネルも美しいです。三大ネットワークの復帰も良好で、ニュルンベルクのデータセンターを選びました。中国移動はCMIIN2の高級回線、他の2つは通常の回線を使用しています。価格はRackNerdやCloudConeなどの格安マシンには及びませんが、同等の性能を持つマシンの中では非常に安く、さらに悪用防止機能が優れているため、サービスを運営するのに十分です。\n一方、Contaboはパフォーマンスが弱く、SLA保証が非常に緩い（SLA95％、つまり年間18日以上停止しても問題ない）ため、さらに多くの制限（メールポートの非開放など）があります。試してみた結果、個人的にはお勧めしません。\n淘宝の格安データSIMカード 淘宝で安いデータSIMカードを買う場合、詐欺に遭う覚悟をしておく必要があります。今回は1枚購入し、データSIMカードの詐欺の仕組みを大まかに理解しました。まず、宣伝画像には月額9元のプランが表示されており、注文後に「発送できない」と言われ、最終的にはより高価で悪いプランに変更するように誘導されます。\n今回購入したものは、最初は宣伝画像に月額9元のプラン（中国移動105Gの通常データ + 30Gの定向データ）が表示されていました。しかし、発送できないと言われた後、聯通70G全国データ + 120G省内データのプランに変更され、実際の月額料金は19元に変わったようです（ただし、実際の月額料金は来月の請求を待ってみないとわかりません）。さらに酷いことに、2年の契約期間もあります。それでも、このプランはまだ比較的安価なので、とりあえず使ってみます。半年後には捨てる予定ですが、詐欺の仕組みを理解して経験を積むのも悪くない報酬です。\niOSのp12証明書 多くの人はAndroidが「いじりやすい」デバイスだと思っていますが、実はそうではありません。手間を惜しまなければ、iOSでもAndroidに劣らないほどいじることができます。p12証明書は、本来Appleが開発者に提供しているツールで、AppStoreに未登録のアプリをテストするためのものです。どんなアプリでも、開発者のp12証明書で署名されさえすれば、iOS/iPadOSで実行可能です。\nAppleは、開発者アカウントを持たないユーザーが署名できるアプリの数を3つに制限していますが、開発者アカウントを持つ場合は無制限に署名できます。開発者アカウントのサブスクリプション料金は99ドル/年で、アプリを数個しかインストールしない人にとっては明らかに無駄です。インターネット上では、すでに署名済みの開発者証明書を販売している人がいて、それを直接購入して使用できます。\n現在、私はBHTwitterとEhPandaをインストールしています。Esignをインストールし、証明書をインポートすれば、自由にアプリをインストールできます。また、サードパーティのソフトウェアソースを追加することも可能です。無料のソースは品質が低めですが、有料のソースは比較的品質が高く、アプリも豊富です。したがって、今回はその点を体験することはできません。\nこの証明書は、アプリの多重起動やゲームのチートなどにも使用でき、遊び方は多岐にわたります。証明書の価格は6～100元と幅がありますが、Apple公式の99ドル/年の開発者サブスクリプションと比べると、非常にお得です。\n","date":"2024-11-15T18:39:17+08:00","image":"/2024/11/recent-gadgets/cover_hu_7ec602792c5b9b6.webp","permalink":"/ja/2024/11/recent-gadgets/","title":"最近手に入れた小さなガジェット"},{"content":"桂林での短期滞在 またこの陳腐な始まりです：「桂林の山水は天下第一」。\n桂林と言えば、その街を知っているか、実際に訪れたことがある人が大半でしょう。世界レベルの自然景観と三線級の都市建設。十年以上前、私はしばらくの間桂林に住んでいました：市内の象鼻山、二江四湖の遊覧船；市外の陽朔、漓江の竹筏、そして川辺のバーベキュー。\n他人の旅行地であった興味はとっくに失われました。ある冗談を聞いたことがあるかもしれません。「長城に行かぬ者は男に非ず、再び行く者は愚か者である」というものです。それはまるで甘い飲み物のようなもの、初めて飲んだ時は天国のように素晴らしく感じますが、一度味に慣れるとただ不快になるだけです。\n香港から帰国したばかりで、数日後に再び桂林へ向かうことになりましたが、本当はあまり行きたくありませんでした。香港の旅はとてもストレスが多く、疲れ切ってしまいました。国慶節の全休日を使って休息する必要があると感じました。\nしかし、人生は常に不思議で予測不可能です。何故か新たな旅に出ることになり、ほぼ完全に探索し尽くしたこの街へと向かいました。\n一つの街が一つの気持ちを反映 長沙が娯楽死を意味するなら、私の目に映る桂林は比較的に悠々自適です：桂林米粉一杯６元で無制限供給、望むなら一日三食全てこれで済ませ、18元で一日の食事が解決できます；閑散期には二江四湖はほぼ無人で、過剰な受け入れ能力が閑散期には大量の余剰を生み出し、ホテルの価格は非常に安くなり、観光地も同様です。そのため、以前桂林にいた時、食べること、遊ぶことがとても安かったのです。\n国慶節の休日には、旅行中の親戚の家に泊まり、宿泊費は無料でした；母の会社が家族車の燃料費を全て支給してくれました；加えて桂林の日常の生活費が非常に低いため、このように気分転換する方法は本当に非常にけち経済的です。\nその結果、桂林で楽しく5日間を過ごしました。\nラズベリーパイとCloudflare Tunnel ラズベリーパイはルームメイトのAAと一緒にプロジェクトのために購入しましたが、プロジェクトが終わった後、それは私のものになりました。既に利用可能なコンピューティングリソースなので、ラズベリーパイにRaspberry Pi OS Lite 64bitをインストールし、ネットワークに接続し、サーバーとして使用しました。\nARMアーキテクチャであるため、ラズベリーパイの消費電力は非常に低く、待機時の消費電力は5W未満、ピーク時の電力は25Wで、通常はピーク電力に達することはほとんどありません。年間の電気代は数十元程度です。\n最も困難な部分は、中国独特のインターネット環境のおかげでネットワークの問題でした。家庭内サーバーの内容を公開インターネットに公開するのは頭痛の種です：ISPは通常、デフォルトで公衆IPv4アドレスを提供しませんし、提供されたとしても動的です；80や443などの一般的なポートを開くことは考えられません；静的IPを取得することは不可能ではありませんが、ビジネスラインが必要で、各種認証が必要であり、家庭用インターネットよりも少なくとも10倍高価です。\n当初、Cloudflare Tunnelにはあまり期待していませんでしたが、頻繁に切断されたり、パケットロスが発生したりするというオンラインの苦情が多かったためです。しかし、実際に使用してみると、予想以上に性能が良かったです。ルートドキュメントの読み込み時間が比較的長いことを除けば、他の静的リソースはCloudflareの強力なエッジネットワークの恩恵を受け、非常に迅速に読み込まれました。また、地域の違いやISP間の違いか、私のTunnelはピークタイムであっても安定しており、比較的速い速度を維持しています。これは私がラズベリーパイで設立したテストブログです。具体的な加速効果を知りたい場合は、チェックしてみてください：https://rpiblog.l3zc.com。\n内部ネットワークの貫通問題を解決することで、ラズベリーパイの可能な使用範囲が大幅に拡大し、将来は多くの興味深いプロジェクトに使用できるようになりました。ISPが無理やり私のTunnelを切断しないことを願っています。\n私のRSSフィード Followに参加し、私のブログを認証する Followについて初めて知ったのはDIYGodのツイートを見たときでした。これはDIYGodによるRSSHubに続くもう一つのオープンソースプロジェクトで、まだアルファ段階にありますが、既にかなり完成度が高いです。\nFollowはRSSリーダーで、RSSHubやRSS3（本当然ながら）と深く統合されています。ほとんどのRSSリーダーとは異なり、Followはクラウドサーバーを使用してコンテンツを取得するため、購読できるフィードの数に制限があります。現在はベータ版のため、招待コードが必要ですが、オンラインコミュニティの助けを借りれば入手はそれほど難しくありません。\nFollowを使い始めて1週間が経ちましたが、全体的に非常に満足しています。機能が強力で、操作がスムーズで、現在は無制限（今のところ）のLLM要約/翻訳機能が特徴です。\nFollowは、フィードの保守者が自分のフィードを認証できるコミュニティでもあり、寄付を受け取ることができます。寄付はPowerと呼ばれるERC-20トークンを使用して実装されています（本当に、なぜ？ RSSフィードを読むだけなのに、なぜブロックチェーンに関わらなければならないのでしょうか？）。このアプローチはまだ議論の余地がありますが、Followはこの機能をうまく磨き上げ、楽しい経験を提供しています。\nRSSフィードの読み取り体験の問題を修正する 私のブログの元のRSSフィードは、Hugoのデフォルトテンプレートを使用して生成されました。.Content変数から直接引っ張られたコンテンツには、組み込みの画像処理機能によって生成されたさまざまな解像度の画像URLが含まれており、コードブロックにはchromaによって生成された行番号やハイライトマークが含まれていましたが、ほとんどのリーダーはこれを適切に扱うことができませんでした。そこで、Hugoに以下のレンダーフックを追加して、これらの問題を修正しました：\n./layouts/_default/render-codeblock.rss.xml:\n{{ .Inner }}./layouts/_default/render-image.rss.xml:\n{{- $url := urls.Parse .Destination -}} {{- if not (or (eq $url.Scheme \"http\") (eq $url.Scheme \"https\")) -}} {{- $result := .Page.Resources.GetMatch (printf \"%s\" (.Destination | safeURL)) -}} {{- with $result -}} {{- end -}} {{- end -}}このようにして、以前は問題だった読み取り体験がもはや問題ではなくなりました~~（願わくば）~~。\nまた、フロントエンドのいくつかのマイナーな最適化も行いました。これで、コードをコピーする際に行番号を誤って選択することがなくなりました。フォントはJet Brains Monoに変更され、コピーが容易になるようにパディングが調整されました。\nブログを書くこと以外に、ブログのバグを修正するのもいつも楽しい作業です。この変更は私の気分を良くするだけでなく、皆の読み取り体験を向上させました。\n","date":"2024-10-23T02:05:20+08:00","image":"/2024/10/guilin-raspberrypi-and-rss-feed/cover_hu_9e407f5dddff8939.webp","permalink":"/ja/2024/10/guilin-raspberrypi-and-rss-feed/","title":"最近の出来事：桂林、ラズベリーパイ、そして私のRSSフィード"},{"content":"最近香港を訪れ、いくつかのお土産を持ち帰りました。これらのお土産と香港での思い出を文章にまとめ、記念として残します。\nオクトパスカード 香港に到着する前にすでにオクトパスカードを開通していました。オクトパスカードは香港のほぼ全域で利用可能です。MTR、コンビニ、トラム、バス、ピークトラム、スターフェリーなど、ほぼどこでも使えます。\nApple Payを使って人民元でオクトパスカードを開通できますが、50香港ドルのデポジットが必要です。返却可能だと言われていますが、実際に返却する人はどれほどいるでしょうか？手数料と考えたほうがいいかもしれません。しかし、Apple Payでは手数料なしで人民元を直接使ってカードを開通・チャージでき、為替レートもかなり良好です。これは高評価です。\ncsl. SIMカード 香港旅行で最も安いSIMカードは中国移動香港のMySIMですが、私はあえてそれよりも倍近く高いcsl.を選びました。もちろん、番号を保持するためです。\n以前、ClubSIMが1年に6香港ドルで番号を保持できることを知っていましたが、香港に到着して最初に入ったコンビニにはそのカードが売っていませんでした。仕方なくcsl.の香港ツーリストSIMを選びました。50香港ドルをチャージすれば180日間の有効期限が延長されます。計算してみると、このcsl.は1年に100香港ドルかかります。面倒ですね。もしあの時ClubSIMを売っている店を見つけていればよかったのに。\nもちろん、このカードも記念として残せます。\nSUA登録ラベル/香港政府の公文書 香港に到着して最初に行ったことは、事前に申請していたSUA（小型無人航空機）登録ラベルを受け取ることでした。\n香港の法律第448G章「小型無人機令」によると、私のドローンは甲二類無人機に分類され、民航処に登録し、民航処のQRコードを貼り付ける必要があります。また、オンラインで「リモートパイロット」として登録し、相応のライセンスを取得する必要があります。これらが揃って初めて合法的に飛行できるようになります。\n長沙から香港への直行便がなかったため、西九龍高鉄駅から入境しました。入境後、すぐに柯士甸駅に向かい、屯馬線に乗り換え、東涌線を経由して空港に直行しました。高鉄の利便性があったにもかかわらず、民航処までの長い往復の旅が倍の苦痛となりました。\n東涌線を降りた後、S1空港バスに乗り換え、「民航処本部；東耀路」停留所で降りると、このような何もない景色が広がります：\n香港は本当に暑いです。室内の冷房はしっかり効いていますが、このような遠く離れた場所には冷房がありません。汗をかきやすい私にとっては地獄のような場所です。少し坂を登っただけで、かなりの汗をかきました。幸い、民航処のオフィスビルに入ると、待ち望んでいた冷房がありました。スタッフはとても親切で、迅速に2ヶ月前に印刷されていたラベルを取り出してくれました。また、ドローンのパイロットライセンスの取得手続きも案内してくれました（規則を確認するだけなので心配いりません）。\nこうして嬉しく登録ラベルを手に入れました。\nHSBC銀行カード 香港で銀行口座を開設することには多くの利点があります。例えば、50万香港ドルの最低預金額なしで香港株を取引できたり、中国本土の外貨管理の制限を受けなかったりします。今回の旅行では時間があったので、朝早くから銀行口座を開設することにしました。\n私が泊まっていたホテルは湾仔にあり、香港島の東側にあるHSBC本店に行く予定でした。香港島を横断するには、主に2つの方法があります。MTRの島線か、香港名物のトラム、通称「叮叮」です。高いMTRに比べて、叮叮は香港で最もお得な交通手段の一つです。距離に関係なく運賃は一律3香港ドル。これだけ安い料金で、100年以上の歴史を持つトラムシステムを体験できます。専用の軌道があるため、叮叮はほとんど渋滞に巻き込まれることはなく、ゆっくりと香港の喧騒の中を進んでいきます。時折ベルを鳴らしながら、ダブルデッカーバスの轟音や群衆のざわめき、さらには視覚障害者向けの信号音が響く通りを進んでいくのです。これが活気に満ちた、騒がしい香港の姿です。\nHSBC本店のメインエントランスは、実は皇后大道中にありますが、ほとんどの人が便利な公共交通機関に接続しているスタチュー広場側の徳輔道中の入口を利用します。バンクストリートで降りると、すぐにHSBC本店が目の前に見えます。エレベーターに乗って上がると、そこが目的地です。口座開設の予約？そんな必要はありません。一部の支店では予約が1ヶ月先まで埋まっていることもありますが、そんなに待てる人はいないでしょう。受付で口座開設を希望することを伝えれば、その場で番号をもらえます。予約している人がどこに行くのかはわかりませんが、私が行ったときは待ち時間がほとんどなく、1人だけ待っていました。サービスは素晴らしく、いくつかの質問に答えた後、その場でカードを受け取りました。\n口座開設後、セントラルを散策しました。終審法院、スタチュー広場、戦争記念碑、威爾斯親王軍営、そして添馬の政府本部などを訪れました。高層ビルが立ち並ぶエリアに、これほど多くの歴史的な建造物や記念碑があるのは感慨深いです。香港の豊かな歴史を感じさせる場所です。多くの有名な金融機関や政府機関が集まっているこのエリアは、まさに香港の政治・経済の中心地と言えるでしょう。\n『囲城』と『書店でたまに』 この2冊の本には特別な意味はありません。ただ、本屋で見つけて面白そうだと思っただけです。2冊で約300香港ドルもかかりました。香港は本当に高いですね。\n香港の出版業界はかつて栄えていましたが、返還後は検閲の圧力で徐々に衰退していきました。今回の旅行中、訪れた本屋や読んだ本のすべてが、著者や出版社が何かを抑制しているような感覚を与えてくれました。それが非常に残念でした。最終的に、国家安全法が施行される前に出版された本と、中国本土からの珍しい縦書きの本を記念として選びました。\nピークトラム往復券 オクトパスカードを使うこともできましたが、あえて記念として往復のピークトラムチケットを購入しました。88香港ドルと高額ですが、香港の基準では日常の通勤手段とも言えるかもしれません。うーん、私はただ中国本土の人間として貧しいだけかもしれません。\nピークトラムの中環駅に向かう途中、HSBC本店の裏手にあるフランス外方伝道会ビルや聖ジョンズ大聖堂も訪れました。後者は香港で最も古い西洋式教会で、荘厳な雰囲気、優雅な装飾、そしてシンプルで静かな外観が特徴です。セントラルには本当に宝物がたくさんあります。\nピークトラムは1888年から運行されており、現在は6代目の車両が使われています。中環駅では観光客だけでなく、地元の人々も多く見かけます。車両のデザインは時代とともに進化しており、今では冷房も完備されています。これは、始まり以来車両が変わっていない叮叮とは大きな違いです。ただし、チケットの価格は叮叮の20倍以上です。\nビクトリア・ピークに到着してみると、残念ながら天気が悪く、良い写真は撮れませんでした。ドローンを使っても、あまり良い結果は得られませんでした。\n天気、機材、そして絞りが少し開きすぎていたことを考えると、結果には満足しています。\n香港ドル紙幣 他の場所とは異なり、香港には独自の通貨発行システムがあります。香港金融管理局によって認可および規制されている3つの発券銀行、HSBC、スタンダードチャータード銀行、そして中国銀行香港が紙幣を発行しています。香港政府は10香港ドル紙幣を発行しています。今回はエリザベス女王の肖像が描かれたコインを手に入れることができませんでしたが、これらの異なる発券銀行の紙幣も記念品としては価値があります~~（実際には使い切れなかっただけですが）~~。\nその他の写真 この記事を書いていると、これらのお土産が私の香港での体験の大部分をつなぎ合わせることができる一方で、街を歩き回って発見したランダムな瞬間を捉えることはできないことに気づかされます。これは記念としての文章なので、重要な瞬間はできるだけ詳しく記録しておくべきです。そこで、お土産の説明を一旦中断し、残りの香港での時間を写真で記録します。\n高速鉄道のチケット（領収書）とまとめ チケットはすでにデジタル化されており、今では物理的なチケットとして手に入るのは領収書のみです。これらは実際のチケットとしては使えません。私は払い戻しが必要なかったのですが、物理的なチケットを記念として手に入れました。これが香港を離れる前の最後のお土産となりました。\n","date":"2024-10-12T11:49:42+08:00","image":"/2024/10/hk-souvenirs/cover_hu_330bd22de0169088.webp","permalink":"/ja/2024/10/hk-souvenirs/","title":"香港から持ち帰ったお土産は？"},{"content":"手短に言うと、最近ゲームプレイのライブ配信を始めました。多くの視聴者を期待しているわけではなく、ただ、なぜやらないのか？という感じです。さらに、各配信プラットフォームにはライブの再生機能があります。つまり、毎回のゲーム録画を無料で保存できるわけですから、利用しない手はありません。\nさて、本題に入りますが、ご覧のとおり、最近複数のプラットフォームで同時に配信する必要が出てきました。しかし、OBS自体は明らかに同時配信をサポートしておらず、プロキシ設定の欠如と他のよく知られた理由により、twitch.tvへの配信ができませんでした。そこで、解決策を探し始めました。\n要求の明確化 複数のプラットフォームで同時に配信する パフォーマンスへの影響が少ない方が良い 1つの配信にはプロキシが必要 マルチストリーミング マルチストリーミングには既成のプラグインがあります：Github\nReleaseページから.exeインストーラーをダウンロードします。インストールが完了したら、「ドック」メニューで「Multi-Output」にチェックを入れるのを忘れないでください。デフォルトでは別ウィンドウが表示されますので、この機会にOBSのレイアウトを調整しましょう。\nプラグインの設定は簡単で、元のOBSと同じ手順で設定できます。\nBilibili ライブアシスタント 奇妙なことに、Bilibiliではフォロワーが50人未満の配信者はライブアシスタントを使用する必要があり、他の国内プラットフォームでも同様の規則があるかもしれません。サードパーティの配信モードを有効にすると、ライブパネルに配信設定が表示されます。この時、ライブアシスタントが提供する配信アドレスを使用する必要はありません。なぜなら、ライブアシスタントは毎回変わるローカルIPを提供するからです。単に127.0.0.1またはlocalhostに置き換えるだけで良いです。\nTwitchへの配信 Twitchへの配信はGFWのために多くの不要なトラブルが発生します。\nOBS自体はプロキシ設定をサポートしていません。当初、ClashのTAPモードを使用してOBSのトラフィックを強制的にプロキシしようとしましたが、ClashのTAPはrtmpトラフィックをリッスンしないため、失敗しました。そこで、Twitchと通信でき、GFWの影響を受けない転送サーバーを設定することにしました。\n調査の結果、CaddyはRTMPプロトコルをサポートしておらず、nginx-rtmpモジュールはRTMP専用に設計されています。ほぼ唯一の選択肢です。\n前提条件：\n基本的なLinuxコマンドライン操作に慣れていること。 サーバーにdockerとdocker composeがインストールされていること。 適切なコマンドラインテキストエディター、例えばnvimやほとんどのディストロにデフォルトで付属しているnano。 ディレクトリを作成：\nmkdir nginx-rtmp \u0026\u0026 cd nginx-rtmpdocker-compose.ymlを作成：\nservices: nginx-rtmp: image: tiangolo/nginx-rtmp:latest container_name: nginx_rtmp ports: - \"1935:1935\" # RTMP port volumes: - ./nginx.conf:/etc/nginx/nginx.conf restart: unless-stoppednginx.confを作成：\nworker_processes auto; events { worker_connections 1024; } rtmp { server { listen 1935; chunk_size 4096; application live { live on; push rtmp://live.twitch.tv/app/{Twitchのメインストリームキー}; } } }設定を開始：\ndocker compose up -d # 古いバージョンのcomposeプラグインの場合は docker-compose upファイアウォールのポートを開くのを忘れないでください。私のファイアウォール設定は、記事To Fix The Docker and UFW Security Flaw Without Disabling Iptablesに基づいており、ポートを開くコマンドは次のとおりです：\nufw route allow proto tcp from any to any port 1935設定が完了したら、OBS内の配信ターゲットアドレスにrtmp://サーバーip/liveを入力し、任意の配信キーを入力します。設定が完了したら配信を開始できます。\nNetch サーバーがない場合、Netchを使用してOBSプロセスをプロキシして配信することもできます。\nまず、Netchバージョン1.9.2をダウンロードします。必ず1.9.2バージョンであることを確認してください。プロセスモードを追加し、OBSフォルダーを追加して、そのプロセスモードのプロキシを有効にします。\n結論 TwitchとBilibiliに同時に配信するために、多くの不要なトラブルに遭遇しました。OBSにプロキシ機能が組み込まれていないことを非難することもできますし、Clash VergeなどのツールがRTMPをサポートしていないことを非難することもできます。しかし最終的には、GFWを非難するしかありません。最終結果は満足のいくものでしたが、配信のためにこれらのことを苦労して行う経験は決して良いものではありません。将来的には、Mihomoカーネルを修正してRTMPプロトコルをサポートさせるか、OBSのトラフィックを転送する独立した実装を開発することを検討すべきかもしれません。いずれにしても、この土地でスムーズに配信するのは道のりが長く険しいです。\n最後に、私のTwitchチャンネルをフォローしてください: https://www.twitch.tv/powerfullz233\n","date":"2024-09-18T14:16:51+08:00","image":"/2024/09/my-multi-streaming-setup/cover_hu_891493d684eb454d.webp","permalink":"/ja/2024/09/my-multi-streaming-setup/","title":"OBS マルチストリーミング奮闘記：不要なトラブル"},{"content":"ある朝、目を覚ますと受信トレイに見慣れないメールが届いており、韓国から自分のメールアドレスでログインがあったと通知されていました。最初は誤検出かと思い気にしませんでしたが、その後も発信元IPが毎回異なるメールが継続的に届くようになり、さすがに問題が発生していると認識しました。対策を取らなければ、自分のメールアカウントが迷惑メール送信に悪用されかねません。そこで、すぐにドメインの MX、SPF、DMARCレコードを削除し、新しい解決策を探すことにしました。\nもともとはパスワードを変更したかったのですが、大手中国プロバイダの管理画面ではパスワード変更の導線が非常に分かりづらく、結局見つけられませんでした。こんなことで手間取るくらいなら、いっそサービス自体を移行しようと思い、この構築記録を書くことにしました。\n本記事では、防火壁ポートの解放から配信成功率の最適化まで、docker-mailserver を使ったメールサーバ構築の実体験をまとめています。これから構築される方の参考になれば幸いです。\ndocker-mailserver 構築前の準備 ファイアウォールの設定 まずはメールサーバに必要な主要ポート（25、143、465、587、993）をファイアウォールで開放します。OSやディストリビューションによって操作が異なりますが、例えば Ubuntu で UFW（Uncomplicated Firewall）を使う場合は以下の通りです。\nufw allow 25 ufw allow 143 ufw allow 465 ufw allow 587 ufw allow 993なお、私の環境では UFW だけでなく、To Fix The Docker and UFW Security Flaw Without Disabling Iptables という設定を併用しています。Dockerコンテナのポートを外部公開する場合には追加の設定が必要です。\n# メールサーバ用ポートの開放 ufw route allow proto tcp from any to any port 25 ufw route allow proto tcp from any to any port 143 ufw route allow proto tcp from any to any port 465 ufw route allow proto tcp from any to any port 587 ufw route allow proto tcp from any to any port 993サーバの構築条件を確認する 多くの格安VPSなどでは、メールサーバ用途に適さない場合があります。世界中のメール大手プロバイダは、Spam 対策の一環として過去にスパム送信履歴のあるIPアドレスを大規模にブラックリスト化しています。もし自分のVPSに割り当てられたIPがすでにスパマーに利用されていたものだと、どれだけ設定してもリモートのメールサーバにメールが一切届きません。それに加え、VPS業者側でメール関連のポート自体を全て封鎖していることも珍しくありません。\n以下のスクリプトで、自分のサーバがメールサーバ運用に適しているか、最低限の通信・受信条件を満たしているかを検査できます。\nbash \u003c(curl -sL IP.Check.Place) 上記チェックでサーバがメールサーバ用に適していない、またはポートが開放されていない場合は、潔くあきらめてよりクリーンで制限の少ないIPアドレスに乗り換えましょう。\n構築手順 設定ファイルの取得 docker-mailserver で必須の設定ファイルは compose.yaml と mailserver.env の２つです。以下で取得できます。\nmkdir mailserver \u0026\u0026 cd mailserver sudo apt install wget wget -O compose.yaml \"https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/compose.yaml\" wget -O mailserver.env \"https://github.com/docker-mailserver/docker-mailserver/blob/master/mailserver.env\"必要に応じて各種設定を変更します。私のケースの例は以下です。\nPOSTMASTER_ADDRESS=webmaster@l3zc.com TZ=Asia/Shanghai SSL_TYPE=manual SSL_CERT_PATH=/certs/cert.crt SSL_KEY_PATH=/certs/cert.keyCaddy でTLS証明書の準備と自動管理1 すでに Caddy を導入済みのため、証明書の自動取得はCaddy側で完結させることにしました。公式ドキュメントに従い、Caddyfile にサブドメイン設定を追加すればCaddyが自動で証明書を更新・管理してくれます。\nmail.example.com { tls internal { # これは内部用証明書を生成する設定です key_type rsa2048 } # Optional, 証明書取得動作確認用レスポンス例 respond \"Hello DMS\" }ただし、私の環境は少し特殊で、Caddy の自動取得機能ではなく Cloudflare Origin 証明書（15年有効なワイルドカード証明書）を使っています。この場合、Caddy は該当サブドメインに対して証明書ファイルがあれば新たに証明書を発行しません。そのため、Cloudflare Origin Certificate とCaddyによる証明書自動管理は基本的に併用できません。結局、dns.providers.cloudflare モジュールを追加し、Caddy でLet’s Encryptを使ったドメインごとの自動更新運用に切り替えました。手動管理が不要になるぶん心が軽くなります。\ndns.providers.cloudflare 導入後のグローバル設定例：\n{ acme_dns cloudflare {API_KEY} }Caddy で取得・管理された証明書ディレクトリを docker-mailserver コンテナにボリュームマウントします。\nvolumes: - /home/user/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/yourdomain.tld/:/certs/Caddy を root 権限で動かす場合、証明書の格納先は /root/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/yourdomain.tld/ となります。環境に合わせてパスを調整してください。\n設定ファイルでも /certs/ ディレクトリ以下を参照するよう指定します。\nSSL_CERT_PATH=/certs/cert.crt SSL_KEY_PATH=/certs/cert.key初回コンテナ起動 最初のコンテナ起動時、すぐ（120秒以内）に新しいPostmasterアカウントを作成する必要があります。\ndocker compose up -d docker exec -it setup email add 配信成功率の最適化 DNSレコード設定 Aレコード１つ：名前は任意（以下では仮にmail）、サーバのグローバルIPを指定（Cloudflare利用時は「DNSのみ」運用推奨） MXレコード１つ：Apex ドメイン（@）に対し、mail.yourdomain.tld を宛先に TXTレコード（SPF）：Apex ドメイン（@）用、こちらで生成可能（任意） TXTレコード（DMARC）：名前_dmarc、こちらで生成可能（任意） TXTレコード（DKIM）：名前mail._domainkey、設定手順は後述（任意） DKIM・SPF・DMARC の設定2 DKIM・SPF・DMARCとは何か、簡単に言えば以下の通りです：\nDKIMはデジタル署名方式、SPFは「正規送信サーバ一覧」として働きます。DMARCはDKIM・SPFでの認証に失敗したメールを受信側がどう扱うかを定義する規格です。3\nまずDKIMの鍵ペアをサーバで生成します。\ndocker exec -it setup config dkim生成された鍵のペアは、コンテナのボリューム ./docker-data/dms/config/opendkim/keys/ 以下に保存されます。\nmail.txt をダウンロード（または内容を全てコピー＆ローカル保存）し、Cloudflareのダッシュボード等にインポートすればDKIM設定は完了です。なお、反映にはコンテナの再起動が必要です。4\ndocker compose up -d --force-recreateSPFについては、「送信許可リスト」なので、正規送信サーバが1台だけの場合、DNSには以下のように設定します。\n\"v=spf1 mx ~all\"DMARCは前述のテンプレートジェネレーター等を使って作成します。\nドメインレジストラやDNSプロバイダが独自のガイドやインポート機能を提供している場合（例: Cloudflare）、それを活用するとより簡単に設定できます。\nメールクライアントの設定 あとはご利用のメールクライアントにて、IMAP／SMTPサーバ共に mail.yourdomain.ltd を指定し、「SSLあり」でIMAP:993、SMTP:465ポートを使ってログインすれば利用できます。\nMailTester を活用する これでdocker-mailserverによるメールサーバの一連の構築は完了です。運用前に MailTester で設定全体が正しいかをチェックできます。10/10 のスコアが出れば、配信到達率も非常に高くなります。ぜひご利用ください。\nスコアが10/10でなくても、減点理由ごとに順番に対処していけば段階的に改善できます。焦らず原因を一つ一つ解消しましょう。\nTODO-List WebUI 対応 参考: https://docker-mailserver.github.io/docker-mailserver/latest/config/security/ssl/#caddy\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考: https://docker-mailserver.github.io/docker-mailserver/latest/config/best-practices/dkim_dmarc_spf/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n詳細解説（英語）: https://www.cloudflare.com/learning/email-security/dmarc-dkim-spf/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n公式ドキュメント 参照。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-09-06T11:57:18+08:00","image":"/2024/09/docker-mailserver-deployment-recap/docker-mailserver_hu_a649605529f354c4.webp","permalink":"/ja/2024/09/docker-mailserver-deployment-recap/","title":"docker-mailserver メールサーバの構築記録"},{"content":"私の Firefish インスタンスは昨年の11月に構築されましたが、使用しているデータベースのバージョンは当然最新ではありません。具体的には、5年前のPostgresに基づいたPGroonga 12という古いバージョンです。将来の互換性やセキュリティの問題を避けるため、またパフォーマンスを向上させるために、今日はこのデータベースをアップグレードする必要があります。\nDockerで稼働しているデータベースをアップグレードするのは、他のDockerコンテナをアップグレードするのとは大きく異なります。新しいイメージをプルするだけでは終わりません。Postgresはほぼ毎回メジャーバージョンでBreaking Changesがあり、旧バージョンと新バージョンで生成される永続化ファイルは互換性がありません。新しいイメージを直接プルして実行すると、データベースは起動しません。そのため、データを移行するための手段を講じる必要があります。\nPostgresには公式のアップグレードツールpg_upgrade1がありますが、今回は使用しません。私のデータベースは1年以上稼働しており、しかも5年前の古いバージョンを使用しているため、このツールを使って問題が発生しないか確信が持てません。この移行では、SQLをエクスポートしてから新しいバージョンにインポートするという大まかな手順を取ります。\nアップグレード前のデプロイ状況 以下はアップグレード前に知っておくべき設定情報です：\n項目 設定 インスタンスのデプロイ方法 Docker Compose データベースコンテナ名 firefish_db アップグレード前のデータベースコンテナイメージ groonga/pgroonga:3.1.9-alpine-12-slim データベースユーザー example-firefish-user データベース名 firefish Docker Composeのデータベース部分は以下の通りです：\ndb: restart: unless-stopped image: groonga/pgroonga:3.1.9-alpine-12-slim container_name: firefish_db networks: - calcnet env_file: - .config/docker.env volumes: - ./db:/var/lib/postgresql/data healthcheck: test: pg_isready --user=\"${POSTGRES_USER}\" --dbname=\"${POSTGRES_DB}\" interval: 5s timeout: 5s retries: 5現在のデータベースのエクスポート データベースをアップグレードする前に、まずFirefishのオーケストレーションを停止します：\ndocker compose downデータベースコンテナを単独で起動し、現在のデータベースをSQLとしてエクスポートします：\ndocker compose up -d db docker exec -it firefish_db pg_dumpall -U example-firefish-user \u003e backup.sqlFirefishのデータベースは比較的大きいため、エクスポートプロセスにはかなりの時間がかかる可能性があります。例えば、私の個人インスタンスでは10分以上かかりました。\nエクスポートファイルの処理 おそらく新しいバージョンのPostgresの認証方法が変更されたため、以前エクスポートしたbackup.sqlファイルを新しいデータベースに直接インポートすると、新しいデータベースの認証スキームが変更され、その後Firefishがデータベースに接続する際に認証に失敗します。この問題を避けるためには、現在のbackup.sqlファイルを処理し、firefishデータベースの部分のみを抽出し、すべてのデータを直接インポートしないようにする必要があります。2\n#!/bin/bash [ $# -lt 2 ] \u0026\u0026 { echo \"Usage: $0 \"; exit 1; } sed \"/connect.*$2/,\\$!d\" $1 | sed \"/PostgreSQL database dump complete/,\\$d\"上記の内容でシェルスクリプトを作成し、script.shとして保存して、現在のbackup.sqlを処理します：\nnvim script.sh # またはお好みのエディタ chmod +x script.sh ./script.sh backup.sql firefish \u003e\u003e upgrade.sqlすべてが順調に進めば、現在のディレクトリにupgrade.sqlという名前のファイルが作成されます。これを開いて、正しくエクスポートされたか確認してください。\n新しいデータベースに既存データをインポート docker-compose.ymlを修正します：\ndb: restart: unless-stopped image: groonga/pgroonga:3.2.2-alpine-16-slim # 最新のコンテナ container_name: firefish_db networks: - calcnet env_file: - .config/docker.env volumes: - ./database:/var/lib/postgresql/data # この行の変更に注意 healthcheck: test: pg_isready --user=\"${POSTGRES_USER}\" --dbname=\"${POSTGRES_DB}\" interval: 5s timeout: 5s retries: 5データベースディレクトリのマッピング設定が./db:/var/lib/postgresql/dataから./database:/var/lib/postgresql/dataに変更されていることに注意してください。これは、新しいデータベースに新しいスタートを与えつつ、古い永続化データを保存するためです。問題が発生しても、古いデータベースにいつでも戻すことができます。\n新しいコンテナをプルして起動します：\ndocker compose pull docker compose up db -dupgrade.sqlを新しいデータベースにインポートします：\ncat upgrade.sql | docker exec -i firefish_db psql -U example-firefish-user -d firefishデータベースのサイズに応じて、インポートプロセスも長時間かかる可能性があります。\n仕上げ作業 インポートが完了したら、全体のオーケストレーションを起動します：\ndocker compose stop db docker compose upインポート後の最初の起動では、-dパラメータを使用しないことをお勧めします。パラメータなしで起動し、起動プロセスに問題がないことを確認した後、-dパラメータで再起動してください。\n最後に、新しく起動したFirefishインスタンスにログインし、データが損失していないか確認します。問題がなければ、作業完了です🎉\n公式ドキュメント：https://www.postgresql.org/docs/current/pgupgrade.html\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n参考：https://thomasbandt.com/postgres-docker-major-version-upgrade\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-08-30T12:45:12+08:00","image":"/2024/08/upgrading-firefish-database-docker/cover_hu_c0ecfda1e4670195.webp","permalink":"/ja/2024/08/upgrading-firefish-database-docker/","title":"Firefish データベースアップグレード記録"},{"content":"前回の記事こちらで、Aria2を使ったBTオフラインダウンロードサーバーを構築したことを紹介しました。Caddyをリバースプロキシとしてデプロイするために、以前一括スクリプトでデプロイしたTrojanをアンインストールしました。理由は簡単で、そのスクリプトがポート80と443を占有していたため、アンインストールしないと続行できなかったからです。\nその結果、オフラインダウンロードサーバーは構築できましたが、時々必要なプロキシはオフラインにせざるを得ませんでした。少し考えた後、以前見たCloudflare + V2Ray + WSでブロックされたVPSを復活させる方法を思い出しました。WebSocketを使用しているので、Cloudflareでリバースプロキシすることができるなら、Caddyでも同様にできるはずです。さらに、Caddyは自動TLSを提供しており、Nginx + Certbotの組み合わせよりも設定が簡単です。設定が成功すれば、Caddyのためにポート443を確保しながらプロキシを実行できます。\nVLESSとCaddyのインストール VLESSのインストールはv2fly/fhs-install-v2rayのワンクリックスクリプトを使用して行えます：\n# 実行ファイルと.datデータファイルのインストール bash \u003c(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)Caddyのインストールについては公式チュートリアルを参照してください。例えば、私はDebian 12を使用しているので、以下のコマンドを使用します：\nsudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddyVLESSの設定 /usr/local/etc/v2ray/config.jsonを編集します：\n{ \"log\": { \"access\": \"/var/log/v2ray/access.log\", \"error\": \"/var/log/v2ray/error.log\", \"loglevel\": \"warning\" }, \"inbounds\": [ { \"port\": 1234, // 任意のポート \"listen\": \"127.0.0.1\", \"protocol\": \"vless\", \"settings\": { \"clients\": [ { \"id\": \"super-random-uuid\", // ランダムに生成されたUUIDに置き換えてください \"level\": 0, \"email\": \"example@example.com\" } ], \"decryption\": \"none\" }, \"streamSettings\": { \"network\": \"ws\", \"security\": \"none\", \"wsSettings\": { \"path\": \"/\" // 後のCaddyの設定と一致させる必要があります } } } ], \"outbounds\": [ { \"protocol\": \"freedom\" } ] }編集後、保存して終了します。\nCaddyの設定 好きな場所にCaddyfileを作成するか、既存のCaddyfileを編集し、VLESS設定ファイルで設定したポートをリバースプロキシするために以下の内容を追加します：\nyourdomain.com { # 指定されたパスのWebSocketリクエストをすべてマッチさせるMatcherを使用 @websockets { path / # VLESSのpathと一致させる必要があります header Connection Upgrade header Upgrade websocket } reverse_proxy @websockets :1234 }これで、サーバー側のすべての設定ファイルが編集されました。\nサービスの起動 VLESSを起動し、起動時に自動的に開始するよう設定します：\nsystemctl enable v2ray \u0026\u0026 systemctl start v2rayCaddyを起動またはCaddyの設定を更新します：\ncaddy start caddy reload # 設定を更新する場合以上の操作がすべて完了すると、CaddyでVLESSをリバースプロキシする設定が完了します。\nクライアント設定 クライアント側の設定は手動で行う必要があります：\nアドレスはVLESSにバインドされたドメインです。 ポートは443です。 TLSを有効にします。 トランスポート方法はWebSocketを選択します。 UUIDはVLESS設定ファイルに入力したUUIDです。 ほとんどのクライアント設定は似ています。Clashの設定ファイルについては、Mihomoドキュメント1を参照してください。以下は私のサンプル設定ファイルです：\nproxies: - name: \"A Random Name\" type: vless server: yourdomain.com port: 443 udp: true uuid: super-random-uuid flow: xtls-rprx-vision packet-encoding: xudp tls: true servername: yourdomain.com alpn: - h2 - http/1.1 skip-cert-verify: false network: ws smux: enabled: falseClashの設定ファイルを生成するには、V2RaySEが提供するツールを使用できます。\n完成 これでVLESSサーバーが構築され、Caddyは自動的にTLS証明書を取得および維持してくれますので、非常に便利です。\nちょっとした手間で、かつてSSRを一括スクリプトで構築したときの喜びを再び感じることができました。google.comをスムーズに開くことができる興奮を楽しんでください。\nTODOリスト 基本設定 カモフラージュ 結局のところ、Clash Metaの遺産を受け継いだMihomoもClashの正統な後継者と見なされます。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-08-13T16:24:26+08:00","image":"/2024/08/caddy-vless-proxy/cover_hu_1cd20ddda32e23a.webp","permalink":"/ja/2024/08/caddy-vless-proxy/","title":"中国のネット封鎖を突破：CaddyでVLESSをリバースプロキシ"},{"content":"安い VPS をいくつか購入してから、手に余った Azure の学生向けマシンが一台あります。Trojan を動かす以外には特に用途がありません。ちょうど最近 BT 資源をダウンロードしたいと思っていたところ、国内の BT 環境については言わずもがなでしょう。そこで、このほぼ遊んでいるマシンを使って BT の离线ダウンロードを行うことにしました。\nまず声明します。すべての BT ダウンロード行為において、著作権侵害のクレームを受けるリスクは自己責任で負う必要があります。\nAria2 のインストール 「インフラ」ではないソフトウェアの場合、私は Docker コンテナを引っ張ってくる方案を好みます。今回は、修正済みの Docker コンテナである P3TERX/Aria2-Pro-Docker1 を採用しました。Docker コンテナのデプロイ手順はどれも同じです。まず docker-compose.yml を編集し、docker compose up ですべてのコンテナを起動し、最後に露出しているポートをリバースプロキシするだけです。\n私の docker-compose.yml は以下の通りです2：\nservices: Aria2-Pro: container_name: aria2-pro image: p3terx/aria2-pro environment: - PUID=65534 - PGID=65534 - UMASK_SET=022 - RPC_SECRET=replace-me # この行を変更してください - RPC_PORT=6800 - LISTEN_PORT=6888 - DISK_CACHE=64M - IPV6_MODE=false - UPDATE_TRACKERS=true - CUSTOM_TRACKER_URL= - TZ=Asia/Shanghai volumes: - ./aria2-config:/config - ./aria2-downloads:/downloads network_mode: bridge # IPV6 ネットワークが必要な場合は、host モードも利用可能です ports: - 6800:6800 - 6888:6888 - 6888:6888/udp restart: unless-stopped # ログでディスクがいっぱいになるのを防ぐ logging: driver: json-file options: max-size: 1m # 他のパネルを使用することも可能です AriaNg: container_name: ariang image: p3terx/ariang command: --port 6880 --ipv6 network_mode: bridge ports: - 6880:6880 restart: unless-stopped logging: driver: json-file options: max-size: 1mCaddy によるリバースプロキシ 以前のリバースプロキシは Nginx ベースの方案を使っていましたが、このところ Caddy に関する好評が絶えません。今回は Caddy に乗り換えました。もちろん、新しいもの・新技术を試したいという理由もあります。\nCaddy の使い方は本当にシンプルで、初心者にも非常に親切です。例えば、よくある本机の特定ポートへのリバースプロキシなら、Caddyfile は 3 行で搞定です。\ndomain.com { reverse_proxy :1234 }Caddy のインストールは公式ドキュメントを参照してください。例えば、私のサーバーは Debian を使用しているため、以下のコマンドでインストールします。\nsudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install caddyインストール完成后、防火墙和从服务商策略组的 80 和 443 端口を開放するのを忘れないでください。\n域名プロバイダー側でバインドする域名をサーバーに向ければ、Caddyfile の作成を開始できます。3 つのポートをリバースプロキシする必要があります。それぞれ用途が異なります。私の Caddyfile は以下の通りです。\n# Aria-NG パネル download.l3zc.com { reverse_proxy :6880 } # Aria2 API arapi.l3zc.com { reverse_proxy :6800 } # Alist downloaded.l3zc.com { reverse_proxy :5244 }これほど簡潔な設定ファイルを見ると、Nginx に比べて Caddy は本当に使い心地が良いと感じずにはいられません。設定を書き込んだら、Caddy を再起動3 します。すると、Caddy が自動的に SSL 証明書を申請し、HTTPS を設定してくれる絶賛の過程を眺めることができます。これで、リバースプロキシの部分は完了です。\nAria-NG の設定 Aria-NG はフロントエンドパネルに過ぎず、任意の Aria2 バックエンドと通信できます。そのため、Aria-NG に設定情報を提供する必要があります。先ほどリバースプロキシした Aria-NG パネルにアクセスし、AriaNG 設定に移動して設定情報を入力します。\nRPC アドレスは先ほどリバースプロキシした RPC アドレスです。プロトコルは HTTPS、リクエスト方法は POST、RPC 秘密鍵は docker-compose.yml の replace-me を置き換えた値です。\n「Aria2 状態」の隣に「已接続」が表示されれば、設定は正確です。\nAlist によるダウンロードディレクトリのマッピング Alist でダウンロードディレクトリをマッピングし、サーバー上にダウンロード済みのファイルをより簡単に閲覧・管理・ダウンロードできるようにします。Alist も Docker でデプロイします。Alist 自体はコンテナ内で実行されるため、コンテナ外のファイルにアクセスできません。デプロイする際、Aria2 のダウンロードディレクトリを事前に Alist のコンテナ下にバインドする必要があります。\n私の docker-compose.yml は以下の通りです。\nservices: alist: image: \"xhofe/alist:latest\" container_name: alist volumes: - \"/etc/alist:/opt/alist/data\" - \"/home/azureuser/aria2/aria2-downloads:/aria2-downloads\" # ここは状況に応じて自身のディレクトリをバインドしてください ports: - \"5244:5244\" environment: - PUID=0 - PGID=0 - UMASK=022 restart: unless-stoppedAlist を初めて起動すると、admin ユーザーのパスワードがランダムに生成されます。そのため、この編成を初めて起動する際は、-d パラメータを付けずに直接 docker compose up し、コンテナ起動後の出力を妥善に保存しておくのがベストです。うっかり管理者パスワードを保存し忘れた場合、以下のコマンドでランダムに再生成できます。\ndocker exec -it alist ./alist admin randomAlist にログイン成功したら、ディレクトリのマウントを開始できます。\nドライバーは「ローカルストレージ」を選択し、マウントパスに注意してください。私の編成では、コンテナ外の /home/azureuser/aria2/aria2-downloads ディレクトリをコンテナ内の /aria2-downloads にマウントしているため、マウントパスは /aria2-downloads はずです。\n完了 現在、すべてのサービスがデプロイされオンラインになりました。AriaNG を開いてダウンロードタスクを追加でき、ダウンロード済みのファイルは Alist を開いて閲覧・ダウンロード・オンライン視聴できます。\nこのサービスを構築する前に、VPS プロバイダーの利用規約を仔細に確認し、BT ダウンロード行為が違反にならないことを確認してください。また、ルクセンブルクなど少数の国/地域を除き、DMCA で保護された資源をダウンロードするとクレームを受ける可能性があり、これらのリスクは自己責任で負う必要があります。\nどうせこの Azure の学生機は無料枠で使っているものですし、クレーム来て回収されても構いません。とにかく、今は余計なことを気にせず、資源を探す快乐を享受できます。\nもちろん SuperNG6/docker-aria2 を試してみてもいいです。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n原作者の docker-compose.yml を参考にしました。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\ncaddy stop と caddy start、Caddy 文档 を参照。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-08-10T15:46:40+08:00","image":"/2024/08/aria2-downloading-server/cover_hu_935547325c8335d7.webp","permalink":"/ja/2024/08/aria2-downloading-server/","title":"BT 离线下载サーバーを構築する"},{"content":"長沙は本当に素晴らしい場所です。三方を山に囲まれており、唯一の開口部が北側にあり、洞庭湖に面しています。冬は冷たい空気が容易に流入し、夏は暑い空気がなかなか逃げず、南方特有の湿気と合わさって体感温度はさらに厳しくなります。冬はとても寒く、夏はとても暑いです。\n最近の暑さには耐えられず、山へ水遊びに行って涼を取ることにしました。\n目的地 今回訪れる場所は芦溪村七仙殿という名前で、長沙と岳陽の境界に位置し、岳陽が管理しています。長沙市区からは80キロ余り、車で2時間かかりますので、出発前には十分な時間を確保する必要があります。例えば、午後一杯です。\n長沙で長く暮らしていますが、市内のほとんどの場所には行ったことがありますが、郊外のこのような野外スポットの名前は聞いたことがありませんでした。今回この場所を知ったのは、父がTikTokを見ていたときにここが推薦されたからです。さて、目的地が決まりました。平日の午後、昼食を食べた後、出発しました！\n長沙市区から七仙殿へのドライブでは、一般的に2つのルートがあります。一つは武深高速道路を一部利用するルート、もう一つは国道と田舎道だけを通る純粋なルートです。距離がそれほど遠くないため、高速道路を使うと片道で約20分の時間が節約できます。どちらを選ぶかは個人の判断によります。現在私は夏休み中で時間がたっぷりあるため、国道と田舎道を通るだけで十分です。\n田舎道をほぼ2時間走り、ほとんどの時間は速度が50から60キロの間で揺れ動きます。これが田舎道の魅力だと思います──平坦で単調な高速道路とは異なり、曲がりくねった道とユニークな景色が楽しめます。一方の手でハンドルを握り、もう一方の手で冷蔵庫から取り出したばかりの飲み物を持ち、視界が広がり、日差しは強烈明るい──冷蔵庫は後で取り付けた車載冷蔵庫で、車のシガレットライターの電源で簡単に動かせます。冷たい飲み物を飲みながら、田舎の景色を楽しみ、運転は快適です。対照的に、高速道路では車の流れが少ないときはまだましですが、少し退屈です。車の流れが多くなると、集中して運転する必要があり、余裕はありません。\n冷水井 山間部に入ると、目的地に近づくと、一つの寺院が目に入ります。壁には「冷水井」という額が掲げられています。この井戸は伝説の神仙の泉水で、信仰が厚く、この井戸の名前を長く聞いていましたが、こんなに人里離れた場所で出会うとは思いませんでした。すぐに車を停めて、車の後ろに既に用意してあったバケツを取り出し、井戸の前でひざまずいて礼を尽くし、水を汲み始めました。礼を尽くして水を汲む人が絶え間なく訪れ、井戸の前は常に賑わい、バケツも長い列ができていましたが、幸いなことに水を汲むスピードは速く、その日は人が少なかったので、待つことはあまりありませんでした。\n寺院内のLEDスクリーンでは、功徳榜1と井水が「霊験あらたかである」というエピソードが交互に表示されます。例えば、ある人が病院である種の癌と診断され、不治の病とされていましたが、井水を飲んだ後、どのように改善され、最終的に回復したかという話です。上にある話が本当か偽りか、本当に井水が霊験あらたかであるのか、それとも他の理由があるのか、ここでは議論しません。これは地元の神の井戸ですから、真偽にかかわらず、私は地元の風習に従い、敬意を表して礼を尽くします。\n井戸で水を汲むのには料金が必要で、価格はそれほど高くありませんが、以前は井水が一般に公開され、道具も提供されていましたが、現在は料金が必要です。それでも、ピーク時にはバケツの長い列が寺院の外まで続きます。列に並ぶ時間は、5〜6時間に延長されることもあります。\n七仙殿 もう少し進むと、野を越えて目的地の七仙殿に到着します。ここは連続する滝があり、各滝の下には水槽があります。水は山の泉水で、非常に冷たいです。ただし、道を選ぶ際には注意が必要です。滑りやすい岩が多く、注意しないと滑って落ちてしまうこともあります。特に注意してください。父が滑って水槽に落ちた後、想像もできない事態になりました。\n2時間のドライブの後、ようやく到着しました。すぐに水着に着替えて、水の中で涼を取ります。この野外スポットは週末にも人で溢れかえりますが、みんな食べ物を持って来て、ここで水遊びやピクニックを楽しんで、一日中過ごすことができます。しかし、彼らが去った後に残されたゴミの山は本当に景観を損ないます。\n水はそれほど澄んでいなくても、実際に涼しく感じます。水に入るときは本当に緊張しましたが、最後には思い切って飛び込みました。その後は水遊びを楽しみ、飛び込み、泳ぎ、頭を洗い、暑さが和らぎました。意外な発見は、ここにはたくさんの小魚がいることでした。水に潜ってよく見るまで、そんな小さな生き物がいることを知りませんでした。人を見ると逃げるので、私が魚ではないので、魚がそうする意味を推測することはありません。\n私のスマートフォンはIP68等級の防水機能を持っており、理論上は水中撮影に対応していますが、普段は「防水は手が届かない」という考えを持っており、実際にこのスマートフォンを水に持ち込むことはありません。今回は例外として、水中での撮影を一度許可しました~~（スマートフォンを変えたいから）~~。現時点で、私のスマートフォンは正常に機能しています。\nここで夫婦にも出会いました。私たちが到着したとき、彼らはすでに2時間以上水に浸かっていたと言っていましたので、ついでに彼らの飛び込みのビデオを撮ってあげました。\nYour browser doesn't support HTML5 video. Here is a link to the video instead. 同じ道を行く人に出会うのもなかなか良いものです。\nここでは水温が比較的低く、約23度です。冷たい水に長時間いるのは適していません。長く遊んだ後は、熱量を補給することに注意してください。\n仕事を終えて、家に帰る 水の中に2時間浸かって、本当にすっきりと暑さを解消しました。もう浸かりたくなくなった後は、すぐに荷物をまとめて家に帰りました。この時の熱消費と解消した暑さのおかげで、家に帰ると食欲が湧き、たくさんのご飯を食べました。\nここ数年の感じでは、毎年の夏が前年よりも暑くなっています。この点から見ると、地球温暖化は私たちを欺かないようです。ヨーロッパの人々も暑さに耐えられずにエアコンを設置し始めていますが、これほど深刻な問題は軽視できないかもしれません。\n数日間の台風の「エアコンの外機」を吹いて、これからの台風が少しでも正の効果を発揮して、早く来て冷却を助けてくれることを願っています。\n寄付者と彼らの寄付額。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-07-26T17:14:06+08:00","image":"/2024/07/summer-cooling-off-wild-swimming/cover_hu_b2f1244eb71894a1.webp","permalink":"/ja/2024/07/summer-cooling-off-wild-swimming/","title":"夏日の涼み方：水遊びの小話"},{"content":"きっかけ ようやく時間ができて、外に出かけることにしました。\n例年この時期には私たちも旅行に出かけていましたが、当時は防疫政策が転換したばかりで、観光業の状況は封鎖期間とほとんど変わりませんでした。今年は各地の人気観光地が人で溢れかえり、とても賑やかです。マレーシアが中国人にビザ免除をしたことを知り、マレーシアに行く予定でしたが、家族が忙しくて時間が取れず、家族が時間を取れるようになった時には航空券が5000元以上に値上がりしていました。この価格なら、国内で遊ぶ計画を立てる方が良いと思い、初めての計画として厦門と泉州で新年を過ごすことにしました。\nその前に、私が子供の頃に育った場所に一度戻り、家族を訪問する必要がありました。これは私の個人的な用事なので、ここでは詳しくは述べません。\n今回の旅行は昨年のように詳細な計画を立てることはせず、江西省のある都市で中継し、大まかな日程だけを立てました。\n出発 永州：江西ではないが、必ず戻るべき場所 長沙から出発し、まず京珠高速（G4）に乗り、その後泉南（G72）に乗り換え、途中で小さな渋滞を経験し、永州が目の前に現れました。\n七三一九 永州はのんびりとした小さな都市で、生活のペースが非常にゆっくりです。何かをするためには、15分前に出発すれば十分です。この都市は、かつての全市GDPが数百億元しかなく、今でも2000億元程度の地級市であり、私が育った場所です。\nこれはかつて私の家の屋上で撮った写真で、一江の碧水、雲淡風軽、壁を隔てた下の生産区には新しく生産された車がぎっしりと停まっています。当時、長豊獵豹は三菱パジェロのライセンス生産車を製造しており、軍から民間への転用もあり、軍民両方の販売ルートに困ることはなく、非常に潤った日々を過ごしていました。湘江の対岸は永州の中心市街地で、始発駅から12路のバスに乗ると、対岸の学校やショッピングエリアまで行くことができました。当時の長豊獵豹は湖南省で最も優れた自動車企業であり、永州の工場だけでも市のGDPの半分以上を占めていました。しかし、一連の出来事がこの国有企業を2021年に破産申請に追い込んだのです。これは後の話です。\n残念ながら、このような景色は永遠に消えてしまいました。今回戻ってみると、川辺の駐車場として使われていた土地には30階以上の高層ビルが建っており、私が住んでいた小区も将来取り壊され、あるいは「人材住宅」や「福利住宅」に改装されるという話が出ています。私が離れている間に、多くのものが静かに変わってしまいました。\n浜江公園 浜江公園は冷水滩の中山公園で、私が子供の頃に遊んだ場所でもあります。夜に散歩に出かけ、ついでにいくつかの写真を撮りましたが、あまり意識して撮ったわけではありません。今となっては、もっと昼間に撮っておけばよかったと少し後悔しています。何しろ10年以上も戻っていなかったので、公園の木々は当時はまだ小さな苗木でしたが、今では立派な並木道を形成しています。当時の若い木々は、今では大きな木に成長しています。\n川沿いには24時間自動図書室が設置されており、環境はもちろん良く、景色も素晴らしいです。ただし、内部の書籍は期待外れでした。本棚が一つしかない中から適当に一冊取り出してみると、印刷が乱れていて、思わず笑ってしまいました。\n零陵古城 画図曾識零陵郡，今日方知画不如。\n——欧陽修\n欧陽修は零陵郡を非常に高く評価しています。観光に関して言えば、永州の資源は決して悪くありませんが、うまく開発利用されていない上、隣には桂林という重量級の観光地があるため、今日の永州はあまり知られていません。\n零陵古城は永州が近年開発したもので、現在は外地からの観光客はほとんどいません。外地からの観光客がいないため、個性的な店が生き残れず、雰囲気が作り出せず、結果として外地からの観光客がますます来なくなるという悪循環に陥っています。現在の零陵古城は主に地元の人々の商業集積地（中心とは言えません）であり、観光客が消費できる店はほとんどありません。しかし、古い街並みは本物であり、写真を撮るには非常に良い場所です。\nここで永州の飛行禁止区域について文句を言わざるを得ません。零陵空港の空域保護区域が永州の市街地全体を覆っているため、市街地にいる限り、ドローンを飛ばすには事前に解除申請をしなければなりません。零陵空港のフライト数は非常に少ないにもかかわらず。\n柳子庙は一見の価値があります。内部はほぼ小さな博物館のようです。\n文化大革命時期でも革命委員会によって保護された文物は、普通の文物とは言えません。当時の永州はまだ零陵地区であり、20世紀80年代になって初めて永州市に変わりました。文物保護単位と革命委員会の署名が同じ石碑に刻まれているのを見ると、違和感を覚えます。\n零陵武庙 永州武庙は長江以南で最大かつ最も地域色豊かな武庙です。武庙は関羽を祀っており、洪武年間に建てられ、最後に修繕されたのは光緒年間の古建築です。文化大革命後の廃墟の中で唯一残された貴重な遺産です。「青石の龍鳳柱四本があり、浮彫の雌雄の龍が大きな頭を持ち、口を開けて珠を含み、動き出しそうな勢いで、二雌龍は小龍を抱き、小龍は活発で天真爛漫で、精巧極まりない」とされています。これは現存する数少ない古代の彫刻芸術の逸品です。1\n実際に見てみないと、当時の精巧な彫刻技術を想像するのは難しいです。\n「発展しないことが最大の発展」 千山鳥飛絶，万径人踪滅。\n孤舟蓑笠翁，独釣寒江雪。\n——柳宗元《江雪》\n柳宗元が永州に左遷された時、多くの素晴らしい文章を残しました。『江雪』の他にも、『永州八記』の『小石潭記』や『捕蛇者説』などが教科書に選ばれたことがあります。柳宗元は水、木、魚、石の描写が非常に生き生きとしており、詳細です。彼が『愚溪詩序』で言ったように「清莹秀澈，锵鸣金石」と述べています。柳宗元は永州の山水の中で自分の精神的な寄り所を見つけ、彼が書いたこれらの文章は、うまく処理すれば「桂林山水甲天下」のような強力な無料の観光広告になることができます。\n他の人と永州について話すとき、私が最も好きな言葉は「工業が必要なら、工業はうまくいっていない。観光が必要なら、観光も成功していない」です。現在の永州は非常に中途半端で、良い山水を持っているにもかかわらず、隣には世界級の観光地である桂林があります。かつての市の工業の支柱企業は今や破産に追い込まれています。今の永州には何か誇れるものが残っているのか、私には思い浮かびません。\n地元の人々には「永州は発展しないことが最大の発展だ」という言葉がよくあります。一城の良い山水を守り、都市を精緻で清潔で「悠々自適」にすることが永州の最大の発展だと。\n南昌：長江中流地域の「重要な」中心都市 武漢、長沙、南昌の距離はほぼ同じで、三つの都市が長江中流都市群を形成しています。私は長沙に常駐しており、武漢にも何度も行ったことがありますが、南昌には一度も行ったことがありませんでした。今回、長江中流都市群のすべての都市を訪れることができました。\nネット上では「環江西」という言葉が流行っています。例えば「環江西経済圏」や「環江西5G示範帯」などです。現代の江西の経済は周辺の省に比べて確かに遅れています。この現象の原因は多く、ネット上には詳しく説明している動画や記事がたくさんあります2。ここでは詳しくは述べません。南昌の印象は「10年前の長沙のようだ」と感じました。\n湖南よりも辛い 湖南と江西は全国で最も辛いものを食べる二つの省ですが、どちらが一番辛いかと言えば、江西が二番目なら湖南は一番とは言えません。そう、江西は本当に湖南よりも辛いのです。\n湖南人は実際には江西人であり、元朝時代の「江西填湖広、湖広填四川」3により、湖南人の祖籍は多くが江西から来ています（私も含めて）。辛さに関して言えば、江西の「微辛」は本当に辛いです。私の主観的な感覚では、江西の微辛は湖南の中辛に近いです。\n江西省博 博物館はその省の古代文化の窓口として、訪れる価値があります。\n江西省博は全体的に非常に大きく、立派ですが、展示されているものが少ない印象を受けました。これは無理もありません。江西は湖南の馬王堆漢墓の辛追夫人などの世界的な遺産を持っているわけでもなく、湖北のように古代楚国の経済政治文化の中心でもありません。湖南、湖北両省の博物館を見た後に江西省博物館を見ると、「沧海を経て水を難しとする」という感覚を覚えます。\n江西省博の展示は、古代の青銅器などの一般的なものの他に、彼らの省の特色があります。江西の井岡山は中央ソビエト区として、多くのソビエト政権活動の痕跡を残しています。また、江西は歴代の重要な陶器製造業の中心地であり、多くの古今の陶器が展示されており、非常に特徴的です。\n滕王閣 Your browser doesn't support HTML5 video. Here is a link to the video instead. 物華天宝、人傑地霊、雄州霧列、俊采星馳。『滕王閣序』は古代江西の輝きを極限まで表現しており、江西の古代の繁栄の半分は滕王閣にあります。\n最も「江西らしい」都市ではない 江西で最も「江西らしい」都市と言えば、私が最初に思い浮かべるのは南昌ではなく贛州です。南昌の存在感は非常に低いです。京九鉄道の終点はもともと江西の九江に計画されており、江西の代表的な古城は間違いなく贛州古城です。江西省の発展戦略も、最近までは九江と贛州の発展に重点を置いていました。「千城一面」の今日、南昌は本当に「江西らしくない」です。結局、それは存在感のない省都です。\n宜春：温泉に浸かる どうして宜春という場所を知っているのか？答え：高速道路の広告で見たからです。ここは「富硒温泉」と呼ばれ、世界で唯一、または世界で二つしかないと言われています。とにかく、温泉に浸かることが目的であり、世界唯一かどうかは関係ありません。温泉は常に70度前後を保ち、毎日2万トンの温泉水が湧き出し、硒を豊富に含み、硫黄の含有量が低く、温泉療養の絶好の場所です。\nホテルのシャワーも温泉水であり、欠点は温度が安定しないことです。本当に温泉水なのか、どれだけ加熱された水が混ざっているのかは分かりません。このように考えると、このバスタブ付きのホテルは半分のプライベート温泉のようなものです。しかし、バスタブの水はなぜか非常に少なく、温泉チケットも付いているので、正規の温泉に行った方が良いでしょう。山頂のいわゆる無限プールも温泉水ですが、水位が足りないために有限プールになってしまい、少しがっかりしました。ここは空気が非常に清新で、「負イオン」の含有量が高いと言われていますが、この言葉がどれほど信頼できるかは分かりません。\n温湯町にある常に70度の古井戸は、無料で一般に開放されており、非常に興味深い文化が形成されています。ここではこの水温が最適な用途として……足湯が挙げられます。町の人々は、年齢を問わず、毎日バケツを持って古井戸に来て、適温の富硒温泉水を汲み、井戸の周りや近くの長い亭に座り、一緒に足湯をしながらおしゃべりを楽しみます。もし水が冷たくなったら、それを捨てて新しい水を汲み、満足するまで足湯を続けます。ここで足湯を楽しむ人々が足の病気にかかることは絶対にないでしょう。\nここでのホテルは春節の間でも料金の値上げ幅が大きくありません。もともと料金が高いのかもしれませんが、ここで数日間滞在するべきだったと感じました。\n泉州や厦門に行く予定はどうなったのか？ 泉州や厦門に行かなかった理由は……\n参考：百度百科\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nこの動画を見てください：https://www.bilibili.com/video/BV1mw411C7RL\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nこの歴史についてはウィキペディアと湖南日報を参照してください。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-02-18T14:20:47+08:00","image":"/2024/02/2024-new-year-trip-archive/cover_hu_13f375941587768a.webp","permalink":"/ja/2024/02/2024-new-year-trip-archive/","title":"予定外の「不完全な江西旅行」"},{"content":"「年間振り返り」という文字を書いている今の気分は、たぶん「独り悲しみに沈んで涙がこぼれる」といったところだ。ほとんど書き終えていたはずの年末総括も、マイコプラズマ感染と試験のプレッシャーのせいで危うく未完に終わるところだった。この年末総括を書き上げられただけでも、かなり大変だった。\n2023年は苦しい一年だった。年初の感染の波をどうにかやり過ごし、登校して前学期に終わらなかった期末試験を受け、課題制作をこなし、自分の心理状態や精神状態を立て直し、悪くなっていく一方の世界を見つめ……そんなふうに、私は苦しみながら自分の生活を続けていた。この一年をどうにか生き延びられたのは、たぶん本当に、人間が生き続けようとする本能だけだったのだと思う。\nみなさんがこの一年をどう過ごしたのか、私にはわからない。でも、生きているだけで十分だ。\n学業 人生に、見事にからかわれたような気分だ。\n大学に入って以来、私の学業はずっとうまくいっていない。今年も例外ではなかった。\n夏休みより長い冬休みを過ごしたあと、前学期に感染対策方針の転換による混乱で延期されていた5科目の大きな期末試験が、一気に私たちにのしかかってきた。たぶん何らかの自己防衛機制のおかげで、私の精神はまだ完全には壊れていなかった。当時、ルームメイトの一人はすでにかなり危うい状態になっていて、この爆発的な試験日程がどれほどの圧力だったかがよくわかる。そしてその自己防衛機制のせいで、私は強い精神的プレッシャーの中、ひどく低い効率でしか勉強できず、結果もかなり悲惨だった。大学2年後期には状態を整え、休みながら体力を回復した。平たく言えば――授業に行かなかった。でもそれは何も勉強していなかったという意味ではない。少なくとも試験の成績は、前のひどい学期よりはずっと良かった。だが思わぬことも起きた。組み込みシステムの単位を落としたのだ。まったく理解不能だったが、聞いてみると朝8時の点呼に来なかったせいで平常点を削られたらしい。で、追試では80点を取った。私が教えた別の追試受験者は、丸暗記した定型文で100点を取った。なんとも皮肉な話だ。\n大学3年前期、夏休みを経て、私は心の底から「ちゃんと」勉強しようと思った。今振り返ると、それはあまり良いことではなかった。この考えに加えて、寮の部屋がゲームの音でうるさすぎたこともあり、私はほとんど毎晩図書館へ行っていた。どうやら私は「頑張りすぎた」らしい。そのせいで、昔からの心の傷が再発した。骨身にしみるような痛み、と言っても大げさではない。あの数日、私は図書館で泣き崩れ、部屋に戻ると無理に笑顔を作っていた。そんな心の不調に、行き過ぎた「努力」が重なって、私はすっかり消耗し、もう勉強できなくなった。今になってようやくわかった。今の私の精神状態で図書館で勉強するのは、間違った選択だったのだ。\n振り返ってみると、こういうやり方は、大学1年前期の未熟だった自分が高校時代の勉強法をそのまま持ち込んでいたあの学期とそっくりだ。毎晩図書館へ行くなんて、本当に苦しいわりに効率が悪すぎる。ぐるぐる回ってまた出発点に戻ってきたような感覚は、あまり気分のいいものではない。それでも当時の自分には、それが最善の選択に思えたのも事実で、同じ失敗を繰り返すべきではなかった。\nどうやら私は、あまり力を入れて勉強すること自体が精神的に許されていないらしい。ある限度を超えると、何かしらの防衛機制が働いて神経を麻痺させ、それ以上無理をさせない。今のところ、この制限を破れるのかはわからない。でもこの制限が休めと知らせてくれるのだとしたら、それはそれで悪いことではないのかもしれない。とはいえ、本気で勉強したいときにこうした制限が現れるのは、やはり悲しいことでもある。私は世界でいちばん運の悪い大学生なのかもしれない――期末直前にマイコプラズマ肺炎にかかり、しかも狂ったような時間割のせいで、たった2日授業を休んだだけなのに、また以前と同じように試験勉強をする羽目になった。結局、頑張っても何も得られなかった。入学してからというもの、落とした科目も少なくない。「どれだけ努力しても成績が上がらない」という感覚を、これほど深く味わったことはなかった。もしかすると、以前の自分の愚かな願い事への報いなのかもしれない。そしてここ数年自分が受けてきた苦しみを突き詰めれば、結局のところ、それは自分が下層に属する人間であり、貧しい人間であることへの報いなのだろう。なぜ私がその代償を払わなければならないのか。もし天に意志があるのなら、訴えることはできるのだろうか。\n今学期の電力網計画の課題制作については、別に書く価値があると思う。最初は完成品を買おうとしたのだが、結局はただ授業料を余計に払ったようなものになってしまった。なんとも皮肉だ。そのうちの一人は ChatGPT で適当にごまかしていたのではないかと強く疑っている。結局、私たちは他人なら1か月かかるような作業を1週間で終わらせ、締切に間に合わせるため、部屋の全員で朝5時半まで徹夜して最後の清書作業をした。40ページ以上ある課題レポートを全部手書きしたのだから、なかなか強烈だった。\n健康 去年と比べて、この一年の健康状態に大きな変化はなかった。年初に COVID から回復し、年末にはマイコプラズマ感染にかかったくらいだ。それに加えて、脳神経科の病院で中等度のうつ病と強迫症と診断された。\nうつはたびたび再発する。一方で、強迫症は自分にとってそれほど大きな影響はないと思っている。うつが出ているときは、酒を少し多めに飲んで、あとは休むくらいしか本当に手がない。メンタルヘルスの危機は相変わらず続いていて、この一年は心の古傷の再発が、ある時期に私の気力をすべて奪っていった。\n謎の状態に陥る：\n娯楽を楽しめない。音楽すら聴きたくない\n勉強も進まない。そのくせ試験は次々やってくる\n休息もうまく取れない。眠ることすらできない\nつまり、遊ぶこともできず、勉強もできず、休むことすらできない\n今回の極度の疲弊で、人の気力というものがどれほど貴重か、ようやく思い知った。自分でもわかっている。私の振る舞いは、結局のところ自暴自棄なのだ。私は社会的な支えを必要としている。そんなものを、私はこれまでほとんど持ったことがない。COVID もマイコプラズマも、私の不安とうつを悪化させた。今のこの身動きの取れなさは言葉にしがたいが、どうしようもなく、ただ耐えるしかない。空えずきも出るようになった。たぶん不安症状が強くなったのだろう。少なくとも心理士からは薬物療法を勧められている。\nこの一年、私はずっと自分を治そうとして、外部の支えを求め続けていた。おかしな話だ。人生がここまで人を痛めつけているのに、それでも人間の生存本能はなお、自分を引きずって生き続けさせる。これは人類全体にとっては幸運なのかもしれないが、一人ひとりの個人にとっては悲しみでもある。\n読んだ本 本は変わらない。でも人は変わる。\n読書とは、結局は自分自身を読むことなのだと思う。2023年、私は新しい本も読んだし、とても好きな古い本もいくつか読み返した。こうした古い本は、読むたびにまるで新刊のように感じられる。\n本を1冊読むたびに、その電子版をbooks.l3zc.comにアップしている。もちろん例外もあるかもしれないが、整理してみると、この一年に読んだ文学作品は次の通りだ。\n『豊乳肥臀』（莫言） 『私刑』（梁暁声） 『湘行散記』（沈従文） 『故都の秋（文集）』（郁達夫） 『世界から猫が消えたなら』（川村元気） 『失楽園』（渡辺淳一） 『夏と花火と私の死体』（乙一） 『東京夢華録』（孟元老） 『十錦緞』（方寸光） 『ナミヤ雑貨店の奇蹟』（東野圭吾） 『放課後』（東野圭吾） 『吾輩は猫である』（夏目漱石） 『The Ferryman』（誰が書いたかはともかく） このほかにも、思い出せる範囲のもの以外にウェブ小説やライトノベルをいくつか読んでいるが、ここには載せないことにする。\nすぐにわかるのは、この一年で思い出せる12冊の文学作品の大半が東アジアのものだということだ。欧米圏の作品として唯一挙げられる『The Ferryman』についても、読後の感想は「かなり平凡」、いや「ひどい」と言ってもいいくらいだった。『遣词造句』でも書いたが、私は沈従文や郁達夫、さらには武侠ポルノ小説『十錦緞』の作者・方寸光の中国語表現力にすら強い憧れを抱いている（この作者、本当に文章力が高い）。一方で翻訳作品は、原作者・訳者・出版社のうち誰か一つでも駄目だと、読書体験は一気に悪くなる。だが東アジア文化圏の内部では文化的な共通性が高く、翻訳されても比較的自然で、親しみやすく読める。\nそれでも、私が求めるような文章の力という意味では、今生きている翻訳者の中で、傅雷のように二つの言語を自分の文体まで含めて融け合わせられる人はまだ見たことがない1。そうした翻訳作品も、やはり本土の文学には及ばない。だからこそ、「生まれながらの」本土文学が今なお半分近くを占めているのだろう。\n私は中華民国期の作品が好きだ。文語から口語へ移る過渡期の簡潔さが好きで、あの素朴で原初的な感情が好きだ。中国で大家が出た時代は二つしかない、戦国と民国だ、とよく言われるが、あながち誇張でもない。人々があれほど悠然として素朴な調子で文章を書けたということは、少なくとも二つを意味している。政府の統制がなかったこと、そして収入が快適に暮らせる程度にはあったことだ。この二つは、1949年以降、一度として同時に満たされたことがない。滑稽なのは、今の当局がなお「旧中国」だの「極度の貧困と弱体化」だのと宣伝していることだ。実に恥知らずである。\n『故都の秋』と『湘行散記』を読み終えたあとに書いた言葉\n（追記予定）\n行った場所 年初には長距離旅行を一度した。だいたい滬昆高速に沿って、長沙から麗江まで移動し、途中の多くの都市にも立ち寄った。この旅では虎跳峡を歩き、麗江古城にも長く滞在して、心身を少しは休めることができた。もちろん、帰り道で10時間渋滞にはまった経験は別として。\n8月には武漢にも一度行った。主な目的は、中国産 Galgame の聖地巡礼だった。\n正直に言えば、あまりお金のない学生として、頻繁に長距離旅行をするのは無理だ。私だって世界を見てみたい。でもお金がないし、私のパスポートも大して役に立たない。結局、夢を見るのはそのくらいにして寝るしかない。\n聴いた音楽 音楽は私の生活の大切な一部だ。使っているプラットフォームのどこもまともな年間レポートを出してくれないので2、自分で年間プレイリストをまとめることにした。\nこの一年で「これは」と思ったアーティストは主に Camelia と TAYORI（倚水と言ったほうが通じるかもしれない）だった。前者は高速系の鬼才、後者は J-Pop。星塵3はアップデート後に本当に驚かされて、当然のように何度も繰り返し聴き、私の年間プレイリストにもその記憶が残った。\n「音楽は反社交的だ」という考え方がある。私はかなりそう思っている。普通、友人同士の集まりでみんなで一緒に音楽を聴くだろうか。たぶん聴かない。仮にそういう場面があったとしても、流れるのは大抵、みんなが無難に受け入れられるポップスだ。\nポップミュージックがポップであるためには、いつだって何かしらの犠牲が必要になる。いわゆる「宝物」のような曲に比べれば、どうしてもあの独特さが薄れてしまう。\nこのプレイリストの一曲一曲の裏には、それぞれ何かしらの物語や体験がある。落ち込んでキャンパスを歩くときに耳元で寄り添ってくれた曲かもしれないし、ゲームを少し楽しくしてくれたBGMかもしれないし、通学や移動の時間をやわらかく埋めてくれた旋律かもしれない……ここまで書いて、なぜか言葉が詰まってしまう。うまく表現できない。でも、それらを見ると、初めて聴いたときの驚きや感動を今でも思い出せる。その物語を共有していない他の人には、きっと「平凡な曲だな」としか思えないのだろう。\n私はもう、流行の音楽をあまり聴かなくなった。この一年、自分を驚かせてくれる曲は減った。2021年、2022年の年間プレイリストも自分でまとめたが、それと比べても、今年は選曲がとりわけ難しかった。実際に聴いた曲の質が下がっていたのか。それとも今年のプレッシャーがこれまで以上に大きくて、悪い記憶がたくさん残ってしまったのか。たぶん、その両方だろう。\n遊んだゲーム まずは私の Steam 年間レビュー を見てほしい。\nゲーム活動の大半は Steam 上で行っているので、このレポートはかなり参考になると思う。\n2023年、私のゲーム時間の大半は「車」に関係するゲームに費やされた。Forza Horizon 4 と 5、それから Euro Truck Simulator 2。この3本で200時間ほど遊んだことになる。よく「貧乏人は車で遊び、金持ちは時計で遊ぶ」なんて言うけれど、車すら持てない貧乏学生の私は、せいぜいゲームの中で遊ぶしかない。\nでは、なぜ一部のゲームを Steam で遊んでいないのか。うーん、事情が複雑なのだ。この手のゲームでいちばん遊んだのは Stellaris で、見積もる限り少なくとも150時間はやっている。2番目は Minecraft だろう。でもこのゲームは一緒に遊ぶ人がいないとあまりに退屈なので、実際のプレイ時間は30時間前後だと思う。\nそれから、この一年に読んだビジュアルノベル／Galgameについても触れておきたい。おそらく20本ほど読んだ。『Nekopara』のような「定番」もあれば、『三色絵恋』や『恋愛綺譚』のような中国産 Galgame もあったし、『Expression Amrilato』や『夏之鎖』のような比較的ニッチな作品もあった。R18作品もあれば、大半は純粋なビジュアルノベルだった。ビジュアルノベルは、小説をより高次の形で表現したものだと思っている。優れた作品は、文学性や物語性の面で、普通の小説を完全に超えている。\nこの一年、ひととおりビジュアルノベルや Gal を遊び終えて、中国産 Galgame がここまでできるのかと驚かされた。\n中国産 Gal は「親しみやすさ」があって、そこがとても好きだ。この題材の親しみやすさ、生活環境の親しみやすさは、他の Gal には出せない。前にも書いたように、重圧の多い環境の中でも、中国産 Gal がなお自分たちの追求を保ち、優れた作品を届けてくれているのは本当にうれしい。奇妙なことに、こんなに悪い環境でも、私たちはなおいくつかの面で成果を出している。人々はそうした成果を称え、苦難の正当性を当然のように受け入れるが、そもそも何がこんな劣悪な環境を生み出したのかを問う人はほとんどいない。\n先ほど、優れた作品は文学性や物語性で普通の小説を超えると書いたが、実際に遊んだ作品の中には、社会問題に踏み込んだり、少数者の声を代弁したりするものさえあった。これは中国本土の創作環境を考えると、きわめて得難いことだ。\nこの一年、私はずっと原神に触れていなかった。今は戻ってメインストーリーを進めつつ、あの無茶苦茶な運営が何をやらかしていたのか見ているところだ。\n交流 この一年の対人関係は、私にとって非常にひどいものだった。\n今学期、私たちは部屋替えになった。もともとのルームメイトの一人は休学し、代わりにとてもうるさい新しいルームメイトが入ってきた。これもまた、私が図書館へ向かうようになった間接的な理由だった――静かな場所で、自分の問題について考える必要があったのだ。\nたぶん私には、何人かの友人か、あるいは一匹の猫が必要なんだと思う。\n本当に、一緒にゲームをしてくれる人がほとんどいない。だから Minecraft も当然あまりやらない。レースゲームも一緒に遊ぶ相手がいないから、一人で少し走るだけだ。FPSはもともとやらないし。\nたまに部屋の何人かでバドミントンをしに行くことがあって、そういうときは比較的気分がいい。\n実のところ、同じ部屋のみんなで一緒に原神をやっていた頃を少し懐かしく思う。あの時期は、みんなそれなりに楽しかった。7月の振り返りにも書いたけれど、長年の孤独のあとで、私は少しオフラインの社交を求めるようになったのだと思う。何度も引っ越してきたせいで、幼い頃からずっと一緒だった同級生もいないし、近所に住んでいて気軽に家へ遊びに行けるほど仲のいい相手もいない。ただ時間が一日一日過ぎていくのを眺め、同級生に会いに行く人たちが楽しそうに行き来するのを見ているだけだった。ふと気づく。友達がいるというのは、本当に幸せなことなのだと。そう考えると、友達がいないというのは、なんと大きな悲しみなのだろう。\n2024年への願い これは明らかに完璧な年末総括ではない。書こうとはした。でも、書き留められるのを待っている思いはいつも尽きない。そして実際に書き出した言葉は、いつも自分が本当に表現したいものと少しずれてしまう。最初は、自分の中国語の Master が足りないせいだと思っていた。でも今ではわかる。それは、自分の表現したいという欲求が長年抑え込まれてきたからなのだと。そしてその欲求を取り戻すには、結局少しずつ練習していくしかない。これは一つの修行であり、私はいつかその真意にたどり着けたらと思っている。絶対に完璧な年末総括なんてない。ただ、この年末総括を書いている自分が、自分なりの成長と幸福を見つけられればそれでいい。\n2023年は、問答無用で苦しい一年だった。こんなふうに状況が悪くなっていく中では、自分自身を追い求めることなどなおさら難しい。私はよく、自分に「惨憺たる現実」と向き合えと言い聞かせている。でもこの現実は、あまりにも惨憺たるものだ。\n2024年は、もっと楽しく過ごせる年になってほしい。もっと大事なのは、自分の払ったものに見合う報いが返ってくることだ。それは本来、私が受け取っていいはずのものでもある。この一年のつらさで、私はすっかり消耗してしまった。もうここで特に言いたいこともない。ただ、今年は少しでも良くなってくれればと願うばかりだ。\n傅雷訳の『ウージェニー・グランデ』はおすすめ。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n著作権などの都合で、音楽を聴くアプリを頻繁に乗り換えているし、中には YouTube で MV を見るしかない曲もあるからだ。\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nバーチャルシンガー。https://space.bilibili.com/15817819\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-01-17T17:09:20+08:00","image":"/2024/01/2023-end-of-the-year-summary-public/20240117173426_hu_28cd58b804814e66.webp","permalink":"/ja/2024/01/2023-end-of-the-year-summary-public/","title":"2023年の振り返り"},{"content":"最近のイーロン・マスクの迷走により、Twitterユーザーの大量流出が再び発生している。私はこれを「Twitter Exodus（エクソダス）」と呼びたい。この状況を見て、隣のザッカーバーグが黙っていられるわけもなく、急遽自社の競合サービスのリリース日を前倒しにした。その結果、7月6日10:00には新サービスを目にすることができる。\nMetaの新サービスの名前は「Threads」。一見すると、Instagramのテキスト版のようなもので、Instagram上のフォロワーやフォロー情報をそのまま引き継げる。「また平凡で退屈なサービスか…競合のおかげで成り立つものだな」と、最初に概要を見たときはそう思った。\nしかし、Threadsはそんな単純なものではない。\n新しい独立したアプリはInstagramをベースにしており、ActivityPubという分散型ソーシャルメディアプロトコルと統合される予定です。理論的には、このアプリのユーザーは、ActivityPubをサポートする他のアプリ（Mastodonなど）でも自分のアカウントやフォロワーを引き継ぐことができます。\n報道によると、Threadsは将来的にActivityPubを介してFediverseに接続するとされている。このニュースが出た途端、多くの（ActivityPubを採用する）インスタンス管理者が不満を表明し、独自のインスタンスでThreadsをブロックすると明言したり、ユーザー投票でブロックの是非を決めたりする動きが出てきた。\nFediverseとは？ Fediverse（フェディバース）とは、Federation（連合）とUniverse（宇宙）を組み合わせた言葉であり、日本語では「連邦宇宙」と訳されることが多い。その名の通り、Fediverseは複数の独立したインスタンスが相互に通信できるネットワークであり、その仕組みは電子メールに似ている。あるインスタンスがこのネットワークに参加したり退出したりしても、他のインスタンスや全体のネットワークには影響を与えない。そのため、単に「連邦」と呼ぶよりも「邦連（コンフェデレーション）」の方が適しているかもしれない。\nたとえば、Mastodonのアカウントを1つ持っているだけで、Fediverse内の他のあらゆるインスタンス上のアカウントと（Mastodon以外のGNU Social, Friendica, Hubzilla, Diasporaなども含めて）やり取りができる。\nなぜThreadsに対する抵抗があるのか？ Mastoの信奉者たち：「私たちはオープンです。ぜひフェデレーションしましょう！」\nInstagram：「素晴らしい、新しいサービスを作って参加します。」\nMastoの信奉者たち：「そんなオープンさはいらない！」\n各インスタンスがThreadsに強く反対している主な理由のひとつは、Threadsが「乗っ取り」を行う可能性である。最初は大企業のリソースを活かして他のインスタンスよりも優れた体験を提供し、クリエイターたちを囲い込んだ後、ActivityPubの連携を断ち切るというシナリオだ。Instagramの膨大なユーザーベースがあるため、これは十分に可能な戦略である。\n仮にそのような展開にならなかったとしても、以下の問題が発生する可能性がある。\nThreadsとフェデレートしようとしている管理者たちへ。もし「Libs of TikTok」が何千人もの極右ユーザーを送り込み、あなたのユーザーを攻撃し始めたらどうしますか？\n——@siege@octodon.social\n@StarKillerさん、こんにちは！現在、ThreadsはFediverseにまだ接続されていません。Mastodon中国語インスタンス「長毛象中文站」はThreadsのドメインを即時ブロックする予定はありません。しかし、連携後に以下の問題が発生した場合、インスタンスレベルでThreadsを非表示または禁止することを検討します：\n攻撃的な言動のコントロールができなくなる 外部サイトへの広告配信 リモート投稿の削除要求を無視 サーバー負荷の著しい増大 MastodonのユーザーデータがThreadsへ流れることへの懸念については、以下の投稿の2点目を参考にしてください。 https://m.cmx.im/@strawberry/109437505\n——@strawberry@m.cmx.im\nFediverseは、すべてのユーザーに平等なソーシャルパワーを持たせるために設計されており、そのために利便性を多少犠牲にすることもある。しかし、Metaが影響力のある有名人を連れて参入することで、こうしたバランスが崩れる可能性がある。結果として、「極右ユーザー」をはじめとする過激なコミュニティの攻撃的な言動が増えることが危惧されている。\nさらにMetaのプライバシー問題も懸念される。Facebook-ケンブリッジ・アナリティカ事件のように、Metaは過去にユーザーデータを流用し、政治広告などへの活用を行っていた歴史がある。\n抵抗が生む逆効果の可能性 重要なのは機能の優劣ではなく、このサービスを利用する「人々」である。\nTwitterに投稿し続けなければならない、なぜなら私の観客がそこにいるから。\nMastodonのようなサービスが存在しても、なぜ人々はTwitterにとどまるのか？ それはTwitterが「人々」と「コンテンツ」を蓄積し続けているからだ。同様に、Threadsも単に「面白い人々」が集まる場所になれば、Fediverseからの拒絶は単なる排他的な行動と受け取られる可能性がある。\nThreadsの可能性 ThreadsはFediverseへの導入障壁を下げる役割を果たすかもしれない。Gmailが電子メールの利用を簡単にしたように、ThreadsもActivityPubの普及に寄与する可能性がある。\nまとめ Threadsの未来は不透明だが、Gmailが独立系Eメールを圧迫しつつも普及を促進したように、Threadsにも同じような役割が期待される。どのように展開するかが楽しみである。\n参考記事 Not that kind of \u0026ldquo;Open\u0026rdquo;\nIs Gmail killing independent email?\n","date":"2023-07-05T13:12:05Z","image":"https://blog-img.l3zc.com/20231216110724.webp","permalink":"/ja/2023/07/opinions-on-meta-thread/","title":"「Threads」に関するいくつかの考察"},{"content":"1年前、ネット上に自分用の文章を書く場所が一つ増えた。1年が経ち、それなりの量を書き溜めた。中学生の頃、訳も分からず初めてブログを開設したあの時から、実際にブログで記録を残し始めたこの1年までを振り返ると、時の流れの速さに思わずため息が出る。\nなぜブログ開設に至ったのか？ 旅には必ず始まりの理由があるものだ。だが、思い立ったらすぐに出発することだってある。\n当時の自分、つまり GitHub Pages で不慣れな手つきで初めての静的ブログをデプロイしようとしていた自分に聞いてみるしかない。理由なんてない。「Because that\u0026rsquo;s cool.（かっこいいから）」ただそれだけだ。\nそこで HTML、JS、CSS を少し学んだ。そして Hexo のテーマがどう動いているのか理解するのに時間をかけ、手探りで既存のテーマを改造し、なんとか自分の望むバージョンに仕上げた。当時は Webpack が何かも知らなかったのに、山のような .min.css や .min.js を一つずついじり倒していたのだ。今振り返れば苦笑いするしかない。\n何かを始めるのに理由はいらない。明確な反対理由がないなら、とにかくやってみればいい。\nこの1年で起きたこと 2022.04：\nブログ開設。GitHub Pages で「Hello World」を発信。\n19歳になる\n~~（他人と）~~いくつかのコンテストに参加：挑戦杯、創青春、イノベーション・起業コンテスト\n2022.06：\n大学英語検定6級（CET-6）の成績発表。点数は芳しくなかったが、1年生のうちに合格できたのは上出来だろう\n形式的な学部学生代表大会に参加\n2022.07：\nAzure 学生向けサーバーを取得。ブログフレームワークを WordPress に移行\n朝5時に起きて新キャンパスへ引っ越し。死ぬほど疲れた\n2022.08：\n運転免許を取得\n新学期開始。新入生の軍事訓練を見守る\n2022.09：\n先輩から受け継いだチームの後始末を担当\n学部学生会で副部長に就任\n2022.10：\n新入生新入生向けの入学式を主催\nPCR検査、PCR検査、毎日PCR検査\n学内運動会に無理やり駆り出される\n2022.11：\n新PCを導入。旧型の 1715 はしばらくお休み\n11月24日。故人に安らかな眠りを。沈黙も無関心も拒否する。\n2022.12:\n大規模な抗議活動を防ぐため、政府から帰宅を促される\n新型コロナウイルスに一度感染\n2022.01:\n長距離旅行。虎跳峡をトレッキング、麗江で遊ぶ……\n春節期間、部署の WeChat グループでふざけた紅包（お年玉）リレー\n2022.02：\n新しいモニターとコントローラーを購入。これでゲーミング寝室の完成\n統計データ 統計プラットフォームを3回も乗り換えたため、連続したデータは残っていない。参考程度に見てほしい。\nGoogle Analytics はブロックされやすいため、データはおおよその推計となる。Umami の1ヶ月のアクセス数を基に全体の訪問者数を概算すると、過去1年で約 8,000 人のユニークユーザーと、約 10,000 PV を獲得した計算になる。\n開設からわずか1年で、ICP登録（备案）もなく百度のインデックスにも載っていないサイトとしては、まずまずの結果だろう。\nこの1年で計 27 本の記事を執筆し、コメントは 18 件増えた。月平均に換算すると 2.25 本となる。\n自分自身の変化 ブログ開設当初は、SEO 対策やセンシティブな話題を避けるため、中途半端な技術記事ばかりを投稿していた。今振り返ると、自分自身を窮屈にさせていたなと思う。\n自己検閲については以前記事を書いた。それ以降、自己検閲はやめた。これにより、このブログは本来の目的を果たせるようになった。書くために書くのではなく、感じたことをそのまま吐き出す場所だ。もし感じたままに書く衝動まで自己検閲で消し去ってしまうなら、他のことなど書けるはずがない。\n言語の意義は、最も簡潔な言葉で最も正確な情報を伝えることにあると私は考える。文章を書くことは一種の修行であり、詳略をわきまえ、論理が明確で、言葉遣いが洗練されている状態が、その到達点だ。以前はブログで文字数を稼ぐことに執着していたが、無駄な文章をたくさん書いた末に、ようやくそのこだわりを手放せた。\n……\nその他、少しだけ この1年でブログは Hexo から WordPress へ移行し、最近では Hugo への乗り換えも考えている。だが、これだけ長く運用し、SEO 対策にも1年を費やしてきた今、さらにブログシステムを乗り換えるのはあまりにも試行錯誤する手間がかかりすぎる。結局、WordPress に留まることにした。\nブログのホスティング先も何度も変えてみた。香港 Azure、Cloudflare、Racknerd、Bandwagon。あれこれ試しては落とし穴にハマり、結局また香港 Azure に戻ってきた。やはり平凡で安定しているのが一番なのだろうか。\n最初の段階でもっと多様な技術スタックに触れておかなかったことを後悔している。それが今年の目標だ。見栄えの良いテーマや必要な機能を実装するために PHP を学び、Umami をデプロイするために Docker Compose の使い方を学んだ……。ブログ構築はそもそも学習のプロセスそのものだ。学べば学ぶほど書けるようになり、書けば書くほどさらに学べる。\n最後に この1年を振り返ると、「なぜ自分はこれしかできなかったのだろう」という感覚に襲われる。\n確かに、時間を公務に費やしすぎ、自己研鑽に割く時間が少なすぎた。学生会という組織への興味も、日に日に薄れている。大学に入学したばかりの頃、同学のために尽くし自分を高めたいという情熱は、無意味な形式的な活動の繰り返しで削がれていった。今思えば、当時の自分はあまりに天真爛漫だったのかもしれない……。学生会で何かを成し遂げたいと強く願っていても、この大学に蔓延る形式主義と官僚主義は、情熱に満ちた人間を憂鬱にし、ただ日々をやり過ごすだけの存在に変えてしまう。今の言葉で言えば、「寝そべり（躺平）」である。\n「窮すれば独りてその身を善くし、達すれば天下を兼ねて済す」。現在の私の立場を顧みれば、まずは「独りて身を善くする」こと、つまり自分自身の成長と内省にしっかり向き合うべきだろう。\n","date":"2023-05-02T22:28:18Z","permalink":"/ja/2023/05/1st-anniversary/","title":"ブログ開設一周年"}]