How to Get the Kestrel Web Server to Listen to Non-Localhost Requests

How do I get the kestrel web server to listen to non-localhost requests?

The default configuration file used by Kestrel server is hosting.json. The name was changed multiple times in different beta versions. If you use now project.json with the following "command" section

"commands": {
"web": "Microsoft.AspNet.Server.Kestrel"
}

then during starting the server from the command line by

dnx web

the file hosting.json will be read. The file

{
"server.urls": "http://0.0.0.0:5000"
}

will configure the server to listen 5000 on every IP4 address. The configuration

{
"server.urls": "http://::5000;http://0.0.0.0:5000"
}

will inform to listen 5000 on both IP4 and IP6 address.

One can specify alternative configuration files by usage ASPNET_ENV environment variable or by the usage of --config myconfig1.json (or config=myconfig1.json). For example you can use

SET ASPNET_ENV=Development

and to create hosting.Development.json file with specific configuration. Alternatively you can use project.json with

"commands": {
"web": "Microsoft.AspNet.Server.Kestrel"
"webProd": "Microsoft.AspNet.Server.Kestrel --config prod.json"
}

and start the server by usage

dnx webProd

I have to remind additionally that it could be required that you allow to additionally listen and to register (to start dnx web). It's required because of the firewall and the local security of listening new TCP/HTTP ports. Something like below should make local registering and listening of 5000 port for everybody (IPv4 and IPv6):

netsh http add iplisten ipaddress=0.0.0.0:5000
netsh http add iplisten ipaddress=::5000
netsh http add urlacl url=http://+:5000/ user=\Everyone

To be more secure you can adjust the above configuration to grant minimal rights.

UPDATED: Thanks @BlaneBunderson. One can use * instead of IP address (like http://*:5000) to listen on any IP4 and IP6 addresses from any interface. One should be carefully and not use these

  • http://*:5000;http://::5000
  • http://::5000;http://*:5000
  • http://*:5000;http://0.0.0.0:5000
  • http://*:5000;http://0.0.0.0:5000

because it will require to register IP6 address :: or IP4 address 0.0.0.0 twice.

Corresponds to the announcement

Technically, any hostname that isn't "localhost" or a valid IPv4 or
IPv6 address will cause Kestrel to bind to all network interfaces.

I think that the behavior could be changed in the future. Thus I would recommend to use only *:5000, 0.0.0.0:5000 and ::5000 form for registering of any IT address.

UPDATED 2: ASP.NET Core RC2 changes (see the announcement) the behavior of loading the defaults. One have to make changes in the Main to load the settings from hosting.json and the command line parameters. Below is an example of the usage

public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
.AddCommandLine(args)
.Build();

var host = new WebHostBuilder()
.UseUrls("http://*:1000", "https://*:1234", "http://0.0.0.0:5000")
.UseEnvironment("Development")
.UseConfiguration(config)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();

host.Run();
}

The above code use three bindings: "http://*:1000", "https://*:1234", "http://0.0.0.0:5000" by default instead of usage the default port 5000 by default (to be exact the usage of http://localhost:5000). The call of .UseConfiguration(config) are made after .UseUrls. Thus the configuration loaded from hosting.json or the command line overwrite the default options. If one remove .SetBasePath(Directory.GetCurrentDirectory()) line then the hosting.json will be loaded from the same directory where the application dll will be compiled (for example bin\Debug\netcoreapp1.0).

One can use execution like

dotnet.exe run --server.urls=http://0.0.0.0:5000

to overwrite the default settings (from UseUrls) and the settings from "server.urls" property of hosting.json if it's exist.

In the same way one could overwrite the ULR settings by setting the environment variable

set ASPNETCORE_SERVER.URLS=http://localhost:12541/

then the default start of the application using dotnet.exe run will use http://localhost:12541/ for binding.

You can find here an example of the usage of HTTPS binding.

REMARK: The name of environment variable is changed from ASPNETCORE_SERVER.URLS to ASPNETCORE_URLS in later versions of ASP.NET(see here the documentation of ASP.NET Core 3.1).

How to Change ASP.NET Core's Built-In Web-Server (Kestrel) Default IP Binding, from 127.0.0.1 to 0.0.0.0?

The launchSettings.json is only really meant to be used for development purposes. At that time, you are usually developing only locally and are not looking for external devices to access your server. That’s why the default on the loopback interface makes sense.

For production or general non-development purposes, you should properly bundle the application using dotnet publish (or through Visual Studio). At that time, the published application will not include the launchSettings.json, so that configuration doesn’t actually apply.

Instead, you should set the URL your application should listen on through configuration. For example using the environment variable ASPNETCORE_URLS:

# E.g. on Linux:
ASPNETCORE_URLS=http://0.0.0.0:80 dotnet MyApp.dll

Or by passing the URL to the --url command line argument

MyApp.exe --urls http://0.0.0.0:80

You can also put this into the appsettings.json or an environment-specific appsettings.ENV.json:

{
// …
"urls": "http://0.0.0.0:80"
}

Since the appsettings are usually committed to source control, this allows you to keep the configuration across machines.

As for changing multiple projects at once, the only option would be to set a global environment variable with the updated URL. But since multiple applications cannot be hosted on the same interface/port combination, this probably wouldn’t be the best idea since the value from the enviroment variable would overwrite the value from the appsettings, making this more complicated to reason about.

Kestrel: get access to IP+port pair(s) it's listening on

The IWebHost interface has a ServerFeatures property , which is an instance of IFeatureCollection . If you want to get the server address & port before a HttpContext created , you could retrieve them by :

public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();

var serverAddresses = host.ServerFeatures.Get<IServerAddressesFeature>();

// ... use serverAddresses as you like

host.Run();
}

Note the serverAddresses here is the Address:Port listened by the WebHost , not by IIS or nginx .



Related Topics



Leave a reply



Submit