Reinforcing the security of common services

Case 2: Reinforcing the security of common services

2.1 Question

This case requires optimizing the security of common network services to accomplish the following tasks:

  1. Optimizing security configuration for Nginx services
  2. Optimize the security configuration of MySQL database
  3. Optimize Tomcat's security configuration

2.2 Program

Nginx security optimization includes removing unwanted modules, modifying version information, restricting concurrency, rejecting illegal requests, and preventing buffer overflow.
MySQL security optimization includes initializing security scripts, password security, backup and restore, and data security.
Tomcat security optimization includes hiding version information, launching with reduced authority, and deleting default test pages.

2.3 Steps

The following steps are required to implement this case.

Step 1: Optimize the security configuration of the Nginx service

1) Delete unnecessary modules
Nginx is modular design software. What functions and modules are needed and what modules are not needed can be customized when compiling and installing the software. Some modules can be opened by using the with parameter, and some modules can be disabled by using without.Minimizing installation is always the right solution!
Here are some examples of disabling modules:

[root@proxy ~]# tar -xf nginx-1.12.tar.gz
[root@proxy ~]# cd nginx-1.12
[root@proxy nginx-1.12]# ./configure \
>--without-http_autoindex_module \            //Disable Auto-Index File Directory Module
>--without-http_ssi_module
[root@proxy nginx-1.12]# make
[root@proxy nginx-1.12]# make install

2) Modify version information and hide specific version numbers
The default Nginx displays version information along with the specific version number, which facilitates attackers to find specific version vulnerabilities.
If you need to mask the version number information, do the following to hide the version number.

[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
... ...
http{
     server_tokens off;                            //Manually add such a line under http
     ... ...
}
[root@proxy ~]# nginx -s reload
[root@proxy ~]# Curl-I http://192.168.4.5//View header information for server response

However, the server still shows that the software used is nginx, which can be modified in the following ways.

[root@proxy nginx-1.12]# vim +48 src/http/ngx_http_header_filter_module.c
//Note: vim command must be executed in nginx-1.12 source package directory!!!!!
//The effect before modifying the file is as follows:
static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF;
//Here are the results of our modifications:
static u_char ngx_http_server_string[] = "Server: Jacob" CRLF;
static u_char ngx_http_server_full_string[] = "Server: Jacob" CRLF;
static u_char ngx_http_server_build_string[] = "Server: Jacob" CRLF;
//After the modification is complete, compile and install Nignx, and the version information will no longer be displayed as Nginx, but Jacob
[root@proxy nginx-1.12]# ./configure
[root@proxy nginx-1.12]# make && make install
[root@proxy nginx-1.12]# killall nginx
[root@proxy nginx-1.12]# /usr/local/nginx/sbin/nginx //Start the service
[root@proxy nginx-1.12]# Curl-I http://192.168.4.5//View Version Information Verification

3) Limit concurrency
A DDOS attacker can send a large number of concurrent connections, consuming server resources (including number of connections, bandwidth, and so on), which can leave normal users waiting or unable to access the server.
Nginx provides a ngx_http_limit_req_module that can effectively reduce the risk of DDOS attacks by:

[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
... ...
http{
... ...
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    server {
        listen 80;
        server_name localhost;
        limit_req zone=one burst=5;
            }
}
//Note Notes:
//The limit_req_zone syntax format is as follows:
//limit_req_zone key zone=name:size rate=rate;
//In the above case, shared memory with client IP information store name one has a memory space of 10M
//1M can store 8,000 IP information, 10M can store 80,000 host connection status, capacity can be adjusted as needed
//Accept only one request per second, put extra into funnel
//More than 5 funnels error
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload

Client uses ab software to test the effect:

[root@client ~]# ab -c 100 -n 100  http://192.168.4.5/

4) Refuse illegal requests
The website uses the HTTP protocol, which defines a number of methods for users to connect to the server and get the resources they need.But in practice, only get and post are generally required.
The meaning of the specific HTTP request method is shown in the table.

Before modifying the server configuration, the client tests using different request methods:

[root@client ~]# Curl-i-X GET http://192.168.4.5//Normal
[root@client ~]# Curl-i-X HEAD http://192.168.4.5 //Normal
//curl command option description:
//-i option: Display header information for HTTP when accessing server pages
//-X option: Specify the method of requesting the server

The following settings allow Nginx to reject illegal request methods:

[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
http{
       server {
                 listen 80;
#Here,!Symbol means the opposite of the regular, ~Symbol is a regular matching symbol
#retrun returns 444 error messages if the user accesses the site using a non-GET or POST method
              if ($request_method !~ ^(GET|POST)$ ) {
                     return 444;
               }    
        }
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload

After modifying the server configuration, the client tests using different request methods:

[root@client ~]# Curl-i-X GET http://192.168.4.5//Normal
[root@client ~]# Curl-i-X HEAD http://192.168.4.5//Error

4) Prevent buffer overflow
When a client connects to a server, the server enables various caches to store connection status information.
If an attacker sends a large number of connection requests and the server does not restrict the cache, memory data may overflow (out of space).
Modifying the Nginx configuration file and adjusting various buffer parameters can effectively reduce the overflow risk.

[root@proxy ~]# vim /usr/local/nginx/conf/nginx.conf
http{
client_body_buffer_size  1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
 ... ...
}
[root@proxy ~]# /usr/local/nginx/sbin/nginx -s reload

Step 2: Database Security

1) Initialize security scripts
After MariaDB or MySQL is installed, the default root has no password and provides a test test test database that anyone can operate on.There is a script named mysql_secure_installation that can help us set a password for root, prevent root from logging in to the database from other remote hosts, and delete the test database.

[root@proxy ~]# systemctl status mariadb
//Ensure that the service is started 
[root@proxy ~]# mysql_secure_installation
//Execute Initialization Security Script

2) Password security
Manually modify passwords for MariaDB or MySQL databases:

[root@proxy ~]# mysqladmin -uroot -predhat password 'mysql'
//Change password, old password is redhat, new password is mysql
[root@proxy ~]# mysql -uroot -pmysql
MariaDB [(none)]>set password for root@'localhost'=password('redhat');
//Log in to the database with an account and change your password
MariaDB [(none)]> select user,host,password from mysql.user;
+--------+---------+---------------------------------------------+
| user     | host     | password                                       |
+--------+---------+---------------------------------------------+
| root     | localhost     | *84BB5DF4823DA319BBF86C99624479A198E6EEE9 |
| root     | 127.0.0.1     | *84BB5DF4823DA319BBF86C99624479A198E6EEE9 |
| root     | ::1           | *84BB5DF4823DA319BBF86C99624479A198E6EEE9 |
+--------+-----------+--------------------------------------------+

The password was modified successfully and the password is encrypted in the database. Is there any problem?The problem is that your password is recorded in clear text. Here's a look at clear text passwords:

[root@proxy ~]# cat .bash_history
mysqladmin -uroot -pxxx password 'redhat'
//Passwords modified from the command line automatically record history, where clear text passwords are recorded
[root@proxy ~]# cat .mysql_history 
set password for root@'localhost'=password('redhat');
select user,host,password from mysql.user;
flush privileges;
//Passwords modified by the mysql command also have a record of all instructions for operation, where clear text passwords are also recorded

The database also has a binlog log log with a clear password (fixed after version 5.6).
How to solve it?
Manage your history, do not use clear text login, select the appropriate version after 5.6, log, behavior audit (find the actor), use firewall to set ACL from TCP layer (prohibit external network from contacting database)
3) Data backup and restore
First, back up the database (note that the user name is root and the password is redhat):

[root@proxy ~]# mysqldump -uroot -predhat mydb table > table.sql
//Back up a table in a database
[root@proxy ~]# mysqldump -uroot -predhat mydb > mydb.sql
//Back up a database
[root@proxy ~]# mysqldump -uroot -predhat --all-databases > all.sql
//Back up all databases

Next, restore the database (note that the user name is root and the password is redhat):

[root@proxy ~]# Mysql-uroot-predhat mydb < table.sql //restore data table
[root@proxy ~]# Mysql-uroot-predhat mydb < mydb.sql //restore database
[root@proxy ~]# mysql -uroot -predhat < all.sql

4) Data security
On the server (192.168.4.5), create a database account:

[root@proxy ~]# mysql -uroot -predhat
//Log on to the database using an administrator
MariaDB [(none)]> grant all on *.* to tom@'%' identified by '123';
//Create a new account tom

Snap packs with tcpdump (192.168.4.5)

[root@proxy ~]# tcpdump -w log -i any src or dst port 3306
//Grab a packet whose source or destination port is 3306 and save it in a log file

Client (192.168.4.100) logs on to the database server remotely (192.168.4.5)

[root@client ~]# mysql -utom -p123 -h 192.168.4.5
//In 192.168.4.100 this host logged on to the remote database server using the mysql command (192.168.4.5)
//User name tom, password 123
MariaDB [(none)]> select * from mysql.user;
//After logging into the database, execute any query statement

Go back to the server to see the captured packets

[root@proxy ~]# tcpdump -A -r log
//Using tcpdump to view previously captured packets, data from many databases is displayed in clear text

How to solve?
After you can connect to the server remotely using SSH, you can log in to the database locally (avoid transferring data over the network because there are no packagers known in the network environment).
Alternatively, you can use SSL to encrypt your MySQL server, and just like HTTP+SSL, MySQL also supports SSL encryption (ensuring that the data being transmitted over the network is encrypted).

Step 3: Tomcat security

1) Hide version information, modify Tomcat master profile (Hide version information)
Use commands to view server version information before modifying version information
Note: Proxy has 192.168.2.5 IP addresses, where proxy is used as a client to access 192.168.2.100 servers.

[root@proxy ~]# curl -I http://192.168.2.100:8080/xx        
//Access non-existent page files to view header information
[root@proxy ~]# curl -I http://192.168.2.100:8080    
//Access existing page files to view header information
[root@proxy ~]# curl http://192.168.2.100:8080/xx
//Access non-existent page files to view error information

Modify the Tomcat configuration file, modify the version information (operation 192.168.2.100):

[root@web1 tomcat]# yum -y install java-1.8.0-openjdk-devel
[root@web1 tomcat]# cd /usr/local/tomcat/lib/
[root@web1 lib]# jar -xf catalina.jar
[root@web1 lib]# vim org/apache/catalina/util/ServerInfo.properties 
//Modify the content of version information to suit your needs
[root@web1 lib]# /usr/local/tomcat/bin/shutdown.sh //shutdown service
[root@web1 lib]# /usr/local/tomcat/bin/startup.sh //Start the service

After modification, the client looks at the version information again (operation 192.168.2.5):

[root@proxy ~]# curl -I http://192.168.2.100:8080/xx        
//Access non-existent page files to view header information
[root@proxy ~]# curl -I http://192.168.2.100:8080    
//Access existing page files to view header information
[root@proxy ~]# curl http://192.168.2.100:8080/xx
//Access non-existent page files to view error information

Modify the Tomcat server configuration file again, modify the version information, and manually add the server parameter (operation 192.168.2.100):

[root@web1 lib]# vim /usr/local/tomcat/conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"  redirectPort="8443" server="jacob" />
[root@web1 lib]# /usr/local/tomcat/bin/shutdown.sh //shutdown service
[root@web1 lib]# /usr/local/tomcat/bin/startup.sh //Start the service

After modification, the client looks at the version information again (operation 192.168.2.5):

[root@proxy ~]# curl -I http://192.168.2.100:8080/xx        
//Access non-existent page files to view header information
[root@proxy ~]# curl -I http://192.168.2.100:8080    
//Access existing page files to view header information
[root@proxy ~]# curl http://192.168.2.100:8080/xx
//Access non-existent page files to view error information

2) Degradation Start
The default Tomcat starts the service using the system's Senior Administrator account root, and starts the service using the average user whenever possible.

[root@web1 ~]# useradd tomcat
[root@web1 ~]# chown -R tomcat:tomcat /usr/local/tomcat/
//Modify the permissions of the tomcat directory so that the tomcat account has operational permissions on the directory
[root@web1 ~]# su -c /usr/local/tomcat/bin/startup.sh tomcat
//Switch to a tomcat account using the su command to start the tomcat service as the tomcat account
[root@web1 ~]# Chmod +x/etc/rc.local //This file is the startup boot file
[root@web1 ~]# Vim/etc/rc.local//Modify the file to add the following
su -c /usr/local/tomcat/bin/startup.sh tomcat

3) Delete the default test page

[root@web1 ~]# rm -rf  /usr/local/tomcat/webapps/*
145 original articles published, 3 praised, 5302 visited
Private letter follow

Tags: Nginx Tomcat Database MySQL

Posted on Wed, 12 Feb 2020 21:06:24 -0500 by Iasonic