14
votes

I have a site built with Elixir Phoenix frame work. The website runs fine in both dev and prod mode.

When the phoenix server is running in dev mode, I have no issue renewingLet's Encrypt certificate, but when the exact same app is running in prod mode, I keep getting permission error when trying to renew. Please noted that I am talking about the exact same app, on the same FreeBSD server, executed by the same user - both command without sudo. The only difference is MIX_ENV=prod

I also noted that in prod mode, the phoenix server log an 404 error when Letsencrypt is trying to access my priv/static/.well-known/acme-challenge/(some-unique-string) My basic set up for phoenix + letsencrypt is detailed in this blog post

The question is: how is phoenix server treating directory/file permission differently between `prod' and 'dev' mode?

  • Using Elixir 1.2.4 and Phoenix 1.1.4

UPDATE:

Folks, since LetsEncrypt and Phoenix framework evolve rapidly, the issue I listed above is no longer an issue if you are using the latest cerbot from LetsEncrypt and Phoenix 1.2.0

This is not necessary an answer to the original questions though.

1
Phoenix doesn't treat permissions differently. Check what files you can't access. My guess is that there is a difference in configs between prod and dev. For example one of the file paths is misspelled. - tkowal
@tkowal For Let's Encrypt to work, I do not need any configuration in "dev.exs" vs "prod.exs". There is a folder under /priv/static/.well-known that Let's encrypt need access to. When I am running in prod mode, Let's Encrypt can not access it. What is funny is that I run the server in dev mode to update my Let's Encrypt cert, then run it in prod mode. The prod mode is serving the proper updated Let's Encrypt cert that I got through using dev mode. In short, Phoenix server can serve the cert just fine but does NOT allow let's encrypt to update it somehow when in prod mode! - yial2
What are the permissions and owners of this file? Can you post ls -al output on this file? - tkowal
I'm working on the same issue from the same article and I'm currently having the same experience. I noticed that when I run the server in dev with my prod.exs renamed to dev.exs certbot is successful, and the logger is quiet. When I run it in prod with the prod.exs properly named the router logs a GET request for /.well-known/acme-challenge/random_file_name does anyone know about a default config option on the router when the env is set to prod or is this a non-issue? - brittonjb
I've said, I would add some value to this discussion when I did my own researches, the file approach did't work for me, also, but I've managed it with a route.. check out my answer guys - webdeb

1 Answers

2
votes

I've solved it, by using a route, instead of file:

scope "/.well-known", MyApp do
   get "/acme-challenge/:challenge", AcmeChallengeController, :show
end

And a simple controller..

defmodule AcmeChallengeController do
   use MyApp, :controller

   def show(conn, %{"challenge" => "the_random_file_name"}) do
      send_resp(conn, 200, "TheHashInTheFile")
   end

   def show(conn, _) do
      send_resp(conn, 200, "Not valid")
   end
end

This is hardcoded, compiled and faster then sending files, but, it would be also possible to use some kind of key/value store, and manage (add/delete) the the challenges from within the UI without re-deployment.