OpenVPN đọc mật khẩu từ terminal, không phải từ stdin
OpenVPN thực sự đọc mật khẩu ở đâu, vì sao một tệp trên stdin thất bại, và ba con đường được hỗ trợ để đăng nhập bằng script trên Linux và macOS.
OpenVPN hỏi tên người dùng và mật khẩu trên terminal điều khiển, và một tệp được chuyển hướng vào đầu vào chuẩn không phải là terminal đó. Chính chi tiết này giải thích đoạn script bị treo trong khi mật khẩu nằm ngay trong ống. Ứng dụng khách vẽ lời nhắc và việc đọc lấy từ thiết bị terminal, nên chuyển hướng stdin không thay đổi gì. Cấp dữ liệu cho ứng dụng khách qua một trong các đường vào đã được ghi tài liệu và chính đoạn script đó sẽ kết nối ngay lần đầu.
Ba con đường bao phủ gần như mọi trường hợp, và mỗi con đường thất bại theo cách riêng. Hãy chọn theo lời nhắc mà ứng dụng khách thực sự hiển thị, không phải theo tùy chọn dễ viết script nhất.
Lời nhắc không đến từ stdin
Khi OpenVPN cần thông tin đăng nhập, nó mở terminal điều khiển và đọc ở đó. Vì thế một bài kiểm tra tương tác trông ổn trong khi cùng lệnh đó dưới cron hay trong tệp unit lại đứng yên với lời nhắc được ghi vào nhật ký mà không ai xem. Một số bản dựng quay về đầu vào chuẩn khi không có terminal, và sự không nhất quán đó tệ hơn một lỗi cứng vì nó giấu vấn đề cho đến lúc triển khai.
Hãy kiểm tra môi trường trước khi viết bất kỳ mã nào: chạy ứng dụng khách dưới cùng người dùng, với cùng stdin, như bộ lập lịch hay trình quản lý dịch vụ sẽ làm. Nếu lời nhắc không bao giờ xuất hiện trong nhật ký và tiến trình không tiến lên, có gì đó đang chờ một terminal không tồn tại.
Con đường thứ nhất: tệp thông tin đăng nhập hai dòng
Tùy chọn xác thực nhận một đường dẫn, và tệp chứa đúng hai dòng, tên người dùng rồi đến mật khẩu, không có gì khác. Hãy truyền đường dẫn một cách tường minh thay vì dựa vào tên tệp mặc định, vì một tệp thông tin đăng nhập nằm lạc trong thư mục làm việc chính là cách tài khoản sai bị đưa vào dùng. Đặt chế độ 0600 và trao quyền sở hữu cho tài khoản chạy ứng dụng khách.
Ứng dụng khách đọc tệp đó một lần khi khởi động, nên xoay mật khẩu nghĩa là khởi động lại tiến trình. Đó thường là hành vi bạn muốn, và nó thuộc về runbook bên cạnh quy trình xoay.
Con đường thứ hai: askpass cho cụm mật khẩu của khóa
Một khóa riêng được bảo vệ bằng cụm mật khẩu tạo ra lời nhắc thứ hai, khác biệt, và nó có câu trả lời dựa trên tệp của riêng mình: tùy chọn askpass đọc cụm từ ở dòng đầu tiên của một tệp. Với các đường hầm dựa trên SSH, tương đương là một chương trình askpass do ứng dụng khách thực thi, và đầu ra chuẩn của nó trở thành bí mật.
Không dạng nào đặt bí mật vào danh sách đối số, và cả hai đều để nó tồn tại như một tệp hoặc như một chương trình thực thi in ra nó. Bảo vệ nằm ở quyền tệp và quyền sở hữu tiến trình, không phải ở sự mờ ám. Một trình trợ giúp lặp lại chuỗi gán cứng trong mã là một bí mật với thêm bước.
Con đường thứ ba: CLI riêng của ứng dụng khách cổng
Ứng dụng khách doanh nghiệp thường cung cấp một điểm vào dòng lệnh kết nối tới một cổng có tên mà không cần cửa sổ nào, và đó là con đường được hỗ trợ. Trên Linux, ứng dụng khách GlobalProtect cung cấp thao tác kết nối và nhập chứng chỉ qua CLI của nó, và các cổng dùng xác thực bằng chứng chỉ cần bước nhập trước khi một kết nối tự động có thể hoạt động. Hãy ưu tiên nó hơn các lần gõ phím tổng hợp: bạn có mã thoát thật, không phụ thuộc tiêu điểm cửa sổ, và nó sống sót qua màn hình khóa.
Nếu lần kết nối đầu vẫn cần người chấp nhận một chứng chỉ thì tự động hóa chưa xong. Hãy làm bước nhập trong lúc thiết lập và ghi nó như một điều kiện tiên quyết.
Khi luồng cần một pseudo-terminal
Một chuỗi hỏi mật khẩu rồi mã dùng một lần không có một tệp duy nhất để đọc. Một trình điều khiển terminal như Expect là công cụ đúng vì nó chờ từng mẫu theo lượt, và nó cần tiến trình đã được khởi chạy trước khi có thể khớp bất cứ thứ gì.
Hai thất bại chiếm ưu thế. Một script chờ lời nhắc mà không khởi chạy ứng dụng khách sẽ chờ mãi mãi, và Tcl không phải là shell, nên số học shell viết trong một khối expect không được đánh giá như khi đọc. Hãy để cờ gỡ lỗi bật trong khi dựng các mẫu, rồi tắt đi.
Những bí mật rò rỉ, và nơi chúng ẩn
Mọi thứ được truyền làm đối số đều hiện trong danh sách tiến trình, nên thông tin đăng nhập thuộc về một tệp hoặc nằm sau một trình trợ giúp, không bao giờ ở dòng lệnh. Mã dùng một lần bị tiêu hao theo thiết kế và phải được tạo cho từng lần thử. Nhật ký thất bại thường mang tên người dùng và đôi khi nhiều hơn, nên hãy che chúng trước khi gửi đi bất cứ đâu, và giữ bí mật ra ngoài chính hồ sơ, vì một tệp cấu hình có mật khẩu nhúng sẽ bị dán vào phiếu và kho mã. Khi đó xoay tài khoản nghĩa là truy lùng từng bản sao, và đó chính là chi phí mà cách bố trí này tránh được.
Hãy kiểm toán các con đường bạn đã chọn, rồi nối chúng vào tệp unit hoặc bộ lập lịch sẽ thực sự chạy ứng dụng khách. Đường hầm sống đúng bằng thời gian tiến trình đó sống.