サーバー群への管理者アクセス権限を統制する





シンジです。sshを利用してサーバーへアクセスする際、IDとパスワードでrootにダイレクトアクセスさせてるケースもままあるでしょうが、監査も通らないし乗っ取りリスク高すぎ問題なので辞めたいところです。クラウドを日常的に利用する方々の場合、通常は証明書認証によってサーバーログインを行っていると思います。証明書ファイルが次々と増えていく問題、証明書ファイルを手に入れれば多くの人がサーバーにログインできちゃう問題は目をつぶるしかないのか。

そこでエンプラなどでは、「踏み台サーバー」を作って、そこでアクセス権限をコントロールすることで、サーバーログインへの統制を図るわけですが、第一踏み台から第二踏み台へそして第三踏み台とかいう絶望も現実的に存在している実状です。そもそも、エンプラが踏み台サーバーを自前で作るわけがなく、そういう製品を購入して作ってもらう、はい数千万円、保守費毎年よろしくみたいな世界です。

というわけで僕らはsshを辞めました。

Teleport By GRAVIRATIONAL


Teleportを使います。オープンソースです。

Teleport – Github
https://github.com/gravitational/teleport

GRAVIRATIONAL
https://gravitational.com/

GRAVIRATIONALの人たちは、元々Rackspaceの中の人で、大量のサーバー管理をどうすりゃええねんというところで開発されたのがTeleportです。

Teleportという踏み台システムは、AWSやAzure、GCPなどのクラウドインフラだけではなく、オンプレミスの一般的なサーバーでも稼働しますし、Dockerやk8sもサポートしています。Teleportを経由して接続できるサーバー群は、sshを喋るサーバーです。つまり現時点でRDP(Windows Server)をサポートしていません。

Teleportを経由すると、シェル丸ごとTeleportを利用するので、誰にたいしてどのサーバーにどんな権限でアクセスさせたいかをIdPとの接続などで統合管理できる他、シェル内で入力したコマンドは全て記録され、誰がいつ何をしたのかを「動画」として再生することができます。

sshのかわりに、管理配下にしたいサーバーに対して、Teleportのエージェントをインストールするわけです。そうすることで、sshを利用せずにssh風な感じになるってな具合です。

まずはおおまかな挙動を説明します。

Teleportにログイン

URLはRoute53でサブドメインを切っています。Teleportの踏み台サーバーは、自分たちで作ります。簡単です。

ユーザー名とパスワードによるログインも可能ですが、管理が面倒なので、統合認証基盤と接続して、一括管理にします。IdPと接続してシングルサインオンを実現させます。IdPが多要素認証をサポートしていれば、サーバーへのログインに多要素認証が追加されるというお買い得感。IdPの、どのグループに所属している人はrootを持っていて、あのグループに所属している人はこのユーザー名でログインさせたいなどをIdPで制御できるというわけです。

あなたがアクセスできるサーバーはこちらです

2台のサーバーが確認できます。実際に、Hostname ping-demo に root でログインしてみます。

yum updateでエンターキーしてみました。
この操作は記録されているので、それを確認してみます。

まぁざっくりこんな具合です。
このケースではブラウザから操作していますが、通常通りの用途として、iTerm2などを利用したローカルのターミナルから各サーバー群へteleportを利用したアクセスをすることも可能です。

Teleportの構成

自由度が高いので決めはないのですが、今回はAWSでTeleportシステムを構築するとこうなるっていうのを紹介します。

TeleportはAuthサーバーにて発行したTokenをProxy、Nodeの設定ファイル書き込み Teleportを起動する事でAuth⇔Proxy、Auth⇔NodeのJoinを行っています。

Authサーバー

Authサーバーは構築時と同時に証明書を扱うget-certとtokenを扱うpublish-tokenを導入します。get-certは実行時にLet’s Encryptにアクセスを行い、指定ドメインの証明書を取得しS3バケットにアップロードします。publish-tokenは実行時にtctlを実行し、TeleportのサーバーからProxy,Node,Trusted用の各tokenとCAを取得しSSMにアップロードします。

Proxyサーバー

Proxyサーバーの構築時にpush-certとget-tokenが導入されます。push-certは実行時にS3バケットから証明書をダウンロードしてProxyサーバーのWEB証明書として使用します。get-tokenは実行時にSSMからProxy TokenとCAをダウンロードします。teleportは、ここで取得したTokenとCAを使用して、ProxyサーバーとしてAuthサーバーに紐づきます。

Nodeサーバー

Nodeサーバー構築時にget-tokenが導入されます。get-tokenは実行時にSSMからNode Tokenをダウンロードします。teleportは、ここでTokenを使用してNodeサーバーとしてAuthサーバーに紐づきます。

Teleportの構築

今回はTerraformとAnsibleを利用することで、AWS環境にちゃちゃっと作ります。
Githubに公開したので(動くのは確認しましたが責任は取れないけど)参考にして下さい。

TeleportCluster – Ansibleパラメータドキュメント

Trusted Cluster – Ansibleパラメータドキュメント

既存のサーバーをTeleport配下にしてみよう

すだちブログのサーバーは、AWSのEC2で動いているので、これをTeleport配下にしてみます。

IdPからの一次クレデンシャルを取れるようにする(ウチの場合はIAMのキーを使わずにOktaでフェデレーションしているので)

saml2awsをセットアップ
https://github.com/Versent/saml2aws

AWSCLIも入れます。

brew install awscli

direnvをインストール

環境変数あれこれするのに便利

brew install direnv

shellにhookを追加(シンジはzsh、bashでもやってちょ)

vim ~/.zshrc
eval "$(direnv hook zsh)"
source ~/.zshrc

ansibleをインストール

便利な世の中だなぁ

brew install ansible

AuthサーバーとProxyサーバーの秘密鍵をssh_configにぶち込む

セットアップ時にはAuthサーバーとProxyサーバーにsshしたいので、その設定。

vim ~/.ssh/config

的な感じ。

とりあえずsshできればOK。

Githubからteleportを頂戴する

git clone git@github.com:cloudnative-co/teleport_renovation.git
cd teleport_renovation/ansible

Ansibleのパラメータをセットアップする

適宜、それっぽい値にちゃんと変更してください。ウチの場合はEnterpriseライセンスとかいうカッチョイイのを使っているのでライセンスファイルを指定していますが、OSSで使う場合は、指定しなくて大丈夫です。

vim vars/main.yaml

# バージョン
teleport_version: 3.0.1

# アーキテクチャ
teleport_architecture: linux-amd64

# エディション [enterprise/oss]
teleport_edition: enterprise

# インストール時の種別 [ node/auth/proxy/auth-proxy ]
teleport_type: ""

# エディションがenterprise時のライセンスファイルのパス
teleport_license: license.pem

# Teleportのデータディレクトリ
teleport_data_dir: /var/lib/teleport/

# typeがproxy時に指定するAuthサーバーのIPアドレス
teleport_auth_server_addr: hogehoge

# typeがproxyもしくはauth-proxy時のdomain名
teleport_proxy_domain: hogehoge

# authサーバー作成時にのteleportのクラスター名
teleport_cluster_name: aws-webapp

# リージョン
teleport_region: ap-northeast-1

# teleportで使用するS3のBucket名
teleport_bucket: hogehoge

# teleportのサーバーにてLet's encrypt実行時に使用するEMmail
teleport_email: hogehoge@cloudnative.co.jp

# teleportで使用するDynamoDBのデーブル名
teleport_dynamodb_table: hogehoge

# Proxy用tunnel待ち受けポート
teleport_proxy_tunnel_listen_port: 3080

hostsの設定をする

ディレクトリをひとつ上げて、ansibleディレクトリの中に、hostsを作ります。

vim hosts

[teleport-slave]
prd-webapp-teleport-slave

[teleport-node]
prd-shinji-animereview-jp

saml2awsでログインしてクレデンシャルを取得

ウチはOktaを使っているので、この手順が必要になるだけです。

saml2aws configure

いいかんじでやりましょう。設定できたらログインします。

saml2aws login

ログインしてawsコマンドが使えればOK

direnvで環境変数をいい感じにする

vim .envrc

で、新規ファイル作成。

# 設定済みのProfile名を使用
export AWS_PROFILE="saml"
# リージョンを指定
export AWS_DEFAULT_REGION="ap-northeast-1"

teleportのライセンスファイルをAnsible配下にする

一般的にはこの手順は不要です
パスはこんなかんじ

/ansible/license.pem

Ansibleを実行してサーバー構築

いくぜ構築。しばらく待ちます。

ansible-playbook --extra-vars '{ "host_name" : teleport-slave , "teleport_type": "auth-proxy" }' -i hosts install.yaml -v

Trusted Clusterを設定する

vim vars/trusted_cluster.yaml

# 主となるTeleport ClusterのCluster Nameを設定
teleport_master_cluster_name: 'aws-infra'

# 主となるTeleport ClusterのProxyのIPアドレスまたはホスト名を設定
teleport_master_cluster_addr: 'hogehoge.hoge.com'

# Proxy用tunnel待ち受けポート
teleport_proxy_tunnel_listen_port: '443'

# Proxy用WEB待ち受けポート
teleport_proxy_web_listen_port: '443'

Trusted ClusterのAnsibleを実行する

ドーン

ansible-playbook --extra-vars '{ "host_name" : teleport-slave }' -i hosts trusted_cluster.yaml -v

(補足)ユーザー作成

初期構築時はユーザーが1人もいない状態なので、ユーザー作成が必要です。この場合はadminというユーザーを作ります。

ansible teleport-master -i hosts -m shell -a "sudo tctl users add --roles admin admin"

Node追加

Teleport配下にしたいサーバーを追加するAnsibleを実行します。序盤にhostsを指定しましたが、そこに記述されているサーバーがNodeとして追加されます。

ansible-playbook --extra-vars '{ "host_name" : teleport-node , "teleport_type": "node" }' -i hosts install.yaml

以上で完成。

ウチの環境の場合

VPCを跨ぐために、TeleportクラスタをVPCごとに構築しています。クラスタを信頼し合うことで、統合的に管理できるようにするわけです。

すだちブログのサーバーを追加しましたが、VPCが違うので、新たなTeleportクラスタとして追加されてることが分かります。ホストネームはAWSが持つ標準のものが利用されているので分かりにくいかもしれませんが、すだちブログサーバー内の/etc/teleport.yamlにホストネームが記述されているので、そこを変更してサービス再起動すればホストネームは意図した名前に変更されます。

ローカルのターミナルからTeleport経由でアクセスする

sshは使わず、tshというコマンドを利用します。tshのバイナリがダウンロードできるので、落としてそのままおいしく利用させて頂きます。

Download Teleport OSS Edition
https://gravitational.com/teleport/download/

公式リファレンス
https://gravitational.com/teleport/docs/user-manual/

課題はまだまだあるが、OSSだから作ればいいのよ

過去のコマンド検索したい、本番環境にログインしたらSlack通知させたい、とあるコマンド叩いたらワークフロー回してSlackで承認ボタン押すまで実行させたくない、いろいろ思いつきますが、何もかもが実現できる万能アプリにはなっていません。だがしかし、OSSならば作ればいいのだ。

興味ある人、ユーザー会やりませんか!!

一部の企業では既にTeleportが活用されているとの話を何社かで聞きました。Githubのプルリク見てても、国内企業に所属している日本の方からのフィードバックが数多くあるのも見えています。しかしながら、まだまだ国内では認知度も低く、積極的にOSSコミットしてみんなで平和な世界を作ろうではないかということで、おれもおれもという方々でコミュニティを発足したいなと思っています。

まずはやってみたブログ、おもしろそうTweetなどじゃんじゃん上げてもらって、大量の鍵管理や権限管理から解放される世界を作って行きましょうー

ちなみに僕らは

GRAVIRATIONAL本体とコミュニケーションを取っているので、みなさんも参加頂いて、日本でも頑張るぞーっていうのをゴリ押ししたい次第です