Hosting ASP.NET Core 2.0 Web Api on Azure Ubuntu Server with Nginx and Mutual SSL Authentication (PART 4)
PART 4: Setup a Service to Manage Kestrel Process, Create Self Signed SSL Certificate and Configure Nginx as a Reverse Proxy Server
In this post series, I will step by step show you how to host a ASP.NET Core 2.0 Web Api which is using mutual SSL authentication on a Azure Ubuntu Server using Nginx as the reverse proxy server and Kestrel as the default application server.
In this part we will see how to setup a service to manage kestrel process, creating self-signed SSL certificates and configuring Nginx as a reverse proxy server.
For information about how to deploy an Ubuntu Server in Azure check part-1 of this series.
For information about how to setup .Net Core SDK 2.0 and Nginx on Ubuntu Linux check part-2 of this series.
For information about how to configure Azure Network Security Group and Publishing Asp.Net Core Web Api check part-3 of this series.
For information about how to setup mutual SSL for client authentication and passing client certificate data to Asp.Net Core Web Api using HTTP headers check part-5 of this series.
Setup a Service to Manage Kestrel Process
We will create a service to manage the Kestrel process so that it can be started automatically.
Open the service configuration definition file:
sudo nano /etc/systemd/system/kestrel-webapi.service
Copy the following and save/exit:
[Unit]Description=Sample Web API Application running on Ubuntu
[Service]WorkingDirectory=/home/mc/webapiExecStart=/usr/bin/dotnet /home/mc/webapi/WebApi.dllRestart=alwaysRestartSec=10 # Restart service after 10 seconds if dotnet service crashesSyslogIdentifier=dotnet-webapiUser=www-dataEnvironment=ASPNETCORE_ENVIRONMENT=ProductionEnvironment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
[Install]WantedBy=multi-user.target
Execute the following to enable the service (password will be asked twice):
systemctl enable kestrel-webapi.service
Start the service:
systemctl start kestrel-webapi.service
Verify that the service is running:
systemctl status kestrel-webapi.service
This should display the “Active” status as “active (running)”.
Note: Application logs can be viewed by using the following commands:
sudo journalctl -fu kestrel-webapi.service
Orsudo journalctl -fu kestrel-webapi.service --since "2017-11-14" --until "2017-11-15 11:00"
Orsudo journalctl -fu kestrel-webapi.service --since today
Orsudo journalctl -fu kestrel-webapi.service --until 1 hour ago
Create a Self-Signed SSL Certificate
We will use OpenSSL to create a self-signed server ssl certificate which will be used for “https” connection.
Execute the following to create public and private keys:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
Execute the following to create the dhparam key (It may take a few minutes!):
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Configure Nginx as a Reverse Proxy
In our web server Nginx will work as a reverse proxy and accept all http and https requests, do the authentication and transfer the request to the Kestrel application server. This is the suggested best practice by Microsoft. For this purpose we have to make changes in the Nginx config file.
Before changing the Nginx configuration take a backup of the config file as a precaution:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.orig
Open the config file with Nano editor:
sudo nano /etc/nginx/sites-available/default
Delete everything in the file. (use ALT+T)
Paste the following and save/exit:
server {
listen 80;
rewrite ^ https://$host$request_uri permanent;
}server {
listen 443 ssl;
server_name webapi.westeurope.cloudapp.azure.com;
ssl on;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
error_log /var/log/nginx/debugnginx.log debug;location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
To verify configuration changes in Nginx:
sudo nginx -t
It should display:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Restart Nginx to implement our changes:
sudo systemctl restart nginx
Now, you can browse your web api running on the Ubuntu server.
You will get “Your connection is not secure” warning on the browser because the self-signed server certificate is not trusted on your client machine. This is expected. You should get a SSL certificate from a known CA (certificate authority) for production!
Our series will continue with mutual ssl setup for client authentication and passing client certificate data to Asp.Net Core app.
Hope it helps!
Originally published at https://www.weboideas.com on November 24, 2017.