Theo mặc định, Jenkins đi kèm với web server tích hợp riêng, chạy trên cổng (port) 8080. Điều này rất tiện lợi nếu bạn chạy một Jenkins riêng hoặc chỉ cần thiết lập nhanh mà không quan tâm đến bảo mật. Tuy nhiên, một khi bạn có production data thực sự trên máy chủ của mình, tốt nhất là sử dụng một web server an toàn hơn như Nginx để xử lý lưu lượng truy cập.
Bài viết này sẽ trình bày chi tiết cách cấu hình Nginx làm Reverse Proxy cho Jenkins bằng SSL để bảo mật trang web của bạn. Hướng dẫn này giả định bạn đã quen thuộc với các lệnh Linux, đã cài đặt Jenkins và đang sử dụng hệ điều hành Ubuntu 20.04.
Bạn có thể cài đặt Jenkins sau trong hướng dẫn này nếu bạn chưa cài đặt nó.
Yêu cầu tiên quyết
Hướng dẫn này giả định bạn đang sử dụng Ubuntu 20.04. Trước khi bắt đầu, bạn cần có một tài khoản người dùng không phải root với quyền sudo được thiết lập trên hệ thống của bạn. Bạn có thể tìm hiểu cách thực hiện điều này bằng cách làm theo hướng dẫn thiết lập máy chủ ban đầu của Ubuntu 20.04. Bạn cũng sẽ cần cài đặt Nginx server và lưu trữ domain của mình.
Ngoài ra, việc bảo mật Jenkins instance bằng SSL là rất quan trọng. Nếu nó hiển thị trên internet, bạn có thể bảo mật nó bằng Let’s Encrypt. Như đã đề cập trước đó, hướng dẫn này giả định Jenkins đã được cài đặt.
Bước 1: Cấu hình Nginx
Nginx đã trở thành một web server được ưa chuộng vì tốc độ và tính linh hoạt trong những năm gần đây, điều này làm cho nó trở thành một lựa chọn lý tưởng cho ứng dụng của chúng ta.
Chỉnh sửa cấu hình
Tiếp theo, bạn sẽ cần chỉnh sửa tệp cấu hình Nginx mặc định. Ví dụ sau đây sử dụng nano.
sudo nano etc/nginx/sites-enabled/default
Đây là cấu hình cuối cùng có thể trông như thế nào; các phần được chia nhỏ và giải thích ngắn gọn dưới đây. Bạn có thể cập nhật hoặc thay thế tệp cấu hình hiện có, mặc dù bạn nên tạo một bản sao lưu trước.
server {23
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_namejenkins.domain.com;
access_log /var/log/nginx/jenkins.access.log;
location / {
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;
proxy_pass <http://localhost:8080>;
proxy_read_timeout 90;
proxy_redirect <http://localhost:8080> <https://jenkins.domain.com>;
}
...
}
Bạn sẽ cần cập nhật các dòng server_name và proxy_redirect bằng tên domain của riêng bạn. Ngoài ra, có một số “phép thuật” Nginx bổ sung đang diễn ra để yêu cầu được Nginx đọc và viết lại ở phía phản hồi, nhằm đảm bảo reverse proxy hoạt động.
Lưu và đóng tệp. Nếu bạn sử dụng nano, bạn có thể làm điều đó bằng cách nhấn Ctrl + X, Y, và sau đó Enter.
Phần đầu tiên yêu cầu Nginx server lắng nghe bất kỳ yêu cầu nào đến trên port 80 (mặc định của HTTP) và chuyển hướng chúng đến HTTPS.
...
server {
listen 80;
return 301 https://$host$request_uri;
}
...
Sau đó, proxying xảy ra. Về cơ bản, nó lấy bất kỳ yêu cầu đến nào và proxy chúng đến Jenkins instance đang được gắn/lắng nghe trên port 8080 trên giao diện mạng cục bộ.
...
location / {
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;
proxy_pass <http://localhost:8080>;
proxy_read_timeout 90;
proxy_redirect <http://localhost:8080> <https://jenkins.domain.com>;
}
...
Lưu ý: Nếu bạn muốn tìm hiểu thêm về proxying trong Nginx, hướng dẫn này có một số thông tin tốt về các cài đặt proxy của Nginx.
Một vài điều cần lưu ý nhanh ở đây. Nếu bạn không có một tên domain phân giải đến Jenkins server của bạn, thì câu lệnh proxy_redirect ở trên sẽ không hoạt động chính xác nếu không được sửa đổi, vì vậy hãy ghi nhớ điều đó. Ngoài ra, nếu bạn cấu hình sai proxy_pass (ví dụ: bằng cách thêm dấu gạch chéo ở cuối), bạn sẽ nhận được một thông báo tương tự như sau trong trang Cấu hình Jenkins của mình.
Vì vậy, nếu bạn thấy lỗi này, hãy kiểm tra lại các cài đặt proxy_pass và proxy_redirect trong cấu hình Nginx!
Bước 2: Cấu hình Jenkins
Để Jenkins hoạt động với Nginx, chúng ta cần cập nhật cấu hình Jenkins để nó chỉ lắng nghe trên địa chỉ localhost thay vì tất cả (0.0.0.0), để đảm bảo lưu lượng truy cập được xử lý đúng cách. Đây là một bước bảo mật quan trọng vì nếu Jenkins vẫn đang lắng nghe trên tất cả các địa chỉ, thì nó vẫn có thể truy cập được thông qua port ban đầu của nó (8080). Chúng ta sẽ sửa đổi tệp cấu hình /etc/default/jenkins
để thực hiện các điều chỉnh này.
sudo nano /etc/default/jenkins
Tìm dòng JENKINS_ARGS
và cập nhật nó để trông giống như sau:
JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpListenAddress=127.0.0.1 --httpPort=$HTTP_PORT -ajp13Port=$AJP_PORT"
Lưu ý rằng cài đặt --httpListenAddress=127.0.0.1
phải được thêm hoặc sửa đổi.
Sau đó, hãy khởi động lại Jenkins và Nginx.
sudo service jenkins restart
sudo service nginx restart
Bây giờ bạn có thể truy cập domain của mình bằng HTTPS, và trang Jenkins sẽ được phục vụ một cách an toàn.
(Tùy chọn) Cập nhật các URL OAuth
Nếu bạn đang sử dụng plugin GitHub hoặc plugin OAuth khác để xác thực, nó có thể sẽ bị hỏng tại thời điểm này. Ví dụ, khi cố gắng truy cập URL, bạn sẽ nhận được thông báo “Failed to open page” với một URL tương tự như http://jenkins.domain.com:8080/securityRealm/finishLogin?code=random-string
.
Để khắc phục điều này, bạn sẽ cần cập nhật một vài cài đặt trong Jenkins, bao gồm cả cài đặt plugin OAuth của bạn. Đầu tiên, cập nhật URL Jenkins trong giao diện người dùng Jenkins; nó có thể được tìm thấy trong menu Jenkins -> Manage Jenkins -> Configure System -> Jenkins Location.
Cập nhật URL Jenkins để sử dụng HTTPS – https://jenkins.domain.com/
Tiếp theo, cập nhật cài đặt OAuth của bạn với nhà cung cấp bên ngoài. Ví dụ này dành cho GitHub. Trên GitHub, điều này có thể được tìm thấy trong Settings -> Applications -> Developer applications, trên trang GitHub.
Sẽ có một mục cho Jenkins. Cập nhật Homepage URL và Authorization callback URL để phản ánh cài đặt HTTPS. Nó có thể trông tương tự như sau:
Kết luận
Phần còn lại chỉ là để xác minh rằng mọi thứ đã hoạt động chính xác. Như đã đề cập ở trên, giờ đây bạn có thể duyệt đến URL vừa được cấu hình của mình – jenkins.domain.com – qua cả HTTP hoặc HTTPS.
Bạn sẽ được chuyển hướng đến trang an toàn và sẽ thấy một số thông tin trang web, bao gồm cả cài đặt SSL mới được cập nhật của bạn. Như đã lưu ý trước đó, nếu bạn không sử dụng hostname thông qua DNS, thì việc chuyển hướng của bạn có thể không hoạt động như mong muốn. Trong trường hợp đó, bạn sẽ cần sửa đổi phần proxy_pass trong tệp cấu hình Nginx.