NanoPi NEOでNTPサーバ再構築 (全まとめ)

NanoPi NEOでNTPサーバ

2年半ほど前に作ったNanoPi NEOのNTPサーバだが、ストレージの使用状況の値が取れなくなったのでsshでログインしたところ、ファイルシステムが見えなくなっていた。メモリ上に展開済みのサービスだけが動いていて使用できる状態。ファイル操作に関するものはlsすら通らなくて全部I/Oエラー。システムを再起動することも出来ずに電源ブッチして、その後もう一度電源を入れたが2度と起動しなかった(そりゃそうだ)。
NanoPi NEOのストレージはmicroSDカードなので、それを抜いてPCに挿してみたが、カードを認識するもののパーティションもファイルも見えず、こちらもエラー。強制的にゼロフィルしてみたけど、I/Oエラー頻発でもうmicroSDカードとして正常に使えないみたい。
で、このmicroSDカードを作ったときにカードが壊れることを前提に、カードのコピーを作って予備に置いておいたのだが、こちらもPCに挿しても中身が読めず、NanoPi NEOに挿してもやはり使えず。
最近のmicroSDカードは多くがTLCなのでデータの保持期間が短くなっていて2年〜4年で保存されたデータが信頼できなくなる(消える)とは聞いていたけど、本当なのね。
最近はQLCなんてのも登場しているみたいだけど、低容量のカードには採用されてないだろうし、そもそもよく知らないけど怖いなぁ。

ということで、予備も使えないということで、一から作り直すことに。これに懲りて、今後は完成したmicroSDをイメージファイルにしてハードディスクに保管しよう、そうしよう。

さて、2年半ほど前は当時の最新版のArmbianのDebian jessieで作ったが、今はその次のDebian stretchも過ぎて最新版がDebian busterになっている。
ブログ用にDebian jessieのイメージファイルarmbian_5.27_Nanopineo_Debian_jessie_dev_4.10.3-gatolabo.7zを上げてたけど、さすがに古いのでArmbianのDebian busterを最新ソースでビルドすることにした。

カーネルオプションはDebian jessieのときと同じくTimer周りを変更した。(前回の記事参照) なお、Device DriverのPPS SupportのPPS client using GPIOは標準が選択状態だったので触っていない。また、サウンド周りは今回は未変更。

NanoPi NEO用Armbian5.93 Debian buster 4.19.65  Timer変更版 (NanoPi NEO2用ではない)
Armbian_5.93_Nanopineo_Debian_buster_next_4.19.65.7z

NanoPi NEO用Armbian5.94 Debian buster 4.19.68  Timer変更・サウンド無し版
Armbian_5.94_Nanopineo_Debian_buster_next_4.19.68.7z

イメージファイルをmicroSDカードに焼いて、NanoPi NEOに挿すのだが、最近のArmbianでNanoPi NEO/NEO2用は初期値が何故かネットワークを利用できない状態になっている。NanoPi NEOに挿す前にPCに挿してマウントし、その設定を触る。Linuxなどではファイルの書き換えに管理者権限が要る筈なので注意。
同じArmbianでもOrange Pi用はネットワークケーブルを挿すだけで(DHCPなら)自動的にネットワークに繋がるんだけどNanoPiは違うのは何でかしら?

一応、正規のやり方は以下らしい。
焼き終わったmicroSDカードをPCに挿してマウントしたところまでやったとする。
そのmicroSDの中の/boot/armbian_first_run.txt.template をリネームしてarmbian_first_run.txt にする。
そのarmbian_first_run.txtを編集する。何か幾つか存在する設定行の FR_hogehoge='値' を自分のネットワーク環境に合わせて変更する。
これは有線・無線(USBのWi-Fiアダプタ使用時)のどちらもらしい。
で、設定の書き換えが終わったら比較的上の方にあるFR_general_delete_this_file_after_completion=1 という行を削除してからファイルを上書き保存する。で安全な方法でPCからアンマウントしてからNanoPi NEOに挿して最初の電源投入を行ってrootでログインしてarmbian-configでいろいろ設定。
と、いうことらしい。

しかし、面倒なのでそんなのは無視。
以下

/etc/network/interfaces (編集)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
auto lo  #この2行は最初からある筈
iface lo inet loopback

auto eth0
allow-hotplug eth0
#no-auto-down eth0

iface eth0 inet static    #IPv4で固定IPの設定
address 192.168.0.124   #IPv4のIPアドレス
netmask 255.255.255.0  #IPv4のサブネットマスク
gateway 192.168.0.1     #IPv4のデフォルトゲートウェイ
dns-nameservers 8.8.8.8  8.8.8.4  #IPv4用のネームサーバ

iface eth0 inet6 static   #IPv6で固定IPの設定
address 2001:xxxx:xxxx:xxxx::xxxx  #IPv6のIPアドレス
netmask 64    #IPv6プレフィックス長
gateway 2001:xxxx:xxxx:xxxx::yyyy  #IPv6のデフォルトゲートウェイ
dns-nameservers 2001:4860:4860::8888  2001:4860:4860::8844 #IPv6用のネームサーバ

#もし、DHCPなら
auto eth0
iface eth0 inet dhcp

ファイルを書き込んだら正しい手順でアンマウントしてからNanoPi NEOに挿して電源オン。
SSHでログイン。アカウントはrootでパスワードの初期値は1234。初ログイン時はすぐにパスワード変更を求められるので、先に1234を入力してから、次に新しいパスワードを入力する。そのまま新しい通常ユーザー登録に進む。

DHCPを使わない場合は/etc/resolv.confで名前解決の設定も。でないと、少なくともNTPで外部の時刻ソースをホスト名指定したときに困る筈。

CPUクロックの調整

$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
120000 240000 480000 648000 816000 960000 1008000 1056000 1104000 1152000 1200000 1224000 1248000 1296000 1344000 1368000

NanoPi NEOは以前は最高クロックが1008000だった筈だが、1368000まで使えるようになっている?
しかし、そんなクロックは要らないので648000〜1008000辺りで調整。その際に稼働中に周波数が可変にならないよう最低値と最大値を同じにする。実際はガバナーをperformanceにすれば指定した最大クロックしか使われない筈。

/etc/default/cpufrequtils (修正)
1
2
3
4
ENABLE=true
MIN_SPEED=1008000
MAX_SPEED=1008000
GOVERNOR=performance

ガバナーをperformanceにしているのでMIN_SPEEDは0でも何でも良い気がするが、一応MAXと合わせた。

システム再起動する

設定の反映状態を確認。
$ cpufreq-info -p
1008000 1008000 performance
クロックの固定・可変状態の確認
$ cpufreq-info -s
120000:1, 240000:0, 480000:3, 648000:0, 816000:12, 960000:23, 1008000:130755, 1056000:2, 1104000:0, 1152000:0, 1200000:0, 1224000:0, 1248000:0, 1296000:0, 1344000:0, 1368000:798  (58)

1008000:xxxのxxxが大きくて、他のクロックのxxxが0または小さな値であること。
さらに暫くシステムを再起動しない状態の後にもう一度コマンドを実行して1008000:xxxのxxx値だけが増加すること。他のクロックのxxxが増えなければOK.

PPSを使えるようにする

/boot/armbianEnv.txt (編集)
1
2
3
4
5
6
7
8
9
verbosity=1
logo=disabled
console=tty0
overlay_prefix=sun8i-h3
overlays=uart1 pps-gpio
param_pps_pin=PG9
rootdev=UUID=7c95fe25-eeb0-4d04-a3e5-fde8a5771a1f
rootfstype=ext4
usbstoragequirks=0x2537:0x1066:u,0x2537:0x1068:u

基本的には変更するのはoverlays=の行で、他にparam_pps_pin=の行を追加する。
PPSのピンはGP9を指定しているが、これがNanoPi NEOのどのピンかは過去記事参照。
特に気を付けたいのはoverlays=行で、全部書き換え。

システムを再起動してdmesgを確認。

$ dmesg | grep pps
[    1.360813] pps_core: LinuxPPS API ver. 1 registered
[    1.360821] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    9.321577] pps pps0: new PPS source pps@0.-1
[    9.321737] pps pps0: Registered IRQ 96 as PPS source
こんな感じで表示されること。
/devにpps0が出現していればOK.というか、/dev/pps0が出来ていなければ失敗。

NTPのビルド・インストール

システムに最初から入っているntp関係のファイルを削除してビルドしたntp関係のファイルに置き換える。特に難しいところはないので、さくっと実行するだけ。

Armbianの新しいバージョンではntpdではなくChronyが標準のNTPサーバとして入っている。atp install ntpでntpdのパッケージをインストール。armbian用に提供されているパッケージがPPS対応でビルド済みになったので以下にあるようなビルド手順は不要になった。

$ sudo  apt install libcap-dev
$ sudo service ntp stop
$ sudo /lib/systemd/systemd-sysv-install disable ntp
$ sudo apt remove ntp
$ cd ~
$ wget http://archive.ntp.org/ntp4/ntp-4.2.8p13.tar.gz
$ tar zxvf ntp-4.2.8p13.tar.gz
$ cd ntp-4.2.8p13
$ ./configure CFLAGS="-O2 -g -fPIC" --enable-linuxcaps --enable-ATOM --enable-NMEA --enable-ipv6 --prefix=/usr --bindir=/usr/sbin --sysconfdir=/etc
$ make -j4
$ sudo make install
$ sudo mkdir /var/lib/ntp
$ sudo touch /var/lib/ntp/ntp.drift
$ sudo chown -R ntp:ntp /var/lib/ntp
$ sudo rm /etc/systemd/system/ntp.service    #←このファイルの古いのが残っていると困るので忘れずに

ntpは普通のサービスではないのでsystemctl disable HOGEのようなサービス無効化方法ではない。(3行目)
2年前は/usr/local/下にインストールしてシンボリックリンクにしていたが、元ファイルと同じく/usr/binや/usr/sbinなどに置くようconfigureで--prefix=/usrを指定するようにした。
2019年8月中旬現在、ntp4の最新版は4.2.8p13になっている。

/lib/systemd/system/ntp.service (作成)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[Unit]
Description=Network Time Service
Documentation=man:ntpd(8)
After=network.target
Conflicts=systemd-timesyncd.service

[Service]
Type=forking
# Debian uses a shell wrapper to process /etc/default/ntp
# and select DHCP-provided NTP servers if available
ExecStart=/usr/sbin/ntpd
PrivateTmp=true

[Install]
WantedBy=multi-user.target

このファイルはntpパッケージを削除する前の/lib/systemd/systemd/ntp.serviceを退避しておいてそのまま戻すというのはダメ。ExecStart行が元のままでは使えない。
12行目のPrivateTmpは下手に指定しない方が無難かも。(12行目は無しで良い) 上の例のようにしているとntpの各種stats情報を取得しようとして指定ディレクトリにファイルが出力されないと悩むことになるかも。

ここまでやったらntpをサービスとして有効化する。ntpd起動はまだ。

$ sudo ln -s /lib/systemd/system/ntp.service /etc/systemd/system/multi-user.target.wants/ntp.service
$ sudo /lib/systemd/systemd-sysv-install enable ntp

ntp無効化時と同じく、普通のサービスのようにsystemctl enable HOGEで有効化ではない。(2行目)

NTPの設定

ntpdが使用するデバイスを読み込み可にするが、普通のコマンド打ちではシステム再起動後に戻ってしまうので、パーミッションを自動設定するように設定ファイルを書く。

/etc/udev/rules.d/10-gps.rules (新規作成)
1
2
KERNEL=="ttyS1",SYMLINK+="gps0",MODE="0666"
KERNEL=="pps0",MODE="0666"

システム起動後のコマンドを追加する。

/etc/rc.local (exit 0の直前に挿入)
1
2
3
4
/bin/systemctl stop ntp.service
/bin/stty -F /dev/ttyS1 9600
/usr/sbin/ntpdate 162.159.200.1     #CloudFlare NTP Server
/bin/systemctl start ntp.service

ここではserviceコマンドは使わずsystemctlにした。(serviceではサービス起動に失敗したので)
ntpdateが無い場合はapt install ntpdateで入れる。
ntpdate -u xxx.xxx.xxx.xxxの様に-uオプションを使うならNTPサーバ稼働中でも実行できるがここで実行。

/etc/ntp.conf (全面編集)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
driftfile /var/lib/ntp/ntp.drift
leapfile /usr/share/zoneinfo/leap-seconds.list

#statsdir /tmp/
#statistics loopstats peerstats clockstats
#filegen loopstats file loopstats type day enable
#filegen peerstats file peerstats type day enable
#filegen clockstats file clockstats type day enable

#cloudflare
server time.cloudflare.com prefer #162.159.200.1, 162.159.200.123, 2606:4700:f1::1, 2606:4700:f1::123
server ntp1.jst.mfeed.ad.jp #210.173.160.27

#mfeed
#server ntp2.jst.mfeed.ad.jp #210.173.160.57 prefer
#server ntp3.jst.mfeed.ad.jp #210.173.160.87
#server ntp1.v6.mfeed.ad.jp #2001:3a0:0:2001::27:123
#server ntp2.v6.mfeed.ad.jp #2001:3a0:0:2005::57:123
#server ntp3.v6.mfeed.ad.jp #2001:3a0:0:2006::87:123

restrict -4 default ignore
restrict -6 default ignore
restrict -4 127.0.0.1
restrict -6 ::1

#My Network(LAN)
restrict 192.168.0.0 mask 255.255.255.0 nomodify notrap
restrict 2001:xxxx:xxxx:xxxx:: mask ffff:ffff:ffff:ffff:: nomodify notrap

#cloudflare
restrict -4 162.159.200.1 mask 255.255.255.255 nomodify notrap noquery
restrict -4 162.159.200.123 mask 255.255.255.255 nomodify notrap noquery
restrict -6 2606:4700:f1::1 nomodify notrap noquery
restrict -6 2606:4700:f1::123 nomodify notrap noquery

#mfeed
restrict -4 210.173.160.27 mask 255.255.255.255 nomodify notrap noquery
restrict -4 210.173.160.57 mask 255.255.255.255 nomodify notrap noquery
restrict -4 210.173.160.87 mask 255.255.255.255 nomodify notrap noquery
restrict -6 2001:3a0:0:2001::27:123 nomodify notrap noquery
restrict -6 2001:3a0:0:2005::57:123 nomodify notrap noquery
restrict -6 2001:3a0:0:2006::87:123 nomodify notrap noquery

#NMEA
server 127.127.20.0 mode 17 minpoll 4 prefer
fudge  127.127.20.0 time2 0.175 refid NMEA

#PPS
server 127.127.22.0 minpoll 4 true
fudge  127.127.22.0 flag3 1 refid PPS

2年前は外部の時刻ソースは全てMFEEDにしたが、今回は今年の5月くらいだっけに話題になったCloudfalreの公開NTPサーバを参照する。今後はこれをホスト名指定してラウンドロビンで使うのが良いかなと。あと、念の為にMFEEDの1台。
今回はpreferはCloudflareのNTPサーバに付けている。

DHCPの場合はNTPが勝手に制御されて/etc/ntp.confが使われないようなので、次のファイル内のrequest行の最後の部分を消す(黄字の部分)。

/etc/dhcp/dhclient.conf (変更)
request subnet-mask, broadcast-address, time-offset, routers,
	domain-name, domain-name-servers, domain-search, host-name,
	dhcp6.name-servers, dhcp6.domain-search, dhcp6.fqdn, dhcp6.sntp-servers,
	netbios-name-servers, netbios-scope, interface-mtu,
	rfc3442-classless-static-routes, ntp-servers;
一番最後のセミコロンを間違って消さないこと。

システムを再起動する。
または、他は全て準備出来ていて、NTPサービスだけ起動するなら

$ sudo service ntp start

システムまたはNTPサービス起動後、暫く待ってから確認。特にPPSは5分程度待つ。

$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*GPS_NMEA(0)     .NMEA.           0 l    4   16  377    0.000   -1.176   5.355
oPPS(0)          .PPS.            0 l    3   16  377    0.000    0.001   0.002
+2606:4700:f1::1 10.22.8.215      3 u   33   64  377   12.631   -7.143   0.153
+ntp1.jst.mfeed. 133.243.236.17   2 u   57   64  377   11.800    1.048   0.204

上はntpd起動後18時間くらい経っている。外部時刻ソースとの差を要調整かも。

おまけ、不要なサービスの停止

サービスの確認
$ sudo systemctl list-unit-files

リストが表示されるので不要なサービス名をメモる。

サービスの停止と無効化 (それぞれ2行セットで)
$ sudo systemctl stop dbus-fi.w1.wpa_supplicant1.service
$ sudo systemctl disable dbus-fi.w1.wpa_supplicant1.service
$ sudo systemctl stop dbus-org.freedesktop.nm-dispatcher.service
$ sudo systemctl disable dbus-org.freedesktop.nm-dispatcher.service
$ sudo systemctl stop network-manager.service
$ sudo systemctl disable network-manager.service
$ sudo systemctl stop NetworkManager-dispatcher.service
$ sudo systemctl disable NetworkManager-dispatcher.service
$ sudo systemctl stop NetworkManager-wait-online.service
$ sudo systemctl disable NetworkManager-wait-online.service
$ sudo systemctl stop NetworkManager.service
$ sudo systemctl disable NetworkManager.service
$ sudo systemctl stop wpa_supplicant.service
$ sudo systemctl disable wpa_supplicant.service
$ sudo systemctl stop apt-daily-upgrade.timer
$ sudo systemctl disable apt-daily-upgrade.timer
$ sudo systemctl stop apt-daily.timer
$ sudo systemctl disable apt-daily.timer
$ sudo systemctl stop man-db.timer
$ sudo systemctl disable man-db.timer

必要・不要なサービスは人によって、環境によって異なると思うので自己判断で。

関連記事: