Thẻ triển khai là lý do thông thường khiến người ta tìm đến tính năng này: mỗi kết nối nên mang theo một thứ gì đó như vị trí hoặc vai trò, và máy chủ nên đọc nó mà không phải phát minh ra định dạng thông tin xác thực thứ hai. OpenVPN cộng đồng đã có cơ chế này, và nó nhỏ. Phần gây khó chịu là kỳ vọng. Đặt một biến thông thường trong hồ sơ máy khách không làm gì trên máy chủ, và một giá trị thực sự đến chỉ chứng minh rằng máy khách đã gửi nó.

Đây là hướng dẫn cho con đường hoạt động, bước xác minh cho thấy điều gì thực sự đã đến, và việc hoàn tác không để lại hook nào bị cấu hình dở. Không có gì ở đây cần chứng chỉ mới, plugin mới hay tiện ích mở rộng giao thức.

Đặt biến và bật đường đi

Hai dòng thực hiện công việc trong hồ sơ máy khách, và cả hai đều cần thiết. Không có dòng đầu thì không có gì để gửi; không có dòng thứ hai thì máy khách hoàn toàn không cung cấp thông tin máy ngang hàng. Thứ tự không quan trọng, và nên biết điều đó vì hai dòng thường nằm ở các phần khác nhau của một hồ sơ được tạo. Điều quan trọng là cả hai phải sống sót qua bất cứ thứ gì ghi lại hồ sơ trước khi máy khách đọc nó.

setenv UV_DEPLOY field-support
push-peer-info

Tiền tố UV_ không phải đồ trang trí. Một biến DEPLOY thông thường vẫn cục bộ trong tiến trình máy khách và không bao giờ được chuyển tiếp, trong khi dạng có tiền tố là không gian tên mà giao thức dành riêng cho các trường do người dùng định nghĩa. Giữ nguyên phần còn lại của hồ sơ đã được phê duyệt và xác nhận trước khi triển khai rằng bản dựng máy khách bạn triển khai hỗ trợ cả hai chỉ thị.

Một kiểm tra thực tế thuộc về đây, không phải ở cuối: hãy chắc chắn rằng chỉ thị đến được tệp nhị phân của máy khách và không bị một lớp bao bọc nuốt mất. Một máy khách đồ họa tự tạo dòng lệnh của riêng nó, hoặc một giao diện quản lý tải lại hồ sơ đã lưu, có thể bỏ những dòng mà nó không nhận ra. Nếu máy chủ không thấy gì, đây là nơi đầu tiên cần xem.

Đọc trường từ hook của máy chủ

Ở phía máy chủ, thông tin máy ngang hàng nhận được sẽ được xác thực và chèn vào môi trường của luồng công việc kết nối, và đó chính là điều khiến nó có thể đọc được từ một hook mà không cần bất kỳ công việc giao thức nào từ phía bạn. Máy chủ không cần phân tích kênh điều khiển hay lưu trữ bất cứ thứ gì cho bạn; giá trị đơn giản là hiện diện trong khi kết nối được thiết lập. Một script client-connect tối thiểu ghi nhãn bên cạnh tên đã xác thực trông như thế này.

#!/bin/sh
# /etc/openvpn/server/hooks/label.sh
printf '%s %s\n' "$common_name" "${UV_DEPLOY:-unset}" \
  >> /var/log/openvpn/deploy-labels.log

Hãy đọc biến qua môi trường thay vì phân tích nhật ký, và luôn cung cấp cho nó một giá trị mặc định. ${UV_DEPLOY:-unset} giữ cho script hoạt động với những máy khách không bao giờ gửi trường đó, đây là trạng thái bình thường trong một lần triển khai theo giai đoạn. Đừng đổ toàn bộ môi trường vào nhật ký để tìm tên; nó chứa nhiều thứ hơn cả nhãn, bao gồm những giá trị mà bạn không định lưu giữ.

Chạy script bằng tay và nó sẽ báo cáo unset cho mọi thứ, vì một shell thủ công không mang theo môi trường của kết nối. Đó không phải lỗi trong script và cũng không phải bằng chứng rằng trường bị thiếu. Hãy kiểm tra nó qua một kết nối thực, ngữ cảnh duy nhất mà biến tồn tại.

Xác minh điều gì thực sự đã đến

Kết nối một máy khách có nhãn và một máy không có, sau đó đọc tệp. Cặp đôi chính là phép thử: một dòng phải mang giá trị và dòng kia mang giá trị mặc định, và cả hai phải nêu cùng một danh tính đã xác thực mà bạn mong đợi.

tail -n 5 /var/log/openvpn/deploy-labels.log
# field-support deployed-client-07
# unset         legacy-laptop-02

Những dòng chú thích đó là hình dạng của đầu ra, không phải bản ghi từ máy chủ của bạn; hãy đọc tệp của chính bạn. Nếu máy khách thứ hai cũng hiển thị một giá trị, thì biến đã được đặt ở nơi khác trong môi trường, và bạn đang đọc một cấu hình cũ thay vì trường máy ngang hàng.

Cũng hãy kiểm tra nhật ký máy chủ cho kết nối. Thông tin máy ngang hàng có thể xuất hiện ở đó, điều này thuận tiện cho việc gỡ lỗi và là lý do để giữ các giá trị nhàm chán: không có tên người, không có số phiếu, không có gì bạn không muốn người đọc nhật ký nhìn thấy.

Coi nhãn là lời khẳng định, không phải danh tính

Bất kỳ ai có thể sửa hồ sơ máy khách đều có thể thay đổi thẻ, và việc đường hầm được xác thực không làm cho thẻ có thẩm quyền. Lớp truyền tải bảo vệ giá trị trên đường đi; nó không chứng nhận lời khẳng định. Quyền ủy quyền vẫn thuộc về danh tính đã xác thực và một bản ghi đăng ký do máy chủ sở hữu, với nhãn được so sánh với bản ghi đó khi cần.

Sự khác biệt đó quyết định nơi nhãn có thể được sử dụng. Cách dùng tốt là định tuyến một phiên đến đúng tệp nhật ký, chọn một nhóm hiển thị trong bảng điều khiển, hoặc gắn nhãn một phiên hỗ trợ để con người tìm thấy nó sau này. Cách dùng xấu là cho một thiết bị vào mạng con, chọn chính sách tường lửa, hoặc quyết định phiên được đọc dữ liệu của khách hàng nào.

Hãy xác thực giá trị trước khi nó đến một đường dẫn, truy vấn hay lệnh shell. Danh sách cho phép các chuỗi dự kiến là đủ cho một thẻ triển khai, và nó không tốn gì. Không bao giờ nội suy một chuỗi do máy ngang hàng cung cấp vào dòng lệnh shell, và giới hạn mọi quan sát được lưu trong phiên chứ không phải một địa chỉ đường hầm mà máy khách tiếp theo sẽ dùng lại.

case "${UV_DEPLOY:-}" in
  field-support|field-qa|lab) : ;;
  *) UV_DEPLOY=unknown ;;
esac

Hoàn tác gọn gàng

Xóa tính năng là hai lần xóa và một lần xác minh. Xóa các dòng setenv và push-peer-info khỏi hồ sơ máy khách, sau đó xóa hoặc vô hiệu hóa hook và đích nhật ký của nó trên máy chủ.

grep -rn 'UV_DEPLOY\|push-peer-info' /etc/openvpn/
tail -n 3 /var/log/openvpn/deploy-labels.log

Kết nối lại một máy khách sau đó và xác nhận rằng dòng nhật ký không còn xuất hiện. Một hook vẫn kích hoạt sau khi thay đổi hồ sơ thường là hồ sơ thứ hai vẫn được triển khai trên một thiết bị kiểm thử, và tìm ra nó bây giờ rẻ hơn tìm ra nó trong một cuộc kiểm toán.

Điều còn lại cuối cùng là một mẩu siêu dữ liệu phiên nhỏ và có giới hạn với nguồn gốc được ghi lại: máy khách khẳng định nó, máy chủ ghi nhận nó, và không có gì về quyền truy cập phụ thuộc vào nó. Đó là phiên bản hữu ích của tính năng, và nó không cần thông tin xác thực mới để đến đó.

Bài viết liên quan