Ubuntu 20.04上のcurlでftpサーバーへファイルをアップロードする
curl: (18) server did not report OK, got 451
curlでftpサーバーへファイルをアップロードするため、下記のようなスクリプトを書きました。
#!/bin/bash
set -eu
source './.env'
curl --show-error --silent \
--ftp-method 'nocwd' --ssl-reqd --insecure \
--user "${USERNAME}:${PASSWORD}" \
--upload-file 'test.zip' \
'ftp://ftp.example.com/data/'
Ubuntu 20.04上でスクリプトを実行したところ、下記のエラーが出てアップロードができませんでした。
curl: (18) server did not report OK, got 451
原因
curlの公式リポジトリのIssuesに上がっていました。
既知のバグだったようです。
上記test_1.sh
を実行したcurlのバージョンは下記の通りです。
$ curl --version
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets
このcurlはUbuntu 20.04上のapt install
でインストールしたもので、バージョンが古いことがわかりました。
もちろんapt update && apt upgrade
を実行しても、これ以上curlのバージョンは上がりません。
対処法
最新版のcurlをダウンロードして使用する
curlの公式サイトのダウンロードページを参照して、最新版のcurlをダウンロードします。
今回は下記のリポジトリからLinux x86_64のバイナリをダウンロードします。
せっかくなので、インストール済のバージョン7.68.0のcurlを使って、バージョン8.8.0のcurlをダウンロードします。
$ curl -sSfL \
> 'https://github.com/stunnel/static-curl/releases/download/8.8.0/curl-linux-x86_64-8.8.0.tar.xz' |
> tar -xvJ
curl
trurl
バージョン8.8.0のcurlをダウンロードできたことを確認します。
$ ./curl --version
curl 8.8.0 (x86_64-pc-linux-gnu) libcurl/8.8.0 OpenSSL/3.3.0 zlib/1.3.1 brotli/1.1.0 zstd/1.5.6 c-ares/1.28.1 libidn2/2.3.7 libpsl/0.21.5 libssh2/1.11.0 nghttp2/1.62.1 nghttp3/1.3.0
Release-Date: 2024-05-22
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Largefile libz NTLM PSL SSL threadsafe TLS-SRP TrackMemory UnixSockets zstd
下記のようなスクリプトを書いて実行したところ、無事にファイルをアップロードできました。
#!/bin/bash
set -eu
source './.env'
./curl --show-error --silent \
--ftp-method 'nocwd' --ssl-reqd --insecure \
--user "${USERNAME}:${PASSWORD}" \
--upload-file 'test.zip' \
'ftp://ftp.example.com/data/'
冒頭のtest_1.sh
との差分は下記のとおりです。
@@ -5,3 +5,3 @@
source './.env'
-curl --show-error --silent \
+./curl --show-error --silent \
--ftp-method 'nocwd' --ssl-reqd --insecure \
最新版のcurlをDockerで使用する
Dockerインストール済みの環境なら、curlの公式イメージから最新版のcurlを使用できます。
今回はバージョン8.8.0のイメージを使用します。
$ docker container run --rm 'quay.io/curl/curl:8.8.0' --version
curl 8.8.0 (x86_64-pc-linux-musl) libcurl/8.8.0 OpenSSL/3.1.5 zlib/1.3.1 brotli/1.1.0 libidn2/2.3.4 libpsl/0.21.2 libssh2/1.11.0 nghttp2/1.58.0
Release-Date: 2024-05-22
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets
下記のようなスクリプトを書いて実行したところ、無事にファイルをアップロードできました。
#!/bin/bash
set -eu
source './.env'
docker container run --rm \
--user "$(id -u):$(id -g)" \
--workdir '/work' \
--mount 'type=bind,source=.,target=/work' \
'quay.io/curl/curl:8.8.0' \
--show-error --silent \
--ftp-method 'nocwd' --ssl-reqd --insecure \
--user "${USERNAME}:${PASSWORD}" \
--upload-file 'test.zip' \
'ftp://ftp.example.com/data/'
冒頭のtest_1.sh
との差分は下記のとおりです。
@@ -5,3 +5,8 @@
source './.env'
-curl --show-error --silent \
+docker container run --rm \
+ --user "$(id -u):$(id -g)" \
+ --workdir '/work' \
+ --mount 'type=bind,source=.,target=/work' \
+ 'quay.io/curl/curl:8.8.0' \
+ --show-error --silent \
--ftp-method 'nocwd' --ssl-reqd --insecure \
Ubuntu 24.04にアップグレードする
おそらくこれが最善な対処法でしょう。
Ubuntu 20.04の標準サポート期限が2025年4月に迫っているので、時間ができたらアップグレードしたいです。
まとめ
この記事では、Ubuntu 20.04上のcurlでftpサーバーへファイルをアップロードできない問題とその対処法を紹介しました。
最新版のcurlをダウンロードして使用する、最新版のcurlをDockerで使用する、のいずれかで対処できます。
可能であれば、Ubuntu 24.04にアップグレードすることが最善な対処法でしょう。
Discussion