Cách sử dụng Nginx's map Module trên CentOS 7

3 năm trước

Cách sử dụng Nginx's map Module trên CentOS 7

Giới Thiệu 

Khi định cấu hình máy chủ cho trang web, có một số hành động có điều kiện thông thường mà bạn có thể cần phải triển khai. Ví dụ: có thể một số tệp nên được lưu trong trình duyệt của người dùng lâu hơn các trình duyệt khác hoặc một số phần của trang web chỉ được phép thông qua kết nối an toàn (như bất kỳ thứ gì yêu cầu mật khẩu của người dùng),trong khi các phần khác của trang web thì không.

Một ví dụ đơn giản, phổ biến khác là đảm bảo rằng khi một trang web mới được xuất bản thay cho một trang web cũ, tất cả các địa chỉ cũ sẽ chuyển hướng đến các địa điểm chính xác. Điều này rất hữu ích vì nó có nghĩa là các liên kết và dấu trang cũ sẽ không ngừng hoạt động và nó cũng bảo toàn bộ nhớ đệm của Google.

Nginx's map module cho phép bạn tạo các biến trong tập tin cấu hình của Nginx có các giá trị có điều kiện - nghĩa là chúng phụ thuộc vào các giá trị của các biến khác. Trong hướng dẫn này, chúng tôi sẽ giới thiệu cách sử dụng map module của Nginx để thực hiện hai ví dụ: cách thiết lập danh sách chuyển hướng từ URL trang web cũ sang trang web mới và cách tạo danh sách trắng các quốc gia để kiểm soát lưu lượng truy cập đến trang web của bạn.

 

Yêu Cầu 

Để làm theo hướng dẫn này , bạn cần :

 

Bước 1 - Tạo và thử nghiệm một trang web ví dụ

Đầu tiên, chúng ta sẽ tạo một tệp thử nghiệm đại diện cho một trang web mới được xuất bản. Chúng ta sẽ sử dụng tệp này để kiểm tra cấu hình .

Hãy tạo một trang đơn giản, index.html , trong thư mục trang web Nginx mặc định. Tệp này sẽ chỉ có văn bản thuần túy mô tả nội dung bên trong: Home. .

sudo sh -c 'echo "Home" > /usr/share/nginx/html/index.html'

Với tệp thử nghiệm này tại chỗ, tiếp theo chúng ta sẽ kiểm tra xem nó có đang được phục vụ đúng với curl hay không. Chúng ta không cần phải chỉ định index.html cho lệnh này vì tệp đó được phân phát theo mặc định nếu không có tên tệp chính xác nào được cung cấp.

curl http://localhost/

Đáp lại, bạn sẽ thấy một từ duy nhất nói về  Home giống như dưới đây:

Nginx response
Home

Bây giờ, hãy thử truy cập một tệp không tồn tại trong /usr/share/nginx/html, như old.html.

curl -L http://localhost/old.html

Phản hồi sẽ là thông báo lỗi hệ thống, 404 Not Found, nghĩa là trang không tồn tại :

Nginx response

. . .

Chúng ta chỉ sử dụng trang web giả trong hướng dẫn này, nhưng nếu old.html là một trang trên trang web thực sự đã từng tồn tại và đã bị xóa, trả về 404 có nghĩa là tất cả các liên kết đến trang đó đều bị hỏng. Điều này ít hơn lý tưởng, bởi vì các liên kết đó có thể đã được lập chỉ mục bởi Google, được in ra hoặc viết ra hoặc được chia sẻ bởi bất kỳ phương tiện nào khác.

Trong bước tiếp theo, chúng ta sẽ sử dụng map module để đảm bảo rằng địa chỉ cũ này sẽ hoạt động trở lại bằng cách chuyển hướng người xem đến các thay thế mới một cách tự động.

 

Bước 2 - Định cấu hình chuyển hướng

Đối với các trang web nhỏ chỉ với một vài trang, đơn giản  các câu lệnhif có điều kiện có thể được sử dụng cho các chuyển hướng và những thứ tương tự. Tuy nhiên, cấu hình như vậy không phải là dễ dàng để duy trì hoặc mở rộng trong thời gian dài vì danh sách các điều kiện phát triển lâu hơn.

 Map module là một giải pháp ngắn gọn, tđẹp mắt hơn. Nó cho phép bạn so sánh các giá trị biến Nginx với một danh sách các điều kiện, và sau đó kết hợp một giá trị mới với biến tùy thuộc vào kết quả phù hợp. Trong ví dụ này, chúng ta sẽ so sánh URL được yêu cầu với danh sách các trang cũ mà chúng ta muốn chuyển hướng đến các đối tác mới . Đối với mỗi địa chỉ cũ, chúng ta sẽ kết hợp địa chỉ mới.

Map module là một module Nginx cốt lõi, có nghĩa là nó không cần phải được cài đặt riêng để sử dụng. Để tạo cấu hình map và chuyển hướng cần thiết, hãy mở tệp cấu hình Nginx của máy chủ mặc định trong vi  hoặc trình soạn thảo văn bản yêu thích của bạn.  

sudo vi /etc/nginx/nginx.conf

Tìm khối cấu hình server trông như thế này :

/etc/nginx/nginx.conf
. . .
server {
listen 80 default_server;
listen [::]:80 default_server;
. . .

Chúng ta sẽ thêm hai phần mới: một phần trước khối máy chủ  server và một phần trong nó.

Phần trước khối  server là một khối  map mới,xác định việc lập bản đồ giữa các URL cũ và URL mới sử dụng map module . Phần bên trong khối server là chính sự chuyển hướng. 

Modified /etc/nginx/nginx.conf
. . .# Old website redirect map#map $uri $new_uri {/old.html /index.html;}server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Old website redirectif ($new_uri) {rewrite ^ $new_uri permanent;}. . .

Chỉ thị map $uri $new_uri  lấy nội dung của biến $uri của hệ thống, chứa địa chỉ URL của trang được yêu cầu, và sau đó so sánh nó với danh sách các điều kiện trong dấu ngoặc . Mỗi mục trong danh sách điều kiện có hai phần: giá trị khớp với và giá trị mới để gán cho biến nếu nó phù hợp.

Dòng /old.html /index.html trong khối map  nghĩa là nếu giá trị của $uri là /old.html$new_uri sẽ được thay đổi thành /index.html.Nếu nó không phù hợp, nó không thay đổi. Ở đây, chúng ta chỉ định nghĩa một điều kiện, nhưng bạn có thể định nghĩa nhiều điều kiện như bạn muốn trong một map.

Sau đó, sử dụng câu lệnh if có điều kiện bên trong khối server, chúng ta kiểm tra xem giá trị của biến $new_uri có được đặt hay không. Nếu có, điều đó có nghĩa là điều kiện trong map đã được thỏa mãn và chúng ta nên chuyển hướng đến trang web mới bằng cách sử dụng lệnh rewrite. Từ khóa permanent đảm bảo rằng chuyển hướng sẽ là 301 Moved Permanently, có nghĩa là địa chỉ cũ không còn hợp lệ và sẽ không trực tuyến trở lại.

Lưu và đóng tệp để thoát.

Kích hoạt cấu hình mới , khởi động lại Nginx.

sudo systemctl restart nginx

Kiểm tra cấu hình mới ,thực hiện cùng một yêu cầu như trước:

curl -L http://localhost/old.html

Lần này sẽ không có lỗi 404 Not Found nào trong đầu ra. Thay vào đó, bạn sẽ thấy trang chủ đơn giản mà chúng ta đã tạo ở Bước 1.

Nginx response
Home

Điều này có nghĩa là map đã được định cấu hình đúng cách và bạn có thể sử dụng nó để chuyển hướng URL bằng cách thêm các mục nhập khác vào map.

Chuyển hướng URL là một ứng dụng hữu ích của map module. Một điều khác, chúng ta sẽ khám phá trong bước tiếp theo, lọc traffic dựa trên vị trí địa lý của khách truy cập.

Bước 3 - Hạn chế quyền truy cập vào một số quốc gia

Đôi khi, một máy chủ có thể nhận được một số lượng quá lớn các yêu cầu tự động, độc hại. Đây có thể là một cuộc tấn công DDoS, một nỗ lực để lấy mật mã brute-force cho các bảng quản trị trang web hoặc một nỗ lực để khai thác các lỗ hổng được biết đến trong phần mềm tấn công vào trang web và sử dụng nó để gửi spam hoặc sửa đổi nội dung trang web.

Các cuộc tấn công tự động như vậy có thể đến từ rất nhiều máy chủ phân tán khác nhau ở nhiều quốc gia khác nhau, làm cho nó khó chặn. Một giải pháp để giảm nhẹ tác động của cuộc tấn công như thế này là tạo ra một danh sách trắng các quốc gia có thể truy cập trang web.

Nó không phải là một giải pháp hoàn hảo, nhưng trong những trường hợp giới hạn truy cập vào trang web dựa trên vị trí địa lý của khách truy cập là một lựa chọn hợp lý và không giới hạn đối tượng cho trang web, giải pháp này có lợi ích là nhanh và ít lỗi.

Lọc ở cấp máy chủ nhanh hơn lọc ở cấp trang web và cũng bao gồm tất cả yêu cầu (bao gồm tệp tĩnh, như hình ảnh). Loại lọc này cũng ngăn các yêu cầu truy cập vào phần mềm trang web, điều này làm cho lỗ hổng khó khai thác hơn.

Để sử dụng bộ lọc địa lý, hãy tạo một tệp cấu hình mới.

sudo vi /etc/nginx/conf.d/geoip.conf
  •  

Dán các nội dung sau vào tệp. Điều này nói với Nginx nơi tìm cơ sở dữ liệu GeoIP chứa các ánh xạ giữa các địa chỉ IP của khách truy cập và các quốc gia tương ứng. Cơ sở dữ liệu này được cài đặt sẵn với Ubuntu 16.04.

/etc/nginx/conf.d/geoip.conf
# GeoIP database path
#
geoip_country /usr/share/GeoIP/GeoIP.dat;

Bước tiếp theo là tạo cấu hình map và hạn chế cần thiết. Mở máy chủ mặc định cấu hình Nginx.

sudo vi /etc/nginx/nginx.conf

Tìm khối cấu hìnhserver , sau khi sửa đổi ở bước 1 và 2, trông giống như sau:

/etc/nginx/sites-available/default
. . .
# Old website redirect map
#
map $uri $new_uri {
/old.html /index.html;
}server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Old website redirect
if ($new_uri){rewrite ^ $new_uri permanent;
}. . .

Chúng ta sẽ thêm hai phần mới: một phần trước khối server và một phần bên trong nó.

Phần trước khối server là một khối mapmới, xác định hành động mặc định (quyền truy cập không được phép) cũng như danh sách mã quốc gia được cho phép truy cập vào trang web. Phần bên trong khối server sẽ từ chối truy cập trang web nếu kết quả map cho biết.

Modified /etc/nginx/sites-available/default
. . .# Allowed countries#map $geoip_country_code $allowed_country {default no;country_code_1 yes;country_code_2 yes;}# Old website redirect map
#
map $uri $new_uri {
/old.html /index.html;
}server {
listen 80 default_server;
listen [::]:80 default_server;
# Disallow access based on GeoIPif ($allowed_country = no) {return 444;} # Old website redirect
if ($new_uri){rewrite ^ $new_uri permanent;
}. . .

Lưu và đóng file để thoát.

Ở đây, chúng ta đã sử dụng country_code_1  và country_code_2 làm trình giữ chỗ. Thay thế các biến này bằng mã quốc gia gồm hai ký tự cho quốc gia hoặc quốc gia bạn muốn đưa vào danh sách cho phép. Bạn có thể sử dụng danh sách các mã quốc gia đầy đủ, có thể tìm kiếm của ISO để tìm. Ví dụ, hai ký tự mã cho Hoa Kỳ là US.

Không giống như ví dụ đầu tiên, trong khối  map, biến $allowed_country sẽ luôn được đặt thành một cái gì đó. Theo mặc định, nó được đặt thành no; nếu biến $geoip_country_code  khớp với một trong các mã quốc gia trong khối, nó được đặt thành yes. Nếu biến $allowed_country là no, chúng ta sẽ quay lại 444 Connection Closed Without Response thay vì phục vụ trang web thực sự.

Kích hoạt cấu hình mới , khởi động lại Nginx.

sudo systemctl restart nginx

Nếu bạn không thêm quốc gia của mình vào danh sách cho phép, khi bạn cố truy cập http://your_server_ip, bạn sẽ thấy thông báo lỗi như The page isn’t working hoặc The page didn’t send any data. Nếu bạn thêm quốc gia của mình vào danh sách trắng, bạn sẽ thấy Home như trước đây.

 

Kết Luận

Mặc dù đây có thể là một ví dụ rất đơn giản về cách sử dụng map module nhưng nó cho thấy cơ chế có thể được sử dụng theo nhiều cách khác nhau. Map module không chỉ cho phép so sánh đơn giản mà còn hỗ trợ các cụm từ thông dụng cho phép các kết hợp phức tạp hơn. Đó là một cách tuyệt vời để làm cho các tập tin cấu hình sạch hơn nếu nhiều điều kiện phải được đánh giá.

Một trường hợp sử dụng phổ biến khác cho map module là các chuyển hướng có điều kiện cho các phần an toàn của trang web trong một môi trường non- SSL khác. Thiết lập kết nối SSL bắt buộc chỉ dành cho các biểu mẫu yêu cầu, nhập mật khẩu là một ví dụ điển hình về cách áp dụng map module trong kịch bản thực và tôi khuyến khích thử nghiệm với thiết lập như vậy.

Tìm hiểu thêm những điều thú vị  tại ViCloud Community