Can I have insecure GET HTTP requests whilst having MTLS securing all other HTTP requests?

huangapple go评论88阅读模式
英文:

Can I have insecure GET HTTP requests whilst having MTLS securing all other HTTP requests?

问题

我有一个用golang编写的HTTP REST服务,用于演示我正在尝试的内容。

我希望GET请求是不安全的,而其他所有的REST请求都是使用MTLS进行安全传输。
我的实现已经使用了gin web服务器库,所以如果可能的话,我希望继续使用它。

我的问题是,我只能将tlsConfig应用于两个路由组中的所有路由,或者都不应用。我一直无法找到一种在路由组级别应用它的方法。

package main

import (
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"

	"log"

	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()

	// 用于GET请求的不受保护的公共路由
	public := router.Group("/")

	// 使用MTLS的私有路由
	private := router.Group("/")

	public.GET("/insecure-ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "insecure pong",
		})
	})

	private.POST("/secure-ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "secure pong",
		})
	})

	// 获取SystemCertPool,在错误时继续使用空池
	rootCAs, err := x509.SystemCertPool()
	if err != nil {
		log.Fatal(err)
	}
	if rootCAs == nil {
		rootCAs = x509.NewCertPool()
	}

	// 创建一个CA证书池,并将cacert.pem添加到其中
	caCert, err := ioutil.ReadFile("cacert.pem")
	if err != nil {
		log.Fatal(err)
	}

	if ok := rootCAs.AppendCertsFromPEM(caCert); !ok {
		err := errors.New("failed to append CA cert to local system certificate pool")
		log.Fatal(err)
	}

	server := http.Server{
		Addr:    fmt.Sprintf(":%v", 8080),
		Handler: router,
	}

	server.TLSConfig = &tls.Config{
		RootCAs: rootCAs,
	}

	err = server.ListenAndServeTLS("certificate.crt", "privateKey.key")
	if err != nil {
		log.Fatal(err)
	}
}

英文:

I have a HTTP REST service written in golang demonstrating what I'm attempting.

I want GET requests insecure and all other REST requests secured with MTLS.
My implementation already uses the gin web server library so I'd like to stick with that if possible.

My issue is that I have only been able to apply the tlsConfig to both groups or neither. I've been unable to find a way to apply this at the group level.

package main
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io/ioutil"
"net/http"
"log"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// Unprotected public router for GET requests
public := router.Group("/")
// Private router with MTLS
private := router.Group("/")
public.GET("/insecure-ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "insecure pong",
})
})
private.POST("/secure-ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "secure pong",
})
})
// Get the SystemCertPool, continue with an empty pool on error
rootCAs, err := x509.SystemCertPool()
if err != nil {
log.Fatal(err)
}
if rootCAs == nil {
rootCAs = x509.NewCertPool()
}
// Create a CA certificate pool and add cacert.pem to it
caCert, err := ioutil.ReadFile("cacert.pem")
if err != nil {
log.Fatal(err)
}
if ok := rootCAs.AppendCertsFromPEM(caCert); !ok {
err := errors.New("failed to append CA cert to local system certificate pool")
log.Fatal(err)
}
server := http.Server{
Addr:    fmt.Sprintf(":%v", 8080),
Handler: router,
}
server.TLSConfig = &tls.Config{
RootCAs: rootCAs,
}
err = server.ListenAndServeTLS("certificate.crt", "privateKey.key")
if err != nil {
log.Fatal(err)
}
}

答案1

得分: 0

只需创建两个Server实例并同时运行它们,一个使用ListenAndServe,另一个使用ListenAndServeTLS,并配置相同的路由。因为HTTP和HTTPS在不同的端口上运行,所以它们必须有不同的监听器,但是两个监听器可以使用相同的(或不同的)处理程序。例如:

publicRouter := gin.Default()

// 用于GET请求的未受保护的公共路由
public := publicRouter.Group("/")

public.GET("/insecure-ping", func(c *gin.Context) {
    c.JSON(200, gin.H{
        "message": "insecure pong",
    })
})

server := http.Server{
    Addr:    fmt.Sprintf(":%v", 8081), // 或其他端口
    Handler: publicRouter,
}

go func() {
    err = tlsServer.ListenAndServe()
    if err != nil {
        log.Fatal(err)
    }
}()

// 带有MTLS的私有路由
router := gin.Default()
private := router.Group("/")

private.POST("/secure-ping", func(c *gin.Context) {
    c.JSON(200, gin.H{
        "message": "secure pong",
    })
})

// 获取SystemCertPool,在错误时继续使用空池
rootCAs, err := x509.SystemCertPool()
if err != nil {
    log.Fatal(err)
}
if rootCAs == nil {
    rootCAs = x509.NewCertPool()
}

// 创建CA证书池并将cacert.pem添加到其中
caCert, err := ioutil.ReadFile("cacert.pem")
if err != nil {
    log.Fatal(err)
}

if ok := rootCAs.AppendCertsFromPEM(caCert); !ok {
    err := errors.New("failed to append CA cert to local system certificate pool")
    log.Fatal(err)
}

tlsServer := http.Server{
    Addr:    fmt.Sprintf(":%v", 8080),
    Handler: router,
}

tlsServer.TLSConfig = &tls.Config{
    RootCAs: rootCAs,
}

err = tlsServer.ListenAndServeTLS("certificate.crt", "privateKey.key")
if err != nil {
    log.Fatal(err)
}
英文:

Just create two Server instances and run them both, one with ListenAndServe and one with ListenAndServeTLS, configured with the same routes. Because HTTP and HTTPS operate on different ports, they have to have different listeners, but both listeners can use the same (or different) handlers. For example:

publicRouter := gin.Default()
// Unprotected public router for GET requests
public := publicRouter.Group("/")
public.GET("/insecure-ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "insecure pong",
})
})
server := http.Server{
Addr:    fmt.Sprintf(":%v", 8081), // Or whatever
Handler: publicRouter,
}
go func() {
err = tlsServer.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}()
// Private router with MTLS
router := gin.Default()
private := router.Group("/")
private.POST("/secure-ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "secure pong",
})
})
// Get the SystemCertPool, continue with an empty pool on error
rootCAs, err := x509.SystemCertPool()
if err != nil {
log.Fatal(err)
}
if rootCAs == nil {
rootCAs = x509.NewCertPool()
}
// Create a CA certificate pool and add cacert.pem to it
caCert, err := ioutil.ReadFile("cacert.pem")
if err != nil {
log.Fatal(err)
}
if ok := rootCAs.AppendCertsFromPEM(caCert); !ok {
err := errors.New("failed to append CA cert to local system certificate pool")
log.Fatal(err)
}
tlsServer := http.Server{
Addr:    fmt.Sprintf(":%v", 8080),
Handler: router,
}
tlsServer.TLSConfig = &tls.Config{
RootCAs: rootCAs,
}
err = tlsServer.ListenAndServeTLS("certificate.crt", "privateKey.key")
if err != nil {
log.Fatal(err)
}

huangapple
  • 本文由 发表于 2021年10月8日 03:53:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/69487090.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定