Secure Connection Failed

Hello

I have just deployed my phoenix app to linode server, and I can access it at port 80, however, I can’t access it using SSL.

I found this post useful: https://mythicalprogrammer.github.io/technology/webdev/elixir/phoenix/deployments/distillery/edeliver/2019/09/16/deploying-phoenix.html

however, I am not sure how to tackle this SSL issue??! as I have created a certificate my used domain using lets-encrypt

here is my settings

I have checked that the app is working at the desired ports:

$ sudo netstat -tulpn | grep LISTEN
tcp        0      0 0.0.0.0:41305           0.0.0.0:*               LISTEN      9442/ngspice_proxy. 
tcp        0      0 0.0.0.0:5355            0.0.0.0:*               LISTEN      423/systemd-resolve 
tcp        0      0 0.0.0.0:4369            0.0.0.0:*               LISTEN      1065/epmd           
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      423/systemd-resolve 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      424/sshd: /usr/bin/ 
tcp6       0      0 :::4000                 :::*                    LISTEN      9442/ngspice_proxy. 
tcp6       0      0 :::4001                 :::*                    LISTEN      9442/ngspice_proxy. 
tcp6       0      0 :::5355                 :::*                    LISTEN      423/systemd-resolve 
tcp6       0      0 :::4369                 :::*                    LISTEN      1065/epmd           
tcp6       0      0 :::22                   :::*                    LISTEN      424/sshd: /usr/bin/ 

https://ngspice.dcaclab.com/ would lead to browser error:

Secure Connection Failed

An error occurred during a connection to ngspice.dcaclab.com. PR_END_OF_FILE_ERROR

however, the http://ngspice.dcaclab.com/ works as expected.

Any idea?

I have no experience with linode, or with using ufw for port forwarding, but I have a feeling your issue may be related to IPv4 vs. IPV6:

Your application is listening on the IPv6 wildcard interface, as you can see in the netstat output. But your forwarding rules for port 80 and 443 are defined in /etc/ufw/before.rules, which defines firewall rules for IPv4.

I don’t know why port 80 is working, but I would start by removing the :inet6 configuration option in your phoenix endpoint (for both http and https) and see if that helps. If it does, we can always see what it would take to reenable IPv6 (DNS does not return any IPv6 address at this time for this host, though).

1 Like

Thanks @voltone, I’ve removed :inet6 as suggested:

config :ngspice_proxy, NgspiceProxyWeb.Endpoint,
       url: [scheme: "https", host: "ngspice.dcaclab.com", port: 443],
       http: [port: System.get_env("PORT") || 4000],
       https: [
           port: System.get_env("SPORT") || 4001,
           otp_app: :ngspice_proxy,
           cipher_suite: :strong,
           keyfile: System.get_env("SSL_KEY_FILE"),
           certfile: System.get_env("SSL_CERT_FILE"),
           cacertfile: System.get_env("SSL_CACERT_FILE"),
           dhfile: System.get_env("SSL_DHPARAM_FILE")
       ],
       cache_static_manifest: "priv/static/cache_manifest.json",
       server: true,
       code_reloader: false

then I created a new build and deploy a new release, but, I still have the same error in browser.

Hmm. Nothing in the logs? Can you connect locally, with curl -connect-to localhost:4001 -k https://ngspice.dcaclab.com/ or curl -connect-to [::1]:4001 -k https://ngspice.dcaclab.com/?

1 Like

where can I see the logs please?

$ curl -connect-to localhost:4001 -k https://ngspice.dcaclab.com/
curl: (56) Recv failure: Connection reset by peer
curl: (7) Failed to connect to ngspice.dcaclab.com port 443: Connection refused
$ curl -connect-to [::1]:4001 -k https://ngspice.dcaclab.com/
curl: (7) Failed to connect to ::1 port 4001: Connection refused
curl: (7) Failed to connect to ngspice.dcaclab.com port 443: Connection refused
$ curl -connect-to localhost:4000 -k http://ngspice.dcaclab.com/
<!DOCTYPE html>
<html lang="en">
.
.
curl: (7) Failed to connect to ngspice.dcaclab.com port 80: Connection refused

http://ngspice.dcaclab.com loads in browser, regardless of port 80: Connection refused above

maybe I shall include :ssl somehow in the project?

I have run the app at server without otp release, and I found the error:

[error] Failed to start Ranch listener NgspiceProxyWeb.Endpoint.HTTPS in :ranch_ssl:listen([cacerts: :..., key: :..., cert: :..., alpn_preferred_protocols: ["h2", "http/1.1"], next_protocols_advertised: ["h2", "http/1.1"], versions: [:"tlsv1.2"], ciphers: ['ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-ECDSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-ECDSA-AES128-GCM-SHA256', 'DHE-RSA-AES256-GCM-SHA384', 'DHE-RSA-AES128-GCM-SHA256'], eccs: [:secp256r1, :secp384r1, :secp521r1], honor_cipher_order: true, reuse_sessions: true, secure_renegotiate: true, port: 4001, keyfile: nil, certfile: nil, cacertfile: nil, dhfile: nil]) for reason {:options, {:certfile, nil}} (unknown POSIX error)

11:27:18.745 [info] Application ngspice_proxy exited: NgspiceProxy.Application.start(:normal, []) returned an error: shutdown: failed to start child: NgspiceProxyWeb.Endpoint
    ** (EXIT) shutdown: failed to start child: {:ranch_listener_sup, NgspiceProxyWeb.Endpoint.HTTPS}
        ** (EXIT) shutdown: failed to start child: :ranch_acceptors_sup
            ** (EXIT) {:listen_error, NgspiceProxyWeb.Endpoint.HTTPS, {:options, {:certfile, nil}}}
** (Mix) Could not start application ngspice_proxy: NgspiceProxy.Application.start(:normal, []) returned an error: shutdown: failed to start child: NgspiceProxyWeb.Endpoint
    ** (EXIT) shutdown: failed to start child: {:ranch_listener_sup, NgspiceProxyWeb.Endpoint.HTTPS}
        ** (EXIT) shutdown: failed to start child: :ranch_acceptors_sup
            ** (EXIT) {:listen_error, NgspiceProxyWeb.Endpoint.HTTPS, {:options, {:certfile, nil}}}

So your environment variables are resolved at compile time, but they are only set at runtime. There are a number of ways to handle that, depending on the tooling you’re using.

How did you decide this conclusion? by keyfile: nil, certfile: nil, cacertfile: nil, dhfile: nil ?
so, if I hard codded the paths rather than depending on env vars, might actually solve the issue…

I used edeliver to build at server… hmm I am note sure what to do…

What config file is that?

If it is not config/release.exs then the env cars will be read at compile time only.

I’m not familiar with edeliver, but it seems to use distillery, which does not use config/release.exs, does it? It has this page on runtime configuration, which may or may not be helpful.

As far as I know newer edeliver can do both.

Otherwise op needs to clarify which versions of elixir, edeliver and possibly distillery are used.

If it is distillery, I think using a config provider and not using config/*.exs might be most appropriate.

I have managed to start the server in prod mode, I have hard coded the run time env vars, as I am currently need to focus on the https it self, not run time configuration.

Now, when I start the phoenix server, it will start:

17:48:00.459 [info] Running NgspiceProxyWeb.Endpoint with cowboy 2.6.3 at 0.0.0.0:4000 (http)
17:48:00.480 [info] Running NgspiceProxyWeb.Endpoint with cowboy 2.6.3 at 0.0.0.0:4001 (https)
17:48:00.483 [info] Access NgspiceProxyWeb.Endpoint at https://ngspice.dcaclab.com

however, I still can’t access it with https, I have tried to debug using openssl and here is what I got!

openssl s_client -connect ngspice.dcaclab.com:443 -prexit 
CONNECTED(00000005)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 321 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 321 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)

Hi

Any advice about troubleshooting https protocol with phoenix? as I got successful feedback from lets-encrypt certificate creation.

Thanks

No TLS handshake appears to be taking place. If the connection does reach your application you should see errors in your logs. If nothing is logged, then it might be an issue with the port forwarding.

I have solved this issue by using nginx, where installing lets-encrypt easier.