用go搭建tls服务器
tls 简介(来自 wiki)
Transport Layer Security (TLS), and its now-deprecated predecessor, Secure Sockets Layer (SSL), are cryptographic protocols designed to provide communications security over a computer network. Several versions of the protocols are widely used in applications such as email, instant messaging, and voice over IP, but its use as the Security layer in HTTPS remains the most publicly visible.
The TLS protocol aims primarily to provide privacy and data integrity between two or more communicating computer applications.
The TLS protocol comprises two layers: the TLS record and the TLS handshake protocols.
TLS is a proposed Internet Engineering Task Force (IETF) standard, first defined in 1999, and the current version is TLS 1.3 defined in August 2018. TLS builds on the earlier SSL specifications (1994, 1995, 1996) developed by Netscape Communications for adding the HTTPS protocol to their Navigator web browser.
TLS和SSL两者都是加密协议,旨在提供计算机网络上的通信安全性。TLS协议的主要目的是在两个或多个通信计算机应用程序之间提供隐私和数据完整性。
tls 与 ssl 的联系与差别
两者都是为网络通信加密的协议。tls 可以说是 ssl 的升级版本,ssl 已经被遗弃了。
Protocol | Published | Status |
SSL 1.0 | Unpublished | Unpublished |
SSL 2.0 | 1995 | Deprecated in 2011 |
SSL 3.0 | 1996 | Deprecated in 2015 |
TLS 1.0 | 1999 | Deprecated in 2020 |
TLS 1.1 | 2006 | Deprecated in 2020 |
TLS 1.2 | 2008 | |
TLS 1.3 | 2018 |
利用 openssl 来生成证书
搭建 tls 服务器时需要用到证书来证明服务器的身份。
生成 RSA 私钥和自签名证书
openssl req -newkey rsa:2048 -nodes -keyout rsa_private.key -x509 -days 365 -out cert.crt
-
req是证书请求的子命令
-
-newkey rsa:2048 -keyout private_key.pem 表示生成私钥(PKCS8格式)
-
-nodes 表示私钥不加密,若不带该参数将提示输入密码。
-
-x509表示输出证书
-
-days 365 为有效期
-
此后根据提示输入证书拥有者信息,若执行自动输入,可使用-subj 选项。
openssl req -newkey rsa:2048 -nodes -keyout rsa_private.key -x509 -days 365 -out cert.crt -subj "/C=CN/ST=GD/L=SZ/O=vihoo/OU=dev/CN=vivo.com/emailAddress=yy@vivo.com"
生成后缀名为 pem 的证书
ad8 [code]openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
其实后缀名为
.pem与后缀名为
.crt的差别不大。因为用这个参数生成的证书都是文本格式的。后缀为
.crt的优势是,在window系统下面双击能触发安装证书的程序。
根据 RSA 私钥生成自签名
openssl req -new -x509 -days 365 -key rsa_private.key -out cert.crt
搭建 tls 服务器
在
go中有
"crypto/tls",可以方便的处理与
tls有关的业务。
func StartTcpServerWithTls(addr, certFile, keyFile string) { crt, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { panic(err) } tlsConfig := tls.Config{ Certificates: []tls.Certificate{crt}, } tlsListener, err := tls.Listen("tcp4", addr, &tlsConfig) if err != nil { panic(err) } for true { conn, err := tlsListener.Accept() if err != nil { fmt.Printf("AcceptTCP(),err[%v]\n", err) continue } // 返回的是一个 net.Conn,所以没办法设置 ReadBuffer 和 WriteBuffer // 随它去吧 // 所以用的是系统默认的 tcp buffer // linux 下面 // cat /proc/sys/net/ipv4/tcp_wmem // cat /proc/sys/net/ipv4/tcp_rmem go func() { readBuf := make([]byte, 1024) bsCount, err := conn.Read(readBuf) if err != nil { fmt.Printf("Read(),err[%v]\n", err) return } fmt.Println(string(readBuf[:bsCount])) _, err = conn.Write([]byte("hello from server")) if err != nil { fmt.Printf("Write(),err[%v]\n", err) return } }() } }
搭建 tls 客户端
不验证证书
将
tls.Config中的
InsecureSkipVerify设置为
true即可。
func tlsClient(address string) { conf := &tls.Config{ InsecureSkipVerify: true, } conn, err := tls.Dial("tcp", address, conf) if err != nil { log.Println(err) return } defer conn.Close() n, err := conn.Write([]byte("hello from client\n")) if err != nil { log.Println(n, err) return } buf := make([]byte, 1024) n, err = conn.Read(buf) if err != nil { log.Println(n, err) return } log.Println(string(buf[:n])) }
验证证书
需要在电脑上安装之前生成的 crt 证书。且一定要把该证书放在受信任的根证书颁发机构下面。
windows下面可以通过
certmgr.msc命令来管理证书。
Country ad1 Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:www.xxx.com // 注意这里哦 Email Address []:
此外需要将
tls.Config中的
ServerName设置为之前生成证书时的
FADN。
func tlsRun(address, serverName string) { conf := &tls.Config{ ServerName: serverName, } conn, err := tls.Dial("tcp", address, conf) if err != nil { log.Println(err) return } defer conn.Close() n, err := conn.Write([]byte("hello from client\n")) if err != nil { log.Println(n, err) return } buf := make([]byte, 1024) n, err = conn.Read(buf) if err != nil { log.Println(n, err) return } log.Println(string(buf[:n])) }
参考链接
- Go搭建一个Web服务器
- 02.go搭建一个web服务器
- Go搭建第一个web服务器
- Ubuntu Linux服务器搭建SSL/TLS(https)(在StartSSL可以得到免费证书)
- Ubuntu 64-bit下搭建 Apache 2、PHP5、MySQL、GO Web服务器
- GO学习第二天——web服务器搭建
- Go 搭建一个Web 服务器(1):IOC工厂
- Go搭建一个web服务器
- go语言 通过http包搭建简单web服务器 对http包源码的略微分析
- 搭建一个简单的Go Web服务器
- Go游戏服务器开发的一些思考(十八):Docker内网环境搭建(备忘)
- GO搭建一个web服务器
- 用go-module作为包管理器搭建go的web服务器
- Go利用net/http包搭建Web服务器
- Mosquitto服务器的搭建以及SSL/TLS安全通信配置 openhab raspberry-pi 眼泪成诗hocc 2016年05月07日发布 4.8k 次浏览 1、 SSL简介 SSL
- 在 Ubuntu 上使用 SSL/TLS 搭建一个安全的 FTP 服务器
- go搭建一个简单web服务器
- Go搭建简单服务器及http包源码分析
- Go语言进行web开发(一) 搭建一个简单的web服务器
- FTP服务器三种模式搭建详解(vsftpd)