diff --git a/internal/config/config.go b/internal/config/config.go index 1167bf5..4e93ac7 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -68,6 +68,9 @@ type Config struct { // This variable can be used to determine their length. PasswordLength int `env:"PASSWORD_LENGTH" default:"64" parser:"number"` + // Public port to use for the ssh server + PublicSSHPort uint16 `env:"SSH_PORT" default:"2222" parser:"port"` + // A file to be used for global authorized_keys for the ssh server. GlobalAuthorizedKeysFile string `env:"GLOBAL_AUTHORIZED_KEYS_FILE" default:"/var/www/deploy/authorized_keys" parser:"file"` diff --git a/internal/config/config_template b/internal/config/config_template index d3c22f0..bc8b2bc 100644 --- a/internal/config/config_template +++ b/internal/config/config_template @@ -58,6 +58,9 @@ PASSWORD_LENGTH=64 # A file to be used for global authorized_keys for the ssh server. GLOBAL_AUTHORIZED_KEYS_FILE=${AUTHORIZED_KEYS_FILE} +# the port to use for the ssh server +SSH_PORT=2222 + # The admin user and password of the GraphDB interface, to be used for queries GRAPHDB_ADMIN_USER=${GRAPHDB_ADMIN_USER} GRAPHDB_ADMIN_PASSWORD=${GRAPHDB_ADMIN_PASSWORD} diff --git a/internal/dis/component/ssh2/server_handler.go b/internal/dis/component/ssh2/server_handler.go index 2e84784..5f10a05 100644 --- a/internal/dis/component/ssh2/server_handler.go +++ b/internal/dis/component/ssh2/server_handler.go @@ -3,6 +3,7 @@ package ssh2 import ( "bufio" "io" + "strconv" "strings" "github.com/gliderlabs/ssh" @@ -34,7 +35,7 @@ is the name of the WissKI you want to you want to connect to. From a linux (or mac, or windows 11) command line you may use: -ssh -J ${DOMAIN}:2222 www-data@${HOSTNAME} +ssh -J ${DOMAIN}:${PORT} www-data@${HOSTNAME} You may also place the following into your $HOME/.ssh/config file: @@ -44,7 +45,7 @@ Host *.${DOMAIN} Host ${DOMAIN}.proxy User www-data Hostname ${DOMAIN} - Port 2222 + Port ${PORT} and then connect simply via: @@ -81,6 +82,7 @@ func (ssh2 *SSH2) handleConnection(session ssh.Session) { {"${SLUG}", slug}, {"${DOMAIN}", ssh2.Config.DefaultDomain}, {"${HOSTNAME}", slug + "." + ssh2.Config.DefaultDomain}, + {"${PORT}", strconv.FormatUint(uint64(ssh2.Config.PublicSSHPort), 10)}, } { banner = strings.ReplaceAll(banner, oldnew[0], oldnew[1]) } diff --git a/internal/dis/component/ssh2/server_hostkeys.go b/internal/dis/component/ssh2/server_hostkeys.go index d8d5188..dde8611 100644 --- a/internal/dis/component/ssh2/server_hostkeys.go +++ b/internal/dis/component/ssh2/server_hostkeys.go @@ -118,10 +118,10 @@ func (ssh2 *SSH2) makeHostKey(io stream.IOStream, key HostKey, path string) erro // generate and write private key as PEM privateKeyFile, err := ssh2.Environment.Create(path, environment.DefaultFilePerm) - defer privateKeyFile.Close() if err != nil { return err } + defer privateKeyFile.Close() return pem.Encode(privateKeyFile, privateKeyPEM) } @@ -228,8 +228,7 @@ func (ek *ed25519HostKey) UnmarshalPEM(block *pem.Block) (err error) { // store the private key and setup the signer ek.pk = &pk ek.Signer, err = gossh.NewSignerFromKey(ek.pk) - - return nil + return err } // diff --git a/internal/dis/component/ssh2/ssh2.env b/internal/dis/component/ssh2/ssh2.env index 2b65aa7..9e40b5d 100644 --- a/internal/dis/component/ssh2/ssh2.env +++ b/internal/dis/component/ssh2/ssh2.env @@ -7,4 +7,5 @@ SELF_OVERRIDES_FILE=${SELF_OVERRIDES_FILE} SELF_RESOLVER_BLOCK_FILE=${SELF_RESOLVER_BLOCK_FILE} DOCKER_NETWORK_NAME=${DOCKER_NETWORK_NAME} -HTTPS_ENABLED=${HTTPS_ENABLED} \ No newline at end of file +HTTPS_ENABLED=${HTTPS_ENABLED} +SSH_PORT=${SSH_PORT} \ No newline at end of file diff --git a/internal/dis/component/ssh2/ssh2/docker-compose.yml b/internal/dis/component/ssh2/ssh2/docker-compose.yml index 0f30a85..4272501 100644 --- a/internal/dis/component/ssh2/ssh2/docker-compose.yml +++ b/internal/dis/component/ssh2/ssh2/docker-compose.yml @@ -7,7 +7,7 @@ services: environment: CONFIG_PATH: ${CONFIG_PATH} ports: - - "2222:2222" + - "${SSH_PORT}:2222" volumes: - "/var/run/docker.sock:/var/run/docker.sock" - "${CONFIG_PATH}:${CONFIG_PATH}:ro" diff --git a/internal/dis/component/ssh2/stack.go b/internal/dis/component/ssh2/stack.go index a9d8200..532cf90 100644 --- a/internal/dis/component/ssh2/stack.go +++ b/internal/dis/component/ssh2/stack.go @@ -3,6 +3,7 @@ package ssh2 import ( "embed" "path/filepath" + "strconv" "github.com/FAU-CDI/wisski-distillery/internal/bootstrap" "github.com/FAU-CDI/wisski-distillery/internal/dis/component" @@ -33,6 +34,8 @@ func (ssh *SSH2) Stack(env environment.Environment) component.StackWithResources "GLOBAL_AUTHORIZED_KEYS_FILE": ssh.Config.GlobalAuthorizedKeysFile, "SELF_OVERRIDES_FILE": ssh.Config.SelfOverridesFile, "SELF_RESOLVER_BLOCK_FILE": ssh.Config.SelfResolverBlockFile, + + "SSH_PORT": strconv.FormatUint(uint64(ssh.Config.PublicSSHPort), 10), }, CopyContextFiles: []string{bootstrap.Executable}, diff --git a/pkg/stringparser/parse.go b/pkg/stringparser/parse.go index a294548..777d929 100644 --- a/pkg/stringparser/parse.go +++ b/pkg/stringparser/parse.go @@ -46,6 +46,7 @@ var knownParsers map[string]Parser[any] = map[string]Parser[any]{ "domain": asGenericParser(ParseValidDomain), "domains": asGenericParser(ParseValidDomains), "number": asGenericParser(ParseNumber), + "port": asGenericParser(ParsePort), "https_url": asGenericParser(ParseHttpsURL), "slug": asGenericParser(ParseSlug), "file": asGenericParser(ParseFile), diff --git a/pkg/stringparser/stringparser.go b/pkg/stringparser/stringparser.go index f18c98a..59c438f 100644 --- a/pkg/stringparser/stringparser.go +++ b/pkg/stringparser/stringparser.go @@ -76,6 +76,12 @@ func ParseNumber(env environment.Environment, s string) (int, error) { return int(value), err } +// ParsePort parses s as a port +func ParsePort(env environment.Environment, s string) (uint16, error) { + value, err := strconv.ParseUint(s, 10, 16) + return uint16(value), err +} + // ParseHttpsURL parses a string into a url that starts with 'https://' func ParseHttpsURL(env environment.Environment, s string) (*url.URL, error) { url, err := url.Parse(s)