hsbox の proxy実装 の続きをしましょう。 httpは通りました https対応に挑戦です。 最初に検証方法を確認しておきましょう。 httpサービスをしていないhttpsのみのサイトを探しましょう そのサイトを使って、送信データを取得できるか検証しましょう。
確認方法の検討 $ curl -I http: //github.com HTTP/1.1 301 Moved Permanently Content-Length: 0 Location: https://github.com/ $ curl -I https: //github.com HTTP/2 200 date: Fri, 28 Nov 2025 02:58:12 GMT content-type: text/html; charset=utf-8 vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With, Accept-Language,Accept-Encoding, Accept, X-Requested-With content-language: en-US etag: W/"06826aee56dafc29be870ab3e992ec77" cache-control: max-age=0, private, must-revalidate strict-transport-security: max-age=31536000; includeSubdomains; preload ---以下省略 guithub.comのトップでhttpsへのプロキシが効くが確認することにします。
最初の状態 でのProxy動作を確認してみます
$ curl -x http://192.168.2.45:8080 http://github.com 何も応答がありません。 まだ、Proxyが自動的にhttpsに変換していないようです。
プロキシをとおしてプロキシでポストデータを取得するのが目的です。 この場合、POSTはhttpsではなくhttpで送られる必要があるでしょう。そして、プロキシでhttpsに変換する。 そのような使い方をしたいので、 mitmproxy の 設定方法を変更します。
mitmproxy 用解析・保存スクリプトを更新配置(仮2) ■/home/hsbox/pyd/fm_capture.py を更新配置 (内容は以下) #!/usr/bin/env python3 # -*- coding: utf-8 -*- # File: ~/fm_capture.py import json import os from datetime import datetime from mitmproxy import http from mitmproxy import ctx DATA_DIR = "/home/hsbox/fm_data" # ← 自分のホームに合わせて変更 os.makedirs(DATA_DIR, exist_ok=True) # fm_capture.py の先頭に追加 force_https_domains = { "www.frontier-monitor.com", "github.com", # ここに対象ドメインを全部書く(または全部強制したいなら条件を緩く) } def request(flow): host = flow.request.pretty_host if host in force_https_domains or host.endswith(".example.com"): if flow.request.scheme == "http": flow.request.scheme = "https" flow.request.port = 443 def response(flow: http.HTTPFlow): # フロンティアモニターの送信先だけを対象にする if "frontier-monitor.com" not in flow.request.pretty_host: return if flow.request.path.startswith("/upload/data.php"): # 実際のURLに合わせて調整可 try: # POSTされたJSONを取得 raw = flow.request.get_text() data = json.loads(raw) # タイムスタンプを付与(モニターの時刻を優先) timestamp = data.get("timestamp", datetime.now().isoformat()) # 1. 生JSONを保存(デバッグ用) raw_file = f"{DATA_DIR}/raw_{timestamp.replace(':', '-')}.json" with open(raw_file, "w") as f: f.write(raw) # 2. 最新データを上書き保存 latest_file = f"{DATA_DIR}/latest.json" with open(latest_file, "w") as f: json.dump(data, f, indent=2) # 3. SQLiteに挿入(初回はテーブル自動作成) import sqlite3 db_path = f"{DATA_DIR}/fm_data.db" conn = sqlite3.connect(db_path) cur = conn.cursor() cur.execute(""" CREATE TABLE IF NOT EXISTS power ( ts TEXT PRIMARY KEY, generation INTEGER, consumption INTEGER, grid_buy INTEGER, grid_sell INTEGER, temperature REAL, status INTEGER ) """) cur.execute(""" INSERT OR REPLACE INTO power VALUES (?, ?, ?, ?, ?, ?, ?) """, ( timestamp, data.get("generation"), data.get("consumption"), data.get("grid_buy"), data.get("grid_sell"), data.get("temperature"), data.get("status") )) conn.commit() conn.close() ctx.log.info(f"[FM] データ保存成功 → {timestamp}") except Exception as e: ctx.log.error(f"[FM] エラー: {e}") systemd サービスファイルの更新 [Unit] Description=Frontier Monitor Transparent Proxy After=network.target Wants=network.target [Service] Type=simple User=hsbox Environment="PATH=/home/hsbox/.local/bin:/usr/local/bin:/usr/bin:/bin" ExecStart=/home/hsbox/.local/bin/mitmdump --mode regular --listen-host 0.0.0.0 --listen-port 8080 --set upstream_cert=false --showhost --proxyauth ユーザー名:パスワード@ --script /home/hsbox/pyd/fm_capture.py --quiet Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ※ユーザー名とパスワード を設定してください。 使用しない場合、”–proxyauth”の設定は不要です。 上の設定をしたら、設定反映と起動、起動確認を行います。
動作確認 ■curlで、 動作検証します。 curl -x http://<プロキシが動作するhsboxのIP>:8080 http://github.com/ 実行結果例: curl -x http://192.168.1.10:8080 http://github.com <!DOCTYPE html> <html lang="en" data-color-mode="dark" data-dark-theme="dark" data-color-mode="light" data-light-theme="light" data-dark-theme="dark" data-a11y-animated-images="system" data-a11y-link-underlines="true" > <head> <meta charset="utf-8"> <link rel="dns-prefetch" href="https://github.githubassets.com"> <link rel="dns-prefetch" href="https://avatars.githubusercontent.com"> <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com"> <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/"> <link rel="preconnect" href="https://github.githubassets.com" crossorigin> <link rel="preconnect" href="https://avatars.githubusercontent.com"> <link crossorigin="anonymous" rel="preload" as="script" href="https://github.githubassets.com/assets/global-banner-disable-54e442fb573b.js" /> <link rel="preload" href="https://github.githubassets.com/assets/mona-sans-14595085164a.woff2" as="font" type="font/woff2" crossorigin>※これで、proxyで、httpをhttpsに変換してアクセスできていそうです。 NAS設定の修正 11月 28 23:03:07 hsbox systemd[1]: Started Frontier Monitor Transparent Proxy. 11月 28 23:03:45 hsbox mitmproxy[1050039]: POST CAPTURE FAILED: [Errno 13] Permission denied: ‘/mnt/nas/solar_data/capture_20251128.log’
NASの書き込み権限がないため書き込めません、mitmproxyは、hsbox権限で起動しているので、権限を777に設定します。 しかし、smbマウントしていると、chmodでは、権限を設定できません。NAS側のGUI等で、ログインユーザの権限等でフルアクセスできるように設定しておきます。また、暫定対処ですが、起動時に自動マウントするように以下のマウントコマンドを仕込んでおきました。 ※事前に手動実行で操作確認しておいてください
# mitmproxy 用 NAS マウント mount -t cifs //<NASのIP>/share /mnt/<マウントポイント> -o username=user,password=pass,vers=3.0,iocharset=utf8,uid=1000,gid=1000,nounix,cache=none,nolease && logger "NAS mounted for mitmproxy by startup script" mitmproxy 用解析・保存スクリプトを更新配置(仮3) キャプチャデータをローカルおよびNASに保存するスプリプとに更新します。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import os from datetime import datetime from mitmproxy import http from urllib.parse import urlencode LOG_DIR = "/home/hsbox/fm_data" # まずローカルで確認 #LOG_DIR = "/mnt/nas/solar_data" os.makedirs(LOG_DIR, exist_ok=True, mode=0o777) def request(flow): host = flow.request.pretty_host if host in {"www.frontier-monitor.com", "github.com"}: if flow.request.scheme == "http": flow.request.scheme = "https" flow.request.port = 443 def response(flow: http.HTTPFlow): # POSTじゃなければ完全スルー(無駄な書き込みゼロ) #if flow.request.method != "POST": # return now = datetime.now().strftime("%Y%m%d") logfile = f"{LOG_DIR}/capture_{now}.log" post_data = "" if flow.request.urlencoded_form: post_data = urlencode(flow.request.urlencoded_form) elif flow.request.multipart_form: post_data = urlencode(flow.request.multipart_form) elif flow.request.text: post_data = flow.request.text # 空のPOSTは記録しない(必要なら残す) if not post_data.strip(): return entry = { "ts": datetime.now().isoformat(), "host": flow.request.pretty_host, "url": flow.request.pretty_url, "post": post_data } try: with open(logfile, "a", encoding="utf-8", buffering=1) as f: f.write(json.dumps(entry, ensure_ascii=False) + "\n") f.flush() os.fsync(f.fileno()) except Exception as e: os.system(f'logger -t mitmproxy "POST CAPTURE FAILED: {e}"') 手動でポストをシミュレーションして動作確認 httpsのサイトに手動でポストしてみたデータを保存できるか検証します
~$ curl -x http://<hsBoxのIP>:8080 --insecure -X POST -d "test=2111 1&name=フロンティア " http://github.com <!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Security-Policy" content="default-src 'none'; base-uri 'self'; connect-src 'self'; form-action 'self'; img-src 'self' data:; script-src 'self'; style-src 'unsafe-inline'"> <meta content="origin" name="referrer"> <title>Page not found · GitHub</title> <style type="text/css" media="screen"> 保存されたデータを確認 {“ts”: “2025-11-29T10:13:24.269169”, “host”: “github.com”, “url”: “https://github.com/”, “post”: “test=11111&name=%C3%A3%C2%83%C2%95%C3%A3%C2%83%C2%AD%C3%A3%C2%83%C2%B3%C3%A3%C2%83%C2%86%C3%A3%C2%82%C2%A3%C3%A3%C2%82%C2%A2”}{“ts”: “2025-11-29T10:52:06.845328”, “host”: “github.com”, “url”: “https://github.com/”, “post”: “test=21111&name=%C3%A3%C2%83%C2%95%C3%A3%C2%83%C2%AD%C3%A3%C2%83%C2%B3%C3%A3%C2%83%C2%86%C3%A3%C2%82%C2%A3%C3%A3%C2%82%C2%A2 “}
1回のポストで1行追加されました。
ポストしたデータが丸ごと入っていることを確認できました。 これでキャプチャ成功です。 NASへの保存も成功です。
ハードルが複数あるので、着実に1つづつクリアしていくのが、近道でしょう。
・–quiet にしないとサービス起動できない ・サービス起動は通常root相当だが、mitmproxyの起動ユーザはrootではうまく動かない ・書き込みタイミングの課題 ・NASの書き込み権限 ・hsBox独特?の自動マウントの手法
簡単にまとめると権限問題とタイミング問題ですね。開発者あるあるですね。。
関連記事