소스 검색

Merge pull request #9378 from mattbostock/verify_tls

Bugfix: Always verify TLS unless explicitly told otherwise
Carl Bergquist 8 년 전
부모
커밋
9d53653647

+ 16 - 13
pkg/api/app_routes.go

@@ -11,25 +11,28 @@ import (
 	"github.com/grafana/grafana/pkg/middleware"
 	"github.com/grafana/grafana/pkg/middleware"
 	m "github.com/grafana/grafana/pkg/models"
 	m "github.com/grafana/grafana/pkg/models"
 	"github.com/grafana/grafana/pkg/plugins"
 	"github.com/grafana/grafana/pkg/plugins"
+	"github.com/grafana/grafana/pkg/setting"
 	"github.com/grafana/grafana/pkg/util"
 	"github.com/grafana/grafana/pkg/util"
 	macaron "gopkg.in/macaron.v1"
 	macaron "gopkg.in/macaron.v1"
 )
 )
 
 
-var pluginProxyTransport = &http.Transport{
-	TLSClientConfig: &tls.Config{
-		InsecureSkipVerify: true,
-		Renegotiation:      tls.RenegotiateFreelyAsClient,
-	},
-	Proxy: http.ProxyFromEnvironment,
-	Dial: (&net.Dialer{
-		Timeout:   30 * time.Second,
-		KeepAlive: 30 * time.Second,
-		DualStack: true,
-	}).Dial,
-	TLSHandshakeTimeout: 10 * time.Second,
-}
+var pluginProxyTransport *http.Transport
 
 
 func InitAppPluginRoutes(r *macaron.Macaron) {
 func InitAppPluginRoutes(r *macaron.Macaron) {
+	pluginProxyTransport = &http.Transport{
+		TLSClientConfig: &tls.Config{
+			InsecureSkipVerify: setting.PluginAppsSkipVerifyTLS,
+			Renegotiation:      tls.RenegotiateFreelyAsClient,
+		},
+		Proxy: http.ProxyFromEnvironment,
+		Dial: (&net.Dialer{
+			Timeout:   30 * time.Second,
+			KeepAlive: 30 * time.Second,
+			DualStack: true,
+		}).Dial,
+		TLSHandshakeTimeout: 10 * time.Second,
+	}
+
 	for _, plugin := range plugins.Apps {
 	for _, plugin := range plugins.Apps {
 		for _, route := range plugin.Routes {
 		for _, route := range plugin.Routes {
 			url := util.JoinUrlFragments("/api/plugin-proxy/"+plugin.Id, route.Path)
 			url := util.JoinUrlFragments("/api/plugin-proxy/"+plugin.Id, route.Path)

+ 1 - 3
pkg/api/grafana_com_proxy.go

@@ -1,7 +1,6 @@
 package api
 package api
 
 
 import (
 import (
-	"crypto/tls"
 	"net"
 	"net"
 	"net/http"
 	"net/http"
 	"net/http/httputil"
 	"net/http/httputil"
@@ -14,8 +13,7 @@ import (
 )
 )
 
 
 var grafanaComProxyTransport = &http.Transport{
 var grafanaComProxyTransport = &http.Transport{
-	TLSClientConfig: &tls.Config{InsecureSkipVerify: false},
-	Proxy:           http.ProxyFromEnvironment,
+	Proxy: http.ProxyFromEnvironment,
 	Dial: (&net.Dialer{
 	Dial: (&net.Dialer{
 		Timeout:   30 * time.Second,
 		Timeout:   30 * time.Second,
 		KeepAlive: 30 * time.Second,
 		KeepAlive: 30 * time.Second,

+ 16 - 15
pkg/api/login_oauth.go

@@ -78,16 +78,25 @@ func OAuthLogin(ctx *middleware.Context) {
 	}
 	}
 
 
 	// handle call back
 	// handle call back
+	tr := &http.Transport{
+		TLSClientConfig: &tls.Config{
+			InsecureSkipVerify: setting.OAuthService.OAuthInfos[name].TlsSkipVerify,
+		},
+	}
+	oauthClient := &http.Client{
+		Transport: tr,
+	}
 
 
-	// initialize oauth2 context
-	oauthCtx := oauth2.NoContext
-	if setting.OAuthService.OAuthInfos[name].TlsClientCert != "" {
+	if setting.OAuthService.OAuthInfos[name].TlsClientCert != "" || setting.OAuthService.OAuthInfos[name].TlsClientKey != "" {
 		cert, err := tls.LoadX509KeyPair(setting.OAuthService.OAuthInfos[name].TlsClientCert, setting.OAuthService.OAuthInfos[name].TlsClientKey)
 		cert, err := tls.LoadX509KeyPair(setting.OAuthService.OAuthInfos[name].TlsClientCert, setting.OAuthService.OAuthInfos[name].TlsClientKey)
 		if err != nil {
 		if err != nil {
 			log.Fatal(err)
 			log.Fatal(err)
 		}
 		}
 
 
-		// Load CA cert
+		tr.TLSClientConfig.Certificates = append(tr.TLSClientConfig.Certificates, cert)
+	}
+
+	if setting.OAuthService.OAuthInfos[name].TlsClientCa != "" {
 		caCert, err := ioutil.ReadFile(setting.OAuthService.OAuthInfos[name].TlsClientCa)
 		caCert, err := ioutil.ReadFile(setting.OAuthService.OAuthInfos[name].TlsClientCa)
 		if err != nil {
 		if err != nil {
 			log.Fatal(err)
 			log.Fatal(err)
@@ -95,19 +104,11 @@ func OAuthLogin(ctx *middleware.Context) {
 		caCertPool := x509.NewCertPool()
 		caCertPool := x509.NewCertPool()
 		caCertPool.AppendCertsFromPEM(caCert)
 		caCertPool.AppendCertsFromPEM(caCert)
 
 
-		tr := &http.Transport{
-			TLSClientConfig: &tls.Config{
-				InsecureSkipVerify: true,
-				Certificates:       []tls.Certificate{cert},
-				RootCAs:            caCertPool,
-			},
-		}
-		sslcli := &http.Client{Transport: tr}
-
-		oauthCtx = context.Background()
-		oauthCtx = context.WithValue(oauthCtx, oauth2.HTTPClient, sslcli)
+		tr.TLSClientConfig.RootCAs = caCertPool
 	}
 	}
 
 
+	oauthCtx := context.WithValue(context.Background(), oauth2.HTTPClient, oauthClient)
+
 	// get token from provider
 	// get token from provider
 	token, err := connect.Exchange(oauthCtx, code)
 	token, err := connect.Exchange(oauthCtx, code)
 	if err != nil {
 	if err != nil {

+ 8 - 2
pkg/cmd/grafana-cli/main.go

@@ -17,8 +17,6 @@ var version = "master"
 func main() {
 func main() {
 	setupLogging()
 	setupLogging()
 
 
-	services.Init(version)
-
 	app := cli.NewApp()
 	app := cli.NewApp()
 	app.Name = "Grafana cli"
 	app.Name = "Grafana cli"
 	app.Usage = ""
 	app.Usage = ""
@@ -44,12 +42,20 @@ func main() {
 			Value:  "",
 			Value:  "",
 			EnvVar: "GF_PLUGIN_URL",
 			EnvVar: "GF_PLUGIN_URL",
 		},
 		},
+		cli.BoolFlag{
+			Name:  "insecure",
+			Usage: "Skip TLS verification (insecure)",
+		},
 		cli.BoolFlag{
 		cli.BoolFlag{
 			Name:  "debug, d",
 			Name:  "debug, d",
 			Usage: "enable debug logging",
 			Usage: "enable debug logging",
 		},
 		},
 	}
 	}
 
 
+	app.Before = func(c *cli.Context) error {
+		services.Init(version, c.GlobalBool("insecure"))
+		return nil
+	}
 	app.Commands = commands.Commands
 	app.Commands = commands.Commands
 	app.CommandNotFound = cmdNotFound
 	app.CommandNotFound = cmdNotFound
 
 

+ 4 - 3
pkg/cmd/grafana-cli/services/services.go

@@ -22,7 +22,7 @@ var (
 	grafanaVersion string
 	grafanaVersion string
 )
 )
 
 
-func Init(version string) {
+func Init(version string, skipTLSVerify bool) {
 	grafanaVersion = version
 	grafanaVersion = version
 
 
 	tr := &http.Transport{
 	tr := &http.Transport{
@@ -36,8 +36,9 @@ func Init(version string) {
 		IdleConnTimeout:       90 * time.Second,
 		IdleConnTimeout:       90 * time.Second,
 		TLSHandshakeTimeout:   10 * time.Second,
 		TLSHandshakeTimeout:   10 * time.Second,
 		ExpectContinueTimeout: 1 * time.Second,
 		ExpectContinueTimeout: 1 * time.Second,
-
-		TLSClientConfig: &tls.Config{InsecureSkipVerify: false},
+		TLSClientConfig: &tls.Config{
+			InsecureSkipVerify: skipTLSVerify,
+		},
 	}
 	}
 
 
 	HttpClient = http.Client{
 	HttpClient = http.Client{

+ 6 - 0
pkg/setting/setting.go

@@ -122,6 +122,9 @@ var (
 	// Basic Auth
 	// Basic Auth
 	BasicAuthEnabled bool
 	BasicAuthEnabled bool
 
 
+	// Plugin settings
+	PluginAppsSkipVerifyTLS bool
+
 	// Session settings.
 	// Session settings.
 	SessionOptions session.Options
 	SessionOptions session.Options
 
 
@@ -560,6 +563,9 @@ func NewConfigContext(args *CommandLineArgs) error {
 	authBasic := Cfg.Section("auth.basic")
 	authBasic := Cfg.Section("auth.basic")
 	BasicAuthEnabled = authBasic.Key("enabled").MustBool(true)
 	BasicAuthEnabled = authBasic.Key("enabled").MustBool(true)
 
 
+	// global plugin settings
+	PluginAppsSkipVerifyTLS = Cfg.Section("plugins").Key("app_tls_skip_verify_insecure").MustBool(false)
+
 	// PhantomJS rendering
 	// PhantomJS rendering
 	ImagesDir = filepath.Join(DataPath, "png")
 	ImagesDir = filepath.Join(DataPath, "png")
 	PhantomDir = filepath.Join(HomePath, "vendor/phantomjs")
 	PhantomDir = filepath.Join(HomePath, "vendor/phantomjs")

+ 1 - 0
pkg/setting/setting_oauth.go

@@ -13,6 +13,7 @@ type OAuthInfo struct {
 	TlsClientCert          string
 	TlsClientCert          string
 	TlsClientKey           string
 	TlsClientKey           string
 	TlsClientCa            string
 	TlsClientCa            string
+	TlsSkipVerify          bool
 }
 }
 
 
 type OAuther struct {
 type OAuther struct {

+ 1 - 0
pkg/social/social.go

@@ -66,6 +66,7 @@ func NewOAuthService() {
 			TlsClientCert:  sec.Key("tls_client_cert").String(),
 			TlsClientCert:  sec.Key("tls_client_cert").String(),
 			TlsClientKey:   sec.Key("tls_client_key").String(),
 			TlsClientKey:   sec.Key("tls_client_key").String(),
 			TlsClientCa:    sec.Key("tls_client_ca").String(),
 			TlsClientCa:    sec.Key("tls_client_ca").String(),
+			TlsSkipVerify:  sec.Key("tls_skip_verify_insecure").MustBool(),
 		}
 		}
 
 
 		if !info.Enabled {
 		if !info.Enabled {