シンジです。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に公開したので(動くのは確認しましたが責任は取れないけど)参考にして下さい。
- Teleport Renovation レポジトリ
https://github.com/cloudnative-co/teleport_renovation -
Terraformのドキュメント
https://github.com/cloudnative-co/teleport_renovation/tree/master/terraform -
Ansibleドキュメント
https://github.com/cloudnative-co/teleport_renovation/tree/master/ansible/documents -
Teleport Cluster ドキュメント
https://github.com/cloudnative-co/teleport_renovation/tree/master/ansible/documents/teleport_cluster -
Teleport Trusted Cluster ドキュメント
https://github.com/cloudnative-co/teleport_renovation/tree/master/ansible/documents/trusted_cluster
TeleportCluster – Ansibleパラメータドキュメント
-
TeleportCluster – Ansible パラメータ
https://github.com/cloudnative-co/teleport_renovation/blob/master/ansible/documents/teleport_cluster/PARAMETERS.md -
TeleportCluster – Ansible Auth パラメータ
https://github.com/cloudnative-co/teleport_renovation/blob/master/ansible/documents/teleport_cluster/AUTH.md -
TeleportCluster – Ansible Proxy パラメータ
https://github.com/cloudnative-co/teleport_renovation/blob/master/ansible/documents/teleport_cluster/PROXY.md -
TeleportCluster – Ansible Auth/Proxy パラメータ
https://github.com/cloudnative-co/teleport_renovation/blob/master/ansible/documents/teleport_cluster/AUTH-PROXY.md -
TeleportCluster – Ansible Node パラメータ
https://github.com/cloudnative-co/teleport_renovation/blob/master/ansible/documents/teleport_cluster/NODE.md
Trusted Cluster – Ansibleパラメータドキュメント
-
Trusted Cluster – Ansible 構成
https://github.com/cloudnative-co/teleport_renovation/blob/master/ansible/documents/trusted_cluster/CLUSTER.md -
Trusted Cluster Ansible パラメータ
https://github.com/cloudnative-co/teleport_renovation/blob/master/ansible/documents/trusted_cluster/PARAMETERS.md
既存のサーバーを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本体とコミュニケーションを取っているので、みなさんも参加頂いて、日本でも頑張るぞーっていうのをゴリ押ししたい次第です