2026/06/04(木)Windows 11でコマンドを使って標準のブラウザを変更する
どこぞのやつはライセンスが面倒なのと、無料利用だと課金誘導のポップアップが出て面倒そうなので完全無償のPS-SFTAを使って解決する。
確認環境
- Windows 11 Pro 25H2 (OSビルド 26200.8457)
- SFTA.ps1 22a3229
やり方
- PS-SFTAにある
SFTA.ps1を拾ってきてどっかに置く - 標準ブラウザ変更保護プログラムであるUCPDとかいうのを殺す
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\UCPD" -Name "Start" -Value 4 -PropertyType DWORD -Force schtasks /change /disable /tn "\Microsoft\Windows\AppxDeploymentClient\UCPD velocity" - 管理者権限のPowerShellでこれを流す
powershell -ExecutionPolicy Bypass -command "& { . C:/path/to/SFTA.ps1; Set-PTA MSEdgeHTM http; Set-PTA MSEdgeHTM https; Set-FTA MSEdgeHTM .htm; Set-FTA MSEdgeHTM .html }"
あとがき
Windows 11には標準のブラウザを変更するコマンドは用意されておらず、レジストリの操作も単純ではないようなので、やるとしたらWindowsの設定を開き、アプリ→既定のアプリ→Edge→標準ブラウザにするという手間のかかる作業が必要だが、今回の方式ならコマンドを一発叩くだけなので非常に楽である。
しかもWindowsの設定にあるアプリ→既定のアプリはレイアウトシフトが酷く、少し待たないと操作できないのも面倒なので、そういったフラストレーションから解放されるのも大きい。
2026/06/04(木)さくらのレンタルサーバでホスティングしていたサイトの大部分を自宅サーバーに移行した
今日は遂に運営サイトの大半をさくらのレンタルサーバーから自宅サーバーへ移行することに成功した。
自宅サーバーでの個人サイト運営は中学時代からの夢だったので、悲願が叶ったようでちょっと嬉しい。
- 移行したサイトなど
- やったこと
- トラブルシューティング
cgi-binを含むパスが/usr/lib/にマップされた- ダンプ取り込み時に
ERROR 1273 (HY000) at line 30: Unknown collation: 'utf8mb4_0900_ai_ciが出る - MySQLを叩くCGI実行時に
Exception while creating PDO object:SQLSTATE[HY000] [2002] Connection refusedが出る - CGI実行時に
End of script output before headers: hoge.cgi,が出る .htaccess: Invalid command 'Header', perhaps misspelled or defined by a module not included in the server configuration- nginx -> Apache2のリバプロ環境でMatomoが無限リダイレクトしたり、エラーログを吐きまくる
- 504エラーが出たり、やたらめったら凄く重い
- ビジットの外観のミニグラフが出ない
- あとがき
移行したサイトなど
次のサイトやサービスを移行した。
- lycolia.info -
lycolia.info- エントランスページ、LPみたいなもん
- Lycolog -
blog.lycolia.info- このブログ。このブログは2019年より前のログがないが、実はこのサイトは元からブログとして発祥している。当時はブログという概念はなく、日記サイトだった
- Webツール置き場 -
tool.lycolia.info- 適当に作った便利ツールを置いている
- ECO-Wiki (lycolia) -
eco.lycolia.info- 最近一言BBSへの書き込みがないのが気がかりなWiki。実はアクセスは落ちてない
- アクセス解析 Matomo
- TinyTinyRSS
やったこと
さくらのレンタルサーバから自宅サーバーへファイルを移設し、権限を設定
# サイト単位にtarballに固める
tar -cf hoge.tar hoge
# Windows上のRLoginを使って、NASとしてマウントしている自宅サーバーに転送
cp hoge.tar <ホスティングファイル置き場>
tar -xf hoge.tar hoge
# Apacheから見えるように
chown -R www-data:www-data <ホスティングファイル置き場>/hoge
# www-dataに属するユーザーがいじれるように
chmod -R g+rxw <ホスティングファイル置き場>/hoge
cgi-binフォルダを使っているスクリプトの対策
ヘッダーモジュールの有効化
使ってるやつがいたので有効化。
sudo a2enmod headers
さくらのレンタルサーバのMySQLからDBをダンプし、自宅サーバーのMariaDBに取り込み
sudo mysql -u <ユーザー名>
CREATE DATABASE <DB名>;
exit
# 照合順序をMariaDB方式に変換
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g' ~/hoge.sql
sudo mysql <DB名> < ~/hoge.sql
nginxとApache2の設定を追加
nginx -> Apache2の構成にしているので、これの設定。基本的にレンサバでホスティングしていたものはApacheの上にのせておくと色々と楽だ。.htaccessは神だし、静的ファイルやCGIのホスティングをする場合、Apacheは取り回しがとても良い。
/etc/nginx/conf.d/にサイトごとのリバプロの設定を置く。一例としてはこんな感じserver { listen 443 ssl; listen [::]:443 ssl; server_name eco.lycolia.info; client_max_body_size 100M; ssl_certificate /etc/letsencrypt/live/lycolia.info/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/lycolia.info/privkey.pem; location / { proxy_pass http://apache/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; } }/etc/apache2/sites-enabled/にもサイトごとの設定を書く。一例としてはこんな感じ<VirtualHost *:8080> ServerName eco.lycolia.info ServerAdmin webmaster@localhost DocumentRoot /var/www/path/to # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, # error, crit, alert, emerg. # It is also possible to configure the loglevel for particular # modules, e.g. #LogLevel info ssl:warn ErrorLog ${APACHE_LOG_DIR}/eco-error.log CustomLog ${APACHE_LOG_DIR}/eco-access.log combined </VirtualHost>
このリバプロの設定の意味合いについては過去に書いたnginxからApache2のバーチャルホストにいい感じにリバプロする方法、nginxからApache2へセキュアにリバプロしたときに真のクライアントIPを取得できるようにするを参照。
perlとphpのパスにエイリアスを作る
これをしてないと実行時エラーになる。
sudo ln -s /usr/bin/perl /usr/local/bin/perl
sudo ln -s /usr/bin/php /usr/local/bin/php
SSIの有効化
今時SSIを使ってる人なんてまずいないと思うが、令和最新版ということで…。
やり方
- SSIモジュールを有効化する
sudo a2enmod include /etc/apache2/apache2.confを開き、全域でSSIを有効化。ついでにDirectoryIndexにも入れとく。SSIの設定はDirectoryディレクティブの中でないと効かない<Directory /var/www/> AllowOverride All DirectoryIndex index.php index.cgi index.shtml index.html index.txt # Optionsに+Includesの部分を追加する Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch +Includes AddHandler cgi-script .cgi Require all granted </Directory>
.shtmlの場合にSSIを許可するように管理しているのは恐らく/etc/apache2/mods-enabled/mime.confだと思われる。ここでMIME-TYPEも付与していると思われる。
バーチャルホストやんいやパス単位にしたい場合は適当なDirectoryディレクティブにOptions +Includesを書けば機能する。
余談だがSSIはエントランスページの更新日時を出すのに使っていて、過去に記事のネタにしたこともある。
アプリケーションのDBの向き先を変更
移設したMatomoとTTRSSは共にMySQLを使っていたためMySQLの接続情報を書き換えた。
DBの接続先はlocalhostでなく、127.0.0.1でないと上手くいかなかった。::1も通らなかったため、恐らくIPv6でListenしていないのだと思う。
Matomoの設定
- 無限リダイレクト抑制のため
config/config.ini.phpのeneralセクションにassume_secure_protocol = 1を追加する。詳細はトラブルシューティングの該当項目参照 - gd2以上を入れろと言われるので使っているPHPのバージョンにあったものを入れる
sudo apt install php8.3-gd - MySQLの
max_allowed_packetが少なすぎると言われるので/etc/mysql/my.cnfを開きmysqldセクションに設定を足す[mysqld] + max_allowed_packet=64MB
CRONの移行
ttrssとmatomoのCRONを移行。
0 * * * * /usr/local/bin/php /path/to/ttrss/update.php --feeds --quiet 1> /dev/null
0 * * * * /usr/local/bin/php /path/to/analytics/console core:archive --url=https://analytics.lycolia.info/ 1> /dev/null
ドメインの切り替え
- Value-DomainのDNS管理画面を開き、移設したドメインを全て自宅サーバーに向けた
- 移設前はAレコードとMXレコードのIPが同一だが、今回からAレコードとMXレコードのIPが変わるので分離した。これで合っているのか怪しいが一応メールが届くことは確認している
+mx mx.lycolia.info. 10 +a mx 133.167.8.98 +aaaa mx 2403:3a00:101:13:133:167:8:98 mx lycolia.info. 10 -a 133.167.8.98 -aaaa 2403:3a00:101:13:133:167:8:98 +aaaa @ 2400:4153:8f01:c800:c14b:3f7a:2b54:353a +a @ 133.167.8.98 - 今回移設したドメインを対象にvalue-domain-dns-utilの
vd-ddns-v4.plでDDNSを行う設定を追加
トラブルシューティング
cgi-binを含むパスが/usr/lib/にマップされた
例えば/var/www/html/hoge/cgi-bin/mgcount/mgcount.cgiを実行すると/usr/lib/cgi-bin/mgcountを叩こうとしてコケる問題と出会った。
実際に出たログの一例としては以下のような状態だった(IPはマスクしているが他はそのまま)
[Wed Jun 03 21:02:12.751027 2026] [cgid:error] [pid 865047] [client xxxx:xxxx:xxxx:xxxx:xx:xxxx:x:x:x] AH01264: script not found or unable to stat: /usr/lib/cgi-bin/mgcount, referer: https://lycolia.info/index.shtml
これはどうも規定ではcgi-binが入ったパスを/usr/lib/cgi-bin/にバインドする振る舞いがあるらしく、sites-enabled/の設定に次の記述をすることで正しいパスを呼び出すことができるようになった。
<VirtualHost *:8080>
ServerName hoge.lycolia.info
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/hoge
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/hoge-error.log
CustomLog ${APACHE_LOG_DIR}/hoge-access.log combined
# ScriptAliasで既存のバインドを上書きする
ScriptAlias /cgi-bin/ /var/www/html/hoge/cgi-bin/
</VirtualHost>
ダンプ取り込み時にERROR 1273 (HY000) at line 30: Unknown collation: 'utf8mb4_0900_ai_ciが出る
MySQLとMariaDBで照合順序の名前が違うらしいのでダンプファイルをMariaDB流で置換する。
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g' ~/hoge.sql
MySQLを叩くCGI実行時にException while creating PDO object:SQLSTATE[HY000] [2002] Connection refusedが出る
DBに繋がっていないのが原因。ポート番号やIDPWなどに間違いがなく、ローカルDBに繋ぐ場合、DBの接続先をlocalhostでなく、127.0.0.1にすれば直る。
CGI実行時にEnd of script output before headers: hoge.cgi,が出る
これはHeaderを吐く前にエラーが標準出力されているので出るエラーと思われる。昔PHPやってた人にはお馴染みのやつ。
Shebangに書かれているパスにPerlがないのが原因なのでShebangのパスを見てそこにシンボリックリンクを張っておく。
sudo ln -s /usr/bin/perl /usr/local/bin/perl
.htaccess: Invalid command 'Header', perhaps misspelled or defined by a module not included in the server configuration
ヘッダーモジュールを有効化する。
sudo a2enmod headers
nginx -> Apache2のリバプロ環境でMatomoが無限リダイレクトしたり、エラーログを吐きまくる
一般的に内部リバプロはhttpで送るが、これが原因。
Matomoはhttpリクエストをhttpsにリダイレクトするが、リバプロがhttpでリクエストしてくるため無限ループになって発生する。MatomoのGitHubリポジトリのIssueに山ほどある問題。
解消法としては以下の様にconfig/config.ini.phpのGeneralセクションでassume_secure_protocol = 1を設定すればよい。
[General]
+assume_secure_protocol = 1
504エラーが出たり、やたらめったら凄く重い
アクセスが集中してるときにMatomoがDBエラーを吐いてるとAMD Ryzen 5 8500Gでメモリ32GBのNVMe SSDを積んだマシンですら504が出る程度には重かった。
エラーを潰したら平和になった。
ビジットの外観のミニグラフが出ない
GD2以降が必要なのでPHPのバージョンにあったものを入れる。
sudo apt install php8.3-gd
あとがき
2017年から自宅サーバーをマイペースに運用しており、初期はSSHDを立てただけの簡易NASやシンクラ環境として使っていたが、去年からMastodonの運用をはじめ、中学のころの夢だった鯖缶になることができた。そして更に今回、死活監視用に確保しているサイト(未構築)を除き、全てのサイトを自鯖に移行できたので、まさに中学生のころに夢見た、Webサイトを運用する鯖缶になることができ、感激もひとしおだ。
移設作業中は通信トラフィックやディスクI/Oが一気に跳ね上がったりだとか、CPUやメモリも結構頑張っていて、運用しているMastodonがやたら重くなったのが印象的だった。
何せこのブログだけでファイル数15,197の容量13GBもあるのだから無理もない。
あと移設作業中にadiaryのOGPが出なくてなんでだ?と思ったら、HTTPSの判定処理に漏れがあり、HTTPでURLが出ていたので、リバプロのヘッダもみるように改修した。実装上、リバプロしていない場合に子のヘッダが送られてきてもHTTPSになってしまうが、困るのはそんな不正な要求を送った本人なので、特に問題ないだろう。
さて、ここまで来たら次は以前も話に出した、Anubisを導入してWAFを掛けたり、現在日々増強中の監視体制の強化を続けていくなどして、自作サーバーライフを楽しんでいきたいところだ。
振り返ってみたら2025/08/21から今日までの間になんと三回も言及しており、これで四回目らしい。草。
特に意味はないが、過去にあったAnubisへの言及を以下にまとめてみた。
- 2026/05/26 直近でやりたいことリスト
- 2026/05/30 このブログにやってくる海外IPのBOTの挙動を軽く調べた
- 2025/08/21 Ubuntu実機IPv6シングルスタック環境にMastodonを入れてみた
なんと言うか一年くらい塩漬けにしていたプロジェクトが最近はじわじわ進んでいる気がしていて、非常に清々しい。
そういえばadiaryをサーバーモードで動かすと早いという話があるので、そっちも試してみたいところだ。これは最近記事の増加に伴い中々重くなってきているのを感じているからだ。
やりたい事がたくさん湧いてくるのは充実していてとても良い。
2026/06/03(水)Grafanaのダッシュボードに端末情報を出す方法
監視対象のスペックを確認するのに便利かも…?
確認環境
| Env | Ver |
|---|---|
| Ubuntu | 24.04.3 LTS |
| Prometheus | 3.5.0 |
| Grafana | v12.1.1 |
| Node exporter | 1.9.1 |
やり方
- Dashboardを開く
- 右上のボタンからEditモードに入る
- Add->Visualization
次の要領で設定する
項目 状態 Visualization TableTable view ON Queries Codeを選択し node_os_info或いはnode_dmi_infoAdd field override ボタンを押して一個追加する Override 1
項目 状態 Fields with name TimeStandard options > Display name Last SyncedRefreshボタンを押すと完成するのでSave dashboardしたら出てくる
2026/06/03(水)OpenWrtのメトリクスとログをGrafanaで雑に見れるようにした
投稿日:
OpenWrtのメトリクスやログをUbuntu側のGrafanaで見れるようにするまで。
メトリクスの取得にはPrometheus、ログはLokiを使っている。
確認環境
監視する側
| Env | Ver |
|---|---|
| Ubuntu | 24.04.3 LTS |
| Prometheus | 3.5.0 |
| Grafana | v12.1.1 |
| Loki | 3.5.9 |
監視される側
| Env | Ver |
|---|---|
| OpenWrt | 24.10.0 |
| Prometheus | 3.5.0 |
| prometheus-node-exporter-lua | 2025.07.15-r1 |
| prometheus-node-exporter-lua-nat_traffic | 2025.07.15-r1 |
| prometheus-node-exporter-lua-netstat | 2025.07.15-r1 |
| prometheus-node-exporter-lua-openwrt | 2025.07.15-r1 |
| prometheus-node-exporter-lua-thermal | 2025.07.15-r1 |
| perl | 5.40.0-r2 |
| perlbase-json-pp | 5.40.0-r2 |
| perlbase-http-tiny | 5.40.0-r2 |
| perl-time-moment | 0.44.5.40-r1 |
Prometheusでメトリクスを取得してGrafanaで見れるようにする
ほぼOpenWRT | Grafana Labsに書いてある通り。
- 必要なパッケージをインストールする
opkg update opkg install \ prometheus-node-exporter-lua \ prometheus-node-exporter-lua-nat_traffic \ prometheus-node-exporter-lua-netstat \ prometheus-node-exporter-lua-openwrt \ prometheus-node-exporter-lua-thermal /etc/config/prometheus-node-exporter-luaを以下のように編集するconfig prometheus-node-exporter-lua 'main' + option listen_interface 'lan' - option listen_interface 'loopback' option listen_port '9100' #option cert '/etc/uhttpd.crt' #option key '/etc/uhttpd.key'- prometheus-collectors/filesystem.luaとprometheus-collectors/meminfo.luaを拾ってきて
/usr/lib/lua/prometheus-collectorsに配置する - サービスを再起動
/etc/init.d/prometheus-node-exporter-lua restart /etc/prometheus/prometheus.yaml- job_name: "OpenWRT" static_configs: - targets: ['xxxx:xxxx:xxxx:xxxx::1:9100']- Prometheus再起動
sudo systemctl restart prometheus.service - 取れるメトリクスの一覧
curl 'http://[xxxx:xxxx:xxxx:xxxx::1]:9100/metrics' - Grafanaのダッシュボードを作成しID:
18153を取り込む - WiFi関係使ってないので全消し
- Used SWAPのQueriesを以下のように書き換えて0除算でエラーが出ないようにする
( ( (node_memory_SwapTotal_bytes{instance=~"$node:$port",job=~"$job"} - node_memory_SwapFree_bytes{instance=~"$node:$port",job=~"$job"}) / (node_memory_SwapTotal_bytes{instance=~"$node:$port",job=~"$job"} > 0) ) * 100 ) or (node_memory_SwapTotal_bytes{instance=~"$node:$port",job=~"$job"} * 0)
細かい部分の整理はまた追々として、いい感じに見れるようになった気がする。
ログをLokiに送る
Loki exporter for OpenWRTが動かないので自作した。
- OpenWrtのログをLokiに送るやつを拾ってくる
- インストール方法にある通りにファイルを配置、設定ファイルをいじる
- Lokiにログが飛んでればOK
- ログが飛んでいない場合は
/tmp/openwrt-loki.errの中身を見てエラーがないか見る
- ログが飛んでいない場合は
一旦こんな感じで見れるようになった。
既知の問題
複数行のエラーログがLoki上で別のログになる
親子関係を作ってないせい。Claude Opus 4.8には難しいようだったので、そのうち作る。
おまけ:Lokiにログを投げる方法
POST /loki/api/v1/pushを叩けばよい。ペイロードは以下の書式。
LokiのAPIペイロード
{
"streams": [
{
"stream": {
"label": "value"
},
"values": [
[ "<unix epoch in nanoseconds>", "<log line>", { "hoge": "aaaa", "fuga": "1234" } ],
[ "<unix epoch in nanoseconds>", "<log line>", { "hoge": "bbbb", "fuga": "2345" } ]
]
}
]
}
ペイロードの意味合い
nginxのログはペイロードしか入ってなかったりするがどうやって実現してるのか不明。もしかするとvalues[1]にJSONを突っ込んでるのかもしれない。
| 項目 | 意味合い |
|---|---|
| streams | よくわかってない |
| stream | この配下に検索用のラベルをぶら下げる。jobとかlevel、hostとかを入れとくとよいと思われる |
| values | ログの本体を入れる |
| values[0] | ナノ秒まで入ったEPOCH |
| values[1] | ログ本文の文字列 |
| values[2] | オプションペイロード。KEY=VALUE |
おまけ:Loki exporter for OpenWRTのエラーログ
あのシェルスクリプトを読む気が起きなかったので、なぜこうなっているかはわからない。
BOOT=0 /bin/ash /usr/bin/loki_exporter
openwrt-loki-exporter/v1.0.6-0-gd20fb55-20260322-23413663016 started with BOOT=0
/usr/bin/loki_exporter: line 257: malformed ?: operator
あとがき
去年の8月にはやろうとしていたものの、そのままズルズルと長らく放置していたOpenWrtの監視周りだが、このままではいけないということで、一旦は雑に整備した。
大変雑なのでログ周りは機能するかも怪しいし、私以外が使えるようにも作ってない。最低限動くとかそんなレベル。LLMが書いたコードもろくにレビューしていないので、動いている原理さえ不明だ。
幸い全部で300行そこらなのでおいおい読んで理解していきたいとは思う。
基本原理はlogread -fした結果をいい感じに取り込んでLokiにたたきつけているだけのはずだが、この「いい感じ」が難しく、重くなっていると考えている。例えばログの取得漏れや、重複取得などを考慮しないといけないので、なんかそこら辺をいい感じにやってもらうようにLLMに指示したら一気に重くなった。ベースのコードは私が書いていたのだが、全くの別物になってしまった。
しかし去年の8月にしかかって放置している部分はできていないので、またそこは追々やっていきたいところだ。具体的には今回の対応はサーバー側でメトリクスを見る対応なのでネットワークが死ぬと終わってしまう。そこでルーター側でも簡易に見れるのを作ろうという計画がある。
しかしルーター側はスペックがしょぼいので大したことはできないし、ストレージがeMMCなので頻繁な書き込みもできないから、普段はメモリストレージ(/tmp)に置いておき、定期的に永続化のためにeMMCに吐き出すというのをやろうとしている。
そしてeMMCに端に吐き出すのもパフォーマンスと寿命の影響があるのでファイルシステムレベルでの対策をしてやろうみたいなことを考えていたが、尻切れとんぼのままなので、何とかしていきたいところだ。








