一、背景
近期公司业务涉及到微信小程序,即将开发完成需要按照微信小程序平台的要求提供带证书的域名请求服务器。
资源背景介绍如下:
1、域名
公司已有一个二级域名,再次申请新的二级域名并且实现ICP备案不仅需要花重金重新购买,还需要等待备案将近一个月。于是决定借用已有的二级域名将请求绑定到443以外的端口,理想的最终访问形式为:https://erp.aikes.com:8066/xxx/xxx.html(微信小程序也支持该种配置)
2、证书
公司的二级域名上已经绑定证书,新部署的服务也需要有SSL证书认证,否则https请求无法通过。有背景一的担保,该服务复用证书亦是可行的。
3、代理
为安全起见,新部署的服务不再使用线上正在跑的服务器,仅通过代理将请求转发到新的服务器。我们将微信小程序涉及到的资源文件及后端服务部署到新服务器即可。
二、正文
正文中将分为几个部分进行操作记录,尽可能完整的复述当时出现的问题已经整改方案
1、代理和证书的纠葛
关于代理的使用,和同事沟通后初步拟定了两种方案:1、通过Nginx代理;2、通过netsh实现TCP端口转发。
出于安全性以及独立性考虑,尽可能小的影响线上服务器的情况下选择了Nginx进行代理,完整流程:监听目标端口,配置SSL证书,转发请求到目标服务器。
以下是Nginx的配置文件 nginx.conf,证书文件放到同级的conf目录即可:
worker_processes 5; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; client_body_buffer_size 100m; client_max_body_size 100m; # HTTPS server server { listen 8066 ssl; server_name erp.aikes.com; ssl_certificate cert/erp_aikes_com_integrated.crt; ssl_certificate_key cert/erp_aikes_com.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { proxy_pass https://192.168.10.236:8066; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_connect_timeout 60; proxy_read_timeout 300; proxy_send_timeout 300; } } }
上述转发的配置中,跳转到内网的10.236机器正是我们新申请的服务器,8066端口为Tomcat使用,此处配置为https请求的话,Tomcat中也需要增加SSL证书实现https协议。
也可以将其配置为http,则Tomcat也不需要增加证书。整个客户端请求的证书认证在Nginx端已经处理完毕。
以下是新服务器(10.236:8066)上Tomcat增加SSL证书配置 server.xml (核心部分):
<Connector executor="tomcatThreadPool" port="1001" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8066" protocol="org.apache.coyote.http11.Http11Nio2Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" keystoreFile="conf/erp_aikes_com.jks" keystoreType="JKS" keystorePass="cT6W2buDs4LEbKMV" clientAuth="false" SSLProtocol="TLSv1.1+TLSv1.2+TLSv1.3" />
上述Tomcat配置中需要将生成的jks证书放到同级conf目录下,笔者除了8066的 https 端口还额外开放了1001的http端口用于前端调试。
PS:需要注意的是,如果Tomcat服务集成到了windows服务中,在变动证书配置后需要将服务卸载重新装载到windows services才会生效,这是一个大坑,笔者调试一下午一直以为是证书不对,结果偶然点了startup.bat启动后正常了,进而才发现是services中配置未生效导致。
2、证书和域名的关系
通过上述配置,整个流程已经可以跑同,通过域名+端口+路由可以访问到我们目标服务器的目标服务上。
此时记录一个域名访问的小知识,我们的证书申请是通过域名进行绑定的,所以证书生效的前提是通过域名访问。如果使用域名背后的真是IP进行https访问仍会提示网站不安全。
所以,证书的世界是因为有域名而多姿多彩,没有域名的访问,证书一律不认可。
3、域名和代理的清白
域名可以作为IP的别称,而代理只是作为不同IP的相同或不同端口之间的请求转发,所以一定程度上来看,域名和代理是清清白白没有任何关系。
在上述配置中使用Nginx进行端口代理,最终效果使用域名访问时,会先通过DNS解析到具体IP,然后请求到IP+端口后发现是一个代理,进而通过代理跳转到真实服务器,获取请求结果返回客户端。
此时需要记录下代理的调整。在实际使用中并没有按照Nginx进行代理,而是采用了Windows服务器自带的netsh命令实现了TCP端口转发,其原因有二:1、Nginx体量过大,不适合单纯的请求转发;2、线上服务器使用Nginx频繁出现502请求异常,系Nginx关于请求转发的超时配置等问题。
所以最终决定使用netsh进行转发,此时担心的另一个问题出现:netsh需不需要携带SSL证书转发。查阅资料显示,netsh仅转发请求,目标服务器处理证书认证也是可以的。
具体netsh使用指南可以查看笔者另一篇博客:Windows服务器基于netsh命令实现请求转发
于是最终方案为:域名+端口+路由访问——>线上服务器netsh实现请求跳转——>目标服务器接收https请求并验证SSL证书——>处理请求将数据返回客户端浏览器
三、总结
在配置微信小程序涉及的资源文件和后端服务时,域名和代理的关系是相对独立且清晰的。域名在网络中充当IP地址的别称,而代理则是在不同IP或不同端口之间进行请求转发的工具。在实际操作中,通过Nginx进行端口代理可以有效实现请求的转发和SSL证书的管理,但考虑到服务器性能和稳定性,有时会选择使用Windows服务器自带的netsh命令来进行TCP端口转发。
关于域名,它的重要性在于SSL证书的有效性和安全性。SSL证书通常通过域名来绑定,只有通过正确的域名访问才能确保HTTPS连接的安全性,否则会出现浏览器提示网站不安全的情况。因此,域名在HTTPS访问中扮演了关键角色。
总结来说,域名和代理在微信小程序开发中的应用各有其重要性和功能,通过合理的配置和管理,可以确保系统的安全性和稳定性,提供良好的用户体验。