それマグで!

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

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

sed で出現文字をすべて置換する /g オプション

sedで1行の中に複数回出てくる文字を全部置換

sed で置換していると、普段は気にならないけど、複数回登場する場合に置換漏れが出てくる。

グローバルのマッチング・オプション /g がある。

s/cat/dog/g

時々忘れそうになる

設定ファイルを触っているときには、気にならないことが多いので忘れそうになる。

global マッチオプションの例

ファイルを作ります。

takuya@:~$ echo cat cat cat > sample
takuya@:~$ echo cat cat cat >> sample
takuya@:~$ echo cat cat cat >> sample
takuya@:~$ echo cat cat cat >> sample
takuya@:~$ echo cat cat cat >> sample

ファイルの中身を確認

takuya@:~$ cat sample
cat cat cat
cat cat cat
cat cat cat
cat cat cat
cat cat cat

グローバルオプションなしで置換します。

takuya@:~$ cat sample | sed 's/cat/lion/'
lion cat cat
lion cat cat
lion cat cat
lion cat cat
lion cat cat

グローバルのオプションを有効にしたら

takuya@:~$ cat sample | sed 's/cat/lion/g'
lion lion lion
lion lion lion
lion lion lion
lion lion lion
lion lion lion

置換漏れに注意

dockerfile などを書いている場合は sed をグローバルなしで使ってても本当に気にならない。1行に同じ文字が出てくることはあまりない。

ところがデータファイルを扱うととたんに顕著にミスとして顕れてくる。本当に怖い。

参考

man sed

mac用 のトラックパッドをUbuntuで使う設定

macトラックパッドUbuntuで使う設定 mac 用の MagickTrackpad をUbuntuに差し込んだら、普通に動く。

トラックパッドだけナチュラルスクロール

マウスのホイールスクロールと、トラックパッドのスクロールを同じ向きにすると どうしても違和感が生じます。

そこで、マウスとトラックパッドをそれぞれ別個にスクロールの向きを設定すると便利です。

Macではデフォルトでできないんだけど、Ubuntuなら、マウスとトラックパッドでスクロール方向を逆にできるんですよね。

これは、とくに設定しなくてもデフォルトでなってました。

トラックパッドの右下を右クリックに

マジックトラックパッドは、右下の右隅をクリックすると、右クリックになるのですが。 Ubuntuではデフォルトでは動きません

次の設定をすると動くようになります。

マウスクリックのエミュレーション

設定から、マウスクリックのエミュレーションを選ぶと、右下の隅っこをタップすると右クリックとして動作するようになります。

f:id:takuya_1st:20200203182931p:plain

OpenWrt x86 の リリースのバージョン更新する。

ext4のOpenWrtのバージョン更新。

OpenWrt x86ext4 をdist release upgrade してみた。先月にルーターとして稼働させたばかりだけど、マイナーバージョンのアップデートが来ていたので試した。

2020-01-30 に 19.07.1 がリリースされていたので、 インストールした OpenWrt x86をさっそくアップデートしてみた

やること

  • バックアップの作成
  • curlモジュールのインストール
  • boot のvmlinux の更新
  • カーネルのインストール
  • アップデートスクリプトの実行
  • パッケージ取得バージョンの更新

sysuprade コマンドでもできるようですが、今回は手作業でアップデートをしてみた。

root@MyOpenWRT:~# opkg install curl
Package curl (7.66.0-1) installed in root is up to date.

バックアップの作成

アップデートまえに現在の稼働中のOSをバックアップします。

いろいろな方法があるかと思います。わたしは、KVM+Qemu で動かしているので、virt-manager からディスクイメージをバックアップしました。

こういうとき仮想マシンって便利だね。

現在のインストールを最新版まで上げておきます。

現在インストールされているパッケージを最新版までアップデートしておきます。

root@MyOpenWRT:~# opkg update
root@MyOpenWRT:~# opkg list-upgradable
root@MyOpenWRT:~# opkg list-upgradable | cut -d ' ' -f 1 | xargs opkg upgrade

boot のvmlinuz更新

マウントされていることを確認

root@MyOpenWRT:~# mount  | grep boot
/dev/sda1 on /boot type ext4 (rw,noatime)
/dev/sda1 on /boot type ext4 (rw,noatime)

boot に移動

root@MyOpenWRT:~# cd /boot
root@MyOpenWRT:/boot# ls
grub     vmlinuz
root@MyOpenWRT:/boot# cp vmlinuz vmlinuz.bk

vmlinuz をアップデートするので消してもいいようにバックアップを取っておく。

ダウンロードして更新

root@MyOpenWRT:/boot# curl -LJO https://downloads.openwrt.org/releases/19.07.1/targets/x86/64/openwrt-19.07.1-x86-64-vmlinuz
root@MyOpenWRT:/boot# ls
grub                            vmlinuz
openwrt-19.07.1-x86-64-vmlinuz  vmlinuz.bk
root@MyOpenWRT:/boot# cp  openwrt-19.07.1-x86-64-vmlinuz vmlinuz

これで、vmlinuz は更新された、まだ再起動しません。

kernel image の更新

公式サイトから 、kernel_4.XXX_x86_64.ipk を取得して、インストールします。

root@MyOpenWRT:~# curl -LJO https://downloads.openwrt.org/releases/19.07.1/targets/x86/64/packages/kernel_4.14.167-1-e1dd7676581672f6f0bdb1363506dee1_x86_64.ipk
root@MyOpenWRT:~# ll
drwxr-xr-x    3 root     root          4096 Feb  3 17:45 ./
drwxr-xr-x   19 root     root          4096 Jan 21 03:06 ../
-rw-------    1 root     root         12968 Feb  3 16:11 .bash_history
drwx------    2 root     root          4096 Jan 21 03:17 .ssh/
-rw-------    1 root     root         15511 Feb  3 04:31 .viminfo
-rw-r--r--    1 root     root           798 Feb  3 17:45 kernel_4.14.167-1-e1dd7676581672f6f0bdb1363506dee1_x86_64.ipk

ダウンロードできたのでインストールします。

root@MyOpenWRT:~# opkg install kernel_4.14.167-1-e1dd7676581672f6f0bdb1363506dee1_x86_64.ipk
Upgrading kernel on root from 4.14.162-1-e1dd7676581672f6f0bdb1363506dee1 to 4.14.167-1-e1dd7676581672f6f0bdb1363506dee1...
Configuring kernel.

これで、カーネルインストールができました。

パッケージの更新

パッケージをバージョンに合わせて更新するのですが、まず、バージョンの数字を合わせていきます。

/etc/opkg/distfeeds.conf に、パッケージ取得元のURLが記載されています。

確認します。

root@MyOpenWRT:~# cat /etc/opkg/distfeeds.conf
src/gz openwrt_core http://downloads.openwrt.org/releases/19.07.0/targets/x86/64/packages
src/gz openwrt_base http://downloads.openwrt.org/releases/19.07.0/packages/x86_64/base
src/gz openwrt_luci http://downloads.openwrt.org/releases/19.07.0/packages/x86_64/luci
src/gz openwrt_packages http://downloads.openwrt.org/releases/19.07.0/packages/x86_64/packages
src/gz openwrt_routing http://downloads.openwrt.org/releases/19.07.0/packages/x86_64/routing
src/gz openwrt_telephony http://downloads.openwrt.org/releases/19.07.0/packages/x86_64/telephony

この数字を更新するのですが、sedで更新します。

sed -i はミスると致命的なので、先にcat で試しておきます。

## cat で sedのミスがないか確認
root@MyOpenWRT:~# cat /etc/opkg/distfeeds.conf  | sed  's/19.07.0/19.07.1/'
src/gz openwrt_core http://downloads.openwrt.org/releases/19.07.1/targets/x86/64/packages
src/gz openwrt_base http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/base
src/gz openwrt_luci http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/luci
src/gz openwrt_packages http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/packages
src/gz openwrt_routing http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/routing
src/gz openwrt_telephony http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/telephony

sed でただしく、書き換えられることががわかったので、このファイルをsed -i で直接更新(上書き)します。

root@MyOpenWRT:~# sed -i 's/19.07.0/19.07.1/'  /etc/opkg/distfeeds.conf

これで、パッケージ取得元を変更できました。

opkg の一覧を更新して、アップデートします。

root@MyOpenWRT:~# opkg update

実行例

root@MyOpenWRT:~# opkg update
Downloading http://downloads.openwrt.org/releases/19.07.1/targets/x86/64/packages/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_core
Downloading http://downloads.openwrt.org/releases/19.07.1/targets/x86/64/packages/Packages.sig
Signature check passed.
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/base/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_base
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/base/Packages.sig
Signature check passed.
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/luci/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_luci
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/luci/Packages.sig
Signature check passed.
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/packages/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_packages
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/packages/Packages.sig
Signature check passed.
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/routing/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_routing
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/routing/Packages.sig
Signature check passed.
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/telephony/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_telephony
Downloading http://downloads.openwrt.org/releases/19.07.1/packages/x86_64/telephony/Packages.sig
Signature check passed.

インストール中に/lib/functions.shが実行されないように実行権限を外します。 initスクリプトが何度も実行されないように。(らしい

root@MyOpenWRT:~# ll  /lib/functions.sh
-rwxr-xr-x    1 root     root          8104 Jan  7 01:47 /lib/functions.sh*
root@MyOpenWRT:~# chmod -x /lib/functions.sh
root@MyOpenWRT:~# opkg upgrade base-files
Upgrading base-files on root from 204.2-r10860-a3ffeb413b to 204.2-r10911-c155900f66...
...

最後にパッケージ全部アップデートしていきます。

root@MyOpenWRT:~# opkg list-upgradable | cut -d ' ' -f 1 | xargs opkg upgrade

これでアップデート出来ました。

再起動します。

root@MyOpenWRT:~# reboot

アップデートを確認します。

OSのgitのコミットのバージョン

root@MyOpenWRT:~# cat /etc/openwrt_version
r10911-c155900f66

カーネルのバージョン

root@MyOpenWRT:~# uname -a
Linux OpenWRT_livaZ_VM 4.14.167 #0 SMP Wed Jan 29 16:05:35 2020 x86_64 GNU/Linux

wrt関連の情報

root@MyOpenWRT:~# cat /etc/openwrt_release
DISTRIB_ID='OpenWrt'
DISTRIB_RELEASE='19.07.1'
DISTRIB_REVISION='r10911-c155900f66'
DISTRIB_TARGET='x86/64'
DISTRIB_ARCH='x86_64'
DISTRIB_DESCRIPTION='OpenWrt 19.07.1 r10911-c155900f66'
DISTRIB_TAINTS=''

Linux にある os-releaseの情報

root@MyOpenWRT:~# cat /etc/os-release
NAME="OpenWrt"
VERSION="19.07.1"
ID="openwrt"
ID_LIKE="lede openwrt"
PRETTY_NAME="OpenWrt 19.07.1"
VERSION_ID="19.07.1"
HOME_URL="https://openwrt.org/"
BUG_URL="https://bugs.openwrt.org/"
SUPPORT_URL="https://forum.openwrt.org/"
BUILD_ID="r10911-c155900f66"
OPENWRT_BOARD="x86/64"
OPENWRT_ARCH="x86_64"
OPENWRT_TAINTS=""
OPENWRT_DEVICE_MANUFACTURER="OpenWrt"
OPENWRT_DEVICE_MANUFACTURER_URL="https://openwrt.org/"
OPENWRT_DEVICE_PRODUCT="Generic"
OPENWRT_DEVICE_REVISION="v0"
OPENWRT_RELEASE="OpenWrt 19.07.1 r10911-c155900f66"

これで無事にバージョンが出来ました。

後片付け

kernel.ipkのパッケージを削除しておきます

root@MyOpenWRT:/etc# cd /
root@MyOpenWRT:~# rm kernel_4.14.167-1-e1dd7676581672f6f0bdb1363506dee1_x86_64.ipk

/boot に作ったバックアップを削除しておきます。

root@MyOpenWRT:~# cd /boot
root@MyOpenWRT:/boot# ls
grub                            openwrt-19.07.1-x86-64-vmlinuz  vmlinuz                         vmlinuz.bk
root@MyOpenWRT:/boot# rm vmlinuz.bk
root@MyOpenWRT:/boot# rm openwrt-19.07.1-x86-64-vmlinuz

パーミッションも直しておきました。

root@MyOpenWRT:~# chmod +x /lib/functions.sh

今回省略したこと

ハッシュ値のチェック。はやってません。

sysupgrade などのファームウェアの書き換えもやってません。ext4 に直接いれてるOpenWrt x86 なので

参考資料

Upgrading an OpenWrt 18.06.1 x86_64 ext4 image to 18.06.2 – 文卓的笔记

OpenWrt Project: Upgrading OpenWrt firmware via CLI

市販ルータを諦めて 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同様に使えそうだった。そのうちなんとかしたいです。

2020-12-30 更新 TPMを使ったLUKSの自動アンロックは完成した。 → TPMで起動時に自動アンロック

インストール画面

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

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として動く中継機だけを買うほうが楽だという結論に至りました。

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

無線LANどうするか

仮想マシンで起動していいる OPNSense や OpenWRT に無線LANのAPもやらせたい。その場合はUSBでデバイスをパススルーが一番いいと思う。

もしくは、仮想マシンをやめてLivaZにOpenWrtを素で入れれば、OpenWrt側で無線LANのドライバをうまいこと扱ってくれるでお試しするにはいいと思う。

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設定の言及を加筆

2020/12/30

TPMアンロックについて言及。

*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

kvm+qemuの仮想マシンのVMへ、シリアルコンソールで接続する。

仮想マシンVMへ、シリアルコンソールで接続する。

virt-managerVGAを使うより、コンソールで接続したい。と思いました。 サーバー版のLinux を使っていて思うんだけど、インストールしても利用しても、本当ににVGAって必要?

Ubuntu Server や openWRT x86をインストールした仮想マシンVGAによるディスプレイモニタが必要なんでしょうか。

昔からのシリアルコンソールでいいんじゃないんですかね。

やったこと

  • シリアルで接続できること確認。
  • VGAをdisabledにする。
  • シリアルコンソールにログを書き出したい。
  • シリアルコンソールにログインを出したい。

これらを実現させれば、仮想マシンマネージャーからも、virsh からもコンソールでテキストだけで解決するしスクロールバッファも取れるしコピペもしやすくなるよね。

仮想マシンマネージャーでの設定例

設定を変更して、シリアルのみにした

f:id:takuya_1st:20200130013333p:plain

ディスプレイをクリックしたらコンソールのみになる。嬉しい。

f:id:takuya_1st:20200130013338p:plain

スクリーンショットは、OpenWrt のx86_64 を起動したところです。

シリアルからのttyログインを有効にする。

Ubuntu server の場合、tty ログインを有効にするには、次のようにする。

sudo systemctl enable serial-getty@ttyS0.service
sudo systemctl start serial-getty@ttyS0.service

昔ながらのmingetty じゃないんですね。

Grubのブート画面もシリアルコンソールへ

GRUB のOS選択画面もシリアルコンソールに出力したいよね。

/etc/default/grub

grub の起動オプションを次のように追記して。

GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"

grub のメニューを更新する

sudo update-grub 

起動時のGRUBへのアクセスも許可するなら

GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200"

を追記する

コンソールをssh経由で呼び出す。

コンソールでログインできる環境を作っておくと、virsh でかんたんに管理ができる

virsh コマンドでコンソールに接続ができる。便利だわ

takuya@host:~$ virsh
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit

virsh # console OpenWrt
Connected to domain OpenWrt
Escape character is ^]

OpenWRT login:root

シリアルコンソールにして便利

VGAだと画面の拡大率やVGAに割り振るメモリや画像処理に余計なCPUパワーを取られるんだけど、シリアルコンソールならあんまり気にしなくていいね

Linuxの起動時のブートのログを見る

Linuxの起動時のログを見る

systemd が一般的になって、起動時のログを書くにする方法がsystemd経由になった。

journalctl /usr/lib/systemd/systemd -b 

ただし、systemd が起動してからのログなので systemd が起動する以前の initrd のログを見ることはできない

全部を見たいときは。

journalctl -b

また、ブートログはこちら

/var/log/boot.log  ---  System boot log
/var/log/dmesg     ---  print or control the kernel ring buffer

initrd が起動してから sytemd の init で起動し直すので、最近のLinuxのブートログはちょっとカオスかもしれませんね。

参考資料

How to see log to find a boot problem - Ask Ubuntu

ディスクのuuidを取得する方法3つ(使いやすいのは lsblk)

blkid よりも lsblk- f が便利かもしれない

lsblk のオプションに -f があります。

lsblk にオプションをつけると、UUIDが表示されます。

takuya@:~/Downloads$ lsblk -f 
NAME                    FSTYPE      LABEL UUID                                   FSAVAIL FSUSE% MOUNTPOINT
sda                                                                                             
├─sda1                  vfat              5601-CF5B                               498.7M     2% /boot/efi
├─sda2                  ext4              b051eadd-397c-42ea-b1c8-900bb4e6586e      456M    28% /boot
├─sda3                  crypto_LUKS       4df88652-a2db-4aa9-b28d-2ba850132340                  
│ └─sda3_crypt          LVM2_member       TeBacs-1QVa-Za6E-Ain7-9RgV-oU3e-iBatiW                
│   ├─ubuntu--vg-root   ext4              d2d6fb06-24ca-4f56-ae30-1e1b5cdc9df0     42.1G    55% /
│   └─ubuntu--vg-swap_1 swap              0f0fbd57-d05f-4ed6-985f-1a62e61720d5                  [SWAP]
└─sda4                  ext4        data  94eadf49-c020-47ee-b9cb-779af367cf58                  

ディスクの uuid を知りたいときに、 ls /dev/disk/by-id だとか叩いてもいいんだけど、lsblk のほうが圧倒的に見やすい

/dev/disk/by-uuid をls -l で

/dev/disk/by-uuidもいいんだけど、いいんだけどちょっとなぁ

takuya@:~/Downloads$ ls -l /dev/disk/by-uuid/
合計 0
lrwxrwxrwx 1 root root 10 2020-01-20 02:04 0f0fbd57-d05f-4ed6-985f-1a62e61720d5 -> ../../dm-2
lrwxrwxrwx 1 root root 10 2020-01-20 02:04 4df88652-a2db-4aa9-b28d-2ba850132340 -> ../../sda3
lrwxrwxrwx 1 root root 10 2020-01-20 02:04 5601-CF5B -> ../../sda1
lrwxrwxrwx 1 root root 10 2020-01-20 02:04 94eadf49-c020-47ee-b9cb-779af367cf58 -> ../../sda4
lrwxrwxrwx 1 root root 10 2020-01-20 02:04 b051eadd-397c-42ea-b1c8-900bb4e6586e -> ../../sda2
lrwxrwxrwx 1 root root 10 2020-01-20 02:04 d2d6fb06-24ca-4f56-ae30-1e1b5cdc9df0 -> ../../dm-1

blkid の場合

blkid でブロックデバイスの id を見てみると

blkid mでも十分見やすいんだけど、lvm on dm-crypt とかの階層構造がわかりにくい。

takuya@:~/Downloads$ blkid
/dev/mapper/sda3_crypt: UUID="TeBacs-1QVa-Za6E-Ain7-9RgV-oU3e-iBatiW" TYPE="LVM2_member"
/dev/mapper/ubuntu--vg-swap_1: UUID="0f0fbd57-d05f-4ed6-985f-1a62e61720d5" TYPE="swap"
/dev/mapper/ubuntu--vg-root: UUID="d2d6fb06-24ca-4f56-ae30-1e1b5cdc9df0" TYPE="ext4"

結論

ストレージのuuidを知りたいときは、lsblk -f が便利。

シェル(bash)の履歴を指定業だけど消す(間違えてパスワードを履歴に残した)

パスワードを打ち込んでエンターしてしてしまった。

パスワードなど、履歴を残したくない文字列を履歴に残してしまった場合。

たまに、やらかしますよね。複数ウインドウでフォーカスが違ってたとか。

takuya@:~$ 'MyP@$$word'
-bash: MyP@$$word: コマンドが見つかりません

ログアウトすると、パスワードが履歴に残ってしまいます。

takuya@:~$ history
 1844  history -d 1840
 1845  ll -al | grep hist
 1846  history 
 1847  'MyP@$$word'
 1848  history 

指定した行だけ消せます。

history -d 1847
history -w 

パスワードなど記録に残したくないコマンドの履歴を削除(?)して、historyファイル を更新しています。

その他の方法

history -r 
rm .bash_history
vim .bash_history

もちろん、 vim .bash_histrory をしてもいいのですが、vim を使ったことがバレてしまう!!

たいていは削除をしたがると思うのですが、履歴はその場でファイルに書き込まれているとは限りません。

history -r で保存するより先に、履歴をファイルから読み直すとかもありです。

履歴の考え方。

bash の設定にもよりますが、ヒストリは、環境変数と書き込みタイミングが設定次第で変えられます。

基本的にはログアウトした瞬間に書き込まれます。

shopt の histappend を設定していると、削除して保存は無く追記になります。

$HISTSIZE に指定した件数分が起動中にbash に保存されます。

$HISTFILESIZEに指定した件数分が ファイル保存されます。

$HISTFILE に指定したファイルに書き込まれます。

ファイルに書き込んだ履歴を呼び出すには history -r です。

この辺をうまく組み合わせると、保存せずにログアウトもできます。

保存先を /dev/null とかメモリにするとか。HISTSIZEをゼロにするとか。ですかね

ファイルを空っぽにするコマンド truncate

ファイルを空っぽにしたい

exim4 にパニックログが残ってると、エラー監視ログが上がってくるんですね。ログファイルを空にしたい。

exim paniclog /var/log/exim4/paniclog on acid has non-zero size, mail system might be broken. The last 10 lines are quoted below.

2019-11-21 22:53:06 socket bind() to port 25 for address 172.17.0.1 failed: Cannot assign requested address: daemon abandoned

truncate ファイルを空にするコマンド

truncate でファイルを空にする事ができます。

truncate -s 0 /var/log/file

空にする必要があるの?

あります。

ファイルの監視の問題とopenしている場合

削除であれば、ファイルをWatchしている各種サーバー類やファイルの移動をすると面倒くさいことがある。open していると取り合いにある。truncate は成功する可能性がある。

パーミッションの問題。

なにより rm して touch すると umask の設定によってはオーナやパーミッションが変わってしまうことがあります。面倒くさい。

ログファイルの空に

今回の exim4 のログファイルのように、「定期的にファイルを空にする」と解決する場合に活躍します。

ファイルを削除して作成してパーミッションを合わせるより、既存のファイルを空っぽにするほうがずっと楽だ。

truncate を crontab にサクッと書いて終わりです。

そもそもなぜexim4がlogrotate しないのかは謎だけど、調べるのも面倒くさい話です。

実例

takuya@:exim4$ cat  /var/log/exim4/paniclog
2019-11-21 22:53:06 socket bind() to port 25 for address 172.17.0.1 failed: Cannot assign requested address: daemon abandoned


takuya@:exim4$ sudo truncate  -s 0 /var/log/exim4/paniclog

takuya@:exim4$ cat  /var/log/exim4/paniclog

そもそもtruncate コマンドは?

ファイルを指定サイズに切り詰めます。

truncate のその他の使い方。指定サイズのファイルを作る。

一緒に覚えておくと便利です。

指定したサイズより、ファイルが小さいなら、指定サイズになるまで0埋めされる。

ファイルのサイズを指定したら0埋めしたダミーファイルをサクッと作れます。

たとえば1GBのファイルを作るのであれば truncate の 引数に 1GB を指定すれば良いわけです。

takuya@:~$ truncate -s $(( 1024*1024*1024 )) sample

takuya@:~$ ll sample
-rw-rw-r-- 1 takuya takuya 1.0G 2020-01-15 01:06 sample

参考資料

  • man truncate

dd のコピー進捗状況を表示する- progress verbose outout

dd コマンドで進行状況を確認したい

dd といえば、USRシグナルを送れば進捗状況が見えるのですが。

kill -USR1 $pid; sleep 1; kill $pid

これは起動中にddコマンドに対してpidへシグナルを送ることで表示されるのですが。説明するのは大変ですよね。

進捗をコマンド引数で指定する status=progress

status=progress をつけると、どれくらい進んでいるか閲覧が可能になって便利。

dd if=/dev/zero of=out.img bs=1024 count=$((1024*512)) status=progress

rsync みたいに転送状況を知りたいときはこれを使うと便利。

ddするときは、忘れずにつけておきたい。

実例

次のような感じに、コピーの書き込み速度や、何バイトをddできたかを見ることができます。

takuya@NO NAME$ dd if=/dev/zero of=out.img bs=1024 count=$((1024*512)) status=progress
260588544 bytes (261 MB, 249 MiB) copied, 9 s, 28.7 MB/s

進捗見るならdd rescue が

dd の変わりに dd_rescue を使うと良いのは周知の事実ですが。dd のほうがbs count の細かい数字が指定しやすくていいですよね。

進捗を見る方法まとめ

dd コマンドで状況を確認するには、次の方法があります。

  • kill USR1 シグナル
  • ddrescue
  • dd status=progress

活用事例/ dd を直接使う場合

ddrescue なら、進捗を見れるが、dd は見れない・・・ってときに便利です。

dd で直接指定バイトを取り出すとき、状況が見やすくとても便利です。

sudo dd if=/dev/sda bs=512 skip=2048 count=$(( 408373247-2048)) of=/dev/nvme0n1p4 status=progress

上記のコマンドなら次のように表示される。

takuya@ubuntu:~$ sudo dd if=/dev/sda bs=512 skip=2048 count=$(( 408373247-2048)) of=/dev/nvme0n1p4 status=progress
28953080320 bytes (29 GB, 27 GiB) copied, 265 s, 109 MB/s

残り時間や、進捗のパーセンテージは自分の計算こそ必要です。通常のdd違って、状況を表示するだけでも、速度とコピー済みの実績バイト数がわかるので計算が可能になり、安心感が違います。

2022-05-08

加筆修正。verbose がキーワードになかったので、本文に追加

mac のdd / ddrescue が遅すぎる大問題に対処する。

mac で ddするとめっちゃ遅い

本当に遅い。

信じられないくらいに遅い。2MB/s程度しか出ない。32GBのraspi のSDカードをコピーに一晩中掛かってしまった。辟易した。調べたら mac はもともと遅いらしい・

rdisk を使う

mac の /dev/diskX は遅すぎるので、raw モードで読み書きすると早くなる

/dev/disk → /dev/rdisk 

raw で読み書きすると本当に早くなる。2M/s → 30M/s になり、ちゃんとマイクロSDの速度になった。

例。次のようになります。

rdisk と disk で違いがあるのがわかると思います。

sudo ddrescue raspbian-2020-01-13.img /dev/disk3s2
sudo ddrescue raspbian-2020-01-13.img /dev/rdisk3s2

これ、知らないと本当にハマるよね。

速度の違い

/dev/disk は 1.7MB/s で /dev/rdisk へは 38MB/s である。桁違いとはこのことだ。

takuya@Downloads$ sudo ddrescue raspbian-2020-01-13.img /dev/disk3s2 --input-position=$(( 512*94208 )) --size=16G --force 2020-01-13.dd.mapfile
GNU ddrescue 1.24
Press Ctrl-C to interrupt
     ipos:    4024 MB, non-trimmed:        0 B,  current rate:    917 kB/s
     opos:    4024 MB, non-scraped:        0 B,  average rate:   1766 kB/s
non-tried:   12023 MB,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:    3976 MB,   bad areas:        0,        run time:     37m 30s
pct rescued:   24.85%, read errors:        0,  remaining time:      1h 53m
                              time since last successful read:         n/a
Copying non-tried blocks... Pass 1 (forwards)^C
takuya@Downloads$ sudo ddrescue raspbian-2020-01-13.img /dev/rdisk2s2 --input-position=$(( 512*94208 )) --size=16G --force 2020-01-13.dd.mapfile
GNU ddrescue 1.24
Press Ctrl-C to interrupt
Initial status (read from mapfile)
(sizes limited to domain 48234496 B to 16048234496 B of 32010928128 B)
rescued: 3976 MB, tried: 0 B, bad-sector: 0 B, bad areas: 0

Current status
     ipos:    5962 MB, non-trimmed:        0 B,  current rate:  32636 kB/s
     opos:    5962 MB, non-scraped:        0 B,  average rate:  37271 kB/s
non-tried:   10085 MB,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:    5914 MB,   bad areas:        0,        run time:         52s
pct rescued:   36.96%, read errors:        0,  remaining time:          4m
                              time since last successful read:          0s

てか、raw モード以外で読み書きすると、なんでこんなに遅いのmacOSは・・・

mac で ddするときは rdisk

mac でdd するときは、rdisk を使ってraw モードで読み書きしよう。

mac のブロックデバイスへのアクセスは遅すぎる。たぶんFSEVENTとかnotify 系に通知しまくるんだろう。mac のdocker が遅いのとも、似たような理由なのかもしれない。

/dev/disk と /dev/rdisk の違いはランダムアクセスとシーケンシャルアクセスの考え方の違いで、バッファを経由して他のプロセスと共有するかどうかってことらしい。

https://www.junk-works.science/disk-and-rdisk/

参考

ddrescue は レジューム機能がある 。途中で再起動しても大丈夫

ddrescue コマンドを実行中に再起動しちゃった。

macOS で dd / ddrescue するとすごく時間がかかるので、バックグラウンドで流してて、1日近く経過してた、ddrescue 実行中を忘れて再起動してしまいました。悲しい

レジューム機能がある。

悲しいので、こういう悲劇が二度と見たくない。未然に防止する方法を調べたら、ddrescue には「転送再開」のレジューム機能があります。やったね。

takuya@Downloads$ ddrescue -h  | grep map
5:Always use a mapfile unless you know you won't need it. Without a
6:mapfile, ddrescue can't resume a rescue, only reinitiate it.
7:NOTE: In versions of ddrescue prior to 1.20 the mapfile was called

使い方:ログファイル(mapファイル)の指定

ddrescue には第3の引数があります。あるんです。

ddrescue $IN  $OUT  $MAP

mapファイルを使う

次のように第3の引数を指定して実行する。

ddrescue /dev/input out.img 2020-01-10.dd.map

そのあと CTRL-C や 再起動/kill などでプロセスを中止する。

ddrescue /dev/input out.img 2020-01-10.dd.map
^C

再開するのは、同じ「ファイル名」を第3の引数にいれて 起動する

ddrescue /dev/input out.img 2020-01-10.dd.map

map ファイルがあれば再開するようだ。

ddrescuelog というコマンドもある。

ddrescue で作成したmap フィアルの状況を表示することができる。これも便利。

結論:レジューム機能を使うには

ddrescue 自体に3番めのファイルとしてログファイルを指定する。

参考

  • man ddrescue
  • man ddrescuelog

mac で ext4 など Linuxファイルシステムパーティションを扱うGNUコマンド

macOSext4 をチェックしたい。

LinuxデスクトップにいちいちUSBをつなぎ直すのが面倒くさいので、普段使いのmacOSext4 を操作してチェック(verify)修正をしたいなと思った。

e2fsprogs のGNUコマンドはbrewでインストールできます。

brew install e2fsprogs 

e2fsprogs をインストールすると、次のようにLinuxでよく使うであろうファイルシステムを扱うコマンドが入ります。

PATHは通さないほうが良い

PATHを通すと面倒くさい(ゴチャゴチャになる)可能性があるので、PATHは通さないほうが良い。

brew もインストール後は 特にlink しないので、リンクはしないほうがトラブル防止になるんだろうね。

とくに mkfs.関係とか。もともとmacにあるコマンドと名前の似ているコマンドはトラブルの素だ。

コマンドの場所

homebrew でいれたe2fsprogs は次の場所にインストールされる。

/usr/local/opt/e2fsprogs/sbin/

インストールされるコマンド

takuya@Downloads$ ll /usr/local/opt/e2fsprogs/sbin/
total 6.6M
-r-xr-xr-x 1 takuya staff 184K 2019-10-25 16:33 badblocks
-r-xr-xr-x 1 takuya staff  49K 2019-10-25 16:33 blkid
-r-xr-xr-x 1 takuya staff 401K 2019-10-25 16:33 debugfs
-r-xr-xr-x 1 takuya staff 234K 2019-10-25 16:33 dumpe2fs
-r-xr-xr-x 1 takuya staff 178K 2019-10-25 16:33 e2freefrag
-r-xr-xr-x 1 takuya staff 502K 2019-10-25 16:33 e2fsck
-r-xr-xr-x 1 takuya staff 235K 2019-10-25 16:33 e2image
-r-xr-xr-x 1 takuya staff 317K 2019-10-25 16:33 e2label
-r-xr-xr-x 1 takuya staff 234K 2019-10-25 16:33 e2mmpstatus
-r-xr-xr-x 1 takuya staff 192K 2019-10-25 16:33 e2undo
-r-xr-xr-x 1 takuya staff 8.4K 2018-12-16 14:39 filefrag
-r-xr-xr-x 1 takuya staff 317K 2019-10-25 16:33 findfs
-r-xr-xr-x 1 takuya staff  58K 2019-10-25 16:33 fsck
-r-xr-xr-x 1 takuya staff 502K 2019-10-25 16:33 fsck.ext2
-r-xr-xr-x 1 takuya staff 502K 2019-10-25 16:33 fsck.ext3
-r-xr-xr-x 1 takuya staff 502K 2019-10-25 16:33 fsck.ext4
-r-xr-xr-x 1 takuya staff 254K 2019-10-25 16:33 fuse2fs
-r-xr-xr-x 1 takuya staff  14K 2018-12-16 14:39 logsave
-r-xr-xr-x 1 takuya staff 333K 2019-10-25 16:33 mke2fs
-r-xr-xr-x 1 takuya staff 333K 2019-10-25 16:33 mkfs.ext2
-r-xr-xr-x 1 takuya staff 333K 2019-10-25 16:33 mkfs.ext3
-r-xr-xr-x 1 takuya staff 333K 2019-10-25 16:33 mkfs.ext4
-r-xr-xr-x 1 takuya staff  14K 2019-10-25 16:33 mklost+found
-r-xr-xr-x 1 takuya staff 229K 2019-10-25 16:33 resize2fs
-r-xr-xr-x 1 takuya staff 317K 2019-10-25 16:33 tune2fs
-r-xr-xr-x 1 takuya staff  26K 2019-10-25 16:33 uuidd

resize2fs / fsck.ext4 とか便利

ext4パーティションをりサイズで拡張・縮小させたり、 e2fsck もちゃんと使える。

blkid

blkid でuuid を閲覧することもできるが、 /dev/ に対応しないので、引数にちゃんといれる必要がある。

linux 同等のgdisk をしたいときは

brew install gptfdisk

まとめ:mac でもext4

maclinux のフォーマットを扱うには brew install e2fsprogs 。インストール先を直接叩いて使う。

mac でもraspi のSDカードのメンテナンスが簡単にできることがわかりとても安心です。

関連資料

マウントしたいとき、パーティションを触りたいときは。こっちを参考に。

参考

mac で linuxと同等のgdisk コマンドを使うには

mac でgdisk したい

mac にもfdisk があり gpt コマンドで GPT のボリュームも扱えるのですが。「覚えるのが面倒くさい」

brewgnuの gdisk コマンドをインストール

linuxのgdisk コマンドと同じなら使い方も同じなので、覚えることが少ない。

brew install gptfdisk

インストールされるコマンド

gptfdisk をインストールすると、おなじみの sgdisk gdisk のGNUコマンドがmacOSでも使えるようになる。

takuya@~$ ll /usr/local/Cellar/gptfdisk/1.0.4/bin/
total 652K
-r-xr-xr-x 1 takuya staff 200K 2018-07-06 05:19 cgdisk
-r-xr-xr-x 1 takuya staff  64K 2018-07-06 05:19 fixparts
-r-xr-xr-x 1 takuya staff 195K 2018-07-06 05:19 gdisk
-r-xr-xr-x 1 takuya staff 190K 2019-03-11 22:02 sgdisk
takuya@~$

いつものコマンドでリスク回避

ディスクのパーティションを触るときは、王手が掛かってるシビアなときが多いので、普段使いの慣れたコマンドで操作できるのは大変いいことだと思う。

phpで改行が反映されない件(終了タグと改行コードの関係)

php で改行コードが反映されないことがあります。

LFでもCRLFでも関係なく、文字コードも関係ありません。php では終了タグで「改行」すると、出力には改行が反映されません。

<?php 

$title = 'コーチングのプロが教える 「ほめる」技術';
$author = '鈴木 義幸';
?>

著者:<?= $title?>
書題:<?= $author?>

実行結果

$ php sample.php

著者:コーチングのプロが教える 「ほめる」技術書題:鈴木 義幸

不思議ですね。

次のように、単位が入るとさらに表示が想像がつかなくなります。

<?php 

$title = 'コーチングのプロが教える 「ほめる」技術';
$author = '鈴木 義幸';
$price = 1047;
?>
著者:<?= $title?>
価格:<?= $price;?>円
書題:<?= $author?>

これを実行すると次のようになります。

$ php sample.php
著者:コーチングのプロが教える 「ほめる」技術価格:1047円
書題:鈴木 義幸

”円”にだけ改行が反映されています。何故なんでしょうか。改行は無視されるときとされない時があるんです。

改行は反映されません。

php では、<?php ?> で囲まれたエリアはそのまま、コードとして解釈されます。と一般的に習うんでしょうけど、例外があります。

終了タグは、「改行」を含んで終了と解釈されます。?> ⏎?> と同じなのです。

改行コードは2つ続いても、一つになる。

一つだけだと

abc<?php
?>

実行後は

abc

になります。

なので、改行を反映したいときは、空行を入れるか、空白を入れます。

abc<?php
?> ⏎
⏎

これが実行されると

abc⏎

になります。

対策

こうします。空白を入れます。

<?php echo $name; ?>␣⏎

便利なときもある。

php のファイルから php をrequire したときに、改行コードをいい感じにしてくれるので便利なこともある。

テンプレートのフォーマットでは空白か空行を多めにいれる。

そういう仕様なのです。如何ともし難い。仕方ないのです。php で改行がでなくてもHTMLは改行を無視するのであまり気になっていないという現実があります。

これが、phpCSVバッチ処理やメール送信など、プレーンテキストを扱うと途端に問題になります。とくにCSVとメールでしょうか。

php の仕様

仕様なのです。phpは4→5, 5→6とかなり後方互換を切り捨ててきたので、そろそろこの辺もバッサリ切ってほしいと思ったりするのですが。

テンプレートとしてphpを実行したときに改行コードを意識する必要があるのは若干不便ではないでしょうか。

実験に使用したphp

今回は、このphp でサンプルコードを書いて実行しています。

PHP 7.3.11 (cli) (built: Oct 24 2019 11:29:42) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.11, Copyright (c) 1998-2018 Zend Technologies
    with Xdebug v2.7.2, Copyright (c) 2002-2019, by Derick Rethans

参考資料