使用Ansible来以幂等性方式更改EC2(Amazon Linux 2)的SSH端口号

首先

我已经整理了在ansible中确保幂等性的情况下将EC2的SSH端口号从22更改为50001的步骤。

环境

    • ローカル環境

M1 Mac
MacOS Monterey 12.6

サーバ

Amazon Linux2

使用ansible进行安装

在本地安装ansible。
虽然也可以使用Homebrew进行安装,但由于pip可以进行详细的版本指定,因此我们选择了使用pip进行安装。

最新バージョンをインストール場合
$ pip install ansible

バージョン指定
$ pip install ansible==6.5.0

为了确认安装成功,我们需要检查软件的版本。

$ pip list
Package      Version
------------ -------
ansible      6.5.0
ansible-core 2.13.6

启动EC2

我們將啟動一個 EC2 實例,但啟動方式已簡略描述。
安全群組將允許入站規則包括 SSH 22 端口和自訂端口號 50001。
此外,將啟用公有 IP 的自動分配。

スクリーンショット 2022-11-22 23.24.42.png

创建ansible项目

创建一个名为playbook的目录,并在其中创建一个hosts文件、一个playbook.yml文件和一个sshd的roles目录。

$ mkdir playbook
$ cd playbook
$ touch hosts playbook.yml
$ ansible-galaxy init --init-path="roles" sshd

$ tree     
.
├── hosts
├── playbook.yml
└── roles
    └── sshd
        ├── README.md
        ├── defaults
        │   └── main.yml
        ├── files
        ├── handlers
        │   └── main.yml
        ├── meta
        │   └── main.yml
        ├── tasks
        │   └── main.yml
        ├── templates
        ├── tests
        │   ├── inventory
        │   └── test.yml
        └── vars
            └── main.yml

删除未使用的目录,并按照以下方式进行调整。

$ tree
.
├── hosts
├── playbook.yml
└── roles
    └── sshd
        ├── handlers
        │   └── main.yml
        └── tasks
            └── main.yml

4 directories, 4 files

创建hosts文件

请按照以下方式描述:
通常情况下,最好在roles的vars文件夹下的main.yml中写入custom_ssh_port=50001等内容,但由于这样很麻烦,所以我将其整合到hosts文件中。
请在该IP字段中填写服务器的公共IP。

[web] # 記載されたIPに対して接続
11.11.11.11

[web:vars] #[web]で使う変数を定義
ansible_ssh_port=22
ansible_user=ec2-user
__working_user=ec2-user
ansible_python_interpreter=/usr/bin/python2

# custom ssh port (49152~65535)
custom_ssh_port=50001

# pem key path
ansible_ssh_private_key_file=~/.ssh/test.pem

创建playbook.yml

- name: Change port
  hosts: web
  become: yes
  gather_facts: false
  roles:
    - sshd

为了在下一个模块中使用`local_action`,需要将`gather_facts`设置为`false`。

    • gather_facts

対象ホストの情報をansible_facts変数というものに格納し、tasks内の変数で使用することができます。

创建roles文件夹下的sshd目录。

只需在tasks和handlers的main.yml中进行记录。不使用其他内容。

# port22 でSSH接続する。タイムアウトは5秒で、接続失敗しても次に進む
- name: Connect default ssh port
  local_action: wait_for port={{ansible_ssh_port}} timeout=5 host={{inventory_hostname}}
  register: default_port
  ignore_errors: true
  become: False

# port22 で失敗した場合、port 50001でSSH接続する。タイムアウトは5秒
- name: Connect custom ssh port
  local_action: wait_for port={{custom_ssh_port}} timeout=5 host={{inventory_hostname}}
  register: custom_port
  when: default_port.elapsed >= 5
  become: False

# port22 でタイムアウトし、port50001でSSH接続成功した場合、ansible_ssh_portを50001に変える
- name: set ansible_ssh_port custom_ssh_port
  set_fact: ansible_ssh_port={{custom_ssh_port}}
  when: default_port.elapsed >= 5 and custom_port.elapsed < 5
  become: False

# 現在port22でSSH接続している場合、/etc/ssh/sshd_configのPortを50001に書き換える
- name: Rewrite custom_ssh_port
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^#Port'
    line: 'Port {{custom_ssh_port}}'
  notify: Restart sshd
  when: ansible_ssh_port == 22

# ssh接続時のパスワード認証を無効
- name: Disabling password authentication
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^PasswordAuthentication'
    insertafter: '^#PasswordAuthentication'
    line: PasswordAuthentication no
  notify: Restart sshd
# ssh接続時のチャレンジ/レスポンス認証を無効
- name: Disabling Challenge-Response Authentication
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^ChallengeResponseAuthentication'
    insertafter: '^#ChallengeResponseAuthentication'
    line: ChallengeResponseAuthentication no
  notify: Restart sshd

# rootユーザーのログイン無効
- name: Disabling root user login
  lineinfile:
    dest: /etc/ssh/sshd_config
    regexp: '^PermitRootLogin'
    insertafter: '^#PermitRootLogin'
    line: PermitRootLogin no
  notify: Restart sshd
# sshdの設定が変更された場合、再起動する
- name: Restart sshd
  service:
    name: sshd
    state: restarted

模块说明

    • local_action

リモートホストではなくローカルで実行したい場合に使用します。今回であれば、ローカルからSSH接続できます。

wait_for

SSH接続のアクション時、ポートが応答あるまで待つために使用します

timeoutやhost先を指定できます。

register

処理結果を変数の中に一時的に保管できます
elapsed

経過時間を示します

become

そのモジュールを root 権限で実行できます

set_fact

新たな変数を定義できます。

今回は、ansible_ssh_portの値が元々22だったのをcustom_ssh_port(50001)に上書きしました

lineinfile

ファイルを行単位で編集できます
dest

編集するファイルのパスを指定

line

置換または挿入する文字列を指定

regexp

指定した正規表現にマッチした行を、lineで指定した文字列に置き換えます
lineで指定した文字列と、同じ場合は何もしません

insertafter

regexp にマッチする行が無かった場合、ここに指定した正規表現にマッチした次の行に、lineで指定した文字列を挿入する。

それにもマッチしない場合はファイル末尾に、lineで指定した文字列が挿入されます。

notify

notifyを付与したタスクがchangedになった場合、handlers内に定義されたタスクが実行されます。

同じhandlersの呼び出しは1回にまとめらます。notifyを付与している複数のタスクがchangedになっても1度しか実行されません。

执行安琪儿。

在根目录下,您可以使用以下命令来执行ansible。

$ ansible-playbook -i hosts playbook.yml

如果您想要输出详细日志,请添加 -vv。

$ ansible-playbook -i hosts playbook.yml -vv

我们将执行第一次。

$ ansible-playbook -i hosts playbook.yml -vv

PLAY [Change port] ************************************************************************************************************

TASK [sshd : Connect default ssh port] ****************************************************************************************
ok: [13.231.201.67 -> localhost]

TASK [sshd : Connect custom ssh port] *****************************************************************************************
skipping: [13.231.201.67]

TASK [sshd : set ansible_ssh_port custom_ssh_port] ****************************************************************************
skipping: [13.231.201.67]

TASK [sshd : Rewrite custom_ssh_port] *****************************************************************************************
The authenticity of host '13.231.201.67 (13.231.201.67)' can't be established.
ED25519 key fingerprint is SHA256:SgTQf176TUJ/wSqlWH4inIAZ7NWU+eAQrewxa+aqEns.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
changed: [13.231.201.67]

TASK [sshd : Disabling password authentication] *******************************************************************************
ok: [13.231.201.67]

TASK [sshd : Disabling Challenge-Response Authentication] *********************************************************************
ok: [13.231.201.67]

TASK [sshd : Disabling root user login] ***************************************************************************************
changed: [13.231.201.67]

RUNNING HANDLER [sshd : Restart sshd] *****************************************************************************************
changed: [13.231.201.67]

PLAY RECAP ********************************************************************************************************************
13.231.201.67              : ok=6    changed=3    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

第一次运行时,发现端口22被使用。
进行第二次执行。

$ ansible-playbook -i hosts playbook.yml

PLAY [Change port] ************************************************************************************************************

TASK [sshd : Connect default ssh port] ****************************************************************************************
fatal: [13.231.201.67 -> localhost]: FAILED! => {"changed": false, "elapsed": 5, "msg": "Timeout when waiting for 13.231.201.67:22"}
...ignoring

TASK [sshd : Connect custom ssh port] *****************************************************************************************
ok: [13.231.201.67 -> localhost]

TASK [sshd : set ansible_ssh_port custom_ssh_port] ****************************************************************************
ok: [13.231.201.67]

TASK [sshd : Rewrite custom_ssh_port] *****************************************************************************************
skipping: [13.231.201.67]

TASK [sshd : Disabling password authentication] *******************************************************************************
ok: [13.231.201.67]

TASK [sshd : Disabling Challenge-Response Authentication] *********************************************************************
ok: [13.231.201.67]

TASK [sshd : Disabling root user login] ***************************************************************************************
ok: [13.231.201.67]

PLAY RECAP ********************************************************************************************************************
13.231.201.67              : ok=6    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=1

通过第二次,我们可以看到使用了自定义SSH端口的50001端口。

让我们执行第三次。

ansible-playbook -i hosts playbook.yml

PLAY [Change port] ************************************************************************************************************

TASK [sshd : Connect default ssh port] ****************************************************************************************
fatal: [13.231.201.67 -> localhost]: FAILED! => {"changed": false, "elapsed": 5, "msg": "Timeout when waiting for 13.231.201.67:22"}
...ignoring

TASK [sshd : Connect custom ssh port] *****************************************************************************************
ok: [13.231.201.67 -> localhost]

TASK [sshd : set ansible_ssh_port custom_ssh_port] ****************************************************************************
ok: [13.231.201.67]

TASK [sshd : Rewrite custom_ssh_port] *****************************************************************************************
skipping: [13.231.201.67]

TASK [sshd : Disabling password authentication] *******************************************************************************
ok: [13.231.201.67]

TASK [sshd : Disabling Challenge-Response Authentication] *********************************************************************
ok: [13.231.201.67]

TASK [sshd : Disabling root user login] ***************************************************************************************
ok: [13.231.201.67]

PLAY RECAP ********************************************************************************************************************
13.231.201.67              : ok=6    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=1

第三次也使用了端口50001。
而且,更改次数为0,可以看出具有幂等性。

下次,将使用ansible的ansible-lint工具对代码进行重构。

 

请引用

 

广告
将在 10 秒后关闭
bannerAds