A Day in the Life

ftp・ftps でアップロードしたファイルを Google Photos にアップロードする

ミラーレスカメラで撮影した jpeg の撮って出しを基本自動で Google Photos にアップロードされるようにしているのだけど、これが便利。PC / スマフォからいつでもミラーレスカメラの写真にアクセスできる、というのは色々と楽だ。Google Photos の検索も便利だしね。

スマートフォンでは Google Photos アプリを入れてればスマフォカメラで撮影するだけで同等のことがすぐできるのだけど、ミラーレスカメラでは構築までがちょっと手間。ただ、一度構築してしまえば後はほって置けるので便利だ。

とはいえ、カメラ側からftpが使えないと、そもそもシステムを構築しても当たり前だけど使えない。そんなカメラ側で ftp を使うには主に二つの選択肢がある。

カメラ本体の ftp アップロード機能

ftp アップロードに対応しているカメラを使えば OK。ただ、対応しているカメラは多くなく、各種メーカのフラッグシップ機が対応している傾向がある。

例えばソニーなら対応カメラのページに乗っているのだけど、機種によって使える機能が異なる。撮影後に明示的に操作してftp転送する「FTP転送によるワイヤレス取り込み」と、WiFiに繋がっていれば撮ったらすぐに転送される「FTPバックグラウンド転送」があるのだけど、例えばa7iii は前者のみ対応、a7C は両方に対応していたりする。

なお、ソニーのFTP転送は「まだ転送していない画像のみ転送」が簡単にできるので、画像ビューモード(▶)のときになにかのFnキーに登録しておくと便利。

FlashAir を使って ftp アップロード

東芝(今はメモリ部門は売却されてキオクシアになってしまったけど)の FlashAir を使えば、カメラが対応していなくても FTP 転送することができる。ただお手軽に使えるわけではなく、FlashAir 上で動く Lua スクリプトを使ってアップロードする必要がある。

  • https://bitbucket.org/harbortronics/flashair-ftp-upload/src/master/

カメラとの相性(ファイルIO周りなのか、電源周りなのか…)もあるようで、うまくアップロードが動いたり動かなかったりするのだけど FlashAir の W-04 と自分の E-M1 mark II ではftpアップロードが不安定で、同じオリンパスの PEN-F では安定して動いている。

Docker で ftpd / Google Photos へのアップローダを立ち上げる

ftpd とアップローダには以下の Docker イメージを使っている。 pure-ftpd の Docker イメージはいくつかあるのだけど、Raspberry Pi の 32bit ARM 環境で利用したかったので、この pure-ftpd のイメージを利用。

  • https://github.com/rfgamaral/docker-gphotos-uploader
  • https://github.com/vgist/dockerfiles/tree/master/pure-ftpd

Docker Compose を使う

協調させて動かしてるので、Docker Compose で動かしている。 docker-compose.yml はこんな感じ。適宜必要に応じて変える必要があり。

version: '3'

services:
  gphotos-uploader:
    image: rfgamaral/gphotos-uploader
    container_name: gphotos-uploader
    volumes:
      - "/home/pi/ftp_uploads/gphoto-config:/config"
      - "/home/pi/ftp_uploads/photos:/photos"
    ports:
      - "29070:29070"
    environment:
      GPU_SCHEDULE: "*/3 * * * *"
    restart: unless-stopped
  pure-ftpd:
    image: gists/pure-ftpd
    container_name: pure-ftpd
    command: ['/usr/sbin/pure-ftpd', '-P', "192.168.24.12", '-p', "30000:30009", '-l', 'puredb:/etc/pureftpd/pureftpd.pdb', '-E', '-j', '-R', '-0']
    ports:
      - "10021:21"
      - "30000-30009:30000-30009"
    volumes:
      - "/home/pi/ftp_uploads/photos:/home/ftpuser"
      - "/home/pi/ftp_uploads/pureftpd:/etc/pureftpd"
      - "/home/pi/ftp_uploads/private-pem:/etc/ssl/private"
    restart: always

/home/pi/ftp_uploads が working dir なので適当に変えれば OK 。このままじゃ動かないので gphotos-uploader の設定を、ftp_uploads/gphoto-config/config.hjson に書いておく。Google Photos の API を使うために GCP のプロジェクト設定が必要なので、ドキュメントに沿って 行う必要がある。なお、OAuthのトークンはデスクトップ用を選択する。

 {
   SecretsBackendType: auto
   APIAppCredentials: {
    ClientID: "xxxxxxx"
    ClientSecret: "yyyyyyy"
   }
   jobs: [
     {
       account: xxx@gmail.com
       sourceFolder: "/photos"
       makeAlbums: {
         enabled: true
         use: folderName
       }
       deleteAfterUpload: true
       includePatterns: [ "*.jpg", "*.png", "*.jpeg", "*.JPG"]
       excludePatterns: [ "*ScreenShot*" ]
     }
   ]
 }

この設定では、makeAlumbs を有効化してあり、例えば photos/a7C/ 以下に置かれたファイルは a7C というアルバムに追加されるので便利。

$ docker-compose up -d
$ docker exec -it gphotos-uploader run
# リダイレクトで localhost を差してエラーになる場合、アクセスできるホスト名にする ( 192.168.24.12 とか)

これで gphotos-uploader はうまく動くはず。つづいて、pure-ftpd の設定。

docker exec -it pure-ftpd chown ftpuser:ftpuser -R /home/ftpuser
docker exec -it pure-ftpd pure-pw useradd {ユーザ名} -m -u ftpuser -d /home/ftpuser
# password を打ち込む
docker exec -it pure-ftpd pure-pw mkdb

これで、pure-ftpd もうまく動くようになったはず。

pure-ftpd の ftps 対応

ftp だとパスワードもデータも平文でやり取りされる。自宅など安全なネットワークでで完結している環境ならそれでも良いのだろうけど、信頼できないネットワークを通るので ftps (TLS対応) したい場合は、pure-ftpd の -Y オプションを使う。

  • https://download.pureftpd.org/pub/pure-ftpd/doc/README
  • https://download.pureftpd.org/pub/pure-ftpd/doc/README.TLS

'-Y 0': Disable the TLS encryption layer (default). '-Y 1': Accept both standard and encrypted sessions. '-Y 2': Refuse connections that aren't using TLS security mechanisms, including anonymous sessions. The server must have been compiled with --with-tls and a valid certificate must be in place to get this feature. See the README.TLS file for more info about TLS. '-Y 3': Cleartext sessions are refused and only TLS compatible clients are accepted. Clear data connections are also refused, so private data connections are enforced.

続けて指定する数値によって挙動が変わるのだけど、ftp も ftps も受けれ入れたいので 1 を使う。その場合、以下のように起動すればOK。

    command: ['/usr/sbin/pure-ftpd', '-P', "192.168.24.12", '-p', "30000:30009", '-l', 'puredb:/etc/pureftpd/pureftpd.pdb', '-E', '-j', '-R', '-0', '-Y', '1']

また、認証に使う証明書関連は /etc/ssl/private/pure-ftpd.pem が使われるので、そこに作れば OK。セキュアではない、いわゆるオレオレ証明書で良ければ、こんな感じで作れる。

openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout /home/pi/ftp-uploads/private-pem/pure-ftpd.pem -out /home/pi/ftp-uploads/private-pem/pure-ftpd.pem

ちゃんとLet's Encrypt を使ってpure-ftpd用の証明書を作る方法を書いている方も居て偉い。セキュアにやるならちゃんとやりましょう。

なお、ftp クライアント側の a7C には証明書エラーでも無視して接続するオプションもあって、まぁ現場では必要だろうなぁ…という感じがする。


ftp なんて15年ぐらい触ってなかったので寂れたプロトコル、なんて勝手に思っていてごめんよ。あと動作確認のため ffftp をすごく久しぶりに入れたのだけど、懐かしの UI なのだけど、機能追加・改善はOSSでされていてありがたや、というお気持ち。