Previous part is here.
I found that I was missed one critical part that I did in my application but forgot to explain here. Let me explain little bit. Effectively secure communication via HTTPS protocol happens between browser and nginx that is web server. Nginx communicates with .NET application via HTTP protocol. And effectively .NET application believes that it is communicating via HTTP. It called SSL termination.
And as result .NET application can return something that is not compatible with HTTPS protocol. In my case it returns link to profile from Gravatar service via HTTP. This in turn leads to complain from web browser that there is mixed content: HTTP and HTTPS. And that one only minor problem but
[...Read More]
This is continuation of Running .NET Core app on AWS Lightsail Linux instance.
By this moment everything is working exactly as I want. But I have 2 things that really annoys me: backup and updating web site. Because I revoked access to web site directory for every account except www.example.com I have to run a lot of commands from sudo user to backup and update my web site. I would like to automate these steps.
Backup
I have 2 things to backup: web site itself and its data. I separate them because they have different update schedule. For example, I can update web site few times per day and then did not update it for weeks. Obviously, I
[...Read More]
This is continuation of Running .NET Core app on AWS Lightsail Linux instance.
One of the useful features I always use for .NET and .NET Core application in IIS is special file app_offline.htm. If this found exist in application’s directory, then .NET module for IIS will return contents of that file for every request. Usually, it used for maintenance. For example, I put some text that web site is under maintenance and that it will be finished in few minutes. Then I am updating all necessary files that are impossible to update while web site is running. When I finished, I will rename it to app_offline.hml_ until next maintenance.
I found like to implement something
[...Read More]
Previous part is here.
DNS
Firstly, you need domain name. “You can purchase a domain name from Namecheap, get one for free with Freenom, or use the domain registrar of your choice”. Then follow instructions on how to setup A record. Because you have static IP it will be really easy to do. For example from Namecheap instructions are here.
Keep in mind that it could take up to 24 hours to propagate changes. But if you never accessed your domain before, then it should work in few minutes. Remove your changes from hosts file on your computer and when changes are propagated, you should be able to refresh your browser and see your site with
[...Read More]
Previous part is here.
Web service
Next step will be to run dotnet application in service that starts with your virtual PC and system will restart it if application crashes. We will create specific user (www.example.com) that will run dotnet application. Why do we need specific user? Answer is quite simple – security.
Let me elaborate on that. Nginx is running from specific user (
www-data). Service will run from another user that we will create (
www.example.com). Surely you can run everything from root account, but if nginx or dotnet has some vulnerability then hacker will get access to whole system. If each service has own quite limited account that not even able to login. Moreover,
[...Read More]
Previous part is here.
Configuring Web Server
I chose nginx as web server because after research it looks like it is gaining a lot of popularity while second contender Apache2 is losing popularity.
First step is to ensure that your web server is working correctly. Because http port is opened in Amazon router and in your virtual PC you should be able to access it from outside from your browser. Just type http://<you static IP address> in your browser and press Enter. You should see standard nginx web page.
Next step is to make sure that nginx will not serve anything that is not specifically added. Edit file /etc/nginx/sites-available/default and replace it content with following:
server {
listen 80 default_server;
listen [::]:80 default_server;
return 444;
}
[...Read More]
Some time ago I needed simple tutorial site. Initially I was thinking about static page hosting and I started research. But during research I found AWS Lightsail service. It cost $3.5 per month and offers 1 vCPU, 512 MB of RAM, 20 GB of SSD space and 1 TB of data transfer. It is about that the same as my current hosting offers but in case of Amazon it is your own virtual PC, and you can do whatever you like there. It looks attractive, but there is one catch. It is Linux. I had some experience with Linux, but it was far from extensive. On another side I really like challenges, so I decided to try it.
But before
[...Read More]
Recently I got relatively simple deadlock case, but I found quite interesting things during investigation. Our application hangs when user tries to quit it. I got dump file for this case and started investigation.
Call stack for main thread looks like this:
...
clr!JITutil_MonContention+0x115
System_ni!System.ComponentModel.Component.Dispose(Boolean)$##60031F8+0x40
System_ni!System.IO.FileSystemWatcher.Dispose(Boolean)$##600266D+0xd7
System_ni!System.IO.FileSystemWatcher.Dispose(Boolean)$##600266D+0xa6
System_ni!System.ComponentModel.Component.Dispose()$##60031F7+0x1a
...
As you clearly see, application waiting in
FileSystemWatcher’s
System.ComponentModel.Component.Dispose. If you go to
https://sourceof.net and paste name of the method there to see source code, you will see that there is
lock(this) and it looks like some other thread obtained lock before us. Obviously, I went over other 168 threads and found 2 similar call stacks. First thread was executing event from first
[...Read More]
Recently I got strange situation in our application. We have two different classes in .NET that exposed to managed code via COM interfaces. Both classes look very similar but one class by some reason supports IDispatch while another class does not. We have piece of code that work quite differently depending on IDispatch support. And was asked to investigate what is going on and why these two classes behave different.
Here is some data. First class looks like this:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Foo : BaseClass1, IDisposable
Second class looks like this:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Bar : BaseClass2, IMyInterface
IMyInterface declared like this:
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("XXX")]
If
[...Read More]