PHP+NGINX伺服器效能安全最佳化

本文適用於 php7。4+NGINX環境,適用於執行 wordpress 環境

一、更新伺服器

sudo apt update

二、命令快捷縮寫設定

透過ssh登入伺服器,在使用者目錄下執行以下命令

sudo nano 。bashrcalias ngt=‘sudo nginx -t’alias ngr=‘sudo systemctl reload nginx’alias fpmr=‘sudo systemctl reload php7。4-fpm’alias rr=‘sudo systemctl restart redis’alias mdr=‘sudo systemctl restart mariadb’alias rb=‘sudo reboot’alias fup=‘sudo apt-get -y update;sudo apt-get -y full-upgrade;sudo apt-get -y autoremove; sudo apt-get -y autoclean’

按CTRL+S儲存, CTRL+X退出

執行

source 。bashrc

重啟伺服器使簡化命令生效

後面要重啟 nginx 或者 過載 nginx 只需要執行 ngt 或者 ngr 即可!

三、設定 nginx。conf

通常位於 /etc/nginx 目錄下

# HTTP Header Server Delete for information leakload_module modules/ngx_http_headers_more_filter_module。so;# Run as a unique, less privileged user for security reasons。# Default: nobody nobodyuser www-data www-data;# Sets the worker threads to the number of CPU cores available in the system for best performance。# Should be > the number of CPU cores。# Maximum number of connections = worker_processes * worker_connections# Default: 1worker_processes auto;# Maximum number of open files per worker process。# Should be > worker_connections。# Default: no limitworker_rlimit_nofile 15000;events { # If you need more connections than this, you start optimizing your OS。 # That‘s probably the point at which you hire people who are smarter than you as this is *a lot* of requests。 # Should be < worker_rlimit_nofile。 # Default: 512 worker_connections 4096; multi_accept on; use epoll;}# Log errors to this file# This is only used when you don’t override it on a server{} level# Default: logs/error。log errorerror_log /var/log/nginx/error。log error;# The file storing the process ID of the main process# Default: nginx。pidpid /var/run/nginx。pid;http { # Basic Settings server_tokens off; more_clear_headers ‘Server’; server_names_hash_bucket_size 64; # Webp Map Directives map $http_accept $webp_suffix { default “”; “~*webp” “。webp”; } # Specify MIME types for files。 include mime。types; # Rate Limit limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m; # Default: text/plain default_type application/octet-stream; # Update charset_types to match updated mime。types。 # text/html is always included by charset module。 # Default: text/html text/xml text/plain text/vnd。wap。wml application/javascript application/rss+xml charset_types text/css text/plain text/vnd。wap。wml application/javascript application/json application/rss+xml application/xml; # Include $http_x_forwarded_for within default format used in log files log_format main ‘$remote_addr - $remote_user [$time_local] “$request” ’ ‘$status $body_bytes_sent “$http_referer” ’ ‘“$http_user_agent” “$http_x_forwarded_for”’; # Log access to this file # This is only used when you don‘t override it on a server{} level # Default: logs/access。log combined # access_log /var/log/nginx/access。log main; access_log none; # How long to allow each connection to stay idle。 # Longer values are better for each individual client, particularly for SSL, # but means that worker connections are tied up longer。 # Default: 75s keepalive_timeout 100s; keepalive_requests 1000; # Timeout for reading client request body。 # Default: 60s client_body_timeout 3m; # Timeout for reading client request header。 # Default: 60s client_header_timeout 3m; # Timeout for transmitting reponse to client。 # Default: 60s send_timeout 3m; # Set the maximum allowed size of client request body。 This should be set # to the value of files sizes you wish to upload to the server。 # You may also need to change the values `upload_max_filesize` and `post_max_size` within # your php。ini for the changes to apply。 # Default: 1mB client_max_body_size 64m; client_body_buffer_size 10k; client_header_buffer_size 1k; large_client_header_buffers 4 32k; # Some WP plugins that push large amounts of data via cookies # can cause 500 HTTP erros if these values aren’t increased。 # Default: 8 4k|8k; fastcgi_buffers 16 16k; # Default: 4k|8k fastcgi_buffer_size 32k; # Some other Fastcgi configs fastcgi_busy_buffers_size 64k; fastcgi_temp_file_write_size 64k; fastcgi_read_timeout 300; # File Handler Cache open_file_cache max=1500 inactive=30s; open_file_cache_valid 30s; open_file_cache_min_uses 5; open_file_cache_errors off; # Speed up file transfers by using sendfile() to copy directly # between descriptors rather than using read()/write()。 # For performance reasons, on FreeBSD systems w/ ZFS # this option should be disabled as ZFS‘s ARC caches # frequently used files in RAM by default。 # Default: off sendfile on; # Don’t send out partial frames; this increases throughput # since TCP frames are filled up before being sent out。 # Default: off tcp_nopush on; # Enable gzip compression。 # Default: off gzip on; gzip_disable “msie6”; gzip_buffers 16 8k; gzip_http_version 1。1; # Compression level (1-9)。 # 5 is a perfect compromise between size and CPU usage, offering about # 75% reduction for most ASCII files (almost identical to level 9)。 # Default: 1 gzip_comp_level 5; # Don‘t compress anything that’s already small and unlikely to shrink much # if at all (the default is 20 bytes, which is bad as that usually leads to # larger files after gzipping)。 # Default: 20 gzip_min_length 256; # Compress data even for clients that are connecting to us via proxies, # identified by the “Via” header (required for CloudFront)。 # Default: off gzip_proxied any; # Tell proxies to cache both the gzipped and regular version of a resource # whenever the client‘s Accept-Encoding capabilities header varies; # Avoids the issue where a non-gzip capable client (which is extremely rare # today) would display gibberish if their proxy gave them the gzipped version。 # Default: off gzip_vary on; # Compress all output labeled with one of the following MIME-types。 # text/html is always compressed by gzip module。 # Default: text/html gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd。geo+json application/vnd。ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd。rim。location。xloc text/vtt text/x-component text/x-cross-domain-policy; # This should be turned on if you are going to have pre-compressed copies (。gz) of # static files available。 If not it should be left off as it will cause extra I/O # for the check。 It is best if you enable this in a location{} block for # a specific directory, or on an individual server{} level。 # gzip_static on; # Include files in the sites-enabled folder。 server{} configuration files should be # placed in the sites-available folder, and then the configuration should be enabled # by creating a symlink to it in the sites-enabled folder。 # See doc/sites-enabled。md for more info。 include sites-enabled/*;}

四、設定站點nginx配置 [防止攻擊]

位置通常位於 /etc/nginx/sites-available/{{domain}}/server

1、新建 block-agent。conf

sudo nano block-agent。conf#### BLOCK USER AGENTS###set $block_user_agents 0;if ($http_user_agent ~ “Screaming Frog SEO Spider”) { set $block_user_agents 1;}if ($http_user_agent ~ “Indy Library”) { set $block_user_agents 1;}if ($http_user_agent ~ “libwww-perl”) { set $block_user_agents 1;}if ($http_user_agent ~ “GetRight”) { set $block_user_agents 1;}if ($http_user_agent ~ “GetWeb!”) { set $block_user_agents 1;}if ($http_user_agent ~ “Go!Zilla”) { set $block_user_agents 1;}if ($http_user_agent ~ “Download Demon”) { set $block_user_agents 1;}if ($http_user_agent ~ “Go-Ahead-Got-It”) { set $block_user_agents 1;}if ($http_user_agent ~ “TurnitinBot”) { set $block_user_agents 1;}if ($http_user_agent ~ “GrabNet”) { set $block_user_agents 1;}if ($http_user_agent ~ “dirbuster”) { set $block_user_agents 1;}if ($http_user_agent ~ “nikto”) { set $block_user_agents 1;}if ($http_user_agent ~ “SF”) { set $block_user_agents 1;}if ($http_user_agent ~ “sqlmap”) { set $block_user_agents 1;}if ($http_user_agent ~ “fimap”) { set $block_user_agents 1;}if ($http_user_agent ~ “nessus”) { set $block_user_agents 1;}if ($http_user_agent ~ “whatweb”) { set $block_user_agents 1;}if ($http_user_agent ~ “Openvas”) { set $block_user_agents 1;}if ($http_user_agent ~ “jbrofuzz”) { set $block_user_agents 1;}if ($http_user_agent ~ “libwhisker”) { set $block_user_agents 1;}if ($http_user_agent ~ “webshag”) { set $block_user_agents 1;}if ($http_user_agent ~ “Acunetix-Product”) { set $block_user_agents 1;}if ($http_user_agent ~ “Acunetix”) { set $block_user_agents 1;}if ($block_user_agents = 1) { return 403;}

2。新建 protext-sql-exploit-spam。conf

sudo nano protext-sql-exploit-spam。conf#### SQL INJECTIONS###set $block_sql_injections 0;if ($query_string ~ “union。*select。*\(”) { set $block_sql_injections 1;}if ($query_string ~ “union。*all。*select。*”) { set $block_sql_injections 1;}if ($query_string ~ “concat。*\(”) { set $block_sql_injections 1;}if ($block_sql_injections = 1) { return 403;}#### COMMON EXPLOITS###set $block_common_exploits 0;if ($query_string ~ “(<|%3C)。*script。*(>|%3E)”) { set $block_common_exploits 1;}if ($query_string ~ “GLOBALS(=|\[|\%[0-9A-Z]{0,2})”) { set $block_common_exploits 1;}if ($query_string ~ “_REQUEST(=|\[|\%[0-9A-Z]{0,2})”) { set $block_common_exploits 1;}if ($query_string ~ “proc/self/environ”) { set $block_common_exploits 1;}if ($query_string ~ “mosConfig_[a-zA-Z_]{1,21}(=|\%3D)”) { set $block_common_exploits 1;}if ($query_string ~ “base64_(en|de)code\(。*\)”) { set $block_common_exploits 1;}if ($block_common_exploits = 1) { return 403;}#### BLOCK SPAM###set $block_spam 0;if ($query_string ~ “\b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)\b”) { set $block_spam 1;}if ($query_string ~ “\b(erections|hoodia|huronriveracres|impotence|levitra|libido)\b”) { set $block_spam 1;}if ($query_string ~ “\b(ambien|blue\spill|cialis|cocaine|ejaculation|erectile)\b”) { set $block_spam 1;}if ($query_string ~ “\b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)\b”) { set $block_spam 1;}if ($block_spam = 1) { return 403;}

3、新建 rate-limit。conf

#### Rate Limit for wp-login。php#### domain1不帶。com字尾# domain2 完整域名location = /wp-login。php {limit_req zone=one burst=2 nodelay;limit_req_status 444;include fastcgi。conf;fastcgi_pass unix:/run/php/php7。4-{{domain1}}。sock;include sites-available/{{domain2}}/location/*;}

五、設定 redis

通常位於 /etc/redis/redis。conf

maxmemory 1024mb maxmemory-policy allkeys-lru

六、設定 wp-config。php

/* Memory */define( ’WP_MEMORY_LIMIT‘, ’1024M‘ );/* Undertstand which query */define(’SAVEQUERIES‘, true);/* Disable WP Cron */define( ’DISABLE_WP_CRON‘, true );/* Auto Update */define( ’WP_AUTO_UPDATE_CORE‘, false );/* Debuging */define( ’WP_DEBUG‘, true );define( ’WP_DEBUG_DISPLAY‘, false );define( ’WP_DEBUG_LOG‘, true );/* Dont Allow File Edit */define( ’DISALLOW_FILE_EDIT‘, true );

關於PHP設定,由於程式碼太長,不方便貼出來。下一遍我們將會把以上程式碼做成sh檔案,一鍵自動執行最佳化。