0

I have an ASP.NET app hosted in a Docker container, with a NGINX reverse proxy, hosted on a VPS. When running in production, the x-forwarded-proto header isn't being passed.

From what I understand, this should return the x-forwarded-proto header

curl -I https://awaken.hanumaninstitute.com

The result is

HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Sun, 01 Sep 2024 02:35:33 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding

The NGINX server block is this

server {
server_name   awaken.hanumaninstitute.com;

location /.well-known/acme-challenge/ {
root /var/www/certbot;
}

location / {
proxy_pass         http://127.0.0.1:5009/;
proxy_http_version 1.1;
proxy_set_header   Upgrade $http_upgrade;
proxy_set_header   Connection $connection_upgrade;
proxy_set_header   Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header   X-Forwarded-Proto $scheme;
}

listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/awaken.hanumaninstitute.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/awaken.hanumaninstitute.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

The ASP.NET app has this

var app = builder.Build();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

Server is Debian.

What am I missing? Why isn't x-forwarded-proto working?

1
  • How did you verify that the configuration is not working and this is not an issue on the origin host? Commented Sep 4, 2024 at 15:11

1 Answer 1

1

I had similar issue with hosting asp.net core app on debian server with nginx. I also thought that the issue is in nginx configuration but it was not...

Your nginx configuration looks good. The magic happens in this code:

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

This code reads the XForwardedFor and XForwardedProto headers and sets headers values to HttpContext properties like this:

  • X-Forwarded-For to HttpContext.Connection.RemoteIpAddress
  • X-Forwarded-Proto to HttpContext.Request.Scheme

Documentation is here https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-8.0

If you want to verify, that nginx really provides X-Forwarded-For and X-Forwarded-Proto headers place a simple middleware before app.UseForwardedHeaders().

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
    //This will log all available headers in http request, your log MinimumLevel must be set to information
    app.Use(async (context, next) =>
    {
        var headers = context.Request.Headers.Select(x => new { x.Key, x.Value });

        logger.LogInformation("Headers: {@Headers}", headers);

        await next();
    });

    // this will read X-Forwarded-For and X-Forwarded-Proto headers and remove them from context.Request.Headers
    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    });
    
    // here you can see if the app.UseForwardedHeaders() works as expected
    app.Use(async (context, next) =>
    {
        var xForwardedForHeaderValue = context.Connection.RemoteIpAddress;

        var XForwardedProtoHeaderValue = context.Request.Scheme;

        logger.LogInformation("IP: {Ip}, scheme: {Scheme}", xForwardedForHeaderValue, XForwardedProtoHeaderValue);

        await next();
    });

    // the rest of your code
}
1
  • I found out that ForwardedHeaders.XForwardedFor does NOT WORK by default without adding additional configuration for allowed hosts. Removing For and leaving only Proto fixed the problem. Commented Sep 5, 2024 at 19:48

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.