亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

golang使用mTLS實(shí)現(xiàn)雙向加密認(rèn)證http通信

 更新時(shí)間:2023年08月08日 09:28:36   作者:花酒鋤作田  
這篇文章主要為大家介紹了golang如何調(diào)用mTLS實(shí)現(xiàn)雙向加密認(rèn)證http通信,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的小伙伴可以參考下

前言

假設(shè)一個(gè)場(chǎng)景,服務(wù)端部署在內(nèi)網(wǎng),客戶端需要通過暴露在公網(wǎng)的nginx與服務(wù)端進(jìn)行通信。為了避免在公網(wǎng)進(jìn)行 http 明文通信造成的信息泄露,nginx與客戶端之間的通信應(yīng)當(dāng)使用 https 協(xié)議,并且nginx也要驗(yàn)證客戶端的身份,也就是mTLS雙向加密認(rèn)證通信。

這條通信鏈路有三個(gè)角色:服務(wù)端、Nginx、客戶端。

  • 服務(wù)端部署在內(nèi)網(wǎng),與nginx使用http通信。
  • 客戶端在公網(wǎng),與nginx使用https通信,且雙向加密認(rèn)證。

服務(wù)端

服務(wù)端只使用http,所以這里用gin框架寫個(gè)簡(jiǎn)單的示例,返回客戶端一些基本的http信息,比如客戶端IP、請(qǐng)求方法、host等。

package main
import (
	"log"
	"net/http"
	"time"
	"github.com/gin-gonic/gin"
)
/* 中間件: 獲取api處理時(shí)長(zhǎng) */
func midElapsed(c *gin.Context) {
	start := time.Now()
	c.Next()
	elapsed := time.Since(start)
	log.Printf("API: %s, elapsed: %s", c.Request.URL.Path, elapsed)
}
/* 處理 GET / 請(qǐng)求 */
func f1(c *gin.Context) {
	// 獲取客戶端IP
	clientIP := c.ClientIP()
	// 獲取請(qǐng)求方法
	method := c.Request.Method
	// 獲取協(xié)議
	proto := c.Request.Proto
	// 獲取host
	host := c.Request.Host
	// 請(qǐng)求Path
	path := c.Request.URL.Path
	log.Printf("客戶端IP: %s, 請(qǐng)求方法: %s, 協(xié)議: %s, host: %s, path: %s", clientIP, method, proto, host, path)
	// 獲取請(qǐng)求頭
	headers := c.Request.Header
	for hk, hv := range headers {
		log.Printf("header key: %s, value: %s", hk, hv)
	}
	// 獲取名為"mycookie"的cookie
	var cookies []string
	cookie, err := c.Cookie("mycookie")
	if err != nil {
		log.Printf("get cookie [mycookie] error: %s", err)
	} else {
		log.Printf("get cookie [mycookie]: %s", cookie)
		cookies = append(cookies, cookie)
	}
	c.JSON(http.StatusOK, gin.H{
		"clientIP": clientIP,
		"method":   method,
		"proto":    proto,
		"host":     host,
		"headers":  headers,
		"cookies":  cookies,
		"path":     path,
	})
}
func main() {
	r := gin.Default()
	r.Use(midElapsed) // 全局引用計(jì)算耗時(shí)的中間件
	r.GET("/", f1)
	r.Run("0.0.0.0:8080")
}

生成證書

1.生成ca根證書。生成過程會(huì)要求填寫密碼、CN、ON、OU等信息,記住密碼,填寫的信息也要和下一步openssl.cnf文件內(nèi)容一致。

openssl req -x509 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 3650

2.新建并編輯文件openssl.cnf文件。req_distinguished_name中內(nèi)容按需填寫,DNS.1要替換成實(shí)際域名。

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
countryName = CN
stateOrProvinceName = Anhui
localityName = Hefei
organizationName = zhangsan
commonName = qw.er.com
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = qw.er.com

3.生成服務(wù)端證書

openssl req -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/CN=qw.er.com" -config openssl.cnf
# 提示輸入ca私鑰的密碼
openssl x509 -req -in server.csr -out server.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -extensions v3_req -extfile openssl.cnf

4.生成客戶端證書

openssl req -newkey rsa:2048 -nodes -keyout client.key -out client.csr -subj "/CN=qw.er.com" -config openssl.cnf
# 提示輸入ca私鑰的密碼
openssl x509 -req -in client.csr -out client.crt -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -extensions v3_req -extfile openssl.cnf

Nginx配置

nginx反向代理服務(wù)端的配置示例如下

server {
    listen 80 ssl;
    server_name qw.er.com;
    ssl_certificate /home/atlas/apps/nginx/certs/qwer/server.crt;
    ssl_certificate_key /home/atlas/apps/nginx/certs/qwer/server.key;
    # 校驗(yàn)客戶端證書
    ssl_verify_client on;
    ssl_client_certificate /home/atlas/apps/nginx/certs/qwer/ca.crt;
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-real-ip $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://192.168.0.10:8080; # 服務(wù)端地址
    }
}

客戶端

以下示例使用命令行傳參的方式,指定tls證書文件和是否使用tls通信。

package main
import (
	"crypto/tls"
	"crypto/x509"
	"flag"
	"io"
	"log"
	"net/http"
	"os"
	"time"
)
var (
	cafile  = flag.String("cafile", "ca.crt", "ca 證書文件")
	crtfile = flag.String("crtfile", "client.crt", "客戶端tls證書")
	keyfile = flag.String("keyfile", "client.key", "客戶端tls私鑰")
	url     = flag.String("url", "http://127.0.0.1:8080", "url")
	isTls   = flag.Bool("tls", false, "是否使用tls")
)
func tlsClient(cafile, crtfile, keyfile string) *http.Transport {
	// 加載證書和私鑰
	clientCert, err := tls.LoadX509KeyPair(crtfile, keyfile)
	if err != nil {
		log.Fatalf("load key pair error: %s", err)
	}
	// 加載ca證書
	clientCA, err := os.ReadFile(cafile)
	if err != nil {
		log.Fatalf("load ca cert error: %s", err)
	}
	// 創(chuàng)建根證書池并添加ca證書
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(clientCA)
	// 創(chuàng)建transport
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{
			Certificates: []tls.Certificate{clientCert},
			RootCAs:      caCertPool,
		},
	}
	return tr
}
func main() {
	flag.Parse()
	req, err := http.NewRequest("GET", *url, nil)
	if err != nil {
		log.Fatalf("new request error: %s", err)
	}
	// 自定義HTTP請(qǐng)求頭
	req.Header.Set("myheader1", "myheader1value123")
	// 自定義一個(gè)cookie對(duì)象
	cookie := &http.Cookie{
		Name: "mycookie",
		Value: "mycookievalue",
	}
	req.AddCookie(cookie)
	client := &http.Client{
		Timeout: time.Second * 5,
	}
	if *isTls {
		client.Transport = tlsClient(*cafile, *crtfile, *keyfile)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatalf("get error: %s", err)
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatalf("read error: %s", err)
	}
	log.Printf("body: %+v", string(body))
}

Nginx配置

server {
    listen 80 ssl;
    server_name qw.er.com;
    ssl_certificate /home/elifen/apps/nginx/certs/qwer/server.crt;
    ssl_certificate_key /home/elifen/apps/nginx/certs/qwer/server.key;
    ssl_verify_client on;
    ssl_client_certificate /home/elifen/apps/nginx/qwer/ca.crt;
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-real-ip $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://192.168.0.10:8080;
    }
}

測(cè)試

這里需要先確保qw.er.com能被正常解析到nginx服務(wù)器,比如配置hosts文件或dns解析記錄。

go run main.go -cafile ./ca.crt -crtfile ./client.crt -keyfile ./client.key -url 'https://qw.er.com:80/' -tls

輸出示例

2023/08/07 17:34:51 body: {"clientIP":"192.168.0.11","cookies":["mycookievalue"],"headers":{"Accept-Encoding":["gzip"],"Connection":["close"],"Cookie":["mycookie=mycookievalue"],"Myheader1":["myheader1value123"],"User-Agent":["Go-http-client/1.1"],"X-Forwarded-For":["192.168.0.11"],"X-Real-Ip":["192.168.0.11"]},"host":"qw.er.com","method":"GET","path":"/","proto":"HTTP/1.0"}

到此這篇關(guān)于golang使用mTLS實(shí)現(xiàn)雙向加密認(rèn)證http通信的文章就介紹到這了,更多相關(guān)golang mTLS雙向加密認(rèn)證通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang反射機(jī)制的用法詳解

    golang反射機(jī)制的用法詳解

    Golang 作為靜態(tài)類型的編譯型語言,雖然在設(shè)計(jì)上傾向于簡(jiǎn)潔和高效,但也內(nèi)置了強(qiáng)大的反射機(jī)制,本文將深入講解 Golang 的反射機(jī)制,幫助大家更好地理解和運(yùn)用這一強(qiáng)大的特性,需要的朋友可以參考下
    2023-12-12
  • Golang反射獲取結(jié)構(gòu)體的值和修改值的代碼示例

    Golang反射獲取結(jié)構(gòu)體的值和修改值的代碼示例

    這篇文章主要給大家介紹了golang反射獲取結(jié)構(gòu)體的值和修改值的代碼示例及演示效果,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,感興趣的同學(xué)可以參考閱讀本文
    2023-08-08
  • go-cache的基本使用場(chǎng)景示例解析

    go-cache的基本使用場(chǎng)景示例解析

    這篇文章主要為大家介紹了go-cache的基本使用場(chǎng)景示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • golang三元表達(dá)式的使用方法

    golang三元表達(dá)式的使用方法

    這篇文章主要介紹了golang三元表達(dá)式的使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • go語言使用中提示%!(NOVERB)的解決方案

    go語言使用中提示%!(NOVERB)的解決方案

    o語言的設(shè)計(jì)目標(biāo)是提供一種簡(jiǎn)單易用的編程語言,同時(shí)保持高效性和可擴(kuò)展性,它支持垃圾回收機(jī)制,具有強(qiáng)大的并發(fā)編程能力,可以輕松處理大規(guī)模的并發(fā)任務(wù),Go語言還擁有豐富的標(biāo)準(zhǔn)庫(kù)和活躍的開發(fā)社區(qū),使得開發(fā)者能夠快速構(gòu)建出高質(zhì)量的應(yīng)用程序,需要的朋友可以參考下
    2023-10-10
  • Golang與其他語言不同的九個(gè)特性

    Golang與其他語言不同的九個(gè)特性

    近來關(guān)于對(duì)Golang的討論有很多,七牛的幾個(gè)大牛們也斷定Go語言在未來將會(huì)快速發(fā)展,并且很可能會(huì)取代Java成為互聯(lián)網(wǎng)時(shí)代最受歡迎的編程語言。本文將帶你了解它不同于其他語言的九個(gè)特性
    2021-09-09
  • go責(zé)任鏈行為型設(shè)計(jì)模式Chain?Of?Responsibility

    go責(zé)任鏈行為型設(shè)計(jì)模式Chain?Of?Responsibility

    這篇文章主要為大家介紹了go行為型設(shè)計(jì)模式之責(zé)任鏈Chain?Of?Responsibility使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 淺談Go語言中的結(jié)構(gòu)體struct & 接口Interface & 反射

    淺談Go語言中的結(jié)構(gòu)體struct & 接口Interface & 反射

    下面小編就為大家?guī)硪黄獪\談Go語言中的結(jié)構(gòu)體struct & 接口Interface & 反射。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • 淺析Go語言中的逃逸分析

    淺析Go語言中的逃逸分析

    逃逸分析算是go語言的特色之一,所以這篇文章小編就來和大家聊聊為什么不應(yīng)該過度關(guān)注go語言的逃逸分析,感興趣的小伙伴可以跟隨小編一起了解一下
    2024-10-10
  • golang?gorm的Callbacks事務(wù)回滾對(duì)象操作示例

    golang?gorm的Callbacks事務(wù)回滾對(duì)象操作示例

    這篇文章主要為大家介紹了golang?gorm的Callbacks事務(wù)回滾對(duì)象操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04

最新評(píng)論