{"id":13469795,"url":"https://github.com/nirui/sshwifty","last_synced_at":"2026-04-01T17:08:13.635Z","repository":{"id":37424427,"uuid":"200967040","full_name":"nirui/sshwifty","owner":"nirui","description":"Web SSH \u0026 Telnet (WebSSH \u0026 WebTelnet client) 🔮","archived":false,"fork":false,"pushed_at":"2026-03-18T06:39:55.000Z","size":15833,"stargazers_count":3055,"open_issues_count":42,"forks_count":400,"subscribers_count":29,"default_branch":"master","last_synced_at":"2026-03-18T07:07:13.933Z","etag":null,"topics":["ssh","telnet","webssh","webssh2","webtelnet"],"latest_commit_sha":null,"homepage":"https://sshwifty-demo.nirui.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nirui.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-08-07T03:43:18.000Z","updated_at":"2026-03-18T06:30:45.000Z","dependencies_parsed_at":"2023-11-25T11:22:15.360Z","dependency_job_id":"b8a10686-9b58-454b-8b72-363878eda4a8","html_url":"https://github.com/nirui/sshwifty","commit_stats":{"total_commits":484,"total_committers":5,"mean_commits":96.8,"dds":"0.23966942148760328","last_synced_commit":"7ea1475a162e03037fa3e0e77a7af699d701f073"},"previous_names":["niruix/sshwifty"],"tags_count":194,"template":false,"template_full_name":null,"purl":"pkg:github/nirui/sshwifty","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirui%2Fsshwifty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirui%2Fsshwifty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirui%2Fsshwifty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirui%2Fsshwifty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nirui","download_url":"https://codeload.github.com/nirui/sshwifty/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirui%2Fsshwifty/sbom","scorecard":{"id":87771,"data":{"date":"2025-08-04","repo":{"name":"github.com/nirui/sshwifty","commit":"31d5a6dc60e820d59e8c4af7f48e447cc4736301"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":3.9,"checks":[{"name":"Maintained","score":10,"reason":"19 commit(s) and 9 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/workflow.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: GNU Affero General Public License v3.0: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":8,"reason":"5 out of the last 5 releases have a total of 5 signed artifacts.","details":["Info: signed release artifact: GPG.asc: https://github.com/nirui/sshwifty/releases/tag/0.3.25-beta-release-prebuild","Info: signed release artifact: GPG.asc: https://github.com/nirui/sshwifty/releases/tag/0.3.24-beta-release-prebuild","Info: signed release artifact: GPG.asc: https://github.com/nirui/sshwifty/releases/tag/0.3.23-beta-release-prebuild","Info: signed release artifact: GPG.asc: https://github.com/nirui/sshwifty/releases/tag/0.3.22-beta-release-prebuild","Info: signed release artifact: GPG.asc: https://github.com/nirui/sshwifty/releases/tag/0.3.21-beta-release-prebuild","Warn: release artifact 0.3.25-beta-release-prebuild does not have provenance: https://api.github.com/repos/nirui/sshwifty/releases/228019965","Warn: release artifact 0.3.24-beta-release-prebuild does not have provenance: https://api.github.com/repos/nirui/sshwifty/releases/223607502","Warn: release artifact 0.3.23-beta-release-prebuild does not have provenance: https://api.github.com/repos/nirui/sshwifty/releases/220774338","Warn: release artifact 0.3.22-beta-release-prebuild does not have provenance: https://api.github.com/repos/nirui/sshwifty/releases/219107470","Warn: release artifact 0.3.21-beta-release-prebuild does not have provenance: https://api.github.com/repos/nirui/sshwifty/releases/213654094"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Info: Possibly incomplete results: error parsing shell code: reached \" without matching ( with ): .ci.sh:0","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/workflow.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/nirui/sshwifty/workflow.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/workflow.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/nirui/sshwifty/workflow.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:2","Warn: containerImage not pinned by hash: Dockerfile:25","Warn: containerImage not pinned by hash: Dockerfile:39","Warn: containerImage not pinned by hash: Dockerfile:48: pin your Docker image by updating alpine:latest to alpine:latest@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":1,"reason":"9 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-xffm-g5w8-qvg7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-44c6-4v22-4mhx","Warn: Project is vulnerable to: GHSA-4x5v-gmq8-25ch","Warn: Project is vulnerable to: GHSA-5j4c-8p2g-v4jx"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-15T07:17:45.053Z","repository_id":37424427,"created_at":"2025-08-15T07:17:45.053Z","updated_at":"2025-08-15T07:17:45.053Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ssh","telnet","webssh","webssh2","webtelnet"],"created_at":"2024-07-31T16:00:16.385Z","updated_at":"2026-04-01T17:08:13.629Z","avatar_url":"https://github.com/nirui.png","language":"JavaScript","readme":"# Sshwifty Web SSH \u0026 Telnet Client\n\n**Sshwifty is a SSH and Telnet client made for the Web,** allow you to access\nSSH and Telnet services right from your web browser.\n\n![Screenshot](Screenshot.png)\n\n(The glass glare effect above is only included in the Executive Golden Premium\nPlus+ Platinum Ultimate AD-free version, which can be obtained after joining the\ncult. Though, science has proven that the normal AD-free version is sufficient\nfor most people. In fact, the majority of people surveyed are annoyed by the\nglare, while the rest showed a little interest)\n\n![Build Status](https://github.com/nirui/sshwifty/workflows/Sshwifty-CI/badge.svg)\n\n## Install\n\n### Prebuilt Executables\n\nWe offer prebuilt ready-to-run programs (called executables) for a handful of\npopular platforms in the [Releases] section. You might find one built for your\nplatform there.\n\nPlease aware that these executables are generated by an unsupervised automatic\nprocedure, and we (as the authors and contributors) cannot guarantee to test\nthem. If you've encountered unusual failure caused by those executables, feel\nfree to open an issue, so we can take a look.\n\n[releases]: https://github.com/nirui/sshwifty/releases\n\n### Docker Image (recommended)\n\nDeploying Sshwifty as a [Docker] container allows you to isolate Sshwifty from\nthe rest of the system for better system organization and security.\n\nWe also offer prebuilt Docker Images for few selected platforms generated in the\nsame way as we generate the prebuilt Executables described above. To deploy one\non your Docker host, run:\n\n```shell\n$ docker run --detach \\\n  --restart unless-stopped \\\n  --publish 8182:8182 \\\n  --name sshwifty \\\n  niruix/sshwifty:latest\n```\n\n(Note: it's `niruix/sshwifty` with an `x`)\n\nThis will open port `8182` on the Docker host to accept traffic from all\nclients (including remote ones), and serve them with the Sshwifty instance\njust created.\n\nTo expose Sshwifty locally only to the Docker host, change the line\n`--publish 8182:8182` from the command above to `--publish 127.0.0.1:8182:8182`.\nThis is useful for scenarios where you want to force remote clients to access\nSshwifty only though a reverse proxy, or just simply want to prevent remote\naccess.\n\nWhen TLS is desired and you don't want to setup Docker Volumes, you can use\n`SSHWIFTY_DOCKER_TLSCERT` and `SSHWIFTY_DOCKER_TLSCERTKEY` environment variables\nto import certificate files to the container and automatically apply them:\n\n```shell\n$ openssl req \\\n  -newkey rsa:4096 -nodes -keyout domain.key -x509 -days 90 -out domain.crt\n$ docker run --detach \\\n  --restart always \\\n  --publish 8182:8182 \\\n  --env SSHWIFTY_DOCKER_TLSCERT=\"$(cat domain.crt)\" \\\n  --env SSHWIFTY_DOCKER_TLSCERTKEY=\"$(cat domain.key)\" \\\n  --name sshwifty \\\n  niruix/sshwifty:latest\n```\n\nThe `domain.crt` and `domain.key` in the command above is the location of valid\nX509 certificate and key file.\n\nThough, in most situations where a reverse proxy and/or load balancer (for\nexample, [Nginx] or [Traefik]) is used in front of Sshwifty instances, TLS\nshould usually terminate on the proxy, not on the individual Sshwifty instances.\n\n[Docker]: https://www.docker.com\n[Nginx]: https://github.com/nginx/nginx\n[Traefik]: https://github.com/traefik/traefik\n\n### Compile from source code (recommended for developers)\n\nThe following tools are required in order to compile the software from source\ncode:\n\n- `git` to download the source code\n- `node` and `npm` to build front-end application\n- `go` to build back-end application\n\nTo start the build process, run:\n\n```shell\n$ git clone https://github.com/nirui/sshwifty\n$ cd sshwifty\n$ npm install\n$ npm run build\n```\n\nWhen done, you can find the newly generated `sshwifty` binary under current\nworking directory.\n\nNotice: `Dockerfile` contains the entire build procedure of this software.\nPlease refer to it when you encounter any compile/build related issue.\n\n### Third-party Homebrew Formulae from [@unbeatable-101]\n\nIf you're a macOS user, [@unbeatable-101] is kindly hosting a Homebrew\nFormulae that allows you to install his custom Sshwifty builds for macOS via\n`homebrew`. You can hop over to [unbeatable-101/homebrew-sshwifty] for detailed\ninstruction and contribute to his work.\n\nPlease note that, due to the third-party nature of the work, the author(s) of\nSshwifty are unable to provide any audit, warranty or support for it. If you\nhave any question or request regarding to the Formulae, please contact\n[@unbeatable-101] directly through appreciate channels.\n\nThank [@unbeatable-101] for his work.\n\n[@unbeatable-101]: https://github.com/unbeatable-101\n[unbeatable-101/homebrew-sshwifty]: https://github.com/unbeatable-101/homebrew-sshwifty\n\n## Configuration\n\nSshwifty can be configured through either file or environment variables. By\ndefault, the configuration loader will try to load file from default paths\nfirst, when all failed, environment variables will be used.\n\nYou can also specify your own configuration file with `SSHWIFTY_CONFIG`\nenvironment variable. For example:\n\n```shell\n$ SSHWIFTY_CONFIG=./sshwifty.conf.json ./sshwifty\n```\n\nThis tells Sshwifty to only load configuration from file `./sshwifty.conf.json`.\n\n### Configuration file option and descriptions\n\nHere is all the options of the configuration file:\n\n```jsonc\n{\n  // HTTP Host. Keep it empty to accept request from all hosts, otherwise, only\n  // specified host is allowed to access\n  \"HostName\": \"localhost\",\n\n  // Web interface access password. Set to empty to allow public access to the\n  // web interface (By pass the Authenticate page)\n  \"SharedKey\": \"WEB_ACCESS_PASSWORD\",\n\n  // Remote dial timeout. This limits how long of time the backend can spend\n  // to connect to a remote host. The max timeout will be determined by\n  // server configuration (ReadTimeout).\n  // (In Seconds)\n  \"DialTimeout\": 10,\n\n  // Socks5 proxy. When set, Sshwifty backend will try to connect remote through\n  // the given proxy\n  \"Socks5\": \"localhost:1080\",\n\n  // Username of the Socks5 server. Please set when needed\n  \"Socks5User\": \"\",\n\n  // Password of the Socks5 server. Please set when needed\n  \"Socks5Password\": \"\",\n\n  // Server side hooks, allowing operator to launch external processes on the\n  // server side to influence server behaver\n  //\n  // The operation of a Hook must be completed within the time limit defined\n  // by `HookTimeout` set below. Otherwise it will be terminated, and results\n  // a failure for the execution\n  //\n  // To determine how much time is still left for the execution, a Hook can\n  // fetch the deadline information from the `SSHWIFTY_HOOK_DEADLINE`\n  // environment variable which is a RFC3339 formatted date string indicating\n  // after what time the termination will occur\n  //\n  // Warning: the process will be launched within the same context and system\n  // permission which Sshwifty is running under, thus is it crucial that the\n  // Hook process is designed and operated in a secure manner, otherwise\n  // SECURITY VULNERABILITY (commandline injection, for example) maybe created\n  // as result\n  //\n  // Warning: all inputs passed by Sshwifty to the hook process must be\n  // considered unsanitized, and must be sanitized by each hook themselves\n  \"Hooks\": {\n    // before_connecting is called before Sshwifty starts to connect to a remote\n    // endpoint. If any of the Hook process exited with a non-zero return code,\n    // the connection request is aborted\n    //\n    // This Hook offers two parameters:\n    // - SSHWIFTY_HOOK_REMOTE_TYPE: Type of the connection (i.e. SSH or Telnet)\n    // - SSHWIFTY_HOOK_REMOTE_ADDRESS: Address of the remote host\n    \"before_connecting\": [\n      // Following example command launches a `/bin/sh` to execute a for loop\n      // that prints to Stdout as well as to Stderr\n      //\n      // Prints to Stdout will be sent to the client side visible to the user,\n      // and prints to Stderr will be captured as server side logs and it is\n      // invisible to the user (as server logs usually are)\n      //\n      // The command must be specified in Json array format. Each array element\n      // is mapped to a command fragment separated by space. For example:\n      // [\"command\", \"-i\", \"Hello World\"] will be mapped to `command -i \"Hello\n      // World\"` before it is executed\n      [\n        \"/bin/sh\",\n        \"-c\",\n        \"for n in $(seq 1 5); do sleep 1 \u0026\u0026 echo Stdout $SSHWIFTY_HOOK_REMOTE_TYPE $n \u0026\u0026 echo Stderr $SSHWIFTY_HOOK_REMOTE_TYPE $n 1\u003e\u00262; done\"\n      ],\n      // You can add multiple hooks, they're executed in sequence even when the\n      // previous one fails\n      [\n        \"/bin/sh\",\n        \"-c\",\n        \"/etc/sshwifty/before_connecting.sh\"\n      ],\n      [\n        \"/bin/another-command\",\n        \"...\",\n        \"...\"\n      ]\n    ]\n  },\n\n  // The maximum execution time of each hook, in seconds. If this timeout is \n  // exceeded, the hook will be terminated, and thus cause a failure\n  \"HookTimeout\": 30,\n\n  // Sshwifty HTTP server, you can set multiple ones to serve on different\n  // ports\n  \"Servers\": [\n    {\n      // Which local network interface this server will be listening\n      \"ListenInterface\": \"0.0.0.0\",\n\n      // Which local network port this server will be listening\n      \"ListenPort\": 8182,\n\n      // Timeout of initial request. HTTP handshake must be finished within\n      // this time\n      // (In Seconds)\n      \"InitialTimeout\": 10,\n\n      // How long do the connection can stay in idle before the backend server\n      // disconnects the client\n      // (In Seconds)\n      \"ReadTimeout\": 120,\n\n      // How long the server will wait until the client connection is ready to\n      // recieve new data. If this timeout is exceed, the connection will be\n      // closed.\n      // (In Seconds)\n      \"WriteTimeout\": 120,\n\n      // The interval between internal echo requests\n      // (In Seconds)\n      \"HeartbeatTimeout\": 10,\n\n      // Forced delay between each request\n      // (In Milliseconds)\n      \"ReadDelay\": 10,\n\n      // Forced delay between each write\n      // (In Milliseconds)\n      \"WriteDelay\": 10,\n\n      // Path to TLS certificate file. Set empty to use HTTP\n      \"TLSCertificateFile\": \"\",\n\n      // Path to TLS certificate key file. Set empty to use HTTP\n      \"TLSCertificateKeyFile\": \"\",\n      \n      // Display a short text message on the Home page. Link is supported \n      // through `[Title text](https://link.example.com)` format\n      \"ServerMessage\": \"\"\n    },\n    {\n      \"ListenInterface\": \"0.0.0.0\",\n      \"ListenPort\": 8182,\n      \"InitialTimeout\": 3,\n      .....\n    }\n  ],\n\n  // Remote Presets, the operater can define few presets for user so the user\n  // won't have to manually fill-in all the form fields\n  //\n  // Presets will be displayed in the \"Known remotes\" tab on the Connector\n  // window\n  //\n  // Notice: You can use the same JSON value for `SSHWIFTY_PRESETS` if you are\n  //         configuring your Sshwifty through enviroment variables.\n  //\n  // Warning: Presets Data will be sent to user client WITHOUT any protection.\n  //          DO NOT add any secret information into Preset.\n  //\n  \"Presets\": [\n    {\n      // Title of the preset\n      \"Title\": \"SDF.org Unix Shell\",\n\n      // Preset Types, i.e. Telnet, and SSH\n      \"Type\": \"SSH\",\n\n      // Target address and port\n      \"Host\": \"sdf.org:22\",\n\n      // Define the tab and background color of the console in RGB hex format\n      // for better visual identification\n      //\n      // For example: 110000 will give you a dark red background, 001100 is\n      // dark green and 000011 is dark blue\n      //\n      // The color must not be too bright, as it will make the foreground text\n      // hard to read\n      \"TabColor\": \"112233\",\n\n      // Form fields and values, you have to manually validate the correctness\n      // of the field value\n      //\n      // Defining a Meta field will prevent user from changing it on their\n      // Connector Wizard. If you want to allow users to use their own settings,\n      // leave the field unsetted\n      //\n      // Values in Meta are scheme enabled, and supports following scheme\n      // prefixes:\n      // - \"literal://\": Text literal (Default)\n      //                 Example: literal://Data value\n      //                          (The final value will be \"Data value\")\n      //                 Example: literal://file:///tmp/afile\n      //                          (The final value will be \"file:///tmp/afile\")\n      // - \"file://\": Load Meta value from given file.\n      //              Example: file:///home/user/.ssh/private_key\n      //                       (The file path is /home/user/.ssh/private_key)\n      // - \"environment://\": Load Meta value from an Environment Variable.\n      //                    Example: environment://PRIVATE_KEY_DATA\n      //                    (The name of the target environment variable is\n      //                    PRIVATE_KEY_DATA)\n      //\n      // All data in Meta is loaded during start up, and will not be updated\n      // even the source already been modified.\n      //\n      \"Meta\": {\n        // Data for predefined User field\n        \"User\": \"pre-defined-username\",\n\n        // Data for predefined Encoding field. Valid data is those displayed on\n        // the page\n        \"Encoding\": \"pre-defined-encoding\",\n\n        // Data for predefined Password field\n        \"Password\": \"pre-defined-password\",\n\n        // Data for predefined Private Key field, should contains the content\n        // of a Key file\n        \"Private Key\": \"file:///home/user/.ssh/private_key\",\n\n        // Data for predefined Authentication field. Valid values is what\n        // displayed on the page (Password, Private Key, None)\n        \"Authentication\": \"Password\",\n\n        // Data for server public key fingerprint. You can acquire the value of\n        // the fingerprint by manually connect to a new SSH host with Sshwifty,\n        // the fingerprint will be displayed on the Fingerprint comformation\n        // page.\n        \"Fingerprint\": \"SHA256:bgO....\"\n      }\n    },\n    {\n      \"Title\": \"Endpoint Telnet\",\n      \"Type\": \"Telnet\",\n      \"Host\": \"endpoint.nirui.org:23\",\n      \"Meta\": {\n        // Data for predefined Encoding field. Valid data is those displayed on\n        // the page\n        \"Encoding\": \"utf-8\"\n        ....\n      }\n    },\n    ....\n  ],\n\n  // Allow the Preset Remotes only, and refuse to connect to any other remote\n  // host\n  //\n  // NOTICE: You can only configure OnlyAllowPresetRemotes through a config\n  //         file. This option is not supported when you are configuring with\n  //         environment variables\n  \"OnlyAllowPresetRemotes\": false\n}\n```\n\n`sshwifty.conf.example.json` is an example of a valid configuration file, you\ncan make your own customization base on it.\n\n### Environment variables\n\nValid environment variables are:\n\n```\nSSHWIFTY_HOSTNAME\nSSHWIFTY_SHAREDKEY\nSSHWIFTY_DIALTIMEOUT\nSSHWIFTY_SOCKS5\nSSHWIFTY_SOCKS5_USER\nSSHWIFTY_SOCKS5_PASSWORD\nSSHWIFTY_HOOK_BEFORE_CONNECTING\nSSHWIFTY_HOOKTIMEOUT\nSSHWIFTY_LISTENPORT\nSSHWIFTY_INITIALTIMEOUT\nSSHWIFTY_READTIMEOUT\nSSHWIFTY_WRITETIMEOUT\nSSHWIFTY_HEARTBEATTIMEOUT\nSSHWIFTY_READDELAY\nSSHWIFTY_WRITEELAY\nSSHWIFTY_LISTENINTERFACE\nSSHWIFTY_TLSCERTIFICATEFILE\nSSHWIFTY_TLSCERTIFICATEKEYFILE\nSSHWIFTY_SERVERMESSAGE\nSSHWIFTY_PRESETS\nSSHWIFTY_ONLYALLOWPRESETREMOTES\n```\n\nThese options are correspond to their counterparts in the configuration file.\n\n`SSHWIFTY_PRESETS` is a bit special because it should contain valid JSON\nencoded Preset data. An sample of it's format is demonstrated in the\n[`preset.example.json`] file and can be loaded via `cat` command. For example:\n\n    SSHWIFTY_PRESETS=$(cat preset.example.json) ./sshwifty\n\nOf course, you can also directly setup `SSHWIFTY_PRESETS` with a string. But in\nsuch case, you might need to escape the JSON characters. To do that, one option\nis to use `jq`:\n\n    cat preset.example.json | jq -c | jq -Rs\n\nWhich should give you one line of escaped JSON string, safe for use in scripts.\n\n[`preset.example.json`]: preset.example.json\n\nNotice: When you're using environment variables to configure Sshwifty, only one\nSshwifty HTTP server is then allowed. There is no way to setup multiple servers\nunder this method of configuration. If you need to serve on multiple ports, use\nthe configuration file instead.\n\nBe aware: An invalid value inside following environment variables will cause\nthe value to be silently reset to default during configuration parsing phase\nwithout warning:\n\n```\nSSHWIFTY_DIALTIMEOUT\nSSHWIFTY_INITIALTIMEOUT\nSSHWIFTY_READTIMEOUT\nSSHWIFTY_WRITETIMEOUT\nSSHWIFTY_HEARTBEATTIMEOUT\nSSHWIFTY_READDELAY\nSSHWIFTY_WRITEELAY\n```\n\nPlease verify the value of these options before start the instance.\n\n## FAQ\n\n### Why the software says \"The datetime difference ... is beyond tolerance\"?\n\nCurrently, Sshwifty implemented a layer of obscuration in it's wire protocol.\nThe protocol utilize the common time of both endpoint to generate cryptographic\nkeys to be used to encrypt and decrypt traffic between the client and the\nserver. Thus both end must have accurate datetime relative to the time of the\nworld.\n\nPlease make sure the datetime on both the client and the server are correct by\nresync them with a NTP server, and then simply reload the page. The problem\nshould be gone afterwards.\n\n### Why I got error \"TypeError: Cannot read property 'importKey' of undefined\"\n\nSshwifty's wire protocol requires few cryptographic features which is only\navailable with WebCrypt API. Some old web browsers maybe not support WebCrypt\nAPI, or the newer ones may disable WebCrypt API when the web page is not\naccessed under [Secure contexts], which led to the error message.\n\n[Secure Contexts]: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts\n\nUsually, setup HTTPS either on your reverse proxy or on Sshwifty itself should\nallow you to access Sshwifty via HTTPS (a `https://` URL), and thus solving this\nissue. Also, enabling HTTPS is mostly a good idea anyways, even in a LAN.\n\n### Can I serve Sshwifty under a subpath such as `https://my.domain/ssh`?\n\nThe short story is No. Sshwifty was designed based on an assumption that it will\nrun as the only service under a given hostname, allowing web browsers to better\nenforce their data isolation rules. This is very important because Sshwifty\nsaves user data locally, right on the web browser.\n\nHowever, if you really want to put Sshwifty into a subpath, you can do so by\ntaking advantage of the fact that Sshwifty backend interface and assets are\nalways located under an URL prefix `/sshwifty`. You can thus redirect or proxy\nthose requests to their new location.\n\nKeep in mind, doing so is really hacky, and it's not recommended by the author\nthus no support will be provided if you decide to do so.\n\n### Why I can't add my own key combinations to the Console tool bar?\n\nThe pre-defined key combinations are there mainly to make mobile operation\npossible as well as to resolve some hotkey conflicts. However, if efficiency is\nyour first goal, please consider to use a software/on screen keyboard which is\nspecially designed for terminal.\n\nAnd if that's not enough, connect a physical keyboard through Bluetooth or OTA\ncould be a better alternative. This way you can type as if you're using a\ncomputer console.\n\n## Credits\n\n- Thanks to [Ryan Fortner](https://github.com/ryanfortner) for the grammar fix\n- Thanks to [Tweak](https://github.com/Tweak4141) for the grammar fix\n- Thanks to [CJendantix](https://github.com/CJendantix) for the grammar and typo \n  fix\n- Thanks to [ZStrikeGit](https://github.com/ZStrikeGit) for the grammar and \n  formatting fixes\n\n## License\n\nCode of this project is licensed under AGPL, see [LICENSE.md] for detail.\n\nThird-party components used by this project are licensed under their respective\nlicenses. See [DEPENDENCIES.md] to learn more about dependencies used by this\nproject and read their copyright statements.\n\n[LICENSE.md]: LICENSE.md\n[DEPENDENCIES.md]: DEPENDENCIES.md\n\n## Contribute\n\nThis is a hobbyist project, meaning I don't have that much time to put into it, \nsorry.\n\nUpon release (Which is then you're able to read this file), this project will\nenter the _maintaining_ state, which includes doing some bug fixes and security \nupdates. _Adding new features however, is not a part of the state_.\n\nPlease do not send any pull requests. If you need new feature, fork it, add it \nby yourself, then maintain it like one of your own project. It's not that hard \nwith some Github features.\n\n(Notice: Typos, grammar errors or invalid use of language in the source code and\ndocumentation should be categorized as a bug, please report them if you find \nany. Thank you!)\n\nAppreciate your help, enjoy!\n","funding_links":[],"categories":["Apps","JavaScript","Operation System","置顶","Software","HarmonyOS"],"sub_categories":["Development","Monitoring","05、运维监控体系","Gateways and Terminal Sharing","Remote Access","Windows Manager"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnirui%2Fsshwifty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnirui%2Fsshwifty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnirui%2Fsshwifty/lists"}