OpenConnect nối hai lần trao đổi riêng biệt bằng một giá trị ngắn hạn duy nhất: đăng nhập web và đường hầm VPN. Lần trao đổi đầu là HTTPS thông thường: thông tin xác thực, một lượt SAML hoặc token đi đến cổng, và phản hồi mang theo cookie xác thực. Lần trao đổi thứ hai trình cookie đó cho chính cổng ấy như bằng chứng rằng giai đoạn web đã xảy ra, và chỉ khi đó đường hầm mới dựng lên.

Trong lúc đăng nhập không có gì về đường hầm được thương lượng. Đây chính là phần đáng hiểu, vì phần lớn lỗi script cho rằng cookie là mật khẩu để lưu, hoặc chìa khóa bảo vệ lưu lượng, trong khi thực tế nó là tấm vé mang cho một phiên cổng cụ thể.

Máy khách và cổng trao đổi những gì, theo thứ tự

Giai đoạn xác thực trông giống một trang web được bảo vệ thông thường. OpenConnect gửi thông tin xác thực của người dùng, hoặc theo chuyển hướng của cổng đến nhà cung cấp danh tính, và cổng trả lời bằng một tài liệu nhúng cookie xác thực. Trong giao thức AnyConnect, giá trị đó đi trong tiêu đề cookie ở các yêu cầu tiếp theo, thường dưới một tên như webvpn, và sách hướng dẫn coi nó là thông tin xác thực mang phiên đi tiếp.

Giai đoạn thứ hai là yêu cầu CONNECT tới điểm cuối VPN của cổng với cookie đó được đính kèm. Cổng kiểm tra nó, cấp một địa chỉ, và máy khách khởi động CSTP trên TLS, còn DTLS là đường dữ liệu nhanh hơn tùy chọn khi phiên đã tồn tại. Chỉ tại thời điểm này các tham số đường hầm, tuyến, thiết lập DNS và khóa lưu lượng của phiên mới được thiết lập. Cookie đưa máy khách qua cửa; nó không mã hóa gì cả.

Trình tự này giải thích vì sao openconnect --authenticate tồn tại. Chạy nó, và nó thực hiện giai đoạn web, in ra một khối nhỏ các biến shell như COOKIE, HOST, CONNECT_URL và FINGERPRINT, rồi thoát trước khi bất kỳ đường hầm nào được dựng. Một script bao bọc sau đó có thể bắt đầu kết nối thật với những giá trị ấy, và đó chính là cách tách mà một triển khai không màn hình hoặc hai container cần.

Cookie là vật mang phiên, không phải chìa khóa

Hãy đối xử với giá trị đó như bạn đối xử với một mã phiên trong ứng dụng web. Ai giữ nó trong suốt vòng đời có thể yêu cầu cổng cấp đường hầm mà phiên đó có quyền, nên tính bí mật của nó quan trọng. Nhưng sao chép nó không làm lộ lưu lượng, vì tính bảo mật của đường hầm đến từ bắt tay TLS và các khóa dẫn xuất, không phải từ chuỗi cookie.

Nó cũng không phải sự cho phép vĩnh viễn. Cổng và nhà cung cấp danh tính quyết định phiên sống bao lâu, và một trình duyệt còn hiển thị trang đã đăng nhập không nói gì về việc phiên đường hầm còn hiệu lực hay không. Kết nối lại sau khi hết hạn nghĩa là lặp lại giai đoạn web và tạo cookie mới, và đó chính là mục đích của xác thực lại, không phải phiền toái để lách bằng kỹ thuật.

Đừng coi cookie là vật thay thế phổ quát cho các thông tin xác thực khác. Khẳng định SAML, mật khẩu trình duyệt và cookie do một dịch vụ khác phát hành là những đối tượng khác nhau với đối tượng người dùng khác nhau, và việc dán cái này vào trường của cái kia thường thất bại tại cổng hoặc, tệ hơn, thành công trước ranh giới tin cậy sai.

Bàn giao cookie mà không để lại bản sao

Cách bàn giao cơ học an toàn nhất trên Linux là đầu vào chuẩn. --cookie-on-stdin đọc giá trị từ stdin, nên cookie không bao giờ xuất hiện trong danh sách tham số của tiến trình, nơi bất kỳ người dùng cục bộ nào cũng có thể đọc bằng ps. Một đường ống xác thực trong tiến trình này và nuôi đường hầm trong tiến trình khác giữ giá trị trong ống thay vì trong tệp hay biến môi trường.

Tham số và biến môi trường yếu hơn vì những lý do khác nhau. Tham số hiển thị trong bảng tiến trình suốt vòng đời máy khách và thường rơi vào lịch sử shell. Biến môi trường được kế thừa cho tiến trình con, và một unit systemd đặt nó trong tệp unit sẽ lưu bí mật trong cấu hình đọc được. Nếu buộc phải dùng tệp, hãy giới hạn cho tài khoản dịch vụ và xóa nó khi phiên kết thúc.

Cũng hãy giữ ranh giới đặc quyền một cách có chủ đích. Tiến trình nói chuyện với nhà cung cấp danh tính và có thể mở trình duyệt nên chạy dưới người dùng sở hữu lần đăng nhập đó. Tiến trình cấu hình tuyến, DNS và thiết bị đường hầm có thể cần nhiều đặc quyền hơn. Chạy toàn bộ trình duyệt bằng root để cookie của nó sẵn có cho một đường hầm thuộc root là sự đánh đổi sai, và các thiết lập OpenConnect hiện đại có thể chuyển giá trị qua ranh giới đó một cách tường minh.

Việc ghi log cũng đáng bị nghi ngờ như vậy. Đầu ra chi tiết của máy khách, script phụ trợ và chẩn đoán cổng đều có thể lặp lại tài liệu của yêu cầu, và không phải mọi mức log đều che cookie. Ghi lại bản ghi lỗi nhỏ nhất mà bạn cần, giữ nó ngoài các kênh chia sẻ, và kiểm tra một mẫu đã che trước khi đính kèm vào phiếu.

Xác minh và hết hạn trong giai đoạn thứ hai

Giai đoạn thứ hai vẫn phải xác minh máy chủ. FINGERPRINT mà --authenticate in ra là ghim chứng chỉ ở dạng pin-sha256:, và việc chuyển nó cho lời gọi đường hầm bằng --servercert giữ việc kiểm tra neo vào cổng mà bạn đã xác thực. Tắt kiểm tra chứng chỉ để đơn giản hóa script sẽ bỏ đi bằng chứng duy nhất rằng cookie đang được trao cho đúng máy chủ dự định.

Khi cổng từ chối cookie, giải pháp là một vòng xác thực mới, không phải bộ nhớ đệm dài hơn. Chỉ lưu cookie trong vòng đời kết nối, xóa tệp tạm khi thoát, và dùng quy trình xóa phiên của nhà cung cấp danh tính hoặc của cổng khi phiên bị lộ hoặc thiết bị bị mất. Cookie được lưu đệm không phải là miễn trừ MFA.

Trước khi tự động hóa điều này, hãy xác minh bốn điều: đường hầm chạy dưới đúng tài khoản, cookie đến qua stdin, dấu vân tay chứng chỉ được ghim, và phiên bị hủy khi đường hầm đóng. Nếu thiếu bất kỳ điều nào, tự động hóa đã mở rộng niềm tin vào cookie thay vì tái tạo quy trình thủ công.

Bài viết liên quan