俺様サーバー構築記 - Subversion による /etc のバージョン管理@デスクトップパソコン

「[俺様サーバー構築記 - 基本方針](https://qiita.com/katz_engineer/items/dbabcff4e14e9db2b10f)」以来構築を続けてきた俺様パソコン環境ですが、[Subversionをインストール](https://qiita.com/katz_engineer/items/b893316b4d1bb7731e87)し、[/etc をバージョン管理](https://qiita.com/katz_engineer/items/c9afdcb0e2355ed67ede)するように設定しました。これはクライアント側であるノートパソコンだったので、今回はサーバ側を設定します。

サーバ側と言っても基本的な手順はノートパソコンと同じですが、手順が若干簡単になります。

# 序

Subversion サーバはデスクトップマシンに立ててあります。
参考文献：[俺様サーバー構築記 - Subversionサーバーの構築@デスクトップパソコン](https://qiita.com/katz_engineer/items/b893316b4d1bb7731e87)

このデスクトップマシン上でも同様に svn+ssh でアクセスするようにします。ssh にする必要は全くありませんが、同じコマンドを使用できるようにしておいた方が便利です。中途半端に異なるコマンドだと、何かと引っかかりますので。
参考文献：[俺様サーバー構築記 - Subversion + Dropbear @ノートパソコン](https://qiita.com/katz_engineer/items/678badfbfa842ffc3c14)

```/etc``` バージョン管理の Subversion プロジェクト名は etcmgr です。

# 作業の流れ

0. Subversion リポジトリに etcmgr プロジェクトを作成 →[前回作成した](https://qiita.com/katz_engineer/items/c9afdcb0e2355ed67ede#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A)ので省略
0. デスクトップマシン server0 から etcmgr にアクセスするユーザとして root_server0 を用意
0. etcmgr プロジェクトのセキュリティを設定
0. server0 マシンの ```/etc``` のバージョン管理を開始
0. pacman フックを作成

# etcmgr

## root_server0 ユーザ

プロジェクト etcmgr にアクセスする Subversion ユーザ名は下記の通りとします。サーバマシンの root ユーザから下記ユーザ名で Subversion にアクセスする形になります。

<dl>
<dd>root_＜マシン名＞</dd>
</dl>

当然サーバにも（そしてクライアントにも）登録されていないユーザとなるので、以前調査した[サーバマシンに登録されていないユーザを Subversion アクセスできるように設定](https://qiita.com/katz_engineer/items/678badfbfa842ffc3c14#subversion%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%883-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%9E%E3%82%B7%E3%83%B3%E3%81%AB%E7%99%BB%E9%8C%B2%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%AE%E5%A0%B4%E5%90%88)する方法を利用します。

```console:サーバ側
# hostname
server0
# whoami
root
# cd
# mkdir .ssh
# cd .ssh
# dropbearkey -t ecdsa -s 256 -f id_dropbear_svn | tee >(tail -n+2 | head -n1 >authorized_keys_svn)
Generating 256 bit ecdsa key, this may take a while...
Public key portion is:
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGdj8jt4yY2wPFj/Ma8XNbWwZDjji7DE4XiA4wGZq9zXr+tJ6bKAM8mwciva9VU6BvRjTHe/PiZspMEg2kt1dtw= root@server0
Fingerprint: sha1!! c3:02:ac:ca:90:e9:fc:3b:2b:20:96:aa:d2:a8:4a:8b:95:6c:8f:90
```

これを Subversion の方に設定追加しますが、同じマシン上なので手順は簡略化されます。

```console:サーバ側
# source /etc/subversion/basic.conf
# SVN_USER=$(cat authorized_keys_svn | cut -d" " -f3 | tr @ _)
# cat >>$SVN_HOME/.ssh/authorized_keys <<___
> command="svnserve -tr $SVN_REPO --tunnel-user=$SVN_USER",no-port-forwarding,no-agent-forwarding,no-pty $(cat authorized_keys_svn)
> ___
```

ちなみに ```authorized_keys``` へ追加された行は下記のようになります。参考まで。

```console:サーバ側
# tail -n1 $SVN_HOME/.ssh/authorized_keys
command="svnserve -tr /srv/svn/repo --tunnel-user=root_server0",no-port-forwarding,no-agent-forwarding,no-pty ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGdj8jt4yY2wPFj/Ma8XNbWwZDjji7DE4XiA4wGZq9zXr+tJ6bKAM8mwciva9VU6BvRjTHe/PiZspMEg2kt1dtw= root@server0
```

## Subversion のセキュリティ

server0 マシンのディレクトリは root_server0 ユーザだけが読み書き出来るようにします。まぁ、気休めですね。```/etc``` ディレクトリは、読むだけなら誰でも読めますし。マシン外から読めないようにしておくのは正しいですが。

```console:サーバ側
# cat >>$SVN_REPO/etcmgr/conf/authz <<___
> [/server0]
> root_server0 = rw
> * = 
>    
> ___
```

## トンネルスキーム設定

```/root/.subversion``` を svn コマンドに作成させてから config ファイルを修正します。

```console:クライアント側
# svn --version >/dev/null
# sed -i -e"/\[tunnels\]/a ssh = dbclient -l svn -i $HOME/.ssh/id_dropbear_svn -p 60022" $HOME/.subversion/config
```

## ```/etc``` 管理開始

```console:サーバ側
# svn mkdir --parents svn+ssh://10.0.1.121/etcmgr/$(hostname)/etc -m "Prepare the target directory /etc"

Host '10.0.1.121' is not in the trusted hosts file.
(ecdsa-sha2-nistp256 fingerprint sha1!! c9:c0:6f:79:53:a6:17:b2:27:82:ee:a3:c9:a0:92:23:db:0d:fc:82)
Do you want to continue connecting? (y/n) y
Committing transaction...
Committed revision 6.
# svn co svn+ssh://10.0.1.121/etcmgr/$(hostname)/etc /etc
Checked out revision 6.
# svn add /etc/*
〈省略〉
A  (bin)  /etc/zfs/zfs-functions
A         /etc/zfs/vdev_id.conf.sas_direct.example
A         /etc/zfs/vdev_id.conf.scsi.example
# svn ci /etc -m "initial commit"
Adding         etc/zfs/zpool.d/vendor
Adding         etc/zfs/zpool.d/w_proc
Adding         etc/zfs/zpool.d/w_ucor
Transmitting file data ......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................done
Committing transaction...
Committed revision 7.
```

Subversion リポジトリのセキュリティ設定により、（別マシンの）異なるユーザ taro ではファイル一覧を見る事も出来ません。

```console:クライアント側
$ whoami
taro
$ hostname
client0
$ svn list svn+ssh://10.0.1.121/etcmgr | wc -l
0
$ svn list svn+ssh://10.0.1.121/etcmgr/server0
svn: E170001: Authorization failed
```

## pacman フック

pacman でパッケージを更新した時に、自動的に commit されるようにします。パッケージのインストールや削除の際には手動で ```svn commit``` しましょう。適切なコメントを残す必要もありますので。

自動 commit の為のシェルスクリプトをクライアントマシンに作成して ```/opt/etcmgr/bin``` に置きます。

（2019/10/01 修正ここから）

```console:クライアント側/opt/etcmgr/bin/autocommit.sh
#!/bin/bash

ETC_DIR="$1"
if [[ -z "$ETC_DIR" ]]; then
  echo "$(basename $0) <dirname>"
  exit 1
fi

exec &> >(tee >(systemd-cat -t etcmgr))

cd "$ETC_DIR"
SVN_STATUS=$(svn st)
if [[ -z "$SVN_STATUS" ]]; then exit; fi

echo "auto commit $ETC_DIR when done pacman command${2+: }$2"
echo "$SVN_STATUS" | grep "^?" | cut -b9- | xargs -I{} find {} -type f -or -type d -or -type l | xargs -r svn add
echo "$SVN_STATUS" | grep "^!" | cut -b9- | xargs -r svn rm
svn ci -m "auto commit when done pacman command${2+: }$2"
```
（2019/10/01 修正ここまで）

これ、 ```svn+ssh://10.0.1.121/etcmgr/autocommit.sh``` として Subversion に登録してしまった方が良いかも知れません…

そして ```/opt/etcmgr/bin/autocommit.sh``` が出来たら、pacman のフックを作成します。

参考文献：[2.2 フック - 2 設定 - pacman - ArchWiki](https://wiki.archlinux.jp/index.php/Pacman#.E3.83.95.E3.83.83.E3.82.AF)

（2019/10/01 修正と追加ここから）

```console:クライアント側/usr/share/libalpm/hooks/etcmgr-pre-install.hook 
# etcmgr pre-install hook

[Trigger]
# Operation = Install
Operation = Upgrade
# Operation = Remove
Type = File
Target = etc/*

[Action]
Description = etcmgr: pre-transaction commit
When = PreTransaction
Exec = /opt/etcmgr/bin/autocommit.sh /etc pre-transaction pre-transaction
AbortOnFail
```

```console:クライアント側/usr/share/libalpm/hooks/etcmgr-post-install.hook 
# etcmgr post-install hook

[Trigger]
# Operation = Install
Operation = Upgrade
# Operation = Remove
Type = File
Target = etc/*

[Action]
Description = etcmgr: post-transaction commit
When = PostTransaction
Exec = /opt/etcmgr/bin/autocommit.sh /etc post-transaction
```

（2019/10/01 修正と追加ここまで）

試してみます。

（2019/10/01 修正ここから）

```console:サーバ側
# zfs snapshot tank/main@$(date +%Y%m%d_%H%M%S)_before_upgrade
# zfs list -t snapshot -S name | head -n2
NAME                                        USED  AVAIL     REFER  MOUNTPOINT
tank/main@20190813_153514_before_upgrade      0B      -     2.77G  -
# pacman -Syu --noconfirm --noprogressbar
〈省略〉
:: Running pre-transaction hooks...
(1/2) Remove DKMS modules
==> dkms remove zfs/0.8.1 -k 5.2.11-arch1-1-ARCH
(2/2) etcmgr: pre-transaction commit
auto commit /etc when done pacman command: pre-transaction
A         systemd/network/enp0s25.network
A         systemd/network/enp2s1.network
D         systemd/network/all.network
Sending        .updated
Sending        ld.so.cache
Sending        mail.rc
Sending        pacman.d/gnupg/pubring.gpg
Sending        pacman.d/gnupg/tofu.db
Sending        pacman.d/gnupg/trustdb.gpg
Sending        pacman.d/mirrorlist.pacnew
Sending        services
Deleting       systemd/network/all.network
Adding         systemd/network/enp0s25.network
Adding         systemd/network/enp2s1.network
Transmitting file data ..........done
Committing transaction...
Committed revision 29.
〈省略〉
:: Running post-transaction hooks...
〈省略〉
(13/15) etcmgr: post-transaction commit
auto commit /etc when done pacman command: post-transaction
A         systemd/pstore.conf
Sending        X11/xinit/xinitrc.d/50-systemd-user.sh
Sending        ssl/misc/tsget.pl
Sending        systemd/networkd.conf
Adding         systemd/pstore.conf
Sending        systemd/system.conf
Sending        systemd/user.conf
Sending        zfs/zed.d/all-syslog.sh
Sending        zfs/zed.d/data-notify.sh
Sending        zfs/zed.d/pool_import-led.sh
Sending        zfs/zed.d/resilver_finish-notify.sh
Sending        zfs/zed.d/resilver_finish-start-scrub.sh
Sending        zfs/zed.d/scrub_finish-notify.sh
Sending        zfs/zed.d/statechange-led.sh
Sending        zfs/zed.d/statechange-notify.sh
Sending        zfs/zed.d/vdev_attach-led.sh
Sending        zfs/zed.d/vdev_clear-led.sh
Sending        zfs/zfs-functions
Sending        zfs/zpool.d/ata_err
Sending        zfs/zpool.d/cmd_to
Sending        zfs/zpool.d/defect
Sending        zfs/zpool.d/enc
Sending        zfs/zpool.d/encdev
Sending        zfs/zpool.d/fault_led
Sending        zfs/zpool.d/health
Sending        zfs/zpool.d/hours_on
Sending        zfs/zpool.d/iostat
Sending        zfs/zpool.d/iostat-10s
Sending        zfs/zpool.d/iostat-1s
Sending        zfs/zpool.d/label
Sending        zfs/zpool.d/locate_led
Sending        zfs/zpool.d/lsblk
Sending        zfs/zpool.d/media
Sending        zfs/zpool.d/model
Sending        zfs/zpool.d/nonmed
Sending        zfs/zpool.d/nvme_err
Sending        zfs/zpool.d/off_ucor
Sending        zfs/zpool.d/pend_sec
Sending        zfs/zpool.d/pwr_cyc
Sending        zfs/zpool.d/r_proc
Sending        zfs/zpool.d/r_ucor
Sending        zfs/zpool.d/realloc
Sending        zfs/zpool.d/rep_ucor
Sending        zfs/zpool.d/serial
Sending        zfs/zpool.d/ses
Sending        zfs/zpool.d/size
Sending        zfs/zpool.d/slaves
Sending        zfs/zpool.d/slot
Sending        zfs/zpool.d/smart
Sending        zfs/zpool.d/smart_test
Sending        zfs/zpool.d/smartx
Sending        zfs/zpool.d/temp
Sending        zfs/zpool.d/test_ended
Sending        zfs/zpool.d/test_progress
Sending        zfs/zpool.d/test_status
Sending        zfs/zpool.d/test_type
Sending        zfs/zpool.d/upath
Sending        zfs/zpool.d/vendor
Sending        zfs/zpool.d/w_proc
Sending        zfs/zpool.d/w_ucor
Transmitting file data ...........................................................done
Committing transaction...
Committed revision 30.
〈省略〉
# journalctl -at etcmgr
-- Reboot --
Oct 01 22:26:01 anju etcmgr[31305]: auto commit /etc when done pacman command: pre-transaction
Oct 01 22:26:01 anju etcmgr[31305]: A         systemd/network/enp0s25.network
Oct 01 22:26:01 anju etcmgr[31305]: A         systemd/network/enp2s1.network
Oct 01 22:26:01 anju etcmgr[31305]: D         systemd/network/all.network
Oct 01 22:26:01 anju etcmgr[31305]: Sending        .updated
Oct 01 22:26:01 anju etcmgr[31305]: Sending        ld.so.cache
Oct 01 22:26:01 anju etcmgr[31305]: Sending        mail.rc
Oct 01 22:26:01 anju etcmgr[31305]: Sending        pacman.d/gnupg/pubring.gpg
Oct 01 22:26:01 anju etcmgr[31305]: Sending        pacman.d/gnupg/tofu.db
Oct 01 22:26:01 anju etcmgr[31305]: Sending        pacman.d/gnupg/trustdb.gpg
Oct 01 22:26:01 anju etcmgr[31305]: Sending        pacman.d/mirrorlist.pacnew
Oct 01 22:26:01 anju etcmgr[31305]: Sending        services
Oct 01 22:26:01 anju etcmgr[31305]: Deleting       systemd/network/all.network
Oct 01 22:26:01 anju etcmgr[31305]: Adding         systemd/network/enp0s25.network
Oct 01 22:26:01 anju etcmgr[31305]: Adding         systemd/network/enp2s1.network
Oct 01 22:26:01 anju etcmgr[31305]: Transmitting file data ..........done
Oct 01 22:26:01 anju etcmgr[31305]: Committing transaction...
Oct 01 22:26:01 anju etcmgr[31305]: Committed revision 29.
Oct 01 22:36:00 anju etcmgr[105644]: auto commit /etc when done pacman command: post-transaction
Oct 01 22:36:00 anju etcmgr[105644]: A         systemd/pstore.conf
Oct 01 22:36:00 anju etcmgr[105644]: Sending        X11/xinit/xinitrc.d/50-systemd-user.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        ssl/misc/tsget.pl
Oct 01 22:36:00 anju etcmgr[105644]: Sending        systemd/networkd.conf
Oct 01 22:36:00 anju etcmgr[105644]: Adding         systemd/pstore.conf
Oct 01 22:36:00 anju etcmgr[105644]: Sending        systemd/system.conf
Oct 01 22:36:00 anju etcmgr[105644]: Sending        systemd/user.conf
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/all-syslog.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/data-notify.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/pool_import-led.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/resilver_finish-notify.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/resilver_finish-start-scrub.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/scrub_finish-notify.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/statechange-led.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/statechange-notify.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/vdev_attach-led.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zed.d/vdev_clear-led.sh
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zfs-functions
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/ata_err
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/cmd_to
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/defect
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/enc
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/encdev
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/fault_led
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/health
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/hours_on
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/iostat
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/iostat-10s
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/iostat-1s
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/label
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/locate_led
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/lsblk
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/media
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/model
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/nonmed
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/nvme_err
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/off_ucor
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/pend_sec
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/pwr_cyc
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/r_proc
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/r_ucor
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/realloc
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/rep_ucor
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/serial
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/ses
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/size
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/slaves
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/slot
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/smart
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/smart_test
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/smartx
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/temp
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/test_ended
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/test_progress
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/test_status
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/test_type
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/upath
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/vendor
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/w_proc
Oct 01 22:36:00 anju etcmgr[105644]: Sending        zfs/zpool.d/w_ucor
Oct 01 22:36:00 anju etcmgr[105644]: Transmitting file data ...........................................................done
Oct 01 22:36:00 anju etcmgr[105644]: Committing transaction...
Oct 01 22:36:00 anju etcmgr[105644]: Committed revision 30.
#  svn log -r 29:HEAD /etc
------------------------------------------------------------------------
r29 | root_anju | 2019-10-01 22:26:01 +0900 (Tue, 01 Oct 2019) | 1 line

auto commit when done pacman command: pre-transaction
------------------------------------------------------------------------
r30 | root_anju | 2019-10-01 22:36:00 +0900 (Tue, 01 Oct 2019) | 1 line

auto commit when done pacman command: post-transaction
------------------------------------------------------------------------
```

（2019/10/01 修正ここまで）

サーバ側は日本語を設定していないので ```LESSCHARSET=dos``` は不要でした。

# 結

Etckeeper 風の ```/etc``` の Subversion 管理、サーバでも出来ました。
やったね :thumbsup_tone2: