https://twitter.com/LinuxPony and I figured it out while running .NET Core MVC on Ubuntu without Apache or NGINX.

The magic line is System.Net.IPAddress.Any. This makes Kestrel listen to requests that originate from outside the local machine. (For the machine to receive those requests, we must also open the firewall to Kestrel's port.)

.UseKestrel(options =>
{
    // listen to requests from outside the local machine
    options.Listen(System.Net.IPAddress.Any, 5000);
})

See the official Kestrel docs for reasons we probably should not do this for production apps.

Out of the box, Kestrel only listens to requests that originate from the local machine (i.e. IPAddress.Loopback). We need to tell Kestrell to listen to requests that come from outside the machine (i.e. IPAddress.Any). Once we do this, we can use Kestrel without a reverse proxy: without IIS, without Nginx, without Apache. Just kestrel.

Here is the full Program class.

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseKestrel(options =>
            {
                // listen to requests from outside the local machine   
                options.Listen(System.Net.IPAddress.Any, 5000);
            })
            .Build();
}