Dokku - get ip address of nginx reverse proxy inside container? - nginx

In my ASP.NET Core server, I've have forwarding to support my OpenId Connect authentication workflow:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedFor;
// Only loopback proxies are allowed by default.
// Clear that restriction because forwarders are enabled by explicit
// configuration.
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
}
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
}
However, I'd like to configure KnownProxies (and KnownNetworks). Is there a way to find out the ip address of the proxy server (within the context of a container)? Is the configuration static? If not, can it be automated?
Also, is this address going to be the same thing as the Host address. I.e. would resolving the ip address to host.docker.internal help? Which doesn't seem to be an easy thing to do within a Linux environment anyway...
Also, the above code comes from this documentation. Re-reading that section, is it okay to leave the above code alone? I'm assuming that locking down to a particular proxy server would be better?

The container IP is ephemeral, and may change across app rebuilds or redeploys. By default, Dokku will run your app on the internal docker0 network, and the only things that can access the container are services running on the server itself, so allowing access from all network interfaces is safe.

Related

How to selfhost .net core 3.1 web api

Can any one suggest with example how to selfhost core web API without IIS. I have hosted in the IIS but i want to perfome self hosting and also i want to enable HTTPS for the selfhost web API
To Self host web api you should refer to official documentation
To enable https
On an elevated console (“Run as administrator”), execute
netsh http add urlacl url=https://+:4443/ user=<your user name>
to allow the running user to listen on port 4443 using HTTPS (note the use of https instead of http in the above command).
Also on an elevated console, register the server certificate by running
netsh http add sslcert ipport=0.0.0.0:port certhash=thumbprint appid={
app-guid
}
where,
port is the listening port (e.g. 4443); the special IP address 0.0.0.0 matches any IP address for the local machine;
thumbprint is the certificate’s SHA-1 hash, represented in hexadecimal;
app-guid is any GUID (e.g. {00000000-0000-0000-0000-000000000000}) , used to identity the owning application.
Write self host configuration like
class MyHttpsSelfHostConfiguration : HttpSelfHostConfiguration
{
public MyHttpsSelfHostConfiguration(string baseAddress): base(baseAddress){}
public MyHttpsSelfHostConfiguration(Uri baseAddress) : base(baseAddress){}
protected override BindingParameterCollection OnConfigureBinding(HttpBinding httpBinding)
{
httpBinding.Security.Mode = HttpBindingSecurityMode.Transport;
return base.OnConfigureBinding(httpBinding);
}
}
then Change the base address passed to the MyHttpsSelfHostConfiguration constructor: var config = new MyHttpsSelfHostConfiguration(“https://localhost:4443”);

Nginx redirect not working on public IP

I do have a complex scenerio. I have two AWS instances.
Instance 1: Running Nginx (have 1 private IP, 1 public IP)
Instance 2: Running Nodejs server (have 1 Private IP only, NO PUBLIC IP)
Here is what I am trying to do. I have a redirect setting in my nginx config which forwards the requrest for a particular URL to Instance 2.
It works fine when I try browsing from http://Instance 1's private IP, but it does not work if I try by browsing from http://Instance 1's public IP.
I am using nginx reverse proxy setting. It works great when URL is browsed via private IPs but does not when it is browsed via public IP.
What I might be doing wrong? or this something that is not supported?
Regards
Aun
Simply "redirecting" an HTTP request to the private IP address would not work, as the private IP is not routeable from hosts outside that private network.
What I think you are looking for is Nginx's reverse proxy functionality. There is a good guide on how to set that up here.

How to send requests to a web server running inside a docker container inside an AWS EC2 machine from the outside world?

I have a Python Flask web server running inside a docker container that is running in an AWS EC2 Ubuntu machine. The container is running on a default network setting (docker0). Within the host EC2, I can send requests (Get, Post) to this web server using docker-machine ip (172.x.x.x) and the forwarded ports (3000: 3000) of the host.
url: http:// 172.x.x.x:3000 / <api address>
How can I send requests (GET, POST) to this web server from the outside world? For example from another web server running in another EC2 machine. Or even from the web using my web browser?
Do I need to get a public IP Address for my docker host?
Is there is another way to interact with such web server within another web server running in another EC2?
If you have a solution please explain with as many details as you can for me to understand it.
The only way that I can think of is to write a web server on the main EC2 that listens to the requests and forward them to the appropriate docker container webservers?! But that would be too many redundant codes and I would rather just request to the web server running on the container directly!
The IP address of the docker is not public. Your EC2 instance usually has a public IP address though. You need an agent listening on a port on your EC2 instance and pass it to your docker/Flask server. Then you would be able to call it from outside using ec2-instance-ip:agent-port.
It's still not a long-term solution as EC2 IPs change when they are stopped. You'd better use a load-balancer or an elastic IP if you want the ip/port to be reliable.
That's right, it makes a lot of redundant code and an extra failure point. That's why it's better to use Amazon's managed docker service (https://aws.amazon.com/ecs/). This way you just launch an EC2 instance which is a docker and has a public IP address. It still allows you to SSH into your EC2 instance and change stuff.

ASP.NET Core: How to get remote IP address?

I try to get remote (client) IP addres:
var ip = httpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress
But it works only for local requests (it will return ::1 value)
When I load page from remote machine the value is null. I investigated there is no IHttpConnectionFeature in the Features collection in this case.
Why? And how to get remote ip address correctly?
I know that this post is old but I came here looking for the same question and finnaly I did this:
On project.json add dependency:
"Microsoft.AspNetCore.HttpOverrides": "1.0.0"
On Startup.cs, in the Configure method add:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto
});
And, of course:
using Microsoft.AspNetCore.HttpOverrides;
Then, I got the ip like this:
Request.HttpContext.Connection.RemoteIpAddress
In my case, when debugging in VS I got always IpV6 localhost, but when deployed on an IIS I got always the remote IP.
Some useful links:
How do I get client IP address in ASP.NET CORE? and RemoteIpAddress is always null
The ::1 may be because:
Connections termination at IIS, which then forwards to Kestrel, the v.next web server, so connections to the web server are indeed from localhost.
(https://stackoverflow.com/a/35442401/5326387)
Just try this:
var ipAddress = HttpContext.Connection.RemoteIpAddress;
And if you have another computer in same LAN, try to connect with this pc but use user ip instead of localhost. Otherwise you will get always ::1 result.

docker registry on localhost with nginx proxy_pass

I'm trying to setup a private docker registry to upload my stuff but I'm stuck. The docker-registry instance is running on port 5000 and I've setup nginx in front of it with a proxy pass directive to pass requests on port 80 back to localhost:5000.
When I try to push my image I get this error:
Failed to upload metadata: Put http://localhost:5000/v1/images/long_image_id/json: dial tcp localhost:5000: connection refused
If I change localhost with my server's ip address in nginx configuration file I can push allright. Why would my local docker push command would complain about localhost when localhost is being passed from nginx.
Server is on EC2 if it helps.
I'm not sure the specifics of your traffic, but I spent a lot of time using mitmproxy to inspect the dataflows for Docker. The Docker registry is actually split into two parts, the index and the registry. The client contacts the index to handle metadata, and then is forwarded on to a separate registry to get the actual binary data.
The Docker self-hosted registry comes with its own watered down index server. As a consequence, you might want to figure out what registry server is being passed back as a response header to your index requests, and whether that works with your config. You may have to set up the registry_endpoints config setting in order to get everything to play nicely together.
In order to solve this and other problems for everyone, we decided to build a hosted docker registry called Quay that supports private repositories. You can use our service to store your private images and deploy them to your hosts.
Hope this helps!
Override X-Docker-Endpoints header set by registry with:
proxy_hide_header X-Docker-Endpoints;
add_header X-Docker-Endpoints $http_host;
I think the problem you face is that the docker-registry is advertising so-called endpoints through a X-Docker-Endpoints header early during the dialog between itself and the Docker client, and that the Docker client will then use those endpoints for subsequent requests.
You have a setup where your Docker client first communicates with Nginx on the (public) 80 port, then switch to the advertised endpoints, which is probably localhost:5000 (that is, your local machine).
You should see if an option exists in the Docker registry you run so that it advertises endpoints as your remote host, even if it listens on localhost:5000.

Resources