diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 2e201c8..a4610bf 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -13,6 +13,20 @@ docker run -d \ thiht/smocker ``` +or with TLS enabled: + +```sh +docker run -d \ + --restart=always \ + -p 44300:8080 \ + -p 44301:8081 \ + -e SMOCKER_TLS_ENABLE=true \ + -v /path/to/your/cert.pem:/etc/smocker/tls/certs/cert.pem:ro + -v /path/to/your/key.pem:/etc/smocker/tls/private/key.pem:ro + --name smocker \ + thiht/smocker +``` + ## Manual Deployment ::: tip Note @@ -25,7 +39,14 @@ mkdir -p /opt/smocker && cd /opt/smocker wget -P /tmp https://github.com/Thiht/smocker/releases/latest/download/smocker.tar.gz tar xf /tmp/smocker.tar.gz rm /tmp/smocker.tar.gz + nohup ./smocker -mock-server-listen-port=8080 -config-listen-port=8081 & + +# Or with TLS + +# The certificate is expected in /etc/smocker/tls/certs/ by default +# You can override it with -tls-cert-file and -tls-private-key-file +nohup ./smocker -mock-server-listen-port=44300 -config-listen-port=44301 -tls-enable & ``` ## Healthcheck @@ -35,3 +56,12 @@ To check that Smocker started successfully, just run the following command: ```sh curl localhost:8081/version ``` + +or with TLS enabled: + +```sh +curl https://localhost:44301/version + +# Or if you use a self signed certificate +curl -k https://localhost:44301/version +``` diff --git a/docs/technical-documentation/arguments.md b/docs/technical-documentation/arguments.md index 9004ad2..245a0ab 100644 --- a/docs/technical-documentation/arguments.md +++ b/docs/technical-documentation/arguments.md @@ -4,12 +4,15 @@ Smoker can be parameterized through several arguments. The list of existing Smocker parameters is: -| Flag | Environment Variable | Default | Description | -| ------------------------- | --------------------------------- | :------: | ------------------------------------------------------------------------------------------------ | -| `config-base-path` | `SMOCKER_CONFIG_BASE_PATH` | **/** | Used to deploy Smocker under a sub-path of a domain | -| `config-listen-port` | `SMOCKER_CONFIG_LISTEN_PORT` | **8081** | Port exposed by Smocker's API which is used to administrate Smocker | -| `mock-server-listen-port` | `SMOCKER_MOCK_SERVER_LISTEN_PORT` | **8080** | Port exposed by Smocker's mock server where should be redirected your HTTP calls | -| `static-files` | `SMOCKER_STATIC_FILES` | **.** | The location of the static files to serve for the UI (index.html, etc.) | -| `log-level` | `SMOCKER_LOG_LEVEL` | **info** | The log level of Smocker, Values: `panic`, `fatal`, `error`, `warning`, `info`, `debug`, `trace` | -| `history-retention` | `SMOCKER_HISTORY_RETENTION` | **0** | The maximum number of calls to keep in the history by sessions (0 = infinity) | -| `persistence-directory` | `SMOCKER_PERSISTENCE_DIRECTORY` | **""** | If defined, the directory where the sessions will be synchronized | +| Flag | Environment Variable | Default | Description | +| ------------------------- | --------------------------------- | :----------------------------------: | ------------------------------------------------------------------------------------------------ | +| `config-base-path` | `SMOCKER_CONFIG_BASE_PATH` | **/** | Used to deploy Smocker under a sub-path of a domain | +| `config-listen-port` | `SMOCKER_CONFIG_LISTEN_PORT` | **8081** | Port exposed by Smocker's API which is used to administrate Smocker | +| `mock-server-listen-port` | `SMOCKER_MOCK_SERVER_LISTEN_PORT` | **8080** | Port exposed by Smocker's mock server where should be redirected your HTTP calls | +| `static-files` | `SMOCKER_STATIC_FILES` | **.** | The location of the static files to serve for the UI (index.html, etc.) | +| `log-level` | `SMOCKER_LOG_LEVEL` | **info** | The log level of Smocker, Values: `panic`, `fatal`, `error`, `warning`, `info`, `debug`, `trace` | +| `history-retention` | `SMOCKER_HISTORY_RETENTION` | **0** | The maximum number of calls to keep in the history by sessions (0 = infinity) | +| `persistence-directory` | `SMOCKER_PERSISTENCE_DIRECTORY` | **""** | If defined, the directory where the sessions will be synchronized | +| `tls-enable` | `SMOCKER_TLS_ENABLE=true` | **false** | Enable TLS using the provided certificate | +| `tls-cert-file` | `SMOCKER_TLS_CERT_FILE` | **/etc/smocker/tls/certs/cert.pem** | Path to TLS certificate file | +| `tls-private-key-file` | `SMOCKER_TLS_PRIVATE_KEY_FILE` | **/etc/smocker/tls/private/key.pem** | Path to TLS key file | diff --git a/main.go b/main.go index d66eb4b..bd61b78 100644 --- a/main.go +++ b/main.go @@ -25,12 +25,15 @@ func parseConfig() (c config.Config) { flag.CommandLine = flag.NewFlagSetWithEnvPrefix(os.Args[0], "SMOCKER", flag.ExitOnError) flag.StringVar(&c.LogLevel, "log-level", "info", "Available levels: panic, fatal, error, warning, info, debug, trace") - flag.StringVar(&c.ConfigBasePath, "config-base-path", "/", "Defines the base path which will be applied on Smocker UI") - flag.IntVar(&c.ConfigListenPort, "config-listen-port", 8081, "Defines the listening port of Smocker administration server") - flag.IntVar(&c.MockServerListenPort, "mock-server-listen-port", 8080, "Defines the listening port of Smocker mock server") - flag.StringVar(&c.StaticFiles, "static-files", ".", "The location of the static files to serve (index.html, etc.)") - flag.IntVar(&c.HistoryMaxRetention, "history-retention", 0, "The maximum number of calls to keep in the history by sessions (0 = infinity)") + flag.StringVar(&c.ConfigBasePath, "config-base-path", "/", "Base path applied to Smocker UI") + flag.IntVar(&c.ConfigListenPort, "config-listen-port", 8081, "Listening port of Smocker administration server") + flag.IntVar(&c.MockServerListenPort, "mock-server-listen-port", 8080, "Listening port of Smocker mock server") + flag.StringVar(&c.StaticFiles, "static-files", ".", "Location of the static files to serve (index.html, etc.)") + flag.IntVar(&c.HistoryMaxRetention, "history-retention", 0, "Maximum number of calls to keep in the history per session (0 = no limit)") flag.StringVar(&c.PersistenceDirectory, "persistence-directory", "", "If defined, the directory where the sessions will be synchronized") + flag.BoolVar(&c.TLSEnable, "tls-enable", false, "Enable TLS using the provided certificate") + flag.StringVar(&c.TLSCertFile, "tls-cert-file", "/etc/smocker/tls/certs/cert.pem", "Path to TLS certificate file ") + flag.StringVar(&c.TLSKeyFile, "tls-private-key-file", "/etc/smocker/tls/private/key.pem", "Path to TLS key file") flag.Parse() return } diff --git a/server/admin_server.go b/server/admin_server.go index aefafb3..533208e 100644 --- a/server/admin_server.go +++ b/server/admin_server.go @@ -1,6 +1,7 @@ package server import ( + "crypto/tls" "html/template" "io" "net/http" @@ -71,6 +72,26 @@ func Serve(config config.Config) { log.WithField("port", config.ConfigListenPort).Info("Starting admin server") log.WithField("port", config.MockServerListenPort).Info("Starting mock server") adminServerEngine.Server.Addr = ":" + strconv.Itoa(config.ConfigListenPort) + + if config.TLSEnable { + certificate, err := tls.LoadX509KeyPair(config.TLSCertFile, config.TLSKeyFile) + if err != nil { + log.WithFields(log.Fields{ + "tls-cert-file": config.TLSCertFile, + "tls-key-file": config.TLSKeyFile, + }).Fatalf("Invalid certificate: %v", err) + } + + adminServerEngine.Server.TLSConfig = &tls.Config{ + NextProtos: []string{"http/1.1"}, + Certificates: []tls.Certificate{certificate}, + } + mockServerEngine.TLSConfig = &tls.Config{ + NextProtos: []string{"http/1.1"}, + Certificates: []tls.Certificate{certificate}, + } + } + if err := gracehttp.Serve(adminServerEngine.Server, mockServerEngine); err != nil { log.Fatal(err) } diff --git a/server/config/config.go b/server/config/config.go index 845bb5e..b2212e7 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -8,6 +8,9 @@ type Config struct { StaticFiles string HistoryMaxRetention int PersistenceDirectory string + TLSEnable bool + TLSCertFile string + TLSKeyFile string Build Build }