Ứng dụng vpn đi kèm Cisco AnyConnect cư xử như một cuộc hội thoại: nó in một lời nhắc, chờ một dòng, rồi in lời nhắc kế tiếp. Nếu bạn nạp cuộc hội thoại đó từ một tệp hoặc một ống dẫn, chính tệp nhị phân ấy chạy mà không cần người trông. Kỹ thuật là một lần chuyển hướng cộng với một danh sách câu trả lời có thứ tự, và chính danh sách, không phải việc chuyển hướng, quyết định script có đáng tin hay không.

Trong thực tế có hai thứ làm hỏng việc này. Thứ tự lời nhắc thay đổi khi cổng hỏi thêm điều gì đó, và một mật khẩu được lưu biến một lỗi gõ thành một lần khóa tài khoản. Hãy xem trình tự như dữ liệu có phiên bản mà bạn có thể so sánh sau mỗi thay đổi của cổng. Hãy thất bại thật ồn ào thay vì thử lại, vì vòng lặp chính là cách một mật khẩu gõ sai trở thành tài khoản bị khóa.

Một trình tự, theo đúng thứ tự mà ứng dụng hỏi

Chạy ứng dụng ở chế độ tương tác một lần và ghi lại từng lời nhắc theo thứ tự xuất hiện. Bản ghi đó trở thành tệp câu trả lời. Khi bạn chuyển hướng tệp vào tệp nhị phân, dòng đầu tiên phải là chính lệnh kết nối, vì thế trình tự bắt đầu bằng tên máy chủ chứ không phải tên người dùng.

connect vpn.example.com
0
<username>
<password>
y
exit

0 trần chọn hồ sơ kết nối đầu tiên khi cổng đưa ra một danh sách; hãy dùng chỉ số mà cổng của bạn in ra. y chấp nhận một biểu ngữ đăng nhập, nên hãy xóa dòng đó nếu không có biểu ngữ và chèn một dòng ở nơi cổng của bạn hỏi thêm. exit ở cuối là thứ cho phép ứng dụng kết thúc gọn gàng khi câu trả lời cuối cùng đã được dùng hết.

/opt/cisco/anyconnect/bin/vpn -s < anyconnect.txt

Chế độ không tương tác ở đây không phải là tùy chọn. Không có -s, ứng dụng có thể chiếm lấy terminal và bỏ qua dữ liệu nhập đã chuyển hướng; với nó, các câu trả lời được đọc từ luồng và tiến trình trả về. Nơi tệp nhị phân cần quyền cao hơn, hãy bọc lời gọi trong sudo -n để script thất bại ngay thay vì bị treo ở lời nhắc mật khẩu.

Nơi tệp câu trả lời bị lộ

Một tệp chứa mật khẩu là một thông tin xác thực, nên hãy cấp cho nó quyền của một thông tin xác thực: chế độ 600, thuộc tài khoản chạy công việc, và không bao giờ nằm trong thư mục chia sẻ hay được đồng bộ. Hãy tạo nó với chế độ đã áp dụng sẵn thay vì sửa sau, vì tệp có một khoảnh khắc ai cũng đọc được giữa lúc ghi và lúc chmod.

install -m 600 /dev/null ~/.config/anyconnect.txt
chmod 700 ~/.config

Nửa còn lại là argv. Một mật khẩu được truyền như đối số thì mọi người dùng cục bộ liệt kê tiến trình đều thấy, và nó cũng rơi vào lịch sử của shell. Hãy đọc nó từ bộ mô tả tệp hoặc biến môi trường thay vào đó, và đặt phần dữ liệu trong dấu nháy để shell không thể mở rộng bất cứ thứ gì bên trong.

printf '%s\n' 'connect vpn.example.com' '0' "$VPN_USER" "$VPN_PASS" 'y' 'exit' \
  | sudo -n /opt/cisco/anyconnect/bin/vpn -s

Hãy để ý dấu nháy. Bên trong dấu nháy kép, một mật khẩu chứa ! có thể bị một shell tương tác mở rộng trước cả khi ứng dụng nhìn thấy nó, và lỗi đến dưới dạng một lỗi event-not-found chung trông như vấn đề giao thức.

Chứng minh đường hầm, rồi đóng nó

Trạng thái đã kết nối chỉ chứng minh rằng ứng dụng tin là nó có phiên. Hãy chọn một máy chủ chỉ trả lời từ bên trong mạng doanh nghiệp và thử nó một lần trước khi làm bất cứ việc gì khác. Thất bại ở đó là lỗi định tuyến hoặc chính sách, và chạy lại việc đăng nhập sẽ không thay đổi điều đó.

/opt/cisco/anyconnect/bin/vpn state
curl -sS -o /dev/null -w '%{http_code}\n' --max-time 10 https://<internal-host>/
/opt/cisco/anyconnect/bin/vpn disconnect

Hãy kiểm tra đầu ra trạng thái trước và sau khi ngắt kết nối. Một ứng dụng bị bỏ lại với phiên cũ có thể từ chối lần kết nối tiếp theo trong khi script vẫn báo thành công, và kiểu thất bại đó không nhìn thấy được nếu bạn chỉ xem mã thoát. Hãy so sánh hai lần đọc thay vì tin riêng lần thứ hai. Các bí danh trong hồ sơ shell đủ cho dùng hằng ngày, còn mọi thứ được lên lịch đều đáng được xem xét thông tin xác thực và danh tính như mọi công việc không người trông khác.

Khi một danh sách cố định không còn an toàn

Một tệp câu trả lời mã hóa thứ tự lời nhắc của hôm nay. Một biểu ngữ thay đổi, một lần đổi mật khẩu bắt buộc hoặc một thách thức yếu tố thứ hai biến nó thành một vòng lặp có thể khóa tài khoản, vì thế script phải thoát ngay ở câu trả lời bất ngờ đầu tiên thay vì khởi động lại.

Hãy ghi lại những gì ứng dụng đã in, trả về trạng thái khác không và để người gọi quyết định. Nơi cổng đòi hỏi yếu tố thứ hai, câu trả lời trung thực là đăng nhập không người trông không khả dụng cho hồ sơ đó, chứ không phải trình tự cần thêm một dòng.

Việc luân chuyển thuộc cùng một lần xem xét. Nếu thông tin xác thực được lưu, hãy quyết định ai có thể đọc nó, khi nào nó thay đổi và cái gì xóa nó khi máy chủ được dựng lại. Một script chạy được một năm vì không ai chạm vào mật khẩu không phải là thiết kế, mà là một tai nạn đang chờ một chính sách luân chuyển.

Những hồ sơ không phải AnyConnect

Hai kiểu thông tin xác thực Cisco cũ hơn thường bị nhầm với kiểu này. Hồ sơ vpnc hỏi một IPSec ID, mà thực ra là tên nhóm, rồi một bí mật nhóm, rồi thông tin xác thực của chính bạn, và cả ba đều đến từ người vận hành cổng. Cisco IPsec cũ là một giao thức khác với AnyConnect, nên vpnc không thể chạm tới một dịch vụ chỉ dành cho AnyConnect; openconnect --protocol=anyconnect là ứng dụng mở cho công việc đó.

Một tệp .pcf mô tả hồ sơ ứng dụng cũ. Máy chủ, tên nhóm và mật khẩu nhóm bên trong có thể được nhập lại bằng tay trong một ứng dụng nói Cisco IPsec, dù tệp không phải là bản nhập phổ quát và mọi cổng hay chế độ đường hầm không mặc định thường biến mất khi chuyển.

Hãy bắt đầu từ những gì cổng thực sự cung cấp, rồi chọn ứng dụng nói giao thức đó. Sao chép một hồ sơ từ trang khác chính là cách người ta rốt cuộc phải gỡ lỗi những thông tin xác thực chưa bao giờ là vấn đề.

Bài viết liên quan