LoginSignup
3
3

More than 5 years have passed since last update.

vagrant sshで接続時に自動でSecurityGroupを作り,切断時にSecurityGroupを消す

Last updated at Posted at 2016-01-22

前提

固定IPがないので,SecurityGroupをうまく設定できない.でも0.0.0.0/0を許可したくない.

方針

vagrant-triggersでがんばってみる

vagrant-triggersを使うと,vagrantの任意のサブコマンドの前後に処理を挟みこめます.

しかし,vagrant ssh時においては,接続前のトリガーはうまく動いたものの,切断したときはトリガーが発動せず,断念しました.

config.ssh.ssh_commandを設定する

ドキュメントには見当らなかったのですが,config.ssh.ssh_commandを設定することで,vagrant ssh時に使用されるsshプログラムを指定することができる模様.ソースだとこのあたり

そこで,sshする前に現在のIPからSSHを許可するSecurityGroupを作り,ssh切れたらSecurityGroupを消滅させるシェルを書き,それをvagrant sshで勝手に使ってくれるようにしました.

ソース

Vagrantfileに1つしかVM定義がない前提です.また,VM名を指定してる場合はinstance-idが書かれたファイルのパスが変わるはずです.

あと,awscliをインストールしておく必要があります.

ec2ssh
#!/bin/bash

# 事前にaws configureで設定は済ませておく
export AWS_DEFAULT_PROFILE=sample
set -e

# vagrant upは終わっている前提
# ファイルに書かれているinstance-idを読みとる
test -e .vagrant/machines/default/aws/id
INSTANCE_ID=$(cat .vagrant/machines/default/aws/id)
test -n $INSTANCE_ID

# SecurityGroupを作るために当該インスタンスが属しているVPCを調べる
VPC_ID=$(aws ec2 describe-instances \
    --filter "Name=instance-id,Values=$INSTANCE_ID" \
    --query "Reservations[0].Instances[0].VpcId" \
    --output text)
test -n $VPC_ID

# デフォルトのSecurityGroupを用意しておく
# EC2インスタンスには最低1つSecurityGroup付ける必要があるため.
# どこからも接続できないようなSecurityGroupでOK
DEFAULT_SECURITY_GROUP=$(aws ec2 describe-security-groups \
    --filter "Name=group-name,Values=default" \
    --query "SecurityGroups[0].GroupId" \
    --output text)
test -n $DEFAULT_SECURITY_GROUP

# 新しいSecurityGroupを作成
SECURITY_GROUP=$(aws ec2 create-security-group \
    --group-name "ec2ssh-$(date +%Y%m%d-%H%M%S)" \
    --description "SSH from CURRENT_IP" \
    --vpc-id $VPC_ID \
    --output text)
test -n $SECURITY_GROUP && echo "security-group $SECURITY_GROUP created successfully."

# 現在のIPを調べる
CURRENT_IP=$(curl -s https://api.ipify.org)
# 作ったSecurityGroupに,現在のIPからのSSHを許可するようなルールを作成する
aws ec2 authorize-security-group-ingress \
    --group-id $SECURITY_GROUP --ip-protocol tcp \
    --from-port 22 --to-port 22 --cidr-ip "$CURRENT_IP/32"
aws ec2 modify-instance-attribute \
    --instance-id $INSTANCE_ID \
    --groups $SECURITY_GROUP
echo "SSH connection would be authorized from $CURRENT_IP/32"

# sshが異常終了した場合でも処理を継続するように.
set +e
ssh $*
set -e

# 当該インスタンスのSecurityGroupをデフォルトのみに戻す
aws ec2 modify-instance-attribute \
    --instance-id $INSTANCE_ID \
    --groups $DEFAULT_SECURITY_GROUP
# 作ったSecurityGroupを削除する
aws ec2 delete-security-group \
    --group-id $SECURITY_GROUP
echo "security-group $SECURITY_GROUP deleted successfully."
echo "SSH connection would be revoked from $CURRENT_IP/32"

exit 0

こんなシェルをVagrantfileと同じ場所に置いておく

あとは,Vagrantfile内のsshの設定をやってるところでssh_commandに設定する.

Vagrantfile
    override.ssh.username         = "ec2-user"
    override.ssh.private_key_path = "~/.ssh/private.pem"
    override.ssh.ssh_command      = './ec2ssh' # <-これ

結果

uraura@rosemary $ vagrant ssh
security-group sg-xxxxxxxx created successfully.
SSH connection would be authorized from xxx.xxx.xxx.xxx/32
Last login: Fri Jan 22 11:15:01 2016 from xxx.xxx.xxx.xxx

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2015.09-release-notes/
1 package(s) needed for security, out of 1 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-172-31-8-18 ~]$

[ec2-user@ip-172-31-8-18 ~]$ exit
Connection to ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com closed.
security-group sg-xxxxxxxx deleted successfully.
SSH connection would be revoked from xxx.xxx.xxx.xxx/32

SSHがタイムアウトしたとか,SSH中にインスタンスが停止した場合でも,ちゃんとSecurityGroupが消えます.

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3