lessless

lessless

Hi,

I’m trying to set up client SSL validation with Google Cloud SQL, and things are not going well for multiple reasons.

First off, I was unable to get verify_peer mode working.

2022-08-02T18:42:38.029 app[7047257c] lhr [info] 18:42:38.028 [notice] TLS :client: In state :wait_cert at ssl_handshake.erl:2075 generated CLIENT ALERT: Fatal - Handshake Failure
2022-08-02T18:42:38.029 app[7047257c] lhr [info] - {:bad_cert, :hostname_check_failed}

I tried to add custom verify_fun: &:ssl_verify_hostname.verify_fun/3, through {:ssl_verify_fun, "~> 1.1"} but it falls over due to the bad arity:


2022-08-02T18:39:18.364 app[400cc581] lhr [info] 2022/08/02 18:39:18 listening on [fdaa:0:6924:a7b:276d:1:5d29:2]:22 (DNS: [fdaa::3]:53)
2022-08-02T18:39:20.347 app[400cc581] lhr [info] Reaped child process with pid: 567, exit code: 0
2022-08-02T18:39:23.215 app[400cc581] lhr [info] 18:39:23.214 [notice] TLS :client: In state :wait_cert at ssl_handshake.erl:362 generated CLIENT ALERT: Fatal - Internal Error
2022-08-02T18:39:23.215 app[400cc581] lhr [info] - {:unexpected_error,
2022-08-02T18:39:23.215 app[400cc581] lhr [info] {:badarity,
2022-08-02T18:39:23.215 app[400cc581] lhr [info] {&:ssl_verify_hostname.verify_fun/3, [[bad_cert: :hostname_check_failed]]}}}
2022-08-02T18:39:23.216 app[400cc581] lhr [info] 18:39:23.214 [notice] TLS :client: In state :wait_cert at ssl_handshake.erl:362 generated CLIENT ALERT: Fatal - Internal Error

so I ended up with verify: :verify_none, which works fine with OTP 24.

Next, upgrading to OTP 25 breaks things even further - with that, Ecto can’t find a client certificate.

2022-08-02T19:03:30.027 app[f5a13d3f] lhr [info] 19:03:30.027 [error] Postgrex.Protocol (#PID<0.1965.0>) failed to connect: ** (Postgrex.Error) FATAL 28000 (invalid_authorization_specification) connection requires a valid client certificate

My config:

 config :my_app, MyApp.Repo,
      ssl: true,
      ssl_opts: [
      verify: :verify_none,
        cacertfile: "/.../server-ca.pem",
        keyfile: "/.../client-key.pem",
        certfile: "/.../client-cert.pem"
      ]

Showing Posts 1 to 10

al2o3cr

al2o3cr

In a similar security posture, post a credit card number here to get faster debugging help :stuck_out_tongue:

The symptoms you’re describing make me wonder if Erlang has the right certs in its trust root.

lessless

lessless OP

I can drop a Monero wallet address if that counts :stuck_out_tongue_winking_eye:

Hm, maybe you’re right

I’ve assumed that self-signed certificate should be handled by cacertfile option.

dangdennis

dangdennis

I have the same issue attempting to run verification: verify_peer and cacert file with cockroachdb’s cacert. Have yet to determine actual solution. I suspect we share the same problem and are looking for the same solution.

voltone

voltone

There is some benefit to using TLS even with verify: :verify_none: a passive attacker who can only monitor, but not modify, network traffic will not be able to decode the traffic exchanged with the server.

Verification of the server certificate is necessary to protect against an active attacker. In a closed network environment like GCP some might argue that the risk of an active attacker is somewhat reduced, compared to connections that traverse the public internet.

If the server has a self-signed certificate, the certificate itself can’t be used to establish trust, in the same way that a CA-issued certificate can. But as long as the server continues to present the same certificate, or use the same key pair, you can ‘pin’ the certificate/public key and abort the connection if a different cert/key is used (which then requires manual verification to see if the change is legit or someone is trying to interfere).

The ssl_verify_fun package README has instructions on how to enable certificate or public key pinning. In Elixir that would look something like:

:ssl.connect('self-signed.badssl.com', 443,
  verify_fun: {&:ssl_verify_fingerprint.verify_fun/3, [check_fingerprint: {:sha, "36F81BA2C9B18032D8B7BC61B26F22F6086DAA95"}]},
  verify: :verify_none,
  reuse_sessions: false
)

(It doesn’t really matter here whether you pass verify: :verify_none or verify: :verify_peer - the verify_fun option overrides the default behaviors selected by that option anyway, but in recent OTP versions you’ll get a warning if you don’t set :verify option at all)

(Also note that you probably wouldn’t want to use reuse_sessions: false in production, but it is necessary while testing otherwise a full handshake may not be performed and your changes to the connection options won’t take effect, leading to surprising results)

dangdennis

dangdennis

Thank @voltone . I’ll try this. Great blog you got.

gesta

gesta

I’ve been able to fix this error, occurring when attempting to connect to a Google Cloud SQL instance by restricting the versions options in ssl_opts to [:"tlsv1.2"].
While debugging I noticed an initial handshake attempt over TLS v1.3, then downgrading to a handshake over TLS v1.2 and then an error being returned. After restricting to TLS v1.2 only, the initial handshake attempt is successful and a connection is established afterwards.
NB: Google Cloud SQL supports only TLS versions 1.0, 1.1 and 1.2.

lessless

lessless OP

Amazing, thanks for the shout out.

Are you using verify: :verify_peer with that?

nhpip

nhpip

Hitting the same problem with Amazon RDS. Will try your fix too.

gesta

gesta

Nope, I was able to make it work with verify: :verify_none, and :keyfile, cacertfile, certfile properly set.

kip

kip

ex_cldr Core Team

Are you on an OTP version less than 25?

In my libs (using the advice from @voltone) I’m configuring TLS 1.2 and 1.3 on OTP 25 and only 1.2 on earlier OTP versions. That seems to have stabilised this particular issue (not just on GCP, also on Github actions)

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
psy-q
I’m trying to set up Emacs with elixir-ls via lsp-mode and credo via Flycheck. This should mostly be preconfigured as Flycheck picks up c...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews