在 iPortal 中,您可以将服务代理和反向代理配合使用,为门户和服务的安全提供双重保障。其中,反向代理机制用于保障 iPortal 门户平台的安全,Nginx 代理服务器作为客户端与 iPortal 门户服务器间的屏障,负责接收并转发来自客户端的请求。代理服务器对外表现为一个服务器,客户端不知道内部网络其他服务器的存在,因此对内网服务器可以起到保护作用。iPortal 服务代理机制则提供门户级别的服务访问控制,在原始服务地址和代理服务地址间建立映射,使授权用户只能访问代理服务地址,隐藏原始服务地址,保护您注册服务的安全。

下面将详细介绍如何将服务代理与 Nginx 反向代理配合使用。首先,请确保您的 iPortal 开启了服务代理功能,具体配置信息请参见:服务代理配置

接下来需要对 Nginx 反向代理服务器进行配置。

启动 Nginx

以 Windows 系统为例:

  1. 解压 nginx 到指定目录
  2. 在 nginx 根目录下,通过以下命令启动 nginx:

start nginx

退出 nginx 命令如下:

nginx -s quit

  1. 验证 nginx 正常启动,有以下两种方式:
  • 打开任务管理器,查看 nginx 进程是否已启动。
  • 访问 http://127.0.0.1 或 http://localhost 时,页面出现 "Welcome to nginx!" 字样,则代表 nginx 已成功启动。

Nginx 与 iPortal 使用 HTTP 协议

配置 Nginx

打开【nginx 安装路径】\conf\nginx.conf 文件,修改 http 节点下的 server 节点内容如下:

server {

        listen       80;

        server_name  www.myiportal.com;

        location /{

            proxy_pass   http://192.168.120.52:8190/;

            proxy_set_header Host $host:80;

            proxy_set_header X-Read-IP $remote_addr;

            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                       }

        location /portalproxy/{

            proxy_pass   http://192.168.120.52:8195;

            proxy_set_header Host $host:80;

            proxy_set_header X-Read-IP $remote_addr;

            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                       }

           }

  • listen:设置反向代理的站点监听端口,默认为 80。
  • server_name:设置反向代理后的站点访问域名。
  • proxy_pass:设置需要转发的站点地址,可以是 IP 地址形式,也可以是域名形式。示例中需要转发的站点地址有两个,分别是 iPortal 的门户地址:http://192.168.120.52:8190/,以及启用服务代理后的服务根地址:http://192.168.120.52:8195。
  • proxy_set_header:设置用于转发请求的请求头。语法格式为 proxy_set_header Field Value,具体设置如下
  • Host:请求头字段,对应值 $host:80,传递服务器名及代理服务器端口。
  • X-Read-IP:自定义变量名,对应值  $remote_addr,用于获取真实的客户端 IP,而不是 Nginx 服务器的 IP。
  • X-Forwarded-For(可选):对应值 $proxy_add_x_forwarded_for,当使用两个及以上 Nginx 服务器进行反向代理时,用于获取真实的客户端 IP 和 Nginx 服务器 IP,保障代理服务器间的正常通信。

保存上述修改,重启 nginx 使其生效。重启命令如下所示:

nginx -s reload

如果需要配置多个 iPortal 的反向代理,或需要同时配置多个 iServer 的反向代理,您可以通过在 nginx.conf 中配置多个 server 节点实现。

注意:如果 Nginx 代理后的 iServer 服务注册到 iPortal 门户中,该服务又经过了 iPortal 的服务代理,为了保证经过两次代理后的 iServer 服务能够正常访问,建议以上 Host 参数设置为:Host $http_host。

如果需要匹配多个服务地址,您可以通过在 nginx.conf 中配置多个 location 实现。

 

配置 Nginx 允许客户端请求的最大单文件字节数

Nginx 默认允许客户端请求的最大单文件字节数为 1m,如果用户访问经过 Nginx 代理后的 iPortal,上传大的数据文件到门户中,此时 1m 是远远不够的,建议修改为 1024m,即允许一次最大上传 1024m 大小的数据文件,您也可以根据具体的业务需求进行配置,具体做法如下:

打开【nginx 安装路径】\conf\nginx.conf 文件,在 http 节点下增加如下一行代码:

client_max_body_size 1024m;

client_max_body_size:表示客户端请求服务器最大允许大小,单位是兆。如果请求的数据量大于 client_max_body_size 中设置的值,HTTP协议会报错 413: "Request Entity Too Large",因此当您上传的数据量较大时,需要将参数值改大。

注意:如果在完成以上配置后, iPortal 上传数据量较大的文件时仍卡顿,您需要继续修改 http 节点下 client_max_body_size 和 keepalive_timeout 的内容,设置更大的值,具体请参见:FAQ

 

配置 iPortal

要实现启用服务代理后的服务地址也被反向代理,同时隐藏代理服务端口,还需对 iportal.xml 文件进行配置,位于【SuperMap iPortal 安装目录】\webapps\iportal\WEB-INF 文件夹下。在 iportal.xml 配置文件中的 <serviceProxy> 节点下增加 <proxyServerRootUrl> 节点,设置反向代理服务的根地址。由于代理服务地址中 Host 主机有两种显示方式:域名或 IP,因此,<proxyServerRootUrl> 节点有两种配置方式:

方式一:域名形式

<serviceProxy>

    <enable>true</enable>  

    <port>8195</port>  

    <proxyServerRootUrl>http://www.myiportal.com[:port]</proxyServerRootUrl>  

    <httpConnPoolInfo>

      <maxTotal>20</maxTotal>  

      <defaultMaxPerRoute>2</defaultMaxPerRoute>

    </httpConnPoolInfo>

  </serviceProxy>

方式二:IP 形式,此配置会使代理服务地址根据用户当前的网络环境,动态显示 IP 地址。

<serviceProxy>

    <enable>true</enable>  

    <port>8195</port>  

    <proxyServerRootUrl>http://{ProxyHost}[:port]</proxyServerRootUrl>  

    <httpConnPoolInfo>

      <maxTotal>20</maxTotal>  

      <defaultMaxPerRoute>2</defaultMaxPerRoute>

    </httpConnPoolInfo>

  </serviceProxy>

配置完成后,重启 iPortal 服务。

注意:以上两种配置方式中,[:port]变量表示端口,填写代理后的服务监听端口即可,可以为空,为空默认为 80 端口。

Nginx 与 iPortal 使用 HTTPS 协议

配置 Nginx

  1. 下载并安装 nginx 后,切换至 nginx 安装目录,在命令行中输入如下命令启动 nginx:

start nginx

  1. 向域名服务商购买域名、进行备案,并将域名映射到 nginx 所在机器的公网 IP。
  2. 向官方 CA 机构申请两份 SSL 证书,分别用于 nginx 与 iPortal 配置。
  3. 配置代理转发规则。打开【nginx 安装目录】/conf/nginx.conf 配置文件,添加一个新的 server 节点,如下:

server {
      listen 443;
      server_name www.iportal.com;
      ssl on;
      ssl_certificate E:\nginx.cer;
      ssl_certificate_key E:\nginx.key;
      ssl_session_timeout 5m;
      ssl_protocols SSLv2 SSLv3 TLSv1;
      ssl_ciphers HIGH:!aNULL:!MD5;
      ssl_prefer_server_ciphers on;
      location / {
            proxy_pass https://192.168.13.69:8190;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      }
      location ~*/iserver/services/{
            proxy_pass https://192.168.13.69:8195;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      }
      location ~*\w*/iserver/services/{
            proxy_pass ttps://192.168.13.69:8195;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      }
}

粗体部分说明如下:

  • listen:nginx 监听端口。443 为网页服务器的默认 https 端口,网址后可不带端口直接访问;
  • server_name:配置给 iPortal 的域名,需根据实际申请的域名进行修改;
  • ssl_certificate:nginx 使用的 SSL 证书文件路径;
  • ssl_certificate_key:nginx 使用的 SSL 私钥文件路径;
  • proxy_pass:代理转发的目标地址。其中第一个 proxy_pass 为 iPortal 原始服务地址,后两个 proxy_pass 为 iPortal 代理地址,需根据您实际部署的 iPortal IP 和端口进行修改。
  1. 在命令行中输入如下命令,重新加载 nginx 配置使其生效:

nginx -s reload

配置 iPortal

  1. 打开【iPortal 安装目录】/webapps/iportal/WEB-INF/iportal.xml 文件,修改如下粗体部分:

<serviceProxy>
<!-- 注册、托管的服务是否使用代理,默认值:true,开启服务代理功能 -->
      <enable>true</enable>
      <!-- 是否启用内置的代理服务,默认值:true ,使用 iPortal 内置代理,当您使用独立进程代理时,需设置为 false -->
      <enableBuiltinProxy>true</enableBuiltinProxy>
      <port>8195</port>
      <rootUrlPostfix><rootUrlPostfix>
      <proxyServerRootUrl>https://{ProxyHost}</proxyServerRootUrl>
      <httpConnPoolInfo>
            <maxTotal>100</maxTotal>
            <defaultMaxPerRoute>10</defaultMaxPerRoute>
            <connectionTimeout>30000</connectionTimeout>
            <socketTimeout>30000</socketTimeout>
      </httpConnPoolInfo>
      <!-- 设置使用什么协议启动代理服务,默认使用 http 协议。若设置 https 协议,需设置httpsSetting-->
      <scheme>https</scheme>
      <httpsSetting>
            <keyStorePath>D:\iPortal.pfx</keyStorePath>
            <keyStorePassword>xxxxxx</keyStorePassword>

      </httpsSetting>

参数说明如下:

  • rootUrlPostfix:代理服务根地址的后缀名,默认为 portalproxy。此处设为空值,不携带后缀名;
  • proxyServerRootUrl:代理服务根地址。设为 https://{ProxyHost} 后,iPortal 将自动识别当前域名,动态显示代理服务地址;
  • scheme:代理服务使用的协议。修改为 https,以 HTTPS 协议启用代理服务;
  • keyStorePath:iPortal 的 SSL 证书文件路径;
  • keyStorePassword:iPortal 的 SSL 证书私钥。
  1. 将 iPortal 配置为以 HTTPS 协议启动。 打开【iPortal 安装目录】/conf/server.xml 文件,添加如下内容:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
      maxThReads="150"
      scheme="https"
      secure="true"
      SSLEnabled="true"
      keystoreFile="D:/iportal.pfx"
      keystorePass="xxxxxx"

      clientAuth="false"
      sslProtocol="TLS"
      sslEnabledProtocols="TLSv1.2"/>

其中 keystoreFile 和 keystorePass 分别为 iPortal 的 SSL 证书文件和私钥密码。您还可注释掉以下内容以关闭 HTTP:

<Connector port="8090" protocol="HTTP/1.1"
      relaxedQueryChars="[]|{}"
      relaxedPathChars="[]|{}"
      connectionTimeout="8000"
      redirectPort="8453"
      executor="tomcatThreadPool"
      enableLookups="false"
      URIEncoding="utf-8"
      compression="on"
      compressionMinSize="2048"
      compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css,application/javascript,application/xml,application/json,application/rjson"/>

  1. 在 iPortal 配置好 SSL 之后,为避免出现 “Cookie 中缺少 Secure 属性” 的安全漏洞,可以通过中间件添加 Secure 属性,在 SuperMap iPortal 安装目录/conf/web.xml 下,找到如下配置:

<session-config>
      <session-timeout>30</session-timeout>
</session-config>

修改为:

<session-config>
      <session-timeout>30</session-timeout>
      <cookie-config>
            <http-only>true</http-only>
            <secure>true</secure>
      </cookie-config>
</session-config>

  1. 启动 iPortal,即可通过域名 https://www.iportal.com 访问 iPortal。

Nginx 使用 HTTPS 协议,iPortal 使用 HTTP 协议

除了 Nginx 与 iPortal 均使用 HTTP 或 HTTPS 协议外,您也可以选择 Nginx 使用 HTTPS 协议,iPortal 使用 HTTP 协议。

配置 Nginx

【Nginx安装目录】/conf/nginx.conf中,配置 SSL 证书。SSL 证书由客户单位使用政务网 IP 向 CA 机构申请,包括私钥 *.*.*.*.key 和证书*.*.*.*.cer 两个文件,在文件 server 节点中配置如下:

server {
        listen 443 ssl;
        server_name  localhost 10.150.145.118 *.*.*.*;
        ssl_certificate      sslkey/*.*.*.*.cer;
        ssl_certificate_key  sslkey/*.*.*.*.key;
        ssl_session_timeout  5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
        ssl_prefer_server_ciphers  on;
}

  • listen:nginx 监听端口。443 为网页服务器的默认 https 端口,网址后可不带端口直接访问;
  • server_name:配置给 iPortal 的域名,需根据实际申请的域名进行修改;
  • ssl_certificate:nginx 使用的 SSL 证书文件路径;
  • ssl_certificate_key:nginx 使用的 SSL 私钥文件路径。

location 指令根据不同的 URI,匹配到 SuperMap iPortal 或 SuperMap iPortal Proxy,把 HTTPS 重定向成 HTTP,同时保持请求 scheme 信息相同。
继续编辑【Nginx安装目录】/conf/nginx.conf,在文件server节点中配置如下:

location / {
    proxy_pass   http://10.150.145.104:8190;
    proxy_redirect http:// https://;     
    proxy_set_header Host $http_host;
    proxy_set_header Referer $http_referer;
    proxy_set_header Cookie  $http_cookie;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $server_addr;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_set_header X-Forwarded-Proto $scheme;
      }
 
  location ~* /portalproxy/ {
    proxy_pass   http://10.150.145.53:8195;
    proxy_redirect http:// https://;     
    proxy_set_header Host $http_host;
    proxy_set_header Referer $http_referer;
    proxy_set_header Cookie  $http_cookie;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $server_addr;
    proxy_set_header X-Forwarded-Port $server_port;
    proxy_set_header X-Forwarded-Proto $scheme;
   }

  • proxy_pass:代理转发的目标地址。其中第一个 proxy_pass 为 iPortal 原始服务地址,后两个 proxy_pass 为 iPortal 代理地址,需根据您实际部署的 iPortal IP 和端口进行修改。

配置修改完成后,需要 Nginx 重新加载配置文件,在重新加载配置文件前,最好使用命令检查 Nginx 配置。

Nginx 检查配置文件

/usr/local/openresty/nginx/sbin/nginx -t

Nginx 重新加载配置文件

/usr/local/openresty/nginx/sbin/nginx -s reload

 

配置 iPortal

在 SuperMap iPortal 中分别修改以下三个配置文件:

  • 【SuperMap iPortal安装目录】/conf/server.xml,非必须但建议配置
  • 【SuperMap iPortal安装目录】/webapps/iportal/WEB-INF/web.xml
  • 【SuperMap iPortal安装目录】/webapps/iportal/WEB-INF/iportal.xml
  1. 此步骤非必须但建议配置。在【SuperMap iPortal安装目录】/conf/server.xml 中,修改 Connector 节点,将其属性 redirectPort 修改为 redirectPort="443",对于非 SSL 请求,自动将请求重新定位到 redirectPort 指定端口,同时添加属性 proxyPort="443",表示该连接器在代理中被使用。配置后,访问 http://ip:8190 会被强制重定向到 https://ip:443。

<Connector port="8190" protocol="HTTP/1.1"
               relaxedQueryChars="[]|{}"
               relaxedPathChars="[]|{}"
               connectionTimeout="8000"
               redirectPort="443" proxyPort="443"
               executor="tomcatThreadPool"
               enableLookups="false"
               URIEncoding="utf-8"
               compression="on"
               compressionMinSize="2048"
               compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css,application/javascript,application/xml,application/json,application/rjson" />

  1. 在【SuperMap iPortal安装目录】/webapps/iportal/WEB-INF/web.xml 中,新增如下配置:

在所有的<filter-mapping>之前的<filter>配置列表的任意位置,添加如下 <filter> 配置: 

<filter>        

    <filter-name>remoteIpFilter</filter-name>        

    <filter-class>com.supermap.services.filter.RemoteIpFilter</filter-class>

</filter>

在<filter-mapping>配置列表中的<filter-name>是 iserver-services 的前面,添加如下<filter-mapping>配置:

<filter-mapping>        

    <filter-name>remoteIpFilter</filter-name>        

    <url-pattern>/*</url-pattern>

</filter-mapping>

  1. 在【SuperMap iPortal安装目录】/webapps/iportal/WEB-INF/config/proxy/WEB-INF/web.xml 中,内置代理服务的配置文件新增如下配置:

在所有的<filter-mapping>之前的<filter>配置列表的任意位置,添加如下 <filter> 配置: 

<filter>        

    <filter-name>remoteIpFilter</filter-name>        

    <filter-class>com.supermap.services.filter.RemoteIpFilter</filter-class>

</filter>

在<filter-mapping>配置列表中的<filter-name>是 proxyTunnelFilter 前面,添加如下<filter-mapping>配置:

<filter-mapping>        

    <filter-name>remoteIpFilter</filter-name>        

    <url-pattern>/*</url-pattern>

</filter-mapping>

  1. 在【SuperMap iPortal安装目录】/webapps/iportal/WEB-INF/iportal.xml,修改端口 port、代理服务根地址设置统一的后缀名 rootUrlPostfix 和服务代理后的服务地址 proxyServerRootUrl。

<!-- 注册、托管的服务是否使用代理,默认值:true,开启服务代理功能 --> 
    <enable>true</enable> 
    <!-- 是否启用内置的代理服务,默认值:true ,使用iPortal内置代理,当您使用独立进程代理时,需设置为false --> 
    <enableBuiltinProxy>true</enableBuiltinProxy>
    <port>8195</port> 
    <rootUrlPostfix>portalproxy</rootUrlPostfix>
    <proxyServerRootUrl>https://{ProxyHost}</proxyServerRootUrl> 
    <httpConnPoolInfo>
      <maxTotal>100</maxTotal> 
      <defaultMaxPerRoute>10</defaultMaxPerRoute> 
      <connectionTimeout>30000</connectionTimeout> 
      <socketTimeout>30000</socketTimeout>
    </httpConnPoolInfo>

  • port:云 GIS 门户平台代理包 SuperMap iPortal Proxy 使用 8195 端口。
  • rootUrlPostfix:代理服务根地址设置统一的后缀名设置为 portalproxy,可以根据需要灵活定制,和 SuperMap iPortal Proxy 中配置保持一致。
  • proxyServerRootUrl:代理后服务地址 proxyServerRootUrl 中修改为 {ProxyHost},没有使用固定的 IP 或域名,使用 {ProxyHost} 会使代理服务地址根据用户当前的网络环境,动态显示 IP。且没有指定端口号,使用 HTTPS 协议默认的 443 端口。
  1. 上述配置修改完成后,需要重启 SuperMap iPortal,您的项目即可以对外提供满足 HTTPS 协议的 GIS 服务。

访问门户和代理服务

在完成以上配置后,您通过访问 Nginx 反向代理服务器的 IP 即可获得与访问原 iPortal 门户相同的内容,例如:http://192.168.120.40:80,其中,默认的 80 端口可以隐藏。启用服务代理后的服务根地址也将变成:http://192.168.120.40:80,从而也隐藏了服务代理端口 “8195”。

在实际的业务应用中,如果您想使用域名访问 iPortal 门户和服务,那么您需要将 Nginx 反向代理服务器的 IP 绑定为域名,然后通过该域名访问反向代理后的门户,即 http://www.myiportal.com:80,同时,启用服务代理后的服务根地址也将变成:http://www.myiportal.com:80。