[App Server] Switched Over To HTTPS - Odd Page From Anvil Server

What I’m trying to do:
Move from HTTP to HTTPS implementation of an Anvil app using the open source Anvil server.

What I’ve tried and what’s not working:
Had my IT department generate a SSL certificate.
Successfully installed the SSL certificate.
Reconfigured IIS to manage HTTPS and appropriately direct requests to the anvil server.
https addressed requests result in an odd page that has nothing I have developed on it (see image).
http addressed requests still provide a good page from the anvil application (expected result).

I researched the HTTPS topic in the Anvil Docs and this forum. I found and tried this:
anvil-app-server --app MyApp --origin https://mydomain.example.com
But when I run it I get an error, which makes sense because the domain I am using is a corporate one and we issue our own SSL Certificates:
time="2021-01-28T19:29:53-05:00" level=error msg="Unable to obtain ACME certificate for domains \"XXXX.XXXX.XXXX.com\" : unable to generate a certificate for the domains [bidmanagement.dsone.3ds.com]: acme: Error -> One or more domains had a problem:\n[XXXX.XXXX.XXXX.com] failed to initiate challenge: acme: error: 400 :: POST :: https://acme-v02.api.letsencrypt.org/acme/chall-v3/10434847087/xvz4cg :: urn:ietf:params:acme:error:malformed :: Unable to update challenge :: authorization must be pending, url: \n" providerName=letsEncrypt.acme

So I think the question is, “What is the trick to getting anvil.server to run apps behind a corporate firewall using a privately issued SSL certificate?

It took me a while to figure this out on my own deployment. Assuming you have your certificate and key in your app directory, you should add this to your config-file.yml:

manual-cert-file: "certificate.crt"
manual-cert-key-file: "private.key"

You could also pass them as arguments to your launch command if you wanted and leave them out of your config file.

1 Like

Thanks Robert, I’ll give this a shot tomorrow bd provide feedback!

To add to what has already been suggested. If you are using a reverse proxy (IIS, nginx, etc) in front of anvil app server and the reverse proxy is handling the TLS termination, you should use the --disable-tls option and also --port 3030 as --origin will override the default.

Hi to both, I implemented both of your suggestions individually and together and I still get the same result. I went back to my corporate IT and had them re-issue a new certificate and then create .pem (certification) and .pfx (private key) files and put them into the application directory. Then I restarted the anvil server passing the variables for the cert & key file, no change in application behavior. So I then did the same with the --disable-tls option also included and once again, no change in application behavior.

Any other ideas?

Oh I totally forgot to mention the existing Let’s Encrypt cert. If the Let’s Encrypt certificate json file is still in the data directory it seems to use that first and ignores your config. So you should delete that json file. It should be at:

.anvil-data/letsencrypt-certs.json

The anvil data folder is located one level up from the app code by default. I think I launched and closed the app at least 100 times trying to get everything right.

Hi Robert,

Sounds like a good lead. I looked around my Python install directories and in the application directories where I have my Anvil apps running from and I can’t find a anvil-data or letsencrypt-certs.json

Sorry to ask a dumb question, but do you know where they would be in a default installation?

What OS is the app on? On Linux it’s a “hidden” folder starting with a period.

Try looking up one directory from your app code.

PROGRESS!

I found the .anvil-data folder (on MS Windows), it was under the user’s folder C:\Users\XXX.anvil-data\ and as promised there was “letsencrypt-cert.json”. I removed that file and tried running Anvil again using a variety of different settings (–manual-cert-file, --manual-cert-key-file & --disable-tls) but I got identical behavior to that before. When connecting via HTTP I get the unsecured notification from the browser, but my application displays properly. When connecting via HTTPS I get a secure connection using the correct certificate BUT I get the odd page (per image from previous post).

Any other creative suggesions?

I had to fiddle with the path strings for the certificate and key until it worked. I also tried a few different directories. Try with single quotes, double quotes, and no quotes.

I had this same issue myself and changed so many things back and forth. Could you post your config and run command (obviously obfuscate anything sensitive)?

I cannot see an image in the original post. Can you provide another screenshot?

After coming back to this I think you are having the same issue I had. I have no idea if this is the recommended way to solve things, but this is what I did with my config to get SSL working. In my config file I did this:

origin: "https://my_domain.mn:443"
origin: "https://www.my_domain.mn:443"
http-redirect-port: 80

I bound the origin port to 443 for SSL, then the http-redirect-port redirects traffic from 80 to SSL (which is always 443). Per the docs:

--http-redirect-port PORT - Redirect HTTP requests on the specified port to HTTPS

You should also include the certificate and key arguments for your config as well.

From the larger perspective, I have no idea why connections aren’t automatically redirected to SSL if available. I’m guessing it has to do with their web server (Java based Traefik). Both Apache and Nginx have to also manually configured to do SSL redirection. Although the lovely Let’s Encrypt bots can do that for you automagically now.