LibreSpeed の Go バックエンドには Web インターフェースが組み込まれており、ダウンロード、アップロード、レイテンシを測定する HTTP インターフェースを提供します。この記事では、systemd を使って Debian 上でバックエンドを root 以外のユーザーとして実行し、同じホストの Caddy から公開 HTTPS エントリーポイントを提供します。
Debian 用のプリコンパイル済みバイナリをインストール
このINST.iniでは LibreSpeed の speedtest-go v1.1.6 固定で使用し、Debian の amd64 と arm64 に適用できるコマンドを示します。リリースパッケージの speedtest-backend にはデフォルトのフロントエンドアセットが組み込まれています。その他のアーキテクチャについては公式リリースページを確認してください。
sudo apt update
sudo apt install curl ca-certificates
(
set -eu
version=1.1.6
arch=$(dpkg --print-architecture)
case "$arch" in
amd64|arm64) ;;
*) printf 'Select a release archive for %s\n' "$arch" >&2; exit 1 ;;
esac
archive="speedtest-go_${version}_linux_${arch}.tar.gz"
release="https://github.com/librespeed/speedtest-go/releases/download/v${version}"
workdir=$(mktemp -d)
trap 'rm -rf -- "$workdir"' EXIT
cd "$workdir"
curl -fsSL -o "$archive" "$release/$archive"
curl -fsSL -o checksums.txt "$release/checksums.txt"
awk -v file="$archive" '$2 == file || $2 == "*" file' checksums.txt > archive.sha256
sha256sum -c archive.sha256
tar -xzf "$archive"
sudo install -d -m 0755 /usr/local/bin
sudo install -m 0755 speedtest-backend /usr/local/bin/speedtest-backend
)
systemd サービスを設定する
バックエンドはローカルループバックアドレスで待ち受け、Caddy が TLS を終端します。database_type = "none" はスピードテスト結果と統計情報の記録を無効にします。上流の TOML サンプルと systemd ユニットを参照してください。
sudo install -d -m 0755 /etc/speedtest-go
sudo tee /etc/speedtest-go/settings.toml >/dev/null <<'EOF'
bind_address = "127.0.0.1"
listen_port = 8989
proxyprotocol_port = 0
enable_tls = false
enable_http2 = false
database_type = "none"
EOF
sudo tee /etc/systemd/system/speedtest-go.service >/dev/null <<'EOF'
[Unit]
Description=LibreSpeed Go backend
After=network.target
[Service]
ExecStart=/usr/local/bin/speedtest-backend -c /etc/speedtest-go/settings.toml
DynamicUser=yes
Restart=on-failure
RestartSec=3s
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now speedtest-go.service
systemctl is-active speedtest-go.service
ss -ltn 'sport = :8989'
curl -fsS -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1:8989/
サービス状態が active、待ち受けアドレスが 127.0.0.1:8989 となり、リクエストが HTTP 200 を返すことが期待されます。起動に失敗した場合は、sudo journalctl -u speedtest-go.service -n 50 --no-pager を実行してログを確認してください。
Caddy で公開 HTTPS を提供する
speedtest.example.com を公開ドメインに置き換え、DNS レコードを Caddy に向けます。デフォルトの ACME 設定を使って直接公開する場合は、TCP 80 と 443 ポートへ到達できるようにしてください。クライアントからオリジンサーバーへ直接接続する回線を測定する場合は、スピードテスト用ドメインを DNS only に設定してください。CDN プロキシを有効にすると、測定には CDN エッジとオリジンへの経路が含まれます。Caddy の自動 HTTPSと Cloudflare のプロキシステータスを参照してください。
speedtest.example.com {
reverse_proxy 127.0.0.1:8989
}
Caddy とバックエンドが別々のホストにある場合は、バックエンドを Caddy から到達可能なプライベートネットワークまたは WireGuard アドレスにバインドし、reverse_proxy のアップストリームを変更します。また、ファイアウォールでは Caddy ホストのみが 8989/tcp にアクセスできるようにしてください。公開スピードテストサイトを自分だけが使う場合は、既存のアクセス制御をサイト全体へ適用し、アップロードおよびダウンロード用インターフェースも対象にします。
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddy
測定対象のネットワークで https://speedtest.example.com/index-classic.html を開き、完全なスピードテストを1回実行してください。
CLI でスピードテストを行う
Debian 13 では sudo apt install librespeed-cli を実行します。Homebrew がインストール済みの macOS では、brew tap librespeed/tap と brew install librespeed-cli を順番に実行してください。CLI の公式リリースページにもプリコンパイル済みパッケージがあり、Intel Mac では darwin_amd64、Apple チップ搭載モデルでは darwin_arm64 を選んでください。Debian パッケージと LibreSpeed Homebrew tapを参照してください。
cat > librespeed-servers.json <<'EOF'
[
{
"id": 1,
"name": "Self-hosted LibreSpeed",
"server": "https://speedtest.example.com/",
"dlURL": "garbage",
"ulURL": "empty",
"pingURL": "empty",
"getIpURL": "getIP"
}
]
EOF
librespeed-cli --local-json ./librespeed-servers.json --server 1 --no-icmp
--no-icmp により、レイテンシテストも同じ公開 HTTP エントリーポイント経由で行われるようになります。ドメインが IPv4 と IPv6 の両方に対応している場合は、-4 と -6 をそれぞれ追加して比較できます。CLI オプションとカスタムサーバー形式を参照してください。
SSH トンネル、オリジン直接接続、公開ドメインの比較
SSH のローカルポートフォワーディングを利用すると、クライアントからバックエンドへアクセスできます。測定されるスループットは SSH トンネル経由の値になります。別のターミナルで次のコマンドを実行したままにしてください。
ssh -N -o ExitOnForwardFailure=yes \
-L 18989:127.0.0.1:8989 user@debian.example.com
同じクライアント上で、各経路に対して同一のダウンロードリクエストを1回ずつ発行します。203.0.113.10 は Caddy の公開 IPv4 アドレスに置き換えてください。--resolve は接続先アドレスを指定しながら、TLS と HTTP ルーティングに使うドメインを保持します。Go バックエンドは ckSize=16 を受け取ると 16 MiB のデータを返します。バックエンドの実装と curl マニュアルを参照してください。
host=speedtest.example.com
origin=203.0.113.10
path='/garbage?ckSize=16'
probe_download() {
curl -q --noproxy '*' --http1.1 -fsS \
--connect-timeout 5 --max-time 45 -o /dev/null \
-w 'ip=%{remote_ip} http=%{http_version} status=%{http_code} bytes=%{size_download} avg=%{speed_download} B/s\n' \
"$@"
}
probe_download "http://127.0.0.1:18989$path"
probe_download --resolve "$host:443:$origin" "https://$host$path"
probe_download "https://$host$path"
ステータスコードが 200 で、16777216 バイトをダウンロードできた完全な応答だけを比較します。B/s に8を掛け、100万で割ると Mbps になります。公開ドメインを通常の名前解決で参照したときだけ速度が遅い場合は、出力された IP を確認し、CDN を経由しているか、または別の IP プロトコルスタックが使われているかを調べてください。--noproxy '*' は curl に設定された明示的なプロキシを回避しますが、システムレベルの TUN は引き続き経路に影響する可能性があります。
私の実測では、SSH トンネル経由のダウンロードは約 151 Mbps、Caddy へ HTTP/1.1 で直接接続したダウンロードは約 162 Mbps でした。Chrome を HTTP/3 から HTTP/2 に切り替えた後、Web ページ上のスピードテストは改善しました。その後、以前 SSH のほうが常に高速だと考えていたのは、対照テストに誤りがあったことが分かりました。テストでは HTTP/3 が遅く観測されましたが、具体的な原因はまだ特定できていません。
ブラウザーで再測定するときは、同じネットワーク上で同じ /index-classic.html を開き、DevTools の Network パネルでダウンロードリクエストの プロトコルと リモートアドレスを確認してください。プロトコルが h3 の場合は、ブラウザーの QUIC を一時的に無効にし、再起動後にリクエストが h2 を使用していることを確認してから測定してください。測定後はブラウザーの設定を元に戻してください。比較のたびに、同じスピードテスト入口、クライアントネットワーク、測定方向を維持してください。