Skip to content

Commit

Permalink
Added TLS support for clickhouse and api
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexAkulov committed Dec 15, 2020
1 parent 5ba9988 commit 3a8f061
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 24 deletions.
5 changes: 5 additions & 0 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ clickhouse:
- system.*
timeout: 5m # CLICKHOUSE_TIMEOUT
freeze_by_part: false # CLICKHOUSE_FREEZE_BY_PART
secure: false # CLICKHOUSE_SECURE
skip_verify: false # CLICKHOUSE_SKIP_VERIFY
azblob:
endpoint_suffix: "core.windows.net" # AZBLOB_ENDPOINT_SUFFIX
account_name: "" # AZBLOB_ACCOUNT_NAME
Expand Down Expand Up @@ -159,6 +161,9 @@ api:
enable_pprof: false # API_ENABLE_PPROF
username: "" # API_USERNAME
password: "" # API_PASSWORD
secure: false # API_SECURE
certificate_file: "" # API_CERTIFICATE_FILE
private_key_file: "" # API_PRIVATE_KEY_FILE
ftp:
address: "" # FTP_ADDRESS
timeout: 2m # FTP_TIMEOUT
Expand Down
22 changes: 17 additions & 5 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"crypto/tls"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -110,14 +111,19 @@ type ClickHouseConfig struct {
SkipTables []string `yaml:"skip_tables" envconfig:"CLICKHOUSE_SKIP_TABLES"`
Timeout string `yaml:"timeout" envconfig:"CLICKHOUSE_TIMEOUT"`
FreezeByPart bool `yaml:"freeze_by_part" envconfig:"CLICKHOUSE_FREEZE_BY_PART"`
Secure bool `yaml:"secure" envconfig:"CLICKHOUSE_SECURE"`
SkipVerify bool `yaml:"skip_verify" envconfig:"CLICKHOUSE_SKIP_VERIFY"`
}

type APIConfig struct {
ListenAddr string `yaml:"listen" envconfig:"API_LISTEN"`
EnableMetrics bool `yaml:"enable_metrics" envconfig:"API_ENABLE_METRICS"`
EnablePprof bool `yaml:"enable_pprof" envconfig:"API_ENABLE_PPROF"`
Username string `yaml:"username" envconfig:"API_USERNAME"`
Password string `yaml:"password" envconfig:"API_PASSWORD"`
ListenAddr string `yaml:"listen" envconfig:"API_LISTEN"`
EnableMetrics bool `yaml:"enable_metrics" envconfig:"API_ENABLE_METRICS"`
EnablePprof bool `yaml:"enable_pprof" envconfig:"API_ENABLE_PPROF"`
Username string `yaml:"username" envconfig:"API_USERNAME"`
Password string `yaml:"password" envconfig:"API_PASSWORD"`
Secure bool `yaml:"secure" envconfig:"API_SECURE"`
CertificateFile string `yaml:"certificate_file" envconfig:"API_CERTIFICATE_FILE"`
PrivateKeyFile string `yaml:"private_key_file" envconfig:"API_PRIVATE_KEY_FILE"`
}

// LoadConfig - load config from file
Expand Down Expand Up @@ -167,6 +173,12 @@ func ValidateConfig(cfg *Config) error {
return fmt.Errorf("'%s' is bad S3_STORAGE_CLASS, change one of: %s",
cfg.S3.StorageClass, strings.Join(s3.StorageClass_Values(), ", "))
}
if cfg.API.Secure {
_, err := tls.LoadX509KeyPair(cfg.API.CertificateFile, cfg.API.PrivateKeyFile)
if err != nil {
return err
}
}
return nil
}

Expand Down
5 changes: 4 additions & 1 deletion pkg/clickhouse/clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ func (ch *ClickHouse) Connect() error {
params.Add("database", "system")
params.Add("receive_timeout", timeoutSeconds)
params.Add("send_timeout", timeoutSeconds)

if ch.Config.Secure {
params.Add("secure", "true")
params.Add("skip_verify", strconv.FormatBool(ch.Config.SkipVerify))
}
connectionString := fmt.Sprintf("tcp://%v:%v?%s", ch.Config.Host, ch.Config.Port, params.Encode())
if ch.conn, err = sqlx.Open("clickhouse", connectionString); err != nil {
return err
Expand Down
53 changes: 36 additions & 17 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,32 +105,52 @@ func Server(c *cli.App, cfg *config.Config, configPath string) error {
signal.Notify(sigterm, os.Interrupt, syscall.SIGTERM)
sighup := make(chan os.Signal, 1)
signal.Notify(sighup, os.Interrupt, syscall.SIGHUP)
log.Printf("Starting API server on %s", api.config.API.ListenAddr)
if err := api.Restart(); err != nil {
return err
}

for {
api.server = api.setupAPIServer(api.config)
go func() {
log.Printf("Starting API server on %s", api.config.API.ListenAddr)
if err := api.server.ListenAndServe(); err != http.ErrServerClosed {
log.Printf("error starting API server: %v", err)
os.Exit(1)
}
}()
select {
case <-api.restart:
log.Println("Reloading config and restarting API server")
api.server.Close()
continue
if err := api.Restart(); err != nil {
log.Printf("Failed to restarting API server: %v", err)
continue
}
log.Println("Reloaded by HTTP")
case <-sighup:
log.Println("Reloading config and restarting API server")
api.server.Close()
continue
newCfg, err := config.LoadConfig(configPath)
if err != nil {
log.Printf("Failed to read config: %v", err)
continue
}
api.config = newCfg
if err := api.Restart(); err != nil {
log.Printf("Failed to restarting API server: %v", err)
continue
}
log.Println("Reloaded by SYSHUP")
case <-sigterm:
log.Println("Stopping API server")
return api.server.Close()
}
}
}

func (api *APIServer) Restart() error {
server := api.setupAPIServer(api.config)
if api.server != nil {
api.server.Close()
}
api.server = server
if api.config.API.Secure {
go api.server.ListenAndServeTLS(api.config.API.CertificateFile, api.config.API.PrivateKeyFile)
return nil
}
go api.server.ListenAndServe()
return nil
}

// setupAPIServer - resister API routes
func (api *APIServer) setupAPIServer(cfg *config.Config) *http.Server {
r := mux.NewRouter()
Expand Down Expand Up @@ -172,10 +192,9 @@ func (api *APIServer) setupAPIServer(cfg *config.Config) *http.Server {
})
api.routes = routes
registerMetricsHandlers(r, cfg.API.EnableMetrics, cfg.API.EnablePprof)

srv := &http.Server{
Addr: cfg.API.ListenAddr,
Handler: r,
Addr: cfg.API.ListenAddr,
Handler: r,
}
return srv
}
Expand Down
4 changes: 3 additions & 1 deletion test/integration/config-s3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ general:
remote_storage: s3
clickhouse:
host: localhost
port: 9000
port: 9440
username: backup
password: meow=& 123?*%# МЯУ
secure: true
skip_verify: true
s3:
access_key: access-key
secret_key: it-is-my-super-secret-key
Expand Down
13 changes: 13 additions & 0 deletions test/integration/dhparam.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-----BEGIN DH PARAMETERS-----
MIICCAKCAgEAi9zE9CbGPT/B0wE+eRBgNuIn2sVkkWbEwoqLLh30NbhgIjOwjFb7
ZErTQ2MAgNjAjAfAf2wCMeoWP/s1O9DKF4tPDCcUYXybJ0ZiYp6U2bEysZI0T2r+
1B5XDq6Cwn++JGBsIE3GYspxA8xf6SDawmg5qcXXWXNy12a8pO5AgrPIzZdoRIiX
Wn7BVpJqo+DMNF1HBcFtCG4uPZ1eLrp7dtLBlpT31xz84UWOwX5sixoWatLtQX7f
zynziUKoo3X5Z4AuDZIu2m+OAUA8WOYKv2rYddFbCgATpuFhmXu/c9PPAStrglab
egaHY4xLTjFUSkEkYGNSiKprC79+51YlH9SBpjHCsrr+VaDWKGjEMgtuHHBHTi5k
SaYfMVqrCsnFFkRIpSgLOu5UYAp2B/gIxoXHC3wOkcRQ3MB2RHSi03iAoLhYPuLf
qjVF2TtMVNaA+HNkkJk/zzI9zxh5Sm50Z1XIJkGvEkHue8yy69UQtsnr2YSqQvFc
zk6ygS3vvxfX4SF7Jwaqga8czW+qhxsS+DNKczkf1qK4CkKWiGepfbXd6JLHMaYT
IPbAVtBDWQ+M8eFuMO2U0Me1zX6wbR87Xt0Hu10vOw/d03YpOAOeeXViivyM686l
ah9so85GAnqztdfDBRBp4gvq2rbcUCi6GU6Frzy3vH5g+3z7roOkGLsCAQI=
-----END DH PARAMETERS-----
4 changes: 4 additions & 0 deletions test/integration/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ services:
- ./backup-user.xml:/etc/clickhouse-server/users.d/backup-user.xml
- ${CLICKHOUSE_BACKUP_BIN:-../../clickhouse-backup}:/usr/bin/clickhouse-backup
- ./credentials.json:/etc/clickhouse-backup/credentials.json
- ./server.crt:/etc/clickhouse-server/server.crt
- ./server.key:/etc/clickhouse-server/server.key
- ./dhparam.pem:/etc/clickhouse-server/dhparam.pem
- ./ssl.xml:/etc/clickhouse-server/config.d/ssl.xml
ports:
- 9000:9000
- 7171:7171
Expand Down
17 changes: 17 additions & 0 deletions test/integration/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICpDCCAYwCCQC+C4I0QVCnozANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls
b2NhbGhvc3QwHhcNMjAxMjEzMjEyNzUyWhcNMjExMjEzMjEyNzUyWjAUMRIwEAYD
VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCy
X8N6ox9cWxT4PFBLpRBuaSeaqSs25VeCGkN1+pSyygIms8m30S21wYvszrXFB3Ph
QvlUgpnAjhVdCC2O+Vd3vI+191eH1GmiVrPSEiIJ9jJAT/BQZNarMmLBsG7QSOgp
kSr1AEmfOTYD6YmZKhp+ba6GCGURwPKkCVCvOVkH2nXx2NFo/kKIc01ntQ++79ns
LmMXcPiw92JK3ALrQWfyWlCHD3Q8EfXRKzah3o9wEbwNnjbqVhutg/RSNCY+19Hz
IADxLNvPauAxi+jd+WtyOHNFYPJUBHXh6R3xe2Vafk2yaABOY9s+8sin0SrDiyyr
ro4j4DU/BjtjhBNloun3AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAwhR8ezAGCm
WGeGdaZKu/7gQtKWI0ePzwsFsV2OdHPhvgT7w18dLa5NCJTKBPrmbGs4bIr+jJZa
oKfEHv9v4Xx0OO1F/BNbFrcV9yMYHyPLTmg5twSzlJLpa2gm8YZW7Bz95uf6miLD
A5mOA9UzOpKZ1HA+t+gCLw9DbazX0a1G18v+kLGCmsHe9rRoFGI9cqG/3GRJBBAq
7UNTh8/7+f9k9tlVyQgnc1Ga4S7HfaqRRLGO16NXeNkfEUsjvqjrMOUvJOdoubZk
ZPXSY0SepSgVoGOe5MJePTCCVgwKgd1ICZPV+LILNEkdS6lsifd64Z60iLLJRlJz
FqxjKhsvuyQ=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions test/integration/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCyX8N6ox9cWxT4
PFBLpRBuaSeaqSs25VeCGkN1+pSyygIms8m30S21wYvszrXFB3PhQvlUgpnAjhVd
CC2O+Vd3vI+191eH1GmiVrPSEiIJ9jJAT/BQZNarMmLBsG7QSOgpkSr1AEmfOTYD
6YmZKhp+ba6GCGURwPKkCVCvOVkH2nXx2NFo/kKIc01ntQ++79nsLmMXcPiw92JK
3ALrQWfyWlCHD3Q8EfXRKzah3o9wEbwNnjbqVhutg/RSNCY+19HzIADxLNvPauAx
i+jd+WtyOHNFYPJUBHXh6R3xe2Vafk2yaABOY9s+8sin0SrDiyyrro4j4DU/Bjtj
hBNloun3AgMBAAECggEAJldNRmQfzpNJa55TSB8/6+uwdp8cSd18NNv+WjK1mcSw
N693kYpl/+aNdCZujd5vOyFRRKgZ8njYALpMSKox8evXHC8BYpH27s0iM+pv5KJF
5OsJ5c33Eq9u6OFKwHybYqvwht878/yxLqAZUpHpRfm/hNHzH6DQxw+1hySVjYk8
6Tp25Hl2sZMv4cU1krGNQTEUYwJDumXkO90keyYiT3WPvd/bJnhCDMFhR6jNdHRo
UqPQsi00eURVFoALn+ev9qNN7a/eepyMddTaNZoKjO25EZIdLtC85djP8I9zIU7i
+NOIYgOcR2ejGlmZMpsbnOHJU8P6ZprXTc18Wd+w0QKBgQDWGNCJ4CDszePTrCyl
LeDg8u7fz201m0cQP2Ltz5UTUwz7zHG9AaepfU3VYCVsKJz3vwJK8etSeh3Q8pE1
lcZQJ59MAjOvpGHus54X1PiDum2DZz6sbCONbLjw0gqjEVAbmMlfWFvSGYq7bK0U
wlvko5ZM1jM0DnUlfvQRAb90KQKBgQDVSRQy1kGJW1+i7leiYIRHYCwz602xlyiY
O4h8mMgXGLwlG70eK8wA9v54ztVXAypRJTDXdBWwbDXrWZUgYg/Icd6mV0VG8jCh
okAsw1xiWTLLY7yjHYID1WHKtd4g3IZrYsrSN7CVPWVjpJETjC7JZ2K0huod37rU
ftXKP3gxHwKBgBuu1bgeLOOxs5W5G4S4K+2qO8zgq0RVMZkeORJ61tHK2VDtnH9N
6Xn248uFRRF5JuK55ff+0+i0NYrA8pm1JhFTLjvLxRce8DLHMtfuB7wwrNxiyy3M
RcSRnFA3OHzhTjRjSxZy/FxsRQ36/V5Dy1IC/PoucCx4+hjBE5nnWfQRAoGAa/I1
n9kiiDNPvvWkMtFogXtiQ9C2nMglSo7u8CifNFlXd+yHFcsSz/YyKtB71zMJ6tHI
23KsO4M48ul++UnINSm0hzmqHVMcW+HzWvRxQHFmrNvIsEGR+QC5ItBTIQybl6QD
hMucupu9QeYbaupLD7IcmcOioAYI191ttJPU7/8CgYEAzYv5JA2LGZiCYuHUEA0D
RWVpOmwe9to7cftwbbIzYXJoBOTM/5aGmUCSZ5RR7Igzx0u15KOKKtW8jKJqR2hk
h2xnpIkTOZYVD1ILKIe7luu0BONIfy59pmGBxdqB3RyFL7LNEOhqNVTUdAG0OU0t
XlPk5c9UJgiDXNAzRLe8Glk=
-----END PRIVATE KEY-----
28 changes: 28 additions & 0 deletions test/integration/ssl.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<yandex>
<tcp_port_secure>9440</tcp_port_secure>
<openSSL>
<server>
<!-- openssl req -subj "/CN=localhost" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/clickhouse-server/server.key -out /etc/clickhouse-server/server.crt -->
<certificateFile>/etc/clickhouse-server/server.crt</certificateFile>
<privateKeyFile>/etc/clickhouse-server/server.key</privateKeyFile>
<!-- openssl dhparam -out /etc/clickhouse-server/dhparam.pem 4096 -->
<dhParamsFile>/etc/clickhouse-server/dhparam.pem</dhParamsFile>
<verificationMode>none</verificationMode>
<loadDefaultCAFile>true</loadDefaultCAFile>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
</server>
<client>
<loadDefaultCAFile>true</loadDefaultCAFile>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
<verificationMode>none</verificationMode>
<invalidCertificateHandler>
<name>AcceptCertificateHandler</name>
<!-- <name>RejectCertificateHandler</name> -->
</invalidCertificateHandler>
</client>
</openSSL>
</yandex>

0 comments on commit 3a8f061

Please sign in to comment.