全部产品
Search
文档中心

使用运维编排服务配置多台实例的免密登录

更新时间: 2020-12-11

运维编排是阿里云提供的云上自动化运维服务,能够自动化管理和执行任务。您可以通过模板来定义执行任务、执行顺序、执行输入和输出,然后通过执行模板来完成任务的自动化运行。

SSH免密登录大多用于自动化运维,主要是安全方便自动化管理大批服务器。如果您有大量的实例,期望可以将部分或全部的实例配置成免密登录。那么怎么才能快速的配置实例的免密登录呢?下面为您介绍通过运维编排服务来快速配置大量实例的免密登录。

注意

  1. 先准备好ECS实例。如果您还未有实例,请参考入门概念购买ECS实例

  2. 需要配置免密登录的实例必须拥有相同的用户名。

  3. 本示例仅支持Linux类型实例。

操作步骤

  1. 登录运维编排控制台

  2. 给实例增加新User,如果您的实例内已经有需要做免密配置的用户,请直接跳到下一步。如果实例内还未有相同的User,您可以使用运维编排的批量操作实例功能,执行相应的增加User脚本。如下所示:freelogin-01

  1. 创建模板。

本示例为您提供了一个自动化配置实例免密登录的模板,模板内容请参考附录一:配置免密登录模板

将模板内容复制进入输入框后,单击创建模板。(本模板的主要功能为,选择并获取部分实例的公钥,然后再选择需要配置免密登录的实例,将上一步的公钥配置进指定User下。)freelogin-02

  1. 执行模板。

找到上一步已经创建完成的模板,单击创建执行 >> 下一步:设置参数freelogin-03

  1. 输入参数。选择实例时可以直接选择实例,或者根据实例上的标签选择实例。如下所示:freelogin-05

  1. 单击下一步:确定 >> 创建,确认输入的参数没有问题后,就可以执行模板了。freelogin-06

  1. 等待模板执行成功后,验证免密配置是否生效。

进入其中一个已经配置了免密登录的实例。在某一user下,执行ssh 命令。我们就可以不输入密码直接进入另一台实例了。如下所示的例子:进入一个为freelogin的user下,执行ssh ip地址,即进入了另外一台实例内。此时可以发现免密配置已经生效了。freelogin-07

附录一:配置免密登录模板

模板参数介绍

参数名称

说明

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 }}'