【Nginx37】Nginx学习:SSL模块(一)简单配置与指令介绍

Nginx学习:SSL模块(一)简单配置与指令介绍

又是一个重点模块,SSL 模块,其实就是我们常见的 HTTPS 所需要的配置模块。HTTPS 的重要性不用多说了吧,现在所有的 App、小程序 都强制要求是 HTTPS 的,即使是网站开发,百度也明确了对 HTTPS 的收录会更好。也就是说,HTTPS 已经成为了事实上的正式环境协议标准。

在 Nginx 中,使用 ngx_http_ssl_module 来配置 HTTPS 其实非常简单,不过首先要确认这个模块是否安装了,默认情况下,它是不会自动安装的,需要我们在编译时加上 --with-http_ssl_module 来进行安装。不过现在不管是面板工具还是各种安装教程,都会建议并直接安装上这个模块。

它的配置指令比较多,我们先来配置一套并测试一下,然后了解一下所有的配置指令。下篇文章再拿一套配置进行简单地分析。

先准备证书,这个证书如果要按正式的来说,我们应该去证书提供商那里买的,当然也有一些免费的。或者使用 宝塔面板 之类的工具也有提供免费的 Let's Encrypt 证书。在这里我们进行本地演示,就直接生成证书好了。

[root@localhost article.http.d]# openssl req -new -nodes -newkey rsa:2048 -keyout 37.key -out 37.csr
Generating a RSA private key
......................+++++
..............+++++
writing new private key to '37.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:[root@localhost article.http.d]# openssl x509 -req -days 365 -in 37.csr -signkey 37.key -out 37.crt
Signature ok
subject=C = XX, L = Default City, O = Default Company Ltd
Getting Private key[root@localhost article.http.d]# ll 37*
-rw-r--r-- 1 root root  172 Sep 22 09:13 37.conf
-rw-r--r-- 1 root root 1115 Sep 22 09:15 37.crt
-rw-r--r-- 1 root root  952 Sep 22 09:14 37.csr
-rw------- 1 root root 1704 Sep 22 09:08 37.key

使用 openssl 命令,生成的 csr 和 key 是我们需要的东西。如果你是从云服务商那里买的或者找的免费申请的,在收到邮件下载之后,获得的也是这两个文件。

然后我们就直接用它们进行配置吧。

server{listen 8037;listen 443 ssl;root html;ssl_certificate /etc/nginx/article.http.d/37.crt;ssl_certificate_key /etc/nginx/article.http.d/37.key;}

上面这个配置,我们指定 listen 443 ,并加了 ssl 参数,表示这个端口使用 SSL 监听。然后通过两个配置指令指定证书,这里可以写绝对路径也可以写相对路径,如果是相对路径,就是找的 Nginx 运行 prefix 目录。

就这么简单,配完了。接下来访问一下 https://192.168.56.88/ 吧。

dfe5c5106f63ba8c239d86e9a6152482.png

这是什么情况?为啥访问不了呢?其实呀,我们自己生成的证书是没有经过 CA 认证的,这个 CA 的概念就是一个中介信任机构。如果我们从网上买的证书,会经过一些指定的 CA 机构认证。浏览器也会通过这些 CA 机构来判断你的证书是不是合法的,如果没有 CA 认证,就说明这个证书的来源不明,可能不是正规的或者被篡改了。因此,浏览器的安全机制就会出现这样的提示。

我们只需要忽略并确认继续访问之后就可以直接打开了,但是浏览器地址栏上的 https 这几个字符会有个删除斜杠,表示这个链接是有问题的(或者有个小红锁之类的)。大家可以自己看看哦。

普通的 8037 端口还是可以通过 http 访问的,我们也可以在 listen 8037 后面加上 ssl 参数,让 8037 也走 HTTPS 。并且 WireShark 查看效果。

先来看看普通情况下的 WireShark 抓包情况。

127c5552c5ba1ef5be5cdbcf58a608c4.png

数据是明文的。接下来,添加 ssl 参数 listen 8037 ssl; ,重载配置后使用 https 进行访问。

1c61dd4d48ac66e12f9675e654f5bf87.png

很明显,连接建立时就出现 TLVS 连接了,结果也是乱码的加密信息了。

接下来我们再测试一下,使用普通的 http 协议是不是能访问带 ssl 的端口呢?抱歉,直接 400 错误了,错误信息也非常清楚。

// 访问普通 http://192.168.56.88:8037/
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx/1.23.0</center>
</body>
</html>

如果去掉 ssl ,但是又直接使用 https 访问呢?会直接报出这样的错误信息。

// 访问 https://192.168.56.88:8037/
Error: write EPROTO 140347956612328:error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER:../../../../src/third_party/boringssl/src/ssl/tls_record.cc:242:

好了,一套简单的 HTTPS 配置我们就完成了。

其实从上面也可以看出,最核心的三个配置指令,就可以完成整个 HTTPS 相关的配置。不过,整个 SSL 的配置远不止这些,虽说其它的可能并不常用吧,但不妨碍我们了解一下。大部分配置在官方文档中显示都只能在 http、server 下配置,但有些其实也可以配置在 location 里面。下面我们就一个一个先看看这些配置信息的介绍。

配置指令

ssl

开启或关闭 ssl 。

ssl on | off;

默认 off ,该指令在版本 1.15.0 中已过时,应该使用 listen 指令的 ssl 参数。(新版本的就不要用这个啦~)

ssl_buffer_size

设置用于发送数据的缓冲区大小。

ssl_buffer_size size;

默认情况下,缓冲区大小为 16k,这对应于发送大响应时的最小开销。为了最小化第一个字节的时间,使用较小的值可能是有益的。一般不需要去设置这个。

ssl_certificate

为给定的虚拟服务器指定带有 PEM 格式证书的文件。

ssl_certificate file;

如果除了主证书之外还应指定中间证书,则应按以下顺序在同一文件中指定它们:首先是主证书,然后是中间证书。 PEM 格式的密钥可以放在同一个文件中。

从 1.11.0 版本开始,可以多次指定该指令以加载不同类型的证书,例如 RSA 和 ECDSA。只有 OpenSSL 1.0.2 或更高版本支持不同证书的单独证书链。对于旧版本,只能使用一个证书链。从 1.15.9 版本开始,在使用 OpenSSL 1.0.2 或更高版本时,可以在文件名中使用变量。请注意,使用变量意味着将为每次 SSL 握手加载证书,这可能会对性能产生负面影响。

可以指定值 data:$variable 来代替文件 (1.15.10),它从变量加载证书而不使用中间文件。请注意,不恰当地使用此语法可能会产生安全隐患,例如将密钥数据写入错误日志。应该记住,由于最大互操作性的 HTTPS 协议限制,虚拟服务器应该侦听不同的 IP 地址。

ssl_certificate_key

为给定的虚拟服务器指定具有 PEM 格式的密钥的文件。

ssl_certificate_key file;

可以指定值 engine:name:id 代替文件 (1.7.9),该文件从 OpenSSL 引擎名称加载具有指定 id 的密钥。可以指定值 data:$variable 代替文件 (1.15.10),该文件从变量加载密钥而不使用中间文件。请注意,不恰当地使用此语法可能会产生安全隐患,例如将密钥数据写入错误日志。

从版本 1.15.9 开始,在使用 OpenSSL 1.0.2 或更高版本时,可以在文件名中使用变量。

ssl_ciphers

指定启用的加密算法。

ssl_ciphers HIGH:!aNULL:!MD5;

加密算法以 OpenSSL 库可以理解的格式指定。可以使用“openssl ciphers”命令查看完整列表。之前的 nginx 版本默认使用不同的加密算法。

ssl_client_certificate

如果启用了 ssl_stapling,则指定一个带有 PEM 格式的可信 CA 证书的文件,用于验证客户端证书和 OCSP 响应。

ssl_client_certificate file;

证书列表将发送给客户。如果不需要,可以使用 ssl_trusted_certificate 指令。

ssl_conf_command

设置任意 OpenSSL 配置命令。

ssl_conf_command name value;

使用 OpenSSL 1.0.2 或更高版本时支持该指令。可以在同一级别上指定多个 ssl_conf_command 指令,当且仅当当前级别上没有定义 ssl_conf_command 指令时,这些指令才从先前的配置级别继承。请注意,直接配置 OpenSSL 可能会导致意外行为。

ssl_crl

指定用于验证客户端证书的 PEM 格式的已撤销证书 (CRL) 文件。

ssl_crl file;

ssl_dhparam

为 DHE 密码指定具有 DH 参数的文件。

ssl_dhparam file;

默认情况下未设置任何参数,因此不会使用 DHE 密码。在 1.11.0 版本之前,默认使用内置参数。

ssl_early_data

启用或禁用 TLS 1.3 早期数据。

ssl_early_data on | off;

默认值是 off ,在早期数据中发送的请求会受到重放攻击。为了防止在应用层受到此类攻击,应使用 $ssl_early_data 变量。使用 OpenSSL 1.1.1 或更高版本 (1.15.4) 和 BoringSSL 时支持该指令。

ssl_ecdh_curve

指定 ECDHE 密码的曲线。

ssl_ecdh_curve curve;

默认值是 auto ,使用 OpenSSL 1.0.2 或更高版本时,可以指定多条曲线 (1.11.0),特殊值 auto (1.11.0) 指示 nginx 在使用 OpenSSL 1.0.2 或更高版本或使用旧版本的 prime256v1 时使用内置于 OpenSSL 库中的列表。

在 1.11.0 版本之前,默认使用 prime256v1 曲线。当使用 OpenSSL 1.0.2 或更高版本时,该指令设置服务器支持的曲线列表。因此,为了使 ECDSA 证书发挥作用,重要的是包含证书中使用的曲线。

ssl_ocsp

启用客户端证书链的 OCSP 验证。

ssl_ocsp on | off | leaf;

默认值是 off ,leaf 参数仅启用客户端证书的验证。使 OCSP 验证正常工作,应将 ssl_verify_client 指令设置为 on 或可选。要解析 OCSP 响应程序主机名,还应指定解析器指令。

ssl_ocsp_cache

为 OCSP 验证设置存储客户端证书状态的缓存的名称和大小。

ssl_ocsp_cache off | [shared:name:size];

默认值是 off ,缓存在所有工作进程之间共享。同名缓存可用于多个虚拟服务器。off 参数禁止使用缓存。

ssl_ocsp_responder

覆盖“授权信息访问”证书扩展中指定的 OCSP 响应者的 URL,以验证客户端证书。

ssl_ocsp_responder url;

仅支持“http://”OCSP 响应。

ssl_password_file

指定一个包含密钥密码短语的文件,其中每个密码短语在单独的行中指定。

ssl_password_file file;

加载密钥时会依次尝试密码短语。

ssl_prefer_server_ciphers

指定在使用 SSLv3 和 TLS 协议时,服务器加密算法应优先于客户端加密算法。

ssl_prefer_server_ciphers on | off;

默认值 off 。

ssl_protocols

启用指定的协议。

ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3];

默认值是 TLSv1 TLSv1.1 TLSv1.2 ,TLSv1.1 和 TLSv1.2 参数(1.1.13、1.0.12)仅在使用 OpenSSL 1.0.1 或更高版本时有效。TLSv1.3 参数 (1.13.0) 仅在使用 OpenSSL 1.1.1 或更高版本时有效。

ssl_reject_handshake

如果启用,服务器块中的 SSL 握手将被拒绝。

ssl_reject_handshake on | off;

默认 off 。

ssl_session_cache

设置存储会话参数的缓存的类型和大小。

ssl_session_cache off | none | [builtin[:size]] [shared:name:size];

它的参数意义是:

  • off 严格禁止使用会话缓存:nginx 明确告诉客户端会话可能不会被重用。

  • none 温和地禁止使用会话缓存:nginx 告诉客户端会话可以被重用,但实际上并没有将会话参数存储在缓存中。

  • builtin OpenSSL 中内置的缓存;仅由一个工作进程使用。缓存大小在会话中指定。如果未给出大小,则等于 20480 个会话。使用内置缓存会导致内存碎片。

  • shared 所有工作进程之间共享的缓存。缓存大小以字节为单位指定;一兆字节可以存储大约 4000 个会话。每个共享缓存都应该有一个任意名称。同名缓存可用于多个虚拟服务器。

两种缓存类型可以同时使用,例如:

ssl_session_cache builtin:1000 shared:SSL:10m;

但是只使用没有内置缓存的共享缓存应该更有效。

ssl_session_ticket_key

使用用于加密和解密 TLS 会话票证的密钥设置文件。

ssl_session_ticket_key file;

如果必须在多个服务器之间共享相同的密钥,则该指令是必需的。默认情况下,使用随机生成的密钥。

如果指定了多个密钥,则仅第一个密钥用于加密 TLS 会话票证。这允许配置密钥轮换,例如:

ssl_session_ticket_key current.key;
ssl_session_ticket_key previous.key;

该文件必须包含 80 或 48 字节的随机数据,根据文件大小,使用 AES256(对于 80 字节密钥,1.11.8)或 AES128(对于 48 字节密钥)进行加密。

ssl_session_tickets

通过 TLS 会话票证启用或禁用会话恢复。

ssl_session_tickets on | off;

默认 on 。

ssl_session_timeout

指定客户端可以重用会话参数的时间。

ssl_session_timeout time;

默认 5m 。

ssl_stapling

启用或禁用服务器对 OCSP 响应的装订。

ssl_stapling on | off;

默认 off ,要使 OCSP 装订工作,应该知道服务器证书颁发者的证书。如果 ssl_certificate 文件不包含中间证书,则服务器证书颁发者的证书应存在于 ssl_trusted_certificate 文件中。对于 OCSP 响应程序主机名的解析,还应指定解析器指令。

ssl_stapling_file

设置后,将从指定文件中获取装订的 OCSP 响应,而不是查询服务器证书中指定的 OCSP 响应者。

ssl_stapling_file file;

该文件应采用“openssl ocsp”命令生成的 DER 格式。

ssl_stapling_responder

覆盖“授权信息访问”证书扩展中指定的 OCSP 响应者的 URL。

ssl_stapling_responder url;

仅支持“http://”OCSP 响应。

ssl_stapling_verify

启用或禁用服务器对 OCSP 响应的验证。

ssl_stapling_verify on | off;

默认值 off ,为了使验证工作,服务器证书颁发者的证书、根证书和所有中间证书应使用 ssl_trusted_certificate 指令配置为受信任的。

ssl_trusted_certificate

如果启用了 ssl_stapling,则指定一个带有 PEM 格式的可信 CA 证书的文件,用于验证客户端证书和 OCSP 响应。

ssl_trusted_certificate file;

与 ssl_client_certificate 设置的证书相反,这些证书的列表不会发送给客户端。

ssl_verify_client

启用客户端证书的验证。验证结果存储在 $ssl_client_verify 变量中。

ssl_verify_client on | off | optional | optional_no_ca;

默认值 off 。可选 optional 参数 (0.8.7+) 请求客户端证书并验证证书是否存在。

optional_no_ca 参数(1.3.8、1.2.5)请求客户端证书,但不要求它由受信任的 CA 证书签名。这适用于 nginx 外部的服务执行实际证书验证的情况。证书的内容可通过 $ssl_client_cert 变量访问。

ssl_verify_depth

在客户端证书链中设置验证深度。

ssl_verify_depth number;

默认 1 。

总结

上面的配置是不是很多看着都很懵圈啊?如果是的话,那么咱们水平其实差不多,很多我也不知道是啥意思。但是就像前面说的,本着了解的态度来学习嘛。当然,最核心的那三个,也就是最上面我们配置的那三个还是需要了解的。还好,一个是要在 listen 后面跟上一个 ssl 参数,表示开启这个端口的 SSL 访问。另外两个就是指定密钥文件的地址。这三个配置说实话,真不复杂,也非常好记。

下篇文章我们将继续 SSL 的学习,主要是继续介绍 SSL 模块的错误状态码、变量信息以及分析一下宝塔生成的 SSL 配置是什么内容。

参考文档:

http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_conf_command

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录打卡第五十六天|1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和

1143.最长公共子序列 题目&#xff1a; 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的…

深入理解udp

1.再谈端口号 1.1复习 我们上一篇谈了很久的应用层的http&#xff0c;并在此前我们使用socket编程写了一个能相互通信的客户端与服务端&#xff0c;但是我们也只是粗略的理解了一下tcp和udp在编程过程中所形成的差异性&#xff0c;并没有实质去了解一下其详细内容&#xff0c;…

家政服务系统小程序app开发功能架构;

家政服务小程序系统&#xff0c;轻松搭建上门服务小程序。支持H5与小程序双端&#xff0c;还能DIY页面。根据您的需求&#xff0c;我们可定制开发家政服务小程序系统。想添加多种服务类目、优惠专区以及IM即时沟通功能&#xff1f;没问题&#xff0c;我们支持&#xff01;想要快…

【计算机网络笔记】传输层——可靠数据传输原理之Rdt协议

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

局域网内两台电脑共享文件夹(通过网线直连共享数据)

文章目录 2.设置共享文件夹3.访问共享文件夹 1.将两台电脑置于同一局域网下 用网线将两台电脑连接关闭两台电脑防火墙将两台电脑IP地址设置在同一局域网下 测试是否在同一局域网下&#xff0c;使用ping命令 ping 192.168.0.122.设置共享文件夹 选择想要共享的文件夹&#xff…

微服务-统一网关Gateway

网关的作用 对用户请求做身份认证、权限校验将用户请求路由到微服务&#xff0c;并实现负载均衡对用户请求做限流 搭建网关服务 创建新module&#xff0c;命名为Gateway&#xff0c;引入依赖&#xff08;1.SpringCloudGateway依赖&#xff1b;2.Eureka客户端依赖或者nacos的服…

git命令清单

一、设置和配置 1.初始化一个新的仓库&#xff1a; git init2.克隆&#xff08;Clone&#xff09;一个远程仓库到本地&#xff1a; git clone <repository_url>3.配置用户信息&#xff1a; git config --global user.name "Your Name" git config --global…

CentOS 安装 Hadoop Local (Standalone) Mode 单机模式

CentOS 安装 Hadoop Local (Standalone) Mode 单机模式 Hadoop Local (Standalone) Mode 单机模式 1. 修改yum源 并升级内核和软件 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repoyum clean allyum makecacheyum -y update2. 安…

【新品首发】DPEasy,让数据库安全风险无所遁形!

就在今天&#xff0c;DPEasy 正式出道啦&#xff01;&#xff01;&#xff01; DPEasy 是由杭州图尔兹信息技术有限公司自主研发的一款高效的数据库安全风险扫描工具&#xff0c;旨在帮助大家发现并分析出数据库可能面临的安全威胁。同时&#xff0c;在不影响应用运行的情况下…

【Java 进阶篇】深入理解 Java Response:从基础到高级

HTTP响应&#xff08;Response&#xff09;是Web开发中的一个关键概念&#xff0c;它是服务器向客户端&#xff08;通常是浏览器&#xff09;返回数据的方式。理解如何在Java中处理和构建HTTP响应是开发Web应用程序的重要一部分。本文将从基础知识到高级技巧&#xff0c;详细介…

Qt QWidget、QDialog、QMainWindow的区别

QWidget QWidget是Qt框架中最基础的窗口类&#xff0c;可以理解为用户界面的最基本单元。QWidget类提供了一个空白窗口&#xff0c;可以通过继承该类来创建自定义的窗口类。QWidget类提供了基本的窗口属性和方法&#xff0c;如大小、位置、标题、图标等。 QDialog QDialog是…

【设计模式】第18节:行为型模式之“迭代器模式”

一、简介 迭代器模式&#xff08;Iterator Design Pattern&#xff09;&#xff0c;也叫作游标模式&#xff08;Cursor Design Pattern&#xff09;。 在通过迭代器来遍历集合元素的同时&#xff0c;增加或者删除集合中的元素&#xff0c;有可能会导致某个元素被重复遍历或遍…

Flask Shell 操作 SQLite

一、前言 这段时间在玩Flask Web&#xff0c;发现用Flask Shell去操作SQLite还是比较方便的。今天简单地介绍一下。 二、SQLite SQLite是一种嵌入式数据库&#xff0c;它的数据库就是一个文件&#xff0c;处理速度快&#xff0c;经常被集成在各种应用程序中&#xff0c;在IO…

安装OPENCMS过程记录

今天尝试安装个人网站&#xff0c;或者说是内容管理系统&#xff0c;wordpress 是PHP的&#xff0c;所以上网找了一个免费的&#xff0c;在知乎上基于Java的开源CMS有哪些推荐&#xff0c;各自特点是什么 - 知乎 (zhihu.com) 找了这个opencms&#xff0c;据说是免费&#xff0…

什么是AUTOSAR ComStack,AUTOSAR架构中,CAN通信堆栈CAN Communication Stack介绍

AUTOSAR&#xff08;Automotive Open System Architecture&#xff09;ComStack指的是AUTOSAR架构中的通信堆栈。在AUTOSAR体系结构中&#xff0c;ComStack是指用于不同软件组件&#xff08;如应用软件、基础软件等&#xff09;之间进行通信的一组协议和服务。 在AUTOSAR架构中…

对象存储那点事

在很长的一段时间里&#xff0c;DAS、SAN 和 NAS 这三种架构几乎统治了数据存储市场。所有行业用户的数据存储需求&#xff0c;都是在这三者中进行选择。 然而&#xff0c;随着时代的发展&#xff0c;一种新的数据存储形态诞生&#xff0c;开始挑战前面三者的垄断地位。没错&am…

基于ISO13209(OTX)实现引导诊断

在之前的文章《基于ISO13209&#xff08;OTX&#xff09;实现EOL下线序列》中&#xff0c;讲到了OTX的由来以及OTX在EOL中的实现案例&#xff0c;而本文将讲述OTX的另一个广阔应用场景——定义引导诊断序列。 一 何为引导诊断&#xff1f; 引导诊断&#xff0c;通常也称为“引…

上海亚商投顾:三大指数小幅调整,医药股继续活跃

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 沪指昨日弱势震荡&#xff0c;尾盘探底回升一度翻红&#xff0c;深成指盘中跌超1%&#xff0c;午后跌幅有所收窄。…

两个字符串的最小ASCII删除和

题目描述 给定两个字符串s1 和 s2&#xff0c;返回 使两个字符串相等所需删除字符的 ASCII 值的最小和 。 示例 思路 这个题的解法一和最长公共子序列的解法大致相同&#xff0c;我们可以在此代码基础上稍微更改即可。 代码如下 解法一 public int minimumDeleteSum1(Stri…

unittest与pytest的区别

Unittest vs Pytest 主要从用例编写规则、用例的前置和后置、参数化、断言、用例执行、失败重运行和报告这几个方面比较unittest和pytest的区别: 用例编写规则 用例前置与后置条件 断言 测试报告 失败重跑机制 参数化 用例分类执行 如果不好看&#xff0c;可以看下面表格&…