Unable to download - Unknown CA
I was trying to get esbuild installed in our Phoenix project, but ran into the following error:
> mix esbuild.install
19:39:04.401 [debug] Downloading esbuild from https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.10.tgz
19:39:04.570 [info] TLS :client: In state :certify at ssl_handshake.erl:1895 generated CLIENT ALERT: Fatal - Unknown CA
** (RuntimeError) couldn't fetch https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.10.tgz: {:error, {:failed_connect, [{:to_address, {'registry.npmjs.org', 443}}, {:inet, [:inet], {:tls_alert, {:unknown_ca, 'TLS client: In state certify at ssl_handshake.erl:1895 generated CLIENT ALERT: Fatal - Unknown CA\n'}}}]}}
lib/esbuild.ex:282: Esbuild.fetch_body!/1
lib/esbuild.ex:200: Esbuild.install/0
(mix 1.12.1) lib/mix/task.ex:394: anonymous fn/3 in Mix.Task.run_task/3
(mix 1.12.1) lib/mix/cli.ex:84: Mix.CLI.run_task/2
Our company uses a MitM firewall application (yay 🙄 ), so we need to specify our own certificate bundle when making outbound requests. I was able to work around this by adding my own :cacertfile config parameter (and setting it appropriately):
config :esbuild,
version: "0.13.10",
default: [
args: ~w(js/phoenix.js),
cd: Path.expand("../assets", __DIR__)
],
ssl: [cacertfile: "/etc/ssl/certs/ca-bundle.crt"]
And then edited lib/esbuild.ex with the following in place of esbuild.ex:#L266-L275:
default_ssl_options = [
verify: :verify_peer,
cacertfile: cacertfile,
depth: 2,
customize_hostname_check: [
match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
]
]
ssl_options = Keyword.merge(default_ssl_options, Application.get_env(:esbuild, :ssl, []))
http_options = [ssl: ssl_options]
Is this configuration something that could be included in the project? I'd be happy to submit this as a PR and address review comments.
Let me know if you need any more details.
@ngeraedts a PR to add ssl customization is welcome. If you prefer, you can also install it manually via the steps here: https://github.com/phoenixframework/esbuild/blob/main/lib/esbuild.ex#L28 - your call!
Can confirm that the code snippet still works because I ran into the same problem.
There's a slight chicken-and-egg bootstrapping problem though because I also have to add the cacertfile item to this project's config/config.exs or I can't even run mix test, so maybe going a route like HEX_CACERTS_PATH (maybe alternatively, but which takes precedence) makes sense?
With the latest version of Phoenix I did the following in dev.exs to supply a custom CA cert
config :esbuild,
cacerts_path: "/path/to/ca/cert/file.pem"
Just ran into this issue - with the introduction of tailwind, I had to add a line in for that one as well. So, with the rebuild config line that @meadoch1 described, it looks like this:
config :esbuild, cacerts_path: "/path/to/ca/cert/file.pem"
config :tailwind, cacerts_path: "/path/to/ca/cert/file.pem"
In my case, I needed to point to some Netskope MITM certs provided by my company. Im wondering if there are any global settings so it doesn't have to be specified multiple times.