Jenkins Learn
07. Bảo mật Jenkins

Hardening Jenkins Controller

Giảm bề mặt tấn công của Jenkins controller bằng phân đoạn mạng, kiểm soát tính năng, quyền filesystem và reverse proxy an toàn.

Phạm vi và nguyên tắc thay đổi

Controller là tài sản đặc quyền: nó giữ cấu hình, plugin, credential metadata và điều phối build. Trang này là baseline để review, không phải danh sách bật/tắt áp dụng mù quáng. Mọi thay đổi phải có owner, cửa sổ thay đổi, backup đã kiểm chứng và xác nhận trên Jenkins LTS cùng plugin đang chạy.

Mục lục

Mục tiêu và ranh giới

Hardening controller là giảm khả năng một request, agent, plugin, filesystem hoặc dependency trở thành đường vào cấu hình Jenkins hay capability của build. Nó không biến source code không tin cậy thành an toàn. Controller production nên điều phối; built-in node đặt 0 executor và workload chạy trong agent pool tách biệt theo mức tin cậy.

Sau bài này, bạn có thể lập một baseline có owner và bằng chứng, xác định flow mạng tối thiểu, review thay đổi rủi ro theo version/runtime, và quay lui mà không ghi đè dữ liệu controller. Nền tảng asset, identity và trust boundary được trình bày tại Mô hình bảo mật Jenkins và kiến trúc controller–agent tại Kiến trúc Jenkins.

Không coi controller là public application server

Không publish trực tiếp HTTP port của controller ra Internet để tiện truy cập hoặc debug. Đặt UI/API sau HTTPS tại reverse proxy hoặc load balancer đã được tin cậy; upstream controller chỉ nhận từ proxy hoặc mạng quản trị đã định danh.

Kiến trúc hardening

Luồng và hướng kết nối

direction: down
S: "SCM webhook đã xác thực"
E: "Egress proxy hoặc dịch vụ đã\nduyệt"
B: "Backup mã hóa, access tách biệt"
M: "Management network" {
  U: "Người dùng quản trị và\nautomation"
  P: "Reverse proxy tin cậy"
  C: "Jenkins controller"
  H: "JENKINS_HOME và plugin storage"
}
X: "Execution networks tách theo\ntrust tier" {
  A1: "Agent pool untrusted"
  A2: "Agent pool trusted-release"
}

M.U -> M.P: "HTTPS 443, identity và\nauthorization"
S -> M.P: "HTTPS 443"
M.P -> M.C: "private HTTP hoặc TLS; forwarded\nheaders bị ghi đè"
M.C -> E: "HTTPS allowlist: SCM, Update\nCenter, IdP, artifact"
X.A1 -> M.P: "outbound WSS/HTTPS hoặc\ntransport đã duyệt"
X.A2 -> M.C: "flow riêng, egress hẹp hơn"
M.C -> M.H
M.H -> B
SCM webhook đã xác thựcEgress proxy hoặc dịch vụ đãduyệtBackup mã hóa, access tách biệtManagement networkExecution networks tách theotrust tierNgười dùng quản trị vàautomationReverse proxy tin cậyJenkins controllerJENKINS_HOME và plugin storageAgent pool untrustedAgent pool trusted-release HTTPS 443, identity vàauthorizationHTTPS 443private HTTP hoặc TLS; forwardedheaders bị ghi đèHTTPS allowlist: SCM, UpdateCenter, IdP, artifactoutbound WSS/HTTPS hoặctransport đã duyệtflow riêng, egress hẹp hơn
SCM webhook đã xác thựcEgress proxy hoặc dịch vụ đãduyệtBackup mã hóa, access tách biệtManagement networkExecution networks tách theotrust tierNgười dùng quản trị vàautomationReverse proxy tin cậyJenkins controllerJENKINS_HOME và plugin storageAgent pool untrustedAgent pool trusted-release HTTPS 443, identity vàauthorizationHTTPS 443private HTTP hoặc TLS; forwardedheaders bị ghi đèHTTPS allowlist: SCM, UpdateCenter, IdP, artifactoutbound WSS/HTTPS hoặctransport đã duyệtflow riêng, egress hẹp hơn
Luồng và hướng kết nối

Sơ đồ là threat model khởi điểm, không phải một hợp đồng port cố định. Ghi rõ hostname, proxy hop, DNS resolver, transport agent, destination egress và owner thực tế trước khi viết firewall rule. Một agent WebSocket thường tạo kết nối outbound HTTPS đến proxy; inbound TCP và SSH có hướng kết nối khác, nên phải review theo launch method thay vì chỉ mở một cổng “Jenkins”.

Network policy không phải authorization

Network segmentation giới hạn ai có thể chạm network endpoint. Jenkins authentication và authorization quyết định identity nào được làm gì sau khi đã chạm controller. Một allowlist IP không cấp Job/Build; một permission hợp lệ cũng không cho phép public controller. Giữ độc lập TLS, realm, authorization strategy, CSRF, firewall và policy agent. Xem chi tiết quyền tại Authorization & RBAC và request mutation tại CSRF & API Tokens.

Baseline hardening có bằng chứng

Bảng này là baseline để giao owner xác nhận, không phải cấu hình chung cho mọi Jenkins. Evidence nên là config diff đã bảo vệ, output kiểm tra đã redaction, ticket/change record hoặc kết quả sandbox; không chứa token, cookie, private key hay nội dung JENKINS_HOME.

ControlThreat giảm thiểuOwnerEvidence cần giữRollback an toàn
UI/API chỉ qua proxy HTTPS; upstream privateBypass TLS, header trust và bề mặt Internet trực tiếpNetwork/platformSơ đồ flow, security-group/firewall review, smoke test URL canonicalKhôi phục rule/proxy đã biết tốt; không public upstream để chữa 502.
Agent pools tách trust tier, controller executor 0Code build đọc/ảnh hưởng controller hoặc release capabilityJenkins/CI ownerNode labels, executor setting, job-to-pool matrix, build sandboxRoute job về pool cũ đã kiểm thử; không chuyển workload sang controller.
Egress allowlist và DNS/proxy có ownerDownload độc hại, exfiltration, SSRF tới dịch vụ nội bộNetwork/securityDanh sách FQDN/destination, flow log đã redact, test DNS/TLSKhôi phục allowlist phiên bản trước trong cửa sổ; giữ deny log để điều tra.
Tính năng/plugin được review theo risk và advisoryEndpoint, protocol hoặc code controller không cần thiếtJenkins/securityInventory core/plugin, advisory review, test allow/denyRe-enable hoặc restore version/config đã biết tốt sau staging; không downgrade trên home đã migrate.
Quyền JENKINS_HOME và backup tách biệtĐọc/sửa credential metadata, plugin hoặc configHost/storage ownerUID/GID/mode/label review, backup ID, restore drillKhôi phục ACL/ownership cụ thể; không dùng chmod -R 777.
Header ở edge, URL và proxy trust chain nhất quánClickjacking, MIME sniffing, redirect/origin/crumb lỗiProxy/Jenkins ownerRendered config, browser/API/webhook/static-asset smoke testRevert block header nhỏ đã review; không tắt CSRF để che lỗi.
Log, monitoring và advisory cadenceSự cố không phát hiện hoặc patch không có ownerOperations/securityAlert owner, log retention/ACL, advisory decision recordKhôi phục rule/retention trước; giữ evidence incident theo policy.

Phân đoạn mạng và egress

Mạng quản trị cho UI và API

Đặt controller, UI và API trong mạng quản trị. Người dùng, automation và webhook chỉ đi vào qua reverse proxy/load balancer trên URL HTTPS canonical. Controller bind loopback hoặc private subnet; firewall/security group chỉ cho IP, subnet hoặc identity của proxy đã biết tới upstream. Hướng dẫn URL, context path và forwarded header nằm tại Reverse Proxy và TLS.

Tách các nhóm sau khi threat model yêu cầu:

  • Management: browser quản trị, API automation, proxy, controller, backup và observability. Không mở đường trực tiếp từ mạng build không tin cậy vào filesystem hay cổng quản trị controller.
  • Execution: agent pools riêng cho PR/fork, CI nội bộ và release. Label chỉ là lựa chọn scheduler; ranh giới thật cần identity runtime, filesystem, credential scope và egress riêng.
  • Integration: SCM, IdP, Update Center/mirror, registry và artifact service. Đặt hostname/CA/proxy contract rõ ràng thay vì dùng Internet mở rộng.

Webhook không phải lý do công khai controller. Reverse proxy là điểm nhận webhook, kiểm tra TLS/hostname/routing theo integration và chuyển đúng request tới controller private. Authentication/authorization trong Jenkins vẫn phải bật; webhook validation cụ thể tùy SCM plugin và version nên phải được kiểm thử trong sandbox.

Agent pools, DNS và firewall

Chọn flow theo loại agent, rồi allowlist hướng đi tối thiểu:

FlowHướng cần đánh giáQuyết định firewall/DNSKhông được suy ra
Inbound WebSocket agentAgent → proxy/controller qua HTTPSAgent chỉ resolve/gọi hostname controller; mọi proxy hop hỗ trợ WebSocket và timeout đã testKhông cần hoặc không được mở TCP agent port chỉ vì dùng WebSocket.
Inbound TCP agentAgent → TCP port controller đã cấu hìnhFixed port, nguồn agent/VPN được allowlist, controller không public InternetMột location HTTP proxy được WebSocket sẽ chuyển tiếp TCP Remoting.
SSH agentController → agent SSHController chỉ tới agent host/port và host key theo policyAgent có thể tự đi vào UI/API controller nếu flow không yêu cầu.
Build dependencyAgent → SCM, registry, artifact, DNS/proxy cần thiếtAllowlist theo từng pool/trust tier; release pool hẹp hơn untrusted poolProxy controller tự áp dụng cho process tool trên agent.

DNS là control thực thi: resolver của controller và từng pool chỉ nên phân giải domain được policy cho phép, phản hồi phải đi qua DNS đáng tin cậy và CA/TLS phải khớp hostname. Không dùng IP tạm để né certificate hoặc DNS. Khi có proxy outbound, cấu hình NO_PROXY cho endpoint nội bộ có chủ đích, không dùng nó làm cách né inspection/allowlist.

Egress, webhook và SSRF

Controller cần egress thực sự cần thiết, ví dụ Update Center/mirror đã duyệt, SCM, IdP, artifact service, time service hoặc proxy của tổ chức. Agent cần egress khác theo toolchain. Danh sách phải có FQDN/destination, port/protocol, purpose, owner, nguồn cấu hình và ngày review.

Giảm SSRF (server-side request forgery) bằng cách không cho controller/plugin đi tới metadata service, RFC1918/private endpoint, loopback hoặc admin API chỉ vì request/URL do người dùng, job parameter hay plugin cung cấp. Ở proxy/egress layer, deny các destination nhạy cảm theo policy; ở Jenkins, review plugin và Pipeline nào nhận URL, webhook endpoint, repository URL hay proxy setting từ input. Không coi chặn egress là thay thế cho patch security advisory hoặc validation input.

Update Center và plugin là supply chain

Chỉ cho controller tải metadata/plugin từ nguồn hoặc mirror đã được tổ chức phê duyệt. Một egress rule rộng để “cài plugin cho nhanh” tạo capability download code vào controller. Review advisory, version, dependency và staging trước khi thay đổi plugin.

Đánh giá và giảm tính năng rủi ro

Quy trình cho từng thay đổi

Không có danh sách “tắt tất cả” an toàn cho mọi Jenkins LTS, plugin và launch method. Một control có thể ở Jenkins core, plugin, reverse proxy, service manifest hoặc không tồn tại trong runtime của bạn. Trước khi đổi, xác định chính xác feature/protocol, consumer, version, dependency và tác động build/integration.

  1. Đánh giá rủi ro: gắn feature với actor, asset, network flow và advisory hiện hành. Xác nhận feature có tồn tại/đang bật trên controller sandbox cùng version.
  2. Chỉ định owner và impact: owner Jenkins, network, security hoặc workload phải đồng ý consumer bị ảnh hưởng; thông báo job/team trước change window.
  3. Kiểm thử hẹp: dùng identity, job, agent và webhook sandbox để kiểm tra cả allow lẫn deny. Chụp version/config trước thay đổi.
  4. Triển khai và quan sát: áp dụng một thay đổi logic, theo dõi login, queue, agent, plugin log và endpoint liên quan trong thời gian định trước.
  5. Rollback và advisory review: đặt tiêu chí quay lui, cấu hình/version đã biết tốt và người quyết định. Sau advisory, review core và plugin dependency; compensating control không thay patch khi bản vá đã được phê duyệt.

Danh mục cần review

Feature hoặc bề mặtRủi ro và quyết định có điều kiệnOwner, test và rollback
Anonymous readCó thể lộ tên job, build, log, artifact hoặc topology. Mặc định không cấp permission cho anonymous nếu không có use case đã phê duyệt.Authorization owner test bằng browser chưa đăng nhập tại scope thật. Rollback bằng policy snapshot/recovery admin, không mở Overall/Administer rộng.
CLI, API và legacy endpointCLI/REST là bề mặt automation; legacy transport/endpoint có thể khác core/plugin/version. Chỉ giữ client và transport được inventory, xác thực và cần thiết.API owner test service identity quyền tối thiểu, TLS và deny path. Rollback chỉ khôi phục endpoint/client đã review, đồng thời review advisory.
Agent Remoting/protocolProtocol hoặc inbound port không dùng làm rộng attack surface. Chọn WebSocket, TCP hoặc SSH theo topology; không mô tả một setting là có mặt trên mọi LTS/plugin.Agent/network owner thử node sandbox và timeout/reconnect. Rollback về transport đã thử, giữ firewall hẹp và không mở cổng diện rộng.
Built-in node executorsBuild trên controller có thể đọc file, bão hòa tài nguyên hoặc dùng capability controller. Production thường đặt 0.CI owner xác nhận queue/label và smoke build trên agent. Rollback là khôi phục capacity agent, không bật controller executor cho workload không tin cậy.
Script Approval, sandbox và trusted libraryApprove signature hay bypass sandbox có thể biến input thành code đặc quyền. Không approve từ log/ticket mà chưa review revision, API và ACL.Pipeline/security owner tái hiện ở sandbox và review diff. Rollback bằng xóa approval/thay library version theo change record; đánh giá advisory plugin liên quan.
Plugin, formatter hoặc feature không dùngPlugin là code trong controller; formatter/feature có thể thêm endpoint hoặc XSS/code-execution path. Gỡ/tắt chỉ khi dependency inventory chứng minh không có consumer.Plugin owner staging với plugin/core pin, test startup và job đại diện. Rollback bằng backup/plan tương thích, không xóa file plugin tùy tiện trong JENKINS_HOME.

Xem Authentication, Authorization & RBAC, Credentials & Secrets và CSRF & API Tokens để không nhầm identity, permission, credential hay crumb với network control.

Quyền filesystem và persistent storage

Phân loại dữ liệu và quyền

JENKINS_HOME là security boundary trên filesystem: thường chứa configuration, job/build metadata, plugin, credential metadata đã mã hóa và material trong secrets/. Người đọc/ghi home, plugin hoặc backup có thể có ảnh hưởng vượt quyền Jenkins UI. Dùng service user chuyên dụng, directory ownership và mode tối thiểu; tách quyền host/storage/backup khỏi người chạy build khi có thể.

Vùng dữ liệuOwner/access tối thiểu cần thiếtRủi ro và kiểm tra
JENKINS_HOME config, job, secrets/Service user Jenkins và nhóm quản trị được ủy quyền theo policyXác minh owner, mode, ACL, parent traverse và backup encryption; không mount vào agent hoặc workspace dùng chung.
Plugin và cache controllerService user ghi theo lifecycle cài/upgrade đã kiểm soátPlugin/cache có thể là code hoặc dependency; chỉ update qua change plan, không cho build user ghi.
Log controllerService/runtime ghi; reader là operations/security role cần thiếtLog có thể chứa topology hoặc output nhạy cảm; log rotation, forwarding và ACL riêng.
Backup/archive/key materialBackup identity tối thiểu, storage encrypted, restore identity có phân quyềnBackup không phải bản sao “vô hại”; kiểm tra checksum, retention, access audit và restore cô lập.
Workspace/cache agentIdentity agent và policy theo trust tierKhông phải backup controller; dọn theo policy, không chia sẻ với agent/job không tin cậy.

Credential Jenkins được mã hóa vẫn không thay thế filesystem boundary. Encryption giúp bảo vệ dữ liệu ở lớp Jenkins, nhưng process/host/backup identity đọc được home hoặc key material vẫn cần bị giới hạn. Không copy credentials.xml, master.key hay file trong secrets/ giữa controller/generation. Quy trình backup và restore cô lập nằm tại Backup & Restore Jenkins.

Container, volume, umask và SELinux

Với container, xác minh user/UID/GID mà image thực tế chạy, loại volume (named volume, bind mount, driver từ xa), owner/mode sau restore và security context. Ưu tiên persistent volume chỉ gắn cho controller. Bind mount phải có owner/mode hẹp; mount read-only cho backup reader khi workflow cho phép. Không chạy controller lâu dài bằng root để vượt lỗi volume.

umask ảnh hưởng file mới tạo nhưng không sửa mode file cũ; owner, ACL, mount option và parent directory vẫn phải được review. Với SELinux/AppArmor, đọc denial, context/label và policy tối thiểu cho đúng mount/service. Không tắt security module hay dùng chmod 777/shared writable mount như một cách sửa permission. Ví dụ deployment Docker, named volume và SELinux được giải thích tại Chạy Jenkins với Docker; cấu hình service Linux nằm tại Cài Jenkins trên Linux.

Headers an toàn sau reverse proxy

Cấu hình minh họa ở edge

Headers nên do reverse proxy/load balancer đã được tin cậy sở hữu. Trước khi thêm, inventory header do CDN, WAF, ingress và Jenkins runtime đang phát; Jenkins core/plugin/version có thể thay behavior, vì vậy không khẳng định core tự đặt hay không đặt một header cụ thể. Mẫu Nginx dưới đây chỉ minh họa một block edge, không phải cấu hình hoàn chỉnh để chép vào production:

# Minh họa: đặt trong server HTTPS đã có proxy trust chain được review.
# Xác nhận không có lớp edge khác gửi header mâu thuẫn.
add_header X-Content-Type-Options "nosniff" always;

# Chỉ bật sau khi hostname luôn phục vụ HTTPS ổn định.
# add_header Strict-Transport-Security "max-age=31536000" always;

# Bắt đầu bằng frame-ancestors hẹp; test integration có nhúng UI trước rollout.
add_header Content-Security-Policy "frame-ancestors 'self'" always;
  • HSTS: chỉ bật khi HTTPS ổn định cho hostname. includeSubDomains hoặc preload ảnh hưởng rộng và khó rollback ở browser; chỉ dùng sau review toàn bộ domain liên quan.
  • X-Content-Type-Options: nosniff: giảm MIME sniffing. Kiểm thử download, artifact/static asset và integration có content type không chuẩn.
  • Clickjacking: Content-Security-Policy với frame-ancestors là control hiện đại cho embedding. Nếu dùng X-Frame-Options, xác nhận tương thích/bổ sung thay vì gửi policy mâu thuẫn.
  • CSP: không sao chép một policy “chặt” từ ứng dụng khác. Jenkins UI, Stapler, plugin, inline behavior hoặc integration có thể hỏng. Bắt đầu với mục tiêu hẹp, đo violation và test runtime trước khi mở rộng directive.

Xác minh proxy, CSRF và giao diện

Proxy là trusted boundary chỉ khi nó ghi đè Host, X-Forwarded-Proto, X-Forwarded-Host và X-Forwarded-Port (hoặc quy ước tương đương đã chọn) trước controller. Không pass-through header do Internet client tự gửi. Jenkins URL, hostname, scheme, port và context path phải khớp; lỗi redirect/origin/crumb thường là tín hiệu sửa trust chain, không phải lý do tắt CSRF.

Sau thay đổi proxy/header, xác minh trong sandbox hoặc change window:

  1. browser đăng nhập/đăng xuất qua URL canonical, có và không có context-path slash theo policy;
  2. API read-only bằng service identity tối thiểu, rồi một mutation sandbox có flow crumb/token đúng runtime;
  3. webhook test đại diện vào path canonical, không gửi credential production;
  4. UI, static asset, download artifact đã cho phép, redirect và integration frame đã phê duyệt;
  5. inbound WebSocket agent (nếu dùng), access/error log proxy và trạng thái node.

Đây là validation runtime. Static review chỉ chứng minh header/config render đúng ý định; nó không chứng minh Jenkins, plugin, proxy chain hay browser thực thi tương thích.

Chuỗi thay đổi có kiểm soát

shape: sequence_diagram
O: "Owner thay đổi"
S: "Security/Network reviewer"
J: "Jenkins sandbox"
P: "Proxy/Platform"
R: "Runtime evidence"
O -> S: "Threat model, phạm vi, impact và\nrollback"
S -> O: "Phê duyệt\ncontrol/version/advisory review" {style.stroke-dash: 4}
O -> J: "Chụp baseline và kiểm thử\nallow/deny"
O -> P: "Áp dụng một thay đổi nhỏ trong\ncửa sổ"
P -> J: "Đưa flow/proxy policy mới vào\nruntime"
J -> R: "Login, API, webhook, agent,\nUI/static-asset smoke test"
branch1: "alt: Tiêu chí pass" {
  R -> O: "Evidence đã redact; theo dõi sau\nrollout" {style.stroke-dash: 4}
}
branch2: "else: Tiêu chí fail hoặc tác\nđộng không chấp nhận" {
  O -> P: "Rollback config/rule đã biết tốt"
  O -> J: "Xác nhận phục hồi và mở incident\nnếu cần"
}
Owner thay đổiSecurity/Network reviewerJenkins sandboxProxy/PlatformRuntime evidencealt: Tiêu chí passelse: Tiêu chí fail hoặc tácđộng không chấp nhận Threat model, phạm vi, impact vàrollback Phê duyệtcontrol/version/advisory reviewChụp baseline và kiểm thửallow/denyÁp dụng một thay đổi nhỏ trongcửa sổĐưa flow/proxy policy mới vàoruntimeLogin, API, webhook, agent,UI/static-asset smoke testEvidence đã redact; theo dõi saurolloutRollback config/rule đã biết tốtXác nhận phục hồi và mở incidentnếu cần
Owner thay đổiSecurity/Network reviewerJenkins sandboxProxy/PlatformRuntime evidencealt: Tiêu chí passelse: Tiêu chí fail hoặc tácđộng không chấp nhận Threat model, phạm vi, impact vàrollback Phê duyệtcontrol/version/advisory reviewChụp baseline và kiểm thửallow/denyÁp dụng một thay đổi nhỏ trongcửa sổĐưa flow/proxy policy mới vàoruntimeLogin, API, webhook, agent,UI/static-asset smoke testEvidence đã redact; theo dõi saurolloutRollback config/rule đã biết tốtXác nhận phục hồi và mở incidentnếu cần
Chuỗi thay đổi có kiểm soát

Trước change, giữ bản backup nhất quán và đường recovery administrator. Không gộp nâng core, plugin, proxy, authentication và firewall trong một thao tác nếu không có lý do đã review; khi failure xảy ra, cần biết control nào đổi. Đọc Nâng cấp Jenkins để xử lý version migration và Cấu hình hệ thống Jenkins cho ownership, drift và change window.

Lab local: review threat model không chạm Jenkins

Lab này chỉ tạo fixture review trong thư mục tạm do mktemp sinh ra. Nó không khởi động Docker/Jenkins, không gọi network, không mở firewall, không sửa JENKINS_HOME, không có secret và không chứng minh runtime production. Dùng kết quả như đầu vào cho owner network/Jenkins, sau đó thực hiện validation runtime riêng trên sandbox.

Chuẩn bị fixture an toàn

set -euo pipefail
LAB_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/jenkins-controller-hardening.XXXXXX")"
case "$LAB_ROOT" in
  "${TMPDIR:-/tmp}"/jenkins-controller-hardening.*) ;;
  *) printf 'Refuse unexpected lab path: %s\n' "$LAB_ROOT" >&2; exit 1 ;;
esac

: > "$LAB_ROOT/.lab-owned-marker"
cat > "$LAB_ROOT/review.md" <<'EOF'
# Local-only controller hardening review

| Flow | Direction | Allowed destination | Owner | Runtime test |
| --- | --- | --- | --- | --- |
| UI/API | user -> proxy -> controller | HTTPS canonical URL | platform | login + API read-only |
| Webhook | SCM -> proxy -> controller | declared webhook path | SCM owner | signed sandbox event |
| Agent | agent -> controller/proxy | approved transport | CI owner | node online/reconnect |
| Controller egress | controller -> service | approved FQDN only | network | DNS + TLS check |

Decisions to obtain before rollout:
- Is anonymous access required, and what exact permission/resource proves it?
- Which agent pools are untrusted, CI, and release?
- Which plugin/core advisories apply to the pinned inventory?
- Which proxy header and CSP behavior has runtime evidence?
EOF

printf 'Review fixture: %s/review.md\n' "$LAB_ROOT"

Mở file local, thay các mô tả chung bằng reference đã redaction đến policy/ticket của môi trường, không thay bằng IP production, token, cookie, private key hay dump config. Kết quả mong đợi là fixture có bốn flow và bốn câu hỏi; đây là threat-model/config review, không phải bằng chứng Jenkins đã được harden.

Đọc kết quả và cleanup có guard

Chỉ cleanup khi đã đọc fixture và không còn cần nó. Lệnh dưới kiểm tra marker, prefix và parent tạm trước khi xóa; nó không nhận fixed path, volume hay JENKINS_HOME:

test -f "$LAB_ROOT/.lab-owned-marker"
case "$LAB_ROOT" in
  "${TMPDIR:-/tmp}"/jenkins-controller-hardening.*)
    rm -rf -- "$LAB_ROOT"
    ;;
  *)
    printf 'Refuse cleanup outside guarded lab path: %s\n' "$LAB_ROOT" >&2
    exit 1
    ;;
esac

Nếu guard từ chối hoặc bạn không chắc path thuộc lab, không xóa. Không thay LAB_ROOT bằng đường dẫn do người khác cung cấp. Lab cố ý không có image executable; nếu bạn mở rộng nó thành Docker sandbox riêng, pin image theo tag/version hoặc digest đã phê duyệt, bind loopback và áp dụng guard prefix/parent tương tự cho mọi cleanup.

Troubleshooting

Dấu hiệuKiểm tra theo thứ tựHướng xử lý an toàn
UI/API redirect sang HTTP, :8080 hoặc host lạJenkins URL, context path, proxy Host/forwarded headers, trusted hopSửa URL/trust chain và test lại qua proxy; không public upstream hoặc tắt CSRF.
403 No valid crumb sau proxyScheme/host/prefix canonical, session/cookie, crumb issuer, permissionDùng flow browser/token đúng runtime trong sandbox; không vô hiệu hóa CSRF.
Agent offline sau firewall/proxy đổiLaunch method, DNS/TLS, exact direction, WebSocket upgrade/TCP port, timeout và log hai phíaRollback rule nhỏ hoặc restore flow đã test; không mở Any/Any hay chuyển build về controller.
Plugin/update download thất bạiController egress DNS/proxy/CA, source/mirror, plugin/core version và advisoryKhôi phục allowlist/CA chính xác hoặc dùng artifact đã duyệt; không bỏ TLS verification.
Permission denied trong home/volumeService UID/GID, mount, parent ACL/mode, SELinux/AppArmor denial, restore ownerSửa đúng object/label sau backup; không chạy root lâu dài hay chmod -R 777.
UI hoặc asset hỏng sau CSP/header đổiResponse headers từ mọi edge, browser console, Stapler/plugin page, static asset/downloadRevert header block đã đổi, thu hẹp policy và kiểm thử sandbox; không suy luận core đã đặt header.
Anonymous/API client bị từ chốiIdentity, authorization resource/action, endpoint semantics, service token ownerCấp permission hẹp có evidence hoặc giữ deny; không cấp global administrator.
Cảnh báo advisory liên quan plugin/coreInventory shortName:version, exposure, release note, dependency, staging resultPatch theo plan đã review hoặc áp dụng control bù trừ có expiry; không xóa plugin file trực tiếp.

Khi cần log, thu thập cửa sổ thời gian hẹp và redact trước khi chia sẻ. Logs & Diagnostics và Monitoring & Metrics giúp phân biệt log controller, agent, build và tín hiệu vận hành.

Checklist tự kiểm tra

  • Controller UI/API chỉ nhận traffic qua HTTPS proxy hoặc mạng quản trị; upstream không public trực tiếp.
  • Mỗi flow browser, webhook, agent, controller egress và agent egress có hướng, FQDN/port/transport, owner và evidence.
  • DNS, TLS/CA, firewall/security group và proxy trust chain được review theo từng hop; forwarded header do client không thể pass-through.
  • Tôi không nhầm network policy/label với Jenkins authentication, authorization, credential scope hoặc sandbox.
  • Built-in node/controller có 0 executor cho workload production; pool untrusted, CI và release tách capability phù hợp.
  • Anonymous read, CLI/API, legacy transport, agent protocol, Script Approval và plugin/formatter đã được đánh giá theo runtime/version, không tắt theo danh sách mù.
  • Mỗi change có owner, impact, sandbox test, rollback, advisory review và tiêu chí dừng rollout.
  • JENKINS_HOME, plugin/cache, logs, backup và workspace có ownership/ACL/retention riêng; không có chmod 777, root workaround hay shared writable mount.
  • Credential được mã hóa không bị nhầm là thay thế cho bảo vệ filesystem, backup key hay trust boundary agent.
  • HSTS chỉ được bật khi HTTPS ổn định; clickjacking/CSP/header được test với UI, Stapler/plugin, API, webhook và static asset.
  • Lab chỉ tạo fixture mktemp local, có marker/prefix/parent guard và không chạm controller, host firewall hay secret.

Checklist incident và rollback

Khi rollout làm mất login, webhook, agent hoặc phát hiện exposure, ưu tiên bảo vệ bằng chứng và giới hạn blast radius hơn là sửa nhiều lớp cùng lúc.

  1. Ổn định: dừng change tiếp theo, ghi thời điểm UTC, owner, version core/plugin và config/rule vừa áp dụng. Không xóa log, plugin, volume hay backup.
  2. Phân loại: xác định có phải mất availability, lộ credential, agent compromise, header/proxy lỗi hay advisory exposure. Với nghi ngờ secret, thu hồi/rotate theo incident process thay vì chỉ xóa output.
  3. Cô lập có mục tiêu: đóng flow/rule mới hoặc disable integration theo runbook đã phê duyệt; không lockout toàn bộ network/admin hoặc public controller để debug.
  4. Rollback: khôi phục một config/proxy/firewall/plugin plan đã biết tốt. Nếu core/plugin đã migration state, restore backup trước change vào storage cô lập thay vì chỉ hạ binary trên cùng home.
  5. Xác minh phục hồi: dùng recovery administrator, login URL canonical, API sandbox, webhook đại diện, agent pool, queue, UI/static asset và log/metric trong cửa sổ quan sát.
  6. Đóng vòng: lưu evidence đã redact, quyết định advisory, nguyên nhân, residual risk và follow-up owner/date. Giữ backup/evidence theo retention; không cho hai controller cùng ghi một JENKINS_HOME.

Nguồn Jenkins chính thức

Đọc tiếp

On this page