当前位置: 首页 > news >正文

使用 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 中的代码可以分为以下几种类型&#xff1a; 1.模板代码 模板代码是 Vue 中用来生成 HTML 的一种语法&#xff0c;可以通过 Vue 的模板语法和指令来动态渲染页面。模板代码一般写在 Vue 组件的 template 标签中。 2.JavaScript 代码 JavaScript 代码是 Vue 组件中用来…...

es6中includes用法

js中的includes用法 1.数组 includes 可以判断一个数组中是否包含某一个元素&#xff0c;并返回true 或者false [a,b,c].includes(a) true [a,b,c].includes(1) false includes可以包含两个参数&#xff0c;第二个参数表示判断的起始位置 起始位置第一个数字是0。 2.字符串 …...

QT中QRadioButton实现分组C++

通过对QRadioButton组件进行分组可解决QRadioButton组件的互斥性 实现如下。 假设已设计好UI并且有UI代码情况&#xff1a; 头文件引用&#xff1a; #include <QButtonGroup> 分组功能 &#xff0c;cpp文件代码实现&#xff1a; Your_Project::Your_Project(QWidge…...

kafka实战报错解决问题

需求 在一个在线商城中&#xff0c;用户下单后需要进行订单的处理。为了提高订单处理的效率和可靠性&#xff0c;我们使用Kafka来实现订单消息的异步处理。当用户下单后&#xff0c;订单信息会被发送到Kafka的一个Topic中&#xff0c;然后订单处理系统会从该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包&#xff0c;在react keep alive…...

【android 蓝牙开发——蓝牙耳机】

【android 蓝牙开发——传统蓝牙】 【android 蓝牙开发——BLE&#xff08;低功耗&#xff09;蓝牙 2021-10-09更新】 总结一下蓝牙开发的基本使用以及蓝牙耳机的断开和链接。 所以需权限&#xff1a; <uses-permission android:name"android.permission.ACCESS_FIN…...

Golang goroutine 进程、线程、并发、并行

goroutine 看一个需求 需求&#xff1a;要求统计1-200000000000的数字中&#xff0c;哪些是素数? 分析思路&#xff1a; 1)传统的方法&#xff0c;就是使用一个循环&#xff0c;循环的判断各个数是不是素数&#xff08;一个任务就分配给一个cpu去做&#xff0c;这样很不划算…...

如何做到安全上网

随着信息化的发展&#xff0c;企业日常办公越来越依赖互联网&#xff0c;而访问互联网过程中&#xff0c;会遇到各种各样不容忽视的风险&#xff0c;例如员工主动故意的数据泄漏&#xff0c;后台应用程序偷偷向外部发信息&#xff0c;木马间谍软件的外联&#xff0c;以及各种挖…...

优维低代码实践:菜单

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…...

git merge 如何撤销

如果只是 git merge 未进行其他 git 操作&#xff0c;可以使用 git merge --abort 撤销如果 git merge 之后&#xff0c;再 git add&#xff0c;可以使用 git reset HEAD 或 git reset HEAD file (前者多个文件&#xff0c;后者单个文件)如果 git merge 之后&#xff0c;再 git…...

解读package.json 中的功能

使用 npm init 比较全 一步一步的走,用于完成 package.json 中的各个声明 npm init -y 生成简易的模板下面解读下 package.json 中的功能"version": "1.0.0", //版本号1. 主版本号&#xff1a;非常大的改动 vue2 和 vue3 的改变 2. 功能的升级&#xff0c;…...

UMA 2 - Unity Multipurpose Avatar☀️四.UMA人物部位的默认颜色和自定义(共享)颜色

文章目录 🟥 人物颜色介绍1️⃣ 使用默认颜色2️⃣ 使用自定义颜色🟧 UMA自定义颜色的作用🟨 自定义颜色还可作为共享颜色🟥 人物颜色介绍 UMA不同部位的颜色分为默认的内置颜色和我们新定义的颜色. 1️⃣ 使用默认颜色 比如不勾选UseSharedColor时,使用的眼睛的默认…...

phpstorm配置php运行环境

1&#xff0c;首先安装phpstrom&#xff0c;按照提示的步骤一步一步来就行 2&#xff0c;新建一个项目然后在里面找到这个位置 3&#xff0c;找到php所在的位置&#xff0c;找不到就直接在搜索框中搜索 4&#xff0c;这里要配置php的运行环境&#xff0c;一定要记得自己安装软…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...