写给Go开发者的Tars教程-安全

2024-01-11
2分钟阅读时长

本篇为【写给go开发者的Tars教程】系列第七篇

第一篇:Tars协议基础

第二篇:通信模式

第三篇:拦截器

第四篇:错误处理

第五篇:context/status

第六篇:超时控制

第七篇:安全 👈

本系列将持续更新,欢迎关注 👏 获取实时通知


使用 TLS 安全传输数据

什么是 SSL/TLS

SSL 包含记录层(Record Layer)和传输层[1],记录层协议确定传输层数据的封装格式。传输层安全协议使用X.509[2]认证,之后利用非对称加密演算来对通信方做身份认证,之后交换对称密匙作为会话密匙(Session key[3])。这个会谈密匙是用来将通信两方交换的资料做加密,保证两个应用间通信的保密性和可靠性,使客户与服务器应用之间的通信不被攻击者窃听。

— 维基百科

SSL(Secure Sockets Layer)/TLS(Transport Layer Security)是网络通信中用于实现安全传输的协议。它们提供了加密、身份验证和数据完整性的功能,以确保在客户端和服务器之间传输的数据是安全的。

  • 加密数据: SSL/TLS使用加密算法对数据进行加密,防止在传输过程中被窃取或篡改,确保数据的机密性。

  • 身份验证:

    • 单向认证: 仅服务器需要验证其身份,客户端验证服务器的证书,确保连接的合法性。
    • 双向认证: 除了服务器验证客户端,客户端还提供证书供服务器验证,增加了对双方身份的确认。
  • 数据完整性: 使用哈希函数等机制确保数据在传输过程中未被篡改,维护数据的完整性。

SSL/TLS广泛用于加密网页浏览、电子邮件传输和其他网络应用,通过提供安全通信,防止中间人攻击和保护用户隐私。选择单向或双向认证取决于具体需求,平衡了安全性和复杂性的考虑。

单向认证

单向认证是SSL/TLS协议中的一种身份验证方式,主要涉及服务器向客户端证明其身份的过程。在单向认证中,只有服务器需要提供数字证书,而客户端不需要提供自己的证书。以下是单向认证的详细讲解:

  1. 服务器提供数字证书: 服务器在通信开始前,需要向客户端提供一个数字证书。数字证书通常由受信任的证书颁发机构(CA)签发,证明服务器的身份。证书包含了服务器的公钥以及与之相关的私钥,以确保客户端能够验证其合法性。

  2. 客户端验证服务器证书: 客户端在接收到服务器的数字证书后,使用事先保存的CA公钥来验证证书的签名。如果验证成功,客户端可以确认服务器的身份是合法的,并且可以信任该服务器。

  3. 建立安全通信: 一旦服务器的身份得到确认,客户端和服务器之间的通信就可以开始。SSL/TLS协议使用服务器的公钥对数据进行加密,确保在传输过程中数据的机密性。同时,使用数字签名和哈希函数来保证数据的完整性。

  4. 完成握手过程: 整个单向认证过程完成后,SSL/TLS握手阶段结束,安全通信通道建立起来,双方可以安全地进行数据传输。

总的来说,单向认证确保了客户端与合法服务器的安全通信,适用于大多数互联网应用场景。

✨ 证书组成

在生产环境通常是生成一个 CA 根证书,然后使用 CA 根证书去签名多个服务端的证书。这种方式可以一次管理多个证书,也比较贴近真实情况,当然也可以用来做证书过期、更新等试验,缺点是操作起来略微麻烦一点。

rootCA.key:ca 机构的私钥,用来给服务端签发证书

rootCA.crt:ca 的证书,用来给客户端验证服务端证书

server.key:RSA 的私钥,用来进行数字签名

server.crt:由 ca 签发的服务端证书

图片

单向认证-根证书模式

服务端全局配置:

我们只需要添加SSL/TLS相关配置,程序代码无需任何改动

<tars>
    <application>
        <server>
            # ...
            # 服务器public证书
            cert=ssl/server.crt
            # 服务器private证书
            key=ssl/server.key
            <Test.OrderServer.OrderObjAdapter>
                # ......
                # 只需要把tcp 改为 ssl
                endpoint=ssl -h 127.0.0.1 -p 8080 -t 60000
                # ......
            </Test.OrderServer.OrderObjAdapter>
        </server>
    </application>
</tars>

客户端全局配置:

  1. 对于客户端同样我们只需要添加SSL/TLSca配置
<tars>
    <application>
        <client>
            # ca证书
            ca=ssl/rootCA.crt
        </client>
    </application>
</tars>
  1. 连接协议改为ssl如下代码
func main() {
	comm := tars.GetCommunicator()
	client := new(order.OrderManagement)
    // Test.OrderServer.OrderObj@ 后的 tcp 改为了 ssl
	obj := "Test.OrderServer.OrderObj@ssl -h 127.0.0.1 -p 8080 -t 60000"
	comm.StringToProxy(obj, client)
	// ......
}

证书认证脚本:

shell脚本一次性生成了ca/server/client相关私钥和证书,方便测试使用

#!/bin/bash

set -ex
mkdir -p ssl
cd ssl
# ca
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -days 1024 -out rootCA.crt \
  -subj "/C=CN/ST=BeiJing/L=BJ/O=Tars/OU=TarsGo/CN=TarsCa/emailAddress=lbbniu@gmail.com"

# server
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
  -subj "/C=CN/ST=BeiJing/L=BJ/O=Tars/OU=TarsGo/CN=server/emailAddress=lbbniu@gmail.com"\
  -addext "subjectAltName=IP:127.0.0.1"
#openssl req -text -in server.csr -noout -verify
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 500 \
  -extfile <(printf "subjectAltName=IP:127.0.0.1")
#openssl x509 -in server.crt -noout -text

# client
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
  -subj "/C=CN/ST=BeiJing/L=BJ/O=Tars/OU=TarsGo/CN=client/emailAddress=lbbniu@gmail.com"
#openssl req -text -in client.csr -noout -verify
openssl x509 -req -in client.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out client.crt -days 500
cd -

运行代码:

# 终端1
go run client/main.go --config=config/config.conf
# 终端2
go run main.go --config=config/config.conf

双向认证(mTLS)

双向认证是SSL/TLS协议中的身份验证方式,要求服务器验证客户端证书和客户端验证服务器证书,以确保通信双方的合法身份。下面进行介绍TarsGo中的应用

证书组成

rootCA.key:ca 机构的私钥,用来给服务端签发证书

rootCA.crt:ca 的证书,用来给客户端验证服务端证书

server.key:服务端 RSA 的私钥,用来进行数字签名

server.crt:由 ca 签发的服务端证书

client.key: 客户端 RSA 私钥,用来进行数字签名

client.crt: 由 ca 签发的客户端证书

image-20240115224454191

服务端配置如下:

<tars>
    <application>
        <server>
            # ......
            # ca公有证书,不验证客户端可以不填写
            ca=ssl/rootCA.crt
            # 是否验证客户端
            verifyclient=1
            # 服务器public证书
            cert=ssl/server.crt
            # 服务器private证书
            key=ssl/server.key
            <Test.OrderServer.OrderObjAdapter>
                # ......
                endpoint=ssl -h 127.0.0.1 -p 8080 -t 60000
                # ......
            </Test.OrderServer.OrderObjAdapter>
        </server>
    </application>
</tars>

客户端配置如下:

<tars>
    <application>
        <client>
            # ca证书
            ca=ssl/rootCA.crt
            # 客户端public证书
            cert=ssl/client.crt
            # 客户端私钥
            key=ssl/client.key
        </client>
    </application>
</tars>

** 运行代码同上 **

进阶

TarsGo同样支持对不不同的Servant配置不同的证书,下面给出ssl完整配置共小伙伴们参考

<tars>
    <application>
        <client>
            # ca证书
            ca=ssl/rootCA.crt
            # 客户端public证书
            cert=ssl/client.crt
            # 客户端私钥
            key=ssl/client.key
            <Test.OrderServer.OrderObj>
                ca=ssl/rootCA.crt
                # 客户端public证书
                cert=ssl/client.crt
                # 客户端私钥
                key=ssl/client.key
            </Test.OrderServer.OrderObj>
        </client>
        <server>
            # ......
            # ca公有证书,不验证客户端可以不填写
            ca=ssl/rootCA.crt
            # 是否验证客户端
            verifyclient=1
            # 服务器public证书
            cert=ssl/server.crt
            # 服务器private证书
            key=ssl/server.key
            <Test.OrderServer.OrderObjAdapter>
                allow
                endpoint=ssl -h 127.0.0.1 -p 8080 -t 60000
                # ......
                # ca公有证书,不验证客户端可以不填写
                ca=ssl/rootCA.crt
                # 是否验证客户端
                verifyclient=0
                # 服务器public证书
                cert=ssl/server.crt
                # 服务器private证书
                key=ssl/server.key
            </Test.OrderServer.OrderObjAdapter>
        </server>
    </application>
</tars>

总结

经过上面对TarsGo中怎么开启SSL/TLS的相关介绍,详细小伙们已经可以启动开启此功能是自己的服务更安全了。


👇 欢迎关注👇

关注公众号获得更多精彩文章

公众号:程序员大兵