Nếu công ty của bạn chặn lưu lượng truy cập ra ngoài qua proxy doanh nghiệp, các trợ lý AI như Cursor và Claude Code
sẽ không phản hồi: tự động hoàn thành bị treo, CLI hiển thị ETIMEDOUT
hoặc vấn đề chứng chỉ SSL.
Hãy cùng tìm hiểu cách thiết lập đúng các biến môi trường HTTPS_PROXY,
cấu hình xác thực và tránh các lỗi thường gặp khiến các lập trình viên mất hàng giờ để gỡ lỗi các thiết lập mạng thay vì mã.
Tại sao trợ lý AI cần proxy trong mạng doanh nghiệp
Cursor và Claude Code không phải là các mô hình cục bộ. Chúng liên tục gọi đến các API bên ngoài: Cursor kết nối đến các máy chủ lập chỉ mục mã của mình và đến các API mô hình (OpenAI, Anthropic, Google tùy thuộc vào nhà cung cấp được chọn), trong khi Claude Code — kết nối trực tiếp đến API của Anthropic qua HTTPS. Trong mạng doanh nghiệp, quyền truy cập trực tiếp vào internet thường bị chặn bởi tường lửa, và toàn bộ lưu lượng truy cập ra ngoài phải đi qua máy chủ proxy (Squid, Zscaler, Blue Coat, Fortinet FortiProxy hoặc cổng doanh nghiệp nội bộ). Nếu không có các biến môi trường được cấu hình đúng, ứng dụng sẽ không biết rằng lưu lượng cần phải được chuyển qua proxy, và cố gắng kết nối trực tiếp đến internet — dẫn đến thời gian chờ.
Một khó khăn riêng biệt là Cursor được xây dựng trên Electron (về cơ bản là Chromium + Node.js), trong khi Claude Code là
một ứng dụng CLI Node.js. Mỗi ứng dụng có logic riêng để đọc các thiết lập proxy: Electron một phần kế thừa các thiết lập hệ thống
của OS, trong khi các quy trình Node.js đọc các biến môi trường HTTP_PROXY/HTTPS_PROXY
trực tiếp hoặc qua các thư viện như undici và node-fetch.
Điều này gây ra sự nhầm lẫn: các thiết lập đã được cấu hình, nhưng công cụ lại không "nhìn thấy" chúng.
Các biến HTTP_PROXY, HTTPS_PROXY và NO_PROXY: cách hoạt động
Cách cổ điển để chỉ định proxy cho các ứng dụng Node.js, Python và Go trên console là thông qua các biến môi trường. Sự khác biệt giữa HTTP_PROXY và HTTPS_PROXY là nguyên tắc: cái đầu tiên được sử dụng cho các yêu cầu qua giao thức HTTP, cái thứ hai — cho các yêu cầu HTTPS (và hầu hết lưu lượng của các trợ lý AI đi qua HTTPS). Nên chỉ định cả hai, ngay cả khi lưu lượng thực tế chỉ là HTTPS — một số thư viện khi khởi động thực hiện các yêu cầu HTTP phục vụ.
export HTTP_PROXY="http://proxy.company.local:8080" export HTTPS_PROXY="http://proxy.company.local:8080" export NO_PROXY="localhost,127.0.0.1,.company.local"
Lưu ý: ngay cả đối với lưu lượng HTTPS, sơ đồ trong địa chỉ proxy được chỉ định là http://,
chứ không phải https:// —
đây là địa chỉ của chính máy chủ proxy, không phải tài nguyên mục tiêu. Kết nối với proxy qua HTTP là điều bình thường, mã hóa
đến máy chủ cuối cùng vẫn hoạt động thông qua cơ chế kết nối CONNECT.
Biến NO_PROXY cần thiết
để loại trừ các địa chỉ nội bộ của công ty khỏi việc proxy — nếu không, các yêu cầu đến các kho git nội bộ, Jira
hoặc các dịch vụ phát triển cục bộ cũng sẽ đi qua proxy bên ngoài và có thể không tìm thấy hoặc bị chậm lại. Một điểm quan trọng:
một số thư viện nhạy cảm với chữ hoa chữ thường của các biến. Để đảm bảo, hãy chỉ định cả hai biến —
chữ hoa và chữ thường:
export http_proxy="$HTTP_PROXY" export https_proxy="$HTTPS_PROXY" export no_proxy="$NO_PROXY"
Cấu hình proxy cho Cursor
Cursor một phần sử dụng các thiết lập proxy hệ thống của OS (đặc biệt trên macOS và Windows), nhưng để hoạt động ổn định trong mạng doanh nghiệp, tốt hơn là cấu hình rõ ràng thông qua các biến môi trường và, nếu cần, thông qua tệp cấu hình của ứng dụng.
Trên macOS và Linux, dễ nhất là thêm xuất biến vào tệp hồ sơ shell, để chúng được nạp mỗi khi khởi động terminal mà từ đó Cursor được khởi động:
# ~/.zshrc hoặc ~/.bash_profile export HTTP_PROXY="http://user:[email protected]:8080" export HTTPS_PROXY="http://user:[email protected]:8080" export NO_PROXY="localhost,127.0.0.1,*.company.local"
Sau khi thay đổi tệp hồ sơ, hãy thực hiện source ~/.zshrc
và khởi động lại hoàn toàn Cursor (không chỉ thu nhỏ cửa sổ — hãy kết thúc quy trình qua Activity Monitor hoặc trình quản lý
tác vụ, vì các ứng dụng Electron lưu cache môi trường khi khởi động).
Trên Windows, các biến dễ dàng hơn khi được thiết lập qua các thiết lập hệ thống môi trường (Control Panel → System → Advanced system settings → Environment Variables) hoặc qua PowerShell để lưu trữ vĩnh viễn:
[System.Environment]::SetEnvironmentVariable('HTTPS_PROXY','http://user:[email protected]:8080','User')
[System.Environment]::SetEnvironmentVariable('HTTP_PROXY','http://user:[email protected]:8080','User')
[System.Environment]::SetEnvironmentVariable('NO_PROXY','localhost,127.0.0.1','User')
Nếu sau đó Cursor vẫn không kết nối được với API của các mô hình, hãy kiểm tra các thiết lập proxy bên trong chính ứng dụng: Settings → Network (hoặc General) — có thể có một trường riêng Proxy URL, cái này sẽ ghi đè các biến hệ thống. Trong một số phiên bản của Cursor, cũng cần phải bật tùy chọn "Use system proxy settings".
Cấu hình proxy cho Claude Code
Claude Code là một công cụ CLI trên Node.js, được khởi động qua npm/npx, vì vậy nó đọc trực tiếp các biến môi trường từ phiên terminal mà nó được gọi. Điều này đơn giản hóa việc cấu hình: chỉ cần xuất các biến trước khi khởi động.
export HTTPS_PROXY="http://user:[email protected]:8080" export HTTP_PROXY="http://user:[email protected]:8080" claude
Nếu bạn khởi động Claude Code như một phần của pipeline CI hoặc từ một script, hãy truyền các biến rõ ràng vào lệnh khởi động, để tránh phụ thuộc vào môi trường toàn cầu của shell:
HTTPS_PROXY="http://proxy.company.local:8080" \ HTTP_PROXY="http://proxy.company.local:8080" \ claude --print "Kiểm tra các bài kiểm tra trong dự án"
Để cấu hình vĩnh viễn, dễ dàng hơn khi cố định các biến trong tệp .env
ở gốc dự án và nạp nó qua direnv
hoặc hỗ trợ tích hợp dotenv, nếu shell của bạn hỗ trợ. Điều này đặc biệt tiện lợi khi các dự án khác nhau yêu cầu
các thiết lập proxy khác nhau (ví dụ, một dự án làm việc với API nội bộ, trong khi dự án khác làm việc với các dịch vụ bên ngoài).
Xác thực trên proxy doanh nghiệp
Hầu hết các proxy doanh nghiệp yêu cầu xác thực — Basic Auth, Digest hoặc NTLM. Đối với Basic Auth, tên đăng nhập
và mật khẩu có thể được nhúng trực tiếp vào URL của proxy, như đã trình bày ở trên: http://user:[email protected]:8080.
Một điểm quan trọng — nếu mật khẩu chứa các ký tự đặc biệt (@, #, %),
chúng cần được mã hóa URL, nếu không, bộ phân tích cú pháp chuỗi proxy sẽ bị lỗi ở ranh giới giữa tên đăng nhập và máy chủ.
# Nếu mật khẩu là P@ssw0rd#2024, mã hóa các ký tự đặc biệt: # @ -> %40, # -> %23 export HTTPS_PROXY="http://user:P%40ssw0rd%[email protected]:8080"
Khó khăn hơn với xác thực NTLM (thường được sử dụng kết hợp với Microsoft ISA Server, Forefront TMG hoặc Fortinet) —
Node.js và hầu hết các HTTP client không hỗ trợ NTLM "ngay từ đầu". Trong trường hợp này, giải pháp tiêu chuẩn —
là thiết lập một proxy trung gian cục bộ, cái này sẽ xử lý việc bắt tay NTLM, và sau đó cung cấp một proxy HTTP "sạch"
cho ứng dụng. Để làm điều này, thường sử dụng cntlm hoặc px (proxy NTLM cục bộ trên Python).
Sơ đồ đơn giản: Cursor/Claude Code → localhost:3128 (cntlm) → proxy NTLM doanh nghiệp → internet.
# Ví dụ cấu hình cntlm (/etc/cntlm.conf) Username your_login Domain COMPANY Password mật_khẩu_của_bạn_hoặc_hash Proxy proxy.company.local:8080 Listen 3128 # Sau khi khởi động cntlm, chỉ định địa chỉ cục bộ: export HTTPS_PROXY="http://127.0.0.1:3128" export HTTP_PROXY="http://127.0.0.1:3128"
Chứng chỉ và MITM: vấn đề SSL trong mạng doanh nghiệp
Nếu trong công ty triển khai sản phẩm lớp Zscaler, Netskope hoặc bất kỳ bộ lọc web nào khác với kiểm tra SSL,
lưu lượng được giải mã trên proxy và ký bằng chứng chỉ Root CA doanh nghiệp. Node.js (và do đó cả
Claude Code, cũng như phần lớn các mô-đun nội bộ của Cursor) theo mặc định chỉ tin tưởng vào bộ chứng chỉ gốc tích hợp của nó
và sẽ ném ra lỗi UNABLE_TO_VERIFY_LEAF_SIGNATURE hoặc
self signed certificate in certificate chain.
Giải pháp — xuất chứng chỉ CA doanh nghiệp (thường có thể lấy từ bộ phận IT hoặc xuất từ
kho chứng chỉ của trình duyệt) và chỉ định cho Node.js đường dẫn đến nó thông qua biến NODE_EXTRA_CA_CERTS:
export NODE_EXTRA_CA_CERTS="/etc/ssl/certs/company-root-ca.pem"
Rất không khuyến khích việc tắt kiểm tra chứng chỉ toàn cầu thông qua NODE_TLS_REJECT_UNAUTHORIZED=0 —
điều này loại bỏ bảo vệ chống lại các cuộc tấn công MITM trên toàn bộ quy trình, bao gồm cả các kết nối hợp pháp. Chỉ sử dụng cờ này cho
việc chẩn đoán một lần và nhất định phải khôi phục lại bảo vệ.
Các lỗi thường gặp và cách giải quyết
| Lỗi | Nguyên nhân | Giải pháp |
|---|---|---|
| ETIMEDOUT / ECONNREFUSED | Các biến proxy không được xuất trong phiên mà ứng dụng đang chạy | Kiểm tra echo $HTTPS_PROXY trong cùng một terminal, khởi động lại toàn bộ ứng dụng |
| 407 Proxy Authentication Required | Tên đăng nhập/mật khẩu không được chỉ định hoặc đã lỗi thời | Cập nhật thông tin đăng nhập trong chuỗi proxy, mã hóa URL các ký tự đặc biệt trong mật khẩu |
| self signed certificate in certificate chain | Proxy MITM doanh nghiệp thay thế chứng chỉ | Chỉ định NODE_EXTRA_CA_CERTS với chứng chỉ Root CA doanh nghiệp |
| Proxy hoạt động trong terminal, nhưng không trong Cursor | Cursor được khởi động không từ terminal đó hoặc qua shortcut không có môi trường | Khởi động Cursor bằng lệnh từ terminal với các biến đã xuất, hoặc chỉ định các biến toàn cầu trong hệ thống |
| NTLM authentication failed | Client không hỗ trợ bắt tay NTLM | Thiết lập proxy trung gian cntlm hoặc px giữa ứng dụng và proxy doanh nghiệp |
Kiểm tra kết nối qua curl
Trước khi tìm hiểu lý do tại sao Cursor hoặc Claude Code không hoạt động, hãy đảm bảo rằng proxy có thể truy cập và chính xác proxy hóa lưu lượng HTTPS. Để làm điều này, hãy sử dụng curl — nó đọc cùng các biến môi trường và cho phép nhanh chóng xác định vấn đề mà không cần khởi động các ứng dụng nặng.
# Kiểm tra khả năng truy cập proxy và xác thực curl -v -x "http://user:[email protected]:8080" https://api.anthropic.com # Kiểm tra với chứng chỉ doanh nghiệp curl -v --cacert /etc/ssl/certs/company-root-ca.pem \ -x "http://user:[email protected]:8080" \ https://api.anthropic.com
Nếu curl nhận được phản hồi thành công (ngay cả 401 hoặc 403 — điều này là bình thường, có nghĩa là quá trình bắt tay TLS đã thành công), nhưng Claude Code vẫn không kết nối được — vấn đề không nằm ở mạng, mà ở việc quy trình không nhìn thấy các biến môi trường. Nếu curl cũng gặp lỗi chứng chỉ hoặc thời gian chờ — vấn đề nằm ở cấp độ mạng hoặc proxy, và các công cụ không liên quan.
Khi nào cần proxy bên ngoài thay vì doanh nghiệp
Đôi khi nhiệm vụ không chỉ giới hạn ở việc truy cập từ mạng doanh nghiệp ra ngoài. Các lập trình viên, những người thử nghiệm tích hợp với các API phụ thuộc vào địa lý, kiểm tra hành vi của dịch vụ từ các quốc gia khác nhau hoặc gỡ lỗi chính sách giới hạn tần suất của các nhà cung cấp mô hình, gặp phải tình huống mà proxy doanh nghiệp cung cấp cùng một địa chỉ IP doanh nghiệp cho tất cả các yêu cầu. Trong những kịch bản như vậy, việc cho phép lưu lượng thử nghiệm đi qua proxy bên ngoài song song với môi trường làm việc chính là rất tiện lợi.
Đối với các phiên thử nghiệm lâu dài ổn định với rủi ro thấp về việc bị chặn theo IP, các proxy cư trú là lựa chọn phù hợp — chúng sử dụng các địa chỉ IP thực từ các nhà cung cấp gia đình và trông giống như lưu lượng của người dùng thông thường, điều này quan trọng khi kiểm tra các phản hồi API phụ thuộc vào địa lý. Nếu cần tái tạo hành vi của khách hàng di động hoặc thử nghiệm các kịch bản nhạy cảm với loại mạng, nên xem xét proxy di động. Còn đối với việc thử nghiệm hàng loạt các yêu cầu đến các API công cộng, nơi tốc độ và chi phí lưu lượng quan trọng hơn việc ngụy trang thành người dùng thông thường, thường chỉ cần proxy trung tâm dữ liệu.
Quan trọng: proxy bên ngoài như vậy được cấu hình chính xác giống như thông qua các biến HTTPS_PROXY/HTTP_PROXY,
nhưng cho môi trường thử nghiệm hoặc một hồ sơ terminal riêng biệt, để không trộn lẫn với lưu lượng làm việc chính
qua cổng doanh nghiệp. Nếu chính sách doanh nghiệp yêu cầu rằng toàn bộ lưu lượng của công ty chỉ đi qua
proxy nội bộ, việc sử dụng bên ngoài phải được đồng ý với IT/Bảo mật — nhiều công ty hoàn toàn
cấm việc vượt qua cổng doanh nghiệp mà không có sự cho phép.
Danh sách kiểm tra cấu hình
- Đã xuất cả hai biến:
HTTP_PROXYvàHTTPS_PROXY(trong cả hai chữ hoa và chữ thường) - Trong
NO_PROXYđã liệt kê các miền nội bộ và localhost - Các ký tự đặc biệt trong mật khẩu đã được mã hóa URL
- Ứng dụng đã được khởi động lại hoàn toàn, không chỉ thu nhỏ/đưa lên
- Đã kiểm tra bằng yêu cầu curl với cùng các biến như ứng dụng
- Nếu có kiểm tra MITM SSL — đã chỉ định
NODE_EXTRA_CA_CERTSvới chứng chỉ Root CA doanh nghiệp - Nếu proxy sử dụng NTLM — đã thiết lập cntlm/px trung gian trên localhost
- Đối với các kịch bản thử nghiệm, proxy bên ngoài đã được đưa vào hồ sơ môi trường riêng biệt
Kết luận
Hầu hết các vấn đề với Cursor và Claude Code qua proxy doanh nghiệp đều liên quan đến ba điều: các biến môi trường
không đến được quy trình, xác thực được cấu hình sai, hoặc chứng chỉ MITM doanh nghiệp không được thêm vào
danh sách tin cậy. Kiểm tra ba điểm này theo thứ tự — thông qua curl,
thay vì ngay lập tức qua chính ứng dụng — bạn tiết kiệm hàng giờ cho việc gỡ lỗi và nhanh chóng xác định nguyên nhân.
Nếu nhiệm vụ vượt ra ngoài mạng doanh nghiệp và bạn cần thử nghiệm hành vi của API từ các khu vực khác nhau hoặc từ các loại IP khác nhau, chúng tôi khuyên bạn nên thử proxy cư trú — chúng cung cấp lưu lượng ổn định và ít bị nghi ngờ hơn đối với các dịch vụ bên ngoài so với các địa chỉ trung tâm dữ liệu thông thường.