LoginSignup
1
3

More than 5 years have passed since last update.

Slack BotでAWSのセキュリティーグループ設定を行う話。

Last updated at Posted at 2016-12-19

ヴァル研究所 Advent Calendar 2016、19日目はSlackからAWSのセキュリティグループの設定を追加・削除する例を紹介しようと思います。

AWSのセキュリティグループ

EC2インスタンスを立ち上げてsshでログインする際、基本的には社内ネットワークからのみssh接続を受け付けるようなセキュリティグループの設定を行うかと思います。とはいえ、テレワークなどで自宅や近所のカフェからsshで接続するような場面もあります。
その都度セキュリティグループを設定すれば良いのですが、AWSのマネジメントコンソールから自分のEC2インスタンスに紐付いているセキュリティグループを見つけて設定を追加・削除するのはちょっと面倒です。

そこで今回は、SlackからAWSのセキュリティグループの設定を追加・削除するBotを作成してみました。

セキュリティーグループ設定・削除Bot

Botのソースコードは以下のようになります。RubyスクリプトからAWS CLIのコマンドを呼び出す形でセキュリティグループの操作を行います。AWS CLIの応答には若干のタイムラグがあるので、スレッド上でコマンドを実行するのが良さそうです(Botの応答性を上げるという意味で)。
今回はssh(TCP/22)のインバウンドポートのみを設定・削除する動作になっています。

使い方は単純にsg authorize <SGID> <CIDR>でSG追加、sg revoke <SGID> <CIDR>でSG削除、sg describe <SGID>で現在のセキュリティグループでインバウンドの疎通が許可されているIPアドレス一覧の表示を行います。

#!/usr/bin/env ruby
# coding: utf-8

require 'net/http'
require 'uri'
require 'erb'
include ERB::Util
require 'json'

require 'slack'

def post(channel, msg)
  param = {
    token:   ENV['SLACK_TOKEN'],
    channel: channel,
    text:    msg,
    username: "SecurityGroupBot",
    icon_url: 'https://ekiworld.net/ekiworld/info/images/machinami.png'
  }
  Slack.chat_postMessage(param)
end

Slack.configure {|config|
  config.token = ENV['SLACK_TOKEN']
}
client = Slack.realtime

start_time = Time.now.to_i

client.on :message do |data|
  post_time = data["ts"].sub(/\..*$/, "").to_i
  next if post_time < start_time

  msg = data["text"]

  # "sg <authorize|revoke> ..."が投稿された場合の処理。
  # sshのSGを追加、削除する。
  if msg =~ /^sg (.*) (.*) (.*)/
    type  = $1
    next if type != "authorize" and type != "revoke"

    sg_id = $2

    # XXX.XXX.XXX.XXX/XXという文字列は、Slack的に電話番号として
    # 認識され、先頭に"tel:"とか付けられてしまうので除去する。
    cidr  = $3.sub(/<tel:/, '').sub(/\|.*$/, '')
    next unless sg_id or cidr

    channel = data["channel"]
    if type == "authorize"
      post(channel, "SG追加します。")
    else
      post(channel, "SG削除します。")
    end

    cmd = ''
    cmd = cmd << "aws ec2 #{type}-security-group-ingress "
    cmd = cmd << "--group-id #{sg_id} "
    cmd = cmd << "--ip-permissions '[{\"IpProtocol\": \"TCP\", \"ToPort\": 22,\"FromPort\": 22,\"IpRanges\": [{\"CidrIp\": \"#{cidr}\"}]}]'"

    begin
      Thread.new do
        # AWS CLIコマンドを実行する。
        p JSON.parse(IO.popen(cmd, "r+") {|p| p.read})
      end
    rescue Exception => e
      puts e.message
      puts e.backtrace.inspect
    end
  end

  # "sg describe ..."が投稿された場合の処理。
  # 指定されたSGグループに設定されているIngress側IPアドレスを表示する。
  if msg =~ /^sg describe (.*)/
    sg_id = $1
    cmd = "aws ec2 describe-security-groups --group-ids #{sg_id}"

    channel = data["channel"]
    begin
      Thread.new do
        addr_list_str = ''

        # AWS CLIコマンドを実行する。
        json_str = JSON.parse(IO.popen(cmd, "r+") {|p| p.read})
        json_str["SecurityGroups"][0]["IpPermissions"][0]["IpRanges"].each do |iprange|
          addr_list_str = addr_list_str << iprange["CidrIp"] << "\n"
        end

        if addr_list_str != ''
          result = "セキュリティグループで許可されているIPアドレス\n\`\`\`\n#{addr_list_str}\`\`\`"
        else
          result = "セキュリティグループで許可されているIPアドレスはありません。"
        end

        post(channel, result)
      end
    rescue Exception => e
      puts e.message
      puts e.backtrace.inspect
    end

  end

end
STDERR.puts("ok.")

client.start

微妙に注意が必要な個所として、SlackではXXX.XXX.XXX.XXX/XXのようなフォーマットを入力すると電話番号として解釈されるようで、Botには<Tel:XXX.XXX.XXX.XXX/XX>のようなフォーマットが追加された文字列が渡されてきます。
IPアドレスとして処理する際には、付加された文字の除去が必要になります。

実際に使ってみる

実際にBotを動かしてみます。sg describe <SGID>で現状のセキュリティグループで疎通許可されているIPアドレスが一覧表示されます。

img100.png

ここでsg authorize <SGID> <CIDR>と投稿すると、指定したIPアドレスがTCP/22(ssh)のインバウンド設定として追加されます。疎通許可IPアドレスの項目が増えていますね。

img101.png

sg revoke <SGID> <CIDR>で設定したIPアドレスを除去できます。これで一連のセキュリティグループ設定の追加・削除が行えることが確認できました。

img103.png

まとめ

Slack BotからAWSのセキュリティグループ設定の追加・削除を行ってみました。サンプルなのでTCP/22(ssh)のインバウンド設定のみですが、出先で一時的にsshの疎通を許可したいようなケースで有用かなと思います。

1
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
1
3