

Reverse Proxy giúp ẩn hệ thống backend, tập trung quản lý lưu lượng và tăng cường bảo mật cho các dịch vụ web. Trong bài viết này, chúng ta sẽ thực hành Hướng dẫn cấu hình NGINX làm Reverse Proxy trên Ubuntu 24.04, từ bước chuẩn bị môi trường, tạo backend giả lập đến thiết lập định tuyến và kiểm tra kết quả.
Proxy là máy chủ trung gian đứng giữa client (người dùng) và server backend (các trang web mà client truy cập). Nó ngăn chặn client và server giao tiếp trực tiếp với nhau, từ đó giúp tăng tính bảo mật và kiểm soát các lượt truy cập.
Khác với Forward Proxy (đại diện cho client, ẩn danh tính client với server), Reverse Proxy đại diện cho server - nó ẩn danh tính và cấu trúc thật của backend khỏi client.
Trong môi trường vận hành NetBackup và OpenStack, Reverse Proxy thường được dùng để:
Cấu hình dưới đây sẽ mô phỏng đúng tình huống này - nhưng để đơn giản hóa và không cần cài đặt NetBackup/OpenStack thật, ta sẽ dùng 2 trang web giả lập đặt tên giống NetBackup và Horizon, chạy ở các port nội bộ khác nhau trên cùng 1 VM.
Sử dụng 1 VM Ubuntu 24.04 duy nhất, đóng 3 vai trò cùng lúc:
| Thành phần | Port | Vai trò |
| Nginx (Reverse Proxy) | 80 | Cổng vào duy nhất client truy cập |
| Backend A - “Netbackup Demo” | 8081 | Web server giả lập Netbackup Web UI |
| Backend B -”Horizon Demo” | 8082 | Web server giả lập Openstack Horizon |
Client truy cập http://<IP-VM>/netbackup/ sẽ được Nginx route đến Backend A (port 8081). Truy cập http://<IP-VM>/horizon/ sẽ được route đến Backend B (port 8082). Với client, mọi thứ trông như chỉ có 1 server duy nhất ở port 80 - đây chính là bản chất của reverse proxy.
Python3 đã có sẵn trên Ubuntu 24.04, dùng module http.server có sẵn để giả lập 2 backend mà không cần cài thêm phần mềm nào khác.
sudo apt update
sudo apt install -y nginx python3
systemctl status nginx 
Tạo thư mục và file HTML đơn giản, có nội dung rõ ràng để khi xem trên trình duyệt biết ngay đang ở backend nào - phục vụ mục đích minh họa.
mkdir -p ~/lab-nginx/backend-a
cat > ~/lab-nginx/backend-a/index.html << 'EOF'
<html>
<head><title>NetBackup Web UI (Demo)</title></head>
<body style="font-family:Arial;background:#0b3d62;color:white;padding:40px">
<h1>NetBackup Web Management Console (Demo)</h1>
<p>This is a simulated Backend A page — running on port 8081</p>
<p>Server time: <span id="t"></span></p>
<script>document.getElementById('t').innerText = new Date();</script>
</body>
</html>
EOF mkdir -p ~/lab-nginx/backend-b
cat > ~/lab-nginx/backend-b/index.html << 'EOF'
<html>
<head><title>OpenStack Horizon (Demo)</title></head>
<body style="font-family:Arial;background:#7a1f1f;color:white;padding:40px">
<h1>OpenStack Horizon Dashboard (Demo)</h1>
<p>This is a simulated Backend B page — running on port 8082</p>
<p>Server time: <span id="t"></span></p>
<script>document.getElementById('t').innerText = new Date();</script>
</body>
</html>
EOF Mở 2 terminal/session riêng (hoặc dùng tmux, hoặc tạo systemd service) để chạy song song 2 web server đơn giản:
# Terminal 1 — Backend A, port 8081
cd ~/lab-nginx/backend-a
python3 -m http.server 8081
# Terminal 2 — Backend B, port 8082
cd ~/lab-nginx/backend-b
python3 -m http.server 8082 Kiểm tra nhanh từ chính VM (chưa qua Nginx):
curl http://127.0.0.1:8081
curl http://127.0.0.1:8082 Nếu thấy nội dung HTML trả về tương ứng, 2 backend đã chạy đúng.



Để 2 backend tự khởi động cùng hệ thống thay vì phải mở terminal thủ công, tạo service:
sudo tee /etc/systemd/system/lab-backend-a.service << 'EOF'
[Unit]
Description=Lab Backend A - NetBackup Demo (port 8081)
After=network.target
[Service]
WorkingDirectory=/home/%i/lab-nginx/backend-a
ExecStart=/usr/bin/python3 -m http.server 8081
Restart=always
User=%i
[Install]
WantedBy=multi-user.target
EOF
# Lặp lại tương tự cho backend-b với port 8082, đổi tên service
sudo systemctl daemon-reload
sudo systemctl enable --now lab-backend-a@$USER.service Nếu gặp lỗi, có thể cổng đang bị chiếm khi chạy thủ công ở bước 4.3, thực hiện các bước sau để khắc phục:
pkill -f "http.server"
systemctl daemon-reload
systemctl enable --now lab-backend-a.service
systemctl enable --now lab-backend-b.service
# Kiểm tra
systemctl status lab-backend-a.service
systemctl status lab-backend-b.service
curl http://127.0.0.1:8081
curl http://127.0.0.1:8082
sudo nano /etc/nginx/sites-available/lab-reverse-proxy.conf server {
listen 80;
server_name _;
# ---- Backend A: NetBackup Demo ----
location /netbackup/ {
proxy_pass http://127.0.0.1:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# ---- Backend B: Horizon Demo ----
location /horizon/ {
proxy_pass http://127.0.0.1:8082/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# ---- Trang mặc định, hướng dẫn nhanh ----
location / {
return 200 "Lab Reverse Proxy dang chay. Truy cap /netbackup/ hoac /horizon/\n";
add_header Content-Type text/plain;
}
}| Directive | Ý nghĩa |
| Listion 80 | Nginx lắng nghe ở cổng 80 — đây là cổng duy nhất client cần biết |
| Location /netbackup/ | Mọi request có path bắt đầu bằng /netbackup/ sẽ khớp block này |
| Proxy_pass http://127.0.0.1:8081 | Forward request tới Backend A đang chạy nội bộ ở port 8081. Dấu / cuối quan trọng — nó cắt bỏ phần /netbackup/ trước khi gửi tới backend |
| Proxy_set_header Host $host | Giữ nguyên tên host gốc khi forward, để backend biết domain/IP client đã gõ |
| X-Real-IP / X-Forwarded-For | Gắn IP thật của client vào request, vì backend chỉ thấy kết nối đến từ Nginx (127.0.0.1) nếu không có 2 header này |
| X-Forwarded-Proto | Cho backend biết request gốc là http hay https — quan trọng khi sau này thêm SSL ở Nginx |
# Tắt site default để tránh xung đột khi test bằng IP
sudo rm -f /etc/nginx/sites-enabled/default
# Bật site lab
sudo ln -s /etc/nginx/sites-available/lab-reverse-proxy.conf /etc/nginx/sites-enabled/
# Kiểm tra cú pháp trước khi áp dụng
sudo nginx -t
# Áp dụng cấu hình (không downtime)
sudo systemctl reload nginx Lưu ý: sudo nginx -t luôn là bước bắt buộc trước reload — giúp phát hiện lỗi syntax (thiếu dấu ;, sai block...) trước khi nó ảnh hưởng đến Nginx đang chạy.
sudo ufw allow 'Nginx Full'
sudo ufw status curl http://127.0.0.1/netbackup/
curl http://127.0.0.1/horizon/
curl http://127.0.0.1/ Kết quả mong đợi: request đầu trả về nội dung trang NetBackup Demo, request thứ hai trả về nội dung Horizon Demo, dù cả hai đều gõ cùng port 80 - đây chính là minh chứng Nginx đang route request theo path.



Lấy địa chỉ IP của VM:
ip addr show | grep inet Sau đó từ máy khác, mở trình duyệt và truy cập:
Quan trọng: máy khách không cần biết và không thể truy cập trực tiếp port 8081/8082 nếu firewall chỉ mở port 80 - toàn bộ traffic bắt buộc đi qua Nginx. Đây chính là lợi ích bảo mật của reverse proxy.


Để thấy rõ Nginx có gắn IP thật của client vào request hay không, dừng tạm Python server và chạy lại ở chế độ in log chi tiết, hoặc đơn giản hơn — sửa tạm location để trả về toàn bộ header nhận được:
# Cách nhanh: dùng httpbin-style bằng curl -v để xem header gửi đi
curl -v http://127.0.0.1/netbackup/ 2>&1 | grep -i "X-" Hoặc xem trực tiếp log Nginx, log sẽ ghi lại IP nguồn của client thật (không phải 127.0.0.1):
sudo tail -f /var/log/nginx/access.log| Phép thử | URL | Kết quả |
| Qua Reverse Proxy | http://<IP-VM>/netbackup/ | Thành công — Nginx forward tới 8081 |
| Trực tiếp backend (nếu firewall chặn port 8081) | http://<IP-VM>:8081/ | Connection refused / timeout từ máy ngoài |
| Trực tiếp backend (test nội bộ trên VM) | http://127.0.0.1:8081/ | Thành công — vì chạy ngay trên VM, không qua firewall ngoài |
Lưu ý: Việc port 8081/8082 chỉ truy cập được từ localhost (trừ khi tự mở firewall) chính là minh họa rõ nhất cho lợi ích "ẩn backend" của reverse proxy.
Qua bài Hướng dẫn cấu hình NGINX làm Reverse Proxy, hy vọng bạn đã biết cách sử dụng NGINX để tiếp nhận request và chuyển tiếp đến nhiều backend theo từng đường dẫn. Mô hình này không chỉ giúp ẩn cổng dịch vụ nội bộ mà còn tạo nền tảng để triển khai SSL, cân bằng tải, giám sát tập trung và nâng cao tính sẵn sàng cho hệ thống.
