增加云星空业务站点安全IP检查原创
金蝶云社区-yaojunsong
yaojunsong
5人赞赏了该文章 568次浏览 未经作者许可,禁止转载编辑于2023年02月28日 14:54:05

增加云星空业务站点安全IP检查


一、功能描述

    安全加固,仅允许来自已经授权的网关IP访问云星空,未授权的一律拒绝。


二、部署

    增加站点资源IP拦截器,适用于云星空。
    1、解压KDExt_IPSecUrlBlocking.zip中的KDExt_IPSecUrlBlocking.dll到website/bin目录;

    2、配置website/web.config的modules拦截器;

   <!-- website/web.config 找到 defaultPageModule 插件,
          在该插件下面增加一行定制url拦截插件 
          路径:[configuration/system.webServer/modules]-->   
   <add name="KDExt_IPSecUrlBlocking" type="KDExt_IPSecUrlBlocking.IPSecModule,KDExt_IPSecUrlBlocking" />

    3、配置website/app_data/common.config的拦截资源类型和允许IP列表, 允许IP段设置如:192.168.;

   <!-- 拦截资源类型,类型数量需要与性能需求平衡,分号分割 -->
   <add key="_BlockIpSecTypeList" value="aspx;js;html;htm;css;ashx;svc;asmx;jsp;php;jhtml;txt;" />
   <!-- 业务站点允许访问IP,数量需要与性能需求平衡,分号分割。 -->
   <!-- 支持安全IP段设置,比如对 192.168.255.255的所有ip都允许,则写入192.168.;即可,如下例子 -->
   <add key="_IndexIpSecList" value="::1;localhost;127.0.0.1;192.168.;ip1;ip2;ip3" />
    4、重启IIS;

    5、拦截效果(需要允许ip,把拒绝后面的ip写入白名单即可,支持私有云的ipv6网关地址);


三、拦截效果

    如果需要允许改ip入口,仅需要把下面红线ip写入common.config的 _IndexIpSecList 参数列表即可;


    image.png


四、二开定制自己的拦截模块(参考代码)

    任何安全措施都是相对而言的,浏览器基于安全不允许获取本机信息,因此作为通用方案只能在httprequest请求头中获取可用信息来进行校验匹配,基于这个思路,可在此IPSec基础代码之上,二开考虑用httprequest请求头的参数做更多严格控制,IPSec的参考代码如下: 


using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using Kingdee.BOS;
using Kingdee.BOS.Log;
using Kingdee.BOS.Util;

namespace KDExt_IPSecUrlBlocking
{
    public class IPSecModule : IHttpModule
    {
        /* 增加aspx等资源的页面IP拦截器
         配置:
            <!-- website/web.config 找到 defaultPageModule 插件,在该插件下面增加一行定制url拦截插件 -->
            路径:[configuration/system.webServer/modules]
            <add name="KDExt_IPSecUrlBlocking" type="KDExt_IPSecUrlBlocking.IPSecModule,KDExt_IPSecUrlBlocking" />

            <!-- website/app_data/common.config 添加拦截页面类型和允许ip -->
            路径:[configuration/appSettings]
            <!-- 拦截页面类型,分号分割 -->
            <add key="_BlockIpSecTypeList" value="aspx;js;html;htm;css;" />
            <!-- 允许访问IP,分号分割 -->
            <add key="_IndexIpSecList" value="localhost;127.0.0.1;119.145.5.245;123.60.238.48;10.203.54.211" /> 
         
         测试:
            https://xxx/k3cloud/html5/index.aspx;  https://xxx/k3cloud/error.html; 
         */


        public void Init(HttpApplication context)
        {
            context.BeginRequest += context_BeginRequest;
        }
        void context_BeginRequest(object sender, EventArgs e)
        {
            string key = string.Empty;
            try
            {
                var ctx = sender as HttpApplication;
                var req = ctx != null ? ctx.Request : null;
                var resp = ctx != null ? ctx.Response : null;

                if (req == null || req == null || !UrlVerify(req, resp))
                {
                    ctx.Response.End();
                    return;
                }
            }
            catch (ThreadAbortException aex)
            {
                //do nothing
            }
            catch (Exception ex)
            {
                Kingdee.BOS.Log.Logger.Info("IPSecUrlBlocking.IPSecModule",
                    string.Format("Key={0}\t{1}\t{2}", key, ex.Message, ex.StackTrace));
            }
        }

        public void Dispose()
        {
        }

        /// <summary>
        /// IPSecure
        /// </summary>
        /// <returns></returns>
        private static bool UrlVerify(HttpRequest req, HttpResponse resp)
        {
            var ret = true;
            try
            {
                var rawUrl = string.Format("{0};{1}", req.RawUrl, req.Url.AbsoluteUri).ToLowerInvariant();

                var blockTypes = KDConfiguration.Current.GetAppSettingItemValue("_BlockIpSecTypeList");
                var blockTypeLst = (string.IsNullOrWhiteSpace(blockTypes) ? string.Empty : blockTypes).Split(';');
                var eclutype = true;
                foreach (var ty in blockTypeLst)
                {
                    if (!string.IsNullOrWhiteSpace(ty))
                    {
                        var tyR = new Regex("\\/[\\w]{0,}." + ty, RegexOptions.IgnoreCase);
                        if (tyR.IsMatch(rawUrl))
                        {
                            eclutype = false;
                            break;
                        }
                    }
                }
                if (eclutype)
                {
                    return ret;
                }

                var sb = new StringBuilder();
                sb.AppendFormat("{0} {1}", req.RawUrl, req.Headers.ToString());
                var url = Kingdee.BOS.KDHttpUtility.RequestUtility.UrlDecode(sb.ToString());

                var _ipLstStr = KDConfiguration.Current.GetAppSettingItemValue("_IndexIpSecList");
                var targetIp = "";
                if (!string.IsNullOrWhiteSpace(_ipLstStr))
                {
                    ret = false;
                    var lurl = url.ToLowerInvariant();
                    var lst = _ipLstStr.Split(';');
                    var rip = new Regex("\\&X\\-Real\\-IP\\=[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}\\&", RegexOptions.IgnoreCase);
                    var m = rip.Match(lurl);
                    targetIp = m != null ? m.Value : req.UserHostAddress;
                    if (!string.IsNullOrWhiteSpace(targetIp))
                    {
                        targetIp = targetIp.ToLowerInvariant().Replace("&", "").Replace("x-real-ip=", "");
                    }
                    if (string.IsNullOrWhiteSpace(targetIp))
                    {
                        targetIp = req.UserHostAddress;
                    }

                    foreach (var ip in lst)
                    {
                        if (!string.IsNullOrWhiteSpace(ip))
                        {
                            var ipRgR = new Regex(string.Format("\\&X\\-Real\\-IP\\={0}", ip), RegexOptions.IgnoreCase);
                            //var ipRgF = new Regex(string.Format("\\&X\\-Forwarded\\-For\\={0}", ip), RegexOptions.IgnoreCase);
                            if (ipRgR.IsMatch(lurl) || req.UserHostAddress.StartsWith(ip))
                            {
                                ret = true;
                                break;
                            }
                        }
                    }
                    if (!ret)
                    {
                        var msgsb = new StringBuilder();
                        msgsb.AppendLine(string.Format("Access denied from [{0}]!", targetIp));
                        resp.Clear();
                        resp.ContentType = "text/plain; charset=utf-8";
                        resp.Write(msgsb.ToString());
                        resp.End();
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("IPSec", "IPSecUrlBlocking.IPSecModule", ex);
            }
            return ret;
        }
    }
}


五、更高的安全要求方案:

    如有更高的安全需求,可考虑购买市面上的零信任安全代理或网关服务,来获取更高的网络安全属性。


-------------------------------

创建于   2022-06-15 09:32

编辑于   2022-06-24 09:56:31

赞 5