APP下载

基于Nginx反向代理解决公网上服务跨域问题的研究

2023-06-25崔娟王伟民冯继虎李怀堂王林柱

现代信息科技 2023年8期
关键词:跨域安全

崔娟 王伟民 冯继虎 李怀堂 王林柱

摘  要:對软件开发人员来说,除了日常在本地的开发工作之外,最终的目的是要将项目部署到公网上,供用户使用。但是基于系统安全的考虑,一般不能将内网服务器上所有服务全部暴露在外网上,这个时候选择通过Nginx的反向代理来解决这个问题。通过实现前端后分离部署,修改Nginx配置文件,解决了公网上浏览、下载内网服务器上图片等问题。

关键词:安全;Nginx;docker容器化部署;反向代理;跨域

中图分类号:TP393    文献标识码:A  文章编号:2096-4706(2023)08-0079-05

Abstract: For software developers, in addition to daily local development work, the ultimate goal is to deploy the project to the public network for users to use. However, based on the consideration of system security, it is generally not possible to expose all services on the intranet server to the outer internet. At this time, this paper chooses the nginx reverse proxy to solve this problem. By implementing front end separate deployment and modifying nginx configuration files, the problems of browsing and downloading pictures on the intranet server by public network are solved.

Keywords: security; Nginx; docker container deployment; reverse proxy; cross domain

0  引  言

软件开发采用前后端分离的模式开发,前端使用vue框架。根据业务需要,项目中需要有上传图片,显示图片的功能。我们选择将图片上传到对象存储服务minio上,而minio通过docker安装在内网服务器上。上传后的图片我们通过后台接口返回的图片URL来访问。而这个图片的地址是携带了内网IP和端口号的地址,同时我们也是存储到数据库中,这样下次显示图片的时候就直接读取图片字段的URL。问题是图片的URL由内网IP+端口号+其他路径+图片名称组成,那么在公网上是直接访问不到这个内网的IP或者这个端口号的地址的,这个时候就会出现图片打不开的问题。所以我们的解决思路是:外网要能访问服务器上的前端项目,我们必须要将一个IP地址+端口号映射在公网上,那么我们可以选择将前端项目放在一个服务器上,后端项目放在另一台服务器上,映射前端服务器上的IP到公网上,通过配置Nginx访问后端内网服务器。或者我们将前端项目和后端项目部署在同一个台服务器的不同端口下。本文按照第二种方式部署,部署到同一台服务器上的不同端口下。

1  部署后端项目到服务器上

1.1  部署后端项目

将后端项目部署到linux服务器上,我们可以选择传统的部署方式:上传jar包到服务器上,运行命令“nohup  Java  -jar  xxx.jar --server.port=8011 ”。这种部署方式的弊端是只要我们代码有修改,就必须重新打包,然后再上传jar包到服务器上,重新运行命令,效率低下。所以我们也可以采用docker容器的部署方式。

1.1.1  第一种方式

采用dockerFile文件+jar包的方式部署,根据自己的项目编写对应的dockerFile文件,同时上传dockerFile文件和jar包在同一个父目录下。通过运行命令“docker build -t  imageName   .”构建我们的项目镜像。然后我们就可以通过命令“docker run -d  -P  --name 容器名称 镜像名称 ”运行基于这个镜像的容器,如图3所示,这样我们的后端服务就可以正常启动了。当然这种方式和传统的部署方式本质上并没有帮我们开发人员解决运维时间,只是使用了当下流行的docker容器而已。

1.1.2  第二种方式

配置pom文件,让其打包的时候就直接构建对应的镜像。首先配置docker的服务地址和IP例如

http://192.168.60.192:2375

这样打包的时候才能找到对应的服务器上的docker,接下来就是配置打包时自动构建镜像的命令:

build-image

package

build

最后配置如何根据相应的jar构建什么样名称,什么样版本号的镜像:

repository/${project.artifactId}:${project.version}

${docker.host}

java:8

["java", "-jar","/${project.build.finalName}.jar"]

/

${project.build.directory}

${project.build.finalName}.jar

打包成功之后我们就可以在Linux服务器上能看到对应的镜像,如图1所示。

最后就是通过docker run的命令启动容器,我们的服务也就起来了。相对于第一种方式我们少了自己打包jar,然后又上传到服务器上的过程,更加节约时间。但是有一个缺点是我们重新打包,构建镜像的时候要手动删除原先的容器和镜像,不然会因为镜像名冲突的问题而构建不知名的镜像none,如圖2所示。

1.1.3  第三种方式

基于Jenkins+shell脚本的部署方式,这是一种半自动化的部署,只需要上传shell脚本到服务器上,结合我们的gitee或者其他的版本控制工具,将项目上传到对应的版本控制工具上,再配置我们的Jenkins,就可以完成镜像、容器一起的构建。不需要再手动输入docker run的命令,当然这一步是因为我们在shell脚本提前写入了运行容器的命令。在shell脚本中如果我们写了构建镜像的命令

“docker build -t ${group_name}/${app_name}:${app_version}  .”我们就可以在配置文件pom文件中不写自动构建镜像的配置。这种方式我们每次只需要上传我们修改的代码到版本控制工具中,然后在Jenkins中点击构建对应的项目,我们的后端项目就可以启动起来了。不需要再手动上传文件到Linux服务上。根据shell脚本,每次构建的时候都会删除原先的容器和镜像,所以也不会出现第二种方式的问题了。

上述的几种方式实现原理都是通过构建镜像和运行容器的方式来部署项目,部署过程不重要,最终目的是将后端项目部署到内网服务器上,最后的容器运行截图如图3所示,表示后端项目正式运行起来了。部署后的后端访问地址比如说是:192.168.60.192:8011。(这个地址在Nginx配置反向代理的时候用)

1.2  测试后端项目正常运行

确保通过postman或其他工具测试接口上传图片到minio是成功的,如图4所示。url中的“http:192.168.60.192:9090/”就是minio内网ip+端口号,这个地址就是我们返回给前端,前端用来展示图片的地址,当我们在内网的浏览器上输入这个url就会显示图片了,但是我们外网访问的时候就打不开这个图片。

2  部署前端项目

2.1  上传代码到Linux服务器

将我们的前端项目通过命令npm  build打包到dist目录下,上传dist文件夹到linux服务器上,如图5所示,dist文件夹所在的目录是“/usr/local/sti/minjian”如果我们的前端代码在本地启动的时候加上了前缀/admin,例如:http://localhost:8022/admin/,如图6所示,那么我们配置Nginx的时候记得也是要多写这个/admin。

2.2  配置Nginx启动前端项目

Nginx代理监听的时候是根据配置文件中Nginx所在服务器的IP地址和端口号来的,当它监听到这个端口号之后,依据请求的路径,根据配置文件转发不同的代理。在服务器上启动的项目的端口号和前端代码启动时本地写的端口号没有关系,比如2.1中本地项目前端地址的端口号是8022,但是我们Nginx中配置的可以是其他端口号如8024。这儿修改Nginx的配置文件如图7所示,代表我们的前端项目在公网上就会是8024的端口号。

因为本地前端项目的启动地址里端口号后面加入了/admin,如图6所示。所以我们在这儿配置location的时候需要加上/admin,server_name可以写成localhost或者这台服务器的IP地址,当然后续我们的IP地址有相应的域名,就可以写成域名了,如baidu.com。此时我们访问http://192.168.60.192:8024/admin/,就可以正常启动我们的前端项目,如图8所示。如果我们访问的路径是“http://192.168.60.192:8024”,那么在这个端口下就匹配不到转发规则,就默认走Nginx的默认80端口的路径,如图9所示。

2.3  配置Nginx连接后端项目

基于前面的步骤,我们只是将前端项目和后端项目分别部署到了服务器上,各自都能启动起来,但是前端项目访问不到后端的接口。获取验证码的时候,提示系统接口异常404,如图8所示。原因是我们本地項目本来就是前后端分离的,跨越进行访问的。所以本地访问后端接口的时候需要进行代理,我们在前端中配置的请求的地址如图10所示。加上路径/dev-api就说明要去请求后端接口了。

所以Nginx还需要再配置个location,当在服务器上访问到路径/prod-api时就去转发,去访问后端8011端口上的请求,配置文件如图11所示,这样前端就能正常访问到后端的接口了,如图12所示,就不会报跟图8一样的错误。同时后端的IP和端口也没有暴露在外网上,增加被攻击的危险性。

2.4  配置nginx访问内网服务器minio上的图片

图片上传到内网服务器上的minio中,接口返回给前端的是一个内网图片地址例如“http://192.168.60.192:9090/minjian/20200405/re34.png”,外网访问不到,此时我们需要将前端拿到的图片地址进行转化,将内网的IP和端口号修改为nginx所在服务器的IP和端口号,再根据业务需求加上一个前缀。比如/pic,再加图片本来的地址。转化后的地址是:http://ngnix服务器的IP:端口号/pic/minjian/20200405/re34.png,然后配置nginx中的localtion,如图13所示。

如果监听到了这个端口号下的/pic路径下的请求时,就进行转发。转发到图片真正所在的服务器地址上。实现逻辑同上一个过程,这样公网上就能访问到内网的图片了。具体实现有以下两种方式。

2.4.1  第一种方式

前端拿到后端返回的图片地址时,需要给图片属性src赋值,可以不写IP和端口号,直接加前缀/pic,src的属性值就是“/pic/minjian/20200405/re34.png“,如图14所示,因为没有对应的IP和端口号,所以一般情况下Nginx时间听不到的,这里可以正常访问的,原因是image标签的src属性问题,本地代码里面写的是相对路径,实际点击访问的时候会自动补充当前服务器的IP和端口号,如图15所示,这样nginx代理服务器才能监听到请求了该端口下的/pic路径,然后根据转发逻辑请求真正的图片所在的地址。

2.4.2  第二种方式

第二种方式就是将图片地址中的IP和端口号改为nginx所在的服务器的端口号,然后再加入请求路径/pic,赋值给image标签的src 属性,如src属性值等于“http://192.168.60.192:8024/pic/minjian/20200405/re34.png ”。但是这种方式的坏处是写死了IP和端口号,将来若是将前端项目部署在其他服务器上,需要重新修改前端代码。而第一种方式就不会出现这种问题。

3  结  论

至此,我们的系统就能正式运行。我们选择将前后端分离开发的项目分别部署到Linux服务器上,相对window系统而言,具有稳定性好,不易受到攻击,硬件维护成本低的特点。同时使用nginx的反向代理,我们很好的保护了我们内网服务器的安全性,暴露在公网上的IP和端口越少,我们的系统更加的安全,更好的解决了公网IP或者端口号如何跨域访问我们的内网服务器上的服务,同时使用docker容器化的部署,也大大提升了部署的效率。

参考文献:

[1] 李彬,朱亚兴.Nginx在实现网站负载均衡方面的研究 [J].信息与电脑:理论版,2013(22):49-50.

[2] 伍春生.Nginx负载均衡技术在高速公路视频云联网平台中的应用 [J].上海船舶运输科学研究所学报,2021,44(1):60-64.

[3] 谭畅,谭歆,胡磊,等.云中心基于Nginx的动态权重负载均衡算法 [J].重庆邮电大学学报:自然科学版,2021,33(6):991-998.

[4] 郝淑惠.基于Nginx的Web服务器负载均衡策略改进与实现 [J].电子技术与软件工程,2019(2):23.

[5] 黎宇.Nginx在不同网络域名访问中的应用 [J].通讯世界,2019,26(2):88-89.

[6] 张文新.基于Linux的“数据保护+备份”架构——文件防篡改 [J].内蒙古科技与经济,2021(20):90-91+122.

作者简介:崔娟(1995—),女,汉族,甘肃白银人,研究实习员,本科,研究方向:大数据、软件工程;王伟民(1970—),男,汉族,甘肃兰州人,高级工程师,本科,研究方向:信息化、农业工程;冯继虎(1982—),男,汉族,甘肃陇南人,工程师,本科,研究方向:科技管理与服务;李怀堂(2000—),男,汉族,甘肃民勤人,本科,研究实习员,研究方向:数据库加密;王林柱(1997—),男,汉族,甘肃静宁人,研究实习员,本科,研究方向:高性能计算。

猜你喜欢

跨域安全
跨域异构体系对抗联合仿真试验平台
基于多标签协同学习的跨域行人重识别
为群众办实事,崂山区打出“跨域通办”组合拳
G-SRv6 Policy在跨域端到端组网中的应用
物联网环境下的跨域信任评价研究
基于岗位映射的应急组织间跨域访问控制研究