-
Notifications
You must be signed in to change notification settings - Fork 524
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
Use libbeat LoadCertificate function on server side #235
Use libbeat LoadCertificate function on server side #235
Conversation
Can one of the admins verify this patch? |
@ruflin @jalvz Here is the change to use the libbeat There is no test for a private key with a pass_phrase. To allow that we should think to reuse the following function with little modification to decrypt the pem block: https://github.com/elastic/beats/blob/d15cab2b3ec265a7f8bf3514c0e4fbc01c498a40/libbeat/outputs/transport/transptest/testing.go#L180 Do I make the modification on beats repository or I copy the function inside our repository and apply the modification ? |
As the functionality is inherited from beats now, it should be up to beats to make sure it works as expected. Or is the usage / implementation different here? |
@ruflin , |
PR open on beats repository --> elastic/beats#5431 When the PR will be merged, I'll can add more tests on the |
Gentlemen, I've use the beats modification that I've made to create testing certificate. I've also added a new unit test to test the server in https mode with a encrypted certificate key. |
Great @sterchelen ! Ill have a look soon. In the meanwhile, can you rebase master and fix conflicts? |
@jalvz I've already merged master on it :) |
_meta/beat.reference.yml
Outdated
@@ -20,7 +20,8 @@ apm-server: | |||
#ssl.enabled: false | |||
#ssl.certificate : "path/to/cert" | |||
#ssl.key : "path/to/private_key" | |||
|
|||
#ssl.pass_phrase: "foobar" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct attribute here is ssl.key_passphrase
@@ -13,7 +13,10 @@ import ( | |||
"testing" | |||
"time" | |||
|
|||
"github.com/kabukky/httpscerts" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this dependency is not used anymore, should be removed then (also remember to run make notice
after removing it to remove its entry from the NOTICE file as well)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jalvz This dependency is already removed. You are looking in the wrong side of the diff :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I meant the actual content from the dependency, not the import.
https://github.com/elastic/apm-server/blob/master/vendor/vendor.json#L1163-L1168 , https://github.com/elastic/apm-server/tree/master/vendor/github.com/kabukky/httpscerts and https://github.com/elastic/apm-server/blob/master/NOTICE.txt#L817-L848
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't look like this has been addressed yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved !
@@ -160,16 +163,29 @@ func TestServerNoContentType(t *testing.T) { | |||
assert.Equal(t, http.StatusBadRequest, rr.Code, rr.Body.String()) | |||
} | |||
|
|||
func TestServerSecureOkWithPasswordKey(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good!
I miss 1 more test that "breaks" if the passphrase generated and the one passed in the server config do not match.
Note: in that scenario the server won't be able to start, so you need to assert that a timeout happens instead, the one in waitForServer
. That is hardcoded to 10 seconds, so you will also need to modify that function to accept a timeout
param and pass a lower value for that test because 10 secs every time it runs would be very slow.
Does this makes sense to you?
logp.Info("Loading private key: %s", config.SSL.Certificate.Key) | ||
cert, err := outputs.LoadCertificate(&config.SSL.Certificate) | ||
if err != nil { | ||
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code path should also be tested, I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jalvz While I'm writing a test for this path, I saw that we are completely hiding error from the setupServer
function (server_test
file). Particularly on the go run
statement.
If we check the error while running the server, we could remove all the checkErrMsg
tests.
For instance, the TestServerSecureBadDomain
test, would only have to check if an error has occured with the following msg : http: TLS handshake error from 127.0.0.1:60368: remote error: tls: bad certificate
.
Again, for the TestServerBadProtocol
test, we would only have to check for an error like http: TLS handshake error from 127.0.0.1:60386: tls: oversized record received with length 21536
which tells us that we are trying to reach the https server with the http protocol.
Do you agree ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sterchelen that sounds good to me, but how do check the error while running the server?
Great work @sterchelen ! I think this is very very close :) |
Rev: 5c51448f5fc0c9f458273c452e0ce855fc749a1f
- Inject certificate in the http.Server - Change tests to use the output.CertificateConfig
- Vendoring transptest package from beats repository - Use GenCertForTestingPurpose function to generate testing certificates
@jalvz sorry for the delay ... So much professional work :) |
_meta/beat.reference.yml
Outdated
@@ -20,7 +20,7 @@ apm-server: | |||
#ssl.enabled: false | |||
#ssl.certificate : "path/to/cert" | |||
#ssl.key : "path/to/private_key" | |||
|
|||
#ssl.key_passphrase: "foobar" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's make this an empty string to match other elastic pkgs
apm-server.reference.yml
Outdated
@@ -20,7 +20,7 @@ apm-server: | |||
#ssl.enabled: false | |||
#ssl.certificate : "path/to/cert" | |||
#ssl.key : "path/to/private_key" | |||
|
|||
#ssl.key_passphrase: "foobar" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's make this an empty string to match other elastic pkgs
beater/client.go
Outdated
secureInfo := "" | ||
if secure { | ||
secureInfo = " (secure mode activated)" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
building secureInfo
can be done outside the for loop. Also good with removing it altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with building it outside the for loop. Not agree with removing it. IMO, logged that the server is in secure mode is relatively important to know ?
beater/server.go
Outdated
"net/http" | ||
"time" | ||
|
||
"github.com/elastic/apm-server/version" | ||
"github.com/elastic/beats/libbeat/outputs" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra newline here
@@ -274,7 +301,7 @@ func randomAddr() string { | |||
return l.Addr().String() | |||
} | |||
|
|||
func waitForServer(secure bool, host string) { | |||
func waitForServer(secure bool, host string, timeout int) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would prefer a context to timeout here but we can add that later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean the name of the variable is not intelligible ?
if check() == http.StatusOK { | ||
return | ||
} | ||
time.Sleep(time.Second * 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How long does this normally take? I expect we can bring this way down.
beater/server_test.go
Outdated
// if check() == http.StatusOK { | ||
// return | ||
// } | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove commented out code
beater/server_test.go
Outdated
|
||
return &SSLConfig{Cert: cert, PrivateKey: key} | ||
return &SSLConfig{Enabled: newTrue(), Certificate: outputs.CertificateConfig{Certificate: name + ".pem", Key: name + ".key", Passphrase: passwordKey}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is the only usage of newTrue()
, a local truthy
var like elsewhere would be preferred.
@@ -13,7 +13,10 @@ import ( | |||
"testing" | |||
"time" | |||
|
|||
"github.com/kabukky/httpscerts" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't look like this has been addressed yet.
@graphaelli Does the PR seems good to you ? |
@graphaelli @ruflin Any news ? |
Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually? |
Hi @sterchelen we would like to have this changes in, but this got a bit old now and needs to rebase master. |
Hi !
I will update the PR by the end of the week !
Sounds correct to you ?
… On 8 May 2018, at 17:23, Juan Álvarez ***@***.***> wrote:
Hi @sterchelen we would like to have this changes in, but this got a bit old now and needs to rebase master.
Do you think you will have time to have a look or should I cherry-pick your work and take it from there?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Sounds fantastic! 👍 |
@jalvz I will start fresh from master ! It tried to rebase master on the branch but it's too old... I don't want to add wrong code. |
Hi @sterchelen, I want to make sure you still have time for this. If not it is ok, I appreciate a lot the work you have done so far! |
Hi Juan ! Sorry for the delay ! Unfortunately I can't update the PR right
now ! May be this week end but not sure !
Cordialement,
Sterchele Nicolas.
2018-06-07 9:23 GMT+02:00 Juan Álvarez <notifications@github.com>:
… Hi @sterchelen <https://github.com/sterchelen>, I want to make sure you
still have time for this. If not it is ok, I appreciate a lot the work you
have done so far!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#235 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AQfcaYoVy7SVPz2UQHelcYZvrSOKkRc9ks5t6NT-gaJpZM4P4bN3>
.
|
Took this over to #1010 |
To add the encrypted private key loading feature, I've :
vendor/github.com/elastic/beats/libbeat/outputs
package which put in public mode theLoadCertificate
function.LoadCertificate
function and inject the certificate in thehttp.Server
.