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

Native SSL support #226

Closed
wants to merge 1 commit into from
Closed

Conversation

natemueller
Copy link

Add three new flags for atlantis server:

--ssl to enable ssl
--ssl-key-file for the key
--ssl-cert-file for the server and CA certs

If you specify --ssl then all the other two are required.

Currently defaults to non-SSL mode. I think you could make a good
argument for SSL by default but since that would be a breaking change
I left it for the maintainers to decide.

Removed docs for setting up an NGINX frontend.

@CLAassistant
Copy link

CLAassistant commented Jan 3, 2018

CLA assistant check
All committers have signed the CLA.

Copy link
Collaborator

@lkysow lkysow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much @natemueller and sorry it took me so long to get to this.

I facepalmed when I read this because I didn't know it was this easy to set up golang to serve TLS. Should have done this months ago!

A couple comments. Let me know what you think and if you don't have time LMK and I can make the changes myself.

cmd/server.go Outdated
@@ -31,6 +31,9 @@ const (
LogLevelFlag = "log-level"
PortFlag = "port"
RequireApprovalFlag = "require-approval"
SSL = "ssl"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need the SSL flag? Let's just use SSL if any of the other options are specified. I'm just thinking that it's simpler if we eliminate it.

Append Flag to SSLKeyFile and SSLCert to match the rest of the constants above it. The Flag part is so the string isn't confused with the actual contents of the flag.

cmd/server.go Outdated
@@ -31,6 +31,9 @@ const (
LogLevelFlag = "log-level"
PortFlag = "port"
RequireApprovalFlag = "require-approval"
SSL = "ssl"
SSLKeyFile = "ssl-key-file"
SSLCertFile = "ssl-cert-file"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SSLCertFile should be before SSLKeyFile to keep alphabetic ordering

cmd/server.go Outdated
@@ -94,13 +97,26 @@ var stringFlags = []stringFlag{
description: "Log level. Either debug, info, warn, or error.",
value: "info",
},
{
name: SSLKeyFile,
description: "Server key file, required if using SSL",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change this to description: fmt.Sprintf("File containing x509 private key matching --%s.", SSLCertFileFlag)

I'm just following the way the docs are for Kubernete's kubelet which I thought would be good docs to copy from (https://kubernetes.io/docs/reference/generated/kubelet/)

cmd/server.go Outdated
},
{
name: SSLCertFile,
description: "Server and CN cert file, required if using SSL",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again stealing from the kubelet, let's change this to:
description: "File containing x509 Certificate used for serving HTTPS. If the cert is signed by a CA, the file should be the concatenation of the server's certificate, any intermediates, and the CA's certificate."

The last part is from the golang docs on ListenAndServeTLS

cmd/server.go Outdated
@@ -250,6 +266,10 @@ func (s *ServerCmd) validate(config server.Config) error {
}
vcsErr := fmt.Errorf("--%s/--%s or --%s/--%s must be set", GHUserFlag, GHTokenFlag, GitlabUserFlag, GitlabTokenFlag)

if config.SSL && (config.SSLKeyFile == "" || config.SSLCertFile == "") {
return errors.New("ssl-key-file and ssl-cert-file are required for ssl")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the flag constants when printing this error message so if we change the flag name we don't miss changing this error message too

Add two new flags for atlantis server:

  --ssl-key-file for the key
  --ssl-cert-file for the server and CA certs

You either need to use both or neither.  You'll get an error if you
accidentally use only one.

Currently defaults to non-SSL mode.  I think you could make a good
argument for SSL by default but since that would be a breaking change
I left it for the maintainers to decide.

Removed docs for setting up an NGINX frontend.
@natemueller
Copy link
Author

Should all be addressed now. I was torn on the --ssl flag too. I ended up adding it because I felt it was more defensive then an implicit linkage between the separate cert and key flags but I feel strongly about it.

Copy link
Collaborator

@lkysow lkysow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • RE: --ssl option, I hear you. Not sure what the best thing in this case is.
  • We also need to update the tests in cmd/server_test.go. Here's what I came up with
func TestExecute_ValidateSSLConfig(t *testing.T) {
	expErr := "--ssl-key-file and --ssl-cert-file are both required for ssl"
	cases := []struct {
		description string
		flags       map[string]interface{}
		expectError bool
	}{
		{
			"neither option set",
			make(map[string]interface{}),
			false,
		},
		{
			"just ssl-key-file set",
			map[string]interface{}{
				cmd.SSLKeyFileFlag: "file",
			},
			true,
		},
		{
			"just ssl-cert-file set",
			map[string]interface{}{
				cmd.SSLCertFileFlag: "flag",
			},
			true,
		},
		{
			"both flags set",
			map[string]interface{}{
				cmd.SSLCertFileFlag: "cert",
				cmd.SSLKeyFileFlag:  "key",
			},
			false,
		},
	}
	for _, testCase := range cases {
		t.Log("Should validate ssl config when " + testCase.description)
		// Add in required flags.
		testCase.flags[cmd.GHUserFlag] = "user"
		testCase.flags[cmd.GHTokenFlag] = "token"

		c := setup(testCase.flags)
		err := c.Execute()
		if testCase.expectError {
			Assert(t, err != nil, "should be an error")
			Equals(t, expErr, err.Error())
		} else {
			Ok(t, err)
		}
	}
}

@@ -481,7 +481,7 @@ However, if you were to lose the data, all you would need to do is run `atlantis

**Q: How to add SSL to Atlantis server?**

A: Atlantis currently only supports HTTP. In order to add SSL you will need to front Atlantis server with NGINX or HAProxy. Follow the document [here](./docs/nginx-ssl-proxy.md) to use configure NGINX with SSL as a reverse proxy.
A: Pass the `--ssl` option to enable SSL for incoming connections. You will need to get a trusted certificate and pass it into Atlantis server with the `--ssl-key-file` and `--ssl-cert-file` options.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect now after the removal of the ssl flag. Should read

Start atlantis server with the --ssl-cert-file and --ssl-key-file flags.

@@ -248,13 +258,17 @@ func (s *ServerCmd) validate(config server.Config) error {
if logLevel != "debug" && logLevel != "info" && logLevel != "warn" && logLevel != "error" {
return errors.New("invalid log level: not one of debug, info, warn, error")
}
vcsErr := fmt.Errorf("--%s/--%s or --%s/--%s must be set", GHUserFlag, GHTokenFlag, GitlabUserFlag, GitlabTokenFlag)

if (config.SSLKeyFile == "") != (config.SSLCertFile == "") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

took me a bit to grok this but like its simplicity. I think I could probably improve my three if's below using the same pattern.

vcsErr := fmt.Errorf("--%s/--%s or --%s/--%s must be set", GHUserFlag, GHTokenFlag, GitlabUserFlag, GitlabTokenFlag)

if (config.SSLKeyFile == "") != (config.SSLCertFile == "") {
return fmt.Errorf("%s and %s are required for ssl", SSLKeyFileFlag, SSLCertFileFlag)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just missing the -- in front of the %s's so it ends up reading

--ssl-key-file and --ssl-cert-file are both required for ssl

instead of

ssl-key-file and ssl-cert-file are both required for ssl

Let's also add in both required so it's clear that the error is because both aren't specified

@lkysow lkysow mentioned this pull request Jan 23, 2018
@lkysow
Copy link
Collaborator

lkysow commented Jan 23, 2018

Closed by #233 (I just made the changes I stated above)

@lkysow lkysow closed this Jan 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants