失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 系统安全性和保密性设计

系统安全性和保密性设计

时间:2020-12-29 05:42:39

相关推荐

系统安全性和保密性设计

这个话题很大,我只是把我经历的或者说知道的,写一写,总总结,我并不是这方面的高手。

1 安全基础

1.1 国密算法

国家商用密码定义了一系列算法,我了解到的是SM2、SM3、SM4,因为国家对一些系统有安全要求,必须通过支持这三种算法,颁布相应授权证书。国密算法(国家商用密码算法简介)。

SM2是替代RSA的算法,算法流程参考图解SM2算法流程(合

几个算法对比可以参见 国密算法SM1/SM2/SM3/SM4,我并不关心算法的实现,因为我只需要购买加密机就可以了,只要加密机支持这些算法,对接加密机就可以了。

从下图很容易想到几个问题

1、根密钥如何保证安全

应用系统使用的密钥是分散出来的,那么根密钥很容易想到也应该做分散。然后就是根密钥的灌装了。

2、这个前置与加密机之前的通讯安全如何保障?

应用系统不直连加密机,那么就需要设计一个前置系统。那么前置系统与机密机之间的安全设计呢?从下图可以看到加密机管理控制台有哪些功能,

这里面可以想象到加密机的前置系统,与加密机之间的接口通讯,采用了对称了加密,他们在内网,通过设置ip白名单进行授信。

3、应用系统通过前置与加密机通信?

前置和加密机也大都会采用对成加密,但是接口报文的加、解密是在交给加密机来处理,所以报文是安全的,而被截获的报文,即使知道了应用与加密机的加密密钥,那么也是密文,还是不知道如何解密。

1.2 MD5、SHA摘要算法

摘要算法很厉害,因为他不可逆,计算一个文件是否更改,只要看看他的摘要是否发生变化就可以。我的应用场景主要是在登录的时候使用。第2.3.3章 WEB系统最佳实践属性配置之shiro.properties,第2.1.7章 WEB系统最佳实践Spring文件配置之spring-shiro.xml这两篇文章提到我的计算使用的是SHA-1,应用的shiro权限框架,这里稍微带一带。下图的密码流程,很容易就想到几个问题

1、客户端做MD5值,再调用后台请求之前,MD5做几次呢?

客户端一定是计算摘要的,是不是选择MD5算法抛开一边。但是一次MD5是可以破解的,比如在线MD5破解,密码通常6位~20位,MD5值是32位,因此再做一次MD5值,就相当难破解了,所以客户端只需要做2次MD5就可以了。

2、SHA-1安全吗

2月23日,CWI Amsterdam与Google宣布了一个成功的SHA-1碰撞攻击,我相信有人攻击我的代价和他的收益没那么大,所以可以放心使用了。但是shiro也可以支持sha2.

3、加盐值是怎么产生的?

给出8位的长度,随机生成16个字节的加盐值,不容易猜吧。

byte[] salt = DigestsUtil.generateSalt(saltSize);record.setSalt(EncodesUtil.encodeHex(salt));

4、多少次迭代合适呢?

网上大多数采用的是1024,虽然我不知道为什么,应该够用了。

5、保存到数据库中的密码安全吗?

最终存放到数据的密码长度为40位,在数据库中是无法猜到用户的账号密码的,内贼是可以防住了。可是运维的权限呢,如果运维更改了账号和密码,临时登录进去,再改回来。这就需要数据库的审计功能了。

1.3 数字签名

数字签名是保障信息的不可抵赖性。现在的开放接口大多提供一个appId和appKey给到接入方,可以看看蚂蚁金赋开放平台的做法,照着做就是了。实际应用,大多会砍一砍。

从下面可以思考几个问题,既然是数字签名,那么其实算法是公开的,那么问题就在于如何让appKey保密。

1、appKey存放到哪里呢

很多时候appKey写到了后台配置文件中,如果人员离职,这个appKey就带走了,不过还好大多数开放平台,appKey都可以更新,appId是不变的。

2、前端后端分离的appKey暴露了怎么办?

比如使用springboot+vue做前后端分离或者js访问开放平台的,有些人把appKey写到了前端,直接暴露有人觉得很危险,于是想到了,将appKey做分散,或者js做了混淆,只是增加了难度,而那些做爬虫的人,才不关心你怎么封装的,直接抓包看请求,这就需要用到了数字证书了。

从下图可以看到密码传输到终端用户,为什么很多企业用户花钱需要手机短信把,因为解决了密码传输的问题。

appId作为参数传到后台

private <T extends AlipayResponse> RequestParametersHolder getRequestHolderWithSign(BatchAlipayRequest request) throws AlipayApiException {List<AlipayRequestWrapper> requestList = request.getRequestList();//校验接口列表非空if (requestList == null || requestList.isEmpty()) {throw new AlipayApiException("40", "client-error:api request list is empty");}RequestParametersHolder requestHolder = new RequestParametersHolder();//添加协议必须参数AlipayHashMap protocalMustParams = new AlipayHashMap();protocalMustParams.put(AlipayConstants.METHOD, request.getApiMethodName());protocalMustParams.put(AlipayConstants.APP_ID, this.appId);protocalMustParams.put(AlipayConstants.SIGN_TYPE, this.signType);protocalMustParams.put(AlipayConstants.CHARSET, charset);protocalMustParams.put(AlipayConstants.VERSION, request.getApiVersion());if (request.isNeedEncrypt()) {protocalMustParams.put(AlipayConstants.ENCRYPT_TYPE, this.encryptType);}//添加协议可选参数AlipayHashMap protocalOptParams = new AlipayHashMap();protocalOptParams.put(AlipayConstants.FORMAT, format);protocalOptParams.put(AlipayConstants.ALIPAY_SDK, AlipayConstants.SDK_VERSION);requestHolder.setProtocalOptParams(protocalOptParams);Long timestamp = System.currentTimeMillis();DateFormat df = new SimpleDateFormat(AlipayConstants.DATE_TIME_FORMAT);df.setTimeZone(TimeZone.getTimeZone(AlipayConstants.DATE_TIMEZONE));protocalMustParams.put(AlipayConstants.TIMESTAMP, df.format(new Date(timestamp)));requestHolder.setProtocalMustParams(protocalMustParams);//设置业务参数AlipayHashMap appParams = new AlipayHashMap();//构造请求主题StringBuilder requestBody = new StringBuilder();// 组装每个API的请求参数for (int index = 0; index < requestList.size(); index++) {AlipayRequestWrapper alipayRequestWrapper = requestList.get(index);AlipayRequest alipayRequest = alipayRequestWrapper.getAlipayRequest();Map<String, Object> apiParams = alipayRequest.getTextParams();apiParams.put(AlipayConstants.METHOD, alipayRequest.getApiMethodName());apiParams.put(AlipayConstants.APP_AUTH_TOKEN, alipayRequestWrapper.getAppAuthToken());apiParams.put(AlipayConstants.ACCESS_TOKEN, alipayRequestWrapper.getAccessToken());apiParams.put(AlipayConstants.PROD_CODE, alipayRequest.getProdCode());apiParams.put(AlipayConstants.NOTIFY_URL, alipayRequest.getNotifyUrl());apiParams.put(AlipayConstants.RETURN_URL, alipayRequest.getReturnUrl());apiParams.put(AlipayConstants.TERMINAL_INFO, alipayRequest.getTerminalInfo());apiParams.put(AlipayConstants.TERMINAL_TYPE, alipayRequest.getTerminalType());apiParams.put(AlipayConstants.BATCH_REQUEST_ID, String.valueOf(index));// 仅当API包含biz_content参数且值为空时,序列化bizModel填充bizContenttry {if (alipayRequest.getClass().getMethod("getBizContent") != null&& StringUtils.isEmpty(appParams.get(AlipayConstants.BIZ_CONTENT_KEY))&& alipayRequest.getBizModel() != null) {apiParams.put(AlipayConstants.BIZ_CONTENT_KEY,new JSONWriter().write(alipayRequest.getBizModel(), true));}} catch (NoSuchMethodException e) {// 找不到getBizContent则什么都不做} catch (SecurityException e) {AlipayLogger.logBizError(e);}requestBody.append(new JSONWriter().write(apiParams, false));if (index != requestList.size() - 1) {requestBody.append(BATCH_API_DEFAULT_SPLIT);}}appParams.put(AlipayConstants.BIZ_CONTENT_KEY, requestBody.toString());// 只有新接口和设置密钥才能支持加密if (request.isNeedEncrypt()) {if (StringUtils.isEmpty(appParams.get(AlipayConstants.BIZ_CONTENT_KEY))) {throw new AlipayApiException("当前API不支持加密请求");}// 需要加密必须设置密钥和加密算法if (StringUtils.isEmpty(this.encryptType) || getEncryptor() == null) {throw new AlipayApiException("API请求要求加密,则必须设置密钥类型和加密器");}String encryptContent = getEncryptor().encrypt(appParams.get(AlipayConstants.BIZ_CONTENT_KEY), this.encryptType, this.charset);appParams.put(AlipayConstants.BIZ_CONTENT_KEY, encryptContent);}requestHolder.setApplicationParams(appParams);if (!StringUtils.isEmpty(this.signType)) {String signContent = AlipaySignature.getSignatureContent(requestHolder);protocalMustParams.put(AlipayConstants.SIGN,getSigner().sign(signContent, this.signType, charset));} else {protocalMustParams.put(AlipayConstants.SIGN, "");}return requestHolder;}

AlipaySignature这个类可以看到参数根据字母的顺序进行排序

public static String getSignContent(Map<String, String> sortedParams) {StringBuffer content = new StringBuffer();List<String> keys = new ArrayList<String>(sortedParams.keySet());Collections.sort(keys);int index = 0;for (int i = 0; i < keys.size(); i++) {String key = keys.get(i);String value = sortedParams.get(key);if (StringUtils.areNotEmpty(key, value)) {content.append((index == 0 ? "" : "&") + key + "=" + value);index++;}}return content.toString();}

DefaultSigner中包含了签名的方法

public String sign(String sourceContent, String signType, String charset) {String sign = null;try {sign = AlipaySignature.rsaSign(sourceContent, this.privateKey, charset, signType);} catch (AlipayApiException e) {throw new RuntimeException(e);}return sign;}

1.4 数字证书

私钥加密,公钥解密,这个大家都很容理解,自己写的证书,浏览器是不识别的,因为没有授权。很容易理解,你自己颁布的证书,只有你自己可以认,虽然也是对称的,但是并不是CA机构所认可。数字证书解决通讯安全的问题,也就是说抓包是被加密的。但是它并不能解决源头授信的问题。

下图是参考一个spring-cloud项目,生成公私钥对,以及公私钥对存储的流程。

java学习-AES加解密之AES-128-CBC算法是对称算法,这里可自行指定对称算法。按照下图的流程,公私钥的存储周期,可以通过redis的销毁机制来控制。这里可以思考几个问题

1、私钥存到密钥的加密因子在哪里?

这个是固定的,很多人也都会想到写到配置文件中。

2、对离职人员的防范

哔哩哔哩源码的泄露是来自内部员工,史上最大账号密码数据库泄露,41GB数据文件出现在暗网,这些案例可以看到,基本出问题来自内部。采用下图的方式,是可以一定程度上防范。因为公私钥对有生命周期,即使开发人员或者SE知道算法,但是生成过程并不会干预。

2 访问控制

2.1 系统之间

2.1.1 每30秒获取允许访问的清单

既然Eureka作为服务中心,调用者订阅服务即可,不用关心服务提供者是谁,思考一下:

1 为何获取这个允许放单的清单从哪里来呢?

ServiceAuthRestInterceptor这段代码可以看出这个配置实际上是从数据库中获取的,这是一个技术业务问题。

@Override@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HandlerMethod handlerMethod = (HandlerMethod) handler;// 配置该注解,说明不进行服务拦截CheckClientToken annotation = handlerMethod.getBeanType().getAnnotation(CheckClientToken.class);IgnoreClientToken ignoreClientToken = handlerMethod.getMethodAnnotation(IgnoreClientToken.class);if (annotation == null) {annotation = handlerMethod.getMethodAnnotation(CheckClientToken.class);}if (annotation == null || ignoreClientToken != null) {return super.preHandle(request, response, handler);} else {String token = request.getHeader(serviceAuthConfig.getTokenHeader());try {IJWTInfo infoFromToken = serviceAuthUtil.getInfoFromToken(token);String uniqueName = infoFromToken.getUniqueName();for (String client : serviceAuthUtil.getAllowedClient()) {if (client.equals(uniqueName)) {return super.preHandle(request, response, handler);}}}catch(ClientTokenException ex){response.setStatus(HttpStatus.FORBIDDEN.value());logger.error(ex.getMessage(),ex);response.setContentType("UTF-8");response.getOutputStream().println(JSON.toJSONString(new BaseResponse(ex.getStatus(), ex.getMessage())));return false;}response.setStatus(HttpStatus.FORBIDDEN.value());response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());response.getOutputStream().println(JSON.toJSONString(new BaseResponse(RestCodeConstants.EX_CLIENT_FORBIDDEN_CODE,"Client is Forbidden!")));return false;}}

2 拦截器

授权系统拦截

@Configuration("securityWebConfig")@Primarypublic class WebConfiguration extends WebMvcConfigurerAdapter {@BeanGlobalExceptionHandler getGlobalExceptionHandler() {return new GlobalExceptionHandler();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {/*增加服务权限烂机器*/registry.addInterceptor(getServiceAuthRestInterceptor()).addPathPatterns("/**");/*增加用户权限拦截器*/registry.addInterceptor(getUserAuthRestInterceptor()).addPathPatterns("/**");super.addInterceptors(registry);}/*** 配置服务权限拦截* @return*/@BeanServiceAuthRestInterceptor getServiceAuthRestInterceptor() {return new ServiceAuthRestInterceptor();}/*** 配置用户用户token拦截* @return*/@BeanUserAuthRestInterceptor getUserAuthRestInterceptor() {return new UserAuthRestInterceptor();}}

auth:serviceId: ace-authuser:token-header: Authorizationlimit-expire: 1440 # 一天过期client:id: your-systemsecret: 123456token-header: client-token

@Scheduled(cron = "0/30 * * * * ?")public void refreshAllowedClient() {log.debug("refresh allowedClient.....");BaseResponse resp = serviceAuthFeign.getAllowedClient(serviceAuthConfig.getClientId(), serviceAuthConfig.getClientSecret());if (resp.getStatus() == 200) {ObjectRestResponse<List<String>> allowedClient = (ObjectRestResponse<List<String>>) resp;this.allowedClient = allowedClient.getData();}}

2.1.2 access token

access token的产生使用到了一个第三方jar,通过私钥进行了加密,通过公钥进行解密.

在系统初始化的时候,公私钥就产生了。

1 token的产生

@Configuration@Slf4jpublic class AuthServerRunner implements CommandLineRunner {@Autowiredprivate RedisTemplate<String, String> redisTemplate;private static final String REDIS_USER_PRI_KEY = "AG:AUTH:JWT:PRI";private static final String REDIS_USER_PUB_KEY = "AG:AUTH:JWT:PUB";private static final String REDIS_SERVICE_PRI_KEY = "AG:AUTH:CLIENT:PRI";private static final String REDIS_SERVICE_PUB_KEY = "AG:AUTH:CLIENT:PUB";@Autowiredprivate KeyConfiguration keyConfiguration;@Autowiredprivate AECUtil aecUtil;@Autowiredprivate RsaKeyHelper rsaKeyHelper;@Autowiredprivate GatewayRouteBiz gatewayRouteBiz;@Overridepublic void run(String... args) throws Exception {boolean flag = false;if (redisTemplate.hasKey(REDIS_USER_PRI_KEY)&&redisTemplate.hasKey(REDIS_USER_PUB_KEY)&&redisTemplate.hasKey(REDIS_SERVICE_PRI_KEY)&&redisTemplate.hasKey(REDIS_SERVICE_PUB_KEY)) {try {keyConfiguration.setUserPriKey(rsaKeyHelper.toBytes(aecUtil.decrypt(redisTemplate.opsForValue().get(REDIS_USER_PRI_KEY).toString())));keyConfiguration.setUserPubKey(rsaKeyHelper.toBytes(redisTemplate.opsForValue().get(REDIS_USER_PUB_KEY).toString()));keyConfiguration.setServicePriKey(rsaKeyHelper.toBytes(aecUtil.decrypt(redisTemplate.opsForValue().get(REDIS_SERVICE_PRI_KEY).toString())));keyConfiguration.setServicePubKey(rsaKeyHelper.toBytes(redisTemplate.opsForValue().get(REDIS_SERVICE_PUB_KEY).toString()));}catch (Exception e){log.error("初始化公钥/密钥异常...",e);flag = true;}} else {flag = true;}if(flag){Map<String, byte[]> keyMap = rsaKeyHelper.generateKey(keyConfiguration.getUserSecret());keyConfiguration.setUserPriKey(keyMap.get("pri"));keyConfiguration.setUserPubKey(keyMap.get("pub"));redisTemplate.opsForValue().set(REDIS_USER_PRI_KEY, aecUtil.encrypt(rsaKeyHelper.toHexString(keyMap.get("pri"))));redisTemplate.opsForValue().set(REDIS_USER_PUB_KEY, rsaKeyHelper.toHexString(keyMap.get("pub")));keyMap = rsaKeyHelper.generateKey(keyConfiguration.getServiceSecret());keyConfiguration.setServicePriKey(keyMap.get("pri"));keyConfiguration.setServicePubKey(keyMap.get("pub"));redisTemplate.opsForValue().set(REDIS_SERVICE_PRI_KEY, aecUtil.encrypt(rsaKeyHelper.toHexString(keyMap.get("pri"))));redisTemplate.opsForValue().set(REDIS_SERVICE_PUB_KEY, rsaKeyHelper.toHexString(keyMap.get("pub")));}log.info("完成公钥/密钥的初始化...");List<GatewayRoute> gatewayRoutes = gatewayRouteBiz.selectListAll();redisTemplate.opsForValue().set(RedisKeyConstants.ZUUL_ROUTE_KEY, JSON.toJSONString(gatewayRoutes));log.info("完成网关路由的更新...");}}

public String generateToken(IJWTInfo jwtInfo) throws Exception {return jwtHelper.generateToken(jwtInfo, keyConfiguration.getServicePriKey(), expire);}

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.7.0</version></dependency>

@Scheduled(cron = "0 0/10 * * * ?")public void refreshClientToken() {log.debug("refresh client token.....");BaseResponse resp = serviceAuthFeign.getAccessToken(serviceAuthConfig.getClientId(), serviceAuthConfig.getClientSecret());if (resp.getStatus() == 200) {ObjectRestResponse<String> clientToken = (ObjectRestResponse<String>) resp;this.clientToken = clientToken.getData();}}

public IJWTInfo getInfoFromToken(String token) throws Exception {try {IJWTInfo infoFromToken = jwtHelper.getInfoFromToken(token, serviceAuthConfig.getPubKeyByte());Date current = infoFromToken.getExpireTime();if(new Date().after(current)){throw new ClientTokenException("Client token expired!");}return infoFromToken;} catch (ExpiredJwtException ex) {throw new ClientTokenException("Client token expired!");} catch (SignatureException ex) {throw new ClientTokenException("Client token signature error!");} catch (IllegalArgumentException ex) {throw new ClientTokenException("Client token is null or empty!");}}

2 token检查

这里可以看到拦截器,通过反编译,将带CheckClientToken 注解的请求都拦截下来了。加了注解,就需要验证token。

@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HandlerMethod handlerMethod = (HandlerMethod) handler;// 配置该注解,说明不进行服务拦截CheckClientToken annotation = handlerMethod.getBeanType().getAnnotation(CheckClientToken.class);IgnoreClientToken ignoreClientToken = handlerMethod.getMethodAnnotation(IgnoreClientToken.class);if (annotation == null) {annotation = handlerMethod.getMethodAnnotation(CheckClientToken.class);}if (annotation == null || ignoreClientToken != null) {return super.preHandle(request, response, handler);} else {String token = request.getHeader(serviceAuthConfig.getTokenHeader());try {IJWTInfo infoFromToken = serviceAuthUtil.getInfoFromToken(token);String uniqueName = infoFromToken.getUniqueName();for (String client : serviceAuthUtil.getAllowedClient()) {if (client.equals(uniqueName)) {return super.preHandle(request, response, handler);}}}catch(ClientTokenException ex){response.setStatus(HttpStatus.FORBIDDEN.value());logger.error(ex.getMessage(),ex);response.setContentType("UTF-8");response.getOutputStream().println(JSON.toJSONString(new BaseResponse(ex.getStatus(), ex.getMessage())));return false;}response.setStatus(HttpStatus.FORBIDDEN.value());response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());response.getOutputStream().println(JSON.toJSONString(new BaseResponse(RestCodeConstants.EX_CLIENT_FORBIDDEN_CODE,"Client is Forbidden!")));return false;}}

@Retention(RetentionPolicy.RUNTIME)@Target(value={ElementType.METHOD,ElementType.TYPE})public @interface CheckClientToken {}

这里配置那些需要检查客户端token

@RestController@RequestMapping("depart")@CheckClientToken@CheckUserTokenpublic class DepartController extends BaseController<DepartBiz,Depart> {}

token拦截器得到token后,如果token过期,那么就刷新token。那么客户端token是否过期呢,则需要在客户端调用时,设置token过期标志,那么带来的问题是,为什么客户端自己不去刷新token呢?这就是上图中的access token是1个小时刷新一次,那么当在调用的时候,刚好1个小时呢,不就出问题了,所以这里做了一下主动刷新token。

@Component@Logpublic class OkHttpTokenInterceptor implements Interceptor {@Autowired@Lazyprivate ServiceAuthUtil serviceAuthUtil;@Autowired@Lazyprivate ServiceAuthConfig serviceAuthConfig;@Autowired@Lazyprivate UserAuthConfig userAuthConfig;@Overridepublic Response intercept(Chain chain) throws IOException {Request newRequest = chain.request().newBuilder().header(userAuthConfig.getTokenHeader(), BaseContextHandler.getToken()).build();Response response = chain.proceed(newRequest);if(HttpStatus.FORBIDDEN.value()==response.code()){if(response.body().string().contains(String.valueOf(RestCodeConstants.EX_CLIENT_INVALID_CODE))){log.info("Client Token Expire,Retry to request...");serviceAuthUtil.refreshClientToken();newRequest = chain.request().newBuilder().header(userAuthConfig.getTokenHeader(), BaseContextHandler.getToken()).header(serviceAuthConfig.getTokenHeader(),serviceAuthUtil.getClientToken()).build();response = chain.proceed(newRequest);}}return response;}}

2.1.3 获取公钥

获取公钥由系统自动完成,避免了人为干预。

@Scheduled(cron = "0 0/1 * * * ?")public void refreshUserPubKey(){BaseResponse resp = serviceAuthFeign.getUserPublicKey(serviceAuthConfig.getClientId(), serviceAuthConfig.getClientSecret());if (resp.getStatus() == HttpStatus.OK.value()) {ObjectRestResponse<byte[]> userResponse = (ObjectRestResponse<byte[]>) resp;this.userAuthConfig.setPubKeyByte(userResponse.getData());}}@Scheduled(cron = "0 0/1 * * * ?")public void refreshServicePubKey(){BaseResponse resp = serviceAuthFeign.getServicePublicKey(serviceAuthConfig.getClientId(), serviceAuthConfig.getClientSecret());if (resp.getStatus() == HttpStatus.OK.value()) {ObjectRestResponse<byte[]> userResponse = (ObjectRestResponse<byte[]>) resp;this.serviceAuthConfig.setPubKeyByte(userResponse.getData());}}

3 网络安全

3.1 VPN

VPN是企业网在internet等公共网络上的延伸,它通过一个私有的通道在公共网络上创建一个安全的私有连接。

五分钟搞懂内网和外网之间的通信的原理,先搞明白公网ip和私有ip,大家知道企业宽带很贵,首先因为他有固定的公网ip,很容易理解出他是独享的,因为运营商可以让多个家庭宽带使用同一个公网ip,企业宽带凭什么比民用宽带贵?有没有更便宜的企业宽带,一般企业用户都要求是双线。那么什么是双线呢?

什么是双线宽带,这里提到了南电信北网通的问题,也就是南北网络互通的问题。

有了固定ip,就可以解决异地机房通信的问题。先看一下深信服IPSec VPN快速配置文档,通过防火墙的配置,可以实现家庭宽带与企业网络建立虚拟专用网,说白话,就是企业网访问家庭网络,就像访问内网一样。思考几个问题

1、家庭宽带和家庭宽带是不是没法实现vpn呢?

没有固定ip,连对方是谁也不清楚,连通讯都建立不起来,又怎么建立转有通道呢,有防火墙也没有用。

2、企业网络与企业网络之前一定能建立VPN吗?

例如阿里云与企业网络建立vpn,怎么建立呢?

3、IPSec协议的工作原理是什么?

建立网络专用通道,那么很容易理解IPSec是网络层协议,IPSec简介,VPN和IPsec协议

3.2 防火墙

防火墙监控到内网有一台机器一直在请求DNS服务器,分析:

1、先分析一下HTTP请求流程

一次完整的HTTP请求过程,域名解析会先搜索浏览器自身的DNS缓存,缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存。

如果通过程序请求,而不是浏览器,会有DNS缓存吗?再看看这篇文章一文搞懂DNS缓存,浏览器和应用程序以及IPS网络运营商都会对DNS进行缓存。如果后台程序只访问一个地址,为什么会一直发送DNS呢?

2、为什么总是在请求DNS服务器呢?

防火墙抓包,全是在请求DNS。什么情况才会导致不断请求DNS呢?如果后台程序有循环bug,一直在请求某个网站,那么是否DNS就请求频繁呢?

通过zabbix可以监控到网络的请求情况,那么

1、Incoming指的是什么呢?

2、Outgoing指的是什么呢?

3、网络流量算大吗?

如果觉得《系统安全性和保密性设计》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。