Sử dụng keychain với OpenSSH

Chứng thực khóa công khai hoạt động như thế nào?

Giả sử rằng chúng ta có 1 client muốn kết nối đến 1 SSH server. Trước tiên client sẽ phát sinh 1 cặp khóa và gửi khóa công khai đến server. Sau đó, mỗi khi client cần kết nối, server sẽ gửi 1 gói tin (challenge) được mã hóa với khóa công khai. Chỉ người giữ khóa bí mật tương ứng (client) có thể giải mã nó, như vậy chúng ta cũng đoán được rằng việc trả lời chính xác sẽ dẫn đến việc chứng thực thành công.

Tuy nhiên như trong bài Cấu hình chứng thực khóa công khai với OpenSSH, mỗi khi kết nối SSH sử dụng cách chứng thực này, chúng ta sẽ được yêu cầu nhập passphrase cho khóa công khai này. Việc này gây ít nhiều bất tiện cho chúng ta, nhất là trong trường hợp ta cần làm việc với nhiều máy chủ qua SSH hoặc có những tác vụ tự động cần kết nối qua SSH.

Để những thông báo yêu cầu nhập passphrase không xuất hiện mỗi lần kết nối qua SSH, chúng ta thường tạo và sử dụng những cặp khóa không có passphrase (tức là không nhập passphrase trong quá trình tạo khóa). Việc làm này giúp chúng ta tránh được sự bất tiện khi phải nhập đi nhập lại passphrase mỗi lần kết nối, nhưng lại làm cho kết nối và hệ thống của chúng ta ít an toàn hơn. Do đó tôi không khuyến khích các bạn sử dụng phương pháp này. Vậy có cách nào giúp cho ta tránh được những bất tiện đã đề cập ở trên mà vẫn đảm bảo an toàn cho hệ thống?

keychain là gì?

Như đã đề cập ở trên, vấn đề đặt ra là chúng ta cần giải mã các khóa bí mật 1 lần và sử dụng chúng cho các kết nối tiếp theo để ta có thể truy cập ssh 1 cách tự do mà không cần nhập passphrase cho mỗi lần truy cập. ssh_agent sẽ giúp chúng ta thực hiện việc này.

Chương trình ssh-agent thường được bắt đầu vào đầu phiên làm việc của chúng ta trên giao diện đồ họa (Window X), hoặc từ kịch bản khởi động như ~/.bash_profile. Nó hoạt động bằng việc tạo ra 1 unix-socket, và đăng ký các biến môi trường tương ứng để tất cả các ứng dụng tiếp sau đó có thể tận dụng những dịch vụ của nó bằng việc kết nối đến socket này. Rõ ràng việc này chỉ có ý nghĩa khi chạy ssh-agent tại tiến trình cha của phiên làm việc nếu chúng ta muốn sử dụng tập các khỏa bí mật được mã hóa trong tất cả các ứng dụng tiếp theo.

ssh-agent sẽ giữ các khóa giải mã cho đến khi chúng ta đóng tiến trình ssh-agent. Nếu chúng ta muốn thiết lập vòng đời cho các khóa, sử dụng đối số -t  của ssh-agent.

keychain là 1 trình quản lý các ssh-agent được viết bằng Bash shell, thường được chạy từ ~/.bash_profile. Nó cho phép các shell và cron của chúng ta cùng chia sẻ 1 tiến trình ssh-agent. Mặc định thì ssh-agent được bắt đầu bằng keychain sẽ tiếp tục chạy thậm chí sau khi chúng ta đã đăng xuất ra khỏi hệ thống. Nếu chúng ta muốn thay đổi điều này, tham khảo qua tùy chọn –clear and –timeout được đề cập bên dưới.

Cài đặt keychain trên CentOS, RHEL, Fedora:

Chúng ta cần có repo RPMForge để có thể cài đặt keychain:

# yum install keychain

Cài đặt keychain trên Debian, Ubuntu:

apt-get update && apt-get install keychain

Cài đặt keychain trên FreeBSD:

# portsnap fetch update
# cd /usr/ports/security/keychain
# make install clean

Tạo các cặp khóa 

Thực hiện từng bước như trong hướng dẫn ở bài Cấu hình chứng thực khóa công khai với OpenSSH trên CentOS.

Sử dụng keychain

Cập nhật tập tin $HOME/.bash_profile như sau:

$ vi $HOME/.bash_profile
### START-Keychain ###
# Let re-use ssh-agent and/or gpg-agent between logins
/usr/bin/keychain $HOME/.ssh/id_dsa
source $HOME/.keychain/$HOSTNAME-sh
### End-Keychain ###

Như vậy là chúng ta đã cấu hình để gọi công cụ keychain mỗi lần đăng nhập. Thoát ra và đăng nhập lại hệ thống để kiểm tra xem các cấu hình của chúng ta đã hoạt động chưa:

$ ssh [email protected]
[email protected] 's password: <Nhập mật khẩu của tài khoản>
Last login: Mon Oct 20 17:26:34 2014 from test.local
* keychain 2.7.0 ~ http://www.funtoo.org
* Found existing ssh-agent: 21755
* Found existing gpg-agent: 21780
* Adding 1 ssh key(s): /root/.ssh/id_rsa
Enter passphrase for /root/.ssh/id_rsa: <Nhập passphrase cho khóa đã tạo>
* ssh-add: Identities added: /root/.ssh/id_rsa

Việc chúng ta cần làm tiếp theo là gửi khóa công khai ~/.ssh/id_rsa.pub (hoặc id_dsa.pub) đến các máy chủ mà chúng ta muốn kết nối ssh đến.

Từ bây giờ mỗi lần ta kết nối bằng ssh đến các server này, ta sẽ không bị yêu cầu nhập passphrase nữa.

Để xóa các khóa của ssh-agent, ta sử dụng tùy chọn –clean với keychain như sau:

# keychain --clear

Đảm bảo rằng kẻ xâm nhập không thể sử dụng các khóa của ssh-agent đang có.

Để thực hiện việc này, chúng ta chỉ nên cho phép các kịch bản sao lưu hoặc các cron là có thể đăng nhập không cần mật khẩu, còn với tất cả người dùng (bao gồm cả kẻ xâm nhập) bắt buộc phải cung cấp 1 khóa passphrase cho việc đăng nhập. Việc này được thực hiện bằng cách xóa tất cả khóa của ssh-agent. Việc này sẽ tăng sự bảo mật, đồng thời nó vẫn cho phép các cron của chúng ta sử dụng các khóa ssh khi chúng ta thoát khỏi hệ thống. Cập nhật tập tin ~/.bash_profile như sau:

/usr/bin/keychain --clear $HOME/.ssh/id_dsa
/usr/bin/keychain $HOME/.ssh/id_rsa
source $HOME/.keychain/$HOSTNAME-sh

nếu chúng ta sử dụng RSA, sử dụng:

/usr/bin/keychain --clear $HOME/.ssh/id_rsa
/usr/bin/keychain $HOME/.ssh/id_rsa
source $HOME/.keychain/$HOSTNAME-sh

 Từ bây giờ, mỗi khi ta đăng nhập bằng SSH, ta sẽ được yêu cầu nhập passphrase để giải mã cho khóa công khai của chúng ta, khóa được giải mã này sẽ được lưu giữ cho đến khi ta thoát ra khỏi hệ thống.

Sử dụng keychain cho các kịch bản sao lưu tự động

Với các kịch bản sao lưu tự động cần sử dụng SSH, để sử dụng keychain, thêm dòng sau vào đầu kịch bản:

source $HOME/.keychain/$HOSTNAME-sh

Ví dụ:

Giả sử chúng ta có kịch bản rsync tự động như bên dưới:

#!/bin/bash
# Remote Server Rsync backup Replication Shell Script
# Local dir location
LOCALBAKPOINT=/iscsi
LOCALBAKDIR=/backups/server1.nixcraft.net.in/wwwroot
# Remote ssh server setup
SSHUER=root
SSHSERVER=server1.nixcraft.net.in
SSHBACKUPROOT=/wwwroot 

# Make sure you can log in to remote server without a password
source $HOME/.keychain/$HOSTNAME-sh
 
# Make sure local backup dir exists
[ ! -d ${LOCALBAKPOINT}${LOCALBAKDIR} ] && mkdir -p ${LOCALBAKPOINT}${LOCALBAKDIR}
 
# Start backup
/usr/bin/rsync --exclude '*access.log*' --exclude '*error.log*' -avz -e 'ssh ' ${SSHUER}@${SSHSERVER}:${SSHBACKUPROOT} ${LOCALBAKPOINT}${LOCALBAKDIR}
 
# See if backup failed or not to /var/log/messages file
[ $? -eq 0 ] && logger 'RSYNC BACKUP : Done' || logger 'RSYNC BACKUP : FAILED!'

Nếu chúng ta sử dụng máy chủ sao lưu rsnapshot, thêm dòng sau vào tập tin /etc/rsnapshot.conf

# Get ssh login info via keychain
cmd_preexec    source /root/.keychain/hostname.example.com-sh

Lưu ý:

  • Những kẻ tấn công với những kỹ thuật tấn công trình độ cao vẫn có thể lấy được khóa của bạn từ bộ nhớ. Tuy nhiên, keychain làm cho việc này khó khăn hơn với người dùng và những kẻ tấn công bình thường để có thể lấy trộm được khóa của bạn và sử dụng nó.
  • Máy chủ OpenSSH (sshd) cung cấp 2 tùy chọn bổ sung để bảo vệ việc lạm dụng khóa. Đầu tiên, đảm bảo rằng việc đăng nhập bằng tài khoản root bị vô hiệu hóa (PermitRootLogin no). Thứ 2, chỉ rõ những tài khoản người dùng nào trên máy chủ được phép sử dụng cho chứng thực bằng việc thêm AuthorizedKeysFile %h/.ssh/authorized_keys_FileName

Kết luận:

Từ những điều đã tìm hiểu được ở trên, chúng ta cùng tóm tắt lại những ý chính về keychain như sau:

  • Việc sử dụng chứng thực khóa công khai với SSH thay cho mật khẩu tĩnh mang lại hiệu quả về mặt bảo mật, an toàn hệ thống.
  • Với các khóa công khai không được mã hóa bằng passphrase, khi đăng nhập sẽ không bị hỏi passphrase, tiện lợi trong việc sử dụng (nhất là với các kịch bản hay các cron chạy tự động cần sử dụng SSH) nhưng không an toàn, nhất là trong trường hợp bị mất khóa => không khuyến khích sử dụng.
  • Với các khóa công khai được mã hóa bằng passphrase, mỗi lần kết nối sẽ được yêu cầu nhập passphrase, an toàn nhưng lại bất tiện cho việc sử dụng.
  • ssh-agent mã hóa khóa công khai bằng passphrase được cung cấp và lưu giữ khóa đã mã hóa này trong suốt vòng đời tiến trình của nó. Các ứng dụng sau đó sử dụng SSH chỉ cần kết nối đến socket do ssh-agent tạo, không cần phải nhập passphrase.
  • keychain là 1 trình quản lý các ssh-agent, giúp cho việc sử dụng các ssh-agent dễ dàng và tiện lợi hơn.

Chúng ta kết thúc bài tìm hiểu về cách sử dụng keychain với OpenSSH tại đây. Chúc các bạn thành công!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.