2025/08/19(火)Ubuntuのネイティブ環境にPrometheusとGrafanaをIPv6スタックで導入した

更新日:
投稿日:

この記事では自宅サーバーの監視環境導入にあたり、ほぼ前提知識なしの状態からPrometheusとGrafanaを導入した経緯を書いている。IPv6シングルスタック対応。

確認環境

Ubuntu実機AMD64環境

Env Ver
Ubuntu 24.04.3 LTS
nginx 1.26.1
Prometheus 3.5.0
Node exporter 1.9.1
NGINX Prometheus Exporter 1.4.2
Grafana v12.1.1

OpenWrtで設置サーバー向けのPrometheusとGrafanaのDNS設定をしてアクセス可能にする

今回の作業はLAN内にある作業機からサーバーマシンに対して行うため、利便性のため各サービスに対してドメインを振っておく。

  1. OpenWrtの/etc/hostsを開きPrometheusとGrafanaの設定を書く
    1. ここでは一旦、prometheus.testgrafana.testとする
  2. /etc/init.d/dnsmasq restart
  3. これでLAN配下の端末からnginxで設定したホスト名でアクセスできるようになる

Prometheusの導入

Prometheusとは

PrometheusとはSoundCloudで開発された時系列のスタンドアロンバイナリのツールで、時系列でメトリクスを収集するツールのようだ。オープンソースソフトウェアとして公開されている。

メトリクスとは数値測定のことで、例えばCPU使用率や、メモリ使用量、HTTPサーバーがこれまでに返したレスポンスコード別のカウントなど、そういった数値のことだ。Prometheusはこれを定期的に収集することで、収集時刻+メトリクスで時系列の数値データを蓄積しているものと思われる。

実際のデータとしてはメトリック名に対して連想配列を格納したデータを保持しているっぽい。イメージとしては以下のような感じだろうか。

<metricName>: { <labelName>: <labelValue>, ... }

メトリクスはExporterと呼ばれるサービスに対してHTTP要求を投げ、その応答を記録しているようだ。つまりExporterがメトリクスを取得、Prometheus向けに情報加工し、PrometheusはExporterからこれを取得、時系列のデータベースにしているのだろう。

またエンドポイントが揮発性であるなど、短命である場合はPushgatewayというプロキシを使い、PushgatewayがPrometheus向けに情報公開する仕組みもあるようだ。

EoLはリリースから一年ほどと、短い。

本体のインストール

  1. Prometheusセットアップコマンドを流す

    # 作業場所の作成
    mkdir temp
    cd temp
    
    # バイナリ取得
    wget https://github.com/prometheus/prometheus/releases/download/v3.5.0/prometheus-3.5.0.linux-amd64.tar.gz
    tar xvfz prometheus-3.5.0.linux-amd64.tar.gz
    
    # Prometheus実行ユーザーの作成
    sudo groupadd prometheus
    sudo useradd prometheus -g prometheus -d /var/lib/prometheus -s /usr/sbin/nologin -m
    ls -la /var/lib/prometheus/
    
    # binを配置
    cd prometheus-3.5.0.linux-amd64
    sudo cp prometheus promtool /usr/local/bin/
    ls -la /usr/local/bin | grep prom
    
    # 設定ファイルを配置
    sudo mkdir /etc/prometheus
    cat<<'EOF' | sudo tee /etc/prometheus/prometheus.yaml
    global:
    scrape_interval:     15s
    evaluation_interval: 15s
    
    rule_files:
    # - "first.rules"
    # - "second.rules"
    
    scrape_configs:
    - job_name: prometheus
        static_configs:
        - targets: ['[::]:9090']
    EOF
    
    sudo chown -R prometheus:prometheus /etc/prometheus
    ls -la /etc/prometheus
    
    # デーモン作成
    cat <<'EOF' | sudo tee /etc/systemd/system/prometheus.service
    [Unit]
    Description=Prometheus - Monitoring and alerting toolkit
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    User=prometheus
    Group=prometheus
    WorkingDirectory=/var/lib/prometheus
    ExecStart=/usr/local/bin/prometheus \
        --config.file=/etc/prometheus/prometheus.yaml \
        --storage.tsdb.path=/var/lib/prometheus \
        --web.listen-address=[::]:9090
    ExecReload=/bin/kill -HUP $MAINPID
    Restart=on-failure
    RestartSec=5s
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    # デーモン有効化
    sudo systemctl daemon-reload
    sudo systemctl enable --now prometheus
    
  2. nginxからPrometheusの管理画面が開けるようにする。/etc/nginx/conf.d/prometheus.confを作成し、以下を記述。

    upstream prometheus {
      server [::1]:9090;
    }
    
    server {
      listen        [::]:80;
      server_name   prometheus.test;
    
      access_log   /var/log/nginx/prometheus.access.log;
      error_log    /var/log/nginx/prometheus.error.log;
    
      location / {
        proxy_set_header Host $host;
        proxy_pass  http://prometheus;
      }
    }
    
  3. sudo service nginx restart

  4. 設定したホストにアクセスできればOK

本体設定の説明

先ほどの「Prometheusセットアップコマンドを流す」ステップで作成した設定の説明。

First steps with Prometheusに書いてある通り、設定はprometheus.yamlのようなYAMLファイルに定義し、./prometheus --config.file=prometheus.ymlの様にして起動時に読み込んで利用する。

global:
  scrape_interval:     15s
  evaluation_interval: 15s

rule_files:
  # - "first.rules"
  # - "second.rules"

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ['[::1]:9090']

globalセクションではポーリング頻度と、ルールの評価頻度が指定されている。

rule_filesではルールファイルが指定される。

scrape_configsではポーリング先のリソースを指定する。この場合はhttp://localhost:9090/metricsに対して行われる。

ログの保持期限について

ログの保持期限はprometheusを蹴るときのコマンドラインオプションで決まる。

デフォルトでは15日だが、--storage.tsdb.retention.timeを指定することで増やせるようだ。

単位はy, w, d, h, m, s, msがあり、--storage.tsdb.retention.time=90dの様にして指定する模様。

How long to retain samples in storage. If neither this flag nor "storage.tsdb.retention.size" is set, the retention time defaults to 15d. Units Supported: y, w, d, h, m, s, ms. Use with server mode only.

個人的にはデフォルトの15日で様子見し、必要に応じて伸ばしていこうと考えている。商業サービスのように可用性が重視され、障害発生などで過去を遡りたい場合には長期記録があると手がかりが増えるので、有用だと思う。

Exporterの導入

Exporterは実際に数値を収集し、Prometheusに対して情報公開するためのHTTPエンドポイントを提供するサービスで、この章では今回利用するものについて書いていく。

OSやマシンの監視:Node exporter

POSIX系システムのOSやマシンの監視にはPrometheus公式のNode exporterを利用する。

インストール
# 取得
wget https://github.com/prometheus/node_exporter/releases/download/v1.9.1/node_exporter-1.9.1.linux-amd64.tar.gz
tar xvfz node_exporter-1.9.1.linux-amd64.tar.gz
cd node_exporter-1.9.1.linux-amd64/

# binを配置
sudo cp node_exporter /usr/local/bin/
ls -la /usr/local/bin/ | grep node_exporter

# デーモン作成
cat <<'EOF' | sudo tee /etc/systemd/system/node_exporter.service
Description=Node exporter
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=prometheus
Group=prometheus
WorkingDirectory=/var/lib/prometheus
ExecStart=/usr/local/bin/node_exporter \
    --web.listen-address=[::]:9100
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF

# デーモン有効化
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
prometheus.yamlの設定

/etc/prometheus/prometheus.yamlを開きscrape_configs:に以下を追記

  - job_name: 'node'
    static_configs:
      - targets: ['[::1]:9100']
nginxの監視:NGINX Prometheus Exporter

nginxの監視にはnginx公式のNGINX Prometheus Exporterを利用する。

これはログを監視するわけではなく、接続を許可した数や、現在の接続数、これまでのHTTP要求合計などの数値を公開しているようだ。

nginxにヘルスチェック追加

/etc/nginx/conf.d/status.confを作ってstub_status_moduleを埋める。

server {
    listen [::]:80;

    location /stub_status {
        stub_status on;
        access_log off;
        allow ::1;
        deny all;
    }
}

疎通確認

curl -v http://localhost/stub_status

こんなのが来ればOK

< HTTP/1.1 200 OK
< Server: nginx/1.26.1
< Date: Mon, 18 Aug 2025 10:31:59 GMT
< Content-Type: text/plain
< Content-Length: 97
< Connection: keep-alive
<
Active connections: 1
server accepts handled requests
 1 1 1
Reading: 0 Writing: 1 Waiting: 0
* Connection #0 to host localhost left intact
Exporterのインストール
# 取得
wget https://github.com/nginx/nginx-prometheus-exporter/releases/download/v1.4.2/nginx-prometheus-exporter_1.4.2_linux_amd64.tar.gz
tar xvfz nginx-prometheus-exporter_1.4.2_linux_amd64.tar.gz

# binを配置
sudo cp nginx-prometheus-exporter /usr/local/bin/
ls -la /usr/local/bin/ | grep nginx-prometheus-exporter

# デーモン作成
cat <<'EOF' | sudo tee /etc/systemd/system/nginx_exporter.service
[Unit]
Description=NGINX Exporter
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/nginx-prometheus-exporter \
    --nginx.scrape-uri=http://[::]/stub_status \
    --no-web.systemd-socket \
    --web.listen-address=:9113
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF

# デーモン有効化
sudo systemctl daemon-reload
sudo systemctl enable --now nginx_exporter
prometheus.yamlの設定

/etc/prometheus/prometheus.yamlを開きscrape_configs:に以下を追記

  - job_name: 'nginx'
    static_configs:
      - targets: ['[::1]:9113']

Prometheusの管理画面を確認

http://prometheus.testにアクセスできることを確認し、ついでにStatus→Target healthでExporterの死活も見ておくと良い。

Grafanaの導入

Grafanaとは

Grafanaとはオープンソースのビジュアライザツールである。PrometheusやMySQLなどのデータソースを基にグラフにしたりすることができる。

Lokiというツールを使うことでログも扱うことができ、ログビューワとしても使えるようだ。

インストール

  1. 次のコマンドでインストールする

    # debの取得とインストール
    sudo apt-get install -y adduser libfontconfig1
    wget https://dl.grafana.com/grafana-enterprise/release/12.1.1/grafana-enterprise_12.1.1_16903967602_linux_amd64.deb
    sudo dpkg -i grafana-enterprise_12.1.1_16903967602_linux_amd64.deb
    
    # デーモンの有効化
    sudo /bin/systemctl daemon-reload
    sudo /bin/systemctl enable grafana-server
    sudo service grafana-server start
    

Grafanaの画面を見れるようにする

  1. 適当にnginxの設定ファイルを切って以下のように書き、アクセスする

    # This is required to proxy Grafana Live WebSocket connections.
    map $http_upgrade $connection_upgrade {
      default upgrade;
      '' close;
    }
    
    upstream grafana {
      server [::1]:3000;
    }
    
    server {
      listen        [::]:80;
      server_name   grafana.test;
    
      access_log   /var/log/nginx/grafana.access.log;
      error_log    /var/log/nginx/grafana.error.log;
    
      location / {
        proxy_set_header Host $host;
        proxy_pass  http://grafana;
      }
    
      # Proxy Grafana Live WebSocket connections.
      location /api/live/ {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_pass http://grafana;
      }
    }
    
  2. ID: admin, PW: adminでログインしパスワードを変更する

  3. ログインしたら画面右上からProfileを開き、Usernameを変更する

GrafanaからPrometheusのメトリクスを見れるようにする

Prometheusとの接続
  1. Home→Connections→Add new connectionでPrometheusを検索
  2. 右上のAdd new data sourceを押す
  3. Connectionにhttp://localhost:9090を入れる
  4. Save & testを押す
Prometheusダッシュボードの作成
  1. Connections→Data sourcesからprometheus→Dashboard
  2. Prometheus 2.0 StatsをImport
  3. DashboardsにPrometheus 2.0 Statsが追加されていて、中身が動いていることを確認
Node exporterダッシュボードの作成
  1. Dashboardsを開き、右上のNewボタン→Import
  2. Node Exporter FullのIDをコピーしてID欄に貼り付けLoadする
  3. 「Select a Prometheus data source」でprometheusを選んで保存
  4. 右上のEditボタンを押す
  5. 同じ場所にSettingsボタンが出てくるので更に押す
  6. Settings画面に遷移するのでVariablesタブを開き、jobの文字を押す
  7. 下にスクロールし、Query optionsのLabel filtersをjob = nodeになるようにする(nodeの部分はprometheus.yamlに定義したジョブ名を指定する)
  8. 右上のSave dashboardボタンを押す
  9. Saveボタンを押す
  10. ダッシュボードにメトリクスが反映されていることを確認
  11. 何も出てない場所はウィジェットを編集してメトリクスを手で指定していくしかないと思う
Nginxダッシュボードの作成

Grafana公式のダッシュボードテンプレートに使えるものが見当たらなかったので自作するしかない。

  1. Dashboardsを開き、右上のNewボタン→New Dashboard
  2. +Add visualizationボタンを押す
  3. Select data sourceダイアログが出てくるのでprometheusをクリック
  4. 出てきた画面下部にあるMetricからnginx関係のメトリクスを探して適当に設定していく

Dockerを使わなかった理由

IPv6縛りでやっているとPrometheusのNode exporterがPrometheus本体と疎通できなかったので諦めた。恐らくコンテナの中からIPv6でホストと通信するのが難しいのだと思う。

Node exporterホストのメトリクスを取る場合、Node exporterのネットワークはHost側に行くのため、prometheus.yamlのstatic_configs.targetslocalhostにするとコンテナ内を見てしまうから疎通できないし、host.docker.internalを指定してもv4アドレスの127.0.0.11が返ってきてしまうので疎通できない。IPv6をデフォルトにしてもhost.docker.internal127.0.0.11のままで、AAAAレコードがない。

ググっても当てはまるものは出ず、GPT-5やClaude Opus 4.1に聞いても答えは得られず、消耗戦になるので諦めた。

それに物理サーバー一台の環境だとコンテナ化の恩恵もさほどないので、Docker固有の問題に苦しむくらいならバイナリを直に叩いた方が楽というのもある。

今回の作業で得られたもの

init.dの書き方の記事でイケていなかった部分に気付けた

init.dの書き方で冗長だった記述や、誤解を招く記述の整理ができた。例えばNAME変数の影響範囲が広すぎて、本来波及してほしくない場所まで波及してしまう問題や、giteaにべったりで応用の利かない部分を直せたほか、一度しか出現しないのに変数化されていたり、存在しないファイルを参照するコードがあったのに気づけるなど、収穫が多くあった。

修正点としてはNAME変数はサービス名のみに影響するようにして、実行ファイル名に波及しないようにしたり、"$DAEMON -- $DAEMON_ARGS"となっていた場所も$DAEMON $DAEMON_ARGSとするなど、影響範囲を狭めたり、変数側で調整が効くものをべた書きで依存させないようにした。

今回は微妙な記事を参考にinit.dを書いてしまい、結構ハマってしまったが、今回の修正によって今後init.dを書く場合には、より詰まりづらくなることが期待できる。

Prometheusの役割を知れた

今までPrometheusのことを色んなアプリケーションのログをフェッチしてDBに放り込んでくれるツールだと思っていたが、全然違った。Prometheusはメトリクスを時系列に集め、それをGrafanaなどのビジュアライザに提供できるツールだ。

この「メトリクス」や「時系列」という言葉が鍵で、「メトリクス」は任意の数値、時系列は取得した時間だ。

例えばCPU使用率が20%、メモリ使用量が24GBという情報をExporterが公開しているとして、10:00にPrometheusが取得すれば10:00のCPU使用率は20%、メモリ使用量は24GBとなる。次回10:11に取得すれば別の数値が取れるだろう。これを積み重ねていくことで時系列に数値を取ることが可能になり、時系列で集計することが可能になる。そうするとグラフにしたときに使用率の急増などが掴めるようになるわけだ。

具体的にはExporterと呼ばれるプログラムが、この値を収集し、http://<ホスト>/metricsのエンドポイントで公開している。なのでprometheus.yamlにはホスト部のみを定義すれば読みに行ってくれる。逆に言えばExporterを自作する場合は、ここに値を置けばよいのだろう。

他にもExporterが置けない、揮発性のものに対してもPushgatewayと呼ばれる外部プログラムにデータをプールさせることで、Exporterの代わりになると言う事も知れた。結局のところ相手が何であろうと、Prometheusはメトリクスエンドポイントをポーリングして情報を収集するだけなのだ。

そしてGrafanaとかは恐らくPrometheusにPromQLで問い合わせてデータを引き出すのだろう。

全体像を理解するにあたりPrometheus公式にある、アーキテクチャ図が非常にわかりやすく、だいぶ助けられた。

名前は聞いたことがあるものの今まであまりよくわかっていなかったPrometheusの理解が深まったことは、今回の作業で最大の収穫だった。

トラブルシューティング

Prometheusの管理画面でNode exporterがUpにならない

次のエラーが出る場合、もしDocker Composeを使っているのなら、バイナリをホストにインストールすると回避できる。

  • Error scraping target: Get "http://node_exporter:9100/metrics": dial tcp: lookup node_exporter on 127.0.0.11:53: server misbehaving
  • Error scraping target: Get "http://localhost:9100/metrics?collect%5B%5D=cpu&collect%5B%5D=meminfo&exclude%5B%5D=netdev": dial tcp [::1]:9100: connect: connection refused
  • Error scraping target: Get "http://host.docker.internal:9100/metrics?collect%5B%5D=cpu&collect%5B%5D=meminfo&exclude%5B%5D=netdev": context deadline exceeded

参考までに一番上と一番下はIPv4なので疎通できず、真ん中はlocalhostがコンテナの中を見ているのでホストに疎通できていない状態と思われる。

Prometheus関連のデーモンを起動したが、Prometheusの管理画面のStatus→Target healthに出てこない

数秒~数十秒のラグがあるので少し待つと出てくる。ステータスがUpになるのにも時間がかかるのでゆっくり待つしかない。

参考までに筆者のマシンはCPUがAMD Ryzen 5 5600Gでメモリは32GB積んでいるが、これほど掛かる。

NGINX Prometheus Exporterのメトリクスが取れない

--nginx.scrape-uri=stub_statusのパスが指定できていないか、パスが間違っていないか確認すると解決するかもしれない。

参考までにPrometheusの管理画面でnginx-upのメトリクスが0の場合は取得に失敗しているので、どこかの設定がおかしい。

任意のメトリクスが取れない

以下の手順を試し、原因の切り分けを図り対策する。

  1. Exporterが動いているか
    • ps ax | grep promで上がっているかどうか確認する
    • ポートが塞がっている場合sudo lsof -i :<ポート番号>でプロセスを特定して殺してから起動する(ゾンビプロセスに塞がれていることがある)
  2. Exporterのエンドポイントにcurlが疎通するか
    • curl -v http://localhost:{exporterのport}/metricsで確認可能
      • ポート番号はExporterのGitHubや、起動時のログに出ているので、そこを確認する
  3. Exporterにcurlを投げた時にメトリクスらしきものが出ているか確認する
  4. Prometheusの管理画面を開き、取得できていないメトリクスを取得するクエリを打ち、取れるかどうかを確認

GrafanaのNginx系ダッシュボードテンプレートをImportしたが何も出ない

諦めて自分で作るしかない。幸い素のnginxはメトリクスが少ない。

Node Exporter Fullダッシュボードでメトリクスが表示されない

Node exporterダッシュボードの作成を参照のこと。

Grafanaの待ち受けポートを変える

/etc/nginx/conf.d/grafana.confhttp_portのコメントを外し、任意のポートに変更し、sudo service grafana-server restartで再起動する。

前段にnginxなどがいる場合は、そちらの設定を変えるのも忘れないこと。

3000番はNode.js系がよく使うため変えた方が色々便利だ。

2025/08/13(水)OCNバーチャルコネクト環境でIPv6サーバーをポート443で公開した時にやったこと

この記事はフレッツ光ネクストを対象としたものです。フレッツ光クロスには当てはまらないので注意してください。

本記事はここ昨今のOpenWrtセットアップシリーズの続きである。

OCNバーチャルコネクトのIPoEでIPv4 over IPv6のMAP-E環境だと、IPv4ではWell-known portsが開けない。しかし、IPv6であれば、理論上全部のポートが使えるはずで、それであればサーバーを建てられるのではないかと考えたので、やってみた記録。

セキュリティを考慮し、サーバー以外にはアクセスできないよう、NATのような仕組みで構築する。

確認環境

環境 内容
ISP OCN光
ISP契約 OCN 光 with フレッツ マンション・スーパーハイスピード 隼・プラン1・西日本
ISP接続方式 OCNバーチャルコネクト(IPoE, MAP-E)
RouterOS OpenWrt 24.10.0
ServerOS Ubuntu 24.04.3 LTS
HTTPD nginx 1.26.1
ドメインレジストラ Value Domain

前提条件

IPv4環境下でのHTTPSアクセスが可能で、かつ以下のセットアップが終わっているものとする。

今回の要件

ルーターのファイアウォールでサーバーマシンのみ穴をあけ、それ以外を塞ぐ。つまりIPv4のNATにあったセキュリティの再現を行うことで、関係ない端末が攻撃されないようにする。

やり方

サーバーとDNSの設定

  1. nginxの設定を開きlisten [::]:443を追加して再起動
    1. sudo service nginx restart
  2. サーバーマシンのIPv6(Global Unique Address, GUA)を控える
    ip -6 addr | grep 'global dynamic' | perl -ale '$F[1] =~ /^([^\/]+)/; print $1;'
    
  3. Value DomainのDNS設定を開きAAAAレコードに、先ほど控えたIPv6アドレスを登録する

ルーターのファイアウォールに穴をあける

設定ファイルを編集する方法
  1. vi /etc/config/firewallで以下の行を追加
    config rule
            option name 'Allow-Server-IPv6'
            option src 'wan'
            option dest 'lan'
            option proto 'tcp udp'
            option dest_ip 'さっき控えたサーバーのIPv6アドレス'
            option dest_port '443'
            option family 'ipv6'
            option target 'ACCEPT'
    
  2. service firewall restartでfirewallを再起動する
LuCIでやる方法
  1. LuCIに入りNetwork→Firewall→Traffic Rulesを開く
  2. Addボタンを押し、次の要領で入力して保存
    General Settings

    項目
    Name Allow-Server-IPv6
    Protocol TCP│UDP
    Source zone wan
    Destination zone lan
    Destination address さっき控えたサーバーのIPv6アドレス
    Destination port 443

    Advanced Settings

    項目
    Restrict to address family IPv6 only
  3. 穴をあけたIP以外が外部から疎通しないことを確認

  4. 穴をあけたIPが外部から疎通することを確認

備考

OCN光のIPoE(MAP-E)方式のIPはv4, v6ともに基本的に変動しない

結論から言うと引っ越しでもしない限り、v4が固定なのは知っていたが、v6も固定らしい。

v6のアドレスが変わる気配がないので、OCNのテクニカルサポートに聞いた結果、PPPoEは変動IPv4でルーター再起動時にIPが変わるが、IPoEであればIPv4, IPv6ともに半固定で通常は変わらないとのことだった。

つまりVLANやip6tablesがなくてもサーバーを公開できると言う事でOCN様々と言う事である。

IPv4アクセスをどうするか?

現状は2案検討している。

  1. どっかにペラのページを置いておき、「IPv6でアクセスしてください」みたいなお知らせページにしておく
  2. SNSなどのOGP対策で、簡単なプロキシを組んでおき、OGPだけ出るようにしておく

2のケースだとレンサバにv6側サイトのOGP取得用のCGIを置いておくとか、v6側サイト更新時にOGP付きのペラのHTMLを置いておくなどが検討できると思う。

Cloudflare Tunnelを使わない理由

Cloudflare Tunnelを使えればIPv4を利用でき、デュアルスタック対応もできるだろう、しかしなぜ使わないのかという話。

基本的にオンプレミス至上主義だからというのが答えにはなるが、実務的な理由もある。

まずCloudflare Tunnelを利用する場合、ネームサーバーを委任する必要があるが、CloudflareのDNSはさくらインターネットのSPFレコードを扱おうとするとバリデーションエラーを吐いて使えない。他にも、管理画面のUIがお世辞にもよくなく、言葉を選ばず言えばクソである点もある。勿論、余計なレイヤーを増やすことによる運用コストの増大もあるため、使わなくて済むのであれば、それに越したことはないという考えだ。

またCloudflareのWAF機能やhCAPTCHAがユーザーとして嫌いなのもあり、自分が嫌いなものをユーザーに提供したくないのもあるし、Cloudflareのエラー画面を見て嬉しく思う人もいないと思うので、あのインフラには乗りたくない思いもある。

IPv4のデュアルスタック対応としては、VPNにリバプロをかけるのも検討したが、レガシーに縋っていても仕方がなく、今のところはIPv6に注力する方向にしようとしている。世界のIPv6移行に末端からでも貢献出来たらいいなくらいの気持ちでやっていくのだ。

疎通検証に使える簡易サーバーの作り方

PHP

php -S "[::]:80"でIPv6向けの簡易サーバーをサクッと立てられるので疎通検証をするときに便利。

Node.js

http-serverだとhttp-server -p 80 -a "[::]"でいける。serveは未対応っぽい。

疎通確認に使えるcurl例

IPv6はURL形式が特殊なのでアドレス部分を[]で囲んだ書式で投げる。これはブラウザで確認する場合でも変わらない。

curl -v "http://[aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh]:80/"

ドメインを利用する場合に、リクエスト先をAレコードとAAAAレコードで明示的に分ける場合は、以下の書き分けができる。

# IPv4向け
curl -4 -v "http://example.com/"
# IPv6向け
curl -6 -v "http://example.com/"

複数ポートの開き方

option dest_portに値を半角スペース区切りで追加すればよい。LuCIでも同じ書き方で通用する。

例:

option dest_port '80 443 8080'

連番で開ける場合は公式ドキュメントによると、'1024:65535'のような書式にすれば、連番で開けられるようだ。

例:

option dest_port '8000:8999'

関連記事

2025/08/04(月)R86SとOpenWrt 24.10でOCNバーチャルコネクトに接続したときのメモ

前回、OSインストールの記事を書いてから約四ヶ月、今回は実際にインターネットへの接続をやっていく。接続にはOCN バーチャルコネクトを利用する。

色々あって四ヶ月放置していたR86Sにはいい感じに埃が積もっていた。

確認環境

  • R86S U1
  • OpenWrt 24.10.0
  • OCNバーチャルコネクト
  • フレッツ光ネクスト

手順

OSインストールが終わっているものとする。

また、この手順ではLANケーブル(RJ45)を使って進めている。

途中でインターネットを利用する場面が何度かあるため、キャリア回線でWWWに出られるスマホがあると便利だ。

R86Sに接続する

eth1にWAN, eth0にLANを接続する。

パッケージのインストール

SSHで192.168.1.1に接続し次のコマンドを流しパッケージをインストールする。

opkg update
opkg install luci
opkg install map
reboot

Web管理画面へのアクセス

http://192.168.1.1/にアクセスするとWeb管理画面が開くので、ここから設定をしていく。

設定情報の取得

管理画面上部のNetworkからInterfacesを開き、wan6のIPv6にある先頭4セクションを控え、http://ipv4.web.fc2.com/map-e.htmlを開き入力、計算する。出力されたoption始まりの行の内容をすべて控えておく。

wan6のIPv6にある先頭4セクション(aaaa:bbbb:cccc:dddd)とoptionの値は後で使うので全部控えておく。

WAN側IPv6のDHCP(DHCPv6 client)の設定

wan6のEditボタンを押す。

DHCP Serverタブを開き、「Set up DHCP Server」ボタンを押す。

IPv6 Settingsタブを開きRA-Service、DHCPv6-Service、NDP-Proxyをrelay modeに変更し、保存する。

LAN側IPv6のDHCPの設定

先ほどと同様にDHCP Serverタブ→IPv6 Settingsタブと開き、RA-Service、DHCPv6-Service、NDP-Proxyをrelay modeに変更し、保存する。

ルータ広告用のインターフェースの作成

画面左下にある「Add new interface...」ボタンを押し、以下の要領で選択し作成する。ルーター広告はIPv6のRouter Advertisementのことなのでインターフェース名をwan6raとしている。

項目
Name wan6ra
Protocol Static address
Device Alias Interface: "@wan6"

Deviceは項目選択後は画像のように@wan6表記になる。

ルータ広告用のインターフェースの設定

ここでは控えておいたwan6のIPv6にある先頭4セクション(aaaa:bbbb:cccc:dddd)を利用する。

wan6raインターフェースのEditボタンを押し、General Settingsタブにある項目を次の要領で設定する。

項目
IPv6 address aaaa:bbbb:cccc:dddd::1001
IPv6 gateway aaaa:bbbb:cccc:dddd::1
IPv6 routed prefix aaaa:bbbb:cccc:dddd::/56

各設定項目に応じて、先頭4セクションの後ろに::1001、::1、::/56を追記するイメージ。

疎通確認

Save&Applyを押し、以下のサイトが開けることを確認する。

この段階ではIPv6にしか繋がらないため、続けてIPv4向けの設定をしてゆく。

MAP-E用インターフェースの作成

次の要領でインターフェースを作成する。

項目
Name wanmap
Protocol MAP / LW4over6

MAP-E用インターフェースの設定

ここでは控えておいたoption始まりの行の内容を利用する。

wanmapインターフェースのEditボタンを押し、General Settingsタブにある項目を次の要領で設定する。

項目
Type MAP-E
BR / DMR / AFTR option peeraddrの値
IPv4 prefix option ipaddrの値
IPv4 prefix length option ip4prefixlenの値
IPv6 prefix option ip6prefixの値
IPv6 prefix length option ip6prefixlenの値
EA-bits length option ealenの値
PSID-bits length option psidlenの値
PSID offset option offsetの値

Advanced Settingsタブを開き「Use legacy MAP」にチェックを入れ、保存する。

Firewallの設定

SSHで192.168.1.1に接続し/etc/config/firewallを開く。

config zone
	option name 'wan'
	...
	list network 'wan'
	list network 'wan6'

となっている箇所の末尾に以下を追記し保存。rebootコマンドで再起動する。

	list network 'wan6ra'
	list network 'wanmap'

ルーター再起動後、http://wa.kiriwake.jpne.co.jp/に接続し、判定ボタンを押し、試験1~4と、契約中のフレッツ東西の光がOKになっていれば疎通は問題ないと思われる。

後は適当に幾つかサイトを開いたりfast.comで回線速度を見て疎通確認を実施した。

ストレージの拡張(2025/08/26追記)

イメージを焼いた関係で、初期パーティションが狭い。R86S U1のeMMCは128GBもあるので、これを拡張する。

  1. GPartedのサイトからイメージを落とし、最新のRufusで適当なメディアにイメージを焼く。
  2. GPartedを焼いたメディアをR86Sに接続
  3. R86Sを起動しDeleteボタン連打でBIOSに入る
  4. Boot OptionでGPartedの起動順位をトップにする
  5. 再起動し一番上のGParted Live(Default settings)で起動
  6. 起動するとGPartedの画面が出ているのでパーティションを最大まで広げる

やり終えてから思ったが、OpenWrtインストール時に使ったUbuntuServerにpartedくらい入ってるだろうし、それでやってもよかったかもと思った。

発生したトラブル

192.168.1.1に繋がらない

eth0にLANを接続する事で繋がる。初期設定ではeth0がブリッジ、eth1がWAN、eth2は未設定。

ポート不足?(ニチバン問題?)(未解決)

ニチバン問題と同じものかはわからないがコネクションが225を超えた付近で通信が詰まる傾向があった。このため、Configuring OpenWrt to work with Japan NTT IPv6 (MAP-E) serviceのADVANCED CUSTOM CONFIGURATIONを利用し解決を試みたが、たぶん特に意味はなかった。

以下のコマンドを流すことで導入できた。

cd /lib/netifd/proto
mv map.sh map.sh.orig
wget -O map.sh https://raw.githubusercontent.com/fakemanhk/openwrt-jp-ipoe/refs/heads/main/map.sh.new
reboot

ひとまず変更して、意図的に大量のサイトを開いた状態がこちら。一見解消しているように見えるが、人為的にやった結果なので同等の結果かどうかは怪しい。

また一気に大量のサイトを開きまくると、流石に若干詰まりが見られたが、詰まっていた時はルーターさえ疎通しなかったので、単にOSのポートを食いつぶしていただけという可能性もある。

参考までに元のmap.shに戻して同じ操作をしてみたところ、ちゃんとコネクションが張れたので関係なさそう。

以前と比べてネットワーク構成が変わっており、Buffaloのルーターをスイッチングハブとして使っている影響などが関係しているかもしれないので、しばし静観の方向で…。

ルーター起動後、Windowsでネットワークアダプタが認識中のままになる、インターネットに繋がらない

電源投入からOCNバーチャルコネクトのリンクアップまで20~50秒ほどかかるので気長に待つ。

LAN側IPv6のDHCPの設定でDHCPv6-Serviceの値はrelay modeかserver modeか?

OpenWrtではDHCPv6の運用が難しいため、基本的にrelay modeでよいと思う。

おまけ

eth0をWAN、eth1をLANにする方法

  1. NetworkからInterfacesを開く
  2. wanとwan6のDeviceをeth0に変更
  3. Devicesタブに切り替る
  4. br-lanの「Configure…」ボタンを押す
  5. General device optionsのBridge portsをeth1にして保存
  6. Save & Applyを押す

CPU温度を見る方法

luci-app-temp-statusをインストールする。

2025年8月4日時点では以下のコマンドでインストールできる。

wget --no-check-certificate -O /tmp/luci-app-temp-status_0.7.1-r2_all.ipk https://github.com/gSpotx2f/packages-openwrt/raw/master/current/luci-app-temp-status_0.7.1-r2_all.ipk
opkg install /tmp/luci-app-temp-status_0.7.1-r2_all.ipk
rm /tmp/luci-app-temp-status_0.7.1-r2_all.ipk
service rpcd restart

インストールが終わるとトップ画面にTemperatureが出てくるほか、Status→Realtime GraphsにもTemperatureが出てくるようになる。

セットアップが完了したR86Sの姿

まぁまぁいい塩梅だと思う。

撤去されたYAMAHA RTX830

R86S + OpenWrtを導入するまで使っていたRTX830。価格の割にIPv6向けの機能が貧弱だったり、設定が手間だったり、マニュアルが雑目だったり、あまりいい思い入れはなかった。

OCNバーチャルコネクトの接続がBuffaloルーターより早く安定している点と、LAN向けのDNSがあるのは便利だったが、あの読みづらいマニュアルはもう少し何とかした方がよいと思う。

今回セットアップした感想

今のところ予想以上にトラブルや問題がなく、平然と動いているため、かなり満足している。

RTX830との比較

管理画面の操作性や充実度はRTX830を遥かに超えており、非常に体験がよかった。

設定変更についてもSave & Applyを押すまでは保留状態になるため、間違った設定が即座に反映されないのもよい。

しかもPending changesをクリックすると設定ファイルに対する差分も確認でき、大変便利だ。

電源投入からOCNバーチャルコネクトへのリンクアップまでの時間も体感RTX830と大差なく、Buffaloルーターのように接続ネゴシエーションの成功を祈っていたら1~2時間経過していたみたいなこともないのは素直にうれしい。fast.comで計測した限りでは速度やレイテンシの劣化もなく大変満足している。

DHCP設定の静的リースのUIが便利すぎる

Network→DHCP and DNS→Static Leasesから現在繋いでいる機器が見れるのがありがたいし、リース情報もわかりやすい。

しかも静的リースを行うときにOpenWrtが把握しているMACアドレスとドメイン名の一覧が出てくるので、手打ちしたり、確認する手間が省けるのも便利だ。リース時間も設定できるし、至れり尽くせりである。

ちょっとうるさい

唯一残念なところを挙げるとするとファンが微妙にうるさく、2mの距離があってもモスキート音レベルのささやかな動作音が聞こえる部分だ。これは慣れれば気にならなくなると思いたい。今の時期だとエアコンの音にかき消されてほぼ聞こえないが、それでも寝る前だと個人的には若干気にならなくもない程度だ。薄型のシロッコファンゆえにNoctuaのファンに変えるのも難しく、正直解決策としては物理的に遠くするか、間に何か防音材を放熱の邪魔にならないように挟むくらいしかないだろう。一応メーカー的には静穏ファンとのこともあり、大半の人は気にならないとは思う。

Banana Pi BPI-R4にもSPF+が2つあり、RJ45ソケットもあり、2.5万程度と安価なため、冷却装置をDIYして静穏化する場合はこちらの方が向いている可能性がある。実際にやってる人もいる

ただまぁスペックはR86Sの方が上等なので、安く静かで多くを求めず、多少大きくてもいいならBanana Pi BPI-R4、多少の騒音を許容でき、スペックが欲しい場合はR86Sというのもありだろう。一般家庭のルーターに、そこまでスペック要るのかどうかというのはさておき…。

微妙なスイッチングハブの使用による性能劣化

今回ルーター側のポート数の制約により、ルーター直結でなくスイッチングハブを通してWWWに接続している。使えるものがBuffaloのWiFiルーターのAPモード(スイッチングハブとして機能する)しかなかったので、これを使っているが、直結と比べた場合にあからさまな性能劣化が見られた。以下は数回計測した上での平均値。小数点以下は切り捨て。

直結時

下り速度 上り速度 アンロードレイテンシ ロード済みレイテンシ
435Mbps 430Mbps 4ms 5ms

Buffalo経由時

下り速度 上り速度 アンロードレイテンシ ロード済みレイテンシ
357Mbps 422Mbps 5ms 13ms

上りは誤差だが、下りが78Mbps低く、ロード済みレイテンシも倍以上の差が出ている。MMOを辞めた今となっては問題ないとはいえ、なんとも微妙だ…。

ただまぁ、将来的には10GbEスイッチを購入する予定であるため、恐らくソフトウェア的な制御によって起きているであろうこの問題は、いずれ解消するとは思う。

次の作業に向けて

設定のカスタマイズなどを通してよりよい環境にしていき、IP変動環境でIPv6を利用した自宅サーバーの公開や、10GbEの導入などに向けて挑戦していきたいところだ。

参考記事

2025/03/07(金)UbuntuからValue-DomainにIPv6でDDNSを通す方法

このコマンドをcronとかで回し続けてれば行けそう

事前準備

Value-Domainのコンパネから登録対象のDNSレコードにaaaaレコードを足しておく。

コマンド

ipaddr=$(ip a | grep 'scope global temporary dynamic' | perl -ne '/inet6 ([^\/]+)/; print $1')
echo 'https://dyn.value-domain.com/cgi-bin/dyn.fcg?d=<ドメイン>&p=<パスワード>&h=<ホスト名>&i='$ipaddr

凡例

項目
ドメイン example.comみたいなルートドメイン
パスワード Value-DomainのDDNSパスワード
ホスト名 sub.example.comのsubの部分

参考