ConoHaではサーバ内でファイアウォールを設定しなくても、VPSの外側でセキュリティグループを設定することで開放ポートを設定することができます。
しかしここで設定できるのはデフォルトで用意されたこれだけです。もうちょっと頑張りたいとき――例えばSSHポートは22番から8022番に変更してアタックされにくくして、FTPは使わないので20/21番は閉じたい、という場合にはブラウザからは操作できません。APIならできます。
大雑把な手順
- 新しいセキュリティグループを追加する
- セキュリティグループにルールを追加する
- ネットワークポートにセキュリティグループを適用する
- サーバ内のファイアウォールを設定する
- SSHの待ち受けポートを8022番にする
OSはCentOS7.1のイメージを使う前提とします。
1と2はアカウント単位での作業です。VPSを2つ以上作るときでも作業は1回しておけばOKです。3はVPS単位です。4はAPIではありませんが、デフォルトでは22番ぐらいしか開いていませんので作業が必要です。5番を忘れるとネットワークの外側から接続できなくなります。
APIトークンを発行する
まず「APIのログイン」ともいえるトークン発行を行います。
usernameは管理画面の「API」タブにあるAPIユーザ名をコピペします。自分で設定はできません。 passwordは管理画面で事前に設定します。右側の鉛筆アイコンです。 tenantIdも管理画面のAPI情報「テナントID」からコピーします。
パイプで「python -mjson.tool」に渡すことで、jsonの出力を整形して読みやすくしています。実行結果は次のようになります。
$ curl -X POST \ > -H "Accept: application/json" \ > -d '{"auth":{"passwordCredentials":{"username":"gncu12345678","password":"PASSWORDPASSWORDPASSWORD"},"tenantId":"tenantidtenantidtenantidtenantid"}}' \ > https://identity.tyo1.conoha.io/v2.0/tokens \ > | python -mjson.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 2592 100 2452 100 140 4163 237 --:--:-- --:--:-- --:--:-- 4162 { "access": { "metadata": { (中略) }, "serviceCatalog": [ (中略) ], "token": { (中略) "id": "9999tokenid9999tokenid9999tokeni", (中略) } }, "user": { (中略) } } }
これのうちaccess.token.idの値がトークンになります。以降のリクエストヘッダ「X-Auth-Token: 9999tokenid9999tokenid9999tokeni」として指定することで、各APIを使用できます。
新しいセキュリティグループを追加する
追加する前に、現在あるセキュリティグループを確認しましょう。
$ curl -X GET \ > -H "Accept: application/json" \ > -H "X-Auth-Token: 9999tokenid9999tokenid9999tokeni" \ > https://networking.tyo1.conoha.io/v2.0/security-groups \ > | python -mjson.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 7496 100 7496 0 0 11431 0 --:--:-- --:--:-- --:--:-- 11426 { "security_groups": [ { "description": "default", (中略) }, { "description": "gncs-ipv4-ssh", (中略) }, { "description": "gncs-ipv6-ssh", (中略) }, (中略) } ] }
セキュリティグループを作成します。ブラウザ画面でいうところのチェックボックスに相当するものを追加するわけですが、ブラウザには表示されません。
$ curl -X POST \ > -H "Accept: application/json" \ > -H "X-Auth-Token: 9999tokenid9999tokenid9999tokeni" \ > -d '{"security_group": {"name": "ssh-8022"}}' \ > https://networking.tyo1.conoha.io/v2.0/security-groups \ > | python -mjson.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 809 100 769 100 40 958 49 --:--:-- --:--:-- --:--:-- 958 { "security_group": { "description": "", "id": "11112222-3333-4444-5555-666677778888", "name": "ssh-8022", "security_group_rules": [ (中略) ], "tenant_id": "tenantidtenantidtenantidtenantid" } }
セキュリティグループのIDは「11112222-3333-4444-5555-666677778888」です。
セキュリティグループにルールを追加する
セキュリティグループ「11112222-3333-4444-5555-666677778888」にルールを追加します。tcp8022番ポートは受け付ける、というルールになります。
$ curl -X POST \ > -H "Accept: application/json" \ > -H "X-Auth-Token: 9999tokenid9999tokenid9999tokeni" \ > -d '{"security_group_rule": {"direction": "ingress", "ethertype": "IPv4", "security_group_id": "11112222-3333-4444-5555-666677778888", "port_range_min": "8022", "port_range_max": "8022", "protocol": "tcp"}}' \ > https://networking.tyo1.conoha.io/v2.0/security-group-rules \ > | python -mjson.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 526 100 324 100 202 380 237 --:--:-- --:--:-- --:--:-- 380 { "security_group_rule": { "direction": "ingress", "ethertype": "IPv4", "id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "port_range_max": 8022, "port_range_min": 8022, "protocol": "tcp", "remote_group_id": null, "remote_ip_prefix": null, "security_group_id": "11112222-3333-4444-5555-666677778888", "tenant_id": "tenantidtenantidtenantidtenantid" } }
同様にして80/443番を開けるセキュリティグループも作ります。できたセキュリティグループIDは「99992222-9999-4444-9999-666677779999」とします。
できあがったらもう一度セキュリティグループ一覧を取得し、差分を確認すると完璧です。
ネットワークポートにセキュリティグループを適用する
さて、新しいセキュリティグループをネットワークポートに適用したいわけですが、IPアドレスはわかるもののAPI上のIDはわかりません。一覧を取得して、探し出しましょう。
$ curl -X GET \ > -H "Accept: application/json" \ > -H "X-Auth-Token: 9999tokenid9999tokenid9999tokeni" \ > https://networking.tyo1.conoha.io/v2.0/ports \ > | python -mjson.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 2762 100 2762 0 0 4281 0 --:--:-- --:--:-- --:--:-- 4275 { "ports": [ { (中略) "fixed_ips": [ { "ip_address": "172.21.140.210", "subnet_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" } ], "id": "11111111-2222-2222-2222-3333port3333", (中略) }, (中略) "security_groups": [ "22222222-4444-4444-6666-666688888888" ], (中略) ] }
IPに紐づくネットワークポートIDと、ついでに今あるセキュリティグループも分かりました。 今あるセキュリティグループに、先ほどの新しいセキュリティグループを追加した形で上書きします。
$ curl -X PUT \ > -H "Accept: application/json" \ > -H "X-Auth-Token: 9999tokenid9999tokenid9999tokeni" \ > -d '{"port": {"security_groups": ["11112222-3333-4444-5555-666677778888","99992222-9999-4444-9999-666677779999","22222222-4444-4444-6666-666688888888"]}}' \ > https://networking.tyo1.conoha.io/v2.0/ports/11111111-2222-2222-2222-3333port3333 \ > | python -mjson.tool % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 995 100 846 100 149 986 173 --:--:-- --:--:-- --:--:-- 986 { "port": { (中略) "security_groups": [ "11112222-3333-4444-5555-666677778888", "22222222-4444-4444-6666-666688888888", "99992222-9999-4444-9999-666677779999" ], "status": "BUILD", "tenant_id": "tenantidtenantidtenantidtenantid" } }
これでセキュリティグループの設定が完了しました。
サーバ内のファイアウォールを設定する
セキュリティグループはサーバの外側を守ってくれますが、これに不具合ができないとも限らないので、内側のファイアウォールも同じように必要なだけを開けることとします。
# firewall-cmd --add-port=8022/tcp --zone=public --permanent
# firewall-cmd --add-port=80/tcp --zone=public --permanent
# firewall-cmd --add-port=443/tcp --zone=public --permanent
# firewall-cmd --reload
結果はこんな感じになります。
# firewall-cmd --list-all public (default, active) interfaces: eth0 sources: services: dhcpv6-client ssh ports: 80/tcp 443/tcp 8022/tcp masquerade: no forward-ports: icmp-blocks: rich rules:
sshdの待ち受けポートを8022番に変更
# vi /etc/ssh/sshd_config
# systemctl restart sshd
一緒に操作端末の~/.ssh/configに対象サーバのポートが8022番であることの設定をしておけば、22番以外に変更していることを気にしなくて済むようになります。
API直接でなくneutronコマンドでも可能
この辺の操作はAPIを直接使うのではなくneutronコマンドを使ったほうが楽かもしれません。実際、中の人の連載でもそのようにしています。
http://gihyo.jp/dev/serial/01/conoha/0005?page=2
負荷の増減に合わせてインスタンスを作ったり破棄したりするような、AWS的な仕組みを作るなら手順3以降は自動化する必要があります。その際はAPIのほうが都合がよいかもしれません。
柔軟な運用はfirewalld + ansibleなどで実現したほうがやりやすそうです。しかしインスタンスをAPI経由で作るとデフォルトのセキュリティグループ”default”だけは全アクセス拒否になってしまうので、何かしらの操作は必要になります。自動化するなら避けて通れないところのAPI手順でした。
最近のコメント