よしだのブログ

サブタイトルはありません。

【追記あり】(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

環境

用意したスクリプト

  • /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 の下にテキストエリアがあります。ここにスクリプトをそのまま貼り付けて起動します。そうすると、初回起動時に当該スクリプトが呼ばれます。
また、スクリプトはファイルで用意しておいて、ファイルアップロードもできるので、管理しやすいと思います。

f:id:yoshi0309:20140305191753p:plain

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 など別のサービスを利用するしか無いのでしょうか? 対処方法がわかったら更新しようと思います。