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

External TLS termination for the Charm server #37

Closed
rubiojr opened this issue Dec 9, 2021 · 0 comments · Fixed by #89
Closed

External TLS termination for the Charm server #37

rubiojr opened this issue Dec 9, 2021 · 0 comments · Fixed by #89

Comments

@rubiojr
Copy link
Contributor

rubiojr commented Dec 9, 2021

I have a Caddy server proxying a few other servers and doing TLS termination for them, so I'd like to do that with the Charm server also, and setup a Charm server using the docker container, behind a Caddy container doing the TLS termination.

Screenshot from 2021-12-09 17-43-00
not that this helps a lot but the issues looks less boring :)

The setup is straight forward but I'm finding some resistance: if I don't specify CHARM_SERVER_HTTP_SCHEME=https server side (as documented in the README), the client tries to communicate using plain HTTP with the server eventually (presumably after being told to use http by the server), so I need to set CHARM_SERVER_HTTP_SCHEME=https. However, if I do that, the server crashes when starting up because it obviously requires key material to do the TLS termination and I'm not setting CHARM_SERVER_TLS_KEY_FILE and CHARM_SERVER_TLS_CERT_FILE:

charm          | 2021/12/09 16:02:51 HTTPS server listening on: :35354                                                                                                                        
charm          | 2021/12/09 16:02:51 Server crashed: open : no such file or directory                                                                                                         

It'd be nice if an external proxy (like Caddy in my case) could do the TLS termination while the server lets the client know it should still use https to communicate (I think this is related to the URL schema being used to send requests.

I'm currently using a small patch and seems to be working as expected, with Charm server serving plain text and Caddy doing the TLS termination, but keeping the client happy and the transport layer secure:

diff --git a/server/http.go b/server/http.go
index 642996f..7fed612 100644
--- a/server/http.go
+++ b/server/http.go
@@ -88,7 +88,7 @@ func (s *HTTPServer) Start() {
 	}()
 
 	log.Printf("%s server listening on: %s", strings.ToUpper(s.cfg.HTTPScheme), listenAddr)
-	if useTls {
+	if useTls && !s.cfg.TLSDisableTermination {
 		log.Fatalf("Server crashed: %s", server.ListenAndServeTLS(s.cfg.TLSCertFile, s.cfg.TLSKeyFile))
 	} else {
 		log.Fatalf("Server crashed: %s", server.ListenAndServe())
diff --git a/server/server.go b/server/server.go
index 0ea177c..038e840 100644
--- a/server/server.go
+++ b/server/server.go
@@ -17,21 +17,22 @@ import (
 
 // Config is the configuration for the Charm server.
 type Config struct {
-	Host        string `env:"CHARM_SERVER_HOST" default:"localhost"`
-	SSHPort     int    `env:"CHARM_SERVER_SSH_PORT" default:"35353"`
-	HTTPPort    int    `env:"CHARM_SERVER_HTTP_PORT" default:"35354"`
-	HTTPScheme  string `env:"CHARM_SERVER_HTTP_SCHEME" default:"http"`
-	StatsPort   int    `env:"CHARM_SERVER_STATS_PORT" default:"35355"`
-	HealthPort  string `env:"CHARM_SERVER_HEALTH_PORT" default:"35356"`
-	DataDir     string `env:"CHARM_SERVER_DATA_DIR" default:"./data"`
-	TLSKeyFile  string `env:"CHARM_SERVER_TLS_KEY_FILE" default:""`
-	TLSCertFile string `env:"CHARM_SERVER_TLS_CERT_FILE" default:""`
-	TLSConfig   *tls.Config
-	PublicKey   []byte
-	PrivateKey  []byte
-	DB          db.DB
-	FileStore   storage.FileStore
-	Stats       stats.Stats
+	Host                  string `env:"CHARM_SERVER_HOST" default:"localhost"`
+	SSHPort               int    `env:"CHARM_SERVER_SSH_PORT" default:"35353"`
+	HTTPPort              int    `env:"CHARM_SERVER_HTTP_PORT" default:"35354"`
+	HTTPScheme            string `env:"CHARM_SERVER_HTTP_SCHEME" default:"http"`
+	StatsPort             int    `env:"CHARM_SERVER_STATS_PORT" default:"35355"`
+	HealthPort            string `env:"CHARM_SERVER_HEALTH_PORT" default:"35356"`
+	DataDir               string `env:"CHARM_SERVER_DATA_DIR" default:"./data"`
+	TLSKeyFile            string `env:"CHARM_SERVER_TLS_KEY_FILE" default:""`
+	TLSCertFile           string `env:"CHARM_SERVER_TLS_CERT_FILE" default:""`
+	TLSConfig             *tls.Config
+	TLSDisableTermination bool `env:"CHARM_SERVER_TLS_DISABLE_TERMINATION"`
+	PublicKey             []byte
+	PrivateKey            []byte
+	DB                    db.DB
+	FileStore             storage.FileStore
+	Stats                 stats.Stats
 }
 
 // Server contains the SSH and HTTP servers required to host the Charm Cloud.

Diff here. I'm currently unaware of how many kittens per day this patch could eat.

With that patch, I can start the server with the following env variables and have Caddy in front, serving and doing the TLS termination:

CHARM_SERVER_TLS_DISABLE_TERMINATION=1 CHARM_SERVER_HTTP_SCHEME=https CHARM_SERVER_HOST=my.awesome.charm ./charm serve

Did I miss something or having external TLS termination isn't currently possible?

❤️

aymanbagabas added a commit that referenced this issue Dec 16, 2021
aymanbagabas added a commit that referenced this issue Jan 3, 2022
aymanbagabas added a commit that referenced this issue Jan 4, 2022
aymanbagabas added a commit that referenced this issue Jan 4, 2022
rubiojr pushed a commit to rubiojr/charm that referenced this issue Jan 31, 2022
aymanbagabas added a commit that referenced this issue Feb 22, 2022
* Specify server public http url in a environment variable

Fixes: #37
Related: #58
aymanbagabas added a commit that referenced this issue Feb 22, 2022
* Specify server public http url in a environment variable

Fixes: #37
Related: #58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant