RaspbianのApache2+Subversionで認証つきリポジトリ

# やりたかったこと
Subversionサーバーって使ったことなかったので手持ちのラズパイでさくっと動作確認。

# 環境
- Raspberry pi 3B+
- Raspbian 10 Buster
- Windows8.1(on Parallels Desktop)

# 取りあえず必要なパッケージインストールから
Apache2(Webサーバー)と，Subversionとその関連ツールをまとめてインストールしまする。
最初の `sudo apt-get update` を忘れぬように。

```bash:command
sudo apt-get update
sudo apt-get -y install apache2
sudo apt-get -y install subversion subversion-tools libapache2-mod-svn
```
自分の環境だとこの時点ですでにサービスactive(running)になってました。
なおサービスの稼働状態の確認はこちら。

```bash:command
systemctl status apache2.service
```

# 何はともあれ動かしてみる
まずはテスト用リポジトリ作るところから。リポジトリフォルダはデフォルトの設定ファイルに記述されてた場所。

```bash:command
sudo mkdir /var/lib/svn
sudo svnadmin create /var/lib/svn/test

# リポジトリはApache2が操作するので所有権をデフォルト実行ユーザーwww-dataに変更しておく
sudo chown -R www-data:www-data /var/lib/svn
```

続いて/etc/apache2/mods-enabled/dav_svn.confを修正してさっき作ったリポジトリと紐付け。
とは言え4カ所コメント外すだけだけど。。

```config:/etc/apache2/mods-enabled/dav_svn.conf
# dav_svn.conf - Example Subversion/Apache configuration
(略)
#<Location /svn> # ・・・(1)
<Location /svn>

  # Uncomment this to enable the repository
  #DAV svn # ・・・(2)
  DAV svn

  # Set this to the path to your repository
  #SVNPath /var/lib/svn
  # Alternatively, use SVNParentPath if you have multiple repositories under
  # under a single directory (/var/lib/svn/repo1, /var/lib/svn/repo2, ...).
  # You need either SVNPath or SVNParentPath, but not both.
  #SVNParentPath /var/lib/svn # ・・・(3)
  SVNParentPath /var/lib/svn
(略)
#</Location> # ・・・(4)
</Location>
```

これで `sudo systemctl restart apache2.service` とすれば取りあえず動くようにはなるはず。

![svn初期状態テスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536565/7a0e4835-58b7-821c-a227-986b3f1440be.png)
ブラウザから `http://(サーバーIPアドレス)/svn/test`にアクセスしてこんな感じで表示されたらOK。

# せっかくなのでユーザー認証出来るようにしておく
リポジトリへのアクセス制御するため `/etc/apache2/dav_svn.passwd` と `/etc/apache2/dav_svn.authz` を用意する。
`dav_svn.passwd` は登録ユーザー情報， `dav_svn.authz` はアクセス制御情報で， `dav_svn.passwd` だけでも簡単な制御は出来るけどユーザー毎の制御までは出来ないので二つとも設定する。

まず，認証ユーザーはLinuxユーザーである必要があるみたいなので必要に応じて新規作成する。

```bash:command
sudo adduser --no-create-home hoge
# hogeユーザーを作成。今回不要なんでHOMEディレクトリは作成しない設定
```

続いて `dav_svn.passwd` に登録ユーザー情報(認証ユーザー名とパスワード)を設定する。

```bash:command
sudo htpasswd -c /etc/apache2/dav_svn.passwd pi
# /etc/apache2/dav_svn.passwdファイルにpiユーザーを登録
sudo htpasswd /etc/apache2/dav_svn.passwd hoge
# -c はファイル生成スイッチで登録二人目以降はつけない
```
`dav_svn.passwd` ファイルは暗号化されてて常人は読めない。

```bash:/etc/apache2/dav_svn.passwd
pi:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
hoge:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

リポジトリ毎のアクセス制御情報は `dav_svn.authz` に記述する。
初期状態ではファイルは存在しないので新規ファイル編集して名前を付けて保存するか，以下コマンドで先に生成しておく。

```bash:command
sudo touch /etc/apache2/dav_svn.authz
```
制御情報は次の要領で記述する。

``` /etc/apache2/dav_svn.authz
[/]
* = r

[test:/]
* = r
pi = rw
hoge = n

# [test:/] ← リポジトリ名:フォルダ名
# * = r    ← 全ユーザー読取り可
# pi = rw  ← ユーザーpiは読み書き可
# hoge = n ← ユーザーhogeはアクセス拒否
```

さっきの /etc/apache2/mods-enabled/dav_svn.conf をさらに修正。例によってコメント外していく。
ただ途中の `Require valid-user` は追記する必要がある。

```config:/etc/apache2/mods-enabled/dav_svn.conf
# dav_svn.conf - Example Subversion/Apache configuration
(略)
#<Location /svn> # ・・・(1)
<Location /svn>
(略)
  #AuthType Basic
  AuthType Basic
  #AuthName "Subversion Repository"
  AuthName "Subversion Repository"
  #AuthUserFile /etc/apache2/dav_svn.passwd
  AuthUserFile /etc/apache2/dav_svn.passwd

  # ここだけ追記
  Require valid-user

  # To enable authorization via mod_authz_svn (enable that module separately):
  #<IfModule mod_authz_svn.c>
  <IfModule mod_authz_svn.c>
  #AuthzSVNAccessFile /etc/apache2/dav_svn.authz
  AuthzSVNAccessFile /etc/apache2/dav_svn.authz
  #</IfModule>
  </IfModule>
(略)
#</Location> # ・・・(4)
</Location>
```
ここで再度 `sudo systemctl restart apache2.service` とすればアクセス制御かかった状態で稼働開始する。

# インストール済みバージョン確認
Raspbian側

```bash:Raspian
$ apache -v
Server version: Apache/2.4.38 (Raspbian)
Server built:   2019-10-15T19:53:42
$ subversion --version -quiet
1.10.4
```
Windows側(検証用)
![TortoiseSVNバージョン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536565/e9209cf8-e635-af9a-1613-09cfdacd6111.png)

# 気づき
今回セットアップやってて，数年前まで使ってたCentOS時代に "`service`コマンドはもう古いぞよ，これからは`systemctl`に統一なるぞよ"って啓示をを受けた気がするが，Raspbianだと全然`service`コマンドが使えるという知見を得た（うっかり手癖でコマンド打ったらエラー吐かないので気がついた次第）。Raspbianでも普段 `systemctl` で設定変更したりするがUbuntuでも同じで `service` コマンド使えるのかな。いや今さら使わないか。

# 最後に
今回Raspbian上に構成した環境でWindows8.1(on Parallels Desktop)からTortoiseSVN(Windows用Subversionクライアントアプリ)によるユーザー認証とリポジトリブラウズ，コミット，アクセス制御まで確認出来ますた(リポジトリアクセスの詳細については今回は割愛)。
本当にあっさり動くんでちょっと拍子抜けした次第。

あとSubverionサーバーって何が嬉しいのかよく分かってなかったけど，一番は共有フォルダを使わないのでリポジトリフォルダ内の制御ファイルを直接触れないとこにあるのだなと理解した。アクセス制限は共有フォルダ単位でも出来るけど，アクセス出来るユーザーが制御ファイルをうっかり致してしまう可能性を考えてなかった。