お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。
投稿日:
ジャンル::自宅サーバー

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

細かいセキュリティ設定とかはしていないので、それはまた追い追いやってゆく。

また本記事の時点ではGrafanaでメトリクスがちゃんと見れないが、それも出来るようになったら、また別の記事に書く予定だ。

確認環境

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: ['localhost:9090']
    EOF
    
    sudo chown -R prometheus:prometheus /etc/prometheus
    ls -la /etc/prometheus
    
    # デーモン作成
    sudo touch /etc/init.d/prometheus
    sudo chmod 755 /etc/init.d/prometheus
    cat <<'EOF' || sudo tee /etc/init.d/prometheus
    #! /usr/bin/env bash
    ### BEGIN INIT INFO
    # Provides:          Prometheus
    # Required-Start:    $remote_fs $network $syslog
    # Required-Stop:     $remote_fs $network $syslog
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: monitoring and alerting toolkit.
    # Description:       Monitoring and alerting toolkit, collects and stores its metrics as time series data.
    ### END INIT INFO
    
    # Do NOT "set -e"
    
    # PATH should only include /usr/* if it runs after the mountnfs.sh script
    PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
    DESC="Prometheus - Monitoring and alerting toolkit, collects and stores its metrics as time series data"
    NAME=prometheus
    PIDFILE=/run/$NAME.pid
    SCRIPTNAME=/etc/init.d/$NAME
    WORKINGDIR=/var/lib/$NAME
    DAEMON=/usr/local/bin/$NAME
    DAEMON_ARGS="--config.file=/etc/prometheus/prometheus.yaml --storage.tsdb.path=$WORKINGDIR --web.listen-address=[::]:9090"
    USER=prometheus
    
    # Exit if the package is not installed
    [ -x "$DAEMON" ] || exit 0
    
    do_start()
    {
        PRM_ENVS="USER=$USER HOME=$WORKINGDIR"
        PRM_EXEC="$DAEMON $DAEMON_ARGS"
        sh -c "start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\
            --background --chdir $WORKINGDIR --chuid $USER \\
            --exec /bin/bash -- -c '/usr/bin/env $PRM_ENVS $PRM_EXEC'"
    }
    
    do_stop()
    {
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME --oknodo
        rm -f $PIDFILE
    }
    
    do_status()
    {
        if [ -f $PIDFILE ]; then
            if kill -0 $(cat "$PIDFILE"); then
                echo "$NAME is running, PID is $(cat $PIDFILE)"
            else
                echo "$NAME process is dead, but pidfile exists"
            fi
        else
            echo "$NAME is not running"
        fi
    }
    
    case "$1" in
        start)
            echo "Starting $DESC" "$NAME"
            do_start
            ;;
        stop)
            echo "Stopping $DESC" "$NAME"
            do_stop
            ;;
        status)
            do_status
            ;;
        restart)
            echo "Restarting $DESC" "$NAME"
            do_stop
            do_start
            ;;
        *)
            echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
            exit 2
            ;;
    esac
    
    exit 0
    EOF
    
    sudo update-rc.d prometheus defaults
    sudo service prometheus start
    
  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: ['localhost:9090']

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

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

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

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

# デーモン作成
sudo touch /etc/init.d/prometheus_node_exporter
sudo chmod 755 /etc/init.d/prometheus_node_exporter
cat <<'EOF' | sudo tee /etc/init.d/prometheus_node_exporter
#! /usr/bin/env bash
### BEGIN INIT INFO
# Provides:          Prometheus Node exporter
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Prometheus exporter for hardware and OS.
# Description:       Prometheus exporter for hardware and OS metrics exposed.
### END INIT INFO

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="Prometheus Node exporter - Prometheus exporter for hardware and OS metrics exposed"

NAME=prometheus_node_exporter
PIDFILE=/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
WORKINGDIR=/var/lib/prometheus
DAEMON=/usr/local/bin/node_exporter
DAEMON_ARGS="--path.rootfs=/host --web.listen-address=[::]:9100"
USER=prometheus

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

do_start()
{
    PRM_ENVS="USER=$USER HOME=$WORKINGDIR"
    PRM_EXEC="$DAEMON $DAEMON_ARGS"
    sh -c "start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\
        --background --chdir $WORKINGDIR --chuid $USER \\
        --exec /bin/bash -- -c '/usr/bin/env $PRM_ENVS $PRM_EXEC'"
}

do_stop()
{
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME --oknodo
    rm -f $PIDFILE
}

do_status()
{
    if [ -f $PIDFILE ]; then
        if kill -0 $(cat "$PIDFILE"); then
            echo "$NAME is running, PID is $(cat $PIDFILE)"
        else
            echo "$NAME process is dead, but pidfile exists"
        fi
    else
        echo "$NAME is not running"
    fi
}

case "$1" in
    start)
        echo "Starting $DESC" "$NAME"
        do_start
        ;;
    stop)
        echo "Stopping $DESC" "$NAME"
        do_stop
        ;;
    status)
        do_status
        ;;
    restart)
        echo "Restarting $DESC" "$NAME"
        do_stop
        do_start
        ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
        exit 2
        ;;
esac

exit 0
EOF

sudo update-rc.d prometheus_node_exporter defaults
sudo service prometheus_node_exporter start
prometheus.yamlの設定

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

  - job_name: 'node'
    static_configs:
      - targets: ['localhost: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 /nginx_status {
        stub_status on;
        access_log off;
        allow ::1;
        deny all;
    }
}

疎通確認

curl -v http://localhost/nginx_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

# デーモン作成
sudo touch /etc/init.d/prometheus_nginx_exporter
sudo chmod 755 /etc/init.d/prometheus_nginx_exporter
cat <<'EOF' | sudo tee /etc/init.d/prometheus_nginx_exporter
#! /usr/bin/env bash
### BEGIN INIT INFO
# Provides:          Prometheus NGINX exporter
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Prometheus exporter for NGINX.
# Description:       Prometheus exporter for NGINX metrics exposed.
### END INIT INFO

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="Prometheus Node exporter - Prometheus exporter for NGINX metrics exposed"

NAME=prometheus_nginx_exporter
PIDFILE=/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
WORKINGDIR=/var/lib/prometheus
DAEMON=/usr/local/bin/nginx-prometheus-exporter
USER=prometheus

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

do_start()
{
    PRM_ENVS="USER=$USER HOME=$WORKINGDIR"
    sh -c "start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \\
        --background --chdir $WORKINGDIR --chuid $USER \\
        --exec /bin/bash -- -c '/usr/bin/env $PRM_ENVS $DAEMON'"
}

do_stop()
{
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME --oknodo
    rm -f $PIDFILE
}

do_status()
{
    if [ -f $PIDFILE ]; then
        if kill -0 $(cat "$PIDFILE"); then
            echo "$NAME is running, PID is $(cat $PIDFILE)"
        else
            echo "$NAME process is dead, but pidfile exists"
        fi
    else
        echo "$NAME is not running"
    fi
}

case "$1" in
    start)
        echo "Starting $DESC" "$NAME"
        do_start
        ;;
    stop)
        echo "Stopping $DESC" "$NAME"
        do_stop
        ;;
    status)
        do_status
        ;;
    restart)
        echo "Restarting $DESC" "$NAME"
        do_stop
        do_start
        ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
        exit 2
        ;;
esac

exit 0
EOF

sudo update-rc.d prometheus_nginx_exporter defaults
sudo service prometheus_nginx_exporter start
prometheus.yamlの設定

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

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

Prometheusの管理画面を確認

paste-image-2025-8-19_9-55-25-731.png

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を見れるようにする

  1. Home→Connections→Add new connectionでPrometheusを検索
  2. 右上のAdd new data sourceを押す
  3. Connectionにhttp://localhost:9090を入れる
  4. Save & testを押す
  5. Connections→Data sourcesからprometheus→Dashboard
  6. Prometheus StatsをImport
  7. DashboardsにPrometheus Statsが追加されていて、中身が動いていることを確認
  8. Dashboardsに戻り、右上のNewボタン→Import
  9. Node Exporter FullのIDをコピーしてID欄に貼り付けLoadする
  10. 「Select a Prometheus data source」でprometheusを選んで保存
  11. 先ほどと同様にNginxのIDをコピーしてダッシュボードを作成する

今回作ったDashboardたち

概ねあまり機能していないので、追い追いどうにかしていきたい。

paste-image-2025-8-19_8-35-17-814.png

Prometheus本体のダッシュボード。Local Storage Memory Seriesが出ていない。

paste-image-2025-8-19_8-35-59-356.png

Node Exporterのダッシュボード。全滅。

paste-image-2025-8-19_8-37-1-93.png
paste-image-2025-8-19_8-37-44-466.png

Nginxのダッシュボード。Network InputとOutputだけ出ている。謎。

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-arch.png

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

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

最近OpenWrtカテゴリで10GbE対応ルーターPCであるR86S U1のセットアップを延々しているし、フレッツ光クロス、10Gbps対応に関する覚書でも神戸市の対応状況や、必要なものをまとめたりしているが、費用面はどうだろう?と言う事で調査してみた。

結論から言うと私のケースでは年額4万くらい増えることが分かった。

NTTのサイトが謳う回線料

paste-image-2025-8-18_4-13-29-338.png

NTT西日本のサイトを見てみると、なんとフレッツ光ネクスト隼より安く使えるとある。これが事実ならめっちゃ契約したい。以前より劇的に安くなっている気がする!!!

実際に安くなるのか計算してみた

そんなうまい話はなかった。

現状の料金

NTT

マンション・スーパーハイスピードタイプ 隼 プラン1(割引あり)

サイト上は3,575円だが、何かしらの因果で実際は3,388円だった。

OCN

光 with フレッツ(新2年割、西日本)

891円

合算

4,279円

クロスにする場合の料金

NTT

フレッツ光クロス マンションタイプ(光はじめ割クロスあり)

5,720円

OCN

OCN 光 with フレッツクロス(新2年割あり)

1,815円

合算

7,535円

隼とクロスの差額

月額で3,256円、年に換算すると39,072円。これはかなり厳しい。仮に導入するとしても実運用で回線が厳しくならないと難しい予算帯だ。

ここ5年くらいはfast.com基準で下り平均360Mbps、上り平均420Mbps、レイテンシ平均4-5msほど出ているため、大きな不満はない。機嫌が良ければ上下ともに500Mbpsを超え、レイテンシが3msになることもあるので、なおさらだ。

おまけの機材代

R86S U1は既にあるのでそれ以外。

機材 製品 費用 購入先
L2スイッチ MikroTik CRS305-1G-4S+IN 27,357円 Amazon
NIC * 2 Mellanox ConnextX-4 3,359円 * 2 AliExpress
SPF+ DACケーブル 1.5m 10Gtek 10G SFP+ ケーブル 黒 1.5m 2,359円 Amazon
SPF+ DACケーブル 0.5m 10Gtek 10G SFP+ ケーブル 黒 0.5m 1,999円 Amazon
SPF+ DACケーブル 0.3m 10Gtek 10G SFP+ ケーブル 黒 0.3m 1,799円 Amazon
合計 40,232円

そこそこ高いが一度買えば基本的に買い替え不要なので、この程度はおもちゃ代としてみれば個人的に許容範囲だったが、クロスを導入できない以上、購入は見送ることになった。

R86S U1については10GbEは活かせないが、それ以外は活かせているため全然許容している。R86S U1は間違いなく過去最高のルーターだ。

まとめ

機材費は許容範囲だが、回線費がどうにも厳しかったので、現状の回線でどうしても無理なら契約を検討になると思う。

正直、現状だとIPv6シングルスタック運用は厳しい可能性もあり、仮にするとしてもアクセス数的にトラフィックをそこまで食わない気がするので、現状でも問題ない可能性が多分にある。

R86S U1のSPF+ポートを活かせないのは残念だが、R86S U1自体は先代のRTX830より活躍してくれているし、今のところは現状維持という形にしたいと思う。

デフォルトではeth2は無効化されており、繋いでも何も起きない。

LuCIで設定してゆく。

確認環境

  • R86S U1
  • OpenWrt 24.10.0

手順

  1. LuCIに入る
  2. Network→InterfacesからDevicesタブを開く
  3. br-lanのConfigureを開く
  4. General device optionsタブのBridge portsでeth2を選択する
    r86s-wrt-eth2_1.png
    r86s-wrt-eth2_2.png
  5. 保存してSave & Apply

R86S U1を買ってOpenWrtをインストールしてから今までずっとSPF+ポートが認識されていなかったので認識可能にした。

確認環境

  • R86S U1
  • OpenWrt 24.10.0

前提条件

  • インターネット環境があること

手順

  1. 認識されているかどうか確認し、何も出てこなければ次のステップへ
    dmesg | grep mlx4
    
  2. ドライバをインストール
    opkg install kmod-mlx4-core
    
  3. 再び認識されているかどうかを確認する
    dmesg | grep mlx4
    

なぜこれをしようと思ったか?

最初はeth0, eth1との排他制御かと考えていたが、RJ45とSPF+でNICが分離している構造上ありえないので、有効化できるはずだと思ったためやってみた。ポートはあればあるほど都合がいいし、RJ45が使えればSPF+に対応してない機器もつなげて便利なので。

有効化したSPF+ポートをLANに繋ぐ方法

機材不足で未検証だが、基本的にはOpenWrtでR86S U1のeth2ポートをLANに繋ぐ方法でLANに繋ぐものが出来ると思う。

参考までに有効化したSPF+ポートはeth3, eth4として認識されていることを確認している。これはdmesg | grep mlx4すると分かる。

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

OCNバーチャルコネクトのIPoEでIPv4 over IPv6のMAP-E環境であれば理論上IPv6ポートは全部使えるので、そんならポート指定なしでサーバーを建てられるのでは?というのでやってみた。

確認環境

環境 内容
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アクセスが可能で、かつ以下のセットアップが終わっているものとする。

今回の要件

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

やり方

サーバーとDNSの設定

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

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

  1. LuCIに入りNetwork→Firewall→Traffic Rulesを開く
  2. Addボタンを押し、次の要領で入力して保存
    General Settings

    項目
    Name 適当につける
    Protocol TCP│UDP
    Source zone wan
    Destination zone lan
    Destination address さっき控えたサーバーのv6IPアドレス
    Destination port 開けたいポートを半角スペース区切りで入れる

    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を使えば確かにこんなことはしなくて済むが、次の理由で使っていない。

一つは、オンプレなのに外部サービスに頼りたくない思いがあること、もう一つはCloudflareでドメイン管理する必要性があるはずだが、Cloudflareでドメイン管理すると今使っているメールサーバーのSPFレコードが正しく登録できない問題があることだ。

関連記事