なるべく安く定額でS3互換ストレージを立ち上げたい

# はじめに

* いつきさんは、月額固定じゃない料金形態が大嫌い
    * この時点で、世の中のS3オブジェクトストレージは大体候補から外れます
* ほぼ固定のwasabiとかどう？
    * [Wasabi’s free egress policy](https://wasabi.com/paygo-pricing-faq/#free-egress-policy)読むと、「保存した容量より転送したら嫌です（意訳）」とか書いてある。怖い。
* どうせなら自分で立てるか！

## 前提

* [(さくらの)VPS](https://vps.sakura.ad.jp/)は契約してるけど、ディスクが空いてない
* 200Gぐらいストレージが欲しい
* 追加料金は月500円ぐらいに抑えたい
* 互換ストレージは[minio](https://min.io/)で良いか。

## 考えたこと

* [さくらのレンタルサーバー スタンダード](https://rs.sakura.ad.jp/standard.html)が月500円以下で、容量が300G。
* この容量だけ使いたい……！

## 解決案

* [rclone](https://rclone.org/)で、さくらのレンタルサーバーの領域をディスクとしてマウントしてしまおうぜ！！

## まずは？

* [さくらインターネット](https://www.sakura.ad.jp/)さんの利用規約的に、それは大丈夫なのか？

### さくらインターネットのサポートに問い合わせてみた

いつき「さくらレンタルサーバのssh接続を利用して、**さくらVPSのLinux上からファイルシステムのように見せて使いたい** と考えています。さくらVPS上のプログラムからさくらレンタルサーバにファイルを書き出して、さくらVPS側から参照する感じを考えています。技術的サポート等は不要ですが、**規約的にそういう使い方をして良いのか分からなかった**ので質問させていただきました 」

サポート様「利用可否についての判断ができませんでしたため、お手数ではございますがお客様にてお試しいただけますでしょうか。」

いつき「もし、**試して出来たとしたら、そのまま契約している限り使い続けて問題ない**という回答でよろしいですか？ 」

サポート様「さようでございます。 」

よしっ！！！　言質取った！！！

## まずは、レンタルサーバー借りる

２週間無料プランでスタンダード以上を借ります（スタンダード以上じゃないとsshが使えないのよー）

## ユーザ作ったり、必要なライブラリ入れたり、rootで事前準備

OSはRocky Linux 8系統。

```sh
adduser minio
loginctl enable-linger minio
yum install rclone
yum --enablerepo=powertools install fuse
```

* minioユーザ作って
* そのユーザでsystemdがずっと立ち上がるようにして
* rcloneインストールして
* fuseをインストール

なお、いつきさん、SELinux有効派＆nginxでプロキシしたので、次の設定を忘れずにやった。えらい。

```sh
setsebool -P httpd_can_network_connect=1
setsebool -P httpd_can_network_relay=1
```

## minioユーザで、マウント準備！

まずは、さくらのレンタルサーバーにアクセスするための公開鍵作ります。

```sh
ssh-keygen
```

どこにファイル置くか聞かれるので、`id_rsa-sakura`とかわかりやすい名前を入力

```sh
cat ~/.ssh/id_rsa-sakura.pub
```
出てきた内容を、さくらのレンタルサーバーにsshログインして、`~/.ssh/authorized_keys`に追記します。
※.sshディレクトリのアクセス権を700、authorized_keysのパーミッションは600を推奨。


```sh
rclone config
```

いろいろ聞かれるけど、次のやつを選んでいきます

```conf
n) New remote
```

nameを聞かれるので、適当に。`sakura`とかで良いんじゃないかな。

```conf
Option Storage.
……
33 / SSH/SFTP Connection
   \ "sftp"
……
Storage>
```

迷うことなく、33を選択

```conf
Option host.
SSH host to connect to.
E.g. "example.com".
Enter a string value. Press Enter for the default ("").
host>
```

**さくらのレンタルサーバーのホスト名を入れます**

```conf
Option user.
SSH username, leave blank for current username, minio.
Enter a string value. Press Enter for the default ("").
user>
```

**さくらのレンタルサーバーのユーザ名を入れます**

```conf
Option port.
SSH port, leave blank to use default (22).
Enter a string value. Press Enter for the default ("").
port>
```

デフォルトで良いのでそのままで。

```conf
Option pass.
SSH password, leave blank to use ssh-agent.
Choose an alternative below. Press Enter for the default (n).
y) Yes type in my own password
g) Generate random password
n) No leave this optional password blank (default)
y/g/n>
```

ssh鍵認証を使うのでnを入れます。

```conf
Option key_pem.
Raw PEM-encoded private key.
If specified, will override key_file parameter.
Enter a string value. Press Enter for the default ("").
key_pem>
```

これは空のままで良いです。

```conf
Option key_file.
Path to PEM-encoded private key file.
Leave blank or set key-use-agent to use ssh-agent.
Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.
Enter a string value. Press Enter for the default ("").
key_file>
```

さっき作ったssh鍵のフルパスを入れます。例えば、`/home/minio/.ssh/id_rsa-sakura`

```conf
Option key_file_pass.
The passphrase to decrypt the PEM-encoded private key file.
Only PEM encrypted key files (old OpenSSH format) are supported. Encrypted keys
in the new OpenSSH format can't be used.
Choose an alternative below. Press Enter for the default (n).
y) Yes type in my own password
g) Generate random password
n) No leave this optional password blank (default)
y/g/n>
```

ssh鍵のパスコードなんてイランでしょう（暴論）`n`で良いです。

```conf
Option pubkey_file.
Optional path to public key file.
Set this if you have a signed certificate you want to use for authentication.
Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.
Enter a string value. Press Enter for the default ("").
pubkey_file>
```

そんなものはないので、そのままで。

```conf
Option key_use_agent.
When set forces the usage of the ssh-agent.
When key-file is also set, the ".pub" file of the specified key-file is read and only the associated key is
requested from the ssh-agent. This allows to avoid `Too many authentication failures for *username*` errors
when the ssh-agent contains many keys.
Enter a boolean value (true or false). Press Enter for the default ("false").
key_use_agent>
```

ssh鍵のパスコードなんてイランでしょう（暴論）そのままで。

```conf
Option use_insecure_cipher.
Enable the use of insecure ciphers and key exchange methods.
This enables the use of the following insecure ciphers and key exchange methods:
- aes128-cbc
- aes192-cbc
- aes256-cbc
- 3des-cbc
- diffie-hellman-group-exchange-sha256
- diffie-hellman-group-exchange-sha1
Those algorithms are insecure and may allow plaintext data to be recovered by an attacker.
Enter a boolean value (true or false). Press Enter for the default ("false").
Choose a number from below, or type in your own value.
 1 / Use default Cipher list.
   \ "false"
 2 / Enables the use of the aes128-cbc cipher and diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1 key exchange.
   \ "true"
```

趣味の世界ですが、デフォルトで良いんじゃないかな！（笑）

```conf
Option disable_hashcheck.
Disable the execution of SSH commands to determine if remote file hashing is available.
Leave blank or set to false to enable hashing (recommended), set to true to disable hashing.
Enter a boolean value (true or false). Press Enter for the default ("false").
disable_hashcheck>
```

デフォルトが良いんじゃないかな！（笑）

```conf
Edit advanced config?
y) Yes
n) No (default)
y/n>
```

これで設定終わりなので、デフォルトで良いです。

```conf
--------------------
[sakura]
type = sftp
host = ホスト名
user = ユーザ名
key_file = /home/minio/.ssh/id_rsa-sakura
--------------------
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d>
```

内容間違ってなければ、yで！

最後に、qで設定抜ければおしまいです。

## マウントしてみよう！

その前に、さくらのレンタルサーバー側で、ファイルを置く場所を作っておきましょう。
個人的には`~/private/minio/data`にしました。
あったり前ですが、さくらのレンタルサーバー側で、~/private/ 以下のパーミッションは700にしておきましょう。
管理者以外に見て欲しくない。

マウントするところをローカルに作ります。
今回は、`~/minio/data`を作りました。

マウントコマンドは次の通り

```sh
rclone mount sakura:~/private/minio/data ~/minio/data
```

何も帰ってこないので安心してください！！
だんまりすれば成功です。

他のターミナルを起動してやるとめっちゃマウントされてるのが見えるはず……！

ローカル側で、`~/private/minio/data`にファイル作ったりディレクトリ作ったりして、さくらのレンタルサーバー側の`~/minio/data`にファイルが増えたり減ったりするのをニヤニヤして眺めましょう。

**いつきさんの環境では、レンタルサーバー側にファイルを置いても、ローカル側で直ぐには見えませんでした。注意**

ちなみに、rcloneをctrl+cとかで落とすと、ディスクは見えなくなりますが、マウントされたままになります。
`fusermount -uz ~/minio/data`とやるとアンマウント出来ますので、落ち着いて！

## 起動時に自動的にマウントするように設定

いつきさんは、ユーザでもsystemdを積極的に使います。

`~/.config/systemd/user/sakura-mount.service`を作りました！

```conf
[Unit]
Description=sakura ssh mount
After=syslog.target network.target auditd.service

[Service]
ExecStart=/usr/bin/rclone mount sakura:＜さくらのレンタルサーバーのホームパス＞/private/minio/data ＜ローカル側のホームパス＞/minio/data
ExecStop=/usr/bin/fusermount -uz ＜ローカル側のホームパス＞/minio/data
KillMode=process
Restart=on-failure
RestartSec=42s
SyslogIdentifier=sakura-ssh-mount
SyslogFacility=daemon
SyslogLevel=info

[Install]
WantedBy=multi-user.target
```

こんな感じのやる気無いserviceファイルを作成。

忘れてましたが、`~/.bashrc`とかに以下の設定が必要です。

```conf
export XDG_RUNTIME_DIR=/run/user/$(id -u minio)
```

minioはユーザ名なので、まぁ合わせて。

この状態で、`systemctl --user start sakura-mount`が効くようになります。
勝手にマウントされるよ！

正常にマウントされたことを確認したら、`systemctl --user enable sakura-mount`でもしておきましょう！
起動時に勝手にマウントされるよ！！

あとは、minioを立ち上げるだけだ！

## minioの起動

いつきさんは、`~/bin`にいろいろ入れるのだ！
そしてwget使いなのだ！

```sh
mkdir ~/bin
cd ~/bin
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod 700 minio
```

あとはminioを起動するだけなのだ！

いきなりserviceファイル～！
`~/.config/systemd/user/minio.service`

```conf
[Unit]
Description=minio service
After=sakura-mount.service

[Service]
EnvironmentFile=/home/minio/minio/env
ExecStart=/home/minio/bin/minio server /home/minio/minio/data --console-address "127.0.0.1:9001" --address "127.0.0.1:9000"
KillMode=process
Restart=on-failure
RestartSec=42s
SyslogIdentifier=minio
SyslogFacility=daemon
SyslogLevel=info

[Install]
WantedBy=multi-user.target
```

パスとかは自分の環境に合わせてね！
管理コンソールは、`127.0.0.1:90001`、本体は`127.0.0.1:9000`で待ち受ける設定だ。

そして、`/home/minio/minio/env`を作る

```conf
MINIO_ROOT_USER=ルートユーザーのユーザー名
MINIO_ROOT_PASSWORD=ルートユーザーのパスワード
MINIO_SERVER_URL=https://外から見たときのminioのURL/
MINIO_BROWSER_REDIRECT_URL=https://素知らぬ場所にアクセスされたときに飛んでいく場所/
```

この状態で、`systemctl --user start minio`が効くようになります。
この状態で、`systemctl --user status minio`で問題なく動いてたら、`systemctl --user enable minio`しておきましょう。
これでminioの設定終わり！

## 外から見えるように……！(nginxの設定)

雑には、こんな感じで追加すれば動くんじゃないかなぁ～！

オブジェクトストレージ本体側
```conf
server {
    listen 80;
    server_name サーバ名;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl http2;
    server_name サーバ名;
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_certificate "/etc/letsencrypt/live/サーバ名/fullchain.pem";
    ssl_certificate_key "/etc/letsencrypt/live/サーバ名/privkey.pem";
    ssl_ciphers EECDH+AESGCM+AES128:EECDH+AESGCM:EECDH+AES128:EECDH+AES256;
    ssl_prefer_server_ciphers on;

    client_max_body_size 30m;

    location / {
        proxy_redirect                      off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout          1m;
        proxy_connect_timeout       1m;
        proxy_pass                          http://127.0.0.1:9000/;
    }
}
```

`ssl_ciphers`は趣味です。
`client_max_body_size`は、アップロードできる最大サイズを指定しましょう。
最初何も書かなかったら1mになってて、若干ハマった。

管理コンソール側も、`proxy_pass http://127.0.0.1:9001/`とすればOKですが、必要時以外は見れないように、認証を掛けておくか、必要時だけssh-forwardしておくことを推奨します。

で、暗黙のうちにlet's encrypt使うことになってますが、その設定は自分でググってね！！　頑張れ！

## で。

さくらのレンタルサーバー上のファイル

![さくらのレンタルサーバー上のファイル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493677/a26f41b5-bdc0-609c-4e1b-a374d5c2afff.png)

www1267.sakura.ne.jp (さくらのレンタルサーバー上)にファイルがもりもり！

動いた模様！

## おまけ

[労働者たちのMisskey](https://msky.work/)というmisskeyインスタンスで実際に使ってます！
超激しいアクセスさえなければ、たぶん大丈夫。

## ところで

さくらのレンタルサーバーから「直接」ダウンロードさせることは出来ないの？　という疑問を受けました！
minioのファイル構造をたどれるcgiでも作れば行けるかもしれませんが、現状は無理かなぁと。

→　追記：やってみた！！　[さくらのレンタルサーバーでminioのデータを読みたい（misskeyのデータ置き場にしたい) ](https://qiita.com/ityuki/items/6faefa5428721b0eb35a)