それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

市販ルータを諦めて x86_64 マシンliva zを Linuxルータにした。

市販ルータに限界を感じた。

PPPoEの再接続の再起動にいちいち、WEB-UI開くのが面倒だし。
ちょっとルーティングテーブルを管理するのでも面倒だし。
ルーターは電源つけっぱなしだけど、他の用途に使えないし。 SSH で管理できないし
VLANを割り振ってアレコレするのも不便だし。

dd-wrt や OpenWRTでファーム書き換えてもいいんだけど そうすると、電波法おじさんが出現する。技適技適!と言われるからでしょうか、ルーターファーム書き換えなどのノウハウはWEBに蓄積していかないので、ググっても微妙だし。

もう、諦めて、x86 で使えるルータOSを使うことにしました。

ubuntuルーターにするというのも考えたのだけれど、スマホから管理するが面倒なのでやめました。 みんなは金持ちなのでYAMAHAルーター買ってきたりCisco買うんだろうけど、、*1

x86_64 がアレば無敵だよね。

目次

ルーターに使えそうな、機器を調べた

ルーターに使うために検討した条件

  1. NICが複数個ある
  2. 小型サーバーのNUCで低消費電力
  3. AES-NIで暗号化処理にもたつかない
  4. トラブル防止のためにAmazonプライム購入できること
  5. 価格は2万くらい

条件を満たしたLivaZ

あれこれ探していたら、条件を満たしたものがあったのでずっとチェックしてた。価格は頻繁に変動するので注意。

f:id:takuya_1st:20200130020312p:plain:w200

存在は1年ほど前から知っていたのですが、Aliexpress類似商品を比較したり、Livaの進化型商品が販売されるかもしれないので、躊躇してた。またルーター構成するとなると一歩間違うと家族に大迷惑なので、アレコレと知識を得たり、試している間に、時間が経過してしまって1年ごしでようやく試せた。*2

Liva Z の 利点

これらはいいところ。

  • NICが2本刺さる
  • 4コアのCPU N4200
  • TDP 10W
  • OSなし版が選べる。
  • VESAマウンタがついてる

惜しいところ

届いたので開封

写真はあとで

オーディオ端子について

オーディオ端子はiPhoneと同じでマイクとスピーカのコンボの4極なので、デスクトップとして使うには優秀なんだろうけど。HDMIあるしね。Bluetoothあるしね。使うことはないんじゃないかなと。

BIOSの設定

消費電力を抑えるために、使う予定のない、オーディオ端子やWiFiやM.2 関連をバッサリとカット。

Ubuntu Serverで起動後アイドル時の消費電力は5Wを切っていたのでホント優秀。

Liva Z 設定

LivaZ の自動電源の設定。

パワーオフ後に電源復帰で起動してくれなくては困ります。

ルータの用に常時起動する機器は特に挿したら起動がいい。

停電しても起動を気にしたくない。停電後の電源復帰で自動起動してくれればいい。

停電は仕方ないものとしても、自動で起動してくれるとルーターとして使い勝手が格段に向上するよね。

AC復帰後の自動起動の設定が少しわかりにくかったのでメモ

EuP「無効」にしないと、停電解消後のパワーオンが選べなかった。有効にし電源さして起動にした。

f:id:takuya_1st:20200130022458p:plain f:id:takuya_1st:20200130022509p:plain

OSの構成

OpenWRT の x86/64 版を入れることにした。ただし、WiFiを使う予定は全くない。付属のIntel 3165 じゃ、5GhzのAPに出来ない。使い物にならない。*7

Ubuntu ServerをインストールしてKVM上に構築することにした。

KVMホストにOpenWrtをゲストとしてインストール。

NICを、macvtap で渡すことにした。

OpenWrtがうまく行かなかった場合などに、OPNSense / pfSense や x86Seil また Sophos など別のOSを試すと予想して、KVM上に構築することにした。

ホストOSの構成

ルーターOSを入れ替えて試したいので、仮想マシンで構成することにしました。

KVMのホストを作ります。

ホストには、Ubuntu Server 19.10 を採用しました。

ubuntu server ディスク構成

最小インストールでkvm を入れてあります。
またLivaZのN4200はルーターには余るくらいのCPUパワーとAES-NIなので、cyrptsetup でeMMC をフル暗号化にしてあります。

Ubuntu Serverのインストール後、KVMをセットアップしたあとのストレージ構成は次のとおりです。

takuya@livaz:~$ lsblk
NAME           MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
loop0            7:0    0 54.9M  1 loop  /snap/lxd/12631
loop1            7:1    0 89.1M  1 loop  /snap/core/8268
loop2            7:2    0 89.1M  1 loop  /snap/core/7917
loop3            7:3    0 64.5M  1 loop  /snap/lxd/13162
mmcblk0        179:0    0 29.2G  0 disk
├─mmcblk0p1    179:1    0  512M  0 part  /boot/efi
├─mmcblk0p2    179:2    0  732M  0 part  /boot
└─mmcblk0p3    179:3    0   28G  0 part
  └─dm_crypt-0 253:0    0 27.9G  0 crypt
    └─vg-lv    253:1    0 27.9G  0 lvm   /
mmcblk0boot0   179:8    0    4M  1 disk
mmcblk0boot1   179:16   0    4M  1 disk

UEFIブート構成

UEFIでブート構成してています。というか普通にインストールしたらUEFIだった。いまどきMBRもないだろうし。

Liva Z のオーナー様のブログやアマゾンのレビューを拝見していると、ブート(UEFI)でトラブった話がちらほら出てくるのですが、書いてるのオッサンばっかなのでEFIブートの慣れの問題じゃないかと思います。

LivaZのTPMバイスの活用

Liva Z N4200モデルのマザーボードにはTPMの項目があり、 /dev/tpm0 が認識されたので TPMでディスクの暗号化鍵を管理しようと思いましたが、うまくいきませんでした。 ストレージのパスワードは、平文で /bootに置くことにしました。

この辺は、ちゃんと調べればBitlocker同様に使えそうだった。そのうちなんとかしたいです。

インストール画面

スクショどっかいったので、探しておきます。

KVM のインストール

KVM のインストール は通常のUbuntu Serverと同じです。

sudo apt-get install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils

他には、いつもの通り、openssh-server vim-nox iperf などが入れてあります。

ゲストOSの構成

ルーターとして動かすOSを選びます。

候補としては次のとおりです

候補に関しては、Wikipedia:en のルーターOS一覧が詳しいです。

このあたりを仮想マシンで動かして試していきたい

ゲストの選定

OpenWRTにしました。

OpenWrtだとWebから管理できる。またGNUコマンド類が使える。とくにip(iproute2)コマンドが影響する。OPNsenseだとBSDなので、ネットワーク系コマンドは別系統で辛い。

  • スマホから設定や状態を見たいときにWEBは必須。
  • ネットワークコマンドがip

これらの観点から

OpenWrtのx86版をext4 のイメージを使いました。

ex4のイメージだと uci commitしなくてもデータが永続化するみたい。便利。

ゲストに作成時にVGAはオフにしました。

ルータ用OSであればディスプレイも必要ないでしょう。VGA分のメモリをゲストに割り振る必要もなくなるので、シリアルコンソールのみにしました。

ゲスト設定で注意したところ

設定をしていく上で、ハマったポイントは、主に IPv6絡みでした。

特に注意したところは、macvtap で ipv6の受け取り設定。NTTのHGWからのPDを受け取りたい

kvm のゲストに IPv6マルチキャストのrouter advertise を渡すには、trustGuestRxFilters='yes'が必要らしい。(とりあえずつけた

  <interface type='direct' trustGuestRxFilters='yes'>
    <mac address='52:54:00:af:28:bc'/>
    <source dev='enp3s0' mode='bridge'/>
    <model type='virtio'/>
    <link state='up'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
  </interface>

OpenWrtの設定

起動すると 192.168.1.1でWEB-UIのアドミン画面が起動する。
192.168.1.0/24 で DHCPが起動している。
macvtap で外に出しているので、作業用のラップトップから直接通信が届くので便利

設定は、主にWEBから行うが、sshでログインして行えるので楽でいい。

OpenWRTでシリアルコンソールのログインを必須したい

シリアルコンソールを見ていると root でログインした状態になっていて気持ち悪いのでログインを必須にする。

option ttylogin '1'を 突っ込むと ログインが必須に成りました。

root@OpenWrtVM:~# cat /etc/config/system 
config system
        option ttylogin '1'
        option log_size '64'
        option urandom_seed '0'
        option zonename 'Asia/Tokyo'
        option hostname 'OpenWrtVM'
        option log_proto 'udp'
        option conloglevel '8'
        option cronloglevel '5'
        option timezone 'JST-9'

config timeserver 'ntp'
        list server 'ntp.nict.jp'

ホスト名や、タイムゾーン、NTPサーバーなどもここでコピペで流し込んでおきました。

設定の編集のために いつものツールをいれる。

ssh 経由で編集するために vim / bash を入れておく。

opkg update
opkg install vim-full bash diffutils

設定を変数するときに差分を見たいが、vimdiff は提供されていない vimdiff の代わりに vim -d を使うのだが、diffコマンドを導入する必要があった。

chsh コマンドはないので、/etc/passwd を直接書き換えて シェルをbashにする

root@OpenWrtVM:~# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash

シェルをbashに変えれば vim で行番号表示やカラーなどフル機能が使えるようになる。

市販ルータのファーム入換たOpenWrtと違ってx86ならROM容量を気にせず、okpgをガンガン使えるのがいいところ。

OpenWrtの基本

  • 設定は指定されたフォルダにある。
  • 追加ソフトは opkg で
  • サービスの起動は /etc/init.d/のコマンド類を serviceコマンドで呼び出し。

設定について

設定は /etc/config/ のフォルダに集まっています。 設定を書き換えたら uci commit で反映されます。 また設定は yaml っぽい感じの json みたいなものになっています。

設定は直接ファイルを書き換えるのが楽です。

uci コマンドを使えば、ucijson のオブジェクトみたいに辿って設定を書き換えることも可能です。

uci コマンドの例。

## dhcp の設定から rebind_localhost を削除する場合
uci del dhcp.cfg01411c.rebind_localhost

ある程度パターンになってる設定はuci を使ってシェルスクリプトにしてしまえるので、自動化ができますね。 ちなみにWEBの画面は uci を使っているようです。

f:id:takuya_1st:20200130034549p:plain

このように設定の差分をuciで見られます。

wan6 に ipv6をpd でもらってくる

HGWのときは、次の設定が必要だった。日本のv6は早すぎたのでちょっとアレゲ。フレッツ壊れたIPv6*8の網内通信をするために、NTTのホームゲートウェイから、OpenWrtのWAN6インタフェースへ、ipv6を割り振ってもらおうとして苦労しています。

目標として、LAN内部にv6を流さずに、ルーター側だけがv6アドレスを持つようにします。

うちは、PPPoEなので、IPoEはまだ契約していないためです。v6アドレスを流してしまうとDNSフォールバックが発生してどうしてもインターネットが遅くなります。( AAAA レコードどおりに接続しようとして IPoE未契約だとタイムアウト待ちになる)。IPoE契約してもいいんだけど、、ルーター設定終わってから試すことにしました。

/etc/config/network

config interface 'wan6'
        option ipv6 '1'
        option proto 'dhcpv6'
        option ifname 'eth1'
        option reqaddress 'try'
        option reqprefix 'auto'
        option defaultroute '0'

wan6の設定は日本の壊れたIpv6にはうまく対応しないので、ndpなどをオフにしておきました

defaultroute をつけているとv6通信が始まるので、IPoE未契約の場合タイムアウトになります。面倒くさいだけなのでOffです。

/etc/config/dhcp

dhcpはこのようにしていました

config dhcp 'wan6'
        option interface 'wan6'
        option ra 'disabled'
        option ndp 'disabled'
        option dhcpv6 'disabled'
        option master '1'

/etc/config/firewall

config rule
        option target 'ACCEPT'
        option name 'to-cpu'
        option family 'ipv6'
        option proto 'all'
        option src 'NGN'
config zone
        option network 'wan6'
        option name 'NGN'
        option family 'ipv6'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'

バイスの input ( cpu ) 側だけにIPv6のrouter adを通してLANには通さないようにしました。

設定の反映

設定の反映は uci を使います。再起動は service コマンドが /etc/init.d を叩いてくれます。

uci commit network
uci commit dhcp
uci commit firewall
service restart network
service restart dhcp
service restart firewall

ext4 イメージならuci commit しなくてもいいみたいだけど、squashfsのときの癖で・・・

WAN6 に無事に HGWから IPv6 がPDとともに割り振られました。

f:id:takuya_1st:20200130034531p:plain

これで、フレッツの網内折返し通信ができますね。

その他入れたもの

OpenWrtに導入したパッケージです

ネットワーク関連

ip-full
tcpdump
bind-dig
iperf

ip コマンドが簡易版なので、ubuntu などと同じモノを入れました。
また、パケットを見たいのでtcpdumpを入れました。
また、dnsをdigしたいのでdigを導入しています。
また、速度測定のために iperfも入れています。

コマンド・ツール関連

ルーターでのssh作業を少しでも快適にするために、使いました。

vim-full
bash
findutils-locate
lscpu
lspci
lsblk
diffutils

ファイルシステム関連

最初はkvmじゃなくて直接インストールしたので、これを使いました。 KVMゲストだと要らないか。

e2fsprogs
partx-utils
mkf2fs

ルーター機能追加

unbound 
ddns
upnp
openvpn-openssl

DNSupnpなど、ルーターに欠かせないもの。トンネリング関連を入れておきました。

dnsmasq はあるのですが、1.1.1.1 や 8.8.8.8 にクエリを投げつけるのが好きではないので、unboundをいれて、dnsmasqが自分自身のunbound ( localhost#5353 )に訊きに行くようにしました。

unboundが roots.hintで DNSルートサーバーから調べてくれるはずです。

pppoe の設定

フレッツPPPoE特有の問題。

フレッツのPPPでは、mtu の値をfix してあげないと、通信が詰まる感じがあったり、TLS 1.3 のパケットをうまく捌けなくて遅くなる。

config zone 
  option name 'wan'
  option network 'myISP'
  option masq '1'
  option mtu_fix '1'
  option input 'REJECT'
  option output 'ACCEPT'
  option forward 'REJECT'
  option family 'ipv4'

Luci では次の箇所で mss clamping の設定をして、mtu の値をうまく扱ってあげると、パフォーマンスが段違いに良くなる。

f:id:takuya_1st:20200203042507p:plain
mss clamping

フレッツ網内折返しでipipを試してみた

ルーターからipv6で網内折返しができるようになり、ルーターLinuxなので ipコマンドが使える。

なので、網内折返しのついでにipipを使ってみたいと思います。ip4ip6で 簡易 ipip のフォワーディングです。網内の別拠点と通信を試してみました。

設定自体は手作業でもできるのですが。wan6が起動したと同時に自動接続したいのでスクリプト化しました。

/etc/hotplug.d/iface/スクリプトを設置すれば、ネットワーク構成が変更(ifup)される都度呼び出されます。スクリプト内部で、どのインタフェースが起動したのかを調べ、ipv6取得したときルーティングテーブルとipip でトンネリング作成後に経路を書換えます。NATはしません。トンネリング通信を試験的に設定します。

root@OpenWrtVM:/etc/config# cat /etc/hotplug.d/iface/99-ifup-ipv6
#!/bin/sh
## フレッツ ipv6 を接続する
## 2020-01-21
## require ip-full kmod-ip6-tunnel
## config netwotk で dhcpv6 設定

TARGET_INTERFACE=wan6
TARGET_DEVICE=eth1
#logger "ACTION=$ACTION"
#logger "INTERFACE=$INTERFACE"

function create_tun1 {

  ip -6 tunnel del tun2 
  ip -6 tunnel add tun2 mode ip4ip6 remote 2001:xxx0:xxxx:xxxx:e80:63ff:xxxx:c53b  local 2001:xxx3:xxxx:xxxx:5054:ff:xxxx:27bb
  ip link set tun2 up
  ip addr add 172.16.2.1/30 dev tun2
  ip route add 192.168.1.0/24 via 172.16.2.2 dev tun2
  iptables -I INPUT   -i tun2 -j ACCEPT
  iptables -I FORWARD -i tun2 -j ACCEPT
  iptables -I OUTPUT  -o tun2 -j ACCEPT
  iptables -I FORWARD -o tun2 -j ACCEPT



}
function add_ip6_default(){
  # add default すると、通信はできるけど、 opkg が動かなくなるので注意
  # ip6 のdefault route はオフにしてある。
  if ! ip -6 route  | grep 'default via ' > /dev/null ; then
   ip -6 route add default via fe80::225:36ff:xxxx:xxxx dev eth1
  fi
}
function add_ip6_route(){
  ip -6 route add 2001:xxxx:xxxx:3700::/64  via fe80::225:xxxx:fe75:xxxx  dev eth1 proto static metric 512 pref medium
}


## main

[ "$ACTION" = "ifup" -a "$INTERFACE" = "$TARGET_INTERFACE"  ] && {
    logger "iface ipv6 up detected..."
    add_ip6_route;
    create_tun1;
}
exit 0

このスクリプトを実行すると次のような経路が出来があります。

root@OpenWrtVM:# ip -6 route
2001:xxx0:38a8:xxxx::/64 via fe80::225:36ff:xxxx:xx42 dev eth1 proto static metric 512 pref medium

ipv4 もできました。

root@OpenWrtVM:# ip a
7: tun2@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1452 qdisc noqueue state UNKNOWN group default qlen 1000
    link/tunnel6 2001:xxx3:xxxx:a300:xxx:ff:feaf:xxbb peer 2001:xxx0:xxx:3700:e80:xxx:xxx:xx3b
    inet 172.16.2.1/30 scope global tun2
       valid_lft forever preferred_lft forever
    inet6 fe80::2ca8:e3ff:xxxx:xxba/64 scope link
       valid_lft forever preferred_lft forever

あとは、対向ルータも同様に設定して。疎通を確認しました。

KVM仮想マシンでOpenWrtを作っているので、もう1台仮想マシンを起動して仮想マシン間をIPv6で作れば、設定はかんたんに試せました。仮想マシンとmacvtap / bridge のおかげで、遠くのフレッツ利用者に協力を仰がなくても試せるのは素晴らしいですね。

ipipの通信は、通信がないと切断されてしまいます。試験的に設定したものです。永続化するものじゃないです。永続化のため定期的にpingを打つのは現実的じゃないので、設定ができたらopenvpnssh-tun などに切り替えたほうがいいと思います。

使ってみて

スループットは大幅に向上しました。

消費電力もそんなに気になりません。iperfで速度測定しまくってても8W程度でした。

ただ、Liva Z N4200 だと 内蔵スイッチがないのでルーターのようにswconfigが使えないのでタグVLANを管理してネットワークを上手に使うというのはできない感じでした。KVMホストに Open vSwitchを入れたりしないとだめかもね。

来月以降は OPNSense/pfSenseやIIJにSeilx86も試したいと思います。

LivaZおすすめ

OpenWrtを動かすだけなら正直言って4コアもいらんかった気がする。

その他のルーターに使えそうな製品

AmazonJPで色々売られています。 N3350 / N4200 あたりがお手頃でAES-NIがついてる感じですかね。

Celenron J1900とかはAES-NIを非搭載なのでVPNなどで苦労するかもしれません。

NICを複数搭載したマザーボードもありますが、ゲーミングPC用だったりで Core i5 9400とか用意しなくちゃいけない。常時起動にはあまりにオーバースペックすぎる。価格も性能も電気代も。

省電力CPUでソコソコの性能でソコソコの価格でNIC二本挿しが可能なのはLivaZくらいしかありませんでした。ルータにするために誕生したような製品ですね。

Lenovo が Think Centre tiny の Ryzen 2400Eを投げ売りしててそっちも買ったのですが、性能とコスパはよくて消費電力アイドル時で10wくらいでいいんだけど、NICが1本なのなんともなんとも。。。

スイッチングハブのない問題- VLAN対応安かった

x86 のPCをルータとして使う場合、ポートが足りない問題があります。

市販ルーターと違ってスイッチングハブがない問題が出てきます。

ギガビットハブなどは、1500円程度で購入可能です。

またタグVLANやポートVLANに対応したスイッチングハブは2500円で購入可能でした。

VLANが切れるので、フレッツ/56に直結させたり、HGWの/60に接続したり、配線を変更せずにパケットを捌けます。 ネットワーク構成をいじるときに大活躍しました。

WiFiない問題。

WiFiは面倒なのでやめましたが、Atherosのチップを搭載したpci-e ( ngff / m2 key e ) のカードを買えば動くかもしれないです。ただしath10kは市販ルーター用で、カードだけ市販されてないしWindowsでは動作しないっぽい。

そこで、APとして動く中継機だけを買うほうが楽だという結論に至りました。

ルーターよりも、このほうが接続すっきりするじゃん。

UTMも作れそう

セキュリティ関係のUTMに近いことも openwrt や opnsense を使って構成していけば作れそうですね。

そういうパッケージもルータOSに用意されてそう。そのうち試したいです。

今回試さなかった構成

PXE BOOT

ネットワーク越しの、ブート ルータなんだし、openwrtをpxeブートに変えたらさらに耐障害性も上がったと思う。そもそもそういうための軽量OSなんだし。仮想マシンではなく、ベアメタルにPXEでよかったかもしんない。

またkvmホスト側もpxeで良かったかもしれない

alpine linux

Dockerでお馴染みのディストリ。KVMホストをubuntu serverじゃなくalpineでよかったかもしれない。

LXD / lxc

kvmを持ち出さないで、dockerコンテナでk8sしてもよかったかもしれない。

DS-liteなどv6技術

IPoE未契約なので試せてない

感想・まとめ

ルーターが自由になると本当に楽しい。

x86のマシンを使っているのでOpenWRTの記事を堂々と書けるのも嬉しい。電波法の技適おじさん怖い

ip コマンドで ip route add したり サブネットを考えたり、NAT転送やforwading とファイアウォールの構成、あとipv6も楽しめる。

自由なソフトウェアとは本当に素晴らしいですね。

OpenWrtをゲスト稼働中のLivaZ の負荷(load)です。

CPUの消費電力が2Wとセンサーからレポートされています。インテルCPUの消費電力ってほんと優秀ですね。

f:id:takuya_1st:20200203183646p:plain

PPPoEの速度です。

いままで使ってた、TP-Linkの c7v5 に比べて100Mbps以上は圧倒的に速い。

f:id:takuya_1st:20200205050735p:plain

修正

一部の誤字脱字を直しました。

2020-02-03

フレッツのPPPoEのMTU設定の言及を加筆

*1: 自由なソフトウェアがいい。できればGNUがいい。

*2: ネットワーク初心者なので、IPAのネスペ取得からはじめました。大掛かり

*3: いまさら DDR3L の8Gx2=16GBを買うのはちょっと・・・

*4: 12v / 16v のAC電源でも動いたけどね。実際にはDC12-19Vなんじゃないかな。

*5: N4200はVt-d対応ってIntelは書いてあるけど、有効化する方法が見つからない

*6: 2.4GHz のAPしか作れない

*7: Linux Wireless を参考のこと https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi

*8: 壊れたv6 https://internet.watch.impress.co.jp/docs/news/534357.html