Hướng dẫn setup server VPS host ASP.Net , .Net Core + MongoDB + Nginx và bảo vệ server cơ bản bằng ufw + fail2ban. (Phần 2 – hướng dẫn setup nginx)

Nối tiếp bài viết trước bài viết trướcPhần 1 – Cài đặt môi trường và firewall Hôm nay mình sẽ hướng dẫn setup nginx cơ bản, cách tăng tốc và bảo vệ website của bạn. Cài đặt Nginx: Tham khảo: “https://nginx.org/en/docs/“ Nginx là một trong những web server phổ biến nhất trên thế giới và

Nối tiếp bài viết trước bài viết trướcPhần 1 – Cài đặt môi trường và firewall
Hôm nay mình sẽ hướng dẫn setup nginx cơ bản, cách tăng tốc và bảo vệ website của bạn.

Cài đặt Nginx:

Tham khảo: “https://nginx.org/en/docs/

Nginx là một trong những web server phổ biến nhất trên thế giới và chịu trách nhiệm lưu trữ một số trang web lớn và có lưu lượng truy cập cao trên internet. Nó là một lựa chọn nhẹ có thể được sử dụng như một web server or reverse proxy.
Đầu tiên mình sẽ kiểm tra nginx có đang run:

systemctl status nginx
Output
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2020-04-20 16:08:19 UTC; 3 days ago
     Docs: man:nginx(8)
 Main PID: 2369 (nginx)
    Tasks: 2 (limit: 1153)
   Memory: 3.5M
   CGroup: /system.slice/nginx.service
           ├─2369 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
           └─2380 nginx: worker process

Hoặc mở web http://your_server_ip

Câu lệnh để quản lý Nginx Process:

Stop web server:

sudo systemctl stop nginx

Start web server khi nginx stop:

sudo systemctl start nginx

Stop và start lại nginx:

sudo systemctl restart nginx

Nếu bạn chỉ thực hiện thay đổi cấu hình, Nginx thường có thể tải lại mà không làm rớt kết nối. Để làm điều này, hãy nhập:

sudo systemctl reload nginx

Theo mặc định, Nginx được định cấu hình để khởi động tự động khi máy chủ khởi động. Nếu đây không phải là những gì bạn muốn, bạn có thể vô hiệu hóa hành vi này bằng cách nhập:

sudo systemctl disable nginx

Để bật lại dịch vụ khởi động khi khởi động, bạn có thể nhập:

sudo systemctl enable nginx

Làm quen với các tệp và thư mục Nginx quan trọng

Server Configuration

*     /etc/nginx: The Nginx configuration directory. All of the Nginx configuration files reside here.
*     /etc/nginx/nginx.conf: The main Nginx configuration file. This can be modified to make changes to the Nginx global configuration.
*     /etc/nginx/sites-available/: The directory where per-site server blocks can be stored. Nginx will not use the configuration files found in this directory unless they are linked to the sites-enabled directory. Typically, all server block configuration is done in this directory, and then enabled by linking to the other directory.
*     /etc/nginx/sites-enabled/: The directory where enabled per-site server blocks are stored. Typically, these are created by linking to configuration files found in the sites-available directory.
>     /etc/nginx/snippets: This directory contains configuration fragments that can be included elsewhere in the Nginx configuration. Potentially repeatable configuration segments are good candidates for refactoring into snippets.

Server Logs

*     /var/log/nginx/access.log: Every request to your web server is recorded in this log file unless Nginx is configured to do otherwise.
*     /var/log/nginx/error.log: Any Nginx errors will be recorded in this log.

Cài đặt server blocks

Khi sử dụng Nginx web server, các web server blocks được sử dụng để cấu hình chi tiết web server và file thực thi. Mình sẽ thiết lập web server tên miền your_domain, bạn nên thay thế bằng tên miền của bạn. Nếu có nhiều tên miền hoặc web service bạn có thể thêm block ở đây mình sẽ có thêm 1 guest , 1 api.

sudo mkdir -p /var/www/your_domain
sudo mkdir -p /var/www/guest
sudo mkdir -p /var/www/api

Tiếp theo, chỉ định quyền sở hữu thư mục với biến môi trường $ USER , thường thì mình sẽ dùng user www-data cho các thưc mục chưa html, các file load trên web.

sudo chown -R www-data:www-data /var/www/your_domain/html
sudo chown -R www-data:www-data /var/www/your_domain/wwwroot
sudo chown -R www-data:www-data /var/www/guest/html

Chỉ định permissions của web, quyền đọc(read), ghi(write) và thực thi file (execute). Các bạn nên chỉ định chính xác quyền sẽ cấp cho thưc mục và files để tăng tính bảo mật. Thông thường “Directories 755 , Files 644”.
Tham khảo “https://www.pluralsight.com/blog/it-ops/linux-file-permissions

sudo chmod  755 /var/www/your_domain
sudo chmod  755 /var/www/guest
sudo chmod -R 644 /var/www/your_domain/
sudo chmod -R 644 /var/www/guest/

Tiếp theo sửa file configuration block của nginx:

sudo nano /etc/nginx/sites-available/your_domain

Thêm vào nội dung:

server {
        listen 80;
        listen [::]:80;
        server_name your_domain www.your_domain;

        location / {
                 root /var/www/your_domain;
                 proxy_pass        https://localhost:5001;
                try_files $uri $uri/ =404;
        }
}

Tiếp theo, hãy kích hoạt tệp bằng cách tạo một liên kết từ nó đến thư mục hỗ trợ trang web, mà Nginx đọc từ đó trong khi khởi động:

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

Hai khối máy chủ hiện đã được kích hoạt và được định cấu hình để phản hồi các yêu cầu dựa trên các lệnh nghe và server_name của chúng (bạn có thể đọc thêm về cách Nginx xử lý các lệnh này tại đây):

your_domain: Sẽ phản hồi các yêu cầu cho your_domain và www.your_domain.
default: Sẽ phản hồi bất kỳ yêu cầu nào trên cổng 80 không khớp với hai khối còn lại.

Tiếp theo, hãy kiểm tra để đảm bảo rằng không có lỗi cú pháp nào trong bất kỳ tệp Nginx nào của bạn:

sudo nginx -t

Nếu không có bất kỳ sự cố nào, hãy khởi động lại Nginx để kích hoạt các thay đổi của bạn:

sudo systemctl restart nginx

Tiếp theo mình sẽ hướng dẫn cài đặt nginx cho server name your_domain với usecase cho nhiều project cùng chạy trên domain.

Trong trường hợp web site của mình có 3 project chạy cùng domain:

  • your_domain cho user thường dùng. https://localhost:5001
  • your_domain/guest cho user không cần đăng nhập dùng với giao diện khác và chức năng hạn chế. https://localhost:5002
  • your_domain/api dùng cho api server. https://localhost:5003Lưu ý cách làm này có thể làm giảm hiệu năng của server và có thể tạo bottleneck. Có nhiều cách tốt hơn như tạo sub domain, thêm IP hoặc thêm VPS
    Mình sẽ setting server blocks bằng cách regex url để reverse proxy về project.
sudo nano /etc/nginx/sites-available/your_domain
server {
        listen 80;
        listen [::]:80;
        server_name your_domain www.your_domain;

        location ~ ^/(?!api|guest)  {
                 root /var/www/your_domain;
                 proxy_pass        https://localhost:5001;
                try_files $uri $uri/ =404;
        }
          location ~ ^/(guest)  {
                 root /var/www/guest;
                 proxy_pass        https://localhost:5002;
                try_files $uri $uri/ =404;
        }
           location ~ ^/(api)  {
                 root /var/www/api;
                 proxy_pass        https://localhost:5003;
                try_files $uri $uri/ =404;
        }
}

Cải thiện hiệu năng và bảo vệ server bằng nginx:

Tiếp theo mình sẽ hướng dẫn các bạn cách cải thiện hiệu năng và bảo vệ server bằng nginx cơ bản. Hy vọng sẽ giúp server ổn định cũng như giảm các cuộc tấn công làm downtime server.

Tham khảo: https://github.com/denji/nginx-tuning , https://gist.github.com/denji/8359866

Đầu tiên mình sẽ thêm fillter và block

*** SQL injections

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;
    	}
  • File injections:
set $block_file_injections 0;
    	if ($query_string ~ "[a-zA-Z0-9_]=http://") {
        	set $block_file_injections 1;
    	}
    	if ($query_string ~ "[a-zA-Z0-9_]=(..//?)+") {
        set $block_file_injections 1;
    	}
    	if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") {
        	set $block_file_injections 1;
    	}
    	if ($block_file_injections = 1) {
        	return 403;
    	}

Mình sẽ fillter và block các exploits đơn giản

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;
    	}

Chặn các user agents bất thường phổ biến
Thường các User-Agent sẽ thay đổi trong quá trình tấn công, nên cách này không hiệu quả. Bạn nên theo dõi server hoặc viết 1 script để tự thêm user-agent.

## Block user agents
	set $block_user_agents 0;
	# Don't disable wget if you need it to run cron jobs!
	if ($http_user_agent ~ "Wget") {
	set $block_user_agents 1;
	}
	 # Disable Akeeba Remote Control 2.5 and earlier
   	if ($http_user_agent ~ "Indy Library") {
        set $block_user_agents 1;
    	}

   	 # Common bandwidth hoggers and hacking tools.
   	 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 ($block_user_agents = 1) {
        return 403;
    	}

Bạn có thể xem log nginx để thêm các fillter trong quá trình website hoạt động để chống lại các truy cập bất thường

Giới thiệu cho bạn 1 tools đơn giản và hiệu quả mình đang dùng “https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker” đừng quên donate cho tác giả đã đóng góp cho cộng đồng.

Chống DDoS đơn giản:

Giới hạn số connection và request.

# limit the number of connections per single IP
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;

# limit the number of requests for a given session
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=5r/s;

# zone which we want to limit by upper values, we want limit whole server
server {
    limit_conn conn_limit_per_ip 10;
    limit_req zone=req_limit_per_ip burst=10 nodelay;
}

# if the request body size is more than the buffer size, then the entire (or partial)
# request body is written into a temporary file
client_body_buffer_size  128k;

# buffer size for reading client request header -- for testing environment
client_header_buffer_size 3m;

# maximum number and size of buffers for large headers to read from client request
large_client_header_buffers 4 256k;

# read timeout for the request body from client -- for testing environment
client_body_timeout   3m;

# how long to wait for the client to send a request header -- for testing environment
client_header_timeout 3m;

Thêm Client-Side Certificate Authentication with nginx
Mình sẽ thêm Client-Side Certificate Authentication cho api server, hoặc server chỉ dùng nội bộ.
Tham khảo “https://fardog.io/blog/2017/12/30/client-side-certificate-authentication-with-nginx/” để tạo file certificate

    # client certificate
    ssl_client_certificate /etc/nginx/client_certs/ca.crt;
    # make verification optional, so we can display a 403 message to those
    # who fail authentication
    ssl_verify_client optional;
       location ~ ^/(api)  {
    
        # if the client-side certificate failed to authenticate, show a 403
        # message to the client
       if ($ssl_client_verify != SUCCESS) {
        return 403;
       }
      
      }

Cải thiện hiệu năng:

Nginx hỗ trợ nhiều loại cache (Disk, Ram) với nhiều cách config khác nhau tùy theo nhu cầu và cấu hình server của bạn.
Tham khảo “https://www.linuxcapable.com/nginx-optimization-tuning-with-caching/

Traditional Disk cache
Đầu tiên tạo thư mục cache:

sudo mkdir -p /cache/tmpfs/

Tiếp theo, thêm phần sau vào khối máy chủ của bạn, sửa đổi khối máy chủ proxy hiện có và thêm các tính năng bổ sung.

proxy_cache_path /cache/nginx/tmpfs levels=1:2 keys_zone=my_cache:100m max_size=6g inactive=1d use_temp_path=off;
server {
    ...
    location / {
        proxy_cache my_cache;
        proxy_cache_key $scheme$request_method$proxy_host$request_uri;
        proxy_cache_valid 404 302 1m;
        proxy_cache_valid 200 1d;
        proxy_http_version   1.1;
        add_header X-Cache-Status $upstream_cache_status;
        proxy_cache_background_update on;
        proxy_cache_lock on;
    }
    ...
}

Cài đặt cache cho các file static thường dùng:

if ( $http_referer  ~* ^.+.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg))
	{
            access_log off;
    		expires 30d;
    		add_header Cache-Control public;
            add_header Vary Accept-Encoding;
            ## No need to bleed constant updates. Send the all shebang in one
    		## fell swoop.
    		#tcp_nodelay off;

    		## Set the OS file cache.
    		#open_file_cache max=3000 inactive=120s;
    		#open_file_cache_valid 45s;
    		#open_file_cache_min_uses 2;
    		#open_file_cache_errors off;
	}

Nginx cache in RAM
Nếu máy chủ của bạn có tài nguyên, bộ cache vào RAM sẽ luôn tốt hơn disk, điều này thậm chí còn áp dụng cho các ổ SSD tối tân. Điều này là nhằm hướng tới các máy chủ tự quản lý và có nguồn tài nguyên dồi dào như ram không làm gì cả.

Đầu tiên, tạo một thư mục mới để lưu vào bộ nhớ đệm trong RAM:

sudo mkdir -p /cache/nginx/tmpfs

Thứ hai, gắn kết thư mục đã tạo trong RAM với (tmpfs) bằng lệnh sau:

sudo mount -t tmpfs -o size=2g tmpfs /cache/nginx/tmpfs

Điều này gắn (/data/nginx/tmpfs) trong RAM, phân bổ 2 GB. Điều này có thể được điều chỉnh tăng hoặc giảm. Các máy chủ nhỏ hơn sẽ bắt đầu với 512MB thay vì 2g
Nếu bạn cần ngắt kết nối, hãy thực thi đoạn mã sau:

sudo umount /cache/nginx/ramcache

Để hoàn tất thiết lập với bộ nhớ đệm RAM với Nginx, bạn cần thêm phần sau vào (/ etc / fstab), để khi máy chủ tự động khởi động lại, thư mục bộ nhớ đệm RAM sẽ được tạo lại.

sudo nano /etc/fstab
tmpfs /cache/nginx/tmpfs tmpfs defaults,size=1g 0 0

Tổng kết:

Bài viết này mình đã hướng dẫn các bạn cài đặt môi trường nginx và setup cơ bản để bảo vệ server an toàn hơn. Nếu có thắc mắc hoặc câu hỏi cần sự giúp đỡ thì đừng ngần ngại comment. Cảm ơn các bạn đã theo dõi, ở phần tiếp theo mình sẽ hướng dẫn setup để HOST 1 web server dùng ASP.Net , .Net Core và mongodb cũng như một số mẹo mà mình biết.

Một phút quảng cáo, mình đang dùng VPS trên digitalocean.com. Đang có chương trình tặng 100$ cho account sử dụng trong 60 ngày, hãy đăng kí sử dụng và dùng invite link này “https://m.do.co/c/666bcca701f7” để ủng hộ mình.

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ