Security Configuration of nginx on Linux server, nginx on linux Server
1. Common sense
In linux, to read a file, you must first have the execution permission on the folder where the file is located, and then read the file.
The execution of php files does not require the execution permission of the files. You only need the read permission of the nginx and php-fpm running accounts.
After a trojan is uploaded, whether the contents of a folder can be listed depends on the read permission of the php-fpm running account on the folder. The permission for executing commands on the trojan is related to the account permission of the php-fpm.
If the Trojan horse needs to execute the command, the php-fpm account must have the permission to execute the corresponding sh.
To read files in a folder, you do not need to have the read permission on the folder. You only need to have the execution permission on the folder.
1. Top Configuration
# Define the Nginx running user and user group user nginx; # process file pid/var/run/nginx. pid; # error log location and level, debug, info, notice, warn, error, criterror_log/var/log/nginx/error. log warn; # Number of processes of Nginx worker, which can be set to the number of available CPU cores. Worker_processes 8; # maximum number of file descriptors opened by each worker. The theoretical value should be the maximum number of opened files (the system value ulimit-n), which is different from the number of nginx processes, but the nginx allocation requests are not uniform. Therefore, we recommend that you keep the value consistent with the value of ulimit-n. Worker_rlimit_nofile 65535;
2. Events Module
Events {# set the maximum number of connections that a worker process opens at the same time worker_connections 2048; # Tell nginx to accept as many connections as possible after receiving a new connection notification multi_accept on; # Set the polling method used to reuse client threads. If you use Linux 2.6 +, you should use epoll. If you use * BSD, you should use kqueue. Use epoll ;}
3. HTTP Module
Http {# Hide the Nginx version to improve security. Server_tokens off; # enable the efficient file transmission mode. The sendfile command specifies whether Nginx calls the sendfile function to output files. For common applications, set it to on, if it is used for application disk I/O heavy load applications such as downloading, you can set it to off to balance the disk and network I/O processing speed and reduce the system load. Sendfile on; # Whether to enable access to the directory list. This option is disabled by default. Autoindex off; # Tell Nginx to send all header files in a data packet, instead of sending tcp_nopush on one by one; # Tell Nginx not to cache data, instead, you can send data in a certain segment. When you need to send data in a timely manner, you should set this attribute for the application. In this way, when sending a small piece of data, you cannot get the return value immediately. Nginx always works in the tcp nopush status by default. However, when the preceding sendfile on is enabled, the last package of nopush is automatically switched to nopush off. To reduce the latency of MS, enable nodelay on and quickly transfer it out. The conclusion is that sendfile on; When enabled, both tcp_nopush and tcp_nodelay are on. Tcp_nodelay on; # Set the log format to log_format main' $ remote_addr-$ remote_user [$ time_local] "$ request" ''$ status $ response" $ http_referer "'' "$ http_user_agent" "$ http_x_forwarded_for" '; # define access logs and set them to off to disable logs and improve the performance of access_log/var/log/nginx/access. log main; # connection timeout time, in the unit of seconds keepalive_timeout 120; # The timeout time for reading the HTTP header. The default value is 60. After the client establishes a connection with the server, it will start to receive the HTTP header. During this process, if the bytes sent from the client are not read within a time interval (timeout), the request times out, the system returns the 408 ("Request timed out") response to the client. Client_header_timeout 60; # The default value is 60. Similar to client_header_timeout, it is valid only when the HTTP packet body is read. Client_body_timeout 10; # The timeout time for sending a response. The default value is 60. That is, the Nginx server sends a data packet to the client, but the client never receives the data packet. If a connection exceeds the timeout value defined by send_timeout, Nginx will close the connection. Send_timeout 60; # the connection will be reset directly by sending an RST packet to the client after the connection times out. After this option is enabled, Nginx will send the RST Reset packet directly to the user instead of closing the TCP connection with four handshakes under normal circumstances after a connection times out, instead of waiting for the user's response, the Nginx server will release all the caches (such as TCP sliding windows) about the socket ). Compared with the normal shutdown method, the server avoids many TCP connections in the FIN_WAIT_1, FIN_WAIT_2, and TIME_WAIT states. Note: Using RST to reset the package to close the connection may cause some problems. It is not enabled by default. Reset_timedout_connection off; # To restrict connections, a container must first count the connections. "zone =" is a name for it, which can be called at will, the name must be consistent with the following limit_conn. $ Binary_remote_addr uses binary to store the client address. 1 m can store 32000 concurrent sessions. Limit_conn_zone $ binary_remote_addr zone = addr: 5 m; # set the maximum number of connections for the given key. Here the key is addr, and the value we set is 100, that is, we allow each IP address to open up to 100 connections at the same time. Limit_conn addr 100; # limit the speed of each connection to 100 kb. If an IP allows two concurrent connections, this IP address is limited to 200 kb. Limit_rate 100 k; # include is an instruction that contains the content of another file in the current file. Here we use it to load the file extension and file type ing table. Nginx sets the Content-Type value of the http Request Response Header Based on the ing relationship. When the ing table cannot be found, use the default value specified by default-type in nginx. conf. Include/etc/nginx/mime. types; # Set the default MIME-type default_type text/html; # default encoding charset UTF-8; # This module can read pre-compressed gz files, this reduces the CPU resource consumption for gzip compression for each request. After this module is enabled, nginx first checks whether there are files ending with the gz request for static files. If yes, the content of the gz file is directly returned. Gzip_static off; # enable gzip compression. Gzip on; # disable the gzip function when the client is IE6. Gzip_disable "msie6"; # enable Nginx as the reverse proxy. Value Options: off | expired | no-cache | no-sotre | private | no_last_modified | no_etag | auth | any gzip_proxied any; # sets the minimum number of page bytes that can be compressed, the number of page bytes is obtained from the Content-Length in the header. We recommend that you set the size to 1 kb. smaller than 1 kb may increase the pressure. Gzip_min_length 1024; # sets the Data Compression level. This level can be any number between 1 and 9, 9 is the slowest but the compression ratio is the largest. Gzip_comp_level 5; # set the system to obtain several units of cache for storing gzip compressed result data streams. For example, 4 k indicates that 4 k is used as the unit, and 4 times the size of raw data is used as the unit to apply for memory. If this parameter is not set, the default value is to apply for a memory space of the same size as the original data to store the gzip compression results. Gzip_buffers 4 16 k; # Set the data format to be compressed. Nginx only compresses text/html by default. Gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml + rss text/javascript; # specify the cache for opening the file, max is not enabled by default. It is recommended that the number of cached files be the same as the number of files opened. inactive indicates how long the files are deleted after they are not requested. Open_file_cache max = 65535 inactive = 30 s; # How long does it take to check the cache's valid information? open_file_cache_valid 30 s; # the minimum number of times files are used in the inactive parameter time in the open_file_cache command, if this number is exceeded, the file descriptor is always opened in the cache. The Last-Modified remains unchanged, because when nginx caches a static file, if it is still accessed within 30 s, its cache will always exist, it will not be accessed until 30 s. Open_file_cache_min_uses 2; # Whether to record the cache error open_file_cache_errors on; include/etc/nginx/conf. d/*. conf; include/etc/nginx/sites-enabled /*;}
4. SERVER Module
Server {# listening port. nginx will decide which SERVER segment to use based on the requested HOST. If server_name does not match, the first configuration file is used by default. With default_server, you can specify the default rules when no matching is found. # Listen 80; listen 80 default_server; # multiple domain names can be separated by spaces: server_name www.test.com test.com; root/user/share/nginx/html/test; #404 configure error_page 404/404 .html; # Configure ssl and enable it if necessary. Ssl on; ssl_certificate/etc/nginx/ssl/server. crt; ssl_certificate_key/etc/nginx/ssl/server. key; location/{index index.html index. php;} # Set the image cache time location ~. *. (Gif | jpg | jpeg | png | bmp | swf) $ {expires 10d;} # JS and CSS cache time settings location ~. *. (Js | css )? $ {Expires 1 h;} location ~ [^/] \. Php (/| $) {fastcgi_index index. php; # enable support for PATH_INFO. The function is to split the parameter into $ fastcgi_script_name and $ fastcgi_path_info according to the given regular expression. # For example, if this row is not configured for index. php/id/1, fastcgi_script_name is/index. php/id/1, and fastcgi_path_info is null. # Fastcgi_script_name is index. php, fastcgi_path_info is/id/1 fastcgi_split_path_info ^ (. + \. php )(. *) $; # The value of fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name; fastcgi_param PATH_INFO $ fastcgi_path_info; fastcgi_param PATH_TRANSLATED $ document_root $ fastcgi_path_info; # specify the listening port and address of the FastCGI server. Must be the same as the PHP-FPM settings. # Fastcgi_pass 127.0.0.1: 9000; fastcgi_pass unix:/var/run/php5-fpm.sock; include fastcgi_params ;}}
2. Common Methods
1. failed to execute the trojan after uploading: add the configuration in the nginx configuration file for the upload directory, so that the directory cannot be parsed by php
2. Disable non-website directory files after Trojan execution: cancel the permission of the php-fpm running account to read other directories.
3. The command cannot be executed after the trojan is executed: cancel the sh execution permission of the php-fpm account.
4. The permission cannot be too high after the command is executed: Do not use root for the php-fpm account or join the root group.
3. Specific Configuration
1. Prohibit PHP file access and execution
location ~ /(attachments|upload)/.*\.(php|php5)?$ { deny all;}
2. Prohibit Access from IP addresses
// Deny 10.0.0.0/24; // allowed allow 10.0.0.0/24; deny all;
3. restrict connections based on users' real IP addresses
# Obtain the original user's IP address map $ http_x_forwarded_for $ clientRealIp {"" $ remote_addr ;~ ^ (? P <firstAddr> [0-9 \.] + ),?. * $ FirstAddr; }## restrict limit_conn_zone $ clientRealIp zone = TotalConnLimitZone: 20 m; limit_conn TotalConnLimitZone 50; limit_conn_log_level notice; # limit_req_zone $ clientRealIp zone = ConnLimitZone: 20 m rate = 10r/s; # limit_req zone = ConnLimitZone burst = 10 nodelay; limit_req_log_level notice; # server {listen 80; location ~ \. Php $ {# A maximum of five queues. Because you process 10 requests and 5 queues per second, you can send up to 15 requests at a time, if there are more, the system will directly return the 503 error message to you. limit_req zone = ConnLimitZone burst = 5 nodelay; fastcgi_pass 127.0.0.1: 9000; fastcgi_index index. php; includefastcgi_params ;}}
4. Obtain the IP address of the original user after multi-layer CDN and configure nginx
Map $ http_x_forwarded_for $ clientRealIp {# Use remote_addr directly without proxy "" $ remote_addr; # use regular expression matching, obtain the user's original IP address from x_forwarded_for # For example, X-Forwarded-For: 202.123.123.11, 208.22.22.234, 192.168.2.100 ,... # here, the first 202.123.123.11 is the user's real IP address, followed by the CDN server ~ ^ (? P <firstAddr> [0-9 \.] + ),?. * $ FirstAddr; }## using the map command, we created a variable $ clientRealIp for nginx, which is the real IP address of the original user. ## no matter whether the user accesses it directly, we can still get the correct original IP address through access after a string of CDN
5. Hide version information
Server_tokens off; proxy_hide_header X-Powered-By; // or modify the source code during compilation.
6. disable unnecessary methods
if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444;}
7. Disable Extension
location ~* .(txt|doc|sql|gz|svn|git)$ { deny all;}
8. properly configure the Response Header
add_header Strict-Transport-Security "max-age=31536000";add_header X-Frame-Options deny;add_header X-Content-Type-Options nosniff;add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://a.disquscdn.com; img-src 'self' data: https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; frame-src https://disqus.com";
Strict-Transport-Security
(HSTS for short) can tell the browser to always access through HTTPS within the specified max-age
X-Frame-Options
Specifies whether the webpage can be nested by iframe. deny means no Nesting is allowed.
9. reject some User-Agents
if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403;}
10. Prevent image leeching
valid_referers blocked www.example.com example.com;if ($invalid_referer) { rewrite ^/images/uploads.*\.(gif|jpg|jpeg|png)$ http://www.examples.com/banned.jpg last}
11. Control Buffer Overflow attacks
client_body_buffer_size 1K;client_header_buffer_size 1k;client_max_body_size 1k;large_client_header_buffers 2 1k;client_body_timeout 10;client_header_timeout 10;keepalive_timeout 5 5;send_timeout 10;
Description
1. client_body_buffer_size 1 k-(8 k or 16 k by default) This command can specify the buffer size of the Connection Request Entity. If the connection request exceeds the value specified in the cache, the whole or part of these request entities will try to write into a temporary file.
2. The client_header_buffer_size 1 k-command specifies the buffer size of the client request header. In most cases, the next request header is not greater than 1 k. However, if a large cookie from the wap client is larger than 1 k, Nginx will allocate a larger buffer, this value can be set in large_client_header_buffers.
3. The client_max_body_size 1 k-command specifies the maximum Request Entity size allowed for client connection. It appears in the Content-Length Field of the request header. If the Request is greater than the specified value, the client will receive a "Request Entity Too Large" (413) error. Remember, the browser does not know how to display this error.
4. large_client_header_buffers-specify the number and size of buffers used by some large request headers on the client. The Request field cannot exceed the buffer size. If the client sends a large header, nginx returns "Request URI too large" (414)
1. client_body_timeout 10;-The command specifies the time-out time for reading the request object. The timeout here means that a Request entity does not enter the read step. If the connection exceeds this time and the client does not respond, Nginx returns a "Request time out" (408) error.
2. client_header_timeout 10;-The command specifies the timeout time for reading the client request header title. Timeout indicates that a Request header does not enter the read step. If the connection exceeds this time and the client does not respond, Nginx returns a "Request time out" (408) error.
3. keepalive_timeout 5;-the first value of the parameter specifies the timeout value for the long connection between the client and the server. If the timeout value is exceeded, the server closes the connection. The second value of the parameter (optional) specifies the time value of Keep-Alive: timeout = time in the Response Header. This value allows some browsers to know when to close the connection, so that the server does not need to be shut down repeatedly. If this parameter is not specified, nginx will not send the Keep-Alive information in the response header. (But this does not mean how to connect "Keep-Alive") the two values of the parameter can be different.
4. send_timeout 10; the command specifies the Timeout time after the response is sent to the client. Timeout indicates that the handshake is completed only when the client does not enter the full established status, if the client does not respond after this time, nginx will close the connection.
12. Control concurrent connections
limit_zone slimits $binary_remote_addr 5m;limit_conn slimits 5;
13. Configure sysctl. conf
# Avoid a smurf attacknet.ipv4.icmp_echo_ignore_broadcasts = 1 # Turn on protection for bad icmp error messagesnet.ipv4.icmp_ignore_bogus_error_responses = 1 # Turn on syncookies for SYN flood attack protectionnet.ipv4.tcp_syncookies = 1 # Turn on and log spoofed, source routed, and redirect packetsnet.ipv4.conf.all.log_martians = 1net.ipv4.conf.default.log_martians = 1 # No source routed packets herenet.ipv4.conf.all.accept_source_route = 0net.ipv4.conf.default.accept_source_route = 0 # Turn on reverse path filteringnet.ipv4.conf.all.rp_filter = 1net.ipv4.conf.default.rp_filter = 1 # Make sure no one can alter the routing tablesnet.ipv4.conf.all.accept_redirects = 0net.ipv4.conf.default.accept_redirects = 0net.ipv4.conf.all.secure_redirects = 0net.ipv4.conf.default.secure_redirects = 0 # Don't act as a routernet.ipv4.ip_forward = 0net.ipv4.conf.all.send_redirects = 0net.ipv4.conf.default.send_redirects = 0 # Turn on execshildkernel.exec-shield = 1kernel.randomize_va_space = 1 # Tuen IPv6net.ipv6.conf.default.router_solicitations = 0net.ipv6.conf.default.accept_ra_rtr_pref = 0net.ipv6.conf.default.accept_ra_pinfo = 0net.ipv6.conf.default.accept_ra_defrtr = 0net.ipv6.conf.default.autoconf = 0net.ipv6.conf.default.dad_transmits = 0net.ipv6.conf.default.max_addresses = 1 # Optimization for port usefor LBs# Increase system file descriptor limitfs.file-max = 65535 # Allow for more PIDs (to reduce rollover problems); may break some programs 32768kernel.pid_max = 65536 # Increase system IP port limitsnet.ipv4.ip_local_port_range = 2000 65000 # Increase TCP max buffer size setable using setsockopt()net.ipv4.tcp_rmem = 4096 87380 8388608net.ipv4.tcp_wmem = 4096 87380 8388608 # Increase Linux auto tuning TCP buffer limits# min, default, and max number of bytes to use# set max to at least 4MB, or higher if you use very high BDP paths# Tcp Windows etcnet.core.rmem_max = 8388608net.core.wmem_max = 8388608net.core.netdev_max_backlog = 5000net.ipv4.tcp_window_scaling = 1
14. Limit the number of connections of each IP address at the firewall level
/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 15 -j DROP
15. Restrict Nginx connection outgoing traffic
/sbin/iptables -A OUTPUT -o eth0 -m owner --uid-owner vivek -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
...
Reference
Http://www.bzfshop.net/article/176.html
Http://nginx.org/en/docs/
Http://www.oschina.net/translate/nginx-setup
Http://www.ha97.com/5194.html