Skip to content
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

Unable to use Yarp on Azure App Services? #2066

Closed
conficient opened this issue Mar 11, 2023 · 4 comments
Closed

Unable to use Yarp on Azure App Services? #2066

conficient opened this issue Mar 11, 2023 · 4 comments
Labels
Type: Bug Something isn't working

Comments

@conficient
Copy link

Scenario

We use a library called Cocoon which utilizes YARP 1.1 to proxy requests to a .NET 6 application to an older WebForms application. It's running fine on our hosted servers - the NET 6 application proxies requests to an internal IP address on a port using HTTP.

Azure Problems

We wish to port our application to Azure App Services, so I set up a DevOps release pipeline to create two App Services hosted on a Windows App Service Plan, in the same region. The parent NET 6 application is then configured to proxy traffic to the WebForm app. I used the Azure domain names for each service with HTTPS for both sites. Both apps are running fine when queried directly.

All proxied requests to the WebForms app fail with a 400 status code, even requests for static content. I've tried to add more logging to see what's going wrong, but I've not figured out any more than a 400 status code.

What I've Tried

  • I tried disabling HTTP/2 on the WebForm app - no change.
  • I configured the proxy address to use http:// and turned off HTTPS Only on the WebForm app in case it was related to SSL.
  • I upgraded the YARP version from 1.1 to 2.0 to see if that made a difference.
  • Tried creating a simple controller action on the WebForm site that logged the request details but it never gets executed

Log

Below is the log from the NET 6 application when it tried to request a proxied resource (in this case a static image /img/DefaultLogojpg). It starts the request and first makes a call to the remote URI https://webform-site-url/facadeauth which is a Cocoon check for authentication status on the WebForm app. This returns 401 which is correct since the user isn't logged in - so this part of the operation worked correctly and did request the remote resource.

It then gets a 400 error on requesting the actual resource, and it seems to be repeated several times (it might be a retry option in Cocoon/YARP?). The image being requested does not require authentication as it's a static file.

2023-03-09 16:45:27.314 +00:00 [INF] Executing endpoint '/{**catch-all}'
2023-03-09 16:45:27.314 +00:00 [INF] Proxying to https://webform-site-url/img/DefaultLogo.jpg HTTP/2 RequestVersionOrLower no-streaming
2023-03-09 16:45:27.328 +00:00 [INF] Request starting HTTP/1.1 GET https://blazor-site-url/img/DefaultLogo.jpg - -
2023-03-09 16:45:27.329 +00:00 [INF] Start processing HTTP request GET "https://webform-site-url/facadeauth"
2023-03-09 16:45:27.330 +00:00 [INF] Sending HTTP request GET "https://webform-site-url/facadeauth"
2023-03-09 16:45:27.334 +00:00 [INF] Received HTTP response headers after 3.1655ms - 401
2023-03-09 16:45:27.335 +00:00 [INF] End processing HTTP request after 5.6275ms - 401
2023-03-09 16:45:27.336 +00:00 [INF] Executing endpoint '/{**catch-all}'
2023-03-09 16:45:27.336 +00:00 [INF] Proxying to https://webform-site-url/img/DefaultLogo.jpg HTTP/2 RequestVersionOrLower no-streaming
2023-03-09 16:45:27.345 +00:00 [INF] Received HTTP/1.1 response 400.
2023-03-09 16:45:27.346 +00:00 [INF] Executed endpoint '/{**catch-all}'
2023-03-09 16:45:27.347 +00:00 [INF] Request finished HTTP/1.1 GET https://blazor-site-url/img/DefaultLogo.jpg - - - 400 0 - 18.8249ms
2023-03-09 16:45:27.348 +00:00 [INF] Received HTTP/1.1 response 400.
2023-03-09 16:45:27.349 +00:00 [INF] Executed endpoint '/{**catch-all}'
2023-03-09 16:45:27.350 +00:00 [INF] Request finished HTTP/1.1 GET https://blazor-site-url/img/DefaultLogo.jpg - - - 400 0 - 43.3374ms
2023-03-09 16:45:27.351 +00:00 [INF] Received HTTP/1.1 response 400.
2023-03-09 16:45:27.351 +00:00 [INF] Executed endpoint '/{**catch-all}'
2023-03-09 16:45:27.352 +00:00 [INF] Request finished HTTP/1.1 GET https://blazor-site-url/img/DefaultLogo.jpg - - - 400 0 - 74.3990ms
2023-03-09 16:45:27.354 +00:00 [INF] Received HTTP/1.1 response 400.
2023-03-09 16:45:27.364 +00:00 [INF] Executed endpoint '/{**catch-all}'
2023-03-09 16:45:27.365 +00:00 [INF] Request finished HTTP/1.1 GET https://blazor-site-url/img/DefaultLogo.jpg - - - 400 0 - 112.8046ms
2023-03-09 16:45:27.366 +00:00 [INF] Received HTTP/1.1 response 400.
2023-03-09 16:45:27.366 +00:00 [INF] Executed endpoint '/{**catch-all}'
2023-03-09 16:45:27.372 +00:00 [INF] Request finished HTTP/1.1 GET https://blazor-site-url/img/DefaultLogo.jpg - - - 400 0 - 152.5473ms
2023-03-09 16:45:27.374 +00:00 [INF] Received HTTP/1.1 response 400.
2023-03-09 16:45:27.375 +00:00 [INF] Executed endpoint '/{**catch-all}'
2023-03-09 16:45:27.380 +00:00 [INF] Request finished HTTP/1.1 GET https://blazor-site-url/img/DefaultLogo.jpg - - - 400 0 - 189.8787ms
2023-03-09 16:45:27.381 +00:00 [INF] Received HTTP/1.1 response 400.

If there are any other tests or YARP configurations I can try, or specific logging I can perform to diagnose the cause I'm welcome to suggestions as I've been stuck on this for several days.

@conficient conficient added the Type: Bug Something isn't working label Mar 11, 2023
@MihaZupan
Copy link
Member

Glancing at Cocoon's implementation, I suspect you are forwarding the request's host header as-is.
For example, if you had sites A.azure and B.azure, where A proxied requests to B, you may be sending requests to B's IP while specifying A as the host.

Assuming you don't have access to YARP's transforms, you can try setting

context.Request.Headers.Host = default;

before proxying the request (e.g. in the first middleware that runs), and YARP will use B.azure as the host header instead.

@conficient
Copy link
Author

Thanks for the suggestion @MihaZupan, will investigate

@karelz
Copy link
Member

karelz commented Mar 23, 2023

Triage: Seems to be answered. 9 days no response. Closing.

@karelz karelz closed this as completed Mar 23, 2023
@conficient
Copy link
Author

@MihaZupa many thanks for your excellent suggestion - it was the Host header that was the culprit!

I believe the Azure front-end uses the Host header value to direct the correct App Service - so when the request is made to A.azure, it forwards to B.azure with the original host header. I think Azure sees this as an error - hence 400 - bad request. All fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants