LoginSignup
7
5

More than 5 years have passed since last update.

OpenShiftのデフォルトユーザーはなにができるか、なぜできるのか

Last updated at Posted at 2018-09-24

はじめに

OpenShift Originを最近触っています。
各種チュートリアルでは新しいProject(≒K8sのNamespace)を作成しているのですが
「そもそも人によってProjectの作成を制限するにはどうすれば良いのか」と疑問が浮かんだので権限周りを調べました。

  • デフォルトのユーザーはなにができるのか
  • なぜそれができるのか

を軸に調べていきます。

※デフォルトユーザーは「クラスタ管理者が、明示的に権限を与えていないユーザー」とします
※ClusterRole/ClusterRoleBindingのあたりの説明は行いません。一番下にリンクがありますのでそちらからどうぞ。

環境

OpenShift Origin 3.9
(ユーザー周りはLDAP連携等いろいろありますが、今回はhtpasswdで簡単にすませました)

なにができるか

権限の確認

早速適当なユーザーを作成し、何ができるかを確認してみます。

自分がどのような操作が可能なのかは、oc auth can-i --listで確認できます。
Command "can-i" is deprecated, use 'oc auth can-i'というメッセージが出てくるのですが、oc auth can-iの方には--listがなさそうです。誰か一覧を出す方法を教えてください。)

VERBS              NON-RESOURCE URLS        RESOURCE NAMES   API GROUPS                     RESOURCES
[get]              [/]                      []               []                             []
[get]              [/]                      []               []                             []
[get]              [/]                      []               []                             []
[get]              [/.well-known]           []               []                             []
[get]              [/.well-known]           []               []                             []
[get]              [/.well-known]           []               []                             []
[get]              [/.well-known/*]         []               []                             []
[get]              [/.well-known/*]         []               []                             []
[get]              [/.well-known/*]         []               []                             []
[get]              [/api]                   []               []                             []
[get]              [/api]                   []               []                             []
[get]              [/api]                   []               []                             []
[get]              [/api/*]                 []               []                             []
[get]              [/api/*]                 []               []                             []
[get]              [/api/*]                 []               []                             []
[get]              [/apis]                  []               []                             []
[get]              [/apis]                  []               []                             []
[get]              [/apis]                  []               []                             []
[get]              [/apis/*]                []               []                             []
[get]              [/apis/*]                []               []                             []
[get]              [/apis/*]                []               []                             []
[get]              [/healthz]               []               []                             []
[get]              [/healthz/*]             []               []                             []
[get]              [/oapi]                  []               []                             []
[get]              [/oapi]                  []               []                             []
[get]              [/oapi]                  []               []                             []
[get]              [/oapi/*]                []               []                             []
[get]              [/oapi/*]                []               []                             []
[get]              [/oapi/*]                []               []                             []
[get]              [/osapi]                 []               []                             []
[get]              [/osapi]                 []               []                             []
[get]              [/osapi]                 []               []                             []
[get]              [/osapi/]                []               []                             []
[get]              [/osapi/]                []               []                             []
[get]              [/osapi/]                []               []                             []
[get]              [/swagger-2.0.0.pb-v1]   []               []                             []
[get]              [/swagger-2.0.0.pb-v1]   []               []                             []
[get]              [/swagger-2.0.0.pb-v1]   []               []                             []
[get]              [/swagger.json]          []               []                             []
[get]              [/swagger.json]          []               []                             []
[get]              [/swagger.json]          []               []                             []
[get]              [/swaggerapi]            []               []                             []
[get]              [/swaggerapi]            []               []                             []
[get]              [/swaggerapi]            []               []                             []
[get]              [/swaggerapi/*]          []               []                             []
[get]              [/swaggerapi/*]          []               []                             []
[get]              [/swaggerapi/*]          []               []                             []
[get]              [/version]               []               []                             []
[get]              [/version]               []               []                             []
[get]              [/version]               []               []                             []
[get]              [/version/*]             []               []                             []
[get]              [/version/*]             []               []                             []
[get]              [/version/*]             []               []                             []
[create get]       []                       []               []                             [buildconfigs/webhooks]
[create get]       []                       []               [build.openshift.io]           [buildconfigs/webhooks]
[create]           []                       []               []                             [builds/docker]
[create]           []                       []               [build.openshift.io]           [builds/docker]
[create]           []                       []               []                             [builds/jenkinspipeline]
[create]           []                       []               [build.openshift.io]           [builds/jenkinspipeline]
[create]           []                       []               []                             [builds/optimizeddocker]
[create]           []                       []               [build.openshift.io]           [builds/optimizeddocker]
[create]           []                       []               []                             [builds/source]
[create]           []                       []               [build.openshift.io]           [builds/source]
[get list]         []                       []               []                             [clusterroles]
[get list]         []                       []               [authorization.openshift.io]   [clusterroles]
[get list watch]   []                       []               [rbac.authorization.k8s.io]    [clusterroles]
[get list watch]   []                       []               [servicecatalog.k8s.io]        [clusterserviceclasses]
[get list watch]   []                       []               [servicecatalog.k8s.io]        [clusterserviceplans]
[delete]           []                       []               []                             [oauthaccesstokens]
[delete]           []                       []               [oauth.openshift.io]           [oauthaccesstokens]
[delete]           []                       []               []                             [oauthauthorizetokens]
[delete]           []                       []               [oauth.openshift.io]           [oauthauthorizetokens]
[create list]      []                       []               []                             [projectrequests]
[create list]      []                       []               [project.openshift.io]         [projectrequests]
[list watch]       []                       []               []                             [projects]
[list watch]       []                       []               [project.openshift.io]         [projects]
[create]           []                       []               [authorization.k8s.io]         [selfsubjectaccessreviews]
[create]           []                       []               []                             [selfsubjectrulesreviews]
[create]           []                       []               [authorization.k8s.io]         [selfsubjectrulesreviews]
[create]           []                       []               [authorization.openshift.io]   [selfsubjectrulesreviews]
[get list]         []                       []               [storage.k8s.io]               [storageclasses]
[impersonate]      []                       []               [authentication.k8s.io]        [userextras/scopes.authorization.openshift.io]
[get]              []                       [~]              []                             [users]
[get]              []                       [~]              [user.openshift.io]            [users]

なにやら大量に出てきましたが、明示的に権限を付与せずともある程度の操作は可能なようです。
今回はRESOUCESに絞ってみていきたいと思います。
表にすると下記のような形に。(○は権限あり)

API GROUPS RESOURCES get list watch create delete impersonate
buildconfigs/webhooks
build.openshift.io buildconfigs/webhooks
builds/docker
build.openshift.io builds/docker
builds/jenkinspipeline
build.openshift.io builds/jenkinspipeline
builds/optimizeddocker
build.openshift.io builds/optimizeddocker
builds/source
build.openshift.io builds/source
clusterroles
authorization.openshift.io clusterroles
rbac.authorization.k8s.io clusterroles
servicecatalog.k8s.io clusterserviceclasses
servicecatalog.k8s.io clusterserviceplans
oauthaccesstokens
oauth.openshift.io oauthaccesstokens
oauthauthorizetokens
oauth.openshift.io oauthauthorizetokens
projectrequests
project.openshift.io projectrequests
projects
project.openshift.io projects
authorization.k8s.io selfsubjectaccessreviews
selfsubjectrulesreviews
authorization.k8s.io selfsubjectrulesreviews
authorization.openshift.io selfsubjectrulesreviews
storage.k8s.io storageclasses
authentication.k8s.io userextras/scopes.authorization.openshift.io
users
user.openshift.io users

usersはget可能になっていますが、ResouceNamesに[~]とあるように、自分自身の情報しか取得できません。
※他にもVerbはあるのですが、いったん出てきたものだけあげています。

OpenShift(Kubernetes)お馴染みのPodなどのリソースが表示されていないので、この状態では参照もできません。

ポイントとなるのはProjectRequestsCreateになっている点です。
このおかげでユーザーはProjectを作成することができます。

「なにができるのか」は上の表で概要はつかめるので、「なぜできるのか」を追っていきます。

なぜできるのか

ClusterRoleBindingの確認

上記をみる限り、自動でなにかしらのClusterRoleがBindingされているようなのでoc get clusterrolebinding.rbac -o wideで確認してみます。

Error from server (Forbidden): clusterrolebindings.rbac.authorization.k8s.io is forbidden: User "[ユーザ名]" cannot list clusterrolebindings.rbac.authorization.k8s.io at the cluster scope: User "[ユーザ名]" cannot list all clusterrolebindings.rbac.authorization.k8s.io in the cluster

おっと、デフォルトのユーザーのままだったので上記のようなエラーが出てしまいました。
表を見る限りClusterRoleの参照はできますが、ClusterRoleBindingの参照は(can-iで確認した通り)できません。
oc login -u [ユーザ名]で参照可能なユーザに変更し、再度コマンドを実行します。

NAME    AGE       ROLE                  USERS       GROUPS       SERVICEACCOUNTS
admin   6h        ClusterRole/admin                              openshift-infra/template-instance-controller
...

たくさん情報が表示されると思いますが、USERSのところには作成したユーザー名は表示されていませんでした。
その代わり、GROUPS欄にいくつかグループが表示されているのがわかると思います。

ざっくりした予想ですが、

  • ユーザーが自動的に属するグループがある
  • そのグループに対してClusterRoleがBindingされている

となっていそうです。

仮想グループ

OpenShiftでは、明示的に指定したグループのほかにも、仮想グループというものが自動的にプロビジョニングされ、ユーザに適用されます。

仮想グループ 説明
system:authenticated 認証されたすべてのユーザーに自動的に関連付けられます。
system:authenticated:oauth OAuthアクセストークンで認証されたすべてのユーザーに自動的に関連付けられます。
system:unauthenticated 認証されていないすべてのユーザーに自動的に関連付けられます。

今回は認証済みユーザについて調査しているので、system:authenticatedsystem:authenticated:oauth関連をみていけばわかりそうです。
先ほどのClusterRoleBindingの出力でGROUPSsystem:authenticatedまたはsystem:authenticated:oauthがあるものを抜き出してみます。

ClusterRoleBinding ClusterRole GROUPS
basic-users basic-user system:authenticated
cluster-status-binding cluster-status system:authenticated
self-access-reviewers self-access-reviewer system:authenticated
self-provisioners self-provisioner system:authenticated:oauth
servicecatalog-serviceclass-viewer-binding servicecatalog-serviceclass-viewer system:authenticated
system:basic-user system:basic-user system:authenticated
system:build-strategy-docker-binding system:build-strategy-docker system:authenticated
system:build-strategy-jenkinspipeline-binding system:build-strategy-jenkinspipeline system:authenticated
system:build-strategy-source-binding system:build-strategy-source system:authenticated
system:discovery system:discovery system:authenticated
system:discovery-binding system:discovery system:authenticated
system:oauth-token-deleters system:oauth-token-deleter system:authenticated
system:scope-impersonation system:scope-impersonation system:authenticated
system:webhooks system:webhook system:authenticated

ClusterRoleを確認していけば、どのようなResourceにどのようなVerbが許可されているのかわかります。
oc describe clusterrole.rbac [ClusterRole名]で確認し、権限の表に「どのClusterRoleが権限を担っているのか」を追加してみます。

API GROUPS RESOURCES get list watch create delete impersonate ClusterRole
buildconfigs/webhooks system:webhook
build.openshift.io buildconfigs/webhooks system:webhook
builds/docker system:build-strategy-jenkinspipeline
build.openshift.io builds/docker system:build-strategy-jenkinspipeline
builds/jenkinspipeline system:build-strategy-jenkinspipeline
build.openshift.io builds/jenkinspipeline system:build-strategy-jenkinspipeline
builds/optimizeddocker system:build-strategy-jenkinspipeline
build.openshift.io builds/optimizeddocker system:build-strategy-jenkinspipeline
builds/source system:build-strategy-source
build.openshift.io builds/source system:build-strategy-source
clusterroles basic-user
authorization.openshift.io clusterroles basic-user
rbac.authorization.k8s.io clusterroles basic-user
servicecatalog.k8s.io clusterserviceclasses servicecatalog-serviceclass-viewer
servicecatalog.k8s.io clusterserviceplans servicecatalog-serviceclass-viewer
oauthaccesstokens system:oauth-token-deleter
oauth.openshift.io oauthaccesstokens system:oauth-token-deleter
oauthauthorizetokens system:oauth-token-deleter
oauth.openshift.io oauthauthorizetokens system:oauth-token-deleter
projectrequests basic-user(list), self-provisioner(create)
project.openshift.io projectrequests basic-user(list), self-provisioner(create)
projects basic-user
project.openshift.io projects basic-user
authorization.k8s.io selfsubjectaccessreviews system:basic-user
selfsubjectrulesreviews basic-user
authorization.k8s.io selfsubjectrulesreviews system:basic-user
authorization.openshift.io selfsubjectrulesreviews basic-user
storage.k8s.io storageclasses basic-user
authentication.k8s.io userextras/scopes.authorization.openshift.io system:scope-impersonation
users basic-user
user.openshift.io users basic-user

ClusterStatussystem:discoveryはNon-Resource URLs関連のため、上記表には登場せず。

きれいに埋まりました。

まとめ

  • デフォルトのユーザーはなにができるのか
    表を参照
  • なぜそれができるのか
    ユーザーは自動的にOpenShiftの仮想グループに属しており、 その仮想グループにClusterRoleがBindingされているから。

さらなる疑問-TODO

「デフォルトユーザのままだと結局Podが作れない?」
「チュートリアルだとPodとかService作れるけど、どこかで権限が付与されている?」

Projectの作成時、Projectローカルなadmin権限が割り当てられてるような気がしています。

「can-iではProjectにlist可と書いてあるのに、defaultやkube-publicが見えない」
自分もよくわかりません。誰か教えてください...。
なにかKubernetesの基本的なところを見落としている気がします。

「どのResouceがなにをあらわしているのか。実際に運用するときに制限を検討した方がいいResourceは?」
Resourceは有名なものしかよくわかりません...どれを制限すべきかは難しいところです。

「クラスタ管理用、プロジェクト管理用、参照用みたいなClusterRoleプリセットはある?」
公式でいくつか用意されています。

ARCHITECTURE 4.2.4. Cluster Roles and Local Roles

ClusterRole 説明
admin プロジェクトマネージャーです。ローカルバインディングで使用されている場合、admin ユーザーにはプロジェクトのリソースを閲覧し、クォータを除くプロジェクトのすべてのリソースを変更する権限があります。
basic-user プロジェクトおよびユーザーについての基本的な情報を取得できるユーザーです。
cluster-admin プロジェクトですべてのアクションを実行できるスーパーユーザーです。ローカルバインディングでユーザーにバインドされる場合、クォータおよびプロジェクトのすべてのリソースに対するすべてのアクションに対するフルコントロールがあります。
cluster-status 基本的なクラスターのステータス情報を取得できるユーザーです。
edit プロジェクトのほとんどのオブジェクトを変更できるが、ロールまたはバインディングを表示したり、変更したりする機能を持たないユーザーです。
self-provisioner 独自のプロジェクトを作成できるユーザーです。
view 変更はできないが、プロジェクトでほとんどのオブジェクトを確認できるユーザーです。これらのユーザーはロールまたはバインディングを表示したり、変更したりできません。

「○○のcreateを"拒否"したい」
「どれを許可するか」が考え方のベースのはずなので、既につけられている権限をなにかしらで拒否するというのはできないような気がします。

「独自のClusterRoleを作りたい」

参考の「How to customize OpenShift RBAC permissions」をどうぞ。

「K8sとの違いはある?」

調べていませんが、多分そんなに違いはないと思いたいです...。

参考

非常に勉強になった記事。必読。

OpenShiftのRBACを完全に理解する - nekop's blog
How to customize OpenShift RBAC permissions - RedHat Developer Blog

おまけ

「Projectの作成を制限したい」というのは公式ドキュメントで方法が紹介されています。
https://docs.openshift.com/container-platform/3.9/admin_guide/managing_projects.html

oc adm policy remove-cluster-role-from-group self-provisioner system:authenticated:oauth

system:authenticated:oauth仮想グループからself-provisionerのRoleを削除しています。
(ちょっと乱暴な気も...「クラスタを更新したら元に戻ってた」とかありそう)

7
5
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
7
5