使用運維編排服務配置多臺實例的免密登陸
運維編排是阿里雲提供的雲上自動化運維服務,能夠自動化管理和執行任務。您可以通過模板來定義執行任務、執行順序、執行輸入和輸出,然後通過執行模板來完成任務的自動化運行。
SSH免密登陸大多用於自動化運維,主要是安全方便自動化管理大批服務器。如果您有大量的實例,期望可以將部分或全部的實例配置成免密登陸。那麼怎麼才能快速的配置實例的免密登陸呢?下面為您介紹通過運維編排服務來快速配置大量實例的免密登陸。
前提條件
- 準備ECS實例。如果您還未有實例,請參考入門概念購買ECS實例
- 需要配置免密登陸的實例必須擁有相同的用戶名。
- 本示例僅支持Linux類型實例。
操作步驟
- 登錄運維編排控制檯。
- 給實例增加新User,如果您的實例內已經有需要做免密配置的用戶,請直接跳到下一步。如果實例內還未有相同的User,您可以使用運維編排的批量操作實例功能,執行相應的增加User腳本。如下所示:
- 創建模版。
本示例為您提供了一個自動化配置實例免密登錄的模板,模版內容請參考附錄一,將模版內容複製進入輸入框後,單擊創建模版。(本模板的主要功能為,選擇並獲取部分實例的公鑰,然後再選擇需要配置免密登錄的實例,將上一步的公鑰配置進指定User下。)
- 執行模板。
找到上一步已經創建完成的模板,單擊創建執行 >> 下一步:設置參數。
- 輸入參數。選擇實例時可以直接選擇實例,或者根據實例上的標籤選擇實例。如下所示:
- 單擊下一步:確定 >> 創建,確認輸入的參數沒有問題後,就可以執行模版了。
- 等待模版執行成功後,驗證免密配置是否生效。
進入其中一個已經配置了免密登錄的實例。在某一user下,執行ssh 命令。我們就可以不輸入密碼直接進入另一臺實例了。如下所示的例子:進入一個為freelogin的user下,執行ssh ip地址,即進入了另外一臺實例內。此時可以發現免密配置已經生效了。
附錄一:配置免密登陸模版
模板參數介紹
參數名稱 | 說明 |
---|---|
regionId | 地域ID。 |
sourceTarget | 做免密登陸配置時,需要獲取免密公鑰的實例。 |
destinationTarget | 需要開通免密登陸的實例。 |
userName | 實例內的用戶名。 |
rateControl | 任務執行的併發比率。 |
OOSAssumeRole | OOS扮演的RAM角色。 |
模板內容
FormatVersion: OOS-2019-06-01
Description:
en: 'In the instance, a user is linked without encryption by means of an authorization key.'
zh-cn: 在實例內,某一用戶通過授權密鑰的方式免密鏈接。
Parameters:
regionId:
Type: String
Description:
en: The id of region.
zh-cn: 地域ID。
AssociationProperty: RegionId
Default: '{{ ACS::RegionId }}'
sourceTarget:
Type: Json
Description:
en: Example of obtaining the secret-free public key when configuring the secret-free login.
zh-cn: 做免密登陸配置時,獲取免密公鑰的實例。
AssociationProperty: Targets
AssociationPropertyMetadata:
ResourceType: 'ALIYUN::ECS::Instance'
RegionId: regionId
destinationTarget:
Type: Json
Description:
en: Need to open an instance of password-free login.
zh-cn: 需要開通免密登陸的實例。
AssociationProperty: Targets
AssociationPropertyMetadata:
ResourceType: 'ALIYUN::ECS::Instance'
RegionId: regionId
Default:
Type: ResourceIds
ResourceIds: []
userName:
Description:
en: Password-free login username in the instance.
zh-cn: 實例內的免密登陸的用戶名稱。
Type: String
rateControl:
Description:
en: Concurrency ratio of task execution.
zh-cn: 任務執行的併發比率。
Type: Json
AssociationProperty: RateControl
Default:
Mode: Concurrency
MaxErrors: 0
Concurrency: 10
OOSAssumeRole:
Description:
en: The RAM role to be assumed by OOS.
zh-cn: OOS扮演的RAM角色。
Type: String
Default: OOSServiceRole
RamRole: '{{ OOSAssumeRole }}'
Tasks:
- Name: getSourceInstance
Description:
en: Get an instance that needs to be logged in without password.
zh-cn: 獲取需要被免密登陸的實例。
Action: 'ACS::SelectTargets'
Properties:
ResourceType: 'ALIYUN::ECS::Instance'
RegionId: '{{ regionId }}'
Filters:
- '{{ sourceTarget }}'
Outputs:
instanceIds:
Type: List
ValueSelector: 'Instances.Instance[].InstanceId'
- Name: getDestinationInstance
Description:
en: Views the ECS instances than to ssh without password.
zh-cn: 獲取配置免密登陸的實例。
Action: 'ACS::SelectTargets'
Properties:
ResourceType: 'ALIYUN::ECS::Instance'
RegionId: '{{ regionId }}'
Filters:
- '{{ destinationTarget }}'
Outputs:
instanceIds:
Type: List
ValueSelector: 'Instances.Instance[].InstanceId'
- Name: generateOrGetPublicKey
Action: 'ACS::ECS::RunCommand'
Description:
en: Generate or get a public key.
zh-cn: 生成或獲取公共密鑰。
Properties:
regionId: '{{ regionId }}'
commandContent: |-
#!/bin/bash
username="{{ username }}"
if [ $username == root ]; then
if [ ! -e "/root/.ssh/id_rsa.pub" ]; then
ssh-keygen -f "/root/.ssh/id_rsa" -P "" >> /dev/null
fi
cat /root/.ssh/id_rsa.pub
else
if [ ! -e "/home/$username/.ssh/id_rsa.pub" ]; then
su $username -l -c "ssh-keygen -f /home/$username/.ssh/id_rsa -P '' >> /dev/null"
fi
chmod 700 /home/$username/.ssh
cat /home/$username/.ssh/id_rsa.pub
fi
instanceId: '{{ ACS::TaskLoopItem }}'
commandType: RunShellScript
Loop:
RateControl: '{{ rateControl }}'
Items: '{{ getSourceInstance.instanceIds }}'
Outputs:
publicKeys:
AggregateType: 'Fn::ListJoin'
AggregateField: publicKey
Outputs:
publicKey:
Type: String
ValueSelector: invocationOutput
- Name: converPublicKeyToStr
Action: 'ACS::ECS::SMCConversionConstantByJqScript'
Description:
en: Convert public key to string.
zh-cn: 將公鑰轉換成字符串。
Properties:
parameter:
'Fn::Jq':
- First
- 'join(",")'
- '{{ generateOrGetPublicKey.publicKeys }}'
jqScript:
- '.[0] | .'
- '.[0] | .'
Outputs:
publicKey:
Type: String
ValueSelector: 'firstValue | split(",") | join("\n")'
- Name: authorizedInstances
Action: 'ACS::ECS::RunCommand'
Description:
en: Enable password-free login for users in the instance.
zh-cn: 開通實例內用戶的免密登陸。
Properties:
regionId: '{{ regionId }}'
commandContent: |-
#!/bin/bash
username="{{ username }}"
publicKey="{{ converPublicKeyToStr.publicKey }}"
if [ $username == root ]; then
if [ ! -e "/root/.ssh/id_rsa.pub" ]; then
ssh-keygen -f "/root/.ssh/id_rsa" -P "" >> /dev/null
fi
cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
else
if [ ! -e "/home/$username/.ssh/id_rsa.pub" ]; then
su $username -l -c "ssh-keygen -f /home/$username/.ssh/id_rsa -P '' >> /dev/null"
fi
chmod 700 /home/$username/.ssh
cat /home/$username/.ssh/id_rsa.pub >> /home/$username/.ssh/authorized_keys
fi
if [ $username == root ]; then
cat >> /root/.ssh/authorized_keys << eof
$publicKey
eof
else
cat >> /home/$username/.ssh/authorized_keys << eof
$publicKey
eof
fi
instanceId: '{{ ACS::TaskLoopItem }}'
commandType: RunShellScript
Loop:
RateControl: '{{ rateControl }}'
Items: '{{ getDestinationInstance.instanceIds }}'
Outputs:
commandOutputs:
AggregateType: 'Fn::ListJoin'
AggregateField: commandOutput
Outputs:
commandOutput:
Type: String
ValueSelector: invocationOutput
Outputs:
commandOutputs:
Type: List
Value: '{{ generateOrGetPublicKey.publicKeys }}'