0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-08-05

俺様サーバー構築記 - 基本方針」以来構築を続けてきた俺様パソコン環境ですが、サーバマシンにSubversionをインストールし、クライアントマシンにも svn+ssh でアクセスできるように設定しました。

これらを基盤として、/etc をバージョン管理します。こういう事は Etckeeper が定番のようで、ArchLinux にも Etckeeper のパッケージがあります。但しこれは Git などの今時の分散バージョン管理ツールだけが対象でした。Subversion は対象外。残念です。

分散バージョン管理は個人的に不勉強ですので、これからの勉強を改めて誓うとして、今回は Subversion を利用したバージョン管理を独自に工夫します。

Subversion サーバはデスクトップマシンに立ててあります。
参考文献:俺様サーバー構築記 - Subversionサーバーの構築@デスクトップパソコン

ノートパソコンからは svn+ssh でアクセスできるように準備しています。但し、今回は root ユーザからアクセスするようにするので、後程その設定を追加します。
参考文献:俺様サーバー構築記 - Subversion + Dropbear @ノートパソコン

/etc バージョン管理については EtcManager という名前のプロジェクトにします。短縮名は etcmgr とし、Subversion プロジェクト等はこの短縮名で用意します。

作業の流れ

  1. Subversion リポジトリに etcmgr プロジェクトを作成
  2. client0 マシンから etcmgr にアクセスするユーザとして root_client0 を用意
  3. etcmgr プロジェクトのセキュリティを設定
  4. client0 マシンの /etc のバージョン管理を開始
  5. pacman フックを作成

etcmgr

プロジェクトの初期設定

Subversion リポジトリに etcmgr プロジェクトを作成します。
これは最初に1度だけ実施し、以降は各マシン毎のサブフォルダを作成していきます。

サーバ側
# /srv/svn/createprj.sh etcmgr
Edit svnserve.conf and authz in the directory /srv/svn/repo/etcmgr/conf as needed.
The file passwd is in the directory /srv/svn/conf, edit it as needed, too.

他のプロジェクトと違い、セキュリティ設定を厳しくします。基本的には各マシンの root ユーザからアクセスしますが、それ以外のユーザはアクセスを禁止します。読み出しも禁止。

その為の下準備として、 /srv/svn/repo/etcmgr/conf 以下の設定ファイルを操作します。不要なコメントも全部削除しておきます。

サーバ側
# cd /srv/svn/repo/etcmgr/conf
# sed -i -e "s:^\(authz-db[[:space:]]*=\).*$:\1 $(pwd)/authz:" -e "s:^\(password-db[[:space:]]*=\).*$:# \1:" svnserve.conf 
# cat >authz <<___
> [aliases]
> 
> [groups]
> 
> [/]
> * = rw
> 
> ___
# rm passwd

結果として、各ファイルの内容は下記の通りとなります。

サーバ側
# cat svnserve.conf 
[general]
anon-access = none
auth-access = write
# password-db =
authz-db = /srv/svn/repo/etcmgr/conf/authz
realm = Project etcmgr
# cat authz 
[aliases]

[groups]

[/]
* = rw

# cat passwd
cat: passwd: No such file or directory

root_client0 ユーザ

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

root_<マシン名>

当然サーバにも(そしてクライアントにも)登録されていないユーザとなるので、以前調査したサーバマシンに登録されていないユーザを Subversion アクセスできるように設定する方法を利用します。

なお、下記で、 taro はサーバ側に Dropbear アクセスできる一般ユーザであり、サーバの IP アドレスは 10.0.1.121 です。

クライアント側
# 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 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBB13AN+v0oUvaeS23hsP4Ak8nzn8GVqMk+3SEPed1bzd2YRAKKNbOGRtVtuCcQnkILI5WWqMTzB03JRUomhZxVY= root@client0
Fingerprint: sha1!! 8c:3f:25:d6:d0:89:28:3a:74:d6:a6:6c:ee:9e:e5:0b:5b:0c:99:d6
# su taro
$ cat authorized_keys_svn | dbclient -p 60022 10.0.1.121 "mkdir /tmp/root_key; cat >/tmp/root_key/authorized_keys_svn"
$ exit
exit
サーバ側
# cd /tmp/root_key
# 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)
> ___
# cd
# rm -r /tmp/root_key

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

サーバ側
# tail -n1 $SVN_HOME/.ssh/authorized_keys
command="svnserve -tr /srv/svn/repo --tunnel-user=root_client0",no-port-forwarding,no-agent-forwarding,no-pty ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBB13AN+v0oUvaeS23hsP4Ak8nzn8GVqMk+3SEPed1bzd2YRAKKNbOGRtVtuCcQnkILI5WWqMTzB03JRUomhZxVY= root@client0

Subversion のセキュリティ

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

サーバ側
# cat >>$SVN_REPO/etcmgr/conf/authz <<___
> [/client0]
> root_client0 = rw
> * = 
>    
> ___

トンネルスキーム設定

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

クライアント側
# 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 管理開始

(2019/08/24 修正ここから)
.pwd.lock.updated は、バージョン管理は不要です。どうも更新時に設定されるロックファイル等で、特に後者は ArchLinux に特有のファイルっぽい。という訳で無視設定にします。

参考文献1: Re: What is /etc/.pwd.lock for ? - debian-user Jul 2005 by thread
参考文献2: karol 2014-07-31 00:12:19 - [SOLVED] /etc/.updated? - System Administration - ArchLinux Forums

が、普通に svn propset svn:ignore すると .updated はエラーになります。理由がよくわかりません。そのため一捻りした結果が下記になります。

クライアント側
# 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...
リビジョン 1 をコミットしました。
# svn co svn+ssh://10.0.1.121/etcmgr/$(hostname)/etc /etc
リビジョン 1 をチェックアウトしました。
# svn propset svn:ignore -F - /etc <<___
> .pwd.lock
> .updated
> ___
属性 'svn:ignore' を '/etc' に設定しました
# svn add /etc/*
〈省略〉
A         /etc/zfs/zpool.d/iostat
A         /etc/zfs/zpool.d/test_progress
A         /etc/zfs/zpool.d/enc
# svn ci /etc -m "initial commit"
〈省略〉
追加しています              etc/zfs/zpool.d/vendor
追加しています              etc/zfs/zpool.d/w_proc
追加しています              etc/zfs/zpool.d/w_ucor
ファイルのデータを送信しています ..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................done
Committing transaction...
リビジョン 2 をコミットしました。

(2019/08/24 修正ここまで)

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

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

pacman フック

pacman を使った時に、自動的に commit されるようにします。ただ、これは良し悪しだと考えています。pacman -Syu の時など自動的に commit してくれるのは助かりますが、新しいパッケージをインストールした時に自動 commit されると、メッセージに覚書を残せなくなります。そこの所を良く検討して判断して下さい。その辺の制御は、下記の etcmgr-pre-install.hook における [Trigger] Operation の設定である程度は制御できると思います。

(2019/08/10 追加ここから)
[Trigger] Operation = Update だけにすれば良いようです。
(2019/08/10 追加ここまで)

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

(2019/09/22 修正ここから)
GnuPG によるパッケージの暗号化がどうとかで、 /etc/pacman.d/gnupg ディレクトリに UNIX ソケットが生成される事があるようです。 Subversion はこれを処理できないのでエラーが発生します。

svn: E200007: パス '/etc/pacman.d/gnupg/S.gpg-agent' のノード種別はサポートされていません
svn: E200007: Unsupported node kind for path '/etc/pacman.d/gnupg/S.gpg-agent'

これを避ける為に、管理対象ファイル追加の処理においてフィルタを設定します。

クライアント側/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/09/22 修正ここまで)

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

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

参考文献:2.2 フック - 2 設定 - pacman - ArchWiki

(2019/09/27 修正ここから)
Operation = InstallOperation = Remove はコメントアウトして、Upgrade の際だけ自動 commit されるようにします。
パッケージのインストールや削除の際には手動で svn commit しましょう。適切なコメントを残す必要もありますので。

更に、pacman は事前と事後にフックを設定できるようです。念の為に両方用意した方が良いでしょう。

クライアント側/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
AbortOnFail
クライアント側/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

試してみます。

クライアント側
# pacman -Syu --noconfirm --noprogressbar
〈省略〉
:: トランザクション前のフックを実行...
(1/2) Remove DKMS modules
==> dkms remove zfs/0.8.1 -k 5.2.9-arch1-1-ARCH
(2/2) etcmgr: pre-transaction commit
auto commit /etc when done pacman command: pre-transaction
送信しています              .updated
ファイルのデータを送信しています .done
Committing transaction...
リビジョン 27 をコミットしました。
〈省略〉
:: トランザクション後のフックを実行...
〈省略〉
(13/24) etcmgr: post-transaction commit
auto commit /etc when done pacman command: post-transaction
A         fonts/conf.avail/05-reset-dirs-sample.conf
A         fonts/conf.avail/09-autohint-if-no-hinting.conf
A         fonts/conf.avail/35-lang-normalize.conf
A         systemd/pstore.conf
D         dbus-1/system.d/org.freedesktop.UPower.conf
送信しています              X11/xinit/xinitrc.d/50-systemd-user.sh
削除しています              dbus-1/system.d/org.freedesktop.UPower.conf
追加しています              fonts/conf.avail/05-reset-dirs-sample.conf
追加しています              fonts/conf.avail/09-autohint-if-no-hinting.conf
追加しています              fonts/conf.avail/35-lang-normalize.conf
送信しています              fonts/conf.avail/40-nonlatin.conf
送信しています              fonts/conf.avail/45-generic.conf
送信しています              fonts/conf.avail/45-latin.conf
送信しています              fonts/conf.avail/60-generic.conf
送信しています              fonts/conf.avail/60-latin.conf
送信しています              fonts/conf.avail/65-nonlatin.conf
送信しています              fonts/fonts.conf
送信しています              fonts/fonts.dtd
送信しています              ld.so.cache
送信しています              mail.rc
送信しています              pacman.d/gnupg/pubring.gpg
送信しています              pacman.d/gnupg/tofu.db
送信しています              pacman.d/gnupg/trustdb.gpg
送信しています              profile.d/vte.sh
送信しています              services
送信しています              ssl/misc/tsget.pl
送信しています              systemd/networkd.conf
追加しています              systemd/pstore.conf
送信しています              systemd/system.conf
送信しています              systemd/user.conf
ファイルのデータを送信しています ........................done
Committing transaction...
リビジョン 28 をコミットしました。
〈省略〉
# export LESSCHARSET=dos
# journalctl -at etcmgr
〈省略〉
 9月 25 21:34:44 honoka etcmgr[14200]: auto commit /etc when done pacman command: pre-transaction
 9月 25 21:34:44 honoka etcmgr[14200]: 送信しています              .updated
 9月 25 21:34:44 honoka etcmgr[14200]: ファイルのデータを送信しています .done
 9月 25 21:34:44 honoka etcmgr[14200]: Committing transaction...
 9月 25 21:34:44 honoka etcmgr[14200]: リビジョン 27 をコミットしました。
 9月 25 22:21:46 honoka etcmgr[113921]: auto commit /etc when done pacman command: post-transaction
 9月 25 22:21:47 honoka etcmgr[113921]: A         fonts/conf.avail/05-reset-dirs-sample.conf
 9月 25 22:21:47 honoka etcmgr[113921]: A         fonts/conf.avail/09-autohint-if-no-hinting.conf
 9月 25 22:21:47 honoka etcmgr[113921]: A         fonts/conf.avail/35-lang-normalize.conf
 9月 25 22:21:47 honoka etcmgr[113921]: A         systemd/pstore.conf
 9月 25 22:21:47 honoka etcmgr[113921]: D         dbus-1/system.d/org.freedesktop.UPower.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              X11/xinit/xinitrc.d/50-systemd-user.sh
 9月 25 22:21:48 honoka etcmgr[113921]: 削除しています              dbus-1/system.d/org.freedesktop.UPower.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 追加しています              fonts/conf.avail/05-reset-dirs-sample.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 追加しています              fonts/conf.avail/09-autohint-if-no-hinting.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 追加しています              fonts/conf.avail/35-lang-normalize.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              fonts/conf.avail/40-nonlatin.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              fonts/conf.avail/45-generic.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              fonts/conf.avail/45-latin.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              fonts/conf.avail/60-generic.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              fonts/conf.avail/60-latin.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              fonts/conf.avail/65-nonlatin.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              fonts/fonts.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              fonts/fonts.dtd
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              ld.so.cache
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              mail.rc
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              pacman.d/gnupg/pubring.gpg
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              pacman.d/gnupg/tofu.db
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              pacman.d/gnupg/trustdb.gpg
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              profile.d/vte.sh
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              services
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              ssl/misc/tsget.pl
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              systemd/networkd.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 追加しています              systemd/pstore.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              systemd/system.conf
 9月 25 22:21:48 honoka etcmgr[113921]: 送信しています              systemd/user.conf
 9月 25 22:21:49 honoka etcmgr[113921]: ファイルのデータを送信しています ........................done
 9月 25 22:21:49 honoka etcmgr[113921]: Committing transaction...
 9月 25 22:21:49 honoka etcmgr[113921]: リビジョン 28 をコミットしました。
# svn log -r 27:HEAD /etc
------------------------------------------------------------------------
r27 | root_honoka | 2019-09-25 21:28:55 +0900 (2019年09月25日 (水)) | 1 line

auto commit when done pacman command: pre-transaction
------------------------------------------------------------------------
r28 | root_honoka | 2019-09-25 22:15:59 +0900 (2019年09月25日 (水)) | 1 line

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

(2019/09/27 修正ここまで)

(2019/08/13 修正ここから)
journalctl の不穏なメッセージ「svn: E200007: パス '/etc/pacman.d/gnupg/S.gpg-agent' のノード種別はサポートされていません」は発生しなくなった筈です。
(2019/08/13 修正ここまで)

Etckeeper 風に、 /etc を Subversion で管理するようにしました。
今回はノートパソコンに導入しましたが、サーバマシンでも同様の手順で実施できると思います。

やったね :thumbsup_tone2:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?