Serve the dfx application front-end via HTTPS

If e.g. following the quick start guide, the application front-end is accessible as

http://127.0.0.1:8000/?canisterId=cxeji-wacaa-aaaaa-aaaaa-aaaaa-aaaaa-aaaaa-q

Accordingly sudo netstat -tnlp shows

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:36585         0.0.0.0:*               LISTEN      1228/replica
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      1224/dfx
tcp        0      0 0.0.0.0:37633           0.0.0.0:*               LISTEN      1228/replica
tcp6       0      0 :::37703                :::*                    LISTEN      1228/replica

Now it seems to be reasonable that users want to run the dfx process behind SSL/TLS. I understand this would require dfx to create an HTTPS server in addition to, or instead of, the HTTP server.

I guess that’s already supported, but couldn’t find anything in the documentation on how to configured this; please advise. Thanks.

You can easily set up ngnix as a reverse proxy that takes incoming https and forwards connection to dfx running on a localhost port.

1 Like

I understand, but the question was a slightly different one: If I would use plain webpack I could configure devServer to serve via HTTPS, does dfx not provide equivalent functionality?

1 Like

The lack of response seems to indicate that dfx indeed does not support HTTPS, which is somehow surprising given that the simple above mentioned application will fail with error TypeError: crypto.subtle is undefined when accessed from another machine via HTTP. The error is expected as HTTPS is required in order for the crypto module to work.

Anyone from Definity please: Can we make this a feature request? What HTTP server implementation does dfx use underneath? It can’t be that difficult to add HTTPS support.

No, dfx does not serve HTTPS. Its primary purpose is to serve a test environment where a browser can be pointed to a localhost URL. Plain HTTP is sufficient. What is your use case that must require HTTPS?

I had a use case where I want to serve a game canister on the public internet using dfx as backend, so setting up ngnix reverse proxy was sufficient and solved my problem.

Your previous suggestion to use a Ngnix as a reverse proxy of course works, but it is inconvenient for development.

In my development environment dfx runs in a bare-bone Linux container without a display server. The browser would run in another Linux container or on another physical machine. The physical machine and the host are in a different subnet, the containers share the same subnet but have different IP addresses, so accessing the dfx port via localhost does not work.

Don’t we use webpack for bundling assets which in turn comes with a devServer supporting HTTPS; dfx could be sensitive to such configuration? Besides, given that HTTP is discouraged, dfx should also support HTTPS in production mode.

Don’t we use webpack for bundling assets which in turn comes with a devServer supporting HTTPS; dfx could be sensitive to such configuration?

The short answer is “no”, pages are not served from webpack’s dev server.

The program (called “replica”) that dfx runs to serve the web site is actually the same thing that runs dfinity network. So the web pages, requests, responses etc. are all served by running the full stack (networking/consensus/execution/etc) on your local machine. Dfx runs a proxy to in order to serve bootstrap JS files so that developers can load and play with apps in their browsers, which has to be “localhost” to avoid potential CORS problems. This unfortunately means your setup cannot work. Even if you could get HTTPS, I think some code in the bootstrap JS file has to be changed to allow the domain name you use (at the moment I think it only allows ic0.app).

1 Like

So you are saying that from the netstat listing above one of the three replica processes serves the web pages and the one dfx process is simply a proxy process?

Domain names are not used in the setup; the listening processes are bound to 0.0.0.0 so they are accessible via all network interfaces by IP address; I’m not seeing any CORS problems, the sole problem of the setup seems the missing support of HTTPS, without it error TypeError: crypto.subtle is undefined can be observed when accessed from another machine via HTTP.