From 8af9a740718cdf48990f04ab06a7ca50a5af5233 Mon Sep 17 00:00:00 2001 From: shodan Date: Wed, 11 Mar 2026 09:01:35 +0000 Subject: [PATCH] sshwifty --- app-of-apps/sshwifty.yaml | 16 ++ homer/configmaps.yaml | 74 +++++---- sshwifty/README.md | 2 + sshwifty/ingress.yaml | 28 ++++ sshwifty/namespace.yaml | 4 + sshwifty/sshwifty.yaml | 321 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 411 insertions(+), 34 deletions(-) create mode 100644 app-of-apps/sshwifty.yaml create mode 100644 sshwifty/README.md create mode 100644 sshwifty/ingress.yaml create mode 100644 sshwifty/namespace.yaml create mode 100644 sshwifty/sshwifty.yaml diff --git a/app-of-apps/sshwifty.yaml b/app-of-apps/sshwifty.yaml new file mode 100644 index 0000000..7d969f6 --- /dev/null +++ b/app-of-apps/sshwifty.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: sshwifty + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: sshwifty + server: https://kubernetes.default.svc + project: default + source: + path: sshwifty + repoURL: http://gitea.gitea.svc.k8s.undercloud.local:3000/Undercloud/k8s-apps.git + targetRevision: HEAD \ No newline at end of file diff --git a/homer/configmaps.yaml b/homer/configmaps.yaml index a6bea88..ccedc14 100644 --- a/homer/configmaps.yaml +++ b/homer/configmaps.yaml @@ -314,42 +314,42 @@ data: tag: "paperless" keywords: "paperless documents scan" url: "https://paperless.apps.undercloud.dev" - - name: "OpenHAB" - logo: "assets/logos/openhab.png" - subtitle: "home automation" - tag: "openhab" - keywords: "openhab home automation" - url: "https://openhab.apps.undercloud.dev" + #- name: "OpenHAB" + # logo: "assets/logos/openhab.png" + # subtitle: "home automation" + # tag: "openhab" + # keywords: "openhab home automation" + # url: "https://openhab.apps.undercloud.dev" - name: "Netbox" logo: "assets/logos/netbox.png" subtitle: "IP Address Management" tag: "netbox" keywords: "ip address" url: "https://netbox.apps.undercloud.dev" - - name: "Keycloak" - logo: "assets/logos/keycloak.png" - subtitle: "Sigle Sign On" - tag: "keycloak" - keywords: "single sign on sso keycloak" - url: "https://keycloak.apps.undercloud.dev" + #- name: "Keycloak" + # logo: "assets/logos/keycloak.png" + # subtitle: "Sigle Sign On" + # tag: "keycloak" + # keywords: "single sign on sso keycloak" + # url: "https://keycloak.apps.undercloud.dev" - name: "Emulator" logo: "assets/logos/emulatorjs.png" subtitle: "emulatorjs" tag: "emulatorjs" keywords: "emulator" url: "https://emulator.apps.undercloud.dev" - - name: "Emulator Backend" - logo: "assets/logos/emulatorjs.png" - subtitle: "backend" - tag: "emulatorjs" - keywords: "emulator" - url: "https://emulator-backend.apps.undercloud.dev" - - name: "MStream" - logo: "assets/logos/mstream.png" - subtitle: "music streaming" - tag: "mstream" - keywords: "mstream music streaming" - url: "https://mstream.apps.undercloud.dev" + #- name: "Emulator Backend" + # logo: "assets/logos/emulatorjs.png" + # subtitle: "backend" + # tag: "emulatorjs" + # keywords: "emulator" + # url: "https://emulator-backend.apps.undercloud.dev" + #- name: "MStream" + # logo: "assets/logos/mstream.png" + # subtitle: "music streaming" + # tag: "mstream" + # keywords: "mstream music streaming" + # url: "https://mstream.apps.undercloud.dev" - name: "Wekan" logo: "assets/logos/wekan.png" subtitle: "Kanban Board" @@ -410,12 +410,18 @@ data: tag: "ssh" keywords: "ssh wetty gateway" url: "https://wetty.apps.undercloud.dev" - - name: "Bastillion" - logo: "assets/logos/bastillion.png" + - name: "sshwifty" + logo: "assets/logos/ssh.png" subtitle: "http ssh client" tag: "ssh" - keywords: "ssh bastillion gateway" - url: "https://bastillion.apps.undercloud.dev" + keywords: "sshwifty gateway" + url: "https://sshwifty.apps.undercloud.dev" + #- name: "Bastillion" + # logo: "assets/logos/bastillion.png" + # subtitle: "http ssh client" + # tag: "ssh" + # keywords: "ssh bastillion gateway" + # url: "https://bastillion.apps.undercloud.dev" - name: "Guacamole" logo: "assets/logos/guacamole.png" subtitle: "RDP, VNC, SSH" @@ -509,12 +515,12 @@ data: tag: "google" keywords: "google drive" url: "https://drive.google.com/drive/my-drive" - - name: "Freenom" - logo: "assets/logos/freenom.png" - subtitle: "DNS Registrar (apps.undercloud.dev)" - tag: "dns" - keywords: "dns regostrar" - url: "https://www.freenom.com/" + #- name: "Freenom" + # logo: "assets/logos/freenom.png" + # subtitle: "DNS Registrar (apps.undercloud.dev)" + # tag: "dns" + # keywords: "dns regostrar" + # url: "https://www.freenom.com/" - name: "Tunnelbroker" logo: "assets/logos/he.png" subtitle: "6in4 Tunnel from Hurricane Electric" diff --git a/sshwifty/README.md b/sshwifty/README.md new file mode 100644 index 0000000..f22413a --- /dev/null +++ b/sshwifty/README.md @@ -0,0 +1,2 @@ +# SSHwifty +## online SSH client, connects via ssh and telnet \ No newline at end of file diff --git a/sshwifty/ingress.yaml b/sshwifty/ingress.yaml new file mode 100644 index 0000000..7e65762 --- /dev/null +++ b/sshwifty/ingress.yaml @@ -0,0 +1,28 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: sshwifty + namespace: sshwifty + annotations: + kubernetes.io/ingress.class: nginx + cert-manager.io/cluster-issuer: letsencrypt + #external-dns.alpha.kubernetes.io/target: firewall.undercloud.dev + #external-dns.alpha.kubernetes.io/ttl: "120" + + +spec: + tls: + - hosts: + - sshwifty.apps.undercloud.dev + secretName: sshwifty-tls + rules: + - host: sshwifty.apps.undercloud.dev + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: nginx + port: + number: 80 \ No newline at end of file diff --git a/sshwifty/namespace.yaml b/sshwifty/namespace.yaml new file mode 100644 index 0000000..083089a --- /dev/null +++ b/sshwifty/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: sshwifty \ No newline at end of file diff --git a/sshwifty/sshwifty.yaml b/sshwifty/sshwifty.yaml new file mode 100644 index 0000000..7154a1b --- /dev/null +++ b/sshwifty/sshwifty.yaml @@ -0,0 +1,321 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: config + namespace: sshwifty +data: + sshwifty.conf.json: | + { + // HTTP Host. Keep it empty to accept request from all hosts, otherwise, only + // specified host is allowed to access + "HostName": "localhost", + + // Web interface access password. Set to empty to allow public access to the + // web interface (By pass the Authenticate page) + "SharedKey": "WEB_ACCESS_PASSWORD", + + // Remote dial timeout. This limits how long of time the backend can spend + // to connect to a remote host. The max timeout will be determined by + // server configuration (ReadTimeout). + // (In Seconds) + "DialTimeout": 10, + + // Socks5 proxy. When set, Sshwifty backend will try to connect remote through + // the given proxy + "Socks5": "localhost:1080", + + // Username of the Socks5 server. Please set when needed + "Socks5User": "", + + // Password of the Socks5 server. Please set when needed + "Socks5Password": "", + + // Server side hooks, allowing operator to launch external processes on the + // server side to influence server behaver + // + // The operation of a Hook must be completed within the time limit defined + // by `HookTimeout` set below. Otherwise it will be terminated, and results + // a failure for the execution + // + // To determine how much time is still left for the execution, a Hook can + // fetch the deadline information from the `SSHWIFTY_HOOK_DEADLINE` + // environment variable which is a RFC3339 formatted date string indicating + // after what time the termination will occur + // + // Warning: the process will be launched within the same context and system + // permission which Sshwifty is running under, thus is it crucial that the + // Hook process is designed and operated in a secure manner, otherwise + // SECURITY VULNERABILITY (commandline injection, for example) maybe created + // as result + // + // Warning: all inputs passed by Sshwifty to the hook process must be + // considered unsanitized, and must be sanitized by each hook themselves + "Hooks": { + // before_connecting is called before Sshwifty starts to connect to a remote + // endpoint. If any of the Hook process exited with a non-zero return code, + // the connection request is aborted + // + // This Hook offers two parameters: + // - SSHWIFTY_HOOK_REMOTE_TYPE: Type of the connection (i.e. SSH or Telnet) + // - SSHWIFTY_HOOK_REMOTE_ADDRESS: Address of the remote host + "before_connecting": [ + // Following example command launches a `/bin/sh` to execute a for loop + // that prints to Stdout as well as to Stderr + // + // Prints to Stdout will be sent to the client side visible to the user, + // and prints to Stderr will be captured as server side logs and it is + // invisible to the user (as server logs usually are) + // + // The command must be specified in Json array format. Each array element + // is mapped to a command fragment separated by space. For example: + // ["command", "-i", "Hello World"] will be mapped to `command -i "Hello + // World"` before it is executed + [ + "/bin/sh", + "-c", + "for n in $(seq 1 5); do sleep 1 && echo Stdout $SSHWIFTY_HOOK_REMOTE_TYPE $n && echo Stderr $SSHWIFTY_HOOK_REMOTE_TYPE $n 1>&2; done" + ], + // You can add multiple hooks, they're executed in sequence even when the + // previous one fails + [ + "/bin/sh", + "-c", + "/etc/sshwifty/before_connecting.sh" + ], + [ + "/bin/another-command", + "...", + "..." + ] + ] + }, + + // The maximum execution time of each hook, in seconds. If this timeout is + // exceeded, the hook will be terminated, and thus cause a failure + "HookTimeout": 30, + + // Sshwifty HTTP server, you can set multiple ones to serve on different + // ports + "Servers": [ + { + // Which local network interface this server will be listening + "ListenInterface": "0.0.0.0", + + // Which local network port this server will be listening + "ListenPort": 8182, + + // Timeout of initial request. HTTP handshake must be finished within + // this time + // (In Seconds) + "InitialTimeout": 10, + + // How long do the connection can stay in idle before the backend server + // disconnects the client + // (In Seconds) + "ReadTimeout": 120, + + // How long the server will wait until the client connection is ready to + // recieve new data. If this timeout is exceed, the connection will be + // closed. + // (In Seconds) + "WriteTimeout": 120, + + // The interval between internal echo requests + // (In Seconds) + "HeartbeatTimeout": 10, + + // Forced delay between each request + // (In Milliseconds) + "ReadDelay": 10, + + // Forced delay between each write + // (In Milliseconds) + "WriteDelay": 10, + + // Path to TLS certificate file. Set empty to use HTTP + "TLSCertificateFile": "", + + // Path to TLS certificate key file. Set empty to use HTTP + "TLSCertificateKeyFile": "", + + // Display a short text message on the Home page. Link is supported + // through `[Title text](https://link.example.com)` format + "ServerMessage": "" + }, + { + "ListenInterface": "0.0.0.0", + "ListenPort": 8182, + "InitialTimeout": 3, + ..... + } + ], + + // Remote Presets, the operater can define few presets for user so the user + // won't have to manually fill-in all the form fields + // + // Presets will be displayed in the "Known remotes" tab on the Connector + // window + // + // Notice: You can use the same JSON value for `SSHWIFTY_PRESETS` if you are + // configuring your Sshwifty through enviroment variables. + // + // Warning: Presets Data will be sent to user client WITHOUT any protection. + // DO NOT add any secret information into Preset. + // + "Presets": [ + { + // Title of the preset + "Title": "SDF.org Unix Shell", + + // Preset Types, i.e. Telnet, and SSH + "Type": "SSH", + + // Target address and port + "Host": "sdf.org:22", + + // Define the tab and background color of the console in RGB hex format + // for better visual identification + // + // For example: 110000 will give you a dark red background, 001100 is + // dark green and 000011 is dark blue + // + // The color must not be too bright, as it will make the foreground text + // hard to read + "TabColor": "112233", + + // Form fields and values, you have to manually validate the correctness + // of the field value + // + // Defining a Meta field will prevent user from changing it on their + // Connector Wizard. If you want to allow users to use their own settings, + // leave the field unsetted + // + // Values in Meta are scheme enabled, and supports following scheme + // prefixes: + // - "literal://": Text literal (Default) + // Example: literal://Data value + // (The final value will be "Data value") + // Example: literal://file:///tmp/afile + // (The final value will be "file:///tmp/afile") + // - "file://": Load Meta value from given file. + // Example: file:///home/user/.ssh/private_key + // (The file path is /home/user/.ssh/private_key) + // - "environment://": Load Meta value from an Environment Variable. + // Example: environment://PRIVATE_KEY_DATA + // (The name of the target environment variable is + // PRIVATE_KEY_DATA) + // + // All data in Meta is loaded during start up, and will not be updated + // even the source already been modified. + // + "Meta": { + // Data for predefined User field + "User": "pre-defined-username", + + // Data for predefined Encoding field. Valid data is those displayed on + // the page + "Encoding": "pre-defined-encoding", + + // Data for predefined Password field + "Password": "pre-defined-password", + + // Data for predefined Private Key field, should contains the content + // of a Key file + "Private Key": "file:///home/user/.ssh/private_key", + + // Data for predefined Authentication field. Valid values is what + // displayed on the page (Password, Private Key, None) + "Authentication": "Password", + + // Data for server public key fingerprint. You can acquire the value of + // the fingerprint by manually connect to a new SSH host with Sshwifty, + // the fingerprint will be displayed on the Fingerprint comformation + // page. + "Fingerprint": "SHA256:bgO...." + } + }, + { + "Title": "Endpoint Telnet", + "Type": "Telnet", + "Host": "endpoint.nirui.org:23", + "Meta": { + // Data for predefined Encoding field. Valid data is those displayed on + // the page + "Encoding": "utf-8" + .... + } + }, + .... + ], + + // Allow the Preset Remotes only, and refuse to connect to any other remote + // host + // + // NOTICE: You can only configure OnlyAllowPresetRemotes through a config + // file. This option is not supported when you are configuring with + // environment variables + "OnlyAllowPresetRemotes": false + } +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: sshwifty + namespace: sshwifty + labels: + app: sshwifty +spec: + replicas: 1 + selector: + matchLabels: + app: sshwifty + template: + metadata: + annotations: + #backup.velero.io/backup-volumes: html + labels: + app: sshwifty + spec: + containers: + - name: sshwifty + image: niruix/sshwifty:latest + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8182 + env: + - name: SSHWIFTY_CONFIG + value: "./sshwifty.conf.json ./sshwifty" + volumeMounts: + - mountPath: "./sshwifty.conf.json" + name: config + subPath: sshwifty.conf.json + volumes: + - name: config + configMap: + name: config + defaultMode: 0777 + items: + - key: "sshwifty.conf.json" + path: "sshwifty.conf.json" +--- +apiVersion: v1 +kind: Service +metadata: + name: sshwifty + namespace: sshwifty +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv6 + - IPv4 + ipFamilyPolicy: PreferDualStack + #ipFamilyPolicy: SingleStack + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 8182 + selector: + app: sshwifty + #sessionAffinity: None + type: ClusterIP