5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Dockerのhttp_proxyで詰まった話

Last updated at Posted at 2021-04-15

概要

proxy環境下でdockerを使うために設定をしていたとき、http_proxy,https_proxyがどうしても上手く読み込めてなかったので何をして何が原因で何をしたのかをここに残す。

設定時

DockerはLinuxシステムの環境変数にあるhttp_proxyhttps_proxyとは別に、専用のproxy設定を施す必要がある。
なのでこのサイトを参考に設定をした。
そのときのconfファイルの設定内容はこんな感じ。(実際の接続先URLは載せるわけにはいかないので、例として架空のurlを用いる)

/etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://aaaa:admin!@example.ad.jp:8080"

のように書き込んだ。
これでdocker pull イメージ名を実行したところ以下のようなエラーが出力された。

Error response from daemon: Get https://registry-1.docker.io/v2/: proxyconnect tcp: dial tcp: lookup https on xxx.xxx.xxx.xxx:xx: no such host

解決策

http://aaaa:admin!@example.ad.jp:8080!をURLエンコードしてやればよい。
どうやらLinuxにおいて!(エクスクラメーションマーク)は特別な意味を持つ記号で、通常の'(シングルクォーテーション)を用いたエスケープが効かないそうだ。

¥(円マーク)でエスケープはできたがURLにそのまま残ってしまう↓

http://aaaa:admin¥!@example.ad.jp:8080

↑この場合PWの一部として円マークが認識されてしまう
※参考ページ: bashに !' で event no found と怒られた理由を考えてみる - https://qiita.com/Qutjl/items/6e0056853c94011d245b

URLなので%21のようにエンコードすればどうにかなるんじゃねと思い、やってみたところできてたっぽい
(この時上記に関係ないエラーが発生して、それを勘違いして最初はこの方法でもできてないと思った)
↓URLエンコードバージョン

/etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://aaaa:admin%21@example.ad.jp:8080"

ちなみにdocker infoを実行することでDockerに関する情報が出力される。先ほどのProxy設定情報も出力される。

[root@hogehoge ~]# docker info
~中略~
HTTP Proxy: http://xxxxx:xxxxx@example.ad.jp:8080
HTTPS Proxy: https://xxxxx:xxxxx@example.ad.jp:8080
~中略~

エスケープしても上のようにusername@passwordが伏字になってしまうことがある。
しかしsystemctl show docker --property EnvironmentでProxy設定情報を確認すると

Environment=HTTP_PROXY=http://aaaa:admin%21@example.ad.jp:8080 HTTPS_PROXY=https://aaaa:admin%21@example.ad.jp:8080

このようにエクスクラメーションマークがエスケープされて登録されていることがわかる。
なぜ伏字になるのかは不明。

余談

上にも書いたが、URLエンコードで対応してもエラーが発生した。このエラーは以下のようなものだった

Get https://registry-1.docker.io/v2/: proxyconnect tcp: tls: first record does not look like a TLS handshake

上手くTLSのコネクションがはれていないのかなと思いググってみた。
すると以下のページに答えが載っていた。
VagrantをProxy経由で利用する - https://qiita.com/daichannel/items/08e074a01e8ab41d52f7#docker

単純にHTTPS_PROXYに設定するURLのスキームをhttpにすれば良いだけだった。
(なぜhttpsではダメなのかは不明。これでいいのか感が否めない・・・)

/etc/systemd/system/docker.service.d/https-proxy.conf
[Service]
Environment="HTTPS_PROXY=http://aaaa:admin%21@example.ad.jp:8080"

余談2

今回は通常のURLエンコードでどうにかなったが、場合によっては%を2回続けないと反映されないらしい。
上記のhttps-proxy.confを例にすると

/etc/systemd/system/docker.service.d/https-proxy.conf
[Service]
Environment="HTTPS_PROXY=http://aaaa:admin%%21@example.ad.jp:8080"

このようにエクスクラメーションマークを変換する際は%%21と%を2回続けると上手くいくこともあるらしい。
どうやらsystemctlでは**%ダブル**で$%などの特殊文字をエスケープしているらしい(?)

参考ページ:https://forums.docker.com/t/proxy-settings-do-not-work-for-either-etc-default-docker-or-systemd-drop-ins/68891/17

結論

systemctlのconfファイルに用いる!はLinuxにおける通常のエスケープ方法が効かないことがわかった。
Linuxシステムにおいて!は扱いが特殊なので、そもそもURLなどに混ぜるべきではないと思った。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?