ConoHa API を叩いてインフラ側で Firewall を設定 - ConoHa で KUSANAGI その4
今回は、Firewall を設定します。
ConoHa では、サーバーにアクセスする手前のインフラ側で Firewall を設定できます。さすがクラウドを謳うだけのことはあります。さくらのVPSには無いサービスですね。
ただ管理画面から設定できる Firewall は一般的な組合せが何通りかあるだけですので、カスタマイズするためには API を叩いて自分で設定する必要があります。
ちなみに、ConoHa の管理画面でサーバーのネットワーク情報を確認すると、接続許可ポートという項目でデフォルトの組合せを確認可能です。おそらくサーバー追加時に特に何も触っていなければ、「全て許可」にチェックが入っているでしょう。
今回の記事の作業で API を叩いて許可ポートを独自設定すると、管理画面の接続許可ポートという項目では、どれも選択されていない状態になります。当たり前ですが API と管理画面がちゃんと連携してるんですね。
さて、この記事では 80 および 443 と、SSHで設定した 55555 以外の全てのインバウンドを閉じることにします。また、アウトバウンドは全開放(デフォルト)のままとします。
サーバー側の Firewalld については念のため次回の記事で設定をしますが、ConoHa のインフラを信頼することにして起動はさせません。
API に接続
API の設定には、curl を使用します。
Windows では、ソフトをいれないと curl コマンドを使えないのですが大丈夫。
現在設定作業中のサーバーを使って API とやり取りすることができます。
API に接続するための情報を入手する
ConoHa の管理画面にログインし 左カラムのメニューから API を選択してページを開きます。
テナント情報で、以下の情報を控えます。
- テナントID xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- テナント名 yyyyyyyyyy
エンドポイントでリージョンを選択し以下の情報を控えます。(東京リージョンなら下記と一緒だと思います。)
- Identity Service https://identity.tyo1.conoha.io/v2.0
- Network Service https://networking.tyo1.conoha.io
APIユーザーでユーザーを追加し以下の情報を控えます。パスワードを設定するとユーザーIDが自動的に付与されます。
- ユーザー名 zzzzzzzzzzzz
- パスワード passpasspass
これで準備完了です。
API からトークンを取得する
入手した情報を使って、24時間有効なトークンをAPIからもらいます。
API の設定作業の際には、このトークンを使ってアクセスします。
サーバーにログインして、curl コマンドを実行します。
トークン取得
curl -i -X POST -H "Accept: application/json" \ -d '{ "auth": { "passwordCredentials": { "username": "zzzzzzzzzzzz", "password": "passpasspass" }, "tenantId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } }' \ https://identity.tyo1.conoha.io/v2.0/tokens
このように打つと、json 形式の返り値が画面に表示されます。トークン取得の返り値には、最初の方に json 形式以外のテキストで HTTP レスポンスコードなどが入っているので、python の mjson.tool でうまく読み取ってくれません。
そこで返り値のうち{}でくくられた部分をコピーして、エディタなどで json 形式に整形して見ると良いです。
私のお気に入りの Atom エディタに pretty JSON というパッケージをインストールして整形してみると、以下の様な感じになりました。
{ "access": { "token": { "issued_at": "2016-05-28T11:57:42.729417", "expires": "2016-05-29T11:57:42Z", "id": "tokentokentokentokentokentoken", ← 最初の方のこれがアクセストークン "tenant": { "name": "yyyyyyyyyy", "enabled": true, "tyo1_image_size": "50GB", "id": "hogehogehogehogehogehogehoge", "sin1_image_size": "50GB", "sjc1_image_size": "50GB", 以下略 } } } }
必要なのはアクセストークンだけです。このあと何回も使いますから控えておきましょう。
セキュリティグループの設定
接続許可の設定は、1)セキュリティグループを作り、2)これをサーバーのネットワークポートに適用して行います。
作成したセキュリティグループは、同じアカウントが管理する他のサーバーに対してもそれぞれ個別に適用することができます。
また、1つのネットワークポートに対して複数のセキュリティグループを同時に適用することが可能です。
というわけで今回は以下の3つのセキュリティグループを作成し、サーバーのインターネット接続用のネットワークポートに適用することとします。
- セキュリティグループ名 / 許可ポート(type)
- my-def-web4 / 80 (IPv4),443(IPv4)
- my-def-web6 / 80 (IPv6),443(IPv6)
- my-def-ssh4 / 55555(IPv4)
グループ名は自分がわかりやす名前を適当に決めます。
既存のセキュリティグループを確認する
まずは肩慣らしに、既存のセキュリティグループを確認してみます。
このコマンドに対する返り値は、頭から JSON なので、mjson.tool にぶん投げれば整形してくれます。
curl -X GET \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ https://networking.tyo1.conoha.io/v2.0/security-groups \ | python -mjson.tool
返り値をダラダラ見てください。
ConoHa の管理画面で設定したことがある接続許可ポートに対応したセキュリティグループが表示されてると思います。
セキュリティグループを作成する
先ほど名前を決めたセキュリティグループ3つを作ります。 それぞれ返り値があり、その中の ID が必要になりますのでメモします。
curl -X POST \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ -d '{"security_group": {"name": "my-def-web4"}}' \ https://networking.tyo1.conoha.io/v2.0/security-groups \ | python -mjson.tool curl -X POST \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ -d '{"security_group": {"name": "my-def-web6"}}' \ https://networking.tyo1.conoha.io/v2.0/security-groups \ | python -mjson.tool curl -X POST \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ -d '{"security_group": {"name": "my-def-ssh4"}}' \ https://networking.tyo1.conoha.io/v2.0/security-groups \ | python -mjson.tool
返り値の例
{ "security_group": { "description": "", "id": "id4id4-id4id4-id4id4-id4id4-id4id4id4id4id4id4", "name": "my-def-web4", "security_group_rules": [ 以下略 ] } }
こんな感じでメモしておきました。
- my-def-web4 / id4id4-id4id4-id4id4-id4id4-id4id4id4id4id4id4
- my-def-web6 / id6id6-id6id6-id6id6-id6id6-id6id6id6id6id6id6
- my-def-ssh4 / idSidS-idSidS-idSidS-idSidS-idSidSidSidSidSidS
セキュリティグループにルールを追加します
1つ見たらなんとなくやり方がわかると思いますが、一応全部載せときます。
#IPv4 80 curl -X POST \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ -d '{"security_group_rule": {"direction": "ingress", "ethertype": "IPv4", "security_group_id": "id4id4-id4id4-id4id4-id4id4-id4id4id4id4id4id4", "port_range_min": "80", "port_range_max": "80", "protocol": "tcp"}}' \ https://networking.tyo1.conoha.io/v2.0/security-group-rules \ | python -mjson.tool #IPv4 443 curl -X POST \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ -d '{"security_group_rule": {"direction": "ingress", "ethertype": "IPv4", "security_group_id": "id4id4-id4id4-id4id4-id4id4-id4id4id4id4id4id4", "port_range_min": "443", "port_range_max": "443", "protocol": "tcp"}}' \ https://networking.tyo1.conoha.io/v2.0/security-group-rules \ | python -mjson.tool #IPv6 80 curl -X POST \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ -d '{"security_group_rule": {"direction": "ingress", "ethertype": "IPv6", "security_group_id": "id6id6-id6id6-id6id6-id6id6-id6id6id6id6id6id6", "port_range_min": "80", "port_range_max": "80", "protocol": "tcp"}}' \ https://networking.tyo1.conoha.io/v2.0/security-group-rules \ | python -mjson.tool #IPv6 443 curl -X POST \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ -d '{"security_group_rule": {"direction": "ingress", "ethertype": "IPv6", "security_group_id": "id6id6-id6id6-id6id6-id6id6-id6id6id6id6id6id6", "port_range_min": "443", "port_range_max": "443", "protocol": "tcp"}}' \ https://networking.tyo1.conoha.io/v2.0/security-group-rules \ | python -mjson.tool #SSH 55555 curl -X POST \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ -d '{"security_group_rule": {"direction": "ingress", "ethertype": "IPv4", "security_group_id": "idSidS-idSidS-idSidS-idSidS-idSidSidSidSidSidS", "port_range_min": "55555", "port_range_max": "55555", "protocol": "tcp"}}' \ https://networking.tyo1.conoha.io/v2.0/security-group-rules \ | python -mjson.tool
セキュリティグループをサーバーに適用する
自分の ConoHa アカウント配下にあるサーバーのネットワークポートを調べます。
curl -X GET \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ https://networking.tyo1.conoha.io/v2.0/ports \ | python -mjson.tool
返り値は以下のようになります。設定したいサーバーの IP アドレスを見つけてネットワークポートの ID を取得しメモしておきます。
返り値の例
{ "ports": [ { "admin_state_up": true, "allowed_address_pairs": [ { "ip_address": "****:****:****:***:****:**:***:***/***", "mac_address": "**:**:**:**:**:**" } ], "binding:vnic_type": "normal", "device_id": "********-****-****-****-***********", "device_owner": "compute:None", "extra_dhcp_opts": [], "fixed_ips": [ { "ip_address": "987.654.321.09", #← サーバーのIPアドレス "subnet_id": "********-****-****-****-*************" }, { "ip_address": "****:****:****:***:****:**:***:***", "subnet_id": "********-****-****-****-*************" } ], "id": "portID-portID-portID-portID-portIDportID", ← これがID! 以下略 } ] }
ポートにセキュリティグループを適用する
ポートにセキュリティグループを適用すると、そのポートに適用されていた以前の設定は上書きされて消されます。
つまり、適用するたびに前の設定が消えるので、セキュリティグループを1つずつ追加していくことができません。
3つのセキュリティグループを同時に適用するためには、一回の操作でまとめて適用します。
curl -X PUT \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ -d '{"port": {"security_groups": ["id4id4-id4id4-id4id4-id4id4-id4id4id4id4id4id4","id6id6-id6id6-id6id6-id6id6-id6id6id6id6id6id6","idSidS-idSidS-idSidS-idSidS-idSidSidSidSidSidS"]}}' \ https://networking.tyo1.conoha.io/v2.0/ports/portID-portID-portID-portID-portIDportID\ | python -mjson.tool
IPv6が不要な場合は、データの部分を
["id4id4-id4id4-id4id4-id4id4-id4id4id4id4id4id4","idSidS-idSidS-idSidS-idSidS-idSidSidSidSidSidS"]
とすれば良いですね。
正しく適用されたかポートの設定を確認する
セキュリティグループが正しく適用されたかポートの設定を確認します。
curl -X GET \ -H "Accept: application/json" \ -H "X-Auth-Token: tokentokentokentokentokentoken" \ https://networking.tyo1.conoha.io/v2.0/ports/portID-portID-portID-portID-portIDportID\ | python -mjson.tool
うまく適用できてましたか?
Firewall が機能しているかどうか実際に確認してみてください。
お手軽に確認したければ、「ポートチェック【外部からポート開放確認】」というページさんのサービスを利用させていただくのもありかと。
次回は、サーバー側で Firewalld を念の為に設定しておきます。