スペック

  • Wi-Fi は 802.11ac(2.4 GHz / 5 Ghz)1x2 MISO Wi-Fi
  • イーサネット (ACアダプタにある) は 100Mbps

MISO は Multi Input Single Output。ダウンロードだけ2本のストリームという意味っぽい?

802.11ac 最低だと1ストリームあたり86.7Mbpsなので、2本だと 173.4Mbps。実際 Chromecast Ultra がどこまで対応しているのか謎。

スペック的には実は Wi-Fi のほうが高いが、Wi-Fi は AP と接続している端末が増えるほど遅くなるのでなんともいえない。専用の AP を立てられて、電波が空いてるなら Wi-Fi のほうが早い可能性がある。

ちなみにうちでは有線LAN接続してる。

  • 既存のインターフェイスを妨げない
    • 今まで使えるものはそのままにする。アクチュエーターが既存の操作の邪魔をしないこと
    • 「生活」に持ちこむ学習コストを最小限にする。少しずつ便利にする
  • 必要ないならインターフェイスを変えない
    • 今までと似た体験にする。アフォーダンス (形の意味) を変えない
    • 必要がないならインターフェイスを追加しない (ゼロクリックを動くことを目指す)
  • それ手でやればよくない?
    • 意味がないことを自動化しても意味がない。家族にも便利であること

インターフェイスの罠としては「定期的に音声で通知する」みたいなのは意外と使えない。というのも、人間だんだん慣れてきて、同じ音が定期的に鳴っていても聞こえなくなるため。視覚に訴えるほうがいいのかも?

  1. トップ
  2. tech
  3. おうちハックで必要なこと

excite光をつかってたので、移行が楽な excite MEC光 という IPoE サービスにしてみました。IPv6 ネイティブかつ DS-Lite による IPv4 接続サービスです。

事前に調べてもさっぱりわからない点があったのでまずそれを検証しました。

ルーターの挙動

  • 貸与ルーター (Aterm WG1810HP) の挙動
    • LAN側は IPv6 ネイティブ接続されるのか? → される。ルーターがRA+DHCPv6 stateless をやってくれる。グローバルIPアドレスが割り当てされる。
    • LAN側の IPv4 アドレスはどうなるのか? → ルータで設定したプライベートIPアドレスがDHCPでくばられる。
    • これまで通りに IPv4 PPPoE セッションははれるのか?
      • レンタルルータだとそもそも設定がなくて貼れない。PPPoE 接続情報自体 excite からもらえない。

この Aterm WG1810HP(MF) は DS-Lite 対応品となっている。DS-Lite 対応ルーターなら他のものも利用可となっているが、このルーターは常に強制的にレンタルする必要がある。

強制レンタルはまぁ許せるけど、それならレンタル料金 (100円/月) を月額料金に含めて書けよと思う。

DS-Lite IPv4 で UPnP のポート解放はできるか

答: できない

DS-Lite では NAT が自宅内ルーターではなく VNE ゲートウェイ (AFTR) 側で行われる (CGN/キャリガグレードナット)ので、手動でポート解放というのが原理的に不可能。それでは UPnP には対応しているのか?という疑問

iijmio ひかりでも答えている。「IPoE接続サービスのDS-Lite方式でのIPv4サービスでは、UPnPによる外部ホストからお客様宅のコンピュータへの通信路確立は行えません。外部へのサービス公開が必要な場合、PPPoE接続を併用されるか、IPv6の利用をご検討ください。」

Mac

デュアルスタック

インターフェイスで IPv6 を有効にすればそれだけで IPv6 ネイティブで繋がるようになる。

なぜか設定でリンクローカルだけの割当になっている端末があったのが罠かった。

Android

デュアルスタック

ZenFone3 (Android 8.0.0)

無線LAN経由で IPv6 接続される。特に設定はなし。

PS4

IPv4 接続

NATタイプ: 2

Nintendo Switch

IPv4 接続

NAT タイプ: B

nasne

IPv4 接続

torne mobileアプリから自宅nasneへ直接接続する機能があるが、機能するか?

アプリから nasne 設定を開くと「通信モード」が表示される。これがNATの状況っぽい? これまでの PPPoE だと通信モードA だった。

IPoE/DS-Lite だとにした直後は通信モード Cで、視聴不可だったが、同一ネットワークから一度つないだら通信モードBになって見れるようになった。

  1. トップ
  2. tech
  3. IPv6 ネイティブ環境に移行 (IPoE + DS-Lite)

おおざっぱにいうと

  • 家庭内のルーター(B4)で IPv4 パケットを IPv6 にカプセル化 (IP IP tunnel)
  • IPv4 ネットワーク接続点 (AFTR) でカプセル化を解き、アドレス変換 (NAT) をして外にアクセスする

だけ。

細かいところで疑問点があったので RFC6333 を見てみた

AFTRのNATの挙動

RFC6333 の B.1.2. Translation Details あたりにAFTR のNATとしての挙動が書いてある。

  • B4 は IPv4 パケットを、AFTR 向け IPv6 パケットにする
  • AFTR は IPv6 パケットから IPv4 パケットをとりだす
  • AFTR はB4グローバルIPv6アドレス・プライベートIPv4アドレスと、グローバルIPv4アドレス・ポートなどをマッピングする
  • AFTR はパケットのIPv4ヘッダを書きかえて IPv4 ネットワークで送信する
  • AFTR はやってくるパケットの宛先グローバルIPアドレス・ポートをもとに、マッピングテーブルから送信すべき B4 IPv6 アドレス・プライベートIPv4アドレスなどを得る
  • AFTR はパケットのIPv4ヘッダを書きかえて、IPv6 パケットにして B4 へ送信する
  • B4 は IPv6 パケットから IPv4 パケットをとりだす
  • B4 は IPv4 パケットを LAN に送信する

NATテーブルは例は RFC6333に書いてあるので引用しておく。結局一番知りたいのはこれだった。

        +------------------------------------+--------------------+
        |         Softwire-Id/IPv4/Prot/Port | IPv4/Prot/Port     |
        +------------------------------------+--------------------+
        | 2001:db8:0:1::1/10.0.0.1/TCP/10000 | 192.0.2.1/TCP/5000 |
        +------------------------------------+--------------------+

            Dual-Stack Lite Carrier-Grade NAT Translation Table

B4側のプライベートIPv4アドレスは勝手に決めていいのか

だいたいいいけど、 DS-Lite では 192.0.0.0/29 が予約されているので、ルーターのLAN側のDHCPでこのレンジが払出されないようにしないとまずいっぽい。

DS-Lite ルーターがデフォルトで 192.168.10.0/24 とかになっているのはこのへんの事情なんだろう。

  1. トップ
  2. tech
  3. DS-Lite の挙動の理解

  • PTR _services._dns-sd._udp.local.
  • A/AAAA [ソースアドレス].in-addr.arpa.

をやりたい。node 付属の dns で mdns クエリを行うとうまくいかなかった。mdns のライブラリを使うと以下のようになった。_services._dns-sd._udp.local. ひいたときにソースアドレスがなぜか取得できないので若干めんどうなことになっている……

//#!/usr/bin/env node

const mdns = require('mdns');

function getServiceWithBrowser(browser, timeout) {
	if (!timeout) timeout = 500;

	return new Promise(function (resolve, reject) {
		const ret = [];
		browser.on('serviceUp', function(service) {
			ret.push(service);
		});
		//browser.on('serviceDown', function(service) {
		//	console.log("service down: ", service);
		//});
		browser.start();
		setTimeout( () => {
			browser.stop();
			resolve(ret);
		}, timeout);
	});
}

function getAllServices(timeout) {
	return getServiceWithBrowser(mdns.browseThemAll(), timeout);
}

function getServiceForType(type, timeout) {
	return getServiceWithBrowser(mdns.createBrowser(type), timeout);
}

async function run () {
	const services = await getAllServices();
	const results = await Promise.all(services.map( (s) => getServiceForType(s.type)));
	const hosts = results.reduce(
		(r, i) => (
			i.forEach((i) => r.set(i.host, i.addresses)),
			r
		),
		new Map()
	);
	for (let [name, addresses] of hosts.entries()) {
		console.log(name);
		for (let address of addresses) {
			console.log("\t", address);
		}
	}
}

run();
  1. トップ
  2. tech
  3. LAN 内の mDNS に応答するホストを列挙したい

ひょんなことから(?)RTX1200を譲ってもらったので使ってみる。VPN 貼りたいとかいう欲求はなくて、普通に家庭用ブロードバンドルーターとして使う (アップストリームが 100Mbps なのでもったいないのだが)。

ネットワークの構成

WAN 側は IPv6 + DS-Lite (excite MEC光)。

なお強制貸与されるルーターはAPモードにできないのでリストラ (動作確認用)。無線LANは手持ちのものをAPモード(ブリッジモード)で再利用する。

LAN側のセグメントは1つ。できるだけ有線LAN接続にしたいので、テレビ付近まで伸ばしてL2スイッチを追加している。

やるべきこと

  • IPv4
    • ipip tunnel を transix に貼る
    • LAN内の IPv4 パケットはすべてそこに流す
    • DHCP サーバで LAN 内のホストにIPアドレス・DNSサーバアドレスを配る
  • IPv6
    • RA で NGN 側から prefix を取得する
    • DHCPv6 クライアントで NGN 側から DNSサーバアドレス を取得する
    • DHCPv6 サーバとなり LAN 側へアドレスプリフィックス・DNSサーバアドレスを通知する
    • RA で LAN 側へアドレスプリフィックスを広告する

初期設定

いちいちコネクション切れるのはうざいので、シリアルコンソール経由でしばらく作業する。クロスケーブルのシリアルケーブルが必要なのが罠かった(ストレートのものしかなかった)が手元に D-SUB 9-Pin のブレッドボードコネクタがあったので、ブレッドボード上で即席でクロス回路をつくってしのいだ…… ネットワーク環境が整えば LAN 内から TELNET か ssh が安定してできるはずなので、あんまり必要はないはず……

screen では encoding sjis を指定しておく。

microSD USB Download を同時押ししながら電源を入れて初期化。その後まず USB からファームウェアを最新にした。USB を押しながら Download を3秒押しつづける。

RTX1200 Rev.10.01.34 (Mon Sep 5 18:55:00 2011) → RTX1200 Rev.10.01.76 (Fri Apr 13 12:25:45 2018)

この状態で念のためシリアルコンソールから cold start (初期化)。再起動後に、一回初期状態で LAN 側に有線接続して web GUI を眺めたりした。

とりあえず以下をしておく。ただしLANの設定がおわってインターネットに繋がるまではシリアルで作業した。

login user USERNAME PASSWORD
sshd host key generate
sshd service on

フィルタ

一番めんどうで一番たいせつ。家庭用ルーターガイドラインを参考に基本的なフィルタを設定していく。

  • IPv4/IPv6 ともに WAN 側からの通信はすべて遮断
  • IPv4/IPv6 ともに LAN 側からの通信はすべて通過
  • TCP WAN 側からの SYN は遮断
  • UDP WAN 側からはすべて破棄
  • WAN 側からの ICMPv6 は必須のもの以外遮断
  • LAN 側からの変な source IPv6 アドレスになっているものは遮断
  • LAN側からの通信を記憶してこのコネクションについてWAN側からの通信を通過

全部は設定できてない

RTX1200 のフィルタ概念

1つでもフィルタが定義されているとデフォルトがリジェクトに設定される

設定

基本的にはこちらからの通信をトリガーにして動的フィルタをかける形になる。「ipv6 lan2 secure filter out 3000 dynamic 100 101 102 103 104 105 106」というフィルタは 「3000 のフィルタをトリガーにして 100 101 102 103 104 105 106 の動的フィルタを生成する」の意味。3000 は単純な pass なので、外に出ていくなんらかの通信すべてをトリガーにして、送信先ホストからの受信を許可する。

RTシリーズのDNSリカーシブ機能はTCPフォールバックが不可能らしいので機能をオフにしておく (IPv6 や DNSEC で TCP フォールバックされるケースが増えているので)。

# IPoE
#ホームゲートウェイ(ひかり電話ルータ)なしの場合(RA回線)
# WAN
# DHCPv6 client を起動
#ir=on だと Information-request (stateless DHCPv6) になるが上流の情報が強制的に設定されるのでつけない (手動で DNS と domain 設定してるからいらないが)
ipv6 lan2 dhcp service client
# v6 ネイティブのため MTU=1500
ipv6 lan2 mtu 1500
#log
ipv6 lan2 prefix change log on

# LAN
# lan1 に付与するアドレスの設定。lan2 から RA プロキシした prefix に ::1 をつける
ipv6 lan1 address ra-prefix@lan2::1/64
# LANに広告(RA)するプリフィックスの定義。lan2 からRAプロキシ
ipv6 prefix 1 ra-prefix@lan2::/64
# 上で設定したプリフィックス定義1を広告するように設定。DHCPv6 から他の情報も送信するので o_flag=on
ipv6 lan1 rtadv send 1 o_flag=on
# DHCPv6 サーバの起動
ipv6 lan1 dhcp service server

# DNS
#Use Cloudflare DNS
#dns server 1.1.1.1 1.0.0.1,2606:4700:4700::1111,2606:4700:4700::1001
#Use Google Public DNS
dns server 8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844
#上の設定が優先されるはずだが dhcp 経由のものも設定はしておく
dns server dhcp lan2
#余計なドメイン指定をけしたい
dns domain .
# DNS リカーシブ機能をオフにする。TCPフォールバックができないため。
dns service off
# DNS リカーシブをオフにしているので、me を DNS サーバとして送らないように
dns notice order dhcp server

# IPv4
# DHCP サーバの起動
dhcp service server
dhcp server rfc2131 compliant except remain-silent
# アドレス範囲が 192.168.0.0/29 にかぶらないようにスタートアドレスを変えておく
dhcp scope 1 192.168.0.10-192.168.0.100/24
# LAN 側のアドレスを設定
ip lan1 address 192.168.0.1/24

# DS-Lite(ipip tunnel)
# IPv4 をトンネル1を通すように設定
ip route default gateway tunnel 1
# トンネル1の設定
tunnel select 1
 # トンネル種別。ipip トンネル (IPv4 over IPv6)
 tunnel encapsulation ipip
 # AFTR のアドレスを設定
 tunnel endpoint address 2404:8e00::feed:101
# IPv6 MTU から IPv4 ヘッダ(40bytes) を減じた MTU
 ip tunnel mtu 1460
 ip tunnel secure filter in 1020 1030 2000
 ip tunnel secure filter out 1010 1011 1012 1013 1014 1015 3000 dynamic 100 101 102 103 104 105 106 107
 ip tunnel tcp mss limit auto
 tunnel enable 1

#Filter IPv6
ipv6 lan2 secure filter in 1010 1011 2000
ipv6 lan2 secure filter out 3000 dynamic 100 101 102 103 104 105 106
ipv6 filter 1010 pass * * icmp6 * *
# 546=dhcpv6 client
ipv6 filter 1011 pass * * udp * 546
ipv6 filter 2000 reject * * * * *
ipv6 filter 3000 pass * * * * *
ipv6 filter dynamic 100 * * ftp
ipv6 filter dynamic 101 * * domain
ipv6 filter dynamic 102 * * www
ipv6 filter dynamic 103 * * smtp
ipv6 filter dynamic 104 * * pop3
ipv6 filter dynamic 105 * * tcp
ipv6 filter dynamic 106 * * udp

#Filter IPv4
ip filter source-route on
ip filter directed-broadcast on
ip filter 1010 reject * * udp,tcp 135 *
ip filter 1011 reject * * udp,tcp * 135
ip filter 1012 reject * * udp,tcp netbios_ns-netbios_ssn *
ip filter 1013 reject * * udp,tcp * netbios_ns-netbios_ssn
ip filter 1014 reject * * udp,tcp 445 *
ip filter 1015 reject * * udp,tcp * 445
ip filter 1020 reject 192.168.0.0/24 *
ip filter 1030 pass * 192.168.0.0/24 icmp
ip filter 2000 reject * *
ip filter 3000 pass * *
ip filter dynamic 100 * * ftp
ip filter dynamic 101 * * www
ip filter dynamic 102 * * domain
ip filter dynamic 103 * * smtp
ip filter dynamic 104 * * pop3
ip filter dynamic 105 * * submission
ip filter dynamic 106 * * tcp
ip filter dynamic 107 * * udp

# etc
schedule at 1 */* 06:00 * ntpdate ntp3.jst.mfeed.ad.jp syslog

status

# ルーターが取得した ipv6 アドレス
show ipv6 address lan2

# DHCPv6 の状態
show status ipv6 dhcp

# IPv4 DHCP サーバの状態
show status dhcp

show status lan1
show status lan2

show log reverse

interface reset lan2
clear ipv6 dynamic routing
clear ipv6 neighbor cache

挙動不信?

DHCPv6 の DNS

dns server を設定して dns notice order dhcp server をしても DHCPv6 の DNS 通知に反映されず、常にルーターの IPv6 アドレスが通知される。解決方法がわからない。

IPv4 の DHCP でもなんか変な挙動で、設定してない IPv4 アドレスの DNS が通知されたりする。

→ LAN 側の IP アドレスを dns server に設定したらルーターのアドレスが設定されなくなった。

DHCPv6 の domain

flets-east.jp のドメインがついたり、iptvf.jp というドメインがついたりする。つかなかったりもする。

ir=on (stateless DHCPv6) にすると強制的に上流の情報が付与されてしまうっぽい。ir=on をなくして、dns server や dns domain を自分で指定すればオッケー

IPv6 接続不可

設定して8時間ぐらい経過したあたりで IPv6 接続ができなくなっていることに気付いた。IPv4 は通るのでインターネットには出れる状態。かなり意味不明でこまった

  • ルーターからtransixまでの NGN 内 IPv6 ルートはある
  • LAN内ホストからルーターまでの IPv4 ルートはある
  • ルーターまで ping6 [link local]%en0 は通る
  • グローバルIPv6アドレスへの ping6 は通らない (no route to host)
  • lan2 の ipv6 フィルタをはずしても効果なし

いろいろ設定変更して restart とかしていたら接続できるようになってしまったが、いまいち解決方法がわかってない。

考えられる原因?

  • ルーターに割り当てられるグローバルIPアドレスプリフィックスが変化したがLAN内ホストがうまく追従できなかった
  • lan1 と lan2 に二重でグローバルIPアドレスが付与されていた?
    • 「デフォルト経路は最後に設定が完了したインタフェースに向く」と書いてあるのでなんかありそう
    • lan2 側で ipv6 address 指定をやめた。

ref

  1. トップ
  2. tech
  3. IPv6 IPoE + DS-Lite 環境での RTX1200 の設定

ndisc6 に入っている rltraceroute6 を使えば良いっぽい。

sudo apt-get install ndisc6

ping6 は通るけど traceroute6 が失敗する場合、途中のルーターでUDPが落とされている可能性がある。-I オプションで ICMPv6 Echo を送るようになる

rltraceroute6 -I  [host]
  1. トップ
  2. tech
  3. Ubuntu で ICMP Echo traceroute6 する

NEC 無線LANルーター dual band Wi-Fi5 (11ac) / WG2600HP3 Atermシリーズ 4ストリーム (5GHz帯 / 2.4GHz帯) ‎PA-WG2600HP3【 iPhone 13 / 12 / SE(第二世代) / Nintendo Switch メーカー動作確認済み】 - Aterm

Aterm

5.0 / 5.0

PA-WG2600HP3 はルーターだけどブリッジモード(AP)として使う。RTX1200 買ったばっかりやろという感じなので最近ルーターにハマってるの?と妻に言われる始末。

今まで使っていたのが 11n までしか対応してないのと、微妙に電波が届かない場所があって不便だったので、最新のものに買い替えてみた。AP機能だけあれば良いが、別にルーター機能があっても殺せれば困らないし、最悪バックアップ機にもなるのでまぁいいかという感じ。

微妙に届かない場所問題は無事に解決した。バンドステアリング (IEEE802.11k とか IEEE802.11v あたりらしい) も有効にしたので、5G が繋がりにくいときは 2.4G で繋ぎなおしてくれる。いい感じ。

ただ、UI が旧機種からだいぶ変わってしまって使いにくくなってしまった。いちいち前のページに戻らないと別の設定にいけないのがだるい。

あとこの機器のLAN側IPアドレスを指定しつつDHCPでDNSを指定するのができなくなった。全部手動で設定するかDHCPで全部取得するかしかできない。

  1. トップ
  2. tech
  3. Wi-Fi ルーター NEC WG2600HP3 を買った

検索すると Lua スクリプトを RTX にいれる方法もあるみたいだが、別途プロキシが必要みたいなので LAN 内の raspberrypi から SNMP で取得して投げるほうを選んでみた。raspberrypi には既に mackerel-agent が入れてあるので、追加の設定をするだけ。

mackerel-agent-plugins

mackerel-agent は arm 版もリリースされているが、プラグインはリリースされていない。自分でビルドする必要がある。

mackerel-plugin-snmp だけあればいいので、mackerel-plugin-snmp のディレクトリで

env GOOS=linux GOARCH=arm GOARM=5 go build

するだけでバイナリができる。できたバイナリを raspberrypi の /usr/local/bin とかにコピーしておく。

設定

SNMP で取得するが、 mackerel の custom_identifier でホスト分けて表示する。

まず mkr create でホストをつくる

mkr --customIdentifier router1 router1

ここで指定した customIdentifier をプラグインの設定に書くとこちらのホストに投稿したことになる。

[plugin.metrics.snmp-router]
command = "mackerel-plugin-snmp  -community='public' -host='192.168.0.1' .1.3.6.1.2.1.2.2.1.16.1:ifOutOctets.2 .1.3.6.1.2.1.2.2.1.10.1:ifInOctets.2 .1.3.6.1.4.1.1182.2.1.15.0:temp.yrhInboxTemperature .1.3.6.1.4.1.1182.2.1.4.0:memory.yrhMemoryUtil .1.3.6.1.4.1.1182.2.1.5.0:cpu.yrhCpuUtil5sec .1.3.6.1.4.1.1182.2.1.6.0:cpu.yrhCpuUtil1min .1.3.6.1.4.1.1182.2.1.7.0:cpu.yrhCpuUtil5min"
custom_identifier = "router1"

SNMP の OID を調べるのがめちゃくちゃ面倒くさいがだいたい上記ぐらいでいいだろう。

この方法の欠点

  • cpu やメモリのメトリクスは mackerel で特別扱いされているが、この方法だとすべて snmp.* のメトリクスになってしまう
  1. トップ
  2. tech
  3. mackerel-agent + snmpで RTX1200 のメトリクス取得

メトリクスの可視化をもうちょっとやりたくて prometheus と grafana をセットアップした。監視は mackerel でやってるのでやらない。

prometheus

Ubuntu の prometheus が古いので最新を自分でおく。/usr/local/prometheus にバイナリを置いていく。node_exporter も同様に /usr/local/node_exporter に置く。

 lm /usr/local/{node_exporter*,prometheus*}
lrwxrwxrwx 1 root  root    28  7月 14 22:32 /usr/local/prometheus -> prometheus-2.3.2.linux-amd64/
lrwxrwxrwx 1 root  root    32  7月 14 23:07 /usr/local/node_exporter -> node_exporter-0.16.0.linux-amd64/

/usr/local/node_exporter-0.16.0.linux-amd64:
合計 17M
-rwxr-xr-x  1 cho45 cho45  17M  5月 16 00:53 node_exporter*
-rw-r--r--  1 cho45 cho45  463  5月 16 00:57 NOTICE
-rw-r--r--  1 cho45 cho45  12K  5月 16 00:57 LICENSE
drwxr-xr-x  2 cho45 cho45 4.0K  5月 16 00:58 ./
drwxr-xr-x 14 root  root  4.0K  7月 14 23:07 ../

/usr/local/prometheus-2.3.2.linux-amd64:
合計 111M
-rwxr-xr-x  1 cho45 cho45  68M  7月 12 23:04 prometheus*
-rwxr-xr-x  1 cho45 cho45  43M  7月 12 23:05 promtool*
-rw-r--r--  1 cho45 cho45  926  7月 13 00:04 prometheus.yml
drwxr-xr-x  2 cho45 cho45 4.0K  7月 13 00:04 consoles/
drwxr-xr-x  2 cho45 cho45 4.0K  7月 13 00:04 console_libraries/
-rw-r--r--  1 cho45 cho45 2.8K  7月 13 00:04 NOTICE
-rw-r--r--  1 cho45 cho45  12K  7月 13 00:04 LICENSE
drwxr-xr-x  4 cho45 cho45 4.0K  7月 13 00:05 ./
drwxr-xr-x 14 root  root  4.0K  7月 14 23:07 ../

systemd の設定を置く

/etc/systemd/system/prometheus.service

[Unit]
Description=Prometheus service
After=network.target

[Service]
ExecStart=/usr/local/prometheus/prometheus --config.file=/etc/prometheus/prometheus.yml --log.level=debug --storage.tsdb.path=/var/lib/prometheus
Restart=always

[Install]
WantedBy=multi-user.target

/etc/systemd/system/node_exporter.service

[Unit]
Description=Prometheus node_exporter
After=network.target

[Service]
ExecStart=/usr/local/node_exporter/node_exporter
Restart=always

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl enable prometheus

sudo systemctl start node_exporter
sudo systemctrl enable node_exporter

grafana

http://docs.grafana.org/installation/debian/ に従ってインストール。Ubuntu のレポジトリのやつはなんかおかしくてアイコンとかが表示されないので使わないほうが無難。

deb https://packagecloud.io/grafana/testing/debian/ stretch main

grafana は初回起動時に admin/admin で入れる。適当にパスワードをかえておくこと。

grafana へのデータソース追加方法はここ
https://prometheus.io/docs/visualization/grafana/

h2o prometheus exporeter

h2o の status に内部アクセスして prometheus 形式にするやつを書いている人がいるので、これを使うとよさそう。
https://gist.github.com/yannick/31d3d8ea6bcc3553dd422aad9d0e4173

リバースプロキシ

prometheus は 9090、grafana は 3000 がデフォルトポート。フロントの http サーバーからリバースプロキシを適当に設定しておく。prometheus は認証もつけておく。grafana は認証機構があるためフロントでは認証をかけない。

  1. トップ
  2. tech
  3. prometheus + grafana のセットアップ (Ubuntu 16.04.4 LTS)


Public VPS 上の Ubuntu に prometheus と grafana をセットアップしたので、自宅のネットワークのメトリクスもとって、そちらで表示したい。

自宅は IPv4 は NAT 内、IPv6 はグローバルだが IPv4 + NAT 程度のアクセス制限をかけていて、あまりそこをいじりたくないので、なんとかして自宅側から外への接続ですませたい。

prometheus は pull 型なのでこういった環境でのメトリクス収集がやっかい。いくつか方法がある

pushgateway を使う。prometheus 公式で提供されている short live batch 用のゲートウェイ。POST すると pushgateway 側で値を保持してくれて、prometheus からの pull に答える。使うのが簡単なので最初はこれでやっていたが、prometheus 的にはこういうやりかたはよくないっぽい。

検討した結果以下のような形にする

  • 自宅内にも prometheus サーバを立てる
  • Public VPS 側からは federate で連携する

自宅セグメント内のメトリクスをひとまとめにしてから、連携させる。こうすることで、各 exporter のアクセスコントロールなどはやりやすくなる。ただ、結局この方法も /federate を pull する形になるので、そこはなんとかする (後述)

自宅 Raspberry Pi への prometheus セットアップ

自力で prometheus と node_exporter を置くところから。prometheus は arm ビルドを公式提供していないので、自分でビルドする。

prometheus のレポジトリの .promu.yml を書きかえ、linux/arm だけ有効にして、promu crossbuild を行う。 .build/linux-armv5 以下に prometheus のバイナリができるので、これを Raspberry Pi 側に scp する。

go get github.com/prometheus/prometheus/cmd/prometheus
cd $GOPATH/src/github.com/prometheus/prometheus
vim .promu.yml
ls  .build/linux-armv5

node_exporter はgithub の releases ページ に arm5 版があるのでそのまま使えば良い。

自宅 Raspberry Pi の prometheus を Public VPS の prometheus と繋ぐ (federate)

Public VPS 側から自宅側の /federate にアクセスして pull する。2つの方法を検討した。

  • 自宅側にさらに別のフロントhttpサーバを用意して、アクセス制限・認証をかけつつ /federate をリバースプロキシし、Public VPS 側から直接アクセスさせる。
  • Public VPS 側でリクエストを中継するサーバを用意して、自宅側からコネクションを貼りにいく。

1番目の方法は「自宅のIPアドレスを取得する」「アクセス制限・認証をかける」あたりが面倒くさい。DDNS の設定、ネットワーク(ルーター)の設定、アプリケーションレベルの認証設定と影響範囲が広い。

2番目の方法は Prometheus のサイトからリンクがある PushProx で実現できる。自宅側からは外向きにコネクションを貼るだけなので、影響範囲は狭い。ということでこれを使ってみることに。

設定

Public VPS 側では PushProx proxy プロセスを立てる。引数なしで立ち上げると 8080 ポートでプロキシサーバが立ちあがる。

./proxy

認証機能がついていないため、フロントの http サーバでリバースプロキシと適当な認証・アクセス制限をつけておく必要がある。

自宅側には client プロセスを立てる。このとき --proxy-url として、Public VPS 側の proxy のアドレスを指定する。リバースプロキシしているので、そのホストを指定する。

prometheus.yml

federate に関係するところを抜きだすと以下のように。raspberrypi となっているところは client 側で送っているホスト名になる。PushProx はこの文字列でプロキシすべき先を区別している。

# Public VPS 側 (federate を pull する側)
  - job_name: 'federate'
    scrape_interval: 15s
    honor_labels: true
    metrics_path: '/federate'
    params:
      'match[]':
        - '{job="node"}'

    proxy_url: http://127.0.0.1:8080/
    static_configs:
      - targets:
        - 'raspberrypi:9090'

また自宅側の prometheus.yml には external_labels を指定しておく。これは federate のときに固定でラベルを追加する設定。

# 自宅側 (/federate を配信する側)
global:
  external_labels:
    location: home

これで 127.0.0.1 のような指定をして instance 名がかぶっていても自宅のものと区別がつく。

PushProx の罠

現状の PushProx はかなり微妙な感じ。client 側がタイムアウトして接続を切っても、proxy 側ではそれがずっと残っていて、タイムアウト数ぶんのリクエストを受けきるまでまともに動作しなくなってしまう。

現状では pull するほうの prometheus (Public VPS側) を止めるときは proxy プロセスも止める必要がある。一応これに対応するパッチは書いた。

このへんが微妙なので、ちゃんと IPv6 で直接アクセスできる環境をつくってもいいかもなあと思っている。

  1. トップ
  2. tech
  3. 自宅 raspberrypi への prometheus セットアップとリモートの prometheus との連携

RTX1200 から直接 prometheus 形式でメトリクスを取得できる Lua スクリプトを書いた。

prometheus + grafana のセットアップ (Ubuntu 16.04.4 LTS) | tech - 氾濫原 自宅 raspberrypi への prometheus セットアップとリモートの prometheus との連携 | tech - 氾濫原 とやってきて、自宅内のメトリクスを grafana で表示できるようにしたので、自宅のルーターの RTX1200 のメトリクスをとるようにした。

RTX1200 はユーザー Lua を実行できる環境があり、そこそこ高級なことができる。TCP サーバは簡単に立てられる。HTTP サーバはないが、不特定多数のリクエストを受けるものでもないので、自力で簡単なものを実装した。

Luaスクリプト

https://github.com/cho45/rtx1200_exporter/blob/master/rtx1200_exporter.lua

エンコーディングが sjis なのが注意点。9100 を listen している。IPv6 を listen する方法はないっぽいので、必ず IPv4 でアクセスする必要がある。

出力サンプル

メトリクス名が prometheus のベストプラクティスから外れてるのは、もともと SNMP でとっていた値があるため。

というか SNMP ではとれるけど Lua からは直接とることのできないメトリクスがあるのでちょっと困る。 Lua から自分向けに SNMP 使えばとれると思うが今回やっていない。

# Collecting metrics...
# TYPE yrhCpuUtil5sec gauge
yrhCpuUtil5sec 3
# TYPE yrhCpuUtil1min gauge
yrhCpuUtil1min 2
# TYPE yrhCpuUtil5min gauge
yrhCpuUtil5min 2
# TYPE yrhInboxTemperature gauge
yrhInboxTemperature 46
# TYPE yrhMemoryUtil gauge
yrhMemoryUtil 24
# TYPE ifOutOctets counter
# TYPE ifInOctets counter
ifOutOctets{if="1"} 51255053848
ifInOctets{if="1"} 8057224805
ifOutPkts{if="1"} 43465561
ifInPkts{if="1"} 27396255
ifOutOctets{if="2"} 8411163805
ifInOctets{if="2"} 52401299138
ifOutPkts{if="2"} 25933809
ifInPkts{if="2"} 42718551
ifOutOctets{if="3"} 0
ifInOctets{if="3"} 0
ifOutPkts{if="3"} 0
ifInPkts{if="3"} 0
# TYPE ipSession counter
ipSession{proto="v4"} 59
ipSession{proto="v6"} 35
# TYPE ipChannel counter
ipChannel{proto="v4"} 59
ipChannel{proto="v6"} 35

Lua のデバッグ方法

いまいちベストのデバッグ方法がわからないが、以下のような手順でやった。

以下の upload.sh を保存するたびに実行

#!/bin/sh

PASS=adminpass

cat <<EOF | tftp 192.168.0.1
put rtx1200_exporter.lua /rtx1200_exporter.lua/$PASS
quit
EOF

telnet 繋ぎっぱなしで以下を手動で実行

terminate lua all
lua /rtx1200_exporter.lua
show status lua
  1. トップ
  2. tech
  3. RTX1200 prometheus exporter Lua スクリプト

127.0.0.1 より localhost のほうが書きやすいし良さそう、と思って localhost と書いているとしばしばハマります。

というかなんとなく localhost = 127.0.0.1 と考えがちではないでしょうか? そんなことはないので気をつけましょう。

最近のシステムなら /etc/hosts を確認すると少なくとも2つの localhost エントリを見ることができるでしょう。

127.0.0.1       localhost
::1             localhost 

上は IPv4、下は IPv6 です。localhost はどちらのアドレスにも解決しうるホスト名となっています。

どういうときにハマるか

例えば同一サーバでリバースプロキシを行ってバックエンドサーバと繋ぎこみを行う場合、フロントのリバースプロキシで localhost:5000 と書くと IPv4 IPv6 どちらでアクセスされるか不定です。バックエンドサーバが IPv4 しか bind していないと IPv6 アドレスが選択されたとき接続不可になります。

正しい方法

すべてのサービスで IPv4 IPv6 ともに接続可能にし、ホスト名でアクセスできるようにすること。

非公開な内部向けサーバとかだと割と IPv4 しか使えないようにしがちではないかと思いますが、ちゃんとやったほうが無難です。

次善の策

ホスト名でひける IP アドレスの種類と実際に受けつけるプロトコルの種類をあわせること。

localhost の替わりに 127.0.0.1 か ::1 を使ってプロトコルを明示すること。

localhost に限らない

実際にところは localhost に限らず、ホスト名でアクセスするときには必ず気をつけるポイントです。DNS で IPv4 IPv6 いずれのアドレスも解決できるようにするなら、そのホスト上で待ち受けるサービスは全てデュアルスタックになっていないと、あらぬところでハマったりします。

  1. トップ
  2. tech
  3. localhost と書くと IPv6 対応したときに死ぬことがある

結論からいうと CAT6 か CAT6A を使う。33m までなら CAT6 でも良いことになっているので家庭なら CAT6 でも十分ということになる。ただ伝送帯域に余裕がないので、取り回しに問題がないなら CAT6A を使うほうが良さそう。

8P8C (RJ45) コネクタを使う CAT7 CAT8 規格は存在しない

簡単にいうと CAT7 CAT8 のコネクタは CAT6A 以前とは互換性がない。市場には 8P8C で CAT7/CAT8 なケーブルが売っているではないか?と思うかもしれないが、あれはケーブルだけ CAT7/CAT8 なだけで、全体としては規格に適合していない野蛮なものである。

ケーブルにいくら CAT7 CAT8 適合なものを使っても、コネクタに 8P8C (RJ45) を使う場合には CAT6A と同等の扱いとなる。ただの硬い CAT6A ケーブルでしかない。それなら CAT6A で良い。

また、CAT7 以上では STP (シールド付き) なので、機器側でアースがしっかりとれていなければならない。家庭用機器でアースをとるものはほとんどない (接地用端子・接地極がついたコンセントがそもそも普及してない) で、この点でもやはり意味がない。

電位が浮いてる状態の導体があると、そこがアンテナになってしまう。また、適切に両端を接地したとしても、今度はグラウンドループが形成されるため、かえってノイズが増えることもある。接地すべきかどうかがケースバイケースで決まってしまう。ノイズ対策は「グランド繋げば解決」みたいな簡単なものでは全くない。

この点でシールドケーブルは素人には光ケーブルよりも取り扱いが難しい。なので10Gbpsを超えるようになってくると本格的にファイバーに移行する必要が出てくるのではないかと思う

  1. トップ
  2. tech
  3. 10GBASE-T LANケーブル CAT6 CAT6A CAT7 CAT8

LAN向けのDNSキャッシュサーバ

経緯としてRTX1200 の DNS 機能が TCP フォールバックに対応してないのでオフにした、というのがある。直接 8.8.8.8 8.8.4.4 を DHCP で広告するようにしてみたが、RTT が 8ms ぐらいあるので、やはり LAN 内にキャッシュサーバがあったほうがいいかなと思いはじめた。

LAN内には常時動いている Raspberry Pi のホストがいるので、ついでにこのホストにDNS機能もやらせることにしてみた。

unbound

unbound がキャッシュサーバ専用でよさそうなのでこれにする。

sudo apt-get install unbound
#/etc/unbound/unbound.conf.d/my.conf   
# See /usr/share/doc/unbound/examples/unbound.conf for a commented
server:
        verbosity: 1
        num-threads: 4
        interface: 0.0.0.0
        interface: ::
        msg-cache-size: 64m
        msg-cache-slabs: 4
        rrset-roundrobin: yes
        rrset-cache-size: 128m
        rrset-cache-slabs: 4
        infra-cache-slabs: 4
        access-control: 192.168.0.0/16 allow
        key-cache-size: 64m
        key-cache-slabs: 4
        neg-cache-size: 64m
        prefetch: yes
        minimal-responses: yes
        incoming-num-tcp: 100
        outgoing-num-tcp: 100
forward-zone:
    name: "."
    forward-addr: 8.8.8.8
    forward-addr: 8.8.4.4
# 自動起動
sudo systemctl enable unbound
# 起動
sudo systemctl start unbound
# ステータス
sudo systemctl status unbound
# ログ
sudo journalctl -r

以下のようなコマンドでクエリ数やキャッシュヒット率が見れる。

unbound-control stats_noreset | grep total

今後

キャッシュヒット率を見つつ、あんまり意味がなさそうなら (数%ぐらいしかヒットしないとか) やめるつもり。

自宅は昼間は誰もいないので、このタイミングでTTLが短いほとんどのキャッシュは無効になってしまう。unbound の prefetch は TTL が残り10%になったときにクエリがくると再問合せする機能なので、クエリがこなければ一切 prefetch はされない。

さらには一番影響がでるブラウザでは、DNS prefetch が実装されているので、体感的にはネットワークの近くにDNSがあっても意味がないことが多い。

自分で DNS キャッシュサーバを運用するコストと釣り合わないかもしれない。

(備考)raspberry pi の ip アドレスを固定

raspi の IP アドレスを固定しておく

#/etc/dhcpcd.conf 
interface eth0
static ip_address=192.168.0.222/24
static routers=192.168.0.1
static domain_name_servers=127.0.0.1
sudo systemctl daemon-reload
sudo systemctl stop dhcpcd
sudo ip addr flush dev eth0 ; sudo systemctl start dhcpcd
sudo systemctl restart avahi-daemon.service 

確認

dig @192.168.0.222 example.com

同一ホストで

sudo unbound-control stats_noreset | grep total
sudo unbound-control dump_cache
  1. トップ
  2. tech
  3. RaspberryPi を家庭内 LAN の DNS キャッシュサーバーに

curl は POST や PUT でリクエストボディの長さが長いなどの特定条件になると、まず Expect: 100-continue をつけてリクエストを送り、サーバ側の対応を待ってからリクエストボディを改めて送るという行儀が良い実装になっている。

しかし、特に IoT っぽい機器では Expect: 100-continue に対応していないものもあるので、抑制したい場合がでてくる。そういうときは以下のようにする。

curl -H "Expect:" -d ... url

空の Expect ヘッダを指定することで上記のような挙動をしなくなり、最初からリクエストをフルで送りつけるようになる。

  1. トップ
  2. tech
  3. curl の Expect: 100-continue を抑制する

今更ながらいまいち理解できてないポイントがあったので、いっかい自分でまとめてみることにする。当たり前のことではあるが……

L2スイッチ

セグメントを構築する機器 スイッチングハブ

用途はリピーターハブと同じで、あるポートに届いたイーサネットフレームを他の全てのポートへ転送する。ただし帯域を有効利用するため転送されてきたポートと MAC アドレスの対応を記憶して、次回から必要のないポートに転送することをやめる。

ルーター

セグメント間を接続する機器

IPヘッダを解釈し、ルーティングテーブルから次に転送すべきルーターへパケットを転送する。

頻出事例

(IPv4) L2スイッチに接続されたコンピュータ同士の通信

同一セグメント内の通信ということになる。L2スイッチで完結する。

192.168.0.101 から 192.168.0.102 への通信の例

  • 101 は 102 の IP アドレスをのせてARPリクエストをイーサネットにブロードキャスト
  • 102 は自分の MAC アドレスをのせてARPレスポンス
  • 101 は取得した MAC アドレス宛にIPパケットをのせたイーサネットフレームを送信

L2 スイッチは多段接続しても1つのネットワーク。

(IPv6)L2スイッチに接続されたコンピュータ同士の通信

ほとんど IPv4 と同じだが ARP ではなく ICMPv6 で MAC アドレスが解決される。Neighbor Solicitation メッセージと Neighbor Advertisement メッセージが使用される。

(IPv4) ルーターを介したコンピュータ同士の通信 (外部ネットワークなど)

192.168.0.101 から 93.184.216.34 への通信の例

  • 101 は自分のルーティングテーブルを参照する
  • 接続先が同一セグメントではないため、デフォルトゲートウェイ(またはルーティングテーブルにあるホスト) へ転送しようとする
  • 転送するホストのIPアドレス (例:192.168.0.1) の MAC アドレスを取得する (ARP)
  • 取得した MAC アドレス宛にIPパケットをのせたイーサネットフレームを送信
  • ルータは送られてきたイーサネットフレームとIPパケットを解釈し、次のルータにIPパケットを転送する。このときIPパケットを載せるプロトコルはイーサネットとは限らない。PPP ということもある。

(IPv6) ルーターを介したコンピュータ同士の通信 (外部ネットワークなど)

こちらも ARP 部分が ICMPv6 でおきかわる。ルーターの場合はネットワーク接続時の要求や、定期的にブロードキャストされる Router Advertisement メッセージから MAC アドレスがキャッシュされているため、基本的にルーター MAC アドレスが既知のものとなる。

  1. トップ
  2. tech
  3. L2スイッチとルーター

  • これまで採用されていた輻輳制御アルゴリズムの多くはパケットロスベースであった
    • CUBIC / (New) Reno など
  • しかし実際はパケットロスと輻輳は厳密に対応しない
  • 輻輳はネットワークの処理能力の限界を超えたときに発生する
    • 処理すべきデータ容量が処理可能なデータ容量を超えると発生する
  • パケットロスは瞬間的なトラフィック増加や、電気的ノイズなどネットワーク処理能力以外の要素でも発生する現象
    • 無線ネットワークのように原理的にパケットロス率が高いことも多い

BBR では通信先との間の実際に使える帯域を推定し、パケットロスが起こっていても、あるいはパケットロスが起こらなくても、輻輳しない程度に最大のスループットを出す。

実際のアルゴリズムは解説してるサイトを見るほうが早い。

ref

  1. トップ
  2. tech
  3. BBR 輻輳制御アルゴリズムの考えかた

(写真は練習の別の候補問題のもの)

日曜日が試験日だった。どうやら筆記試験と違って、試験会場が県あたり1つしかないようで、試験会場の最寄りのマイナー駅がものすごい混雑だった。こんなに受験者がいるのかーとびっくり。

追記:神奈川県の場合、試験会場は2つだったみたい。

候補問題が13問なので2週間ぐらい前から1日1問ずつ消化していった。練習してみると結構欠陥 (不合格) を出してしまう。特に電線の種類・長さを間違えると、他の欠陥に比べて取り返しがつかないことになる。ということで当日は特にこのへんを気をつけようという心掛けをした。

出題問題は候補問題7の4路スイッチを含む回路だった。

あんまり好みの問題ではなかったけど一通りやるだけやったという感じ。電線色が任意の箇所が多いので逆に不安になる。約15分ほど残して終わり。見た目的には教科書通りという感じだけど、一通りチェックはしても細かい欠陥があるかどうかは、勘違いとかもあるのでよくわからない。合格発表は8月20日。合格していなかったら下期に再受験。

  1. トップ
  2. tech
  3. 第二種電気工事士 技能試験

電工ペンチ (圧着とかストリップとか一通りできる便利道具) を捨てて、ちゃんとした圧着ペンチとストリッパーをそれぞれ買った。

ホーザン(HOZAN) 圧着工具(裸圧着端子/裸圧着スリーブ用) 圧着ペンチ コンパクトタイプ サイズ1.25/2 P-732 - ホーザン(HOZAN)

ホーザン(HOZAN)

5.0 / 5.0

ベッセル(VESSEL) ワイヤーストリッパー 電気工事士技能試験対応 3500E-1 - ベッセル(VESSEL)

ベッセル(VESSEL)

5.0 / 5.0

もうほんと、全然使い勝手が違う。最初からこの2つを買うべき。

電工ペンチのストリッパーは全然切れなかったけど、専用ストリッパーは無理矢理ひっぱらなくても綺麗にストリップできる。

圧着ペンチはもう全然違う。電工ペンチではいくら力を入れても一定以上圧着できないうえに、端子を噛みこんでしまって外すのが大変だったけど、ホーザンのこれだと全然力は必要ないし、綺麗にはずれる。電工ペンチで圧着したものを再度新しいもので圧着してみたけど、力はそれほど入れてないのに、さらに強く圧着できた。

  1. トップ
  2. tech
  3. 電工ペンチを捨て、専用ストリッパーと圧着ペンチを買った

しばらく(2年ぐらい?)ELECOMの難燃のケーブルボックスを使ってみた使い勝手がよかったので、うちで使ってるものをこれに統一したり、使ってないところでも使うようにした。

エレコム ケーブル収納ボックス ケーブルボックス ケーブル収納 6個口電源タップ収納 ブラック EKC-BOX001BK - エレコム(ELECOM)

エレコム(ELECOM)

5.0 / 5.0

まず難燃ってのが良い。ケーブルボックスで明確に難燃とうたってる製品はあんまりないのでありがたい。

素材の質感もなかなか良い。スチロール系のテカテカしたプラスチック感はなくて梨子地のいい感じのもの。

そのうえで使い勝手がなかなか良い。蓋はのっかるだけのものだけど、意外と綺麗にしまる。少し高さ(深さ)があるためだと思う。これのおかげで溝からケーブルを出しやすい。

内径で一番狭いところは 365mm x 128mm x 125mm。6個口用と書いてあるがその通りで、6個口のOAタップでちょうどいいサイズ。

Before

  • ONU (GE-PON<M>A GE-PON-ONU<1><2>)
    • 光ルータ (RT-200NE) のハブ
      • 光ルータ (RT-200NE) のWAN
        • ひかり電話 RJ-11
      • PPPoE ルータ (MR-OPT100E)
        • LANコンセント
        • 無線LANルータ (WHR-G54S)

光ルータのハブに一回繋いでからWANに繋いでるのでかなり不安になる感じ (ONU直下のハブとして光ルータのハブ部分を使ってる)。まぁ動いてはいる。そして無線LANルータがブリッジではなくルーターとして接続されているので二重ルーター状態だった。意図がよくわからない。ブリッジの概念を知らなかったのかも。

2006年ごろに構成したので意味不明なのは仕方ない。

After

  • ONU (GE-PON<M>A GE-PON-ONU<1><2>)
    • 光ルータ (RT-200NE) のハブ
      • 光ルータ (RT-200NE) のWAN
        • ひかり電話 RJ-11
      • PPPoE ルータ + Wi-Fi (Aterm WR9500N)
        • LANコンセント

素直な構成としては光ルータに PPPoE 設定をして無線LANルーターはブリッジにすることだけど、設定画面が2つになるのが面倒だし、光ルーターが100Mbpsだし全体的にあんまり変えたくないので、単純に PPPoE ルータ+無線ルータを新しい無線ルータに変えた。ONU直下のハブだけ更新すれば IPv6 は 1Gbps 出せるような気がする。

備考

「GE-PON<M>A GE-PON-ONU<1><2>」は12年前に設置した ONU だが、名前 (Gigabit Ethernet-Passive Optical Network) の通り実はギガビットらしい。

100Mbps 契約なので 100BASE-T でしかリンクしないのだが、契約変更するとNTT側からの遠隔操作で 1000BASE-T でリンクアップするようになるらしい。おもしろデバイス……

MQTT のトピックを subscribe して一時的に保持し、prometheus 向けに exporter として働くデーモンを書いた。要は pushgateway の MQTT 版のようなもの。

うちではセンサーデータの一部を MQTT サーバに送りつけるようにしてあるので、それを面倒なことなしに prometheus に登録していきたい。

使いかたと挙動

mqtt_topic_exporter --mqtt.server=mqtts://user:pass@mqttserver:8883 --mqtt.topic="/home/sensor/+"

みたいに引数を指定する。mqtt.topic はそのまま subscribe に渡される。ワイルドカードも使える。

mqtt_topic_exporter は MQTT サーバに接続して値を待つ。値がきたらメッセージ内容を数値として扱い gauge のメトリクスとして登録する。

/metrics にアクセスすると以下のようにメトリクスが登録される。

mqtt_topic{topic="/home/sensor/temp"} 30.0

また、topic がしばらく受信できないと、該当メトリクスは一定時間で削除される。

./mqtt_topic_exporter --help
usage: mqtt_topic_exporter --mqtt.server=MQTT.SERVER --mqtt.topic=MQTT.TOPIC [<flags>]

Flags:
  -h, --help                     Show context-sensitive help (also try --help-long and --help-man).
      --web.listen-address=":9981"  
                                 Address on which to expose metrics and web interface.
      --web.telemetry-path="/metrics"  
                                 Path under which to expose metrics.
      --mqtt.retain-time="1m"    Retain duration for a topic
      --mqtt.server=MQTT.SERVER  MQTT Server address URI mqtts://user:pass@host:port
      --mqtt.topic=MQTT.TOPIC ...  
                                 Watch MQTT topic
      --log.level="info"         Only log messages with the given severity or above. Valid levels: [debug, info, warn, error, fatal]
      --log.format="logger:stderr"  
                                 Set the log target and format. Example: "logger:syslog?appname=bob&local=7" or "logger:stdout?json=true"
      --version                  Show application version.
  1. トップ
  2. tech
  3. MQTT のトピックを prometheus に登録する

クランプ式電流計は回路を切断せずに電流計測ができるので便利なのだけど、ホット側かコールド側いずれか一方だけをクランプする必要があるため、ほとんどの場合では実際には切断せずに計測というのは難しい。

ということで、写真のように短い延長ケーブルをつくった。線が分離しており、片方だけを挟める。前もって接続しておくことでいつでも計測できるようになる。100均で割けるタイプの延長コードがあればそれでいいけど、最近は二重絶縁のものが主流なのがかえって作りにくくなってしまった。

詳しい施行方法はパナソニックのサイトの「仕様」を見るとわかる。(備考:この延長ケーブルを作るのにあたっては特段なんの資格もいりません)


しかしまだ使えてない。特に冷蔵庫に使いたいんだけど、冷蔵庫の電源を落とすには若干の手順が必要なので面倒 (内容物の確認 → 電源オフ→ 7分間は再度電源入れないこと)

  1. トップ
  2. tech
  3. クランプ式電流計用にホットコールド分離ケーブルをつくる