[{"data":1,"prerenderedAt":1314},["ShallowReactive",2],{"content:\u002Fja\u002Ffiddling\u002Fopnsense-transparent-proxy":3,"series:content_ja":597},{"id":4,"title":5,"authorship":6,"body":7,"categories":567,"date":569,"description":570,"draft":571,"extension":572,"image":573,"meta":574,"navigation":576,"path":577,"permalink":578,"published":578,"readingTime":579,"recommend":578,"references":578,"seo":584,"seoDescription":585,"seoTitle":578,"sitemap":586,"stem":587,"tags":588,"type":595,"__hash__":596},"content_ja\u002Fposts\u002Ffiddling\u002Fopnsense-transparent-proxy.md","OPNsenseで透過プロキシとトラフィック振り分けを実現する","human-only",{"type":8,"value":9,"toc":549},"minimark",[10,14,26,44,47,50,53,63,66,70,74,77,89,102,112,115,123,126,140,144,154,160,168,178,182,185,191,197,200,244,247,280,283,333,336,340,343,346,349,352,358,361,364,368,371,374,390,396,402,412,415,423,429,435,441,447,454,457,463,466,471,479,485,488,491,498,505,508,512,515,518,521,527,534,537,540,543,546],[11,12,13],"h3",{"id":13},"はじめに",[15,16,17,18,25],"p",{},"以前は、iKuaiをメインルーター、OpenWrtをサイドルーターにして透過プロキシと振り分けを行っていました。ネット上の解説でも主流の構成です。その後、iKuaiが",[19,20,24],"a",{"href":21,"rel":22},"https:\u002F\u002Fwusiyu.me\u002F2022-ikuai-non-cloud-background-activities\u002F",[23],"nofollow","裏で勝手に通信したり情報を送信したりする可能性","を知りました。中国製のクローズドソースOSという点でも、安全性に不安がありました。",[15,27,28,29,33,34,38,39,43],{},"その後、",[19,30,32],{"href":31},"\u002Fja\u002Ffiddling\u002Fdebian-as-bypass-router","OpenWrtをメインルーター、Debianをサイドルーターにする構成","へ移りました。さらにサイドルーター方式をやめ、",[19,35,37],{"href":36},"\u002Fja\u002Ffiddling\u002Ffake-ip-based-transparent-proxy","FakeIPベースの振り分け","、",[19,40,42],{"href":41},"\u002Fja\u002Ffiddling\u002Fmore-accurate-chnroute","BGPベースの振り分け","を順に試し、最終的にBGP方式に落ち着きました。",[15,45,46],{},"最近、OPNsenseというファイアウォール・ルーターOSを知りました。まさに理想のルーターOSです。無料でオープンソース、画面もきれいで機能も充実し、振り分け用IPリストの自動更新までGUIで設定できます。今の構成を移し、検閲回避用のソフトウェアルーターを別に置かず、Clashもメインルーターへ直接統合することにしました。",[15,48,49],{},"調べても関連する解説は少なく、古くて動かないものもありました。いくつか落とし穴にはまったので、詳しい手順をまとめることにしました。",[15,51,52],{},"実現したい機能は次のとおりです。",[54,55,56,60],"ul",{},[57,58,59],"li",{},"DNSをClashへ転送して一括で名前解決する。",[57,61,62],{},"OPNsenseに入った通信をリストに基づいて振り分け、一部をClashへ送る。",[15,64,65],{},"OPNsense本体のインストールは、ネット上に説明が多いので省略します。",[11,67,69],{"id":68},"clashのインストール","Clashのインストール",[71,72,73],"h4",{"id":73},"バイナリと設定ファイル",[15,75,76],{},"DNS解決も通信の処理もClashに依存するので、まずClashを入れます。",[15,78,79,80,84,85,88],{},"OPNsenseへSSHで接続します。SSHを有効にする方法？ そこは自分でググってください（STFW）。バイナリ、設定、関連ファイルを置く",[81,82,83],"code",{"code":83},"\u002Fusr\u002Flocal\u002Fclash","を作成します。まだメインルーターで検閲回避できず直接ダウンロードが遅いので、バイナリはscpで送るのがおすすめです。バイナリと設定をこのディレクトリへアップロードし、名前をそれぞれclashと",[81,86,87],{"code":87},"config.yaml","にします。",[15,90,91,92,97,98,101],{},"Mihomoの",[19,93,96],{"href":94,"rel":95},"https:\u002F\u002Fgithub.com\u002FMetaCubeX\u002Fmihomo\u002Freleases",[23],"Releases","から最新コアを入手します。FreeBSD版を選び、マシンに合わせて386、amd64、arm64を選択してください。amd64で後ほどClashを実行した際に次のエラーが出たら、",[81,99,100],{"code":100},"amd64-compatible","版を使います。",[103,104,110],"pre",{"className":105,"code":107,"language":108,"meta":109},[106],"language-shell","This PROGRAM can only be run on _AMD64 processors with v3 microarchitecture_ support.\n","shell","",[81,111,107],{"__ignoreMap":109},[15,113,114],{},"設定ファイルは普段使っているものでかまいませんが、次の部分を変更してください。",[103,116,121],{"className":117,"code":119,"language":120,"meta":109},[118],"language-yaml","mixed-port: 7890\n\ndns:\n  listen: 127.0.0.1:5353\n\ntun:\n  enable: false\n","yaml",[81,122,119],{"__ignoreMap":109},[15,124,125],{},"DNSは5353番で待ち受け、OPNsense標準DNSの上流にします。またTUNを無効にし、Clash自身は通信を取り込まず、OPNsenseが選別して渡すようにします。mixed-portはSOCKS、HTTP、HTTPSプロキシの機能を兼ねます。",[15,127,128,131,132,135,136,139],{},[81,129,130],{"code":130},"pw user add clash -c \"Clash\" -s \u002Fusr\u002Fsbin\u002Fnologin","でログイン不可のclashユーザーを作り、",[81,133,134],{"code":134},"chown clash:clash \u002Fusr\u002Flocal\u002Fclash","でディレクトリの所有権を与えます。その後",[81,137,138],{"code":138},"\u002Fusr\u002Flocal\u002Fclash\u002Fclash -d \u002Fusr\u002Flocal\u002Fclash","を実行し、正常に動くか確認します。",[71,141,143],{"id":142},"clashのサービス登録","Clashのサービス登録",[15,145,146,149,150,153],{},[81,147,148],{"code":148},"\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Fclash","と",[81,151,152],{"code":152},"\u002Fusr\u002Flocal\u002Fopnsense\u002Fservice\u002Fconf\u002Factions.d\u002Factions_clash.conf","を作り、Clashをシステムサービスとして登録します。",[103,155,158],{"className":156,"code":157,"language":108,"meta":109},[106],"#!\u002Fbin\u002Fsh\n# $FreeBSD$\n\n# PROVIDE: clash\n# REQUIRE: LOGIN cleanvar\n# KEYWORD: shutdown\n\n# Add the following lines to \u002Fetc\u002Frc.conf to enable clash:\n# clash_enable (bool): Set to \"NO\" by default.\n# Set to \"YES\" to enable clash.\n# clash_config (path): Clash config dir.\n# Defaults to \"\u002Fusr\u002Flocal\u002Fetc\u002Fclash\"\n\n. \u002Fetc\u002Frc.subr\n\nname=\"clash\"\nrcvar=clash_enable\n\nload_rc_config $name\n\n: ${clash_enable:=\"NO\"}\n: ${clash_config=\"\u002Fusr\u002Flocal\u002Fclash\"}\n\ncommand=\"\u002Fusr\u002Flocal\u002Fclash\u002Fclash\"\n#pidfile=\"\u002Fvar\u002Frun\u002Fclash.pid\"\nrequired_files=\"${clash_config}\"\nclash_group=\"clash\"\nclash_user=\"clash\"\n\ncommand_args=\"-d $clash_config\"\n\nrun_rc_command \"$1\"\n",[81,159,157],{"__ignoreMap":109},[103,161,166],{"className":162,"code":164,"language":165},[163],"language-text","[start]\ncommand:\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Fclash onestart\ntype:script\nmessage:starting clash\n\n[stop]\ncommand:\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Fclash stop\ntype:script\nmessage:stoping clash\n\n[status]\ncommand:\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Fclash statusexit 0\ntype:script_output\nmessage:get clash status\n\n[restart]\ncommand:\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Fclash onerestart\ntype:script\nmessage:restarting clash\n","text",[81,167,164],{"__ignoreMap":109},[15,169,170,173,174,177],{},[81,171,172],{"code":172},"chmod +x \u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Fclash","で実行権限を付け、",[81,175,176],{"code":176},"service configd restart","で有効にします。",[71,179,181],{"id":180},"clashの自動起動","Clashの自動起動",[15,183,184],{},"次はClashの自動起動ですが、落とし穴があります。",[186,187,188],"blockquote",{},[15,189,190],{},"Clashをシステムサービスとして起動しても、起動後にバックグラウンドへ移る機能がありません。そのため再起動時にClashまで進むと止まってしまい、フォアグラウンドに居続けるClashの後ろにあるサービスが起動できません。",[15,192,193,194,177],{},"回り道ですが、OPNsense標準の監視機能MonitでClashを起動・監視する方法があります。",[81,195,196],{"code":196},"サービス → Monit",[15,198,199],{},"Service Test Settingsにテストを2つ追加します。1つ目はClashを起動するためです。",[201,202,203,216],"table",{},[204,205,206],"thead",{},[207,208,209,213],"tr",{},[210,211,212],"th",{},"Setting",[210,214,215],{},"Value",[217,218,219,228,236],"tbody",{},[207,220,221,225],{},[222,223,224],"td",{},"Name",[222,226,227],{},"Clash",[207,229,230,233],{},[222,231,232],{},"Condition",[222,234,235],{},"failed host 127.0.0.1 port 7890 type tcp",[207,237,238,241],{},[222,239,240],{},"Action",[222,242,243],{},"Restart",[15,245,246],{},"2つ目は再起動ループを防ぐためです。",[201,248,249,257],{},[204,250,251],{},[207,252,253,255],{},[210,254,212],{},[210,256,215],{},[217,258,259,266,273],{},[207,260,261,263],{},[222,262,224],{},[222,264,265],{},"RestartLimit4",[207,267,268,270],{},[222,269,232],{},[222,271,272],{},"5 restarts within 5 cycles",[207,274,275,277],{},[222,276,240],{},[222,278,279],{},"Unmonitor",[15,281,282],{},"最後にService Settingsで次を追加します。",[201,284,285,293],{},[204,286,287],{},[207,288,289,291],{},[210,290,212],{},[210,292,215],{},[217,294,295,301,309,317,325],{},[207,296,297,299],{},[222,298,224],{},[222,300,227],{},[207,302,303,306],{},[222,304,305],{},"Match",[222,307,308],{},"clash",[207,310,311,314],{},[222,312,313],{},"Start",[222,315,316],{},"\u002Fusr\u002Flocal\u002Fsbin\u002Fconfigctl clash start",[207,318,319,322],{},[222,320,321],{},"Stop",[222,323,324],{},"\u002Fusr\u002Flocal\u002Fsbin\u002Fconfigctl clash stop",[207,326,327,330],{},[222,328,329],{},"Tests",[222,331,332],{},"Clash,RestartLimit4",[15,334,335],{},"保存して少し待ち、Monit → StatusでClashが正常に動いているか確認します。",[11,337,339],{"id":338},"dns解決","DNS解決",[15,341,342],{},"OPNsense標準のUnbound DNSで上流をClashの127.0.0.1:5353にしたところ、名前解決がずっと失敗しました。何とも不思議です。",[15,344,345],{},"どうしても原因がわからず、結局Unbound DNSを止め、AdGuard Homeを標準DNSに戻して53番ポートを使わせました。",[15,347,348],{},"AdGuard HomeはOPNsense標準のプラグインリポジトリにないので、コミュニティリポジトリを手動で追加します。",[15,350,351],{},"OPNsenseにSSHで入り、次を実行します。",[103,353,356],{"className":354,"code":355,"language":108,"meta":109},[106],"$ fetch -o \u002Fusr\u002Flocal\u002Fetc\u002Fpkg\u002Frepos\u002Fmimugmail.conf https:\u002F\u002Fwww.routerperformance.net\u002Fmimugmail.conf\n$ pkg update\n",[81,357,355],{"__ignoreMap":109},[15,359,360],{},"Web GUIのシステム → ファームウェア → プラグインでadguardを検索し、os-adguardhome-maxitをインストールします。サービス → Adguardhomeから有効にできます。管理画面は3000番です。初期設定は省きますが、DNSの待受ポートは53にし、OPNsenseマシンの標準DNSサーバーとして使ってください。",[15,362,363],{},"AdGuard Homeの設定 → DNS設定で、上流DNSをClashの待受アドレス127.0.0.1:5353にします。",[11,365,367],{"id":366},"中国国内国外ipの振り分け","中国国内・国外IPの振り分け",[71,369,73],{"id":370},"バイナリと設定ファイル-1",[15,372,373],{},"OPNsenseにはプロキシ用のSquidが標準で入っていますが、HTTP\u002FHTTPSしか扱えず、一般的なTCPやUDPは転送できません。プロキシとしては物足りないので、tun2socksでTCP\u002FUDP通信をClashへ渡す方法を使います。",[15,375,376,377,380,381,386,387,380],{},"バイナリと設定用に",[81,378,379],{"code":379},"\u002Fusr\u002Flocal\u002Ftun2socks","を作成します。",[19,382,385],{"href":383,"rel":384},"https:\u002F\u002Fgithub.com\u002Fxjasonlyu\u002Ftun2socks\u002Freleases",[23],"GitHub Releases","から最新のFreeBSDバイナリをダウンロードし、tun2socksへ改名します。設定ファイル",[81,388,389],{"code":389},"\u002Fusr\u002Flocal\u002Ftun2socks\u002Fconfig.yaml",[103,391,394],{"className":392,"code":393,"language":120,"meta":109},[118],"# debug \u002F info \u002F warning \u002F error \u002F silent\nloglevel: info\n\n# URL format: [protocol:\u002F\u002F]host[:port]\nproxy: socks5:\u002F\u002F127.0.0.1:7890\n\n# URL format: [driver:\u002F\u002F]name\n# TUN 设备名称，避免使用 tun0\ndevice: tun:\u002F\u002Fproxytun2socks0\n\n# Maximum transmission unit for each packet\nmtu: 1500\n\n# Timeout for each UDP session, default value: 60 seconds\nudp-timeout: 120s\n",[81,395,393],{"__ignoreMap":109},[15,397,398,401],{},[81,399,400],{"code":400},"proxy","にはClashのSOCKS5ポートのアドレスを指定します。",[15,403,404,407,408,411],{},[81,405,406],{"code":406},"\u002Fusr\u002Flocal\u002Ftun2socks\u002F","で",[81,409,410],{"code":410},".\u002Ftun2socks -config .\u002Fconfig.yaml","を実行し、設定が正しいか確認できます。",[71,413,414],{"id":414},"サービスの登録",[15,416,417,149,420,380],{},[81,418,419],{"code":419},"\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Ftun2socks",[81,421,422],{"code":422},"\u002Fusr\u002Flocal\u002Fopnsense\u002Fservice\u002Fconf\u002Factions.d\u002Factions_tun2socks.conf",[103,424,427],{"className":425,"code":426,"language":108,"meta":109},[106],"#!\u002Fbin\u002Fsh\n\n# PROVIDE: tun2socks\n# REQUIRE: LOGIN\n# KEYWORD: shutdown\n\n. \u002Fetc\u002Frc.subr\n\nname=\"tun2socks\"\nrcvar=\"tun2socks_enable\"\n\nload_rc_config $name\n\n: ${tun2socks_enable:=no}\n: ${tun2socks_config:=\"\u002Fusr\u002Flocal\u002Ftun2socks\u002Fconfig.yaml\"}\n\npidfile=\"\u002Fvar\u002Frun\u002F${name}.pid\"\ncommand=\"\u002Fusr\u002Flocal\u002Ftun2socks\u002Ftun2socks\"\ncommand_args=\"-config ${tun2socks_config} > \u002Fdev\u002Fnull 2>&1 & echo \\$! > ${pidfile}\"\n\nstart_cmd=\"${name}_start\"\n\ntun2socks_start()\n{\n    if [ ! -f ${tun2socks_config} ]; then\n        echo \"${tun2socks_config} not found.\"\n        exit 1\n    fi\n    echo \"Starting ${name}.\"\n    \u002Fbin\u002Fsh -c \"${command} ${command_args}\"\n}\n\nrun_rc_command \"$1\"\n",[81,428,426],{"__ignoreMap":109},[103,430,433],{"className":431,"code":432,"language":165},[163],"[start]\ncommand:\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Ftun2socks start\nparameters:\ntype:script\nmessage:starting tun2socks\n\n[stop]\ncommand:\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Ftun2socks stop\nparameters:\ntype:script\nmessage:stopping tun2socks\n\n[restart]\ncommand:\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Ftun2socks restart\nparameters:\ntype:script\nmessage:restarting tun2socks\n\n[status]\ncommand:\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Ftun2socks status; exit 0\nparameters:\ntype:script_output\nmessage:request tun2socks status\n",[81,434,432],{"__ignoreMap":109},[15,436,437,440],{},[81,438,439],{"code":439},"\u002Fetc\u002Frc.conf","を作成して次を追加します。",[103,442,445],{"className":443,"code":444,"language":165},[163],"tun2socks_enable=\"YES\"\n",[81,446,444],{"__ignoreMap":109},[15,448,449,173,452,177],{},[81,450,451],{"code":451},"chmod +x \u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Ftun2socks",[81,453,176],{"code":176},[15,455,456],{},"tun2socksも手動で起動します。",[103,458,461],{"className":459,"code":460,"language":108,"meta":109},[106],"\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Ftun2socks start\n",[81,462,460],{"__ignoreMap":109},[71,464,465],{"id":465},"自動起動",[15,467,468,380],{},[81,469,470],{"code":470},"\u002Fusr\u002Flocal\u002Fetc\u002Frc.syshook.d\u002Fearly\u002F60-tun2socks",[103,472,477],{"className":473,"code":475,"language":476,"meta":109},[474],"language-bash","#!\u002Fbin\u002Fsh\n\n# Start tun2socks service\n\u002Fusr\u002Flocal\u002Fetc\u002Frc.d\u002Ftun2socks start\n","bash",[81,478,475],{"__ignoreMap":109},[15,480,481,484],{},[81,482,483],{"code":483},"chmod +x \u002Fusr\u002Flocal\u002Fetc\u002Frc.syshook.d\u002Fearly\u002F60-tun2socks","で実行権限を付ければ完了です。",[71,486,487],{"id":487},"インターフェースとゲートウェイの作成",[15,489,490],{},"OPNsenseのインターフェース → 割り当てで新しいインターフェースを追加し、デバイスに設定ファイルで指定したproxytun2socks0を選んで保存します。",[15,492,493,494,497],{},"追加したインターフェースの設定画面で有効化し、説明をTUN2SOCKS、IPv4設定タイプを静的IPv4、IPv4アドレスを",[81,495,496],{"code":496},"10.0.3.1\u002F24","として保存します。",[15,499,500,501,504],{},"システム → ゲートウェイ → 設定で、TUN2SOCKS_MIHOMOというゲートウェイを作ります。インターフェースはTUN2SOCKS、IPアドレスは",[81,502,503],{"code":503},"10.0.3.2","、ほかは標準のまま保存します。",[15,506,507],{},"これで、このゲートウェイへ入った通信は127.0.0.1:7890へ転送され、Clashがプロキシします。",[71,509,511],{"id":510},"中国国内国外ipの振り分け設定","中国国内・国外IPの振り分け設定",[15,513,514],{},"私にとってOPNsenseで特に便利なのが、ファイアウォール → エイリアスです。IPリストを定義し、そのままルールで参照できます。手動入力だけでなく、URLを登録して動的に取得することもできます。",[15,516,517],{},"ファイアウォール → エイリアスで、2つ追加します。",[15,519,520],{},"1つ目はLANのアドレス範囲を表すInternalAddressです。タイプをNetwork(s)にし、内容は次のとおりにします。",[103,522,525],{"className":523,"code":524,"language":165},[163],"0.0.0.0\u002F8\n127.0.0.0\u002F8\n10.0.0.0\u002F8\n172.16.0.0\u002F12\n192.168.0.0\u002F16\n169.254.0.0\u002F16\n224.0.0.0\u002F4\n240.0.0.0\u002F4\n",[81,526,524],{"__ignoreMap":109},[15,528,529,530],{},"2つ目は中国国内のIP範囲を表すCN_V4です。タイプはURL Table (IPs)にし、中国国内の全ネットワーク範囲を含むリストのURLを入力します。たとえば、次のURLです：",[19,531,532],{"href":532,"rel":533},"https:\u002F\u002Fraw.githubusercontent.com\u002Fgaoyifan\u002Fchina-operator-ip\u002Frefs\u002Fheads\u002Fip-lists\u002Fchina.txt",[23],[15,535,536],{},"続いてファイアウォール → ルール → LANの先頭に2つのルールを追加します。上からの順序に注意してください。",[15,538,539],{},"1つ目は宛先をInternalAddressにし、ほかは標準設定にします。LAN宛てを通常のルールでルーティングする指定です。",[15,541,542],{},"2つ目は宛先をCN_V4にして「宛先／反転」にチェックし、ゲートウェイを先ほどのTUN2SOCKS_MIHOMOにします。中国以外のIP宛てをこのゲートウェイへ転送する指定です。",[15,544,545],{},"その下は既存の標準ルールです。残りの通信は通常どおりに流れ、中国国内のIPには直接接続します。",[15,547,548],{},"Googleにアクセスすると、DNSクエリを受けたAdGuard HomeがClashへ転送し、Googleの実IPが返ります。そのIPへの通信はファイアウォールの2つ目のルールに一致し、TUN2SOCKS_MIHOMOへ送られ、SOCKS5ポートからClashに入ります。これで検閲を回避できます。",{"title":109,"searchDepth":550,"depth":550,"links":551},4,[552,554,559,560],{"id":13,"depth":553,"text":13},3,{"id":68,"depth":553,"text":69,"children":555},[556,557,558],{"id":73,"depth":550,"text":73},{"id":142,"depth":550,"text":143},{"id":180,"depth":550,"text":181},{"id":338,"depth":553,"text":339},{"id":366,"depth":553,"text":367,"children":561},[562,563,564,565,566],{"id":370,"depth":550,"text":73},{"id":414,"depth":550,"text":414},{"id":465,"depth":550,"text":465},{"id":487,"depth":550,"text":487},{"id":510,"depth":550,"text":511},[568],"fiddling","2025-01-16 23:09:00","OPNsenseは、美しい画面と充実した機能を備えるオープンソースのファイアウォール・ルーターです。いくつかの構成を試した末に、透過プロキシやトラフィック振り分けでの可能性に気づきました。BGPベースの振り分けと組み合わせることで安全性と安定性を高められ、IPリストの自動更新で管理もしやすくなります。",false,"md","https:\u002F\u002Fblog-img.774352199.xyz\u002FxA8C1E.webp",{"slots":575},{},true,"\u002Ffiddling\u002Fopnsense-transparent-proxy",null,{"text":580,"minutes":581,"time":582,"words":583},"12 min read",11.38,682800,2276,{"title":5,"description":570},"OPNsenseにmihomo、AdGuard Home、tun2socksを組み込み透過プロキシを構築。IPリストを使うファイアウォール規則とDNS転送、サービス起動を設定します。",{"loc":577},"posts\u002Ffiddling\u002Fopnsense-transparent-proxy",[589,590,591,592,593,594],"OPNsense","FreeBSD","mihomo","tun2socks","透過プロキシ","トラフィック振り分け","tech","N4zWhfj1ZQgZPYADUZqtqjFGTxks9BVVMCXbQXkUIfw",[598,616,633,651,668,686,704,720,738,754,770,786,801,817,834,852,867,884,898,915,933,950,954,971,987,1006,1023,1040,1058,1072,1090,1108,1124,1139,1153,1170,1185,1200,1215,1229,1243,1257,1272,1286,1300],{"categories":599,"date":601,"description":602,"image":603,"path":604,"readingTime":605,"recommend":578,"tags":610,"title":615,"type":595},[600],"daily","2024-09-01 22:03:10","子どもの頃からの胃腸の不調が大学時代には不思議と消えたものの、就職後の夜更かしと飲酒で再発。慢性胃炎との付き合いは一筋縄ではいきませんでした。吐き気や胃のむかつきが日常になり、何度か検査を受けて生活を振り返るうちに、ようやく腰を据えて治療に向き合うようになりました。","https:\u002F\u002Fblog-img.774352199.xyz\u002F0Hr9l5.webp","\u002Fdaily\u002Fanti-chronic-gastritis",{"text":606,"minutes":607,"time":608,"words":609},"7 min read",6.485,389100,1297,[611,612,613,614],"慢性胃炎","受診記録","胃内視鏡検査","健康記録","慢性胃炎の治療記録",{"categories":617,"date":618,"description":619,"image":620,"path":621,"readingTime":622,"recommend":578,"tags":627,"title":632,"type":595},[600],"2022-04-11 00:13:13","『三体』では、劉慈欣が壮大な歴史を通して個人と集団の関係を描いています。西側の民主主義への疑念と、大多数の人々に運命を委ねることへの悲観が、三部作を貫いています。英雄たちが力を尽くしても、その努力は歴史の流れに押し流される。文化大革命から始まる物語に、少数の傑出した人物と平凡な大衆の対立を読み、人間性と社会について考えました。","https:\u002F\u002Fblog-img.774352199.xyz\u002FLTzbFP.webp","\u002Fdaily\u002Fpeople-in-three-body",{"text":623,"minutes":624,"time":625,"words":626},"19 min read",18.495,1109700,3699,[628,629,630,631],"三体","劉慈欣","SF文学","読書ノート","『三体』における「大多数の人々」",{"categories":634,"date":635,"description":636,"image":637,"path":638,"readingTime":639,"recommend":578,"tags":644,"title":650,"type":595},[600],"2024-01-04 02:06:51","2024年の学習目標は、日本語をN2レベルに引き上げること、SICPとTAPLを最後までやり切ること、POSIXを完全に実装したカーネルを作ること、そしてブログのテーマを更新すること。どれも簡単ではありませんが、今年取り組む方向は決まりました。","https:\u002F\u002Fblog-img.774352199.xyz\u002FV3rSQC.webp","\u002Fdaily\u002Fplan2024",{"text":640,"minutes":641,"time":642,"words":643},"1 min read",0.345,20700,69,[645,646,647,648,649],"年間計画","日本語学習","SICP","TAPL","オペレーティングシステム","2024年の学習計画",{"categories":652,"date":653,"description":654,"image":655,"path":656,"readingTime":657,"recommend":578,"tags":662,"title":667,"type":595},[600],"2024-09-28 16:26:00","ByteDanceで働いて3年。変化の速い環境で、時間まで加速したように感じながらも、どうにか心のバランスを保ってきました。杭州のオフィスのベランダから遠くの山を眺めていた入社当初を振り返り、仕事の壁や心境の変化、忙しさの中で自分のペースを探してきた日々を記します。","https:\u002F\u002Fblog-img.774352199.xyz\u002FhnCaht.webp","\u002Fdaily\u002Fwork-for-3-years",{"text":658,"minutes":659,"time":660,"words":661},"20 min read",19.73,1183800,3946,[663,664,665,666],"ByteDance","エンジニアのキャリア","仕事の振り返り","メンタルヘルス","ByteDanceで3年働きながら、ある程度の正気を保つことも不可能ではない",{"categories":669,"date":670,"description":671,"image":672,"path":673,"readingTime":674,"recommend":578,"tags":679,"title":685,"type":595},[568],"2025-05-28 22:09:00","ブログをAstroに移行したところ、従来のGoogle Analytics導入方法では性能面が気になるようになりました。headタグにJavaScriptを直接追加してイベントを送ることはできますが、ページの性能に影響します。そこでpartytownでスクリプトをメインスレッドから切り離し、読み込みを妨げないようにしました。サンプルコードに手を加えることでGoogle Analyticsの導入に成功し、性能とアクセス解析を両立できました。","https:\u002F\u002Fblog-img.774352199.xyz\u002FQ0w4RN.webp","\u002Ffiddling\u002Fastro-google-tag-manager",{"text":675,"minutes":676,"time":677,"words":678},"4 min read",3.455,207300,691,[680,681,682,683,684],"Astro","Google Analytics","Google Tag Manager","Partytown","アクセス解析","AstroにGoogle Analyticsを導入する（Tag Manager編）",{"categories":687,"date":688,"description":689,"image":690,"path":691,"readingTime":692,"recommend":697,"tags":698,"title":703,"type":595},[568],"2023-04-08 13:16:36","新しいプログラミング言語の設計は、難しくも面白い作業です。複雑なコンパイラ理論や機能の実装詳細をいったん脇に置き、コードがコンピューターのどこで動くかに注目すると、言語の作り方が見えてきます。RISC-VI命令セットを出発点に、基盤となる構造、階層化されたシステム、仮想マシンのモデルをたどり、言語の本質を考えます。","https:\u002F\u002Fblog-img.774352199.xyz\u002FuO420B.webp","\u002Ffiddling\u002Fchitchat-about-programming-language",{"text":693,"minutes":694,"time":695,"words":696},"28 min read",27.03,1621800,5406,2,[699,700,701,702],"プログラミング言語設計","型システム","コンパイラ設計","RISC-V","プログラミング言語についての雑談",{"categories":705,"date":706,"description":707,"image":708,"path":709,"readingTime":710,"recommend":550,"tags":715,"title":719,"type":595},[568],"2025-04-18 16:43:12","彼女が仕事で北京から上海に引っ越したので、回線の手配も手伝いました。ところが上海電信の500Mは杭州の1000Mより高く、なんとも納得がいきません。そこで上海での透過プロキシ、特定の通信の杭州経由での外部接続、両拠点のLAN相互接続を目指してネットワークを組むことにしました。杭州側はソフトウェアルーターと無線APのシンプルな構成で、普段から自宅経由で通信できる環境があり、次の挑戦に向けた準備はできています。","https:\u002F\u002Fblog-img.774352199.xyz\u002FO6cAGh.webp","\u002Ffiddling\u002Fcross-city-network-setup",{"text":711,"minutes":712,"time":713,"words":714},"11 min read",10.14,608400,2028,[716,591,717,593,718],"Tailscale","拠点間ネットワーク","ホームネットワーク","上海と杭州の自宅ネットワークをつなぐ",{"categories":721,"date":722,"description":723,"image":724,"path":725,"readingTime":726,"recommend":578,"tags":731,"title":737,"type":595},[568],"2021-12-27 00:09:00","CSAPPの学習では実験が欠かせませんが、Linux環境の構築が壁になりがちです。とくに仮想マシンでは、インストール失敗、互換性、ネットワーク接続などの問題に悩まされます。Windows 10バージョン2004以降なら、WSL（Windows Subsystem for Linux）が有力な選択肢です。従来の仮想マシンの複雑さや性能面の負担を避けながら、Linux環境を手軽に利用できます。","https:\u002F\u002Fblog-img.774352199.xyz\u002FvqOC7N.webp","\u002Ffiddling\u002Fcsapplab0",{"text":727,"minutes":728,"time":729,"words":730},"10 min read",9.585,575100,1917,[732,733,734,735,736],"CSAPP","WSL2","Linux","GDB","実験環境","CSAPP Labの環境構築",{"categories":739,"date":740,"description":741,"image":742,"path":743,"readingTime":744,"recommend":578,"tags":749,"title":753,"type":595},[568],"2024-07-13 17:49:00","Debianをサイドルーターに使うと、OpenWrtやLuCIに依存せず、より安定した柔軟な構成を作れます。Debianを直接設定することでシステムを細かく制御でき、GUIの制約や不安定さを避けられます。一般的なサイドルーター構成と比べて透過プロキシを安定して運用しやすく、性能や効率を重視する場合の選択肢になります。","https:\u002F\u002Fblog-img.774352199.xyz\u002FpPRU5x.webp","\u002Ffiddling\u002Fdebian-as-bypass-router",{"text":745,"minutes":746,"time":747,"words":748},"18 min read",17.525,1051500,3505,[750,751,591,752,593],"Debian","サイドルーター","AdGuard Home","Debianをサイドルーターにする",{"categories":755,"date":756,"description":757,"image":758,"path":759,"readingTime":760,"recommend":578,"tags":765,"title":769,"type":595},[568],"2024-08-16 23:53:00","FakeIPを使った透過プロキシ構成で、従来のサイドルーターの単一障害点、性能不足、複雑なポート転送を改善します。プロキシコアをsing-boxに変えることで、転送性能を高めながら設定も簡単にできます。対応プロトコルが豊富で、従来のClashより最適化も進んでいます。同じ構成はClashでも実現できますが、sing-boxは柔軟な選択肢になります。","https:\u002F\u002Fblog-img.774352199.xyz\u002FS2HHD5.webp","\u002Ffiddling\u002Ffake-ip-based-transparent-proxy",{"text":761,"minutes":762,"time":763,"words":764},"14 min read",13.1,786000,2620,[766,767,593,768,594],"FakeIP","sing-box","ポリシーベースルーティング","FakeIPを使った透過プロキシの振り分け",{"categories":771,"date":772,"description":773,"image":774,"path":775,"readingTime":776,"recommend":578,"tags":781,"title":785,"type":595},[568],"2024-08-15 23:50:00","サイドルーターを導入すると、メインルーターのポート転送が効かなくなることがあります。ゲートウェイをサイドルーターに変えることで通信経路が変わり、メインルーターを前提とした転送が正常に動かなくなるためです。ゲートウェイはアドレスを変換して内部ネットワークの通信を外部へ転送し、各端末は外部との通信にこれを必要とします。この仕組みを理解すると、ポート転送の問題を解決しやすくなります。","https:\u002F\u002Fblog-img.774352199.xyz\u002FmRqws9.webp","\u002Ffiddling\u002Ffix-port-forward-in-bypass-router",{"text":777,"minutes":778,"time":779,"words":780},"6 min read",5.155,309300,1031,[751,782,783,784],"ポート転送","NAT","ネットワークのトラブルシューティング","サイドルーター環境でポート転送が効かない問題を解決する",{"categories":787,"date":788,"description":789,"image":790,"path":791,"readingTime":792,"recommend":578,"tags":796,"title":800,"type":595},[568],"2023-02-02 23:24:55","春節の帰省列車で、Goをベアメタルで動かす記事を読み、低レベルのシステムインターフェースに興味が湧きました。実際に動く実装を見て、高級言語でOSを作る可能性に胸が躍ります。関連研究を調べると先行例も見つかり、積もった熱意は期待に満ちたプロジェクトへと変わりました。しかし、最後は思いどおりにはいきませんでした。","https:\u002F\u002Fblog-img.774352199.xyz\u002FxB1Ni5.webp","\u002Ffiddling\u002Fgo-os",{"text":580,"minutes":793,"time":794,"words":795},11.81,708600,2362,[797,702,649,798,799],"Go","ベアメタルプログラミング","ランタイム","失敗に終わったプロジェクト：楽しくなかった春節の7日間",{"categories":802,"date":803,"description":804,"image":805,"path":806,"readingTime":807,"recommend":578,"tags":812,"title":816,"type":595},[568],"2022-08-15 01:05:01","システムのリファクタリングで、階層ごとのエンティティ変換に苦労しました。ビュー層の商品VO、ドメイン層のentity、永続化層のPOは似ていても、型のわずかな違いで直接変換できず、ディープコピーが面倒になります。そこでリフレクションを使った汎用的な変換処理を実装し、大量のassemblerメソッドを減らして、保守性と柔軟性を高めることにしました。","https:\u002F\u002Fblog-img.774352199.xyz\u002FBlhm0I.webp","\u002Ffiddling\u002Fgolang-deepcopy-between-different-type",{"text":808,"minutes":809,"time":810,"words":811},"5 min read",4.14,248400,828,[797,813,814,815],"リフレクション","ディープコピー","構造体変換","Goで異なる型の構造体をディープコピーする",{"categories":818,"date":819,"description":820,"image":821,"path":822,"readingTime":823,"recommend":578,"tags":827,"title":833,"type":595},[568],"2025-03-31 23:51:00","Appleヘルスケアの心拍数を定期的にサーバーへ同期し、Grafanaで可視化して直感的に確認できるようにしました。Health Auto ExportのREST API機能でHTTPエンドポイントへデータを送り、InfluxDBに保存します。Grafanaのダッシュボードから、自分の心拍数の変化を追ったり分析したりできます。","https:\u002F\u002Fblog-img.774352199.xyz\u002FF4qD2T.webp","\u002Ffiddling\u002Fheart-rate-to-grafana",{"text":675,"minutes":824,"time":825,"words":826},3.76,225600,752,[828,829,830,831,832],"Apple Watch","Health Auto Export","InfluxDB","Grafana","心拍数モニタリング","My Heart Beats for U：心拍数をGrafanaで可視化する",{"categories":835,"date":836,"description":837,"image":838,"path":839,"readingTime":840,"recommend":844,"tags":845,"title":851,"type":595},[568],"2025-06-10 20:18:00","macOSとiPadOS 26では、新しいデザイン言語Liquid Glassが導入され、アイコンやウインドウの印象が一新されました。とくにiPadのアプリをウインドウで扱えるようになったことは、生産性向上のための端末へ進む大きな一歩です。一方、透明なコントロールセンターやLaunchpadの統合には賛否があり、使い勝手には改善の余地もあります。課題はありつつも、今後につながる更新だと感じました。","https:\u002F\u002Fblog-img.774352199.xyz\u002FTPSaLE.webp","\u002Ffiddling\u002Fmacos-26-trial",{"text":606,"minutes":841,"time":842,"words":843},6.94,416400,1388,5,[846,847,848,849,850],"macOS 26","iPadOS 26","Liquid Glass","Apple Intelligence","OS使用感","macOS 26とiPadOS 26を試してみた",{"categories":853,"date":854,"description":855,"image":856,"path":857,"readingTime":858,"recommend":578,"tags":862,"title":866,"type":595},[568],"2026-06-11 10:00:00","今年もWWDCでmacOS 27の新しいApple Intelligenceが登場しました。macOS 26時代の回避方法はもう使えず、引き続きAppleとの知恵比べです。","https:\u002F\u002Fblog-img.774352199.xyz\u002FfOFucm.webp","\u002Ffiddling\u002Fmacos-27-apple-intelligence-chatgpt",{"text":727,"minutes":859,"time":860,"words":861},9.74,584400,1948,[863,849,864,865],"macOS 27","ChatGPT","中国本土向けMac","中国本土向けMacでApple Intelligenceを使う：地域変更からChatGPTの取り出しまで",{"categories":868,"date":869,"description":870,"image":871,"path":872,"readingTime":873,"recommend":578,"tags":877,"title":883,"type":595},[568],"2025-07-20 23:32:00","MoonTVはNext.jsとReactで作った動画集約プラットフォームで、連続ドラマなどを手軽に楽しむためのものです。LibreTVを改善しようとしたことが始まりで、数か月の開発を経て多くの関心と利用を集めています。Cursorのおかげで効率よく開発できた一方、複数環境への対応や複雑なデータ依存関係には苦労しました。ユーザーが増える中、フィードバックを受けて改善を続けています。","https:\u002F\u002Fblog-img.774352199.xyz\u002FnIeONi.webp","\u002Ffiddling\u002Fmoontv-vibe-coding",{"text":711,"minutes":874,"time":875,"words":876},10.98,658800,2196,[878,879,880,881,882],"MoonTV","LunaTV","Vibe Coding","Cursor","AI支援開発","MoonTV：Vibe Codingを試してみた",{"categories":885,"date":886,"description":887,"image":888,"path":889,"readingTime":890,"recommend":578,"tags":894,"title":897,"type":595},[568],"2024-10-07 16:51:00","BGPをもとに中国国内・国外のIPを振り分けることで、透過プロキシの効率と精度を高めます。国外の宛先をFakeIPで識別すれば、メインルーターでより適切に通信を振り分けられます。sing-boxのDNS設定も見直し、DNSクエリを柔軟かつ効率的に処理して、ネットワーク全体の使い勝手を改善します。","https:\u002F\u002Fblog-img.774352199.xyz\u002FMOmM1s.webp","\u002Ffiddling\u002Fmore-accurate-chnroute",{"text":777,"minutes":891,"time":892,"words":893},5.75,345000,1150,[895,896,768,594],"BGP","IPアドレスデータベース","BGPで中国国内・国外IPの振り分けをより正確にする",{"categories":899,"date":900,"description":901,"image":902,"path":903,"readingTime":904,"recommend":578,"tags":909,"title":914,"type":595},[568],"2025-12-14 14:31:00","友人の一言からシミュレーターに興味が湧き、Microsoft Flight Simulatorを購入。地図やモデルはリアルタイム配信、アカウントは再ログインが必要、チュートリアルは見つけにくく、キーボード操作も難しい。結局フライトスティックを買い、Pico VRまで設定してようやく一通り体験できました。","https:\u002F\u002Fblog-img.774352199.xyz\u002FlfhEuE.webp","\u002Ffiddling\u002Fmsfs2024-joystick-and-pico",{"text":905,"minutes":906,"time":907,"words":908},"9 min read",8.96,537600,1792,[910,911,912,913],"Microsoft Flight Simulator 2024","Thrustmaster TCA","PICO VR","フライトシミュレーション","Microsoft Flight Simulator 2024をあれこれ試す",{"categories":916,"date":917,"description":918,"image":919,"path":920,"readingTime":921,"recommend":578,"tags":926,"title":932,"type":595},[568],"2025-06-05 23:26:00","OnePlusからiPhoneへと何度も機種変更するうち、いじる楽しさからエコシステムへの依存へと関心が変わりました。最近、彼女の一言をきっかけに写真を改善しようとOPPO Find X8 Ultraを購入。Apple環境からの移行では、Androidアプリの質のばらつきと代替探しの難しさを改めて感じました。1か月をかけて、異なるプラットフォームの摩擦に折り合いをつけた記録です。","https:\u002F\u002Fblog-img.774352199.xyz\u002F19NIhZ.webp","\u002Ffiddling\u002Fone-month-using-android",{"text":922,"minutes":923,"time":924,"words":925},"15 min read",14.05,843000,2810,[927,928,929,930,931],"Android","OPPO","iOS","スマートフォン使用感","エコシステム移行","Androidに乗り換えて1か月",{"categories":934,"date":935,"description":936,"image":937,"path":938,"readingTime":939,"recommend":578,"tags":943,"title":949,"type":595},[568],"2026-05-11 22:43:00","GitHub Trendingで旅行計画ツールを見つけ、自分でも動かしたくなりました。どうせ新しいVPSを借りるなら、ついでにもう少し、いや、だいぶ色々入れてしまおうと。","https:\u002F\u002Fblog-img.774352199.xyz\u002FBBdDWW.webp","\u002Ffiddling\u002Fone-trek-twenty-stacks",{"text":711,"minutes":940,"time":941,"words":942},10.34,620400,2068,[944,945,946,947,948],"TREK","Docker Compose","Dockge","VPS","セルフホスティング","TREKひとつのつもりが、20個のスタックに",{"categories":951,"date":569,"description":570,"image":573,"path":577,"readingTime":952,"recommend":578,"tags":953,"title":5,"type":595},[568],{"text":580,"minutes":581,"time":582,"words":583},[589,590,591,592,593,594],{"categories":955,"date":956,"description":957,"image":958,"path":959,"readingTime":960,"recommend":553,"tags":964,"title":970,"type":595},[568],"2025-03-15 20:35:00","構文解析では、ユーザー定義型名と通常の変数名を見分けることが課題になります。たとえば`a*b;`は算術式とも宣言とも解釈できます。とくに型指定子に関する文法規則によって変数名が型名と解釈され、正確さや読みやすさに影響します。初期化を伴わない変数宣言は多いため、この曖昧さはソースコードの随所に現れます。","https:\u002F\u002Fblog-img.774352199.xyz\u002F2VKHK9.webp","\u002Ffiddling\u002Fparser-type-variable-ambiguity",{"text":761,"minutes":961,"time":962,"words":963},13.58,814800,2716,[965,966,967,968,969],"構文解析","GLR","シンボルテーブル","スコープ","曖昧性解消","構文解析で型名と変数名の曖昧さを解消する",{"categories":972,"date":973,"description":974,"image":975,"path":976,"readingTime":977,"recommend":578,"tags":981,"title":986,"type":595},[568],"2023-05-24 17:51:09","RISC-Vツールチェーンをインストールするには、まずriscv-gnu-toolchainのソースを取得します。clone時に`--depth=1`を付けるとダウンロード量を減らせます。READMEのPrerequisitesを確認し、必要な依存関係をそろえてから進めます。Debianではコマンドで依存パッケージをまとめて導入できます。","https:\u002F\u002Fblog-img.774352199.xyz\u002FrWNOKx.webp","\u002Ffiddling\u002Fspike-install",{"text":675,"minutes":978,"time":979,"words":980},3.89,233400,778,[702,982,983,984,985],"Spike","riscv-pk","クロスコンパイル","ツールチェーン","RISC-Vツールチェーンとエミュレーターのインストール",{"categories":988,"date":989,"description":990,"image":991,"path":992,"readingTime":993,"recommend":997,"tags":998,"title":1005,"type":595},[568],"2026-09-09 23:59:00","これも一種のNTRですよね","https:\u002F\u002Fblog-img.774352199.xyz\u002FNDPUwc.webp","\u002Ffiddling\u002Fsteamdeck-switch-60fps",{"text":761,"minutes":994,"time":995,"words":996},13.905,834300,2781,7,[999,1000,1001,1002,1003,1004],"Steam Deck","Nintendo Switch","EmuDeck","Eden","Lossless Scaling","フレーム生成","Steam Deckの第二の人生：Switchエミュレーター導入からフレーム補間で60FPSまで",{"categories":1007,"date":1008,"description":1009,"image":1010,"path":1011,"readingTime":1012,"recommend":578,"tags":1017,"title":1022,"type":595},[568],"2024-06-23 15:31:32","GFWは単に出口のゲートウェイを監視するのではなく、通信経路の脇から国際通信を傍受します。出入国するIPパケットをクラスタへ複製し、詳しく分析・フィルタリングする仕組みです。どこで何をしているかを理解することは、検閲回避の検討に欠かせません。ネットワーク構成を調べることで、遮断の経路や技術、対処方法が見えてきます。","https:\u002F\u002Fblog-img.774352199.xyz\u002FsOpJuL.webp","\u002Ffiddling\u002Ftech-about-gfw",{"text":1013,"minutes":1014,"time":1015,"words":1016},"25 min read",24.975,1498500,4995,[1018,1019,1020,1021],"GFW","DNSポイズニング","TCP","インターネット検閲","GFWの仕組みを探る",{"categories":1024,"date":1025,"description":1026,"image":1027,"path":1028,"readingTime":1029,"recommend":578,"tags":1033,"title":1039,"type":595},[568],"2022-04-16 00:01:28","Javaでは`this`を使うことで、コンパイラの定数最適化が効かなくなる場合があります。このコード例の`ab1`と`ab2`は同じstatic final変数`s`を参照しているように見えますが、比較結果は異なります。静的変数を直接参照して文字列を連結する`ab1`に対し、`this`経由の`ab2`では同じ定数伝播の最適化が行われません。わずかな構文の違いが、コンパイル結果を変える例です。","https:\u002F\u002Fblog-img.774352199.xyz\u002FgKtkYe.webp","\u002Ffiddling\u002Fthis-in-javac-string-concat",{"text":675,"minutes":1030,"time":1031,"words":1032},3.88,232800,776,[1034,1035,1036,1037,1038],"Java","javac","文字列連結","定数伝播","バイトコード","Javaのthisキーワードでコンパイル時の定数伝播が効かなくなる問題",{"categories":1041,"date":1042,"description":1043,"image":1044,"path":1045,"readingTime":1046,"recommend":578,"tags":1051,"title":1057,"type":595},[568],"2025-01-29 21:58:00","ひとこと投稿機能があれば、静的ブログの記事公開に伴う手間や心理的な負担を減らし、短い思いつきをいつでも共有できます。Cloudflare Workersでバックエンドを実装し、KVで投稿を保存・管理します。フロントエンドはVitePressにVueコンポーネントを埋め込み、投稿を手軽に表示してブログに動きと交流の場を加えます。","https:\u002F\u002Fblog-img.774352199.xyz\u002FhZX6hr.webp","\u002Ffiddling\u002Fvitepress-memos-component",{"text":1047,"minutes":1048,"time":1049,"words":1050},"24 min read",23.345,1400700,4669,[1052,1053,1054,1055,1056],"VitePress","Vue","Cloudflare Workers","Cloudflare KV","マイクロブログ","VitePressにひとこと投稿機能を実装する",{"categories":1059,"date":1060,"description":1061,"image":1062,"path":1063,"readingTime":1064,"recommend":578,"tags":1068,"title":1071,"type":595},[568],"2025-03-15 16:24:00","ある平凡な午後、Telegramの通知で魅力的なVPSプランを見つけました。中国電信CN2直結、帯域2.5Gという好条件です。IPv6付きで動画配信サービスの地域制限解除にも便利ですが、すべての通信をWARP経由にする必要はありません。以前のスクリプトは手軽な一方、速度と振り分けに不満があり、もっと柔軟な方法を探すことにしました。","https:\u002F\u002Fblog-img.774352199.xyz\u002FMcjrrF.webp","\u002Ffiddling\u002Fvps-warp-ipv6",{"text":808,"minutes":1065,"time":1066,"words":1067},4.09,245400,818,[1069,1070,947,768,594],"Cloudflare WARP","IPv6","VPSの特定の通信をWARP経由のIPv6で外に出す",{"categories":1073,"date":1074,"description":1075,"image":1076,"path":1077,"readingTime":1078,"recommend":1082,"tags":1083,"title":1089,"type":595},[568],"2026-08-17 23:59:21","いじればいじるほど、もっといじりたくなります。年を取ってもまだまだ元気、まだまだ元気です。","https:\u002F\u002Fblog-img.774352199.xyz\u002FqfxB0h.webp","\u002Ffiddling\u002Fxiaomi17-root-and-hide-root",{"text":905,"minutes":1079,"time":1080,"words":1081},8.83,529800,1766,6,[1084,1085,1086,1087,1088],"Xiaomi 17","Bootloader","Android Root","ファームウェア書き換え","Rootの隠蔽","Xiaomi 17を普段使いに：ロック解除、ROM書き込み、root化とroot隠し",{"categories":1091,"date":1093,"description":1094,"image":1095,"path":1096,"readingTime":1097,"recommend":578,"tags":1102,"title":1107,"type":595},[1092],"notes","2022-01-20 22:29:00","Lab 1では、masterとworkerという2つの主要な部分からなるMapReduceシステムを実装します。GoのRPCと並行プログラミングを十分に使いこなし、MapReduceの処理の流れも深く理解する必要があります。実装は2つの版を作り、mutexでロックする方式から、よりすっきりしたchannelによる明示的なロックを使わない方式へと改めました。後者のほうが設計もシンプルで分かりやすくなっています。実習を理解する鍵は、関連資料、特にフローチャートとその説明をしっかり読むことです。","https:\u002F\u002Fblog-img.774352199.xyz\u002FibVwPJ.webp","\u002Fnotes\u002F65840\u002Fmapreducelab",{"text":1098,"minutes":1099,"time":1100,"words":1101},"13 min read",12.39,743400,2478,[1103,1104,797,1105,1106],"MIT 6.5840","MapReduce","RPC","並行プログラミング","6.5840 Lab 1：MapReduce",{"categories":1109,"date":1110,"description":1111,"image":1112,"path":1113,"readingTime":1114,"recommend":578,"tags":1118,"title":1123,"type":595},[1092],"2022-01-16 17:32:00","MapReduceは、大規模なデータセットの処理を簡単にするための効率的な並列計算モデルです。利用者はMapとReduceという2つの主要な関数を定義することで、複雑なタスクを簡単な操作に分解できます。データの分配やタスクの割り当てはフレームワークが自動で管理するため、開発者は低レベルの細部に気を取られず、アルゴリズムそのものに集中できます。分散システムで広く使われていることからも、その柔軟性と実用性が分かります。","https:\u002F\u002Fblog-img.774352199.xyz\u002FApIDdC.webp","\u002Fnotes\u002F65840\u002Fmapreducepaper",{"text":905,"minutes":1115,"time":1116,"words":1117},8.085,485100,1617,[1104,1119,1120,1121,1122],"分散システム","論文ノート","並列計算","耐障害性","MapReduce論文を読む",{"categories":1125,"date":1126,"description":1127,"image":1128,"path":1129,"readingTime":1130,"recommend":578,"tags":1134,"title":1138,"type":595},[1092],"2022-12-16 02:06:10","Lab 2Aでは、Raftのリーダー選出とハートビートを実装し、さまざまな厳しい条件でも任期の交代や選挙が正常に行われるようにします。実習全体は4段階からなり、この後に実装する分散KVストアの土台になります。明示的なロックを使わない設計によって、Raft構造体を簡潔にします。実習の手引きには必要な背景知識が載っていますが、前の実習と比べると参考資料に頼れる部分はほとんどなく、自力で実装することが重視されます。","https:\u002F\u002Fblog-img.774352199.xyz\u002Fc11Uk4.webp","\u002Fnotes\u002F65840\u002Fraftlab2a",{"text":745,"minutes":1131,"time":1132,"words":1133},17.515,1050900,3503,[1103,1135,797,1136,1137],"Raft","リーダー選出","分散合意","6.5840 Lab 2A：リーダー選出",{"categories":1140,"date":1141,"description":1142,"image":1143,"path":1144,"readingTime":1145,"recommend":578,"tags":1150,"title":1152,"type":595},[1092],"2022-12-03 21:40:09","Raftは、ログレプリケーションの効率を高めるために設計された合意アルゴリズムです。複数のマシンからなるクラスタに適しており、一部のマシンが故障してもサービスを継続できます。複製状態機械モデルを使い、ログに命令の順序を記録することで、クラスタ内の各マシンが同じ状態に到達できるようにします。論文『In Search of an Understandable Consensus Algorithm』は、Raftの設計思想とPaxosとの比較を詳しく論じ、その理解しやすさを示すとともに、信頼できる大規模なソフトウェアシステムを構築するための土台を提供しています。この記事は、その中心的な概念と応用を理解するための読書メモです。","https:\u002F\u002Fblog-img.774352199.xyz\u002F7mmvIZ.webp","\u002Fnotes\u002F65840\u002Freftextendedpaper",{"text":1146,"minutes":1147,"time":1148,"words":1149},"30 min read",29.245,1754700,5849,[1135,1137,1151,1120],"ログ複製","Raft論文を読む",{"categories":1154,"date":1156,"description":1157,"image":1158,"path":1159,"readingTime":1160,"recommend":1164,"tags":1165,"title":1169,"type":595},[1155],"projects","2021-11-27 14:43:00","MYDBは、データベースの基本原理を学び、実装してみるための個人プロジェクトです。空き時間を使い、半月あまりかけて作りました。大学のデータベースシステムの授業で基礎には触れたものの、インターン中は授業を口実にサボってばかりでした。面接で正直に答えても大きな問題にはなりませんでしたが、それをきっかけに自分の知識を見直し、実際に手を動かして学ぼうと考えるようになりました。そうして生まれたのがこのプロジェクトです。","https:\u002F\u002Fblog-img.774352199.xyz\u002Fxfci2J.webp","\u002Fprojects\u002Fmydb\u002Fmydb0",{"text":905,"minutes":1161,"time":1162,"words":1163},8.03,481800,1606,1,[1166,1034,1167,1168],"MYDB","データベース実装","データベースアーキテクチャ","MYDB 0. プロジェクト構成と、先に伝えておきたいこと",{"categories":1171,"date":1172,"description":1173,"image":1174,"path":1175,"readingTime":1176,"recommend":578,"tags":1181,"title":1184,"type":595},[1155],"2021-11-28 16:10:00","MYDBではXIDファイルでトランザクションを管理します。各トランザクションには1から増える一意のXIDがあり、XID 0は常にコミット済みのスーパートランザクションです。TransactionManagerがこのファイルを管理し、実行中・コミット済み・中止済みという3つの状態を記録します。この仕組みにより状態を正確に照会・管理でき、システムの安定性と信頼性を支えます。","https:\u002F\u002Fblog-img.774352199.xyz\u002FH4zZAK.webp","\u002Fprojects\u002Fmydb\u002Fmydb1",{"text":1177,"minutes":1178,"time":1179,"words":1180},"8 min read",7.42,445200,1484,[1166,1034,1182,1183],"トランザクション管理","XID","MYDB 1. まずはシンプルなTMから",{"categories":1186,"date":1187,"description":1188,"image":1189,"path":1190,"readingTime":1191,"recommend":578,"tags":1195,"title":1199,"type":595},[1155],"2021-12-25 18:26:00","MYDBはMySQLに似たC\u002FS構成を採用し、複数のクライアントがソケットでサーバーへ接続してSQLを実行し、結果を受け取れます。通信には専用のバイナリー形式を使いますが、実装を簡単にするならプレーンテキストも選択肢です。サーバーとクライアントの基本的な転送構造によって、データのやり取りと処理を行います。","https:\u002F\u002Fblog-img.774352199.xyz\u002FPAHrUZ.webp","\u002Fprojects\u002Fmydb\u002Fmydb10",{"text":777,"minutes":1192,"time":1193,"words":1194},5.76,345600,1152,[1166,1034,1196,1197,1198],"Socket","クライアントサーバー構成","通信プロトコル","MYDB 10. サーバー・クライアントの実装と通信プロトコル",{"categories":1201,"date":1202,"description":1203,"image":1204,"path":1205,"readingTime":1206,"recommend":578,"tags":1210,"title":1214,"type":595},[1155],"2021-11-30 23:18:00","データマネージャー（DM）は上位モジュールとファイルシステムをつなぎ、ページとキャッシュを管理しながら、データの安全性と復旧を支えます。キャッシュには従来のLRUではなく参照カウント方式を採用し、汎用性と効率を高めて、この先のデータ操作の土台を作ります。","https:\u002F\u002Fblog-img.774352199.xyz\u002FWdIGoG.webp","\u002Fprojects\u002Fmydb\u002Fmydb2",{"text":711,"minutes":1207,"time":1208,"words":1209},10.395,623700,2079,[1166,1034,1211,1212,1213],"参照カウント","キャッシュ設計","共有メモリ","MYDB 2. 参照カウント方式のキャッシュ基盤と共有バイト配列",{"categories":1216,"date":1217,"description":1218,"image":1219,"path":1220,"readingTime":1221,"recommend":578,"tags":1225,"title":1228,"type":595},[1155],"2021-12-05 15:28:00","DMはファイルシステムをページとして抽象化し、ページ単位で読み書きとキャッシュを行います。データページのデフォルトサイズは8Kで、大量の書き込みではサイズの調整によって性能を高められます。実装済みの汎用キャッシュ基盤を使い、ここではページ構造を具体的に定義して、効率よくページを管理します。","https:\u002F\u002Fblog-img.774352199.xyz\u002FjlFC4E.webp","\u002Fprojects\u002Fmydb\u002Fmydb3",{"text":1177,"minutes":1222,"time":1223,"words":1224},7.14,428400,1428,[1166,1034,1226,1227],"データページ","キャッシュ管理","MYDB 3. データページのキャッシュと管理",{"categories":1230,"date":1231,"description":1232,"image":1233,"path":1234,"readingTime":1235,"recommend":578,"tags":1239,"title":1242,"type":595},[1155],"2021-12-08 22:55:00","MYDBでは、クラッシュ後にデータを復旧できるよう、ログファイルが重要な役割を担います。DMは下位のデータを操作するたびにログを生成・記録し、連続したログ列を作ります。チェックサムと各操作の記録を含む所定のバイナリー形式で保存することで、再起動時にデータの状態を正確に再構築し、整合性と完全性を保ちます。","https:\u002F\u002Fblog-img.774352199.xyz\u002FTRcbsj.webp","\u002Fprojects\u002Fmydb\u002Fmydb4",{"text":1098,"minutes":1236,"time":1237,"words":1238},12.685,761100,2537,[1166,1034,1240,1241],"データベースログ","クラッシュリカバリ","MYDB 4. ログファイルと復旧戦略",{"categories":1244,"date":1245,"description":1246,"image":1247,"path":1248,"readingTime":1249,"recommend":578,"tags":1253,"title":1256,"type":595},[1155],"2021-12-11 15:16:00","ページインデックスはDM層の重要な構成要素です。各ページの空き容量をキャッシュすることで挿入処理を効率化し、上位モジュールが長い探索をせずに適切なページを素早く見つけられるようにします。実装ではデータ項目（DataItem）の抽象化とも密接に連携し、データベースの効率的な動作を支えます。","https:\u002F\u002Fblog-img.774352199.xyz\u002F22PSG1.webp","\u002Fprojects\u002Fmydb\u002Fmydb5",{"text":727,"minutes":1250,"time":1251,"words":1252},9.86,591600,1972,[1166,1034,1254,1255],"ページインデックス","データ管理","MYDB 5. ページインデックスとDMの実装",{"categories":1258,"date":1259,"description":1260,"image":1261,"path":1262,"readingTime":1263,"recommend":578,"tags":1267,"title":1271,"type":595},[1155],"2021-12-18 14:58:00","VMは二相ロックでスケジュールの直列化可能性を保証し、多版型同時実行制御（MVCC）を導入して読み取りと書き込みの相互ブロックを解消します。また、データベース操作の競合を定義し、特に更新と読み取りの関係を整理することで、トランザクションの分離レベルを理解する土台を作ります。","https:\u002F\u002Fblog-img.774352199.xyz\u002F8YzotA.webp","\u002Fprojects\u002Fmydb\u002Fmydb6",{"text":922,"minutes":1264,"time":1265,"words":1266},14.665,879900,2933,[1166,1034,1268,1269,1270],"MVCC","トランザクション分離","二相ロック","MYDB 6. レコードのバージョンとトランザクション分離",{"categories":1273,"date":1274,"description":1275,"image":1276,"path":1277,"readingTime":1278,"recommend":578,"tags":1282,"title":1285,"type":595},[1155],"2021-12-23 21:20:00","VMでは、MVCCに伴うバージョンの飛び越しとデッドロックに対処する必要があります。MYDBはトランザクションに印を付けるだけで取り消しやロールバックを行い、abortedなトランザクションのデータがほかへ影響しないようにします。この設計により並行処理の効率と信頼性を高め、従来の2PLで起こりがちなデッドロックを避けて、システム全体の安定性と性能を向上させます。","https:\u002F\u002Fblog-img.774352199.xyz\u002FBF3yDW.webp","\u002Fprojects\u002Fmydb\u002Fmydb7",{"text":580,"minutes":1279,"time":1280,"words":1281},11.32,679200,2264,[1166,1034,1283,1284],"デッドロック検出","バージョン管理","MYDB 7. デッドロック検出とVMの実装",{"categories":1287,"date":1288,"description":1289,"image":1290,"path":1291,"readingTime":1292,"recommend":578,"tags":1296,"title":1299,"type":595},[1155],"2021-12-24 21:01:00","MYDBはB+木によるクラスタ化インデックスを実装します。IMはバージョンマネージャー（VM）を経由せず、データマネージャー（DM）と直接やり取りし、インデックスデータをデータベースファイルへ直接書き込みます。この章では二分木インデックスの構造を詳しく説明し、葉フラグ、キー数、兄弟ノードの識別子など、インデックス検索の基盤となる要素を扱います。","https:\u002F\u002Fblog-img.774352199.xyz\u002Ff92X4o.webp","\u002Fprojects\u002Fmydb\u002Fmydb8",{"text":606,"minutes":1293,"time":1294,"words":1295},6.53,391800,1306,[1166,1034,1297,1298],"B+木","データベースインデックス","MYDB 8. インデックス管理",{"categories":1301,"date":1302,"description":1303,"image":1304,"path":1305,"readingTime":1306,"recommend":578,"tags":1310,"title":1313,"type":595},[1155],"2021-12-25 15:44:00","テーブルマネージャー（TBM）は、フィールドとテーブルの構造を管理します。ParserはSQL風の文を構造化して解析し、文に含まれる情報を対応するクラスへまとめることで、その後の操作を簡単にします。この章ではMYDBのSQL構文も紹介し、管理処理全体を理解する土台を作ります。","https:\u002F\u002Fblog-img.774352199.xyz\u002FzOMyv5.webp","\u002Fprojects\u002Fmydb\u002Fmydb9",{"text":1177,"minutes":1307,"time":1308,"words":1309},7.99,479400,1598,[1166,1034,1311,1312],"SQL解析","テーブル管理","MYDB 9. フィールドとテーブルの管理",1789914058386]