控制managed node的方式主要都是藉由ssh或者paramiko進去並確認是否有python可以進行一系列的操作
註:相關連線設定可參考 Ansible Configuration Settings — Ansible Documentation
ansible登入方式主要有以下幾種
- 利用ssh金鑰技術免輸入password
- 每次登入時輸入密碼
- 將managed node password寫入Inventory (較不建議有安全疑慮,建議使用方法2.並利用
ansible-vault
進行加密)
註:Controller machine記得要安裝sshpass才可以正常運作
方法一
將ssh金鑰技術免輸入password,假設managed node IP : 192.168.0.132 username: test
產生Controller machine ssh key pair
ssh-keygen
添加managed node的ssh認證信息
ssh-copy-id username@ip
如:
ssh-copy-id test@192.168.0.132
檢查managed node的 ~/.ssh/authorized_keys 可以發現與剛剛在Controller machine產生的金鑰對public key相同
使用ansible ping module進行簡單測試
註:
- ansible ping並非一般網路的ICMP而是去檢查managed node的python
- 檢查Inventory檔案底下的格式資料可以使用
ansible-inventory -i inventory --list
- 如果private key檔案不是預設可以參數 [ --private-key ] 指令金鑰檔,指令範例如下
ansible -i hosts host01 -m ping --private-key ~/.ssh/id_rsa
方法二
每次登入managed node輸入對點設備的ssh password,使用參數 [-k] or [ --ask-pass ] 如下圖
但需要注意如果是還沒使用ssh登入過的managed node,因為ansible預設會先去檢查~/.ssh/know_hosts有沒有相關資料應此會失敗
解決上述問題的方法有兩種
- 手動先ssh到managed node讓~/.ssh/know_hosts 加入該台設備資料
- 新增ansible.cfg加入 host_key_checking = false 省略檢查 ~/.ssh/know_hosts
方法三
在Inventory內加入ansible_password: [password] ,但該作法會有嚴重的安全問題,因此應該要利用ansible-vault進行加密保護ssh password
使用ansible-vault進行加密保護ssh password主要有兩種方法
- 使用一個檔案裡面存儲ansible-vault的密碼,方法如下
產生一個檔案這邊示範使用檔名my-ansible-vault-pw-file,示範用ansible-vault的密碼為"my-ansible-vault-pw”,實際使用時請自行更改
使用指令 ansible-vault encrypt_string --vault-id test@~/my-ansible-vault-pw-file 'ssh password' --name 'ansible_password’
產生加密後的ansible password 將圖片紅框內整段複製到Inventory內
註: test@~/my-ansible-vault-pw-file 是檔案位置,ssh password請自行更改為managed node的ssh password
實際使用指令為 ansible -i hosts host03 --vault-id test@~/my-ansible-vault-pw-file -m ping
- 記憶ansible-vault的密碼每次使用時輸入該組ansible-vault密碼,方法如下
使用指令 ansible-vault encrypt_string --vault-id test@prompt 'SSH_password' --name 'ansible_password’
產生加密後的ansible password 將圖片紅框內整段複製到Inventory內
註:SSH_password
請自行更改為managed node的ssh password
實際使用指令 ansible -i hosts host04 --vault-id test@prompt -m ping
參考資料:Build Your Inventory — Ansible Documentation
實戰
在商業環境中基於安全考量通常不允許利用localhost直接連線操控managed node,通常情形是先透過Bastion host或者Jump host進行連線,接著才通過跳板連線到正式的Production Server (managed node)。這時候有兩種SSH技術可以使用 1. ssh agent forwarding (有資安風險) 2. ssh proxy command。
(圖片來源:AWS Security Blog)
參考連結:
How to Record SSH Sessions Established Through a Bastion Host | AWS Security Blog (amazon.com)
SSH Agent Forwarding
測試環境Localhost (192.168.0.14) 下WSL (172.28.78.158) → Jump host (192.168.0.132) → Target Server (192.168.0.131)
前置必須先取得Target Server登入用的Key,我這邊是先在WSL產生Key pair後在Target Server產生 ~/.ssh/authorizated_keys 並將公鑰資訊輸入在裡面並更改檔案權限
sudo chmod 600 ~/.ssh/authorized_keys
sudo chmod -R go= ~/.ssh
sudo chown -R blacktea:blacktea ~/.ssh
# blacktea:blackte 使用者:群組
實際使用時須先確認ssh-agent是否已經啟用,如使用 echo $SSH_AGENT_PID
如果以啟用應該可以看到 Agent pid XXXX 等資訊,若顯示空白則可以利用 eval $(ssh-agent)
啟用 ,若想要每次自動啟用可以參考 連結。
接著首先必須先使用ssh-add 將連結到Target Server的Private key加入倒ssh-agent中,加入會可以利用ssh-add -L檢查
後續實際連線只需要先利用ssh -A 後再從Jump host ssh 即可使用Localhost上的Key pair直接登入成功
另一種方法則是設定好know_hosts後使用
弱點利用
利用SSH Agent Forwarding登入Target Server做示範
使用 SSH Agent Forwarding 的安全隱憂,起因於 ssh agent service 於連線時會在Jump host /tmp/
目錄下建立一個暫存檔案 /tmp/ssh-xxxxxx/agent.xx
。在通常情況下,它會用使用者透過 ssh-add 所設定的key pair,替我們回答Target Server 所發起的認證要求。因此攻擊者如果取得讀取這個檔案的權限,並將這個檔案的路徑設定在自己的環境變數 SSH_AUTH_SOCK
裡,就可以在不知道認證所需資訊下,利用這個機制來繞過認證要求。
範例繞過認證手法如下
參考連結:
An Illustrated Guide to SSH Agent Forwarding (unixwiz.net)
SSH Agent Forwarding considered harmful | Hacker News (ycombinator.com)
SSH ProxyCommand
測試環境Localhost (192.168.0.14) 下WSL (172.28.78.158) → Jump host (192.168.0.132) → Target Server (192.168.0.131)
示範如下
使用ansible利用SSH ProxyCommand進行連線
參考連結:
SSH to remote hosts through a proxy or bastion with ProxyJump | Enable Sysadmin (redhat.com)
SSH Agent Explained (smallstep.com)
SSH ProxyCommand example: Going through one host to reach another server - nixCraft (cyberciti.biz)
SSH Essentials: Working with SSH Servers, Clients, and Keys | DigitalOcean
Running Ansible through SSH Jump / Bastion Host – techbeatly