From ec3eb5c5669e579425b2e5c07e28f9171bcbc064 Mon Sep 17 00:00:00 2001 From: Ryan Leung Date: Tue, 17 Mar 2020 17:13:14 +0800 Subject: [PATCH] server: support tls for the status server (#5393) Signed-off-by: Ryan Leung --- Cargo.lock | 66 ++++++++++++++ Cargo.toml | 5 ++ cmd/src/server.rs | 5 +- components/test_util/data/ca.crt | 20 ----- components/test_util/data/ca.pem | 22 +++++ components/test_util/data/key.pem | 27 ++++++ components/test_util/data/server.crt | 19 ---- components/test_util/data/server.pem | 49 +++++------ components/test_util/src/security.rs | 8 +- src/server/errors.rs | 7 ++ src/server/status_server.rs | 127 +++++++++++++++++++++++---- 11 files changed, 266 insertions(+), 89 deletions(-) delete mode 100644 components/test_util/data/ca.crt create mode 100644 components/test_util/data/ca.pem create mode 100644 components/test_util/data/key.pem delete mode 100644 components/test_util/data/server.crt diff --git a/Cargo.lock b/Cargo.lock index 29bd5535f65..4b97a02a81c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,6 +45,12 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "antidote" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" + [[package]] name = "anyhow" version = "1.0.26" @@ -1664,6 +1670,24 @@ dependencies = [ "want 0.3.0", ] +[[package]] +name = "hyper-openssl" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52657b5cdb2a8067efd29a02e011b7cf656b473ec8a5c34e86645e85d763006" +dependencies = [ + "antidote", + "bytes 0.4.12", + "futures 0.1.29", + "hyper 0.12.35", + "lazy_static", + "linked_hash_set", + "openssl", + "openssl-sys", + "tokio-io", + "tokio-openssl 0.3.0", +] + [[package]] name = "hyper-tls" version = "0.3.2" @@ -1963,6 +1987,21 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" + +[[package]] +name = "linked_hash_set" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "lock_api" version = "0.1.5" @@ -4233,6 +4272,7 @@ dependencies = [ "grpcio", "hex 0.3.2", "hyper 0.12.35", + "hyper-openssl", "into_other", "itertools", "keys", @@ -4245,6 +4285,7 @@ dependencies = [ "more-asserts", "murmur3", "nom 5.1.0", + "openssl", "panic_hook", "parking_lot 0.10.0", "pd_client", @@ -4271,6 +4312,7 @@ dependencies = [ "sysinfo", "tempfile", "test_sst_importer", + "test_util", "tidb_query", "tikv_alloc", "tikv_util", @@ -4280,7 +4322,9 @@ dependencies = [ "tokio-core", "tokio-fs", "tokio-io", + "tokio-openssl 0.2.1", "tokio-sync", + "tokio-tcp", "tokio-threadpool", "tokio-timer", "toml", @@ -4537,6 +4581,28 @@ dependencies = [ "syn 1.0.5", ] +[[package]] +name = "tokio-openssl" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4646ae1fd623393de3d796ea53af75acd02938dd5579544fbd6d236d041978a6" +dependencies = [ + "futures 0.1.29", + "openssl", + "tokio-io", +] + +[[package]] +name = "tokio-openssl" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771d6246b170ae108d67d9963c23f31a579016c016d73bd4bd7d6ef0252afda7" +dependencies = [ + "futures 0.1.29", + "openssl", + "tokio-io", +] + [[package]] name = "tokio-process" version = "0.2.4" diff --git a/Cargo.toml b/Cargo.toml index 1d4930977f0..f1ae09ebaa7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,8 @@ futures-util = { version = "0.3.1", default-features = false, features = ["io", grpcio = { version = "0.5", default-features = false, features = ["openssl-vendored"] } hex = "0.3" itertools = "0.8" +openssl = "0.10" +tokio-openssl = "0.2" hyper = { version = "0.12", default-features = false, features = ["runtime"] } keys = { path = "components/keys" } kvproto = { git = "https://github.com/pingcap/kvproto.git", default-features = false } @@ -120,6 +122,7 @@ tikv_util = { path = "components/tikv_util" } time = "0.1" tipb = { git = "https://github.com/pingcap/tipb.git", default-features = false } tokio = { version = "0.2", features = ["sync"] } +tokio-tcp = "0.1" tokio-core = "0.1" tokio-fs = "0.1.6" tokio-io = "0.1.12" @@ -144,8 +147,10 @@ git = "https://github.com/tikv/yatp.git" [dev-dependencies] panic_hook = { path = "components/panic_hook" } test_sst_importer = { path = "components/test_sst_importer" } +test_util = { path = "components/test_util" } tokio = { version = "0.2", features = ["macros", "rt-threaded", "time"] } zipf = "5.0.1" +hyper-openssl = "0.7" [patch.crates-io] # TODO: remove this when new raft-rs is published. diff --git a/cmd/src/server.rs b/cmd/src/server.rs index 24f7f039b46..a8fb048b841 100644 --- a/cmd/src/server.rs +++ b/cmd/src/server.rs @@ -755,7 +755,10 @@ impl TiKVServer { server.pd_sender.clone(), )); // Start the status server. - if let Err(e) = status_server.start(self.config.server.status_addr.clone()) { + if let Err(e) = status_server.start( + self.config.server.status_addr.clone(), + &self.config.security, + ) { error!( "failed to bind addr for status service"; "err" => %e diff --git a/components/test_util/data/ca.crt b/components/test_util/data/ca.crt deleted file mode 100644 index fb59b8af545..00000000000 --- a/components/test_util/data/ca.crt +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDWTCCAkGgAwIBAgIJAIIbhWlMUnaXMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNV -BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg -Q29tcGFueSBMdGQwIBcNMTcxMTI0MjAzNjE3WhgPMjExNzEwMzEyMDM2MTdaMEIx -CzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl -ZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQC2KD3v7ewrvsJ2ZluJe7I5sPJG3abd1FZ1FyYc1NAP+FWwbOlNbBYNrMxOW2uK -Dcj3Hsdsiqhw7AfpjgP1qRVGifXSP8s3drFWRfsXRzBRlN0qtxfpvUMBGiypBpYq -RSOSbr0JUZ/NN3rqxTtiFvylVFnErfAoSf5XNeb/gYlOQgmK39qzvgF0ChdXQUib -94XP88FtgmIm+gZBCo8B7fTsAeb3jQfQ40nWYiJ+7NForHcI3gAUulm5gAV5wIwM -5OySf8GGiYJCE0efoKmxkFtC7WCqLMFYdyKfqWuXKKo9cWub/TRKVaA3pkPjAE1b -8kPCDhKBdNk90bQQBIRQMBLRAgMBAAGjUDBOMB0GA1UdDgQWBBQpW0hjwq0KAxLJ -HoDNR4A9V2tz3DAfBgNVHSMEGDAWgBQpW0hjwq0KAxLJHoDNR4A9V2tz3DAMBgNV -HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB1RJVs9CWZVZz0Z/fguQR8xcu3 -zjjgE2EPC2l/zKIp92MyCI4NEtt4tNe01e+IqTONYB/6AGIy4QbhDbsWNzkZjlkk -KxoRJ+wp8eVjnBPhvNNCLdxdc+eguoBAlFA7TfXcdGbTRe3QaR8BolTnvEbPzlEc -GOdIdSwnI4Mh+1x+e3GVxvY3C6AqQip10Ewxv2ypzhgkqEjrjr1UNrM+txgMA3YB -IMi+iBY2yxqlUMsNQYxcepAayaFVpMDH2ruXKIfUxX2xSOw49p1g+eisXWpvhqnC -txeTqia2xlYge6/NsMusZDyKZxjRWj5z9Oc5t9BitiV9k80CjQ7nn0IIA4p0 ------END CERTIFICATE----- diff --git a/components/test_util/data/ca.pem b/components/test_util/data/ca.pem new file mode 100644 index 00000000000..e130a8eece9 --- /dev/null +++ b/components/test_util/data/ca.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIUdZFW8VQoZZzek8cA+5GGu6ZInjowDQYJKoZIhvcNAQEL +BQAwVzELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0Jl +aWppbmcxEDAOBgNVBAoTB1BpbmdDQVAxEjAQBgNVBAMTCU15IG93biBDQTAeFw0x +OTA5MDIwNjEyMDBaFw0yNDA4MzEwNjEyMDBaMFcxCzAJBgNVBAYTAkNOMRAwDgYD +VQQIEwdCZWlqaW5nMRAwDgYDVQQHEwdCZWlqaW5nMRAwDgYDVQQKEwdQaW5nQ0FQ +MRIwEAYDVQQDEwlNeSBvd24gQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDcDtQ7UX+xlVY0vpklp1uUmPoFsN0U6fqRzHU+LvYS5AM5RPJMVLiKBiSi +zGsB+XPmXZ8H7rZZ+osZsEmDIF3HdyiSNpPNzRJKxsz4KVRzfoKZXL9D41TpuE27 ++7tN6qGytYrnAy8cHMA0S1TnQ0biOFTcXZrwh5lvlIcx7ceUamGuEl94tblxSSJl +2SkpHkKIDv0kcgoGmmh4y8SzAtmnwcCjkCSoITvvwKklp5830pFKOnpN9uZJzkXa +tuUSpSji/JG79nQfH91LtL7xMprORVtg9YAa3aJm0Uf33WFvaCTSrt//7CVK8nqK +xayS3u7dNH3GV9b81OGtlR76leFlAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjAS +BgNVHRMBAf8ECDAGAQH/AgECMB0GA1UdDgQWBBS3hxTaN9B7eF8xr0DKLZ3b5vFn +rDAfBgNVHSMEGDAWgBS3hxTaN9B7eF8xr0DKLZ3b5vFnrDANBgkqhkiG9w0BAQsF +AAOCAQEAi9WiEvTQQjmb7ekXHf1tKwdLNu5akQXIwTKeZSWRSeMgqVQcoyTZMPBX +ythl6K3175RUIMtCwO4uZTOpRU1mTl0pIjoEcJGHYX91zyA5BjWahXZttvt7/hyX +UwJN9clBXLfZTCp1ysLCtarLcip4WxWNsxEwXFUisE2gbu3F9ELHAbRSVUe/CwC6 +8BkY+G+fovazjGoTV4NadJVFRzTR/zsWkBNllBOBTrop8FH23ePVh3hXafzJlcip +bDbRxNqSzNtLr88mwswklgiIHXF6PY2TkyscsXVkHPAswZnrv4lLov7M3VjL8ITA +uYm4Me5Tmj+6pb+Foky15+ehmicQbA== +-----END CERTIFICATE----- diff --git a/components/test_util/data/key.pem b/components/test_util/data/key.pem new file mode 100644 index 00000000000..c7f9fa8c340 --- /dev/null +++ b/components/test_util/data/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAsRpq/E/VC82YxsC5LlKFvI9HJuchMtKskn53anW4rNE3sfN0 +WDS6qCyxNumUVBqO98J18xxbz/XkV7aP6TcXZrNgEqw07PZWTDoyZVi+n9HXyWwl +BeiE2WWrCESqsar+cXV5UE3oE7Y4CT56tMN+awKqnf1zLyRl9DlqSg1/GabheVzz +fGhdqddqdpAZcaOHH8UMEWdnZ4qTFaaGNRlrRy3W0VjzgIocQorpvvtZkQM5iCxx +z9wuF9/6gGdopTA0J2SvZKa+oI/867NLpN5Hx+cn/ThHhCTh1N34Ulloa0aiou72 +mGgyMIdQxYAsRnG62EHn+9aPtegIjQd13Be9/wIDAQABAoIBAHJ8v3iIKxNMP10M +rSlS032HqdluRLnUExdIhe3eWBnvze9NkIKM47Vf3te+u9J6sL1dil40kO2o6YoC +TJnYsVoEzzCC/lvJCxSP8pAthF1QjAx7yps9KtRWsu/PZAEipwW1iUzub/5+J09i +gnRkhE6tFJq5g0KQZxAwJZPlkaqEcZIOObfh9zD9hutvCPmXBtB600EbQU4XzyjP +KaU08LtNZVm4mhKMuhXuFt8LBkjjfuw6zNcjsvgMkyflFTLc/SgWWIpq1ALHQCsq +OiFfTPyuLy+8tGTbawvRIqiHHRd23XttPcfkdfWbNVTSBfodTOhXGFaVYbJ6EVA4 +OzVzftECgYEAz/D99wpWbjU8vye5cjKjZCY/+QnY0t76YsUmfD9+fQNBDSQnKCKj +6nO6oYFQ9RI/vPMfrNX0sqo5hKfufNBCr/MILDXR6vtcEuaqd84DgaPVPRjHef6v +paYUi0Enb3gF3LXYggTN1mz9leEW8BablTN/DLP5AAvMfM/XSkVzlIsCgYEA2gjc +mcUDL1smAvriFVmpD4IrPzaZ9kINOfFNqkp/+y7S0BZGeS5ESSodrs0CIojttp3o +9GL7QLhZ9DehJWfh2qfA5mvzKGzUeM2oapR2Ts/m3voS4ErPTm+cTBOjRe3gGSSN +4sAJ5LA071RfNjEZBSktow//WX/oWrhIyovnxt0CgYBxyge/4xlO77URSdSySEGf +MUs6pYfQRRKxb/9SaJB4KoqzfUAsN2CJkNDlRlWd9mGIrWZ89wwTpREapabdCD4l ++JFVWBJKS0ikUzOfoc3LaHLtHx0xhgxqUkrVtU62MfDLSXt0Etrs5vGRzf32Xfi/ +mdGBiw7MVqiM+FNwojbQZwKBgDly5E1P78rmhVl7qV5exYDkl2iMhnywYrPFtOUN +xDL2320csWz0l+F/S1rngYx/78KSUPMzsWgYKvuCPN+SQ5xNXzJXdzZLlqBN7/ZF +L/cMKJTP53FZxM2x8sjI09h1GPsG+quoVfL/yrLU1FF/FkyZ0QCKEooOfbaJoARe +YK+xAoGAfT0P200WsLKRl73XYJZNYQl5+h5s7Sk9J8QuPwFWqm/mGwYKTLI042jg +lsAym4krAR0c1CHTW3aHRimYpYbi7/kztZU1zUQgcGL+79afer3ZuFF7mGzR+I/r +yOQ2dEfmVASfl/fMh1qyExpcCaMuejaODWyILlxOwvnywHWMSCU= +-----END RSA PRIVATE KEY----- diff --git a/components/test_util/data/server.crt b/components/test_util/data/server.crt deleted file mode 100644 index 65db7945340..00000000000 --- a/components/test_util/data/server.crt +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDGDCCAgACCQC8hUiY0zaHIDANBgkqhkiG9w0BAQsFADBCMQswCQYDVQQGEwJY -WDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBh -bnkgTHRkMCAXDTE3MTEyNDIxMTI0NFoYDzIxMTcxMDMxMjExMjQ0WjBYMQswCQYD -VQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0 -IENvbXBhbnkgTHRkMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBANoua/h0FSBGyq+8B3plgpm5JJm0tDUqIBn/VYGb -sNN90KN4HIKi+jb2Me5yJPuteVJxR1H7UIZ7lhYyyFx07YNFYCIOLhlOoAMOw1Mo -LKUPnJRrg+uu/ek4RdlLgyg81poEc4vMc1ohdy/UYQr+XU/tO2+vtEHSxVLIwyha -rX2fmLhONcFU2aZoMXpmsndQ9M64rAJ9AjKVCmTmNm7aVt/CuqCOZ6tj82UVPBrR -Hwii4CqBTc0f0bRmM9pp5wb7OFrnz0jyC25TagdZNc1yWM6i8ct68YWwFsWlxtoW -GcZMIUkSIPMjB+h5L3oc5t37tq4Fjq2vrEfw9bozGTWVoeECAwEAATANBgkqhkiG -9w0BAQsFAAOCAQEAV+g/54X2q+oy2PFNjIhplg7cY7vcR12lfv6Qyfn19Mgq7r+S -+gjT4LHv8cPNIrNSWGtLqZtqaTrOJk/0E7OybLs6tkX1OL9A43z8tKFlOrGl4V9s -ZP/mbMoXeZtOlqTLOeHUscg+PEGDwL4BXi5U1WxUU0Doh1XoO0D1pXLQCm3AP9o2 -s3nLyCExwykPouz7DFgvov4WDFiYquwMzxjEGgjoKV5aqupjWt18UgLTJiip7WSs -fkD9JnVUvJ5kFzoY0CIMeHw/l7EX/4yMveAMiRj7vnODhwh64GRtcbdHiKcPRBLZ -PvdqgIpsxFLK9UhvE2KI+rudDSfhaARj05Svdg== ------END CERTIFICATE----- diff --git a/components/test_util/data/server.pem b/components/test_util/data/server.pem index 95215237d7d..09200bd82f6 100644 --- a/components/test_util/data/server.pem +++ b/components/test_util/data/server.pem @@ -1,27 +1,22 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEA2i5r+HQVIEbKr7wHemWCmbkkmbS0NSogGf9VgZuw033Qo3gc -gqL6NvYx7nIk+615UnFHUftQhnuWFjLIXHTtg0VgIg4uGU6gAw7DUygspQ+clGuD -66796ThF2UuDKDzWmgRzi8xzWiF3L9RhCv5dT+07b6+0QdLFUsjDKFqtfZ+YuE41 -wVTZpmgxemayd1D0zrisAn0CMpUKZOY2btpW38K6oI5nq2PzZRU8GtEfCKLgKoFN -zR/RtGYz2mnnBvs4WufPSPILblNqB1k1zXJYzqLxy3rxhbAWxaXG2hYZxkwhSRIg -8yMH6Hkvehzm3fu2rgWOra+sR/D1ujMZNZWh4QIDAQABAoIBAEfb/EGzcfXUexNQ -OaJNZqtcuDpLswLDohkN6MqsTZwKlzoP6Ev6g7Cwe5eOTrH527iUiKnuvQHeGHut -NCKHfGa85cGxq+s34ym+pgRweevPbYHQu31XgFdc6lx8K3GIQCIwDyJfLyrjVM8T -AvdM+czGVMofM55uXgE7EFPtMbDq0JKHj/A0uAd8+3WKTWebshVxi2h7ejGQK5fO -xi3WzeeAYu65lX7rrqDT9bFZFXuyxd5mhZFJYxG9KxYgI3rRhYLuLDMZHLT0N0wn -M2mcf4lRgoXQr+stzyT5P43fu1QM+FaNZ8uhBUGJm6nRi3cw8QIqWfTzvb22PLvk -NPhznLECgYEA/sbfqqAfm7GH8WGWfAKJLTd4tdoAHn17udTAZWn5Kegy0q+81YMj -BIiETrnpGQRxIZnCJw+aHU/lic5dbkD0ZwvDR5+CNzQjxs4y/hTpjNEsaCKyArSm -jWvuy6mYWcwM1Lp5yuUpL7VQk9x7maXD+7a97xYL2/9t3/CyYS/+zqUCgYEA2zqS -Rbor7dbVkKgDzgRtt8GGC2k+yz1U1rBnHke/OSfUSUBbrdUr7ybsAa3qon02LGA7 -+qidDY4j+s+PQfTr4SMTCOXlV1DpMpJd5+qh5yPXe+XThu+FWh1CXdcWI0XT+/9B -0AwLgWzAuRU/m1JIBhMZakEBasRzQiqB1deWvY0CgYBmM/0xgz5qxJLWH+GwKYxB -2UjRGnyFvqzNZS0xAYv0ZbNNlTXZKNv5S5JXynhZktCXPAkIhle6fnyEBYaxXdkt -JSjXKIOiBYZ8j+cgyd7OoHKB67khILrXbH7EsGnvS82x4IRPAhK9kqyaRA5JGpg9 -95bFvEBRpmu7M+E633gGCQKBgQCSjYYpDLq/JUXhjR/2AinilIFqcXHj5d0oJAbb -TDU+HS0hxt9CxuW22vscaEoZU8D6S17tQviyjhnpWgW3nuZsu8jGwwDcrR8niocy -OT0ASoqLrekJJGeuBS9PkjCfZde/dzVkwhiS7cOsNtMtnwS84tmzmT88Q5WVXtsq -vBNuJQKBgQDgf4GyhMwooWWJy7dkgrLdd5/WIrBIgXi3l731GytEDaQZyWGgNpXN -jiW67honEyX/TX59Fw5nU3eFodvjsPZFDHvhFb6QPUikgnY4TEuR03wxiiTzQO5a -zcG3Oyw62OSzUuI7Yu7nDkV5Pr1BYvHoL3mM7NqqrQOpD9zMuLv1Gg== ------END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDlTCCAn2gAwIBAgIUGKdjy/Uqp64ZiwqMwpTMGP5tKT0wDQYJKoZIhvcNAQEL +BQAwVzELMAkGA1UEBhMCQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0Jl +aWppbmcxEDAOBgNVBAoTB1BpbmdDQVAxEjAQBgNVBAMTCU15IG93biBDQTAgFw0x +OTA5MDIwNjEzMDBaGA8yMTE5MDgwOTA2MTMwMFowFjEUMBIGA1UEAxMLdGlrdi1z +ZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCxGmr8T9ULzZjG +wLkuUoW8j0cm5yEy0qySfndqdbis0Tex83RYNLqoLLE26ZRUGo73wnXzHFvP9eRX +to/pNxdms2ASrDTs9lZMOjJlWL6f0dfJbCUF6ITZZasIRKqxqv5xdXlQTegTtjgJ +Pnq0w35rAqqd/XMvJGX0OWpKDX8ZpuF5XPN8aF2p12p2kBlxo4cfxQwRZ2dnipMV +poY1GWtHLdbRWPOAihxCium++1mRAzmILHHP3C4X3/qAZ2ilMDQnZK9kpr6gj/zr +s0uk3kfH5yf9OEeEJOHU3fhSWWhrRqKi7vaYaDIwh1DFgCxGcbrYQef71o+16AiN +B3XcF73/AgMBAAGjgZcwgZQwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsG +AQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTw7yUYqbAv +BJw3zZctLUfUi0vyqzAfBgNVHSMEGDAWgBS3hxTaN9B7eF8xr0DKLZ3b5vFnrDAV +BgNVHREEDjAMhwSsEAUohwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCBljfge2fC +5X+tt1v7AkWoH5xpymEVvuIWWJmT/6FNTn1rdnIaxWCQzJbBCXjZS/75lKnwfrTB +ZK7iMv1GQaBevT/qm+7GcApsr5nFrI/MvzrvY+XRqvU8gsRhUjHYI+JPLGWxhzZD +pQdJTAGvsDLHu1VVdHR2KsE4M8ceGq58f7zPSq/suf+8SYEOFP8zfuXX1HfUrFVe +69ZQw8PZh4EYL0PYtE5BYfe9iJyFNNtZiejiribMQz/NtNkKM3M+Hm40ULGuwHXq +bKDjDq1PvmpVb/kKO/xADTIAbqproXETZ4W2keI3hwm6NxysvEbYV9+puQBXQqwT +KOt9Lo4ofSAF +-----END CERTIFICATE----- diff --git a/components/test_util/src/security.rs b/components/test_util/src/security.rs index 4ed99be48bc..5ff4610d44e 100644 --- a/components/test_util/src/security.rs +++ b/components/test_util/src/security.rs @@ -7,10 +7,10 @@ use tikv_util::security::SecurityConfig; pub fn new_security_cfg() -> SecurityConfig { let p = PathBuf::from(env!("CARGO_MANIFEST_DIR")); SecurityConfig { - ca_path: format!("{}", p.join("data/ca.crt").display()), - cert_path: format!("{}", p.join("data/server.crt").display()), - key_path: format!("{}", p.join("data/server.pem").display()), - override_ssl_target: "example.com".to_owned(), + ca_path: format!("{}", p.join("data/ca.pem").display()), + cert_path: format!("{}", p.join("data/server.pem").display()), + key_path: format!("{}", p.join("data/key.pem").display()), + override_ssl_target: "".to_owned(), cipher_file: "".to_owned(), } } diff --git a/src/server/errors.rs b/src/server/errors.rs index cad95b0148d..2a1a09308f2 100644 --- a/src/server/errors.rs +++ b/src/server/errors.rs @@ -7,6 +7,7 @@ use std::result; use grpcio::Error as GrpcError; use hyper::Error as HttpError; +use openssl::error::ErrorStack as OpenSSLError; use protobuf::ProtobufError; use tokio_sync::oneshot::error::RecvError; @@ -106,6 +107,12 @@ quick_error! { display("{:?}", err) description(err.description()) } + OpenSSL(err: OpenSSLError) { + from() + cause(err) + display("{:?}", err) + description(err.description()) + } } } diff --git a/src/server/status_server.rs b/src/server/status_server.rs index 97ef9142598..b7136821176 100644 --- a/src/server/status_server.rs +++ b/src/server/status_server.rs @@ -1,22 +1,27 @@ // Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0. use futures::future::{err, ok}; +use futures::stream::Stream; use futures::sync::oneshot; -#[cfg(feature = "failpoints")] -use futures::Stream; use futures::{self, Future}; +use hyper::server::Builder as HyperBuilder; use hyper::service::service_fn; use hyper::{self, header, Body, Method, Request, Response, Server, StatusCode}; +use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; use pprof; use pprof::protos::Message; use regex::Regex; -use std::sync::Arc; use tempfile::TempDir; +use tokio_io::{AsyncRead, AsyncWrite}; +use tokio_openssl::SslAcceptorExt; use tokio_sync::oneshot::{Receiver, Sender}; +use tokio_tcp::TcpListener; use tokio_threadpool::{Builder, ThreadPool}; +use std::error::Error as StdError; use std::net::SocketAddr; use std::str::FromStr; +use std::sync::Arc; use super::Result; use crate::config::TiKvConfig; @@ -24,6 +29,7 @@ use raftstore::store::PdTask; use tikv_alloc::error::ProfError; use tikv_util::collections::HashMap; use tikv_util::metrics::dump; +use tikv_util::security::SecurityConfig; use tikv_util::timer::GLOBAL_TIMER_HANDLE; use tikv_util::worker::FutureScheduler; @@ -385,13 +391,13 @@ impl StatusServer { ) } - pub fn start(&mut self, status_addr: String) -> Result<()> { - let addr = SocketAddr::from_str(&status_addr)?; - - // TODO: support TLS for the status server. - let builder = Server::try_bind(&addr)?; + fn start_serve(&mut self, builder: HyperBuilder) + where + I: Stream + Send + 'static, + I::Error: Into>, + I::Item: AsyncRead + AsyncWrite + Send + 'static, + { let pd_sender = self.pd_sender.clone(); - // Start to serve. let server = builder.serve(move || { let pd_sender = pd_sender.clone(); @@ -424,11 +430,48 @@ impl StatusServer { }, ) }); - self.addr = Some(server.local_addr()); + let graceful = server .with_graceful_shutdown(self.rx.take().unwrap()) .map_err(|e| error!("Status server error: {:?}", e)); self.thread_pool.spawn(graceful); + } + + pub fn start(&mut self, status_addr: String, security_config: &SecurityConfig) -> Result<()> { + let addr = SocketAddr::from_str(&status_addr)?; + + let tcp_listener = TcpListener::bind(&addr)?; + self.addr = Some(tcp_listener.local_addr()?); + + if !security_config.cert_path.is_empty() + && !security_config.key_path.is_empty() + && !security_config.ca_path.is_empty() + { + let mut acceptor = SslAcceptor::mozilla_modern(SslMethod::tls())?; + acceptor.set_ca_file(&security_config.ca_path)?; + acceptor.set_certificate_chain_file(&security_config.cert_path)?; + acceptor.set_private_key_file(&security_config.key_path, SslFiletype::PEM)?; + let acceptor = acceptor.build(); + + let tls_stream = tcp_listener + .incoming() + .and_then(move |stream| { + acceptor.accept_async(stream).then(|r| match r { + Ok(stream) => Ok(Some(stream)), + Err(e) => { + error!("failed to accept TLS connection"; "err" => ?e); + Ok(None) + } + }) + }) + .filter_map(|x| x); + let server = Server::builder(tls_stream); + self.start_serve(server); + } else { + let tcp_stream = tcp_listener.incoming(); + let server = Server::builder(tcp_stream); + self.start_serve(server); + } Ok(()) } @@ -526,19 +569,28 @@ fn handle_fail_points_request( #[cfg(test)] mod tests { - use crate::config::TiKvConfig; - use crate::server::status_server::StatusServer; use futures::future::{lazy, Future}; use futures::Stream; + use hyper::client::HttpConnector; use hyper::{Body, Client, Method, Request, StatusCode, Uri}; + use hyper_openssl::HttpsConnector; + use openssl::ssl::{SslConnector, SslMethod}; + use tokio_core::reactor::Handle; + + use std::env; + use std::path::PathBuf; + + use crate::config::TiKvConfig; + use crate::server::status_server::StatusServer; use raftstore::store::PdTask; + use test_util::new_security_cfg; + use tikv_util::security::SecurityConfig; use tikv_util::worker::{dummy_future_scheduler, FutureRunnable, FutureWorker}; - use tokio_core::reactor::Handle; #[test] fn test_status_service() { let mut status_server = StatusServer::new(1, dummy_future_scheduler()); - let _ = status_server.start("127.0.0.1:0".to_string()); + let _ = status_server.start("127.0.0.1:0".to_string(), &SecurityConfig::default()); let client = Client::new(); let uri = Uri::builder() .scheme("http") @@ -561,6 +613,45 @@ mod tests { status_server.stop(); } + #[test] + fn test_security_status_service() { + let mut status_server = StatusServer::new(1, dummy_future_scheduler()); + let _ = status_server.start("127.0.0.1:0".to_string(), &new_security_cfg()); + let p = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + + let mut connector = HttpConnector::new(1); + connector.enforce_http(false); + let mut ssl = SslConnector::builder(SslMethod::tls()).unwrap(); + ssl.set_ca_file(format!( + "{}", + p.join("components/test_util/data/ca.pem").display() + )) + .unwrap(); + + let ssl = HttpsConnector::with_connector(connector, ssl).unwrap(); + let client = Client::builder().build::<_, Body>(ssl); + + let uri = Uri::builder() + .scheme("https") + .authority(status_server.listening_addr().to_string().as_str()) + .path_and_query("/metrics") + .build() + .unwrap(); + + let handle = status_server.thread_pool.spawn_handle(lazy(move || { + client + .get(uri) + .map(|res| { + assert_eq!(res.status(), StatusCode::OK); + }) + .map_err(|err| { + panic!("response status is not OK: {:?}", err); + }) + })); + handle.wait().unwrap(); + status_server.stop(); + } + #[test] fn test_config_endpoint() { struct Runner; @@ -576,7 +667,7 @@ mod tests { worker.start(Runner).unwrap(); let mut status_server = StatusServer::new(1, worker.scheduler()); - let _ = status_server.start("127.0.0.1:0".to_string()); + let _ = status_server.start("127.0.0.1:0".to_string(), &SecurityConfig::default()); let client = Client::new(); let uri = Uri::builder() .scheme("http") @@ -612,7 +703,7 @@ mod tests { fn test_status_service_fail_endpoints() { let _guard = fail::FailScenario::setup(); let mut status_server = StatusServer::new(1, dummy_future_scheduler()); - let _ = status_server.start("127.0.0.1:0".to_string()); + let _ = status_server.start("127.0.0.1:0".to_string(), &SecurityConfig::default()); let client = Client::new(); let addr = status_server.listening_addr().to_string(); @@ -744,7 +835,7 @@ mod tests { fn test_status_service_fail_endpoints_can_trigger_fails() { let _guard = fail::FailScenario::setup(); let mut status_server = StatusServer::new(1, dummy_future_scheduler()); - let _ = status_server.start("127.0.0.1:0".to_string()); + let _ = status_server.start("127.0.0.1:0".to_string(), &SecurityConfig::default()); let client = Client::new(); let addr = status_server.listening_addr().to_string(); @@ -785,7 +876,7 @@ mod tests { fn test_status_service_fail_endpoints_should_give_404_when_failpoints_are_disable() { let _guard = fail::FailScenario::setup(); let mut status_server = StatusServer::new(1, dummy_future_scheduler()); - let _ = status_server.start("127.0.0.1:0".to_string()); + let _ = status_server.start("127.0.0.1:0".to_string(), &SecurityConfig::default()); let client = Client::new(); let addr = status_server.listening_addr().to_string();