Spring Boot集成ShardingSphere实现数据加密及数据脱敏 | Spring Cloud 48

一、前言

通过以下系列章节:

Spring Boot集成ShardingSphere实现数据分片(一) | Spring Cloud 40

Spring Boot集成ShardingSphere实现数据分片(二) | Spring Cloud 41

Spring Boot集成ShardingSphere实现数据分片(三) | Spring Cloud 42

Spring Boot集成ShardingSphere实现读写分离 | Spring Cloud 43

Spring Boot集成ShardingSphere实现按月数据分片及创建自定义分片算法 | Spring Cloud 44

Spring Boot集成ShardingSphere分片利器 AutoTable (一)—— 简单体验 | Spring Cloud 45

Spring Boot集成ShardingSphere分片利器 AutoTable (二)—— 自动分片算法示例 | Spring Cloud 46

ShardingSphere 5.3 系列Spring 配置升级指南 | Spring Cloud 47

ShardingSphere的数据分片、各分片算法应用、读写分离、最新版本升级等情况有了详细的了解,今天我们继续对其:数据加密数据脱敏功能进行演示学习。

本章节中会应用以上系列章节的部分成功

二、背景

2.1 数据加密

安全控制一直是治理的重要环节,数据加密属于安全控制的范畴。 无论对互联网公司还是传统行业来说,数据安全一直是极为重视和敏感的话题。 数据加密是指对某些敏感信息通过加密规则进行数据的变形,实现敏感隐私数据的可靠保护。 涉及客户安全数据或者一些商业性敏感数据,如身份证号、手机号、卡号、客户号等个人信息按照相关部门规定,都需要进行数据加密。

对于数据加密的需求,在现实的业务场景中一般分为两种情况:

  • 新业务上线,安全部门规定需将涉及用户敏感信息,例如银行、手机号码等进行加密后存储到数据库,在使用的时候再进行解密处理。因为是全新系统,因而没有存量数据清洗问题,所以实现相对简单。

  • 已上线业务,之前一直将明文存储在数据库中。相关部门突然需要对已上线业务进行加密整改。这种场景一般需要处理 3 个问题:

    • 历史数据需要如何进行加密处理,即洗数。
    • 如何能在不改动业务 SQL 和逻辑情况下,将新增数据进行加密处理,并存储到数据库;在使用时,再进行解密取出。
    • 如何较为安全、无缝、透明化地实现业务系统在明文与密文数据间的迁移。

2.2 数据脱敏

随着《网络安全法》的颁布施行,对个人隐私数据的保护已经上升到法律层面。传统的应用系统普遍缺少对个人隐私数据的保护措施。数据脱敏,可实现在不需要对生产数据库中的数据进行任何改变的情况下,依据用户定义的脱敏规则,对生产数据库返回的数据进行专门的加密、遮盖和替换,确保生产环境的敏感数据能够得到保护。

三、使用示例

示例采用springboot集成shardingsphere-jdbc方式搭建。

3.1 项目总体结构

在这里插入图片描述

3.2 Maven依赖

shading-sphere/shading-encrypt-mask-5.3/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>shading-sphere</artifactId>
        <groupId>com.gm</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shading-encrypt-mask-5.3</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core</artifactId>
            <version>5.3.2</version>
        </dependency>

        <!-- 解决Mybatis中LocalDateTime和SQL中datetime的交互 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-typehandlers-jsr310</artifactId>
            <version>1.0.2</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.33</version>
        </dependency>
    </dependencies>

</project>
  • shardingsphere-jdbc-core使用最新的5.3.2版本

  • JDBCORM 框架选用mybatis-plus

3.3 配置文件

src/main/resources/application.yml:

server:
  port: 8844

spring:
  application:
    name: @artifactId@
  datasource:
    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
    url: jdbc:shardingsphere:classpath:shading-auto-tables-encrypt-mask.yaml
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

src/main/resources/shading-auto-tables-encrypt-mask.yaml

dataSources:
  ds1:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    jdbcUrl: jdbc:mysql://192.168.0.35:3306/db1?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
    username: root
    password: '1qaz@WSX'
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1

  ds2:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    jdbcUrl: jdbc:mysql://192.168.0.46:3306/db2?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
    username: root
    password: '1qaz@WSX'
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
rules:
  - !SHARDING
    autoTables:
      # 取模
      t_auto_user_info_mod:
        actualDataSources: ds$->{1..2}
        shardingStrategy:
          standard:
            shardingColumn: user_id
            shardingAlgorithmName: auto_user_info_mod
        # 分布式序列策略
        keyGenerateStrategy:
          # 自增列名称,缺省表示不使用自增主键生成器
          column: user_id
          # 分布式序列算法名称
          keyGeneratorName: snowflake
    # 分片算法配置
    shardingAlgorithms:
      # 取模
      auto_user_info_mod:
        type: MOD
        props:
          sharding-count: 2
    # 分布式序列算法配置(如果是自动生成的,在插入数据的sql中就不要传id,null也不行,直接插入字段中就不要有主键的字段)
    keyGenerators:
      # 分布式序列算法名称
      snowflake:
        # 分布式序列算法类型
        type: SNOWFLAKE
  - !MASK
    tables:
      t_auto_user_info_mod:
        columns:
          password:
            maskAlgorithm: md5_mask
          email:
            maskAlgorithm: mask_before_special_chars_mask
          telephone:
            maskAlgorithm: keep_first_n_last_m_mask
    maskAlgorithms:
      md5_mask:
        type: MD5
      mask_before_special_chars_mask:
        type: MASK_BEFORE_SPECIAL_CHARS
        props:
          special-chars: '@'
          replace-char: '*'
      keep_first_n_last_m_mask:
        type: KEEP_FIRST_N_LAST_M
        props:
          first-n: 3
          last-m: 4
          replace-char: '*'

  - !ENCRYPT
    tables:
      t_auto_user_info_mod:
        columns:
          password: # 加密列名称
            cipherColumn: password # 密文列名称
            encryptorName: password_encryptor # 密文列加密算法名称
            assistedQueryColumn: assisted_query_password # 查询辅助列名称
            assistedQueryEncryptorName: assisted_encryptor # 查询辅助列加密算法名称
          id_card:
            plainColumn: id_card_plain # 原文列名称(ShardingSphere自动创建列)
            cipherColumn: id_card # 密文列名称
            encryptorName: aes_encryptor # 密文列加密算法名称
            assistedQueryColumn: assisted_query_id_card  # 查询辅助列名称(ShardingSphere自动创建列,使用时: ..and id_card = '123...' and ..)
            assistedQueryEncryptorName: assisted_encryptor # 查询辅助列加密算法名称
            likeQueryColumn: like_query_id_card # 模糊查询列名称(ShardingSphere自动创建列,使用时: .. and id_card like '%123%' and ..)
            likeQueryEncryptorName: like_encryptor # 模糊查询列加密算法名称
    encryptors:
      aes_encryptor:
        type: AES
        props:
          aes-key-value: 123456abc
      assisted_encryptor:
        type: AES
        props:
          aes-key-value: 123456abc
      password_encryptor:
        type: MD5
      like_encryptor:
        type: CHAR_DIGEST_LIKE

props:
  sql-show: true

配置简要说明:

逻辑表 t_auto_user_info_mod按照user_id分片键使用MOD自动分片算法进行分片,
其中数据脱敏对:

  • password采用基于 MD5 的数据脱敏算法
  • email采用特殊字符前遮盖数据脱敏算法
  • telephone采用保留前 nm 数据脱敏算法

其中数据加密对:.

  • id_card开启原文列、查询辅助列、模糊查询列,以上这些列在基于shardingsphere-jdbc-core建表时会自动创建,在操作逻辑表的id_card列时shardingsphere-jdbc-core自动对其余列进行数据维护。
  • password开启查询辅助列,此列在基于shardingsphere-jdbc-core建表时会自动创建,在操作逻辑表的password列时shardingsphere-jdbc-core自动对其余列进行数据维护。

ShardingSphere更多数据脱敏配置,请见官网:
https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/yaml-config/rules/mask/

ShardingSphere内置提供了多种数据脱敏算法,请见官网:
https://shardingsphere.apache.org/document/current/cn/dev-manual/mask/

ShardingSphere更多数据加密配置,请见官网:
https://shardingsphere.apache.org/document/5.3.0/cn/user-manual/shardingsphere-jdbc/java-api/rules/encrypt/

ShardingSphere内置提供了多种数据加密算法,请见官网:
https://shardingsphere.apache.org/document/current/cn/dev-manual/encrypt/

3.4 实体类

com/gm/shading/encrypt/mask/entity/AutoUserInfoMod.java

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("t_auto_user_info_mod")
public class AutoUserInfoMod {

    @TableId(type = IdType.ASSIGN_ID)
    private Long userId;
    // 身份证,存储加密
    private String idCard;
    // 密码,存储加密
    private String password;
    // 电话,数据脱敏
    private String telephone;
    // 电子邮箱,数据脱敏
    private String email;
}

3.5 Mapper

com/gm/shading/encrypt/mask/mapper/AutoUserInfoModMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gm.shading.encrypt.mask.entity.AutoUserInfoMod;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface AutoUserInfoModMapper extends BaseMapper<AutoUserInfoMod> {
    void save(AutoUserInfoMod autoOrder);
}

src/main/resources/mapper/AutoUserInfoModMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.gm.shading.encrypt.mask.mapper.AutoUserInfoModMapper">
    <insert id="save" parameterType="com.gm.shading.encrypt.mask.entity.AutoUserInfoMod">
        insert into t_auto_user_info_mod (id_card,password,telephone,email)
        values (#{idCard}, #{password}, #{telephone}, #{email})
    </insert>
</mapper>

3.6 启动类

com/gm/shading/encrypt/mask/ShadingEncryptMaskApplication.java

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.gm.shading.encrypt.mask.mapper")
public class ShadingEncryptMaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShadingEncryptMaskApplication.class, args);
    }
}

3.7 单元测试

src/test/java/com/gm/shading/encrypt/mask/ShadingEncryptMaskApplicationTests.java

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gm.shading.encrypt.mask.entity.AutoUserInfoMod;
import com.gm.shading.encrypt.mask.mapper.AutoUserInfoModMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@SpringBootTest
@Slf4j
public class ShadingEncryptMaskApplicationTests {

    @Autowired
    AutoUserInfoModMapper autoUserInfoModMapper;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    public void testCreateAutUserInfoMod() {
        jdbcTemplate.execute("CREATE TABLE `t_auto_user_info_mod` (\n" +
                " `user_id` bigint(20) NOT NULL COMMENT '用户id',\n" +
                " `id_card` varchar(50) NOT NULL COMMENT '身份证',\n" +
                " `password` varchar(50) NOT NULL COMMENT '用户密码',\n" +
                " `telephone` varchar(50) NOT NULL COMMENT '电话',\n" +
                " `email` varchar(50) NOT NULL COMMENT '邮箱',\n" +
                " PRIMARY KEY (`user_id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;");
    }
    
    @Test
    public void testInsertAutoUserInfoMod() {

        List<String> idCards = Arrays.asList("34122119920825123", "42122319870601123", "32072319750626123",
                "34120219900429123", "15222319970119123", "32038219891112123", "32072319950606123", "32038219900219123", "37132419880902123");
        for (int i = 1; i < 6; i++) {
            AutoUserInfoMod userInfo = new AutoUserInfoMod();
            userInfo.setIdCard(idCards.get(i) + i);
            userInfo.setPassword("abcdefg1234567" + 1);
            userInfo.setTelephone("18645026410");
            userInfo.setEmail("1025304567@qq.com");
            autoUserInfoModMapper.save(userInfo);
        }
    }
    
    @Test
    public void testSelectAutoUserInfoModAll() {
        List<AutoUserInfoMod> list = autoUserInfoModMapper.selectList(new QueryWrapper<AutoUserInfoMod>());
        for (AutoUserInfoMod userInfo : list) {
            log.info("{}", userInfo);
        }
    }

    @Test
    public void testSelectAutoUserInfoModByIdCard() {

        List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from t_auto_user_info_mod where id_card='320723197506261232'");
        for (Map<String, Object> map : list) {
            log.info("{}", map);
        }

        list = jdbcTemplate.queryForList("select * from t_auto_user_info_mod where id_card like '%3412%'");
        for (Map<String, Object> map : list) {
            log.info("{}", map);
        }
    }
}

  • 执行testCreateAutUserInfoMod方法根据自动配置的分片规则进行建表

查看逻辑表的真实表结构:

在这里插入图片描述

此次会发现配置文件中定义原文列、查询辅助列、模糊查询列会自动完成创建

  • 执行testInsertAutoUserInfoMod方法完成数据插入,数据加密规则生效

在这里插入图片描述

  • 执行testSelectAutoUserInfoModAll方法完成数据查询,数据脱敏规则生效

在这里插入图片描述

  • 执行testSelectAutoUserInfoModByIdCard方法完成数据查询,数据加密查询辅助列、模糊查询列规则生效

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/19657.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SoringBoot——pom文件:starter

先来看一看&#xff1a; 这次我们来介绍SpringBoot的pom文件的另一个好玩的地方&#xff1a;starter。 starter的中文含义是启动器&#xff0c;所以有时候我们在Maven仓库找依赖的时候&#xff0c;如果开启了自动翻译就会经常会看见一个奇怪的词叫做某某弹簧启动器&#xff0…

tomcat集群下的session共享和负载均衡(memcache实现)

环境 操作系统&#xff1a;windows tomcat1&#xff1a;Apache Tomcat/7.0.52&#xff08;8085&#xff09; tomcat2&#xff1a;Apache Tomcat/7.0.52&#xff08;8086&#xff09; jdk&#xff1a;1.8.0_251 nginx&#xff1a;nginx-1.20.1&#xff08;8070&#xff09; memc…

day4-字符设备驱动基础上_基础框架

大纲&#xff1a; 设备分类 申请和注销设备号 函数指针复习 注册字符设备 字符设备驱动框架解析 读操作实现 写操作实现 ioctl操作实现 printk 多个次设备的支持 一、Linux内核对设备的分类 linux的文件种类&#xff1a; -&#xff1a;普通文件 (文件内容、文件名、…

【终极解决方案】IDEA maven 项目修改代码不生效。

【终极解决方案】IDEA maven 项目修改代码不生效。 文章目录 【终极解决方案】IDEA maven 项目修改代码不生效。1、项目问题描述2、可能的解决方案3、分析原因4、解决方案5、参考文献 1、项目问题描述 遇到一个非常奇怪的问题&#xff0c;修改了一个基于maven搭建的SSM项目&am…

c++ this指针

this指针介绍&#xff1a; c中成员变量和成员函数分开存储&#xff0c;每一个非静态成员函数只会有一个实例&#xff0c;多个同类型对象共用这一个成员函数。那么代码怎么区分哪个对象调用自己呢&#xff1f;this指针由此应运而生。 c通过提供对象指针&#xff0c;this指针。…

3D点云的基本操作(基于PCL编程)

知识储备 右手系 右手&#xff0c;拇指&#xff0c;食指&#xff0c;中指&#xff0c;分别是x,y,z的正方向。左手系则同理。 旋转矩阵 本质&#xff1a;两个坐标系之间的旋转关系。 用途&#xff1a;旋转点云。 原理&#xff1a;设传感器的坐标系为O1X1Y1Z1&#xff0c;设…

高分辨率光学遥感图像水体分类综述2022.03

本文是Water body classification from high-resolution optical remote sensing imagery: Achievements and perspectives的学习笔记。 相关资源被作者整理到&#xff1a;这里 文章目录 Introduction基本知识 挑战和机遇挑战1. 有限的光谱信息和小场景覆盖2. 形状、大小和分布…

【Python入门】Python循环语句(while循环的基础语法)

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于Python零基础入门系列&#xff0c;本专栏主要内容为Python基础语法、判断、循环语句、函…

Spring_jdbcTemplate基本使用

文章目录 一、导入spring-jdbc和spring-tx坐标二、创建数据库表和实体在applicationContext.xml中配置连接池和JdbcTemplate在test数据库中创建account表 三、创建JdbcTemplate对象四、执行数据库操作 一、导入spring-jdbc和spring-tx坐标 <dependency><groupId>o…

Gateway

Gateway Nacos配置管理 同一配置管理 在配置管理界面点击&#xff0b; 然后填写配置信息 配置获取步骤&#xff1a; 引入Nacos的配置管理客户端 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-…

【源码解析】SpringBoot整合AOP原理解析

AOP介绍 AOP&#xff08;Aspect Oriented Programming&#xff09;是基于切面编程的&#xff0c;可无侵入的在原本功能的切面层添加自定义代码&#xff0c;一般用于日志收集、权限认证等场景。 AOP基本概念 通知&#xff08;Advice&#xff09;: AOP 框架中的增强处理。通知…

力扣sql中等篇练习(十八)

力扣sql中等篇练习(十八) 1 银行账户概要 1.1 题目内容 1.1.1 基本题目信息1 1.1.2 基本题目信息2 1.1.3 示例输入输出 1.2 示例sql语句 # Write your MySQL query statement below SELECT u.user_id,u.user_name,u.creditIFNULL(t1.c1,0) credit,case when u.creditIFNULL…

浅谈Hutool工具类

一、Hutool简介 Hutool是一个Java工具类库&#xff0c;它封装了很多常用的Java工具类&#xff0c;如加密解密、文件操作、日期时间处理、Http客户端等。它的目标是让Java开发变得更加简单、高效。 二、Hutool的特点 高效&#xff1a;提供了很多高效的工具类和方法。 简单&…

Vue3-黑马(二)

目录&#xff1a; &#xff08;1&#xff09;vue3-ref与reactive &#xff08;2&#xff09;vue3-基础-属性绑定与事件绑定 &#xff08;3&#xff09;vue3-基础-表单绑定 &#xff08;1&#xff09;vue3-ref与reactive ref函数可以把普通的数据变成响应式的数据&#xff0…

Springboot 自动装配流程分析

目录 1.基础知识&#xff1a; 2.具体代码执行流程 3.流程总结&#xff1a; 4.参考文章&#xff1a; 1.基础知识&#xff1a; springboot的自动装配是利用了spring IOC容器创建过程中的增强功能&#xff0c;即BeanFactoryPostProcessor&#xff0c; 其中的ConfigurationCla…

卡特兰数三个通项公式的推导

前提条件&#xff1a; 有两种操作&#xff0c;一种操作的次数不能超过另外一个&#xff0c;或者是不能有交集这些操作的合法方案数&#xff0c;通常是卡特兰数 情景&#xff1a; 1&#xff09;n个0和n个1构成的字串&#xff0c;所有的前缀子串1的个数不超过0的个数&#xff…

redis(11)

一)基于Set集合实现点赞功能: 在我们的博客表当中&#xff0c;每一篇博客信息都有一个like字段&#xff0c;表示点赞的数量 需求: 1)同一个用户只能点赞一次&#xff0c;再次进行点赞则会被取消&#xff1b; 2)如果当前用户已经点赞过了&#xff0c;那么点赞按钮高亮显示&…

STL-deque容器

双端数组&#xff0c;可以对头端进行插入删除操作 deque 容器和 vecotr 容器有很多相似之处&#xff0c;比如&#xff1a; deque 容器也擅长在序列尾部添加或删除元素&#xff08;时间复杂度为O(1)&#xff09;&#xff0c;而不擅长在序列中间添加或删除元素。deque 容器也可…

win部署CAS服务并使用

前提描述&#xff1a;通过本次了解cas是个什么东西&#xff0c;并使用它。 cas为oss(单点登录)的一种实现方案。要实现cas单点登录&#xff0c;首先需要部署cas的server服务。 CAS是Central Authentication Service的缩写&#xff0c;中央认证服务&#xff0c;。 一、安装CAS…

VMware NSX-T Data Center 3.2.3 - 数据中心网络全栈虚拟化

VMware NSX-T Data Center 3.2.3 - 数据中心网络全栈虚拟化 重要更新&#xff1a;修复 136 个 bug。 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-nsx-t-3/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org VMwa…