Making requests to localhost within Azure App Services application
Asked Answered
A

3

8

I have a continuous web job that listens for requests containing diagnostic information.

In order to test connectivity I try to hit a health check in my web job but am unable to make requests to localhost per azure app services documentation.

The code below is what I use to verify that I can connect from the application I deploy:

    var uri = new Uri("http://localhost:8989/ping");
    var response = await client.GetAsync(uri);

I get this exception:

System.Net.Http.HttpRequestException: An error occurred while sending the request. 
---> System.Net.WebException: Unable to connect to the remote server 
---> System.Net.Sockets.SocketException: An attempt was made to access a socket in a way forbidden by its access permissions 127.0.0.1:8989

The web job is installed via a site extension install script through Kudu (SCM), which means that the web job is ultimately a child process of Kudu (SCM). The web job application on startup binds itself to port 8989. Starting the application locally on windows, I am able to hit my health check with no problems.

The azure app services documentation says that requests to localhost will fail unless an application within the same sandbox binds to the port (https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#local-address-requests).

The azure app services documentation states that Kudu runs in the same sandbox as the main application (https://github.com/projectkudu/kudu/wiki/Kudu-architecture#security-model).

How do I enable communication with my web job via http?

Preferably it would be something that I could do from a site extension install process, but any options are good.

Update 12-26-2019:

I have attempted to force SCM and the main application to run in the same sandbox with WEBSITE_DISABLE_SCM_SEPARATION=true (https://github.com/projectkudu/kudu/wiki/Configurable-settings#use-the-same-process-for-the-user-site-and-the-scm-site).

The documentation states that they already run in the same sandbox and that if a process listens on a port in the same sandbox, those requests should work. Of note, the actual SCM w3wp.exe process has been able to hit localhost with http for my web job. This setting did not seem to improve the situation though.

Update 04-02-2020:

I officially abandoned the idea of using a web job and I now start the process as a child of the main application instance. This allows me to communicate with localhost:8989 with no issue.

Though I now need to manage my own keep alive logic.

I'd still love to know if there is a way to communicate via TCP with a web job if that is ever possible.

Authority answered 24/12, 2019 at 16:47 Comment(5)
This is the most similar question I have found: #56572539Authority
The access issue could be arising from authentication/authorisation to Kudu. Kindly, share details of the client instance creation.Leonilaleonine
This is before the request even leaves the context of the applicationAuthority
Like I suggested in my answer, the socket connections are not enabled for WebJobs since they run inside an IHost container. Additional details are available in my answer.Leonilaleonine
Wiki documentation on GitHub is not always up-to-date. Nor official documentation either. I question if this is even supposed to work...Ctenoid
M
0

How do I enable communication with my web job via http?

No. It is not possible for the WebJob to directly send requests to the site via localhost. This limitation is documented on the sandbox page like you provided.

Connection attempts to local addresses (e.g. localhost, 127.0.0.1) and the machine's own IP will fail, except if another process in the same sandbox has created a listening socket on the destination port.

Rejected connection attempts, such as the following example which attempts to connect to 127.0.0.1:80, from .NET will result in the above exception.

For more details, you could refer to this SO thread.

Mathers answered 25/12, 2019 at 9:32 Comment(1)
You say the web job can't send requests to the site, but I want the opposite direction. Also, "except if another process in the same sandbox has created a listening socket on the destination port" leads me to believe that it IS possible.Authority
E
0

I believe the problem is related to the port that is assigned to your app (8989). You'll need to use another service (old cloud services), virtual machine or Service Fabric in order to open and receive requests on port 8989.

More info about it:

Network endpoint listening The only way an application can be accessed

via the internet is through the already-exposed HTTP (80) and HTTPS (443) TCP ports; applications may not listen on other ports for packets arriving from the internet. However, applications may create a socket which can listen for connections from within the sandbox. For example, two processes within the same app may communicate with one another via TCP sockets; connection attempts incoming from outside the sandbox, albeit they be on the same machine, will fail. See the next topic for additional detail.

https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox

Expurgate answered 2/1, 2020 at 16:6 Comment(1)
It also did not work if I dynamically picked a free port.Authority
L
0

You should not implement an HTTP server in your WebJob since that's not how they're intended to be run.

A WebJob is basically executed inside an IHost container designed for headless services which can facilitate background processing tasks. Unlike an IWebHost, an IHost is not suitable for web hosting.

Consequently, the WebJob in your created may not have effectively bound itself to the port you mentioned. If it did, quite likely the security policy of the sandbox would restrict access to arbitrary sockets created by a user other than those exposed for accessing your site and kudu service. This was exactly indicated by "System.Net.Sockets.SocketException: An attempt was made to access a socket in a way forbidden by its access permissions 127.0.0.1:8989" in the error stack trace snippet you shared.

How do I enable communication with my web job via http? - Communication with a WebJob may be established via WebJobs API.

You may have to create multiple WebJobs to fulfill the various functionality intended by your attempted HTTP server implementation.

References

Leonilaleonine answered 3/1, 2020 at 19:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.