Cách sử dụng Apache làm reverse-proxy với mod_proxy trên Debian 8
Một reverse-proxy là một loại server proxy nhận các yêu cầu HTTP (S) và phân phối chúng đến một hoặc nhiều server backend một cách minh bạch. Reverse proxy rất hữu ích vì nhiều ứng dụng web hiện đại xử lý các yêu cầu HTTP đến bằng cách sử dụng các server ứng dụng backend vốn không được user truy cập trực tiếp và thường chỉ hỗ trợ các tính năng HTTP thô sơ.Bạn có thể sử dụng Reverse Proxy để ngăn các server ứng dụng cơ bản này bị truy cập trực tiếp. Chúng cũng được dùng để phân phối tải từ các yêu cầu đến đến một số server ứng dụng khác nhau, tăng hiệu suất trên quy mô lớn và cung cấp độ an toàn cho sự cố. Họ có thể lấp đầy khoảng trống bằng các tính năng mà server ứng dụng không cung cấp, chẳng hạn như bộ nhớ đệm, nén hoặc mã hóa SSL.
Trong hướng dẫn này, bạn sẽ cài đặt Apache làm Reverse Proxy cơ bản bằng cách sử dụng trình mở rộng mod_proxy
để chuyển hướng các kết nối đến đến một hoặc một số server backend chạy trên cùng một mạng. Hướng dẫn này sử dụng một chương trình backend đơn giản được viết bằng khuôn khổ web with Flask , nhưng bạn có thể sử dụng bất kỳ server backend nào bạn muốn .
Yêu cầu
Để làm theo hướng dẫn này, bạn cần :
- Một server Debian 8 được cài đặt với hướng dẫn cài đặt server ban đầu này .
- Apache 2 được cài đặt trên server của bạn theo Bước 1 của Cách cài đặt ngăn xếp Linux, Apache, MySQL, PHP (LAMP) trên Debian 8 .
Bước 1 - Kích hoạt các module Apache cần thiết
Apache có nhiều module đi kèm với nó có sẵn nhưng không được kích hoạt trong bản cài đặt mới. Đầu tiên, ta cần bật những cái mà ta sẽ sử dụng trong hướng dẫn này.
Các module ta cần là chính mod_proxy
và một số module bổ sung của nó, mở rộng chức năng của nó để hỗ trợ các giao thức mạng khác nhau. Cụ thể, ta sẽ sử dụng:
-
mod_proxy
, module Apache module proxy chính để chuyển hướng kết nối; nó cho phép Apache hoạt động như một cổng vào các server ứng dụng bên dưới. -
mod_proxy_http
, bổ sung hỗ trợ cho các kết nối HTTP ủy quyền. -
mod_proxy_balancer
vàmod_lbmethod_byrequests
, bổ sung các tính năng cân bằng tải cho nhiều server backend .
Để bật bốn module này, hãy thực hiện liên tiếp các lệnh sau.
- sudo a2enmod proxy
- sudo a2enmod proxy_http
- sudo a2enmod proxy_balancer
- sudo a2enmod lbmethod_byrequests
Để những thay đổi này có hiệu lực, hãy khởi động lại Apache.
- sudo systemctl restart apache2
Apache hiện đã sẵn sàng hoạt động như một Reverse Proxy cho các yêu cầu HTTP. Trong bước tiếp theo (tùy chọn), ta sẽ tạo hai server backend rất cơ bản. Những điều này sẽ giúp ta xác minh xem cấu hình có hoạt động bình thường hay không, nhưng nếu bạn đã có (các) ứng dụng backend của riêng mình, bạn có thể chuyển sang Bước 3.
Bước 2 - Tạo server kiểm tra backend
Chạy một số server backend đơn giản là một cách dễ dàng để kiểm tra xem cấu hình Apache của bạn có hoạt động bình thường hay không. Ở đây, ta sẽ tạo hai server thử nghiệm phản hồi các yêu cầu HTTP bằng cách in một dòng văn bản. Một server sẽ nói Xin chào thế giới! và người kia sẽ nói Howdy world! .
Lưu ý: Trong các cài đặt không thử nghiệm, các server backend thường trả về cùng một loại nội dung. Tuy nhiên, đối với thử nghiệm này nói riêng, việc hai server trả về các thông báo khác nhau giúp dễ dàng kiểm tra xem cơ chế cân bằng tải có sử dụng cả hai hay không.
Flask là một microframework Python để xây dựng các ứng dụng web. Ta đang sử dụng Flask để tạo các server thử nghiệm vì một ứng dụng cơ bản chỉ yêu cầu một vài dòng mã. Bạn không cần phải biết Python để cài đặt những thứ này, nhưng nếu bạn muốn học, bạn có thể xem các hướng dẫn Python này .
Cập nhật danh sách gói trước.
- sudo apt-get update
Sau đó cài đặt Pip, trình quản lý gói Python được khuyến khích .
- sudo apt-get -y install python3-pip
Sử dụng Pip để cài đặt Flask.
- sudo pip3 install flask
Bây giờ tất cả các thành phần bắt buộc đã được cài đặt, hãy bắt đầu bằng cách tạo một file mới chứa mã cho server backend đầu tiên trong folder chính của user hiện tại.
- nano ~/backend1.py
Sao chép mã sau vào file , sau đó lưu và đóng nó.
from flask import Flask app = Flask(__name__) @app.route('/') def home(): return 'Hello world!'
Hai dòng đầu tiên khởi tạo khung Flask. Có một hàm, home()
, trả về một dòng văn bản ( Hello world!
). Dòng @app.route('/')
phía trên định nghĩa hàm home()
yêu cầu Flask sử dụng giá trị trả về của home()
làm phản hồi cho các yêu cầu HTTP được hướng đến /
root URL của ứng dụng.
Server backend thứ hai hoàn toàn giống với server đầu tiên, ngoài việc quay trở lại một dòng văn bản khác, vì vậy hãy bắt đầu bằng cách sao chép file đầu tiên.
- cp ~/backend1.py ~/backend2.py
Mở file mới được sao chép.
- nano ~/backend2.py
Thay đổi tin nhắn được trả lại từ Hello world! đến thế giới Howdy! , sau đó lưu file .
from flask import Flask app = Flask(__name__) @app.route('/') def home(): return 'Howdy world!'
Sử dụng lệnh sau để khởi động server nền đầu tiên trên cổng 8080
. Điều này cũng chuyển hướng kết quả của Flask thành /dev/null
vì nó sẽ làm ảnh hưởng đến kết quả của console .
- FLASK_APP=~/backend1.py flask run --port=8080 >/dev/null 2>&1 &
Ở đây, ta đang đặt trước lệnh flask
bằng cách đặt biến môi trường FLASK_APP
trong cùng một dòng. Các biến môi trường là một cách thuận tiện để truyền thông tin vào các quy trình được tạo ra từ shell. Bạn có thể tìm hiểu thêm về các biến môi trường trong Cách đọc và Đặt các biến Môi trường và Vỏ trên Linux VPS .
Trong trường hợp này, việc sử dụng biến môi trường đảm bảo cài đặt chỉ áp dụng cho lệnh đang được chạy và sẽ không khả dụng sau đó, vì ta sẽ chuyển một tên file khác theo cách tương tự để ra lệnh cho flask
khởi động server thứ hai
Tương tự, sử dụng lệnh này để khởi động server thứ hai trên cổng 8081
. Lưu ý giá trị khác nhau cho biến môi trường FLASK_APP
.
- FLASK_APP=~/backend2.py flask run --port=8081 >/dev/null 2>&1 &
Bạn có thể kiểm tra xem hai server đang chạy bằng cách sử dụng curl
. Kiểm tra server đầu tiên:
- curl http://127.0.0.1:8080/
Điều này sẽ xuất ra Hello world! trong terminal . Kiểm tra server thứ hai:
- curl http://127.0.0.1:8081/
Điều này sẽ xuất ra thế giới Howdy! thay thế.
Lưu ý : Để đóng cả hai server thử nghiệm sau khi bạn không còn cần đến chúng nữa, như khi bạn hoàn thành hướng dẫn này, bạn có thể chỉ cần thực hiện killall flask
.
Trong bước tiếp theo, ta sẽ sửa đổi file cấu hình của Apache để cho phép sử dụng nó như một Reverse Proxy .
Bước 3 - Sửa đổi cấu hình mặc định để kích hoạt Reverse Proxy
Trong phần này, ta sẽ cài đặt server ảo Apache mặc định để phục vụ như một Reverse Proxy cho server backend đơn lẻ hoặc một mảng server backend cân bằng tải.
Lưu ý : Trong hướng dẫn này, ta đang áp dụng cấu hình ở cấp server ảo. Trên cài đặt mặc định của Apache, chỉ có một server ảo mặc định duy nhất được kích hoạt. Tuy nhiên, bạn cũng có thể sử dụng tất cả các đoạn cấu hình đó trong các server ảo khác. Để tìm hiểu thêm về server ảo trong Apache, bạn có thể đọc hướng dẫn Cách cài đặt Server ảo Apache trên Debian 7 này .
Nếu server Apache của bạn hoạt động như cả server HTTP và HTTPS, thì cấu hình Reverse Proxy của bạn phải được đặt trong cả server ảo HTTP và HTTPS. Để tìm hiểu thêm về SSL với Apache, bạn có thể đọc hướng dẫn Cách tạo Chứng chỉ SSL trên Apache cho Debian 8 này .
Mở file cấu hình Apache mặc định bằng nano
hoặc editor yêu thích của bạn.
- sudo nano /etc/apache2/sites-available/000-default.conf
Bên trong file đó, bạn sẽ tìm thấy khối <VirtualHost *:80>
bắt đầu trên dòng đầu tiên. Ví dụ đầu tiên bên dưới giải thích cách cấu hình khối này để đảo ngược proxy cho một server backend duy nhất và ví dụ thứ hai cài đặt Reverse Proxy cân bằng tải cho nhiều server backend .
Ví dụ 1 - Đảo ngược proxy một server backend duy nhất
Thay thế tất cả nội dung trong khối VirtualHost
bằng những thứ sau, để file cấu hình của bạn trông giống như sau:
<VirtualHost *:80> ProxyPreserveHost On ProxyPass / http://127.0.0.1:8080/ ProxyPassReverse / http://127.0.0.1:8080/ </VirtualHost>
Nếu bạn đã làm theo các server mẫu ở Bước 2, hãy sử dụng 127.0.0.1:8080
như được viết trong khối ở trên. Nếu bạn có server ứng dụng của riêng mình, hãy sử dụng địa chỉ của chúng thay thế.
Có ba chỉ thị ở đây:
-
ProxyPreserveHost
làm cho Apache chuyển tiêu đềHost
ban đầu đến server backend . Điều này rất hữu ích, vì nó làm cho server backend biết địa chỉ được sử dụng để truy cập ứng dụng. -
ProxyPass
là chỉ thị cấu hình proxy chính. Trong trường hợp này, nó chỉ định rằng mọi thứ trong URL root (/
) phải được ánh xạ tới server backend tại địa chỉ đã cho. Ví dụ: nếu Apache nhận được một yêu cầu cho/example
, nó sẽ kết nối vớihttp:// your_backend_server /example
và trả lại phản hồi cho client ban đầu. -
ProxyPassReverse
phải có cấu hình giống nhưProxyPass
. Nó yêu cầu Apache sửa đổi các tiêu đề phản hồi từ server backend . Điều này đảm bảo nếu server backend trả về tiêu đề chuyển hướng vị trí, trình duyệt của khách hàng sẽ được chuyển hướng đến địa chỉ proxy chứ không phải địa chỉ server backend , điều này sẽ không hoạt động như dự kiến.
Để những thay đổi này có hiệu lực, hãy khởi động lại Apache.
- sudo systemctl restart apache2
Bây giờ, nếu bạn truy cập http:// your_server_ip
trong trình duyệt web, bạn sẽ thấy phản hồi của server backend của bạn thay vì trang chào mừng Apache tiêu chuẩn. Nếu bạn đã làm theo Bước 2, điều này nghĩa là bạn sẽ thấy Hellow world! .
Ví dụ 2 - Cân bằng tải qua nhiều server backend
Nếu bạn có nhiều server backend , một cách tốt để phân phối lưu lượng trên chúng khi ủy quyền là sử dụng các tính năng cân bằng tải của mod_proxy
.
Thay thế tất cả nội dung trong khối VirtualHost
bằng những thứ sau, để file cấu hình của bạn trông giống như sau:
<VirtualHost *:80> <Proxy balancer://mycluster> BalancerMember http://127.0.0.1:8080 BalancerMember http://127.0.0.1:8081 </Proxy> ProxyPreserveHost On ProxyPass / balancer://mycluster/ ProxyPassReverse / balancer://mycluster/ </VirtualHost>
Cấu hình tương tự như cấu hình trước đó, nhưng thay vì chỉ định trực tiếp một server backend duy nhất, ta đã sử dụng một khối Proxy
bổ sung để xác định nhiều server . Khối được đặt tên là balancer:// mycluster
(tên có thể được thay đổi tùy ý) và bao gồm một hoặc nhiều BalancerMember
, chỉ định địa chỉ server backend cơ bản. Các ProxyPass
và ProxyPassReverse
chỉ sử dụng hồ bơi cân bằng tải tên mycluster
thay vì một server cụ thể.
Nếu bạn đã làm theo các server mẫu ở Bước 2, hãy sử dụng 127.0.0.1:8080
và 127.0.0.1:8081
cho các lệnh BalancerMember
, như được viết trong khối ở trên. Nếu bạn có server ứng dụng của riêng mình, hãy sử dụng địa chỉ của chúng thay thế.
Để những thay đổi này có hiệu lực, hãy khởi động lại Apache.
- sudo systemctl restart apache2
Nếu bạn truy cập http:// your_server_ip
trong trình duyệt web, bạn sẽ thấy phản hồi của server backend của bạn thay vì trang Apache tiêu chuẩn. Nếu bạn đã làm theo Bước 2, làm mới trang nhiều lần sẽ hiển thị Hello world! và Howdy world! , nghĩa là Reverse Proxy đã hoạt động và đang cân bằng tải giữa cả hai server .
Kết luận
Đến đây bạn đã biết cách cài đặt Apache làm Reverse Proxy cho một hoặc nhiều server ứng dụng cơ bản. mod_proxy
được dùng hiệu quả để cấu hình Reverse Proxy cho các server ứng dụng được viết bằng nhiều ngôn ngữ và công nghệ, chẳng hạn như Python và Django hoặc Ruby và Ruby on Rails. Nó cũng được dùng để cân bằng lưu lượng truy cập giữa nhiều server backend cho các trang web có nhiều lưu lượng truy cập hoặc cung cấp tính khả dụng cao thông qua nhiều server hoặc cung cấp hỗ trợ SSL an toàn cho các server backend không hỗ trợ SSL nguyên bản.
Trong khi mod_proxy
với mod_proxy_http
có lẽ là sự kết hợp phổ biến nhất của các module , có một số module khác hỗ trợ các giao thức mạng khác nhau. Ta không sử dụng chúng ở đây, nhưng một số module phổ biến khác bao gồm:
-
mod_proxy_ftp
cho FTP. -
mod_proxy_connect
cho tunnel SSL. -
mod_proxy_ajp
cho AJP (Apache JServ Protocol), giống như backend dựa trên Tomcat. -
mod_proxy_wstunnel
cho socket web.
Để tìm hiểu thêm về mod_proxy
, bạn có thể đọc tài liệu chính thức về mod_proxy
Apache .
Các tin liên quan
Cách sử dụng Apache làm Reverse Proxy với mod_proxy trên Ubuntu 16.042017-02-01
Cách viết lại URL bằng mod_rewrite cho Apache trên Debian 8
2017-01-27
Cách viết lại URL bằng mod_rewrite cho Apache trên Ubuntu 16.04
2017-01-25
Cách mã hóa kết nối Tomcat 8 với Apache hoặc Nginx trên CentOS 7
2017-01-24
Cách tạo chứng chỉ SSL trên Apache cho CentOS 7
2017-01-04
Cách bảo mật Apache bằng Let's Encrypt trên Debian 8
2016-12-20
Cách cung cấp các ứng dụng Django với Apache và mod_wsgi trên Debian 8
2016-12-19
Cách tạo chuyển hướng tạm thời và vĩnh viễn với Apache
2016-12-15
Cách di chuyển web root Apache đến một vị trí mới trên Debian 8
2016-12-14
Cách thiết lập mod_rewrite cho Apache trên CentOS 7
2016-10-26