⬆️ ⬇️

On the way to creating a secure web resource. Part 1 - server software

For quite a long time, I have wanted to formalize all my thoughts, experiences, practiced daily, and much more in one place and make them available to the public. I am sure this material will be useful to many. It is dedicated to different aspects in the configuration of Linux server software and secure approaches to creating sites / applications in php (it is still one of the most popular links, although it is successfully pushed by other technologies. But the tips are also easily applicable to web resources on other technologies).



Those. this is a typical situation. A project (startup), bought a server for it and deployed a website on it. Businesses do not need to spend extra money on the server (so the most productive software bundles will be chosen), and you also need everything to be safe, and it's free :)



Server software configuration



Nginx + php-fpm


I would start by explaining the selected bundle. I had various resources, quite high-loaded, where I had to get along with several applications at once, and besides, not only the web. I tried all sorts of bundles (apache, apache with static feedback by nginx, nginx + php in cgi mode, etc.) and the best option was still a bunch of nginx + php-fpm. Both in terms of stability, and in terms of configuration flexibility, and in terms of security. Well, if you still have Apache, then stop using it right now (C) I do not remember where it comes from (although the following tips are easily ported and suitable for any other bundle).

First of all I would like to say that it is worth sharing machines for each resource. Yes, you can isolate each site from each other, as is done on shared-hosting, but still the rent of virtual servers is not so high (think about it before placing another site on the same machine, even if you follow different rules: different users for each resource, etc. Well, or try jail;).



Let's start with the config of the site itself:

')

location /index.php { ... fastcgi_pass unix:/var/run/php-fpm/php-fpm.socket; ... } 


It is desirable to design a web application so that it can work from just one php file in htdocs and in a similar way configure the location - /index.php. This eliminates the possibility of running a filled php shell in htdocs. We will return to this in the second part of this article.



Fix bug with fix_pathinfo described here . Edit php.ini and change the value of the fix_pathinfo parameter to



 cgi.fix_pathinfo=0 


Complicate the life of the script-kiddies and block popular UA scanners ( from the article ):



 if ( $http_user_agent ~* (nmap|nikto|wikto|sf|sqlmap|bsqlbf|w3af|acunetix|havij|appscan) ) { return 403; } 


Believe me, the lion part of the "hackers" will be cut off :)



Crutch protection against CSRF


I highly recommend the following rule for use , but if you encounter a problem that someone is actively using CSRF on your users, the following rule can help if there is no normal way to add protection against CSRF



 # ANTI CSRF HACK valid_referers blocked example.com www.example.com; if ($invalid_referer) { set $possible_csrf 1; } if ($request_method = POST) { set $possible_csrf "${possible_csrf}2"; } if ($possible_csrf = 12) { return 403; } 


Such terrible constructions are needed, since nginx does not support multiple conditions in if, and also does not support nested ifs. In the first line we indicate the referees who will be valid (blocked - cut by the firewall and the referees from our site). And if the method = POST, then we block the user. Nowadays almost no one uses a proxy server that cuts the referer in client requests, but there is such a possibility. Therefore, the example above is not a solution, but only a dirty hack.



Anti-DNS pinning


The host parsing rules need to be configured so that if the HOST value in the HTTP header is not our resource, then give 404. Example .



X-Frame-Options


Add vital headers (we will also get information from the article by VladimirKochetkov ). First, let's ban the display of our resource in the iframe:



 add_header X-Frame-Options DENY; 


This will save our resource from possible DDOS'a via iframe, as well as from possible clickjacking 'a on the site. Don't forget about CSS tricks with iframe.



X-Content-Type-Options


 add_header X-Content-Type-Options nosniff; 


This will tell IE that it is not necessary to automatically determine the Content-Type, but to use the content-type already submitted. IE already had security bugs related to automatic detection of the content type.



X-XSS-Protection


 add_header X-XSS-Protection "1; mode=block;"; 


Same title for IE. Enables built-in XSS protection.



X-Content-Security-Policy


Pretty specific title, be careful with it.



 add_header X-Content-Security-Policy "allow 'self';"; add_header X-WebKit-CSP "allow 'self';"; 


Determines from which domains you can load JS (X-Content-Security-Policy for IE10 and X-WebKit-CSP for FF / Chrome). In the example above, there is a rule that allows you to load JS only from the same domain.



Strict-Transport-Security


If your resource is working via https and there is a redirect from port 803 to 443 (for convenience), the client can maintain an unprotected connection for some time. This heading excludes the possibility of MITM in this very short period of time ( interception of traffic in TOR ). Read more here .



Firewall


One of the most important configurations. The general idea is this - allow a few, prohibit everything else. I am not an iptables guru, maybe someone in the comments will correct me and we will come to a better solution. We consider that eth0 is our external interface and we will restrict it (usually the access from the internal network is full).



 -A INPUT -i eth0 -p icmp -j ACCEPT #      -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT #        -A INPUT -s 12.34.56.78 -i eth0 -j ACCEPT #   IP ,            (  ) -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT # ssh -A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT # web -A INPUT -i eth0 -j DROP #    


You can also add auto-bans to ddos ​​for this configuration, but I prefer not to use them until they are needed. Perhaps, I would add a limit on the simultaneous number of IP connections. Everything is quite specific with each resource.



Monitor server


An excellent tool for monitoring the server (load, network, number of requests, logging exceptions) is New Relic . With the “correct” (my view on this, I will explain in the second part), the architecture will not even need to monitor access.log / error.log. Installing both under Win and under Linux is very simple. Register, add a server, add a repository and install a daemon for this service. And then in one line it is activated and launched. Must have, in general.



Monitor file system


It was nice to keep track of file system changes, what if someone has flooded or changed? Linux for monitoring the file system provides an excellent API - inotify (more detailed article from youROCK ). And there is a ready-made perl script (of course, there are analogues) - iwatch, which fully automates the process of monitoring the directories we need. Installation on debian systems is simple:



 apt-get install iwatch 




And we get a great watch The config file is located at etc / iwatch / iwatch.xml and looks like this:



 <?xml version="1.0" ?> <!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" > <config lang="xml"> <guard email="youremail@gmail.com" name="IWatch"/> <watchlist> <title>Operating System</title> <contactpoint email="root@localhost" name="Administrator"/> <path type="single" syslog="on">/bin</path> <path type="single" syslog="on">/sbin</path> <path type="single">/etc</path> <path type="recursive">/lib</path> <path type="exception">/lib/modules</path> </watchlist> </config> 


It's pretty obvious. We enumerate the folders we need, that is necessary - we exclude and specify the mail, where to send the reports (everything goes perfectly to gmail).



If you decide to just download the script from sourceforge , then the dependencies in perl are delivered very simply - cpan #modulename, for example cpan XML :: SimpleObject :: LibXML.



AppArmor, SELinux, chroot and other pribludy


Unfortunately, if you enter "SELinux" in Google, then the first hint will be "SELinux disable". With AppArmor is a similar song. This is partly due to the fact that these protections are enabled by default and cause problems for working software. And you have already spent a good hour and drank the third mug of coffee, figuring out why the necessary script / software does not work. I would suggest, nevertheless, to deal with these "magic of the world of Linux" and read the following articles:





I want to say that in practice there really are problems with pentest / hacking from such mechanisms, so try not to neglect them.



IPS, IDS, WAF


If you have an existing business project, then I suggest to skip reading any articles on configuring WAF / IPS / IDS and use ready-made solutions, for example, from F5 or from Cloudflare . With Cloudflare there are a lot of problems (for attackers). If I see a resource on it, it immediately means spent time x 5. I can say that Anonymous, 1337day.com (inj3ct0r) and other pro-security use Cloudflare (no advertisements, this is just a fact). Of course, there are ways to bypass these systems, but they usually require additional expenses from the attacker, for example, for renting cars in the cloud with a bunch of different IP addresses, but this is already a topic of a slightly different topic.



Well, if the project is only at the beginning of its path and there is no money for such services, then I suggest the following articles for reading:





On Habré there is nothing about Suricata (I was persistently recommended by one familiar hacker from Africa). Unfortunately, I can’t say anything about it myself, and I don’t know links to good reviews. I adhere to the use of protective proxy services listed at the beginning.



DNS security


If you are using your DNS server (or someone else's), do not forget to check the AXFR-requests to him (him) for the used domains. Described the problem in detail here .



Grsecurity


I hope someday my hands will reach Grsecurity . And then I will add information about it in the topic.



I keep silent about backups, true chmod / chown, monitoring logs (error.log including) and system events, this should be taken for granted.



Series:

Source: https://habr.com/ru/post/168739/



All Articles