使用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 的自動分配。
创建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工具对代码进行重构。
请引用