VPNトラブル iOS26.1 で回復

iPhone17 に切り替えて設定を移行していたけど、iPhone17 から 自宅 Buffalo ルータへの VPN(L2TP) が接続できない。今まで iPhone12 で iOS26 Beta を入れていても使えていたのに 機種変して iOS 26 の公式版で動かない。

んで、iOS26.1 Beta が早々にでているけど、『「iPhone 17」シリーズでWi-Fi接続が不安定に–一部ユーザーが不具合を報告』の記事の中に”iPhone17 はネットワークに新型チップが導入されていて、そのトラブル対策で 26.1 が公開”という話があった。ということで関連があるかと、早々に Beta インストールの設定を復活させ、iOS26.1 を入れてみたら、VPN が正しく接続できるようになった。

iPhone17移行

昨日はお店のポイント系の移行でパスワードなんて保存してないやつを、パスワード変更しながらの登録…を、10件以上ボチポチしながら繰り返し。

さらに、ワイヤレス充電の台を、サイズ変化に合わせて改造。

iPhone17を購入

4年前に購入していた iPhone12mini であったが、そろそろ機種変更ということで iPhone17 を購入となった。
発売開始に合わせ、キャリア au にて予約・購入。キャリア購入だと少し購入価格が高くなっていて、分割払いで半額分を2年支払えば、残金支払いナシで機種変できるコース。半額しか払わないというと割安感を感じなくもないけど、2年しか使わないと考えると、やっぱり割高にも思う。2年後に買い替えするかなぁ!?
{CAPTION}
とはいえ、最新機種はワクワク。iPhone12miniのサイズに慣れていたとはいえ、iPhone17のサイズは、年齢的にも怪しい視力のなか、見やすい。奥さんの iPhone13 とほぼ同じサイズなんだな。
今回 eSIM に変更になったけど、転送時は重ねる位に近づけながら作業と思ってたのに、ちょい離れてあっても自動で引き継ぎされ、いつの間に…という感じであっという間に開通。ただ、開通後の au Online Shop の移行完了手続き画面を引き出すのが極めて分かりにくい。予約で発送状況確認する際も、購入履歴にたどり着くのか分かりにくい。Amazon ならどこでも画面右上で一発確認できるよねー。
アプリの移行が面倒くさいと思っていたけど、SUICA, ICOCA のクラウド戻し、移行後のダウンロード作業に不安があったけど、自動で移行されてた。ひと手間かかったのが Pikmin Bloom 。歩数データが読み取れないとか言われたけど、指定手順どおりで設定できない。しかたなくアプリ削除&再インストールで無事に設定完了。いくつかのアプリが同じようにアプリ削除&再インストールが必要だった。

自宅ドメインがGoogleDNSで引けない

自宅サイトのドメイン名が9/18より、Google DNS(8.8.8.8) にて名前解決ができない状態。原因不明(後述 原因はmydns.jpへの水責めの影響)。その他の Public DNS では問題がない(はず)。mydns.jp への Dynamic DNS の情報更新も問題ない(はず)。

状況確認

$ whois tsaitoh.net
Domain Name: TSAITOH.NET
:
Registrant Email: nic-staff@sakura.ad.jp
Name Server: NS1.MYDNS.JP
Name Server: NS0.MYDNS.JP
Name Server: NS2.MYDNS.JP

DNSを管理してもらっている、mydns.jp で確認しても、特に問題がないはずなんだが…

$ nslookup tsaitoh.net 8.8.8.8
;; Got SERVFAIL reply from 8.8.8.8      ### Google Public DNS
Server:         8.8.8.8
Address:        8.8.8.8#53
** server can't find tsaitoh.net: SERVFAIL

$ nslookup tsaitoh.net ns0.mydns.jp     ### mydns.jp
Server:         ns0.mydns.jp
Address:        210.197.74.200#53

Name:   tsaitoh.net
Address: 64.33.3.150

$ nslookup tsaitoh.net 208.67.222.222   ### OpenDNS(Cisco)
Server:         208.67.222.222
Address:        208.67.222.222#53

Non-authoritative answer:
Name:   tsaitoh.net
Address: 64.33.3.150

$ nslookup tsaitoh.net 9.9.9.9          ### Quad9(IBM)
Server:         9.9.9.9
Address:        9.9.9.9#53

Non-authoritative answer:
Name:   tsaitoh.net
Address: 64.33.3.150

$ nslookup tsaitoh.net 1.1.1.1          ### Cloudflare
Server:         1.1.1.1
Address:        1.1.1.1#53

Non-authoritative answer:
Name:   tsaitoh.net
Address: 64.33.3.150

Google DNS から DoS 攻撃(水責め)

mydns.jp の運営の方に問い合わせをしたら、報告をもらえた。
DoS 攻撃が静まれば、復帰するかなぁ…

((メールより一部引用))
原因が判明しました。
現在、GoogleのDNSからDoS攻撃、いわゆる「水責め」を受けているため、こちらのDNSがGoogleとのやり取りを一時的に遮断しています。
なので、1.1.1.1では引けても8.8.8.8では引きにくい、という状況が発生しています。

AirTagもどきLEEWINの導入

AirTagもどきを購入したけど、iOS26 を導入しているためか、説明書と違うのでメモ。

位置検出タグの導入目的

父母がシニアカーで遠くまで出かける時があるので、居場所確認に使えないかと導入。でも、BLEタグによる位置検出は、近隣のApple製品経由で位置情報をクラウドに送信してもらうことで、位置を把握する。このため、田畑に出かけて近くにiPhoneスマホを持った人が居なければ、役に立たないとは思うけど。

タグのリセット

  • 登録済み(もしくは電池入れ替え)ならば、「探す」から一旦削除。
  • タグのボタンの長押し – 「ピロ・ピロ」と鳴ったら、ボタンを離す。
  • 素早く2回ボタンを押す – 「ピロピロピロ」と鳴ったら、
  • 5秒の長押し – 「ピーー」と長音がなって終了。
  • 検索アプリで「持ち物を探す」-「+」-「その他の持ち物」で追加。
    (Airtagもどきだから「AirTagを追加」で何も表示されずムダに悩んだ)
  • 最後に、タグの名前の登録、絵文字の登録。

 

イランからの詐欺電話

スマホに「+98」のイランからの詐欺電話。スマホの着信を録音文字起こしを起動させてみたけど、成田空港に落とし物だとか。なんで成田空港警察がイランからかけてくるんだよ。

Buffalo ルータの情報

Home Assistant を使っていたら、UPnP の機能でルータのパケット情報を取得しているらしい。ではどうやって取得するのか?

SSDPでUPnPデバイスを探す

Gemini に「UPnPの機能で Buffalo のルータの通信速度などの情報を調べるには?」と聞いたら、「SSDP(Simple Service Discovery Protocol)を使用してネットワーク上のUPnP対応デバイスを検索します。これは、マルチキャストアドレス239.255.255.250のUDPポート1900にM-SEARCHリクエストを送信することで行います。」とのアドバイスがもらえた。

「取得するプログラムを提案して」と聞いたら、以下の Python コードを教えてくれた。

import socket
import time

# SSDPマルチキャストアドレスとポート
SSDP_ADDR = '239.255.255.250'
SSDP_PORT = 1900

# M-SEARCHリクエストの作成
# ST: Service Type、ここではルーター(WANIPConnection)を指定
# MX: Maximum wait time in seconds
msearch_request = '\r\n'.join([
    'M-SEARCH * HTTP/1.1',
    'HOST: {}:{}'.format(SSDP_ADDR, SSDP_PORT),
    'MAN: "ssdp:discover"',
    'ST: urn:schemas-upnp-org:service:WANIPConnection:1',
    'MX: 3',
    '',
    ''
])

# ソケットの作成
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(5)  # 応答を待機する時間(秒)

print("M-SEARCHリクエストを送信中...")

try:
    # リクエストの送信
    sock.sendto(msearch_request.encode('utf-8'), (SSDP_ADDR, SSDP_PORT))

    while True:
        try:
            # 応答の受信
            data, addr = sock.recvfrom(1024)
            print("-" * 20)
            print("デバイスを発見しました!")
            print("IPアドレス:", addr[0])
            print("ポート:", addr[1])
            print("\n応答内容:")
            print(data.decode('utf-8'))

        except socket.timeout:
            print("-" * 20)
            print("タイムアウトしました。すべての応答を受信したか、デバイスが見つかりませんでした。")
            break

except Exception as e:
    print("エラーが発生しました:", e)

finally:
    sock.close()

SSDPの返答から詳細取得

実行したら、以下の情報が得られた。これより、/getedesc.xml などで 49355 ポートに問い合わせすればいいみたい。

M-SEARCHリクエストを送信中...
--------------------
デバイスを発見しました!
IPアドレス: 192.168.xx.1
ポート: 1900

応答内容:
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=1800
DATE: Tue, 09 Sep 2025 13:57:21 GMT
EXT:
LOCATION: http://192.168.xx.1:49355/gatedesc.xml
SERVER: Linux/3.14.77 UPnP/1.0 Intel_SDK_for_UPnP_devices/1.2
ST: urn:schemas-upnp-org:service:WANIPConnection:1
USN: (略)
  • http://192.168.xx.1:49355/gatedesc.xml
  • http://192.168.xx.1:49355/gateinfoSCPD.xml – 情報量少ない
  • http://192.168.xx.1:49355/gateicfgSCPD.xml
  • http://192.168.xx.1:49355/gateconnSCPD.xml

送受信パケット量を取得

いろいろと試す中、送受信パケットを取得する lua スクリプトを Gemini に作らせたら、下記のようになった。

-- socket.http ライブラリをロードします。
-- 'luasocket'パッケージが必要です。
local http = require("socket.http")
local ltn12 = require("ltn12")

-- UPnPサービス情報
local url = "http://192.168.xx.1:49355/upnp/control/WANCommonIFC1"

-- リクエスト情報を格納するテーブル
local requests = {
    {
        action = "GetTotalBytesReceived",
        tag = "<NewTotalBytesReceived>",
        label = "受信"
    },
    {
        action = "GetTotalBytesSent",
        tag = "<NewTotalBytesSent>",
        label = "送信"
    }
}

-- データを取得する関数
local function get_upnp_data(req_info)
    local soap_data = string.format([[<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <u:%s xmlns:u="urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1">
    </u:%s>
  </s:Body>
</s:Envelope>]], req_info.action, req_info.action)

    local headers = {
        ["Content-Type"] = "text/xml; charset=\"utf-8\"",
        ["SOAPAction"] = '"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1#' .. req_info.action .. '"'
    }

    print(req_info.label .. "データを取得中...")

    local response_body = {}
    local res, status_code = http.request{
        url = url,
        method = "POST",
        headers = headers,
        source = ltn12.source.string(soap_data),
        sink = ltn12.sink.table(response_body),
        timeout = 10
    }

    if status_code and (status_code == 200 or status_code == "200 OK") then
        local response_text = table.concat(response_body)

        local start_tag = req_info.tag
        local end_tag = string.gsub(start_tag, "<", "</")
        
        local _, _, bytes_string = string.find(response_text, start_tag .. "(.*)" .. end_tag)

        if bytes_string then
            local total_bytes = tonumber(bytes_string)
            local megabytes = total_bytes / 1024 / 1024
            
            print(string.format("合計%sバイト数: %d", req_info.label, total_bytes))
            print(string.format("合計%sメガバイト数: %.2f MB", req_info.label, megabytes))
        else
            print(req_info.label .. "データが見つかりませんでした。")
            print("応答内容:\n" .. response_text)
        end
    else
        print(req_info.label .. "データの取得に失敗しました。")
        print("ステータスコード: " .. (status_code or "不明"))
        print("応答内容:\n" .. table.concat(response_body))
    end
    print("----------------------------------------")
end

-- 各リクエストを実行
for _, req_info in ipairs(requests) do
    get_upnp_data(req_info)
end

SSDPとそのあとの処理をまとめた lua スクリプトは以下となった。

munin でのパケット流量観測に組み込んでみた。

Gemini中心のコーディング

でも、今回のプラグイン作成は、Gemini で作らせた。オレがやったのは生成されたプログラムをテストして、プログラム作ってとか、Lua で作ってとか、データ抽出では厳密なXML解析せず正規表現で作って…とか、munin のプラグインに直してとか、命令するばかりで、エディタで悩みながらコード書きはしなかった。エディタ使ったのは、コードの確認・コメント加筆・余計な動作検証の print を消す程度。

Home Assistant のインストール

Google Home mini などでの音声操作は、Google Home に Switchbot を連携させて、使えるようになって十分に便利になったけど、調べて出てきた Home Assistant も試してみたくなった。

Docker をインストール

普通に、Ubuntu の Docker をインストールする手順にてインストール。

Docker に Home Assistant をインストール

参考にしている記事などでは、homebridge なども Docker でインストールしているけど、我が家は homebridge が既に動いているので Home Assistant だけを docker で動かせばいい。これにあわせ、docker-compose.yml を作成。Docker 内の設定ファイルが保存される /config は、/var/lib/homeassistant にマウントさせる。

((( /etc/homeassistant/docker-compose.yml )))
version: '2'
services:
  homeassistant:
    container_name: homeassistant
    image: "ghcr.io/home-assistant/home-assistant:stable"
    volumes:
      - /var/lib/homeassistant://config
      - /etc/localtime:/etc/localtime:ro
    restart: unless-stopped
    privileged: true
    network_mode: host
$ cd /etc/homeassistant
$ sudo docker-compose up -d
$ sudo docker ps
CONTAINER ID   IMAGE                                          COMMAND   CREATED          STATUS          PORTS     NAMES
xxxxxxxxxxxx   ghcr.io/home-assistant/home-assistant:stable   "/init"   15 minutes ago   Up 15 minutes             homeassistant

設定がうまくいったら、http://localhost:8123 を開いて、ユーザ登録などを行う。

 

設定ができた後は色々と設定して、最終的に以下のような画面となった。

2025年・新米

田んぼを耕作してもらっているけど、作ってもらった、今年の新米が届いた。
{CAPTION}

homebridge-gshが有償化

自宅の homebridge の制御を google home mini から行うために homebridge-gsh を使っていた。便利に “OK,google” で便利に使っていたけど、エラーがでるようになってきた。homebridge-gsh の導入した当初のページには、「無償だけど有償登録をお願い」みたいに書いてあったけど、2025年5月から、有償サービスに移行していたようだ。

プラグインの再設定を試みたけど、エラーが出るのでよくよく見たら、Trial Expired … ってしっかり表示されていらぁ。

月額 US$2.00 or 年額 US$22.00 を PayPal or カードで支払いとな。こんだけ便利に使ってるのにケチケチ野郎は導入に悩む。Gemini に聞いてみたところ Home Assistant を導入する方法が紹介された。

でも、よくよく考えたら、メインの機器は Switchbot の配下だし、ぐだぐだ考えずに Google Home アプリで、Switchbot を連携でいいじゃん。