使用 NGINX Unit 实施应用隔离
原文作者:Artem Konev - Senior Technical Writer
原文链接:使用 NGINX Unit 实施应用隔离
转载来源:NGINX 中文官网
NGINX 唯一中文官方社区 ,尽在 nginx.org.cn
NGINX Unit 特性集的最新动态之一是支持应用隔离,该特性于 1.11.0 版中引入,通过 Linux 命名空间实施。
下面我们先简单回顾一下 Linux 命名空间:它本质上是一种内核机制,支持一个进程组将多种系统资源与其他进程组共享的资源分开共享。内核能够确保命名空间中的进程仅访问分配给该命名空间的资源。尽管两个不同命名空间中的进程可以共享一些资源,但其他资源对于另一个命名空间中的进程“不可见”。可在命名空间中隔离的资源类型因操作系统而异,包括进程和用户 ID、进程间通信实体、文件系统中的挂载点、网络对象等。
听起来有点乏味?也许如此,特别是在您不了解操作系统技术的情况下。但命名空间是容器化变革背后的关键因素之一,在单个操作系统实例中隔离应用进程可实现在容器中运行应用所需的关键安全和扩展机制。
想法
现在我们已经确定命名空间可能是个好东西,但 NGINX Unit 拿它有何用呢?在进一步阐释前,我们先概括介绍相关背景信息,了解一下 Tiago 本人的想法:
“我正在研究更好的方法以有效监控和拦截来自应用的流量。闲暇之余,我一直在研究 NGINX Unit 的内部机制,并认为进程隔离可能非常适用。但是,我还不确定是否是最佳方案。之前,我曾考虑 eBPF并研究它如何在内核级别重定向数据包,但后来我有了不同的想法。由于 NGINX Unit 以类似于容器运行时的方式运行并管理应用,那么如果我们为 NGINX Unit 添加应用隔离支持并使用它代替运行时,将会怎样?这一想法与 NGINX Unit 团队未来构思设计之一不谋而合。
在集群中,容器运行时启动和停止应用,因此我们了解集群中运行的一切。NGINX Unit 架构不仅做了同样的事情,而且还默认实施流量监控和拦截:到达应用的唯一途径是 NGINX Unit 的共享内存模型。值得注意的是,我们甚至能够隔离网络,类似于跳过容器内的接口设置,但应用仍可通过与 NGINX Unit 共享内存来与外界通信,而不会遭遇任何代价高昂的网络攻击。”
配置
从配置的角度来看,一切都离不开全新 isolation 对象,它定义了应用对象中的命名空间相关设置。
isolation 对象中的命名空间选项取决于系统,因为可隔离到命名空间的资源类型因操作系统而异。下面是为应用创建单独的用户 ID 和挂载点命名空间的基本示例:
{"applications": { "isolation_app": { "type": "external","executable": "/tmp/go-app","isolation": { "namespaces": { "credential": true,"mount": "true"}}}}
}
目前,NGINX Unit 支持配置 Linux 内核支持的 7 种命名空间隔离类型中的 6 种。相应配置选项为 cgroup、credential、pid、mount、network 及 uname。暂不支持最后一个类型 ipc。
默认情况下,禁用所有隔离类型(选项设置为 false),这意味着应用驻留在 NGINX Unit 命名空间中。当您通过将其选项设置为 true 来为应用启用特定隔离类型时,NGINX Unit 将为该应用创建这一类型的单独命名空间。例如,除了自身有一个单独的 mount 或 credential 命名空间外,应用还可与 NGINX Unit 位于同一命名空间。
有关 isolation 对象中选项的更多详细信息,请参阅 NGINX Unit 文档。
注:在撰写本文时,所有应用均需使用与 NGINX Unit 相同的 ipc 命名空间;此为共享内存机制要求。您可将 ipc 选项添加至配置中,但其设置无效。这一要求可能会在未来版本中发生变化。
用户和组 ID 映射
NGINX Unit 中的应用隔离包括支持 UID 和 GID 映射,如果启用 credential 隔离(这意味着您的应用在单独的凭证命名空间中运行),则可对其进行配置。您可以将应用命名空间(我们称之为 “container(容器)命名空间”)中的一系列 ID 映射至该应用父进程凭证命名空间(我们称之为 “host(主机)命名空间”)中的相同长度 ID 范围。
例如,假设您的一款应用采用非特权用户凭证运行,并启用了 credential 隔离,以便为该应用创建一个容器命名空间。NGINX Unit 支持您将主机命名空间中非特权用户的 UID 映射到容器命名空间中的 UID 0 (root)。根据设计,任何命名空间中取值为 0 的 UID 在该命名空间中拥有全部权限,而其在主机命名空间中映射对应 UID 的权限仍然受限。因此,该应用似乎拥有 root 功能,但仅可用于其命名空间内的资源。GID 映射也是如此。
此处,我们将主机命名空间中从 UID 500 开始的 10 项 UID 范围值映射到容器命名空间中从 UID 0 开始的 UID 范围值(主机:500-509,容器:0-9)。同样,我们将主机命名空间中从 GID 1000 开始的 20 项 GID 范围值映射到容器命名空间中从 GID 0 开始的范围值(主机:1000-1019,容器:0-19):
{"applications": { "isolation_app": { "type": "external","executable": "/bin/app","isolation": { "namespaces": { "credential": true},"uidmap": [ { "container": 0,"host": 500,"size": 10}],"gidmap": [ { "container": 0,"host": 1000,"size": 20}]}}}
}
如果您未创建显式 UID 和 GID 映射,默认情况下,主机命名空间中非特权 NGINX Unit 进程的当前有效 UID (EUID) 将映射到容器命名空间中的 root UID。另请注意,仅当主机操作系统支持用户命名空间时,UID/GID 映射才可用。说到这里,让我们继续了解一下应用隔离对 NGINX Unit 中运行的应用的影响。
入门:基本应用隔离
下面我们从基础开始,了解该特性运行时的行为。为此,我们将采用我们官方存储库中的一个 Go 应用(在测试新版本时运行):
package mainimport ("encoding/json""fmt""net/http""nginx/unit""os""strconv"
)type (NS struct {USER uint64PID uint64IPC uint64CGROUP uint64UTS uint64MNT uint64NET uint64}Output struct {PID intUID intGID intNS NS}
)func abortonerr(err error) {if err != nil {panic(err)}
}func getns(nstype string) uint64 {// readlink returns: [nstype]:[4026531835]str, err := os.Readlink(fmt.Sprintf("/proc/self/ns/%s", nstype))if err != nil {return 0}str = str[len(nstype)+2:]str = str[:len(str)-1]val, err := strconv.ParseUint(str, 10, 64)abortonerr(err)return val
}func handler(w http.ResponseWriter, r *http.Request) {pid := os.Getpid()out := &Output{PID: pid,UID: os.Getuid(),GID: os.Getgid(),NS: NS{PID: getns("pid"),USER: getns("user"),MNT: getns("mnt"),IPC: getns("ipc"),UTS: getns("uts"),NET: getns("net"),CGROUP: getns("cgroup"),},}data, err := json.Marshal(out)if err != nil {w.WriteHeader(http.StatusInternalServerError)return}w.Write(data)
}func main() {http.HandleFunc("/", handler)unit.ListenAndServe(": 7080", nil)
}
这段代码使用应用进程和命名空间 ID 的 JSON 格式清单响应请求,枚举 /proc/self/ns/ 目录的内容。下面我们在 NGINX Unit 中配置应用,暂时忽略 isolation 对象:
{ "listeners": { "*:8080": { "pass": "applications/go-app"}},"applications": { "go-app": { "type": "external","executable": "/tmp/go-app"}}
}
来自运行中应用实例的 HTTP 响应:
$ curl -X GET http://localhost:8080{ "PID": 5778,"UID": 65534,"GID": 65534,"NS": { "USER": 4026531837,"PID": 4026531836,"IPC": 4026531839,"CGROUP": 4026531835,"UTS": 4026531838,"MNT": 4026531840,"NET": 4026531992}
}
现在我们添加 isolation 对象,以启用应用隔离。隔离机制需要重启应用才可生效。NGINX Unit 将在幕后执行这一任务,因此从最终用户的角度来看,更新非常透明。
{ "listeners": { "*:8080": { "pass": "applications/go-app"}},"applications": { "go-app": { "type": "external","user": "root","executable": "/tmp/go-app","isolation": { "namespaces": { "cgroup": true,"credential": true,"mount": true,"network": true,"pid": true,"uname": true},"uidmap": [ { "host": 1000,"container": 0,"size": 1000}],"gidmap": [ { "host": 1000,"container": 0,"size": 1000}]}}}
}
请注意,user 选项设置为 root。启用映射到容器命名空间中的 UID/GID 0 需要执行这一设置。
我们再次发出命令:
$ curl -X GET http://localhost:8080{ "PID": 1,"UID": 0,"GID": 0,"NS": { "USER": 4026532180,"PID": 4026532184,"IPC": 4026531839,"CGROUP": 4026532185,"UTS": 4026532183,"MNT": 4026532181,"NET": 4026532187}
}
我们现已启用应用隔离,命名空间 ID 已变更 — 它们现在是容器命名空间中的 ID,而非主机命名空间中的 ID。唯一保持不变的是 IPC,原因如上所述。
深入探究:网络应用隔离
为进行深入了解,下面我们将探讨应用隔离对网络的实际影响,这对 Web 应用而言非常重要。我们为此选择的工具是 nsenter,它适用于 NGINX Unit 支持的许多操作系统发行版。该实用程序允许我们在进程命名空间内运行任意命令,我们将使用它来演示由前面配置的同一 Go 应用 isolation 对象中的不同设置引起的变化。首先,我们找出主机 PID:
更多代码详情查看NGINX社区官网
确定 PID 后,我们可以进入容器命名空间并查看其内部组成
请注意,仅环回接口可用;但该应用完全能够通过 NGINX Unit 处理外部 HTTP 请求。接下来,我们将从配置的命名空间列表中删除 network 选项,以查看禁用网络隔离的应用的最终网络接口配置
然后,我们重复执行上述相同步骤
现在还有应用进程在启动时沿用 NGINX Unit 的接口 (eth0)。
NGINX 唯一中文官方社区 ,尽在 nginx.org.cn
更多 NGINX 相关的技术干货、互动问答、系列课程、活动资源: 开源社区官网 | 微信公众号
相关文章:
使用 NGINX Unit 实施应用隔离
原文作者:Artem Konev - Senior Technical Writer 原文链接:使用 NGINX Unit 实施应用隔离 转载来源:NGINX 中文官网 NGINX 唯一中文官方社区 ,尽在 nginx.org.cn NGINX Unit 特性集的最新动态之一是支持应用隔离,该特…...
2023/09/12 qtc++
实现一个图形类(Shape) ,包含受保护成员属性:周长、面积, 公共成员函数:特殊成员函数书写 定义一个圆形类(Circle) ,继承自图形类,包含私有属性:半径 公共成员函数:特殊成员函数…...
全科医学科常用评估量表汇总,建议收藏!
根据全科医学科医生的量表使用情况,笔者整理了10个常用的全科医学科量表,可在线评测直接出结果,可转发使用,可生成二维码使用,可创建项目进行数据管理,有需要的小伙伴赶紧收藏! 日常生活能力量表…...
了解消息中间件的基础知识
为什么要使用消息中间件? 解耦:消息中间件可以使不同的应用程序通过解耦的方式进行通信,减少系统间的依赖关系提供异步通信:消息中间件可以实现异步消息传递,提高系统的响应性能。流量削峰:消息中间件可以…...
【linux】Linux wps字体缺失、加粗乱码解决
解决wps字体缺失问题 1、下载字体包 git clone https://github.com/iamdh4/ttf-wps-fonts.git2、创建单独放置字体的目录 mkdir /usr/share/fonts/wps-fonts3、复制字体到系统目录下 cp ttf-wps-fonts/* /usr/share/fonts/wps-fonts4、修改字体权限 chmod 644 /usr/share/f…...
每日两题 103二叉树的锯齿形层序遍历(数组) 513找树左下角的值(队列)
103 题目 103 给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。 示例 1: 输入:root [3,9,…...
ROS2报错:ImportError: cannot import name ‘Log‘ from ‘rosgraph_msgs.msg‘
在使用ros2的bag命令查看数据集信息时报错 Traceback (most recent call last):File "/opt/ros/noetic/bin/rosbag", line 34, in <module>import rosbagFile "/opt/ros/noetic/lib/python3/dist-packages/rosbag/__init__.py", line 33, in <mo…...
【Vue】Vue中的代码分为哪几种类型?
在 Vue 中的代码可以分为以下几种类型: 1.模板代码 模板代码是 Vue 中用来生成 HTML 的一种语法,可以通过 Vue 的模板语法和指令来动态渲染页面。模板代码一般写在 Vue 组件的 template 标签中。 2.JavaScript 代码 JavaScript 代码是 Vue 组件中用来…...
es6中includes用法
js中的includes用法 1.数组 includes 可以判断一个数组中是否包含某一个元素,并返回true 或者false [a,b,c].includes(a) true [a,b,c].includes(1) false includes可以包含两个参数,第二个参数表示判断的起始位置 起始位置第一个数字是0。 2.字符串 …...
QT中QRadioButton实现分组C++
通过对QRadioButton组件进行分组可解决QRadioButton组件的互斥性 实现如下。 假设已设计好UI并且有UI代码情况: 头文件引用: #include <QButtonGroup> 分组功能 ,cpp文件代码实现: Your_Project::Your_Project(QWidge…...
kafka实战报错解决问题
需求 在一个在线商城中,用户下单后需要进行订单的处理。为了提高订单处理的效率和可靠性,我们使用Kafka来实现订单消息的异步处理。当用户下单后,订单信息会被发送到Kafka的一个Topic中,然后订单处理系统会从该Topic中消费订单消…...
vite+react 使用 react-activation 实现缓存页面
对应的版本 "react": "^18.2.0", "react-activation": "^0.12.4", "react-dom": "^18.2.0", "react-router-dom": "^6.15.0",react-activation 这是一个npm包,在react keep alive…...
【android 蓝牙开发——蓝牙耳机】
【android 蓝牙开发——传统蓝牙】 【android 蓝牙开发——BLE(低功耗)蓝牙 2021-10-09更新】 总结一下蓝牙开发的基本使用以及蓝牙耳机的断开和链接。 所以需权限: <uses-permission android:name"android.permission.ACCESS_FIN…...
Golang goroutine 进程、线程、并发、并行
goroutine 看一个需求 需求:要求统计1-200000000000的数字中,哪些是素数? 分析思路: 1)传统的方法,就是使用一个循环,循环的判断各个数是不是素数(一个任务就分配给一个cpu去做,这样很不划算…...
如何做到安全上网
随着信息化的发展,企业日常办公越来越依赖互联网,而访问互联网过程中,会遇到各种各样不容忽视的风险,例如员工主动故意的数据泄漏,后台应用程序偷偷向外部发信息,木马间谍软件的外联,以及各种挖…...
优维低代码实践:菜单
优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。 优维…...
git merge 如何撤销
如果只是 git merge 未进行其他 git 操作,可以使用 git merge --abort 撤销如果 git merge 之后,再 git add,可以使用 git reset HEAD 或 git reset HEAD file (前者多个文件,后者单个文件)如果 git merge 之后,再 git…...
解读package.json 中的功能
使用 npm init 比较全 一步一步的走,用于完成 package.json 中的各个声明 npm init -y 生成简易的模板下面解读下 package.json 中的功能"version": "1.0.0", //版本号1. 主版本号:非常大的改动 vue2 和 vue3 的改变 2. 功能的升级,…...
UMA 2 - Unity Multipurpose Avatar☀️四.UMA人物部位的默认颜色和自定义(共享)颜色
文章目录 🟥 人物颜色介绍1️⃣ 使用默认颜色2️⃣ 使用自定义颜色🟧 UMA自定义颜色的作用🟨 自定义颜色还可作为共享颜色🟥 人物颜色介绍 UMA不同部位的颜色分为默认的内置颜色和我们新定义的颜色. 1️⃣ 使用默认颜色 比如不勾选UseSharedColor时,使用的眼睛的默认…...
phpstorm配置php运行环境
1,首先安装phpstrom,按照提示的步骤一步一步来就行 2,新建一个项目然后在里面找到这个位置 3,找到php所在的位置,找不到就直接在搜索框中搜索 4,这里要配置php的运行环境,一定要记得自己安装软…...
算法训练营day49|动态规划 part10:(LeetCode 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II)
121. 买卖股票的最佳时机 题目链接🔥 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大…...
Swagger 使用教程
Swagger 官网: API Documentation & Design Tools for Teams | Swagger 整合swagger 依赖: springfox-swagger2 springfox-swagger-ui <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</a…...
单例模式-饿汉模式、懒汉模式
单例模式,是设计模式的一种。 在计算机这个圈子中,大佬们针对一些典型的场景,给出了一些典型的解决方案。 目录 单例模式 饿汉模式 懒汉模式 线程安全 单例模式 单例模式又可以理解为是单个实例(对象) 在有些场…...
UG\NX二次开发 复制3元素的double数组到另一个数组 UF_VEC3_copy
文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介: UG\NX二次开发 复制3元素的double数组到另一个数组 UF_VEC3_copy。仔细看第二段代码 。 效果: 代码: #include "me.hpp"void ufusr(char* param, …...
骨传导耳机对人体有危险吗?会损害听力吗?
如果在使用骨传导耳机的时候控制好时间和音量,是不会对人体带来危险和造成伤害的。 下面跟大家解释一下为什么骨传导耳机对人体没有危害,最大的原因就是骨传导耳机不需要空气传导,而是通过颅骨传到听觉中枢,传输过程中几乎没有噪…...
Spring Boot @Value读不到Nacos配置中心的值。(properties配置文件)
读不到配置中心的值, 配置中心的配置文件名字(Data ID的值)要以.properties结尾。 如果是yaml,就以yaml命名。...
Rocky Linux怎么安装mysql
Rocky Linux怎么安装mysql 在Rocky Linux上安装MySQL可以通过以下步骤实现: 更新软件包列表 ⭐️⭐️⭐️必要的,必须更新,更新会顺利很多!!!⭐️⭐️⭐️ 在安装MySQL之前,建议先更新软件包…...
轻量级软件FastGithub实现稳定访问github
当我们想访问全球最大的“同性交友网站”https://github.com/ 时,总会出现无法访问的界面,令人非常苦恼:幸运的是,有一种轻量级的软件可以帮助我们稳定地访问GitHub,那就是FastGithub。 什么是FastGithub?…...
芯科蓝牙BG27开发笔记6-精简第一个程序
1. 这些IO的控制代码在哪里? 还是蓝牙点灯程序: 首先需要对pinout做一些精简: 为了简化工程,去掉了不必要的IO。 至于PTI接口是什么,怎么用,不知道,现在不考虑: 但是提出以下问题…...
Android8.1 hal 加载wifi ko模块流程
Android如果发现wifi没有正常启动,从下面两个方面 1.是否正常编译出wifi ko文件,如果没有,说明编译的有问题,ko文件的地址vendor/lib/module/devices/wifi 2.如果有编译出ko文件,但还提示Wifi HAL start failed之类的…...
网易做相册旅游网站/买链接网
文/金金 首发于一周进步每到期末,都是大作业和报告的高发季,一个“死线”刚过,另一堆“死线”接踵而至。作为一名在报告的海洋里中挣扎,妄图顺利存活的同学,我自然是使用链接到样式的多级列表,Word自动化排…...
做视频网站用什么源码/兰州网络推广技术
属性 类型 默认值 autoOpen Boolean true 实例化时是否自动显示对话框。设置为 false 时,使用 open 方法显示对话框。 false 代码示例 创建实例时设置属性值 $(".class").dialog({…...
wordpress hasnavmenu/百度推广的定义
grpc-webMicrosoft已在.NET Core和ASP.NET Core中推出了对gRPC-Web的实验性支持,从而允许直接从.NET Core gRPC客户端和ASP.NET Core gRPC应用程序中调用gRPC-Web。 gRPC-Web与HTTP / 1和HTTP / 2兼容,是一个JavaScript客户端库,支持与gRPC-…...
上海人才招聘官网/南通百度seo代理
简介 YAML 是一种简洁的非标记语言(YAML Ain’t Markup Language),YAML以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁易读, 常用于作为配置文件, 比json更加简洁。 YAML 1.2 (3rd Edition): http:/…...
连接国外网站做端口映射/百度的人工客服
Biotin-PEG-NH2 生物素-聚乙二醇-氨基 英文名称:Biotin-PEG-Amine 中文名称:生物素-聚乙二醇-氨基 外观: 白色/灰白色液体、半固体或固体,取决于分子量。 溶剂:水,氯仿,DMSO,二氯甲烷等常规…...
建设集团网站方案设计/百度关键词排行榜
计算两个整型数组元素之和,返回一个数组。规则如下:对应的元素相加,不对应的直接赋值给相应的位置,如 {1,2,4}{2,4,6,8}{3,6,10,8} 下…...