ConoHa のオブジェクトストレージを VPS にマウントして、FTP で使えるようにする方法

Conoha オブジェクトストレージ HP トップ

動画をどんどん上げたいとのこと

ConoHa VPS の WordPress (kusanagi) で運用しているサイトで、どんどん動画を上げたいという話があって、本数も一本あたりの時間も結構ある見込みとのこと。

WordPress のメディアとしてアップするのは厳しいので、動画ファイルはオブジェクトストレージに上げてもらうのがいいだろうと。現状、転送量が不明なので Amazon S3 は不安だろう。ってことで ConoHa のオブジェクトストレージを使うことに。

んで問題は、どうやって動画を上げてもらうか。

Cyberduck なら OpenStack Swift にも対応しているので、これで上げてもらうか。ただ、別のサイトも ConoHa で運用しているので、 ConoHa の API 情報を教えるわけにはいかない。別途、先方もしくはこちらでこのためだけに ConoHa のアカウントを作ろうかなとも思ったけど、アカウントの管理が煩雑になるのもなあ。

動画ファイルをもらって、あっしのほうで上げることにしてもらおうかなとも思ったけど、オブジェクトスレージを VPS にマウントして、そこに FTP サーバー作れば、FTPソフトで上げてもらえるやんと。

ってことで、以下、実際にやってみた手順を復習しつつまとめてみました。

まず ConoHa でオブジェクトストレージを使えるようにする

これは実に簡単。ConoHa のコントロールパネルの「オプジェクトストレージ」で、ツールアイコンをクリック。

Conoha コントロールパネル オプジェクトストレージ ツールアイコン

すると以下のようなダイアログが出るので、

Conoha コントロールパネル オプジェクトストレージ 容量選択

必要な容量を選択して、「はい」をクリック。これでオブジェクトストレージが使える準備が整った。転送量などは関係なしで100GBで月450円(税抜)。激安ですな。

とりあえず手元の PC で操作できるように

それでとりあえずは手元の PC でファイルをアップロードできるようにする。Cyberduck とかでもいいけど、コマンドラインツールの swift クライアントを使うことにする。公式の↓を見ればいいんだけど、

https://support.conoha.jp/v/objectstorageswift/?btn_id=v-objectstorage-sidebar_v-objectstorageswift

今回、手元の Windows 機には Cygwin の Python で入れることにする(上記ページの Windows のインストールの方法はちょっとハテナだけど…)。Cygwin のターミナルから

$ pip install python-swiftclient
$ pip install python-keystoneclient

とすれば必要なものを Cygwin の Python で無事入れることができた( pip など入っていなければもちろん入れてやる)。

それで認証情報をいちいち入力するのは面倒なので、Cygwin では Zsh を使っているので .zshrc に以下のように記述しておくことにする。

export OS_AUTH_URL='[Identity Service]'
export OS_TENANT_NAME='[テナント名]'
export OS_USERNAME='[ユーザ名]'
export OS_PASSWORD='[APIユーザー作成時に設定したパスワード]'

※もちろん、[テナント名]などは上記、公式ページを参考にして各自のものを入力のこと。

これで Cygwin のターミナルから

$ swift stat

とやってやって、オブジェクトストレージに関する情報が表示されればオーケー。例えば

$ swift post ginchan

とやると、「ginchan」というコンテナが出来る。それで

$ swift upload ginchan hoge.jpg

でアップロードできる。確認として

$ swift list ginchan

で「hoge.jpg」が表示されていれば問題なく、アップロードされていると。んでこのままだと web には公開されていない状態なので、

$ swift post ginchan -r ".r:*"

ってやってやると、ginchan にアップしたファイルが web で公開されている状態になる。その URL はコントロールパネルの API のところの「エンドポイント」の「Object Storage Service」のところがベースの URL になるので、

Conoha オブジェクトストレージ エンドポイント

もちろん上の画像はモザイクかけているけど、

https://object-storage.tyo1.conoha.io/v1/xx_123456789abcdefghijk01234567890ab

ってな具合にエンドポイントがなっているので、上で上げた hoge.jpg の URL は

https://object-storage.tyo1.conoha.io/v1/xx_123456789abcdefghijk01234567890ab/hoge.jpg

となる。これで最低限、Conoha のオブジェクトストレージにファイルをアップロードできて、web ブラウザからもアクセスできると。

VPS に ConoHa のオブジェクトストレージをマウント

さて、このオブジェクトストレージを VPS にマウントするわけだが、サイト運用しているサーバではなく、別途借りている開発用サーバー ( Ubuntu 18.04LTS ) にマウントすることにする。

んで、VPS へのマウント方法は公式ガイド

https://support.conoha.jp/v/objectstoragemount/

にも書かれているが、今回使用するサーバーは ubuntu なので必要なものは次のように入れる。

まず、fuse と ruby はまあ入ってるけど、入っていなければ、

$ sudo apt-get install fuse ruby

それでオブジェクトストレージ( OpenStack Swift )をマウントするためには svfs( The Swift Virtual File System )が必要なので、https://github.com/ovh/svfs/releases/tag/v0.9.1 から必要なのを選らび取得して入れてやる。今回のわたくしの場合は、

$ wget https://github.com/ovh/svfs/releases/download/v0.9.1/svfs_0.9.1_amd64.deb
$ sudo dpkg -i svfs_0.9.1_amd64.deb

と入れてやる。それで /mnt 以下にマウントする場合は

$ sudo mount -t svfs conoha_storage /mnt -o auth_url="Identity ServiceのURL",username="ユーザー名",password="パスワード",tenant="テナント名"

でマウント。もちろん、ユーザー名などは各自のもので、conoha_storage は適当な名前でと。実際マウントされているか確認として

$ df -h /mnt                                                                                     
Filesystem      Size  Used Avail Use% Mounted on
conoha_storage  8.0E  827M  8.0E   1% /mnt

とここまでは公式のとおりでやってみたが、/mnt 内を見てみると

$ sudo ls -la /mnt/ginchan                                                                          
合計 708
-rwx------ 1 root root 728055  2月 14 17:11 hoge.jpg

なんて感じで root のものになっている。うーん、これじゃあ色々使えないのでは…ってことで調べてみると、

オプションとして uid と gid を付ければいいとのこと。ってことで、

$ sudo mount -t svfs conoha_storage /mnt -o uid=1000, gid=1000, auth_url="Identity ServiceのURL",username="ユーザー名",password="パスワード",tenant="テナント名"

でやってやれば、無事自分のものとしてマウントできた。もちろん、1000 とかは id コマンドで確認した自分のもの。

FTP サーバを構築

ここまでは uid と gid の件はちょっと記憶にないけど、以前試しにやってみたこともあることで、問題は FTP サーバの構築。

いつもは sftp で済ませているので、あっしは FTP サーバを構築したことがないのだ。もちろん今回の件、先方に sftp でやってもらうのは無理だろうな、ってことで、FTP サーバを構築せねば。

最初、 vsftpd を入れてみて、ファイルをアップロードしようとすると 500 OOPS: lseek みたいなエラーが出て、アップロードできず。どうも致命的なエラーとのことだが、よくわからん。もう無理なのかなあと、色々調べてみたら、svfs の Issues で https://github.com/ovh/svfs/issues/54 で大きなファイルのアップに失敗するとのことだが、PureFTP でファイルをアップしている人を発見。

ってことで、PureFTP を入れることに。まず

$ sudo apt-get install pure-ftpd

で入れる。このとき、それまで入れていた vsftpd は自動的に削除される。

PureFTP の設定は以下のサイトなどを参考にさせていただいた。

https://qiita.com/Tats_U_/items/09d9aa5fd0aef6772272

要は /etc/pure-ftpd/conf/ 以下に設定する項目のファイルがあり(無ければ作る)、そこに設定を記述する。とりあえず、以下のようにしてみた。

  • /etc/pure-ftpd/conf/TLS には 2 を設定
  • /etc/pure-ftpd/conf/PassivePortRange は40000 40029
  • /etc/pure-ftpd/conf/UnixAuthentication と /etc/pure-ftpd/conf/PAMAuthentication はともに no に
  • /etc/pure-ftpd/conf/NoAnonymous は yes
  • /etc/pure-ftpd/conf/TLSCipherSuite は AESGCM+TLSv1.3:AESGCM+ECDHE+TLSv1.2

最初の2つはファイルがなかったので、作成して値を記載。3つ目、4つ目は PAMAuthentication 以外は初期値のままだけど一応。最後の上記サイトに習って。そのほかにも設定ファイルがあるけど、それらまあオーケーかなと。

それで SSL 証明書はさしあたってオレオレ証明書でいいんで、

$ sudo cat /etc/ssl/private/ssl-cert-snakeoil.key /etc/ssl/certs/ssl-cert-snakeoil.pem | sudo tee /etc/ssl/private/pure-ftpd.pem

で PureFTP 用の証明書を作る。んでこれだけだと、諸々終わって確認したところ、「sudo service pure-ftpd status」で見たところ

Couldn't load the DH parameters file /etc/ssl/private/pure-ftpd-dhparams.pem

なんてことになっているので

sudo openssl dhparam -out /etc/ssl/private/pure-ftpd-dhparams.pem 3072

で必要なファイルを作ってやる。参考: https://www.howtoforge.com/community/threads/pure-ftpd-couldnt-load-the-dh-parameters-file.82682/

それで FTP にログインしてもらうための PureFTP の仮想ユーザーを作成する。

これは以下のサイトを参考にさせてもらった。

2つ目の記事によると、「仮想ユーザーに割り当てるユーザー ID は FTP 以外の方法でのログインを許可しないのが望ましい」とのこと。ってことで、1つ目の記事にならって、 ftpuser と ftpgroup を作ることにする。

$ sudo groupadd ftpgroup -g 1122
$ sudo useradd -d /dev/null -g www-data -s /usr/sbin/nologin -u 1122 ftpuser

home ディレクトリとログイン権限無しのユーザーを作るってことだね。もちろん 1122 は諸々環境に合わせてで。

それで PureFTP の仮想ユーザーを作るのだが、その前に /etc/pure-ftpd/auth/ 内に /etc/pure-ftpd/conf/PureDB のシンボリックリンクを作ってやる。

sudo ln -s /etc/pure-ftpd/conf/PureDB /etc/pure-ftpd/auth/50puredb

それであとは以下の感じでユーザーを追加

$ sudo pure-pw useradd ginchan_ftp -d /mnt/ginchan -u 1122 -g 1122

パスワードを聞かれるので、パスワードを設定。無事終わったら

$ sudo pure-pw mkdb

を忘れずにやってデータベースに反映させる(こいつを忘れがち)。これで ginchan_ftp でログインすると、マウントした /mnt/ginchan にアクセスできる FTP アカウントが出来た。

んで、上でマウントしたのは uid と gid が 1000 だったので、一旦、アンマウントして、 uid と gid を 1122 に指定してマウント。

$ sudo fusermount -u /mnt
$ sudo mount -t svfs conoha_storage /mnt -o uid=1122, gid=1122, auth_url="Identity ServiceのURL",username="ユーザー名",password="パスワード",tenant="テナント名"

それで再度

$ sudo ls -la /mnt/ginchan                                                                           
合計 708
-rwx------ 1 ftpuser ftpgroup 728055  2月 15 21:08 hoge.jpg

でちゃんと所有権が変わっていることを確認。んであとはポートを開放して、

$ sudo ufw allow ftp
$ sudo ufw allow 40000:40029/tcp

設定を反映させてやるために PureFTP を再起動してやる。

$ sudo service pure-ftpd restart

これでとりあえず lftp で接続してみる(XXX.XX.XXX.XXXはサーバの IP アドレス)。

lftp :~> open -u ginchan_ftp XXX.XX.XXX.XXX
パスワード: 
lftp ginchan_ftp@XXX.XX.XXX.XXX:~> ls
-rwx------    1 1122       ftpgroup       728055 Feb 15 21:08 hoge.jpg

アップロードも問題なく出来た!

最後に

これだけだと、サーバーを再起動したときにマウントし直さなければならない。そこで公式ガイドにしたがって /etc/fstab に

conoha_storage  /mnt    svfs    uid=1122,gid=1122,auth_url="Identity ServiceのURL",username="ユーザー名",password="パスワード",tenant="テナント名",segment_size=5000,rw,_netdev      1

を追加。これでサーバーを再起動させると、自動的にマウントされる。

なお、オプションに segment_size=5000 を追加しているのは、アップロード時にファイルを分割するサイズで、ここでは思い切り大きくして(どのみち上限5GBらしい)、実質、分割してのファイルをアップロードさせないことにした。先に参照した svfs の Issues の https://github.com/ovh/svfs/issues/54 ではこの値を大きくしたことで、大きなファイルのアップロードに失敗とのこと。そんな大きなファイルはアップロードしないということで(本来は PureFTP の仮想ユーザーの設定などで制限を設けるべきだろうけど)。

やれやれ、これでオーケーかと。んで先方は FTP クライアントして Filezila を使うとのことで、試してみると、あれ?

GnuTLS error -110 in gnutls_record_recv: The TLS connection was non-properly terminated.

なんてエラーが…。うーん、がっくし。色々調べてみたら、Ubuntu 18.04TLS に入っているバージョン 1.0.46 の  PureFTP では、TLSv1.3 に対応していないことが原因のようだ。そこで https://packages.ubuntu.com/disco/pure-ftpd にパッケージが用意されていたので、

$ wget http://mirrors.kernel.org/ubuntu/pool/universe/p/pure-ftpd/pure-ftpd_1.0.47-3_amd64.deb
$ wget http://mirrors.kernel.org/ubuntu/pool/universe/p/pure-ftpd/pure-ftpd-common_1.0.47-3_all.deb
$ sudo dpkg -i pure-ftpd_1.0.47-3_amd64.deb pure-ftpd-common_1.0.47-3_all.deb

でバージョンを上げてやったところ、無事 FileZilla でもうまく行った。

ところが、大きめのファイルを上げたところ、タイムアウトを起こして、アップロードが最初からに戻ってしまうことが…。うーんと思ったら、結構あることのようで

https://www.superi.jp/entry/2016/04/17/181542

FileZilla の設定で Timeout の秒数を長くすることで、回避できた。サーバーのほうの設定を見直すべきかなとも思ったけど、先方に実際にアップロードしてもらったら、とくに何も言って来なかったので、このままで。あとは FTP アクセスに IP アドレスによる制限などを設けて、しばらくこれで実際に運用して様子を見ることに。

なおアップロードしたファイルの URL は先に触れたように

https://object-storage.tyo1.conoha.io/v1/xx_123456789abcdefghijk01234567890ab/hoge.jpg

なんて長ったらしいので、リバースプロキシでサイトのドメインを使っての短かい URL にしてやると。

これでやったことはほぼ漏れなく、まとめたはず。以上です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です