-
Notifications
You must be signed in to change notification settings - Fork 801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[UI] Relative Address for HealthCheckEndpoint with Kestrel at http://0.0.0.0:0 #410
Comments
I'm having the same issue as this, did you find a solution? |
i've got the same error in appsettings.json
|
@Genmutant @tidusjar @ildoc , What operative system are you using, are you specifying kestrel to use 0.0.0.0? When I configure relative uris my listening address is http://localhost:{port} |
I'm running my app from a linux docker container with all the kestrel default settings |
I'm running on Windows, but this will apply to all OS's that net core supports. You can repro this using my repo if you want, just pull the sln down (branch = |
0.0.0.0 or * for IPv4 represents kestrel listening on all ips, and [::] is the IpV6 equivalent. If the server addresses service receive something like: http://[::]:5000 it can't compose the final url. I recommend you to setup the listerning urls in the docker container: public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://localhost:5000")
.UseStartup<Startup>(); in 3.X: public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseUrls("http://localhost:5000");
webBuilder.UseStartup<Startup>();
}); |
@rynowak any idea how can we use the IServerAddressFeature from AspNetcore to compose fully qualified urls from a relative path when kestrel is listening to all ips in ipv4/ ipv6?. Thanks! |
There's no real way to do it without some guesswork. The problem is that the server doesn't know and doesn't care what hostname/ip the request arrives on 😆 Usually we avoid these problems in ASP.NET Core by using the hostname of the current request. That only helps if you have a request to use. You could use something like Or you could look at https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1#host-filtering which is something we recommend people use in production deployments. |
Thank you very much @rynowak :). As this feature allows relative urls for the local UI, the GetHostName trick might work!. |
@rynowak this is working with 0.0.0.0:0 and *:{port}. Whenever the IServerAddressFeature reported host name is not resolved as a dns name we resolve using Dns.GetHostname. Looks good? It resolves the dns hostname when hosts like [::], 0.0.0.0 are reported from the feature. internal string AbsoluteUriFromRelative(string relativeUrl)
{
var targetAddress = AddressesFeature.Addresses.First();
Uri.TryCreate(targetAddress, UriKind.Absolute, out var original);
if (targetAddress.EndsWith("/"))
{
targetAddress = targetAddress[0..^1];
}
if (!relativeUrl.StartsWith("/"))
{
relativeUrl = $"/{relativeUrl}";
}
var hostCheck = Uri.CheckHostName(original.DnsSafeHost);
if(hostCheck != UriHostNameType.Dns)
{
targetAddress = $"{original.Scheme}://{Dns.GetHostName()}:{original.Port}";
}
return $"{targetAddress}{relativeUrl}";
} |
The code looks fine. The only concern that I'd have is that techniques like this aren't foolproof - there is no solution that is. Consider what would happen if this were deployed to k8s. Someone navigates to Again, there's no foolproof method you can use here without making the user configure it. You have to know what DNS names are in use by all of your clients - this isn't information the server can guess. |
Would it be better just using DNS names in kestrel configuration? I always configure apps to localhost and never found this problem before but based on the feedback in this issue it looks like there are several people listening on all ips. |
What would this entail? Does that mean that the server has to The simple/safe thing to do is have the user configure the value. If you try to auto-configure it, I think you'll always run into cases that don't work "as expected" for someone/some configuration. Running nslookup yourself and using the results might be the closest you can come, but it sounds pretty complex (you have to list all of the IPs, then look them all up, then figure out which of the many hostnames it might return should be used). I think it's fine to do your best, just keep in mind that there will always be cases you can't address. |
@ildoc @tidusjar @Genmutant , based on @rynowak feedback, I suppose the best think you can do is configuring the listening ip / dns name in Kestrel and problem resolved. If you are using a docker image setting the listening address to localhost fixes the problem. I agree this change "works", but might open new problems in then future while configuring the host ip / dns name is straightforward |
What if we use this: Host = Host.Replace("0.0.0.0", "localhost"); ? |
@CarlosLanderas 👍 |
My workaround for the moment was not by changing the kestrel listening address but by mapping the health checks to absolute URLs using localhost such as:
Obviously the above only works if the app is running in port 80, if not you also need to specify the port in the absolute URL. Not sure if there's something messed up with my docker compose project in Visual Studio but no matter what I tried I couldn't get the proposed solution from @CarlosLanderas to get this to work by keeping relative URLs and doing something like:
I would also appreciate some sample to understand how to run in docker/docker compose. |
@edumserrano @CarlosLanderas |
I didn't find any solution. I just use an absolute url. |
What about my previous suggestion? |
@edumserrano |
I ran into this same problem today, and here's the solution I came up with. Basically, I create an extension method on
Now, when I build my
It would also be possible to combine In my case, I'm adding a healthcheck for the first HTTP binding and the first HTTPS binding found, but your situation might be different and you can adjust the code. Hope this helps someone! |
@MikeChristensen Thank you very much,I modified the regular expression
|
Hi, I've been trying so many things to fix this issues. Ultimately, im trying to deploy on Azure WebApp for Linux Container, but for now i cant get it to work even on my local machine. Everything work except this. I tried settings env variable with urls: "http://localhost:80;https://localhost:443", but then even the index break. I tried to set absolute address on health endpoint, but without success. I changed Kestrel UseUrls to localhost, without success. Any tips ? |
Has anybody resolved this issue, I'm getting the same problems. |
Hi Everyone, |
To workaround the problem in containers you have to specify a single IP address for listening instead all k8s:Use downward API to get container IP (
docker-compose:you can use same trick but instead of using API you can use just linux
you have to overide entrypoint to invoke shell script from command A Hope it will help :) |
The whole UI feature is unusable when using Kestrel with a dynamic port. If HealthChecks.UI.Configuration.Settings allowed me to provide the BaseAddress for the HttpClient with a delegate which supplies the IServiceProvider I could dynamically add the port before each request. Why does the port need to be known upfront? BTW it looks like ConfigureApiEndpointHttpclient should do this however changing the BaseAddress does nothing. Fundamentally doing a replace on 0.0.0.0 to 127.0.0.1 fixes the issue for me:
|
i had the same problem. Can you share an example so I can solve it? |
I've forked the repo with the required change https://github.com/RyanSearle/AspNetCore.Diagnostics.HealthChecks. You'll just need to build it and use the package. Alternatily look at the first commit and make the change yourself. |
Why is this ticket closed, when the solution to this is as simple as visible in the fork? Is there something else to consider with this fix? |
Well my solution makes the assumption that the endpoint it calls is local when the address is found to be 0.0.0.0. Technically 0.0.0.0 is a valid IP address and we are overriding that. Optimal solution would be to make this configurable so as to not make any assumptions about how this is being used. |
Are there any other use-cases to use the loop-back address that I am not aware of? AFAIK it can always only be localhost but I might be wrong here as well :) |
So 127.0.0.1 will always be the loopback address and machines tend to resolve localhost to it. The problem is that 0.0.0.0 could be used for other purposes by other systems so that's where the problem is. |
Could we put a config for this? |
this solution works for me: replace |
Devs, "HealthChecksUI": { Happy Coding! |
Please see #1593 (comment) . If after the publication of the v7 release you will still observe problems, then please open new issue. |
@sungam3r This is unfortunately still an issue for us out of the box, with our Linux deployment. |
Still the issue in V7.0.2To reproduce the issue:
LOGS:
|
If you have Docker profile in your launchSettings.json file like;
just add endpoint like that;
The backend api service of HealthCheckUI, which gets the data from the target, is already running inside the docker. Therefore, when localhost is used as the address, the code will work because the request will go to the docker container that contains it. |
I'm having the same problem. Below is my code: services.AddHealthChecksUI(settings =>
{
settings.AddHealthCheckEndpoint("feedback api", "/api/health");
//other settings...
})
.AddInMemoryStorage(); |
I accept @alexespejoch's solution, which requires only a little bit of additional configuration items (albeit with a little bit of hassle). |
I'm trying to bind HealthCheckEndpoint using the relative address;
but because it is configured to use http://0.0.0.0:0 in Kestrel, it throws an exception. I'm not hard set on using automatic port selection, though it is nice for testing. It throws the same exception when using a specific port, though.
The text was updated successfully, but these errors were encountered: