GCPのVMインスタンスでSFTP接続する方法


 　　

ちょっと詰まったからやったことのまとめ

## 環境

* MacBookPro 13
    * macOS High Sierra 10.13.3
    * 使ったFTPクライアントのアプリ
        * Cyberduck
    * Python 2.7.10 / 3.6.5
* GCP VMインスタンス
  * Ubuntu 16.04.5 LTS (GNU/Linux 4.15.0-1018-gcp x86_64)


## やること・やったこと

「GCPで作ったサーバーにFTP接続したい！！！」

前提として、VMインスタンスを作っている後の話しから始めます。
作り方については、下記リンク先の内容を参考にさせていただきましたm(_ _)m

* [GCE の無料枠のサーバを立るときに、初見でハマりそうなところ](https://qiita.com/ndxbn/items/7ef0a96e409a5b5837bd)
* [ＧＣＰでウェブサーバ構築チャレンジ](http://studiomoonleaf.com/?lid=201611071300)
* [Google Cloud Platformで無料Webサーバを作る](https://blog.mktia.com/deploy-apache-web-server-on-google-compute-engine/)

　

Google Cloudの公式ページにある、[インスタンスへのファイルの転送](https://cloud.google.com/compute/docs/instances/transfer-files)の[Linux ワークステーションまたは macOS ワークステーションのファイル ブラウザを使用したファイルの転送](https://cloud.google.com/compute/docs/instances/transfer-files#filebrowser)に書かれていることをそのままやるんですが、1点気づかぬ設定があったので、わかりやすいように各設定を細かく解説していきます。

### ①SSH認証鍵の設定
いつもの設定って感じですね。わからない人は[公式の新しい SSH 認証鍵を作成する](https://cloud.google.com/compute/docs/instances/adding-removing-ssh-keys#createsshkeys)を見ながら、macとgcpで公開キーの設定をします。

### ②Ubuntuを一度確認
GCPの管理画面のVMインスタンスから「ブラウザ ウィンドウで開く」ってやつを選択するとブラウザ上でターミナル/コマンドプロンプトのようなコマンドラインツールが開きます。
マジか！？GCPスゲェー！！ってなったんですが触ってるとクソ重くって、一瞬で天と地が逆転したような評価になってしまったw
おそらくWebRTCみたいな感じだと思うんで、手元の環境からSSH接続して操作した方が良いです。

 　　

↓「ブラウザ ウィンドウで開く」
![スクリーンショット 2018-09-04 22.21.24.png](https://qiita-image-store.s3.amazonaws.com/0/82601/f435e0c3-a2dc-6f7f-4a47-2510e6a6dcb6.png)
 

↓VMインスタンスのコマンドラインツール
<img width="1012" alt="f8d73658-36a6-00c0-f9e3-e8fa89fffbdb.png" src="https://qiita-image-store.s3.amazonaws.com/0/82601/1947e263-73dd-6c32-984f-c98c2971c912.png">


### ③Cyberduckの設定
どうも公式によるとLinux系のサーバーであればSFTP接続が普通にできるとのこと。
上記のドキュメントで解説されている

```
sftp://[USERNAME]@[IP_ADDRESS]/home/[USERNAME]
```

- [USERNAME] は、そのインスタンスでのユーザー名です。
- [IP_ADDRESS] は、インスタンスの IP アドレスです。

の内容を元にCyberduckに新規登録して見る。

<img width="510" alt="スクリーンショット 2018-09-06 0.11.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/82601/135185bf-e11e-7b1b-55a3-8f2d34ba7abd.png">

コマンドラインツール上を見るとわかる通り、`grem_takuya0223`という名前がユーザー名になっていたのでそのまま設定しました。
ちなみに`grem_takuya0223`は、VMインスタンスを作る際にGCP側でメールアドレスを元に勝手に作られたユーザー名になっています。


### ④ログイン失敗
ずっとこの状態で何が悪いのかわからなくなりました。
これが原因でvsftpdとか入れて遠回りのことをやりましたが、「Connecting...」から帰ってこないなど、余計に混乱して、結局改めて設定を見直すことにしました笑汗

<img width="435" alt="スクリーンショット 2018-09-06 0.16.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/82601/286d1566-8a4b-85c3-5bb6-c055ec1fac24.png">


#### vsftpd

- [GCPのCompute EngineのUbuntuでvsftpdを使う](https://endoyuta.com/2017/05/12/gcp%E3%81%AEcompute-engine%E3%81%AEubuntu%E3%81%A7vsftpd%E3%82%92%E4%BD%BF%E3%81%86/)
- [Ubuntu 16.04: FTPサーバのvsftpdをインストールする](https://www.hiroom2.com/2017/08/06/ubuntu-1604-vsftpd-ja/)


### ⑤再設定
そもそも設定する内容として「公開キーの設定」「IPアドレス」「ユーザー名」の3つで、公開キーが間違えることはなかったので、となるとIPとユーザー名を見直すことに。
まず、IPアドレスで管理画面上には、「プライマリ内部 IP」と「外部 IP」の2つありますが、ここで内部IPを使うことありえないので設定はあっていることに。
では、あとはユーザー名で改めて`インスタンスでのユーザー名`を見ると「どこを指しているんだ？」とわからなくなりました笑

インスタンス内のユーザー名なのか
それともGCPのアカウント名なのか

先ほどGCPがメールアドレスから勝手にユーザー名を作ったと言いましたが、正確には`grem.takuya0223@...`でした。
なので、Cyberduckの設定上のユーザー名に設定していた`grem_takuya0223`を`grem.takuya0223`に変えてみたところ...正常に接続できましたwww

↓再設定
<img width="953" alt="スクリーンショット 2018-09-05 23.33.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/82601/8774a71e-1926-b97b-dc94-4f84496e8c94.png">

↓SFTP接続成功
![スクリーンショット 2018-09-06 0.33.41.png](https://qiita-image-store.s3.amazonaws.com/0/82601/bae7b0e0-e3cc-2eba-f5a6-4999025b7274.png)

## まとめ
`インスタンスでのユーザー名`は、GCPのアカウントIDでした。
まぁ、メールアドレス内にドットが入っていない人には関係ない話だと思います＾＾;

 　　
## 追記: 2018/09
上記の設定から特定の開発環境で扱えるFTP/SFTPクライアントのツール作りを進めていたのですが、これまた知見が生まれたので追記します。

やはり問題は、**メールアドレス（アカウント名）内にドットが入っているとハマってしまう**内容になります。

### `paramiko`
特定の開発環境で扱えるFTP/SFTPクライアントのツールを作っていると、何か問題が発生した時にどこで何が原因になっているのか把握しづらいため、一旦、**Pythonを扱ってシンプルなコードでFTP/SFTPの機能を作って成功体験を得ようと考えました。**

PythonでFTP/SFTPを実現するためには、paramikoというライブラリを扱うとできると調べてわかったので使ってみました。

- paramiko
  - http://docs.paramiko.org
  - https://github.com/paramiko/paramiko

### GCPは`SFTP`でしか接続できない
最初のミスとしてわかったことが、GCPのVMインスタンスでは、SFTPでしか接続できないということが分かり、上記で解説している秘密鍵の`~/.ssh/id_rsa`を通信時に扱うようにしないといけないことが問題になっていました（マジ恥ずかしぃ...w）。


### `IOError: [Errno 13] Permission denied`でハマる
秘密鍵の設定していなかったことで出ていたと思った`IOError`が、なぜかまだ出ていたので調べたところ、[Paramiko Python: IOError: [Errno 13] Permission denied](https://stackoverflow.com/questions/23144286/paramiko-python-ioerror-errno-13-permission-denied)というまんま同じ内容のstackoverflowの記事を見つけたので読んでみた。

そして、ホントに権限周りが問題ではないのかと再確認しました。


### `/home`配下を確認すると

<img width="590" alt="スクリーンショット 2018-09-23 15.22.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/82601/277cac97-0518-b2e8-6e25-fee889472ca2.png">

![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/82601/c6f44730-644c-a580-3556-fd0127e7ba47.png)

上記で解説している問題の原因と同じで、今回は、GCP側が自動で`ドット付きのアカウント名`と`ドットをハイフンにしたアカウント名`が`/home`配下に作られていることと、アカウントも別個に用意されていることが分かりました。

この内容が原因で、ソースコード側では`/home/grem_takuya0223/xxxxx.xxx`とアップロード先を指定していたため、権限は`grem_takuya0223`であってサインインした`grem.takuya0223`ではないため、`Permission denied`とされていたようです。

なので、アップロード先の設定を`/home/grem.takuya0223/xxxxx.xxx`としたら上手くいきました笑


### 最後に

ファイルのアップロードだけですが、[今回作ったSFTPのアップロードができるPythonコードをGitHubGistにアップしました](https://gist.github.com/gremito/2cc1e20a212c6d6121e5394fc746d23c)ので、よかったらご参考にされてくださいー

なんでこんなに面倒なことになるんだろうか...w