Đăng nhập Cisco Secure Client từ shell Linux, không cần GUI
here-document không phải là giao thức đăng nhập. Ghi lại thứ tự lời nhắc thật, dùng expect khi nó thay đổi, và giữ mật khẩu ngoài argv cùng lịch sử.
Niềm tin là một here-document bốn dòng là đăng nhập không tương tác hoàn chỉnh, và nó đứng vững cho đến khi cổng cung cấp hai nhóm, in một băng-rôn, hoặc hỏi token sau mật khẩu. Khi đó cùng đoạn script ấy gõ mật khẩu vào một menu vốn chờ một con số. Ứng dụng dòng lệnh trên Linux có thể viết script, nhưng chỉ khi bạn đưa nó thứ nó thực sự chờ, chứ không phải thứ mà bài hướng dẫn giả định.
here-document cố định là một huyền thoại
Ứng dụng Linux của Cisco cài một chương trình nhỏ tại /opt/cisco/anyconnect/bin/vpn, và Secure Client 5 vẫn phát hành nó. Khi dịch vụ vpnagentd chạy, cờ -s đọc câu trả lời từ đầu vào chuẩn theo thứ tự mà ứng dụng yêu cầu. Thứ tự đó không cố định giữa các máy chủ.
Menu nhóm thêm một dòng. Băng-rôn đăng nhập thêm một dòng nữa. Yêu cầu token sau mật khẩu phá vỡ hoàn toàn một script bốn dòng, vì dòng thứ năm không bao giờ được dành cho token. Thất bại diễn ra âm thầm: ứng dụng nhận chuỗi sai, lần kết nối kết thúc, và script không báo gì hữu ích.
Chạy ứng dụng bằng tay một lần với cùng cổng và cùng phiên bản, rồi ghi lại các lời nhắc theo thứ tự xuất hiện. Bản ghi đó là đặc tả mà script của bạn phải đáp ứng.
Ứng dụng chờ gì
Trong trường hợp thông thường chỉ một nhóm, trình tự là tên người dùng, mật khẩu và đôi khi là xác nhận băng-rôn. Dòng đầu của here-document chỉ trở thành chỉ mục menu khi máy chủ thực sự hiển thị menu, đó là lý do cùng một script chạy được ở nơi này và thất bại ở nơi tiếp theo.
/opt/cisco/anyconnect/bin/vpn -s connect vpn.example.net <<EOF
0
alice
$VPN_PASSWORD
y
EOF
Hãy đọc đó như bốn câu trả lời cho bốn câu hỏi có thể xảy ra, không phải một giao thức cố định. Số không là một lựa chọn menu, không phải mật khẩu, và y ở cuối chấp nhận một băng-rôn mà nhiều cổng không bao giờ gửi.
Dùng expect khi thứ tự không đoán được
Khi thứ tự lời nhắc thay đổi, đừng đếm dòng nữa mà chờ lời nhắc. Một script expect khởi chạy lệnh connect, chờ lời nhắc tên người dùng, gửi, chờ lời nhắc mật khẩu, gửi, rồi chờ trạng thái đã kết nối. Mỗi lần chờ có thời gian chờ riêng.
Hãy coi hết thời gian chờ là thất bại và thoát. Một script tiếp tục gửi dữ liệu sau một lời nhắc bất ngờ sẽ vui vẻ gõ mật khẩu vào một shell, một menu hay bất cứ thứ gì đang đọc. Đó là cách một script đăng nhập trở thành sự cố.
Expect cũng cho bạn một bản ghi có thể lưu lại sau khi bỏ phần bí mật, và điều đó đáng giá hơn mã thoát khi một cổng thay đổi lời nhắc sau khi nâng cấp.
Bí mật phải sống ở đâu đó
Mọi phiên bản của vấn đề này đều có một điểm yếu: mật khẩu phải tồn tại ở dạng mà ứng dụng đọc được. Truyền nó như một đối số phơi bày nó trong bảng tiến trình. In nó qua đường ống thường đưa nó vào lịch sử shell. Cả hai đều đọc được bởi người dùng cục bộ khác trên một máy nhảy dùng chung.
install -m 600 /dev/null ~/.vpn-secret
umask 077; VPN_PASSWORD=$(cat ~/.vpn-secret) /opt/cisco/anyconnect/bin/vpn -s connect vpn.example.net
Một tệp có chế độ 600 thuộc sở hữu tài khoản là mức tối thiểu, và nó vẫn là bí mật dạng văn bản thuần trên đĩa. secret-tool lookup đọc từ khoá của Linux, và trên macOS cùng việc đó do security find-generic-password -w thực hiện. Ở nơi tổ chức hỗ trợ xác thực bằng chứng chỉ hoặc SAML, hãy ưu tiên cách đó, vì mật khẩu lưu sẵn cộng MFA vẫn không thể hoàn tất đăng nhập nếu không có con người.
Xác nhận đường hầm, rồi tự chịu trách nhiệm ngắt kết nối
Đừng tin vào việc không có văn bản lỗi. Hãy hỏi ứng dụng trạng thái của nó và kiểm tra giao diện một cách độc lập:
/opt/cisco/anyconnect/bin/vpn state
ip -brief address
Trạng thái phải đọc là Connected, và giao diện đường hầm phải có địa chỉ. Sau đó yêu cầu một tài nguyên mà đường hầm phải tới được, vì trạng thái đã kết nối mà không có tuyến là một kết quả thật và dễ bị bỏ sót.
Ngắt kết nối bằng vpn disconnect, và để script đã khởi chạy đường hầm tự chịu trách nhiệm ngắt. Một công việc thất bại để lại phiên mở sẽ tiêu tốn một chỗ giấy phép và trông như sự cố xác thực với người tiếp theo thử.
Thứ tự công việc: xác nhận vpnagentd, ghi lại thứ tự lời nhắc thật, chọn here-document hoặc expect, giữ bí mật ngoài argv và lịch sử, kiểm tra trạng thái và một tài nguyên, rồi ngắt kết nối trong cùng script đó.