陈天 · Rust 编程第一课
陈天
Tubi TV 研发副总裁
23195 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 65 讲
基础篇 (21讲)
陈天 · Rust 编程第一课
15
15
1.0x
00:00/00:00
登录|注册

37|阶段实操(5):构建一个简单的KV server-网络安全

使用noise protocol
服务器验证客户端的证书
思考题
在Rust下使用TLS的方便性
网络安全的重要性
让KV client/server支持TLS
在KV server中使用TLS
生成x509证书
小结
使用TLS保证客户端和服务器间的安全性
构建KV server整个网络部分的构建
构建一个简单的KV server
网络安全

该思维导图由 AI 生成,仅供参考

你好,我是陈天。
上一讲我们完成了 KV server 整个网络部分的构建。而安全是和网络密不可分的组成部分,在构建应用程序的时候,一定要把网络安全也考虑进去。当然,如果不考虑极致的性能,我们可以使用诸如 gRPC 这样的系统,在提供良好性能的基础上,它还通过 TLS 保证了安全性。
那么,当我们的应用架构在 TCP 上时,如何使用 TLS 来保证客户端和服务器间的安全性呢?

生成 x509 证书

想要使用 TLS,我们首先需要 x509 证书。TLS 需要 x509 证书让客户端验证服务器是否是一个受信的服务器,甚至服务器验证客户端,确认对方是一个受信的客户端。
为了测试方便,我们要有能力生成自己的 CA 证书、服务端证书,甚至客户端证书。证书生成的细节今天就不详细介绍了,我之前做了一个叫 certify 的库,可以用来生成各种证书。我们可以在 Cargo.toml 里加入这个库:
[dev-dependencies]
...
certify = "0.3"
...
然后在根目录下创建 fixtures 目录存放证书,再创建 examples/gen_cert.rs 文件,添入如下代码:
use anyhow::Result;
use certify::{generate_ca, generate_cert, load_ca, CertType, CA};
use tokio::fs;
struct CertPem {
cert_type: CertType,
cert: String,
key: String,
}
#[tokio::main]
async fn main() -> Result<()> {
let pem = create_ca()?;
gen_files(&pem).await?;
let ca = load_ca(&pem.cert, &pem.key)?;
let pem = create_cert(&ca, &["kvserver.acme.inc"], "Acme KV server", false)?;
gen_files(&pem).await?;
let pem = create_cert(&ca, &[], "awesome-device-id", true)?;
gen_files(&pem).await?;
Ok(())
}
fn create_ca() -> Result<CertPem> {
let (cert, key) = generate_ca(
&["acme.inc"],
"CN",
"Acme Inc.",
"Acme CA",
None,
Some(10 * 365),
)?;
Ok(CertPem {
cert_type: CertType::CA,
cert,
key,
})
}
fn create_cert(ca: &CA, domains: &[&str], cn: &str, is_client: bool) -> Result<CertPem> {
let (days, cert_type) = if is_client {
(Some(365), CertType::Client)
} else {
(Some(5 * 365), CertType::Server)
};
let (cert, key) = generate_cert(ca, domains, "CN", "Acme Inc.", cn, None, is_client, days)?;
Ok(CertPem {
cert_type,
cert,
key,
})
}
async fn gen_files(pem: &CertPem) -> Result<()> {
let name = match pem.cert_type {
CertType::Client => "client",
CertType::Server => "server",
CertType::CA => "ca",
};
fs::write(format!("fixtures/{}.cert", name), pem.cert.as_bytes()).await?;
fs::write(format!("fixtures/{}.key", name), pem.key.as_bytes()).await?;
Ok(())
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何在Rust中构建一个简单的KV server,并着重讨论了网络安全的重要性。作者强调了在基于TCP的应用架构中使用TLS来确保客户端和服务器之间的安全性。文章提到了生成x509证书的必要性,并介绍了使用certify库来生成各种证书的方法。接着给出了一个简单的Rust代码示例,演示了如何生成CA证书、服务端证书和客户端证书,并将它们存入fixtures目录。读者可以通过运行`cargo run --examples gen_cert`命令来生成这些证书和密钥。整个过程简单明了,为读者提供了一种快速了解如何构建一个简单KV server并保证网络安全的方法。文章还介绍了在KV server中使用TLS的重要性,以及如何在Rust下使用tokio-rustls库来实现TLS支持。通过代码示例和测试,读者可以了解如何在Rust中轻松实现TLS协议,保护网络通讯的安全。文章还提到了在KV server中使用TLS的重要性,以及如何在Rust下使用tokio-rustls库来实现TLS支持。通过代码示例和测试,读者可以了解如何在Rust中轻松实现TLS协议,保护网络通讯的安全。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《陈天 · Rust 编程第一课》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(4)

  • 最新
  • 精选
  • 罗同学
    ca 证书和 tls什么关系呢? 另外为何以前做网站的时候证书都要向运营商购买申请?那个是什么证书

    作者回复: TLS 使用非对称加密(比如 ECDH)来协商出本次 session 的密钥。问题是客户端如何信任服务器提供的公钥就是服务器本人?此时需要有人对服务器的公钥进行签名,为其背书,这个背书着就是 CA。那 CA 又是谁来背书?小 CA 由大 CA 背书,大 CA 再被 Root CA 背书。全世界也就几个十几个 Root CA。这些 Root CA 会被你所使用的操作系统信任。这样,某个服务器的证书就可以被一层层追溯到 Root CA,最终客户端可以信任它。这是 PKI 体系的基础。所有的网站,如果要支持 HTTPS,都需要有一个受信的证书。以前需要购买,现在有了 letsencrypt(背后有 google 的支持),所以可以免费得到受信的证书。 当你把 TLS 直接用在 TCP 之上时,可以自己生成 CA 证书。因为此刻,客户端和服务端都是你自己的代码,你可以在客户端内置信任的 CA 证书,这样就可以不依赖 PKI 体系来在服务器和客户端之间构建安全信道。

    2021-11-24
    12
  • 罗杰
    生成证书这块是我比较欠缺的知识,可以好好补充一下了。

    作者回复: 👍

    2021-11-24
  • David.Du
    感谢大神!
    2023-11-30归属地:辽宁
  • 新新人类
    思考题1: 将 ServerConfig 的 ClientCertVerifier 改成 AllowAnyAuthenticatedClient pub fn new(cert: &str, key: &str, client_ca: Option<&str>) -> Result<Self, KvError> { let certs = load_certs(cert)?; let key = load_key(key)?; let mut root_store = match rustls_native_certs::load_native_certs() { Ok(store) | Err((Some(store), _)) => store, Err((None, err)) => { return Err(err.into()); } }; // 如果有签署客户端的 CA 证书,则加载它,这样客户端证书不在根证书链 // 但是这个 CA 证书能验证它,也可以 if let Some(cert) = client_ca { let mut buf = Cursor::new(cert); root_store.add_pem_file(&mut buf).unwrap(); } // 加载 server cert / CA cert,生成 ServerConfig let mut config = ServerConfig::new(AllowAnyAuthenticatedClient::new(root_store)); // 加载服务器证书 config .set_single_cert(certs, key) .map_err(|_| KvError::CertificateParseError("server", "cert"))?; config.set_protocols(&[Vec::from(&ALPN_KV[..])]); Ok(Self { inner: Arc::new(config), }) }
    2022-05-14
收起评论
显示
设置
留言
4
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部