温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么配置nginx的反向代理

发布时间:2021-11-15 10:52:36 来源:亿速云 阅读:203 作者:iii 栏目:大数据

这篇文章主要讲解了“怎么配置nginx的反向代理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么配置nginx的反向代理”吧!

tomcat使用了nginx反向代理,获取的服务器路径变成了nginx中配置的内网地址,如果在同一台服务器上,就变成了127.0.0.1或是localhost,而我们需要的是外网地址,这时候我们需要启用转发的请求头配置

如何启用?下面通过查看源码找一下如何解决

很多人都会强调看源码,如果在没有目的的情况下直接看源码比较枯燥,很难坚持(大神略过),不会有太大的收获。如果我们遇到问题,很多时候都是网上一百度,配置项或是代码复制粘贴,然后测试一下没有问题就过了,但是如果网上的信息很少,或者几乎找不到解决办法,这时候,我们查看一下源码,找到对应实现,有时候直接就能发现问题在哪,我认为这种时候就是读源码的最好时机,利用好eclipse或是intellij IDEA的搜索功能,一般都可以找到对应的源码

先来看一下spring boot tomcat源码  TomcatWebServerFactoryCustomizer类

private void  customizeRemoteIpValve(ConfigurableTomcatWebServerFactory  factory) {           Tomcat tomcatProperties =  this.serverProperties.getTomcat();           String protocolHeader =  tomcatProperties.getProtocolHeader();           String remoteIpHeader =  tomcatProperties.getRemoteIpHeader();           // For back compatibility the valve is also  enabled if protocol-header is set           if (StringUtils.hasText(protocolHeader) ||  StringUtils.hasText(remoteIpHeader)                    || getOrDeduceUseForwardHeaders()) {               RemoteIpValve valve = new RemoteIpValve();               valve.setProtocolHeader(StringUtils.hasLength(protocolHeader) ? protocolHeader                         : "X-Forwarded-Proto");               if (StringUtils.hasLength(remoteIpHeader))  {                    valve.setRemoteIpHeader(remoteIpHeader);               }               // The internal proxies default to a white  list of "safe" internal IP               // addresses               valve.setInternalProxies(tomcatProperties.getInternalProxies());               valve.setPortHeader(tomcatProperties.getPortHeader());               valve.setProtocolHeaderHttpsValue(                         tomcatProperties.getProtocolHeaderHttpsValue());               // ... so it's safe to add this valve by  default.               factory.addEngineValves(valve);           }      }

可以看出,只要protocolHeader和remoteIpHeader任意一项有值就启用了RemoteIpValve

spring boot 对应配置项在Tomcat类里面:

server.use-forward-headers=true server.tomcat.remote-ip-header=x-forwarded-for server.tomcat.protocol-header=X-Forwarded-Proto

获取服务器地址的实现在RemoteIpValve类的invoke方法里面

 public void invoke(Request request, Response response)  throws IOException, ServletException {         final String originalRemoteAddr =  request.getRemoteAddr();         final String originalRemoteHost =  request.getRemoteHost();         final String originalScheme = request.getScheme();         final boolean originalSecure = request.isSecure();         final int originalServerPort =  request.getServerPort();         final String originalProxiesHeader =  request.getHeader(proxiesHeader);         final String originalRemoteIpHeader =  request.getHeader(remoteIpHeader);         boolean isInternal = internalProxies != null &&                  internalProxies.matcher(originalRemoteAddr).matches();         if (isInternal || (trustedProxies != null &&                  trustedProxies.matcher(originalRemoteAddr).matches())) {             String remoteIp = null;             // In java 6, proxiesHeaderValue should be  declared as a java.util.Deque             LinkedList<String> proxiesHeaderValue = new  LinkedList<>();             StringBuilder concatRemoteIpHeaderValue = new  StringBuilder();             for (Enumeration<String> e =  request.getHeaders(remoteIpHeader); e.hasMoreElements();)  {                 if (concatRemoteIpHeaderValue.length() > 0)  {                     concatRemoteIpHeaderValue.append(", ");                 }                  concatRemoteIpHeaderValue.append(e.nextElement());             }             String[] remoteIpHeaderValue =  commaDelimitedListToStringArray(concatRemoteIpHeaderValue.toString());             int idx;             if (!isInternal) {                  proxiesHeaderValue.addFirst(originalRemoteAddr);             }             // loop on remoteIpHeaderValue to find the  first trusted remote ip and to build the proxies chain             for (idx = remoteIpHeaderValue.length - 1; idx  >= 0; idx--) {                 String currentRemoteIp =  remoteIpHeaderValue[idx];                 remoteIp = currentRemoteIp;                 if (internalProxies !=null &&  internalProxies.matcher(currentRemoteIp).matches()) {                     // do nothing, internalProxies IPs are  not appended to the                 } else if (trustedProxies != null &&                          trustedProxies.matcher(currentRemoteIp).matches()) {                      proxiesHeaderValue.addFirst(currentRemoteIp);                 } else {                     idx--; // decrement idx because break  statement doesn't do it                     break;                 }             }             // continue to loop on remoteIpHeaderValue to  build the new value of the remoteIpHeader             LinkedList<String> newRemoteIpHeaderValue =  new LinkedList<>();             for (; idx >= 0; idx--) {                 String currentRemoteIp =  remoteIpHeaderValue[idx];                  newRemoteIpHeaderValue.addFirst(currentRemoteIp);             }             if (remoteIp != null) {                 request.setRemoteAddr(remoteIp);                 request.setRemoteHost(remoteIp);                 if (proxiesHeaderValue.size() == 0) {                      request.getCoyoteRequest().getMimeHeaders().removeHeader(proxiesHeader);                 } else {                     String commaDelimitedListOfProxies =  listToCommaDelimitedString(proxiesHeaderValue);                      request.getCoyoteRequest().getMimeHeaders().setValue(proxiesHeader).setString(commaDelimitedListOfProxies);                 }                 if (newRemoteIpHeaderValue.size() == 0) {                      request.getCoyoteRequest().getMimeHeaders().removeHeader(remoteIpHeader);                 } else {                     String  commaDelimitedRemoteIpHeaderValue =  listToCommaDelimitedString(newRemoteIpHeaderValue);                      request.getCoyoteRequest().getMimeHeaders().setValue(remoteIpHeader).setString(commaDelimitedRemoteIpHeaderValue);                 }             }             if (protocolHeader != null) {                 String protocolHeaderValue =  request.getHeader(protocolHeader);                 if (protocolHeaderValue == null) {                     // Don't modify the secure, scheme and  serverPort attributes                     // of the request                 } else if  (isForwardedProtoHeaderValueSecure(protocolHeaderValue))  {                     request.setSecure(true);                      request.getCoyoteRequest().scheme().setString("https");                     setPorts(request, httpsServerPort);                 } else {                     request.setSecure(false);                      request.getCoyoteRequest().scheme().setString("http");                     setPorts(request, httpServerPort);                 }             }             if (log.isDebugEnabled()) {                 log.debug("Incoming request " +  request.getRequestURI() + " with originalRemoteAddr '" +  originalRemoteAddr                           + "', originalRemoteHost='" +  originalRemoteHost + "', originalSecure='" +  originalSecure + "', originalScheme='"                           + originalScheme + "' will be seen  as newRemoteAddr='" + request.getRemoteAddr() + "',  newRemoteHost='"                           + request.getRemoteHost() + "',  newScheme='" + request.getScheme() + "', newSecure='" +  request.isSecure() + "'");             }         } else {             if (log.isDebugEnabled()) {                 log.debug("Skip RemoteIpValve for request "  + request.getRequestURI() + " with originalRemoteAddr '"                         + request.getRemoteAddr() + "'");             }         }         if (requestAttributesEnabled) {              request.setAttribute(AccessLog.REMOTE_ADDR_ATTRIBUTE,                     request.getRemoteAddr());              request.setAttribute(Globals.REMOTE_ADDR_ATTRIBUTE,                     request.getRemoteAddr());              request.setAttribute(AccessLog.REMOTE_HOST_ATTRIBUTE,                     request.getRemoteHost());              request.setAttribute(AccessLog.PROTOCOL_ATTRIBUTE,                     request.getProtocol());              request.setAttribute(AccessLog.SERVER_PORT_ATTRIBUTE,                      Integer.valueOf(request.getServerPort()));         }         try {             getNext().invoke(request, response);         } finally {             request.setRemoteAddr(originalRemoteAddr);             request.setRemoteHost(originalRemoteHost);             request.setSecure(originalSecure);              request.getCoyoteRequest().scheme().setString(originalScheme);             request.setServerPort(originalServerPort);             MimeHeaders headers =  request.getCoyoteRequest().getMimeHeaders();             if (originalProxiesHeader == null ||  originalProxiesHeader.length() == 0) {                 headers.removeHeader(proxiesHeader);             } else {                  headers.setValue(proxiesHeader).setString(originalProxiesHeader);             }             if (originalRemoteIpHeader == null ||  originalRemoteIpHeader.length() == 0) {                 headers.removeHeader(remoteIpHeader);             } else {                  headers.setValue(remoteIpHeader).setString(originalRemoteIpHeader);             }         }     }

实现在大致过程是如果启用RemoteIpValve,会去获取指定的请求头,更新RemoteAddr和Scheme的值,以及https转的http服务,secure表示是否是https服务

那么就需要在nginx中配置好我们服务的请求地址,也就是host请求头

对应nginx配置项:   

proxy_set_header   Host             $host:$server_port;              proxy_set_header   X-Real-IP        $remote_addr; proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for; proxy_set_header   X-Forwarded-Port  $server_port; proxy_set_header   X-Forwarded-Proto  $scheme;

这样我们在后端服务中直接使用request.getRequestURL()方法就可以获取到我们在nginx中指定的服务器地址了,如果没有使用nginx,就不存在该问题,所以后端服务不需要考虑服务是否使用了反向代理

感谢各位的阅读,以上就是“怎么配置nginx的反向代理”的内容了,经过本文的学习后,相信大家对怎么配置nginx的反向代理这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI