minio最新源码编译(处理安全扫描中跨域访问、.js.map等不安全问题) 版本:RELEASE.2024-06-26T01-06-18Z

news/2024/9/16 7:47:40/ 标签: go, minio, 源码, 安全

编译前注意事项

  1. 编译基于tag为RELEASE.2024-06-26T01-06-18Z的版本
  2. 处理安全扫描问题。如:敏感信息泄露、.js.map、跨域访问问题
  3. 需要准备两个工程,前端工程console和minio工程, 目录结构处理:
gowork/
│
└── src/├── github.com├── minio/└── minio/└── console/
  1. 若想直接使用处理后的源码,可以克隆minio仓库进行编译即可,(其中依赖的console已经更换成
    replace github.com/minio/console => gogs.zyjblogs.cn/minio/console v1.6.1-fix
git clone -b RELEASE.2024-06-26T01-06-18Z-fix https://gogs.zyjblogs.cn/minio/minio
  1. 若想直接使用修改后的minio二进制文件,详见蓝奏云链接: minio.tar.gz - 蓝奏云 (lanzout.com)
  2. 若想自行修改详见下文。

console编译

minioconsole_22">拉取minio的前端工程console

前端工程在console工程下web-app目录

#github.com上的仓库
git clone https://github.com/minio/console.git
#国内镜像加速仓库 gitcode
https://gitcode.com/gh_mirrors/console/console.git

修改package.json

在build下添加 GENERATE_SOURCEMAP=false关闭sourcemap

"scripts": {"start": "PORT=5005 react-scripts start","build": "GENERATE_SOURCEMAP=false react-scripts build","buildistanbulcoverage": "PORT=9090 USE_BABEL_PLUGIN_ISTANBUL=1 react-app-rewired build","test": "react-scripts test","eject": "react-scripts eject","playwright": "PORT=5005 USE_BABEL_PLUGIN_ISTANBUL=1 react-app-rewired start","find-deadcode": "ts-prune -s consoleApi.ts | sh -c '(! grep -v \"used in module\")'"},

如修改下图所示:
image.png

编译

安装依赖

#安装依赖
yarn install
#若出现证书问题可以忽略证书
## linux
export NODE_TLS_REJECT_UNAUTHORIZED=0 && yarn install
## windows
set NODE_TLS_REJECT_UNAUTHORIZED=0 && yarn install

编译前删除console工程下web-app/build目录

yarn build

修改获取不存在文件.js.map时返回文件且内容为index.html内容问题

console中有一个逻辑是访问不存在静态资源时会返回index.html的内容,因为安全漏洞扫描原因访问.js.map文件成功,虽然内容为index.html的内容,但是避免这类问题进行如下处理。

修改文件 api/configure_console.go

  1. 导入os库
go">import ("os"// 其他库
)
  1. 添加环境变量MINIO_HTTP_SERVER_INFO

修改通用的请求头Server显示的信息(默认为MinIO Console),进行自定义防止文件服务信息被泄露
修改方法FileServerMiddleware

go">func FileServerMiddleware(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {serverInfo := os.Getenv("MINIO_HTTP_SERVER_INFO")if serverInfo == "" {serverInfo = globalAppName}w.Header().Set("Server", serverInfo) // do not add version informationswitch {case strings.HasPrefix(r.URL.Path, "/ws"):serveWS(w, r)case strings.HasPrefix(r.URL.Path, "/api"):next.ServeHTTP(w, r)default:buildFs, err := fs.Sub(portal_ui.GetStaticAssets(), "build")if err != nil {panic(err)}wrapHandlerSinglePageApplication(requestBounce(http.FileServer(http.FS(buildFs)))).ServeHTTP(w, r)}})
}

如修改下图所示:
image.png

  1. 拦截.js.map

访问不存在资源且资源为资源为.js.map资源时返回404
修改方法wrapHandlerSinglePageApplication

go">func wrapHandlerSinglePageApplication(h http.Handler) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {if r.URL.Path == "/" {handleSPA(w, r)return}w.Header().Set("Content-Type", mimedb.TypeByExtension(filepath.Ext(r.URL.Path)))nfw := &notFoundRedirectRespWr{ResponseWriter: w}h.ServeHTTP(nfw, r)if nfw.status == http.StatusNotFound {// 拦截 .js.map 文件if strings.HasSuffix(r.URL.Path, ".js.map") {http.NotFound(w, r)return}handleSPA(w, r)}}
}

如修改下图所示:
image.png

minio_133">minio编译

minio_134">拉取minio工程

#github.com上的仓库
git clone https://github.com/minio/minio.git
#国内镜像加速仓库 gitcode
https://gitcode.com/gh_mirrors/mi/minio.git

gomod_142">处理go.mod文件

添加替换文件中依赖github.com/minio/console../console

# 若为本地源代码执行下面命令进行处理
go mod edit --replace github.com/minio/console=../console
# 若想使用已经修改完成的console则使用
go mod edit --replace github.com/minio/console=gogs.zyjblogs.cn/minio/console@v1.6.1-fix

依赖下载

go clean -modcache
go mod download
go mod tidy

修改项目源码

  1. 配置crossdomain.xml

原始minio访问crossdomain.xml可以看到返回xml内容:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"><cross-domain-policy><allow-access-from domain="*" secure="false" />
</cross-domain-policy>

该配置安全扫描为不安全项,需要设置allow-access-from为具体的域名。
现在把它修改为,读取配置的环境变量,然后设置为具体的域名,让其返回类似下面的xml,不能使用*

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy><allow-access-from domain="*.baidu.com" secure="false" /><allow-access-from domain="zyjblogs.cn" secure="false" />
</cross-domain-policy>

修改步骤:

(1)修改项目中的internal/config/constants.go文件,加入需要读取环境的名称,具体看修改后源码

const{}内添加两个环境变量,位置在 86~91行左右。 constants.go

const (//.....// 以下是自定的环境变量参数// EnvMinIOAllowAccessFromDomain crossdomain.xml cross-domain-policyEnvMinIOAllowAccessFromDomain = "MINIO_ALLOW_ACCESS_FROM_DOMAIN"// EnvMinIOServerInfo api 通用的请求头Server显示的信息,进行自定义防止文件服务信息被泄露EnvMinIOServerInfo = "MINIO_HTTP_SERVER_INFO"
)

如修改下图所示:

(2)然后修改crossdomain.xml对应的处理类cmd/crossdomain-xml-handler.go,修改读取环境变量配置的值,具体查看修改后的文件[crossdomain-xml-handler.go](minio/minio @ RELEASE.2024-06-26T01-06-18Z-fix - 逝水无痕の代码仓库 (zyjblogs.cn)。

  1. 在变量crossDomainXML后添如下代码。代码位置32行位置
go">// 自定义crossdomain.xml
const crossDomainXMLPrefix = `<?xml version="1.0"?><!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"><cross-domain-policy>`
const crossDomainXMLSuffix = `</cross-domain-policy>`
const allowAccessFromTemplate = `<allow-access-from domain="{{.Domain}}" secure="false" />`

如修改下图所示:
image.png

  1. 替换方法setCrossDomainPolicyMiddleware为如下内容。 位置
go">
func setCrossDomainPolicyMiddleware(h http.Handler) http.Handler {// get env MINIO_ALLOW_ACCESS_FROM_DOMAINallowAccessFromDomain := os.Getenv(config.EnvMinIOAllowAccessFromDomain)if allowAccessFromDomain == "" {allowAccessFromDomain = "*"}// logger.Info("MINIO_ALLOW_ACCESS_FROM_DOMAIN=%s", allowAccessFromDomain)// 如果配置了多个就需要解析一下domains := strings.Split(allowAccessFromDomain, ",")allowAccessFrom := crossDomainXMLPrefixfor _, domain := range domains {// fill string templatebuffer := &bytes.Buffer{}tmpl, _ := template.New("tmp").Parse(allowAccessFromTemplate)data := struct{ Domain string }{Domain: domain}_ = tmpl.Execute(buffer, data)allowAccessFrom += buffer.String()}allowAccessFrom += crossDomainXMLSuffix// Write to ServeHTTPreturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {// Look for 'crossdomain.xml' in the incoming request.if r.URL.Path == crossDomainXMLEntity {// Write the standard cross domain policy xml.w.Write([]byte(allowAccessFrom))// Request completed, no need to serve to other handlers.return}h.ServeHTTP(w, r)})
}

然后访问对应的地址,即可使用配置的xml。
添加环境变量: MINIO_ALLOW_ACCESS_FROM_DOMAIN=http://localhost,http://127.0.0.1
http://IP:PORT/crossdomain.xml

效果如图所示:
image.png

(3) 添加功能:自定义响应头Server的信息

请求minio接口时,返回的请求头会返回Server: MinIO ,这样扫描会被针对扫描,需要修改为自定义的信息,例如这样:Server: MyOSS ,这样就可以不会暴露出文件服务器的信息了。

直接修改cmd/api-headers.go文件中的setCommonHeaders方法,读取配置环境变量,修改代码如下。可参考api-headers.go第55~59行

go">func setCommonHeaders(w http.ResponseWriter) {// Set the "Server" http header.// w.Header().Set(xhttp.ServerInfo, MinioStoreName)// Set the "Server" http header.serverInfo := os.Getenv(config.EnvMinIOServerInfo)if serverInfo == "" {serverInfo = MinioStoreName}w.Header().Set(xhttp.ServerInfo, serverInfo)// Set `x-amz-bucket-region` only if region is set on the server// by default minio uses an empty region.if region := globalSite.Region(); region != "" {w.Header().Set(xhttp.AmzBucketRegion, region)}w.Header().Set(xhttp.AcceptRanges, "bytes")// Remove sensitive informationcrypto.RemoveSensitiveHeaders(w.Header())
}

如修改下图所示:
image.png

(4)添加功能:追加安全扫描提示的响应头

安全扫描提示需要响应头

Referrer-Policy: strict-origin-when-cross-origin
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: master-only
X-Xss-Protection: 1; mode=block

修改步骤:修改cmd/generic-handlers.go文件的addCustomHeadersMiddleware方法,把缺少的响应头追加上即可,可参考修改后的源码generic-handlers.go第535~557行。

go">// 追加其他的请求头(安全漏洞提示处理)
header.Set("X-Permitted-Cross-Domain-Policies", "master-only")
header.Set("Referrer-Policy", "strict-origin-when-cross-origin")
header.Set("X-Frame-Options", "SAMEORIGIN")

如修改下图所示:
image.png

使用环境变量: export MINIO_HTTP_SERVER_INFO=MyOSS

效果如图所示:
image.png

编译项目

minio工程下执行如下命令
参数介绍 go build -ldflags "-s -w" -o 编译后的二进制文件 项目工程目录
minio工程执行构建命令时,使用.代表当前目录

# window 
go build -ldflags "-s -w" -o E:\minio.exe .
# linux
go build -ldflags "-s -w" -o ~/minio .

运行文件服务

使用环境变量配置启动参数:

export MINIO_ROOT_USER=minioadmin
export MINIO_ROOT_PASSWORD=minioadmin
#export MINIO_BROWSER=false
export MINIO_API_CORS_ALLOW_ORIGIN="https://*.zyjblogs.cn,https://*example.com"
#新添加的参数
export MINIO_ALLOW_ACCESS_FROM_DOMAIN=*.zyjblogs.cn,*example.com
export MINIO_HTTP_SERVER_INFO=MyOSS

变量说明:

变量名称说明
MINIO_ROOT_USER管理控制台账号
MINIO_ROOT_PASSWORD管理控制台密码
MINIO_BROWSERoff关闭web控制台
MINIO_API_CORS_ALLOW_ORIGINapi可使用域名
MINIO_ALLOW_ACCESS_FROM_DOMAIN[new] crossdomain.xml文件的域名配置
MINIO_HTTP_SERVER_INFO[new] 响应头Server的信息

使用9000端口启动文件服务:

#!/bin/bash
export MINIO_ROOT_USER=minioadmin
export MINIO_ROOT_PASSWORD=minioadmin
#export MINIO_BROWSER=false
export MINIO_API_CORS_ALLOW_ORIGIN="https://*.zyjblogs.cn,https://*example.com"
export MINIO_ALLOW_ACCESS_FROM_DOMAIN=*.zyjblogs.cn,*example.com
export MINIO_HTTP_SERVER_INFO=MyOSS
nohup ./minio server data > minio.log 2>&1 &

检查配置是否生效
image.png

参考:
https://www.cnblogs.com/lixingwu/p/17933091.html
https://blog.csdn.net/LoveTheMost/article/details/138950398


http://www.ppmy.cn/news/1520698.html

相关文章

【Xcode】Xcode基本使用指引

文章目录 Xcode安装及iphone模拟器的安装Xcode中Debug和Release的切换Xcode中控件的使用Xcode工程的基本组成Xcode UI基本设计及使用iOS开发项目中的日志系统静态库支持多种架构制作xcframeworklibuv库Xcode路径.pbxproj文件苹果平台的宏Leaks检测内存泄漏OC中的ARC和MRC小结 X…

朴素贝叶斯分类算法

文章目录 贝叶斯定理问题背景朴素贝叶斯朴素贝叶斯分类算法原理朴素贝叶斯分类算法步骤给定示例数据 极大似然估计如何求 P ( 特征 ∣ 类别 ) P ( 类别 ) P(\text{特征} \mid \text{类别}) \times P(\text{类别}) P(特征∣类别)P(类别)&#xff1f;如何求 P ( 类别 ) P(\text{…

10 万元预算,竟能打造满足第一性原理计算的高性价比服务器

科学研究的领域中&#xff0c;第一性原理计算占据着至关重要的地位。它要求服务器具备极高的性能&#xff0c;以应对复杂的量子力学计算任务。 第一性原理计算涉及对物质本质的深入探索&#xff0c;需处理海量数据并进行大规模并行计算。第一性原理计算基于量子力学原理&#x…

flask-解决跨域问题

pip install flask_cors两种方式 # 全局 CORS(app, supports_credentialsTrue)# 包装在 app.route 之上 cross_origin()

开放式耳机的优缺点?有什么推荐吗?四款开放式蓝牙耳机推荐

开放式耳机的优点有很多其实&#xff0c;但是每个东西多多少少都是一把双刃剑&#xff0c;所以缺点当然也是有的。那就先讲它的优点&#xff1a; 首先因为不入耳的设计&#xff0c;耳机不是直接塞入耳道的&#xff0c;所以能让耳道保持“呼吸”&#xff0c;减少长时间佩戴导致…

【C++ | 设计模式】简单工厂模式的详解与实现

1.简单工厂模式概述 简单工厂模式&#xff08;Simple Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它定义了一个工厂类&#xff0c;由这个类根据提供的参数决定创建哪种具体的产品对象。简单工厂模式将对象的创建逻辑集中到一个工厂类中&#xff0c;从而将对…

(计算机论文)基于SpringBoot和Vue的台球赛事服务网站的设计与实现

毕业设计&#xff08;论文&#xff09; 博主可接毕设论文&#xff01;&#xff01;&#xff01; 基于SpringBoot和Vue的台球赛事服务网站的设计与实现 摘 要 在快速发展的信息时代&#xff0c;体育竞赛作为群众文化娱乐的一部分&#xff0c;已日益受到广泛关注。台球&#xff…

LangChain中的缓存机制详解

文章目录 概要整体架构流程SQLite 缓存小结 概要 在处理大规模语言模型&#xff08;LLMs&#xff09;时&#xff0c;频繁的API调用不仅耗费时间和金钱&#xff0c;还可能导致不必要的延迟。为了解决这个问题&#xff0c;LangChain 提供了一种缓存机制&#xff0c;通过存储先前…

gitea + drone实现CI/CD

下面只是使用docker compose 启动容器docker-compose.yml文件 创建drone容器 version: 3 services:drone-server:restart: alwaysimage: drone/drone:2ports:- "3000:80"volumes:- /home/dorne/lib/drone:/var/lib/drone/- /home/dorne/data:/data/environment:- D…

微服务日常总结

1.当我们在开发中&#xff0c;需要连接多个库时&#xff0c;可以在yml中进行配置。 当在查询的时候&#xff0c;跨库时&#xff0c;需要通过DS 注解来指定&#xff0c;需要yml配置需要保持一致。 2. 当我们想把数据存入到clob类型中&#xff0c;需要再字段 的占位符后面加上j…

Spring全局异常处理HandlerExceptionResolver使用

1 引言 全局异常处理在项目中经常会用到&#xff0c;主要作用包括统一处理异常、提供友好的错误信息、避免应用程序崩溃、记录异常日志、避免异常信息泄露等等。下文将以实现HandlerExceptionResolver接口的方式&#xff0c;实现全局异常处理功能及常规用法。 2 代码 下面列…

搜维尔科技:蹦床、跳绳或骑马,OptiTrack可以捕捉难以想象的物体

蹦床、跳绳或骑马&#xff0c;OptiTrack可以捕捉难以想象的物体 搜维尔科技&#xff1a;蹦床、跳绳或骑马&#xff0c;OptiTrack可以捕捉难以想象的物体

Eureka简介与开发

Eureka 是由 Netflix 开源的服务发现和注册中心&#xff0c;它提供了服务的注册与发现功能&#xff0c;是 Spring Cloud 体系中的核心组件之一。Eureka 采用 C/S 架构&#xff0c;包含 Eureka Server 和 Eureka Client 两个主要的组件。 **Eureka Server** 充当服务注册中心&a…

读懂以太坊源码(3)-详细解析genesis.json

要想搞懂以太坊的源代码逻辑&#xff0c;必须要了解以太坊创世区块配置文件(genesis.json)的结构&#xff0c;以及每个配置参数的意义&#xff0c;创世配置文件&#xff0c;主要作用是设置链的ID&#xff0c;指定以太坊网络中硬分叉发生的区块高度&#xff0c;以及初始ETH数量的…

DuplicateKeyException产生原因及解决方案

DuplicateKeyException 是 Spring 框架中与数据库操作相关的异常之一&#xff0c;通常在试图向数据库中插入一条记录时&#xff0c;违反了唯一性约束&#xff08;如主键或唯一索引约束&#xff09;时抛出。这意味着数据库中已经存在具有相同键值的记录&#xff0c;导致插入操作…

小程序中用于跳转页面的5个api是什么?区别是什么

小程序中用于跳转页面的5个主要API分别是wx.navigateTo、wx.redirectTo、wx.reLaunch、wx.switchTab和wx.navigateBack。这些API各自具有不同的功能和特点&#xff0c;适用于不同的页面跳转场景。以下是它们的详细介绍及区别&#xff1a; 1. wx.navigateTo 功能&#xff1a;保…

认识爬虫技术

爬虫目的 网络爬虫&#xff0c;主要目的是代替人工收集网络数据。 应用场景主要包括两个方面&#xff1a; 网页收集的数据量少&#xff0c;但重复操作频率高&#xff1b; 通过网页搜集数据的量大。 只要满足以上两个应用场景&#xff0c;其实都可以考虑使用爬虫技术降低人…

TCP协议 配合 Wireshark 分析数据

在TCP连接中&#xff0c;无论是客户端还是服务端&#xff0c;都有可能成为发送端或接收端&#xff0c;这是因为TCP是一个全双工协议&#xff0c;允许数据在同一连接中双向流动 客户端&#xff08;Client&#xff09;&#xff1a;通常是指主动发起连接请求的一方。例如&#xf…

【归纳总结】常见排序算法及其实现:直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快排、归并排序

思维导图&#xff1a; 目录 思维导图&#xff1a; 一、插入排序 1.直接插入排序&#xff1a; a:基本思想&#xff1a; b:基本步骤&#xff1a; c:复杂度分析 d:Java代码实现&#xff1a; 2.希尔排序&#xff08;缩小增量排序&#xff09; a:基本思想&#xff1a; c…

VMware部署linux系统

前期准备 安装VMware的相关教程在我的另一篇博客。 VMware的安装教程-CSDN博客 CentOS7.6的安装包 链接&#xff1a;https://pan.baidu.com/s/1sl8COPAC_VEcRtKxvu2S1A?pwd84el 提取码&#xff1a;84el 如果觉得百度网盘速度太慢&#xff0c;可以去镜像下载也可以 阿里…