それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

apt-cacher をnginxの後ろに置こうとしてハマる

apt-cacher を443 でnginxの後ろに置こうとした。

動かない。

ログを見た。

10.10.1.240 - - [17/Mar/2023:17:45:20 +0900] "CONNECT esm.ubuntu.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:20 +0900] "CONNECT esm.ubuntu.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:20 +0900] "CONNECT download.docker.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:21 +0900] "CONNECT esm.ubuntu.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:21 +0900] "CONNECT esm.ubuntu.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:22 +0900] "CONNECT download.docker.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:23 +0900] "CONNECT esm.ubuntu.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:23 +0900] "CONNECT esm.ubuntu.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:26 +0900] "CONNECT download.docker.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:27 +0900] "CONNECT esm.ubuntu.com:443 HTTP/1.1" 400 166 "-" "-"
10.10.1.240 - - [17/Mar/2023:17:45:27 +0900] "CONNECT esm.ubuntu.com:443 HTTP/1.1" 400 166 "-" "-"

CONNECTじゃん。nginxでは対応できない。

そうだよね。冷静に考えたらリバプロではく、フォワード・プロキシになるので、CONNECTが必要だよね。CONNECTなど素のnginxで動くはずもないので諦める方がいい。

nginx で Connect できなくても stream で流せば良いんでしょ?

nginxをプロキシで使ってるとついつい次のような発想になりがち

nginxでTCPさばきました

stream で流すって単なるNAT(SNAT+DNAT)じゃん?

それ、iptablesのDNATでやったほうが良いよ。

nginxだと、SNATと同等になるので接続ログの管理がめんどくさいいと思います。

素のTCPしかしゃべらないプロトコルを強引にSSL化するSSLアクセラレータとしてTCPをSTREMする場合は、次のようになるので、この場合はiptablesよりnginxに理由があるのですが、streamでTCPを捌くだけの記事を読んでいてiptablesがめんどくさいんだろうなわかる、とおもいつつもnginxでやる意味・・・とモヤッとした。

stream{
  upstream apt-cacher {
    server my_service:8000;
  }
  map $target $name{
    example.tld apt-cacher
    default 127.0.0.1:443
  }

  server {
    listen  127.0.0.2:443 ssl;
    proxy_pass $name;
    ssl_preread on;
    ssl_certificate     /var//certs/nginx/cert.pem;
    ssl_certificate_key /var//certs/nginx/key.pem;

    proxy_connect_timeout 1s;
    proxy_timeout 3s;
  }
}

上記のように平文通信の間にnginxを挟み込んで、TLS化するのはありだと思った。

stream mapを使ってALPNホスト名ごとに接続先を変えるのは便利だと思う。

apt-cacher で試したが、httpsのaptではうまく動かなかった。

参考資料

https://stackoverflow.com/questions/34741571/nginx-tcp-forwarding-based-on-hostname