0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

分布式应用中使用Dapr时的安全特性和能力

马哥Linux运维 来源: k8s技术圈 作者: k8s技术圈 2022-10-17 11:18 次阅读

安全是 Dapr 的基础,本文我们将来说明在分布式应用中使用 Dapr 时的安全特性和能力,主要可以分为以下几个方面。

与服务调用和 pub/sub APIs 的安全通信

组件上的安全策略并通过配置进行应用。

运维操作安全实践。

状态安全,专注于静态的数据。

Dapr 通过服务调用 API 提供端到端的安全性,能够使用 Dapr 对应用程序进行身份验证并设置端点访问策略。

f0362302-4bd3-11ed-a3b6-dac502259ad0.png安全通信

服务调用范围访问策略

跨命名空间的服务调用

Dapr 应用程序可以被限定在特定的命名空间,以实现部署和安全,当然我们仍然可以在部署到不同命名空间的服务之间进行调用。默认情况下,服务调用支持通过简单地引用应用 ID (比如 nodeapp) 来调用同一命名空间内的服务:

localhost:3500/v1.0/invoke/nodeapp/method/neworder

服务调用还支持跨命名空间的调用,在所有受支持的托管平台上,Dapr 应用程序 ID 符合包含目标命名空间的有效 FQDN 格式,可以同时指定:

应用 ID (如 nodeapp)

应用程序运行的命名空间(production)。

比如在 production 命名空间中的 nodeapp 应用上调用 neworder 方法,则可以使用下面的方式:

localhost:3500/v1.0/invoke/nodeapp.production/method/neworder

当使用服务调用在命名空间中调用应用程序时,我们可以使用命名空间对其进行限定,特别在 Kubernetes 集群中的跨命名空间调用是非常有用的。

为服务调用应用访问控制列表配置

访问控制策略在配置文件中被指定,并被应用于被调用应用程序的 Dapr sidecar,对被调用应用程序的访问是基于匹配的策略动作,你可以为所有调用应用程序提供一个默认的全局动作,如果没有指定访问控制策略,默认行为是允许所有调用应用程序访问被调用的应用程序。

在具体学习访问控制策略配置之前,我们需要先了解两个概念:

TrustDomain - “信任域”是管理信任关系的逻辑组。每个应用程序都分配有一个信任域,可以在访问控制列表策略规范中指定。如果未定义策略规范或指定了空的信任域,则使用默认值 public,该信任域用于在 TLS 证书中生成应用程序的身份。

App Identity - Dapr 请求 sentry 服务为所有应用程序生成一个 SPIFFE id,这个 id 附加在 TLS 证书中。SPIFFE id 的格式为:spiffe:///ns//,对于匹配策略,调用应用的信任域、命名空间和应用 ID 值从调用应用的 TLS 证书中的 SPIFFE id 中提取,这些值与策略规范中指定的信任域、命名空间和应用 ID 值相匹配。如果这三个都匹配,则更具体的策略将进一步匹配。

访问控制策略会遵循如下所示的一些规则:

如果未指定访问策略,则默认行为是允许所有应用访问被调用应用上的所有方法

如果未指定全局默认操作且未定义应用程序特定策略,则将空访问策略视为未指定访问策略,并且默认行为是允许所有应用程序访问被调用应用程序上的所有方法

如果未指定全局默认操作,但已定义了一些特定于应用程序的策略,则会采用更安全的选项,即假设全局默认操作拒绝访问被调用应用程序上的所有方法

如果定义了访问策略并且无法验证传入的应用程序凭据,则全局默认操作将生效

如果传入应用的信任域或命名空间与应用策略中指定的值不匹配,则应用策略将被忽略并且全局默认操作生效

下面是一些使用访问控制列表进行服务调用的示例场景。

场景 1:拒绝所有应用程序的访问,除非 trustDomain = public、namespace = default、appId = app1,使用如下所示的配置,允许所有 appId = app1 的调用方法,并拒绝来自其他应用程序的所有其他调用请求。

apiVersion:dapr.io/v1alpha1
kind:Configuration
metadata:
name:appconfig
spec:
accessControl:
defaultAction:deny
trustDomain:"public"
policies:
-appId:app1
defaultAction:allow
trustDomain:"public"
namespace:"default"

场景 2:拒绝访问除 trustDomain = public、namespace = default、appId = app1、operation = op1 之外的所有应用程序,使用此配置仅允许来自 appId = app1 的方法 op1,并且拒绝来自所有其他应用程序的所有其他方法请求,包括 app1 上的其他方法。

apiVersion:dapr.io/v1alpha1
kind:Configuration
metadata:
name:appconfig
spec:
accessControl:
defaultAction:deny
trustDomain:"public"
policies:
-appId:app1
defaultAction:deny
trustDomain:"public"
namespace:"default"
operations:
-name:/op1
httpVerb:["*"]
action:allow

场景 3:拒绝对所有应用程序的访问,除非 HTTP 的特定 verb 和 GRPC 的操作匹配,使用如下所示的配置,仅允许以下场景访问,并且来自所有其他应用程序的所有其他方法请求(包括 app1 或 app2 上的其他方法)都会被拒绝。

trustDomain = public、namespace = default、appID = app1、operation = op1、http verb = POST/PUT

trustDomain = “myDomain”、namespace = “ns1”、appID = app2、operation = op2 并且应用程序协议是 GRPC,仅允许来自 appId = app1 的方法 op1 上的 POST/PUT 请求以及来自所有其他应用程序的所有其他方法请求,包括 app1 上的其他方法,被拒绝

apiVersion:dapr.io/v1alpha1
kind:Configuration
metadata:
name:appconfig
spec:
accessControl:
defaultAction:deny
trustDomain:"public"
policies:
-appId:app1
defaultAction:deny
trustDomain:"public"
namespace:"default"
operations:
-name:/op1
httpVerb:["POST","PUT"]
action:allow
-appId:app2
defaultAction:deny
trustDomain:"myDomain"
namespace:"ns1"
operations:
-name:/op2
action:allow

场景 4:允许访问除 trustDomain = public、namespace = default、appId = app1、operation = /op1/* 所有 http verb 之外的所有方法。

apiVersion:dapr.io/v1alpha1
kind:Configuration
metadata:
name:appconfig
spec:
accessControl:
defaultAction:allow
trustDomain:"public"
policies:
-appId:app1
defaultAction:allow
trustDomain:"public"
namespace:"default"
operations:
-name:/op1/*
httpVerb:["*"]
action:deny

场景 5:允许访问 trustDomain = public、namespace = ns1、appId = app1 的所有方法并拒绝访问 trustDomain = public、namespace = ns2、appId = app1 的所有方法,此场景展示了如何指定具有相同应用 ID 但属于不同命名空间的应用。

apiVersion:dapr.io/v1alpha1
kind:Configuration
metadata:
name:appconfig
spec:
accessControl:
defaultAction:allow
trustDomain:"public"
policies:
-appId:app1
defaultAction:allow
trustDomain:"public"
namespace:"ns1"
-appId:app1
defaultAction:deny
trustDomain:"public"
namespace:"ns2"

场景 6:允许访问除 trustDomain = public、namespace = default、appId = app1、operation = /op1/**/a、所有 http 动词之外的所有方法。

apiVersion:dapr.io/v1alpha1
kind:Configuration
metadata:
name:appconfig
spec:
accessControl:
defaultAction:allow
trustDomain:"public"
policies:
-appId:app1
defaultAction:allow
trustDomain:"public"
namespace:"default"
operations:
-name:/op1/**/a
httpVerb:["*"]
action:deny

下面我们通过一个具体的示例来展示下访问控制策略的使用,同样还是使用 quickstarts 示例中的 hello-world 进行说明。

gitclone[-b]https://github.com/dapr/quickstarts.git
cdquickstarts/tutorials/hello-world/node
f04e6200-4bd3-11ed-a3b6-dac502259ad0.jpghello world

该示例应用中包含一个 python 应用去调用一个 node.js 应用程序,访问控制列表依靠 Dapr Sentry 服务来生成带有 SPIFFE id 的 TLS 证书进行认证,这意味着 Sentry 服务必须在本地运行或部署到你的托管环境,比如 Kubernetes 集群。

下面的 nodeappconfig 例子显示了如何拒绝来自 pythonapp 的 neworder 方法的访问,其中 pythonapp 是在 myDomain 信任域和 default 命名空间中,nodeapp 在 public 公共信任域中。

#nodeappconfig.yaml
apiVersion:dapr.io/v1alpha1
kind:Configuration
metadata:
name:nodeappconfig
spec:
tracing:
samplingRate:"1"
accessControl:
defaultAction:allow
trustDomain:"public"
policies:
-appId:pythonapp
defaultAction:allow
trustDomain:"myDomain"
namespace:"default"
operations:
-name:/neworder
httpVerb:["POST"]
action:deny
#pythonappconfig.yaml
apiVersion:dapr.io/v1alpha1
kind:Configuration
metadata:
name:pythonappconfig
spec:
tracing:
samplingRate:"1"
accessControl:
defaultAction:allow
trustDomain:"myDomain"

接下来我们先在本地自拓管模式下来使用启用访问策略配置,首先需要在启用 mTLS 的情况下在本地运行 Sentry 服务,我们可以直接在 https://github.com/dapr/dapr/releases 页面下载对应的 sentry 二进制文件,比如我们这里是 Mac M1,则可以使用下面的命令直接下载:

#wgethttps://github.91chi.fun/https://github.com/dapr/dapr/releases/download/v1.8.4/sentry_darwin_arm64.tar.gz
$wgethttps://github.com/dapr/dapr/releases/download/v1.8.4/sentry_darwin_arm64.tar.gz
$tar-xvfsentry_darwin_arm64.tar.gz

然后为 Sentry 服务创建一个目录以创建自签名根证书:

$mkdir-p$HOME/.dapr/certs

使用以下命令在本地运行 Sentry 服务:

$./sentry--issuer-credentials$HOME/.dapr/certs--trust-domaincluster.local
INFO[0000]startingsentrycertificateauthority--version1.8.4--commit18575823c74318c811d6cd6f57ffac76d5debe93instance=MBP2022.localscope=dapr.sentrytype=logver=1.8.4
INFO[0000]configuration:[port]:50001,[castore]:default,[allowedclockskew]:15m0s,[workloadcertttl]:24h0m0sinstance=MBP2022.localscope=dapr.sentry.configtype=logver=1.8.4
WARN[0000]loadingdefaultconfig.couldn'tfindconfigname:daprsystem:statdaprsystem:nosuchfileordirectoryinstance=MBP2022.localscope=dapr.sentrytype=logver=1.8.4
INFO[0000]startingwatchonfilesystemdirectory:/Users/cnych/.dapr/certsinstance=MBP2022.localscope=dapr.sentrytype=logver=1.8.4
INFO[0000]certificateauthorityloadedinstance=MBP2022.localscope=dapr.sentrytype=logver=1.8.4
INFO[0000]rootandissuercertsnotfound:generatingselfsignedCAinstance=MBP2022.localscope=dapr.sentry.catype=logver=1.8.4
#......
INFO[0000]sentrycertificateauthorityisrunning,protectingya'llinstance=MBP2022.localscope=dapr.sentrytype=logver=1.8.4

运行成功后 Sentry 服务将在指定目录中创建根证书,可以通过如下所示的命令来配置环境变量指定相关证书路径:

exportDAPR_TRUST_ANCHORS=`cat$HOME/.dapr/certs/ca.crt`
exportDAPR_CERT_CHAIN=`cat$HOME/.dapr/certs/issuer.crt`
exportDAPR_CERT_KEY=`cat$HOME/.dapr/certs/issuer.key`
exportNAMESPACE=default

然后我们就可以运行 daprd 为启用了 mTLS 的 node.js 应用启动 Dapr sidecar,并引用本地的 Sentry 服务:

daprd--app-idnodeapp--dapr-grpc-port50002-dapr-http-port3501-metrics-port9091--log-leveldebug--app-port3000--enable-mtls--sentry-addresslocalhost:50001--confignodeappconfig.yaml

上面的命令我们通过 --enable-mtls 启用了 mTLS,通过 --config 指定了上面的 nodeappconfig.yaml 这个配置文件。

然后启动 node.js 应用:

$cdnode&&yarn
$nodeapp.js

NodeApplisteningonport3000!

同样的方式在另外的终端中设置环境变量:

exportDAPR_TRUST_ANCHORS=`cat$HOME/.dapr/certs/ca.crt`
exportDAPR_CERT_CHAIN=`cat$HOME/.dapr/certs/issuer.crt`
exportDAPR_CERT_KEY=`cat$HOME/.dapr/certs/issuer.key`
exportNAMESPACE=default

然后运行 daprd 为启用了 mTLS 的 python 应用启动 Dapr sidecar,并引用本地的 Sentry 服务:

daprd--app-idpythonapp--dapr-grpc-port50003--metrics-port9092--log-leveldebug--enable-mtls--sentry-addresslocalhost:50001--configpythonappconfig.yaml

在重新开一个终端直接启动 Python 应用即可:

$cdpython&&pip3install-rrequirements.txt
$python3app.py

HTTP403=>{"errorCode":"ERR_DIRECT_INVOKE","message":"failtoinvoke,id:nodeapp,err:rpcerror:code=PermissionDenieddesc=accesscontrolpolicyhasdeniedaccesstoappid:pythonappoperation:neworderverb:POST"}
HTTP403=>{"errorCode":"ERR_DIRECT_INVOKE","message":"failtoinvoke,id:nodeapp,err:rpcerror:code=PermissionDenieddesc=accesscontrolpolicyhasdeniedaccesstoappid:pythonappoperation:neworderverb:POST"}
#......

由于 nodeappconfig 文件中我们配置了对 /neworder 接口的 POST 拒绝操作,所以应该会在 python 应用程序命令提示符中看到对 node.js 应用程序的调用失败,如果我们将上面的 nodeappconfig 配置中的 action: deny 修改为 action: allow 并重新运行应用程序,然后我们应该会看到此调用成功。

对于 Kubernetes 模式则更简单,只需要创建上述配置文件 nodeappconfig.yaml 和 pythonappconfig.yaml 并将其应用于 Kubernetes 集群,然后在应用的注解中添加 dapr.io/config: "pythonappconfig" 来指定配置即可开启服务访问控制。

annotations:
dapr.io/enabled:"true"
dapr.io/app-id:"pythonapp"
dapr.io/config:"pythonappconfig"

Pub/sub 主题范围访问策略

对于 Pub/sub 组件,你可以限制允许哪些主题类型和应用程序发布和订阅特定主题。

命名空间或组件范围可用于限制组件对特定应用程序的访问,这些添加到组件的应用程序范围仅限制具有特定 ID 的应用程序能够使用该组件。如下所示显示了如何将两个启用 Dapr 的应用程序(应用程序 ID 为 app1 和 app2)授予名为 statestore 的 Redis 组件,该组件本身位于 production 命名空间中:

apiVersion:dapr.io/v1alpha1
kind:Component
metadata:
name:statestore
namespace:production
spec:
type:state.redis
version:v1
metadata:
-name:redisHost
value:redis-master:6379
scopes:
-app1
-app2

除了这个通用组件的 scopes 范围之外,发布/订阅组件还可以限制以下内容:

可以使用哪些主题(发布或订阅)

允许哪些应用发布到特定主题

允许哪些应用订阅特定主题

这被称为发布/订阅主题范围。我们可以为每个发布/订阅组件定义发布/订阅范围,比如你可能有一个名为 pubsub 的 pub/sub 组件,它具有一组范围,另一个 pubsub2 具有另外不同的范围。

示例 1:主题访问范围。如果你的主题包含敏感信息并且仅允许你的应用程序的子集发布或订阅这些信息,那么限制哪些应用程序可以发布/订阅主题可能会很有用。如下以下是三个应用程序和三个主题的示例:

apiVersion:dapr.io/v1alpha1
kind:Component
metadata:
name:pubsub
spec:
type:pubsub.redis
version:v1
metadata:
-name:redisHost
value:"localhost:6379"
-name:redisPassword
value:""
-name:publishingScopes
value:"app1=topic1;app2=topic2,topic3;app3="
-name:subscriptionScopes
value:"app2=;app3=topic1"

这里我们设置了 publishingScopes 和 subscriptionScopes 两个属性,分别用于配置发布范围和订阅范围。要拒绝应用发布到任何主题,请将主题列表留空,比如我们这里配置的 app1=topic1;app2=topic2,topic3;app3=,其中的 app3= 就表示该应用不允许发布到任何主题上去。

根据我们的配置下表显示了允许哪些应用程序发布到主题中:

Topic1 Topic2 Topic3
app1 X
app2 X X
app3

下表显示了哪些应用程序可以订阅主题:

Topic1 Topic2 Topic3
app1 X X X
app2
app3 X

注意:如果未列出应用程序(例如,subscriptionScopes 中的 app1),则允许它订阅所有主题。因为不使用 allowedTopics 并且 app1 没有任何订阅范围,所以它也可以使用上面未列出的其他主题。

示例 2:限制允许的主题。如果 Dapr 应用程序向其发送消息,则会创建一个主题,在某些情况下,应管理此主题的创建。例如:

Dapr 应用程序中生成主题名称的错误可能导致创建无限数量的主题

精简主题名称和总数,防止主题无限增长

在这些情况下,可以使用 allowedTopics 属性进行配置,以下就是三个允许主题的示例:

apiVersion:dapr.io/v1alpha1
kind:Component
metadata:
name:pubsub
spec:
type:pubsub.redis
version:v1
metadata:
-name:redisHost
value:"localhost:6379"
-name:redisPassword
value:""
-name:allowedTopics
value:"topic1,topic2,topic3"

示例 3:组合 allowedTopics 和范围。有时你想结合这两个范围,因此只有一组固定的允许主题并为某些应用程序指定范围。以下是三个应用程序和两个主题的示例:

apiVersion:dapr.io/v1alpha1
kind:Component
metadata:
name:pubsub
spec:
type:pubsub.redis
version:v1
metadata:
-name:redisHost
value:"localhost:6379"
-name:redisPassword
value:""
-name:allowedTopics
value:"A,B"
-name:publishingScopes
value:"app1=A"
-name:subscriptionScopes
value:"app1=;app2=A"

注意这里我们没有列出第三个应用程序,如果没有在范围内指定应用程序,则允许它使用所有主题。

根据上面的配置下表显示了允许哪个应用程序发布到主题中:

A B C
app1 X
app2 X X
app3 X X

下表显示了允许哪个应用程序订阅主题:

A B C
app1
app2 X
app3 X X

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • API
    API
    +关注

    关注

    2

    文章

    1381

    浏览量

    60988
  • 应用程序
    +关注

    关注

    37

    文章

    3133

    浏览量

    56372

原文标题:Dapr 安全性之访问控制策略

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    分布式软件系统

    三个特点:分布性、通信性和稳健性。 分布式文件系统具有执行远程文件存取的能力,并以透明方式对分布在网络上的文件进行管理和存取。 分布式数据库
    发表于 07-22 14:53

    分布式能源有哪些优势? 超级电容

    `分布式能源有哪些优势?由于可以提高能源利用率和供电安全性,实现按需供能以及为用户提供更多选择,分布式能源系统成为全球电力行业和能源产业的重要发展方向。当前,由于一次能源逐渐短缺,环境压力越来越大
    发表于 04-27 11:40

    分布式光伏发电安全

    作为更为贴近人民日常生活的分布式光伏发电与光伏地面电站相比,其安全性如何呢?请看南京研旭在本文内的具体介绍。 从使用的角度,分布式光伏发电特有的优点:1、分布式光伏发电可实现就近供电,
    发表于 10-12 15:35

    分布式系统的优势是什么?

    当讨论分布式系统时,我们面临许多以下这些形容词所描述的 同类型: 分布式的、删络的、并行的、并发的和分散的。分布式处理是一个相对较新的领域,所以还没有‘致的定义。与顺序计算相比、并行的、并发的和
    发表于 03-31 09:01

    HarmonyOS应用开发-分布式设计

    设计理念HarmonyOS 是面向未来全场景智慧生活方式的分布式操作系统。对消费者而言,HarmonyOS 将生活场景中的各类终端进行能力整合,形成“One Super Device”,以实现
    发表于 09-22 17:11

    HarmonyOS分布式数据库,为啥这么牛?

    使用本地数据一样处理,为开发者们提供便捷、高效和安全的数据管理能力,大大降低了应用开发者实现数据分布式访问的门槛。 同时,由于在系统层面实现了这样的功能,可以结合系统资源调度,大大提升跨设备数据远程
    发表于 11-19 15:38

    分布式软总线子系统

    分布式软总线子系统简介目录约束使用涉及仓简介设备通信方式多种多样(USB/WIFI/BT等),不同通信方式使用差异很大且繁琐,同时通信链路的融合共享和冲突无法处理,通信安全问题也不好保证。本项
    发表于 04-23 17:12

    计及分布式发电的配电网潮流计算 精选资料分享

    分布式电源的并网对配电系统的稳定性有着重要影响。分析了几种常见的分布式电源(DG),建立潮流模型,采用前推回代法进行潮流计算。鉴于前推回代法处理PV 节点的能力较弱,对PV 节点进行无功补偿修正
    发表于 07-12 07:30

    各种分布式电源的电气特性

    特性(主要包括电压V、电流I、有功P、无功Q)不同,需要的建模方式也有所不同。1.常见的分布式电源2.分布式电源建模燃料电池是电力电子变换器接口型的潮流计算模型,它在潮流计算里面可以使用pq,pq节点来进行处理。是吗?是pq吗?
    发表于 07-12 07:54

    OpenHarmony 2.2 Beta2 版本发布,具备典型的分布式能力和媒体类产品开发能力

    多家公司推出了基于 OpenHarmony 项目开发的智能终端,如智能手表、智能家电、智慧屏等。亮点特性/核心特性OpenHarmony 2.2 Beta2 版本关键特性:1、支持分布式
    发表于 08-09 15:15

    HDC2021技术分论坛:分布式调试、调优能力解决方案

    应用的调试问题,DevEco Studio提供了分布式调试、调优能力解决方案,解决开发者面临的调试不连续、操作繁琐、功能和性能异常难定位等众多痛点问题。下面让我们先来一睹为快。注:本文涉及
    发表于 11-22 17:17

    HDC2021技术分论坛:如何高效完成HarmonyOS分布式应用测试?

    问题和UX显示问题占比率高达85%。图1 HarmonyOS分布式应用上架问题分析分布式应用测试效率低:分布式应用涉及多台设备协同时,由于没有统一的测试框架,使得分布式应用测试效率较低
    发表于 12-13 14:55

    如何高效完成HarmonyOS分布式应用测试?

    问题和UX显示问题占比率高达85%。图1 HarmonyOS分布式应用上架问题分析分布式应用测试效率低:分布式应用涉及多台设备协同时,由于没有统一的测试框架,使得分布式应用测试效率较低
    发表于 12-13 18:07

    分布式软总线实现近场设备间统一的分布式通信管理能力如何?

    现实中多设备间通信方式多种多样(WIFI、蓝牙等),不同的通信方式使用差异大,导致通信问题多;同时还面临设备间通信链路的融合共享和冲突无法处理等挑战。那么分布式软总线实现近场设备间统一的分布式通信管理能力如何呢?
    发表于 03-16 11:03

    OpenHarmony 3.1 Beta版本关键特性解析——分布式DeviceProfile

    能够相互感知,进而整合成一个超级终端。从而实现设备与设备之间取长补短、相互帮助,为用户提供自然流畅的分布式体验。那么超级终端中,设备的能力和状态如何管理?设备之间如何进行信息协同?要回答这些问题,就不
    发表于 04-25 11:14