Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support https for both client and server #875

Merged
merged 9 commits into from
Dec 21, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
auto upgrade to HTTPS
  • Loading branch information
samanhappy committed Dec 16, 2022
commit 684383dc664fa77ab1991e56e9b6ed2c3e319625
54 changes: 34 additions & 20 deletions cmd/client/command/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"
"io"
"net/http"
"strings"

"github.com/megaease/easegress/pkg/util/codectool"
"github.com/spf13/cobra"
Expand All @@ -32,7 +33,7 @@ type (
// GlobalFlags is the global flags for the whole client.
GlobalFlags struct {
Server string
SSL bool
ForceTLS bool
InsecureSkipVerify bool
OutputFormat string
}
Expand Down Expand Up @@ -115,14 +116,17 @@ const (

// MeshIngressURL is the mesh ingress path.
MeshIngressURL = apiURL + "/mesh/ingresses/%s"

// HTTPProtocal is prefix for HTTP protocal
HTTPProtocal = "http:https://"
// HTTPSProtocal is prefix for HTTPS protocal
HTTPSProtocal = "https://"
)

func makeURL(urlTemplate string, a ...interface{}) string {
var p string
if CommandlineGlobalFlags.SSL {
p = "https://"
} else {
p = "http:https://"
p := HTTPProtocal
if CommandlineGlobalFlags.ForceTLS {
p = HTTPSProtocal
}
return p + CommandlineGlobalFlags.Server + fmt.Sprintf(urlTemplate, a...)
}
Expand All @@ -141,30 +145,22 @@ func handleRequest(httpMethod string, url string, yamlBody []byte, cmd *cobra.Co
}
}

req, err := http.NewRequest(httpMethod, url, bytes.NewReader(jsonBody))
if err != nil {
ExitWithError(err)
}

tr := http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: CommandlineGlobalFlags.InsecureSkipVerify},
}
client := &http.Client{Transport: &tr}
resp, err := client.Do(req)
if err != nil {
ExitWithErrorf("%s failed: %v", cmd.Short, err)
}
defer resp.Body.Close()
resp, body := doRequest(httpMethod, url, jsonBody, client, cmd)

body, err := io.ReadAll(resp.Body)
if err != nil {
ExitWithErrorf("%s failed: %v", cmd.Short, err)
if resp.StatusCode == 400 && strings.Contains(string(body), "Client sent an HTTP request to an HTTPS server") {
fmt.Println("Warning: upgraded to HTTPS, it's better to turn on option --force-tls")
url = strings.ReplaceAll(url, HTTPProtocal, HTTPSProtocal)
resp, body = doRequest(httpMethod, url, jsonBody, client, cmd)
samanhappy marked this conversation as resolved.
Show resolved Hide resolved
}

if !successfulStatusCode(resp.StatusCode) {
msg := string(body)
apiErr := &APIErr{}
err = codectool.Unmarshal(body, apiErr)
err := codectool.Unmarshal(body, apiErr)
if err == nil {
msg = apiErr.Message
}
Expand All @@ -176,6 +172,24 @@ func handleRequest(httpMethod string, url string, yamlBody []byte, cmd *cobra.Co
}
}

func doRequest(httpMethod string, url string, jsonBody []byte, client *http.Client, cmd *cobra.Command) (*http.Response, []byte) {
req, err := http.NewRequest(httpMethod, url, bytes.NewReader(jsonBody))
if err != nil {
ExitWithError(err)
}
resp, err := client.Do(req)
if err != nil {
ExitWithErrorf("%s failed: %v", cmd.Short, err)
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
ExitWithErrorf("%s failed: %v", cmd.Short, err)
}
return resp, body
}

func printBody(body []byte) {
var output []byte
switch CommandlineGlobalFlags.OutputFormat {
Expand Down
4 changes: 2 additions & 2 deletions cmd/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ func main() {

rootCmd.PersistentFlags().StringVar(&command.CommandlineGlobalFlags.Server,
"server", "localhost:2381", "The address of the Easegress endpoint")
rootCmd.PersistentFlags().BoolVar(&command.CommandlineGlobalFlags.SSL,
"ssl", false, "Whether to use secure transport protocal(https)")
rootCmd.PersistentFlags().BoolVar(&command.CommandlineGlobalFlags.ForceTLS,
"force-tls", false, "Whether to forcibly use secure transport protocal(https), if not, client will auto upgraded to HTTPS on-demand")
rootCmd.PersistentFlags().BoolVar(&command.CommandlineGlobalFlags.InsecureSkipVerify,
"insecure-skip-verify", false, "Whether to verify the server's certificate chain and host name")
rootCmd.PersistentFlags().StringVarP(&command.CommandlineGlobalFlags.OutputFormat,
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func MustNewServer(opt *option.Options, cls cluster.Cluster, super *supervisor.S

go func() {
var err error
if s.opt.SSL {
if s.opt.TLS {
logger.Infof("api server (https) running in %s", opt.APIAddr)
err = s.server.ListenAndServeTLS(s.opt.CertFile, s.opt.KeyFile)
} else {
Expand Down
6 changes: 3 additions & 3 deletions pkg/option/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ type Options struct {
Name string `yaml:"name" env:"EG_NAME"`
Labels map[string]string `yaml:"labels" env:"EG_LABELS"`
APIAddr string `yaml:"api-addr"`
SSL bool `yaml:"ssl"`
TLS bool `yaml:"tls"`
CertFile string `yaml:"cert-file"`
KeyFile string `yaml:"key-file"`
Debug bool `yaml:"debug"`
Expand Down Expand Up @@ -141,7 +141,7 @@ func New() *Options {
opt.flags.BoolVar(&opt.UseStandaloneEtcd, "use-standalone-etcd", false, "Use standalone etcd instead of embedded .")
addClusterVars(opt)
opt.flags.StringVar(&opt.APIAddr, "api-addr", "localhost:2381", "Address([host]:port) to listen on for administration traffic.")
opt.flags.BoolVar(&opt.SSL, "ssl", false, "Flag to use secure transport protocol(https).")
opt.flags.BoolVar(&opt.TLS, "tls", false, "Flag to use secure transport protocol(https).")
opt.flags.StringVar(&opt.CertFile, "cert-file", "", "Flag to set the certificate file for https.")
opt.flags.StringVar(&opt.KeyFile, "key-file", "", "Flag to set the private key file for https.")
opt.flags.BoolVar(&opt.Debug, "debug", false, "Flag to set lowest log level from INFO downgrade DEBUG.")
Expand Down Expand Up @@ -347,7 +347,7 @@ func (opt *Options) validate() error {
if !opt.UseInitialCluster() && opt.MemberDir == "" {
return fmt.Errorf("empty member-dir")
}
if opt.SSL && (opt.CertFile == "" || opt.KeyFile == "") {
if opt.TLS && (opt.CertFile == "" || opt.KeyFile == "") {
return fmt.Errorf("empty cert file or key file")
}

Expand Down