【追記あり】(AWS/EC2) UserDataを使って、自動でイントラからSSHログインできるインスタンスを作る!
どうも!
前回の記事では、EC2 でインスタンスを作った時、イントラからそのままではアクセス出来ないことがわかり、対処法の1つを記載しました。それなら、ユーザーデータを使って、自動的にその作業を出来ないかと試してみました。
結論としては、今のところほとんど自動化できるのですが、残念ながら不完全です。
【追記 3/10】諸事情で、インスタンスタイプを(m1.large)で試してみたところうまく行きました。t1.micro ではうまく行きませんでした。インスタンスタイプに依存しているのかもしれません。
ユーザーデータとスクリプトについて
- ユーザーデータにスクリプトを設定することで、初回の起動時に実行することができる。
- スクリプトは root で実行される。なので sudo は呼ばないこと。
- あと、自動的に起動するので対話モードにならないように書くこと。
- yum update の -y 無しみたいなの。
- スクリプトの動作の流れを確認するには /var/log/cloud-init.log にログが書かれるので確認すること。
- スクリプトの動作を書く上では、あまり参考にならなかったので、自前でログを吐くようにすると良いです。
参考:
Launching Instances with User Data - Amazon Elastic Compute Cloud
Amazon EC2のUser Dataにシバンを指定してスクリプトを実行する | Developers.IO
環境
- Red Hat Enterprise Linux 6.4 (PV) - ami-5769f956 (64-bit) を使用します。
- Amazon Linux や CentOS も試しましたが、かなりデフォルトの状態が違うので同じスクリプトではうまくいかないと思います。
用意したスクリプト
- /var/log/user-data.log に実行ログが出力されるようにする。
- sshd_config を修正し、ssh のポートに 443 を追加する。
- selinux の設定を変更し、sshd に 443 が開けるようにする。
- iptables を修正し、443 を受け付けるようにする。
#!/bin/bash -ex exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 perl -pi -e 's/^#?Port 22$/Port 22\nPort 443/' /etc/ssh/sshd_config semanage port -m -t ssh_port_t -p tcp 443 iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT iptables -D INPUT -j REJECT --reject-with icmp-host-prohibited iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited service iptables save service iptables restart service sshd restart
UserData に設定してみる
新しくインスタンスを起こす場合、Step3: Configure Instance Details の Advanced Details の下にテキストエリアがあります。ここにスクリプトをそのまま貼り付けて起動します。そうすると、初回起動時に当該スクリプトが呼ばれます。
また、スクリプトはファイルで用意しておいて、ファイルアップロードもできるので、管理しやすいと思います。
SELinux (semanage) のポート設定が変更できない。
ここまでで、うまくスクリプトが起動時に呼ばれることは確認できました。また、狙った設定も1箇所以外は、自動的に行うことが出来ました。ですが、SELinux の設定だけうまく行きません。
理由は、semanage の呼び出し時に下記のエラーが発生し、SELinux のポート設定が変更出来ませんでした。
【3/10 追記】t1.micro だと同様の現象が起きるようです。m3.large で実行したところ、想定通り設定が反映されることを確認しました。
+ semanage port -m -t ssh_port_t -p tcp 443 libsemanage.semanage_exec_prog: Child process /sbin/setfiles did not exit cleanly. libsemanage.semanage_install_active: setfiles returned error code -1. libsemanage.semanage_exec_prog: Child process /sbin/setfiles did not exit cleanly. libsemanage.semanage_install_active: setfiles returned error code -1. /usr/sbin/semanage: Could not commit semanage transaction
なんとなくですが、起動時の順番に依存する制約が隠れているような気がします。
SELinux をオフにするか、手で設定するか、CloudFormation など別のサービスを利用するしか無いのでしょうか? 対処方法がわかったら更新しようと思います。