Sorc96
I’ve encountered an issue with VerifiedRoutes.url when the application is running behind nginx. I need to send a link via e-mail, so I generate the url with url(~p/some_path/), which returns http://myapp.com:5000/some_path, since the endpoint itself is using http and the port is set to 5000. Of course, what I actually need is https://myapp.com/some_path
I have nginx configured to send the X-Forwarded-For header, so the application knows the actual address that is visible to users. Is there an easy way to make url use this information instead of the endpoint config? Or should I make a custom helper instead?
Trending in Questions
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
New
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
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
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
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
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
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
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
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
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
garrison
The URL generation is controlled by the Endpoint configuration (specifically the
:urloption). The value is configured in runtime.exs by default. This option only controls URL generation (for links in the app), it does not configure the webserver (that’s the:httpoption right below it).I’m assuming from your post that you changed it thinking it was the webserver configuration, so if that’s the case changing it back to the default should resolve the problem
(Also: If this is the case, the links in your app should all be wrong too, right?)
For the record, you could also pass a few other things into
url/2if you needed to, like aconn/socket, a different endpoint, or a URI. But I don’t think that’s what you need here.Not sure I understand what you mean here.
X-Forwarded-Forcontains the original client IP address(es) from the original request (and any proxies in between). The host/port are sent via the Host header, which I assume Nginx just passes along in the proxied request.Either way, by default the URL generation is controlled by the Endpoint config.
Sorc96
Thanks, it seems there are a few options I have mixed together that mean different things and I need to sort them out.
ibarch
I haven’t tested it myself, but I guess that if you configure Nginx to pass the
x-forwarded-portheader, and apply Plug.RewriteOn plug in the endpoint, the url helpers will generate links with the appropriate port(s).Sorc96
So I think the confusion has been explained. The
schemeoption worked as expected, but it seems that theportfrom thehttpconfig gets used for url generation as well, so I had to explicitly set it to 443. Thanks for the help, this is what the config looks like in case anyone else gets confused:Also, to explain why I never noticed it from links in the application itself, it’s because they only need
~punlike links in e-mails, which need the full url, so the incorrect options never manifested.voltone
This configuration might fix the generated URLs, but it does not solve the underlying issue that Phoenix does not know that the server was actually reached via HTTPS. As a result, certain security features are not enabled. In particular, (session) cookies do not get the
secureoption that is meant to prevent them from leaking in plaintext HTTP requests.For more details, see TLS Vulnerabilities | EEF Security WG
The better solution is the use of HTTP headers to pass the external scheme and port from the reverse proxy to the application, as suggested by @ibarch
garrison
Interesting, I was unaware of
It’s funny that reverse proxies don’t just pass along the original
X-Forwarded-Host/Port. That would explain my confusion regardingX-Forwarded-Forin the OPHostheader - obviously in the case of the IP address that’s impossible, but the header could be forwarded just fine. Maybe it’s just done this way for consistency?Is this mentioned anywhere in the Phoenix docs? I would think it should be brought up in the deployment guides, i.e. the
Fly.ioone which would sit behind Fly’s reverse proxy, but I see no mention of it. The Plug.SSL docs are the most I see about it. The defaultruntime.exsdoes have a line suggesting that you enableHSTS.It seems to me like enablingHSTSwould also resolve the issue, correct? The client can’t send cookies over HTTP if it’s not allowed to make insecure requests at all. Obviously this is not an option if you intend to actually serve insecure traffic, but that’s not common anymore.So if that’s the case, either (or both) of these would suffice:Edit: the above is NOT correct, see replies below. You always need
:rewrite_onbehind a reverse proxy:Am I missing anything?
LostKobrakai
Either is not enough. Enabling HSTS would only surface that you’re missing the former, but it wouldn’t enable them.
garrison
I was surprised to read this, but after checking the code I see that you’re correct - the HSTS header is only added if scheme is :https. Indeed, this is also the second line in the docs (hah) which I did not read because I only scanned the options section to see what was accepted by the Endpoint config
This was not intuitive to me because I figured you could technically force HSTS over HTTP, but apparently the browser spec says to ignore
strict-transport-securityover http, so that’s probably why Plug doesn’t send it. Perhaps it would be safer to send it anyway in case the user has misconfigured their reverse proxy setup? I don’t see how it could hurt. (Edit: This would be pointless because forcing SSL would just create a redirect loop anyway, since Plug still doesn’t know the proxy terminated TLS.) I suppose this is really what HSTS preload is for.I will update my previous comment just in case someone stumbles upon it. Thanks!
Also, I found the relevant part of the Phoenix documentation that I was looking for earlier:
I feel like this should be mentioned in all of the deployment guides, but I only see it linked in the Gigalixir/Heroku guides (the ones I didn’t check before, of course). I would think the Fly guide at least should also mention SSL.
Sorc96
I’m glad by original question uncovered something interesting. Yes, the
X-Forwarded-Forheader was wrong,X-Forwarded-Hostis the correct one, along withportandproto.I’ve configured
rewrite_onto use all three headers and made sure nginx was setting them properly. Thanks for your interest, everyone.garrison
I came across a couple things today which I figured I should post here for the sake of completeness.
First, Caddy actually does pass along the original Host header by default like I had thought before, though it of course also sets
X-Forwarded-*. Nginx, on the other hand rewrites the header by default.Second, there is actually a case where you do need to rewrite the
Hostheader: if you are using HTTPS to encrypt traffic between the reverse proxy and your webserver, you need to set theHostto match the cert! In this case you would be forced to rely onX-Forwarded-Hostto know the real host.