{"id":30226410,"url":"https://github.com/johnsonjh/dps8m-proxy","last_synced_at":"2025-08-14T16:41:24.912Z","repository":{"id":304434871,"uuid":"1018740454","full_name":"johnsonjh/dps8m-proxy","owner":"johnsonjh","description":"dps8m-proxy: High performance SSH⟷TELNET proxy and gateway","archived":false,"fork":false,"pushed_at":"2025-08-04T00:15:52.000Z","size":1508,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-04T02:37:45.028Z","etag":null,"topics":["dps8","dps8m","proxy","relay","ssh","telnet","terminal-server"],"latest_commit_sha":null,"homepage":"https://gitlab.com/dps8m/proxy","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnsonjh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2025-07-12T23:50:53.000Z","updated_at":"2025-08-02T00:01:36.000Z","dependencies_parsed_at":"2025-07-27T19:20:43.833Z","dependency_job_id":null,"html_url":"https://github.com/johnsonjh/dps8m-proxy","commit_stats":null,"previous_names":["johnsonjh/dps8m-proxy"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/johnsonjh/dps8m-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Fdps8m-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Fdps8m-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Fdps8m-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Fdps8m-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnsonjh","download_url":"https://codeload.github.com/johnsonjh/dps8m-proxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnsonjh%2Fdps8m-proxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270451394,"owners_count":24586128,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-14T02:00:10.309Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["dps8","dps8m","proxy","relay","ssh","telnet","terminal-server"],"created_at":"2025-08-14T16:41:21.907Z","updated_at":"2025-08-14T16:41:24.886Z","avatar_url":"https://github.com/johnsonjh.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# proxy\n\n\u003c!-- Copyright (c) 2025 Jeffrey H. Johnson --\u003e\n\u003c!-- Copyright (c) 2025 The DPS8M Development Team --\u003e\n\u003c!-- SPDX-License-Identifier: MIT --\u003e\n\u003c!-- scspell-id: 698e77d8-6bd2-11f0-9441-80ee73e9b8e7 --\u003e\n\u003c!-- NB: Do not modify README.md directly; modify README.md.tmpl --\u003e\n\n[![Go Report Card](https://goreportcard.com/badge/gitlab.com/dps8m/proxy)](https://goreportcard.com/report/gitlab.com/dps8m/proxy)\n[![Pipeline Status](https://gitlab.com/dps8m/proxy/badges/master/pipeline.svg)](https://gitlab.com/dps8m/proxy/-/pipelines/)\n[![CodeQL](https://github.com/johnsonjh/dps8m-proxy/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/johnsonjh/dps8m-proxy/actions/workflows/github-code-scanning/codeql)\n[![Dependabot Updates](https://github.com/johnsonjh/dps8m-proxy/actions/workflows/dependabot/dependabot-updates/badge.svg)](https://github.com/johnsonjh/dps8m-proxy/actions/workflows/dependabot/dependabot-updates)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=johnsonjh_dps8m-proxy\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=johnsonjh_dps8m-proxy)\n[![REUSE status](https://api.reuse.software/badge/gitlab.com/dps8m/proxy)](https://api.reuse.software/info/gitlab.com/dps8m/proxy)\n\n## Overview\n\nThe **`proxy`** program acts as a multi‑user *terminal server* and\nrelay 📡, accepting incoming **SSH** client connections on the\nfront‑end (*listeners* 👂) and proxying these connections to one or\nmore **TELNET** servers on the back‑end (*targets* 🎯).\n\n\u003e This project was originally developed to meet the needs of the\n\u003e *BAN.AI Public Access Multics* system and the\n\u003e [DPS8M Simulator](https://dps8m.gitlab.io) project, but may be\n\u003e useful to anyone who wants to offer SSH access to legacy systems.\n\n## Features\n\n* ✅ SSH ⟷ TELNET gateway\n* ✅ Full IPv6 support\n* ✅ Access control whitelist/blacklist (by IP address or CIDR block)\n* ✅ Independent console and session logging (by date/time and host)\n* ✅ Automatic log‑file compression (using gzip, xz, or zstandard)\n* ✅ Banners for accepted, denied, and blocked connections (configurable per target)\n* ✅ Session connection monitoring and idle time tracking (with optional timeouts)\n* ✅ Translation of SSH `window‑change` events to TELNET NAWS messages\n* ✅ Interactive connection management for administrators\n* ✅ User access to TELNET features (*e.g.*, line BREAK, AYT) and statistics\n* ✅ Transparent key remapping mode (translating movement keys to Emacs sequences)\n* ✅ Optional support for management using `systemd` on Linux (running in a sandbox)\n* ✅ Optional mDNS-SD (Multicast DNS Service Discovery) announcements for listeners\n* ✅ Link filtering\n* ✅ Live streaming connection sharing (read‑only)\n  * 🤝 Allows users to share their session with one or more viewers\n\n## Installation\n\n### Binaries\n\n * We currently publish more than 40 binaries supporting 13\n   operating systems (IBM AIX, IBM i, Android, Apple macOS, Dragonfly\n   BSD, FreeBSD, illumos, Linux, NetBSD, OpenBSD, Plan 9, Solaris, and\n   Microsoft Windows) on 14 hardware architectures.\n   * You can download pre-compiled binaries for all of these systems\n     (except IBM i) from\n     **[`https://dps8m.gitlab.io/proxy/`](https://dps8m.gitlab.io/proxy/)**.\n   * Look [**here**](https://gitlab.com/dps8m/proxy/-/snippets) if you\n     need binaries for [IBM i](https://www.ibm.com/products/ibm-i)\n     (OS/400) that run under the\n     [PASE](https://www.ibm.com/docs/en/i/latest?topic=i-pase-overview)\n     subsystem.\n\n### Source\n\nA recent version of [Go](https://go.dev/) 🐹 is required to build\n`proxy` from source code.\n\n* You can clone the\n  [`git` repository](https://gitlab.com/dps8m/proxy.git) 🌱 and build\n  the source code using `make`:\n\n  ```sh\n  git clone https://gitlab.com/dps8m/proxy.git\n  cd proxy\n  make\n  ```\n\n  * If you don’t have a (POSIX) `make` available for some\n    reason, then building with `go build` is sufficient.\n\n  * A [`.cross.sh`](.cross.sh) cross‑compilation helper script is\n    provided (which can be called with `make cross`) that attempts to\n    build `proxy` binaries for *all* supported `GOOS` and `GOARCH`\n    combinations.\n\n* You can also install this software using `go install` 📦:\n\n  ```sh\n  go install gitlab.com/dps8m/proxy@latest\n  ```\n\n  * Installations using `go install` download the required sources,\n    compile, and install the binary to `${GOEXE}/proxy` (which will\n    be `${HOME}/go/bin/proxy` for most users).\n\n## Usage\n\n### Invocation\n\n* The `proxy` command can be invoked with the following command‑line\n  arguments:\n\n```plaintext\nDPS8M Proxy v0.1.10 (2025-Aug-13 g3e6e439) [linux/amd64]\n\nUsage for /home/jhj/dps8m-proxy/proxy:\n\n      --allow-root              Allow running as root (UID 0)\n      --cert-dir string         Directory containing SSH host certificates\n                                    (default: current working directory)\n      --cert-perm octal         Permissions (octal) for new certificate files\n                                    [e.g., \"600\", \"644\"] (default 600)\n      --ssh-addr strings        SSH listener address(es)\n                                    [e.g., \":2222\", \"[::1]:8000\"]\n                                    (multiple allowed) (default \":2222\")\n      --ssh-delay float         Delay for incoming SSH connections\n                                    [\"0.0\" to \"30.0\" seconds] (no default)\n      --no-banner               Disable SSH connection banner\n      --telnet-host string      Default TELNET target [host:port]\n                                    (default \"127.0.0.1:6180\")\n      --alt-host string         Alternate TELNET target(s) [sshuser@host:port]\n                                    (multiple allowed)\n      --debug-telnet            Debug TELNET option negotiation\n      --debug-server string     Enable HTTP debug server listening address\n                                    [e.g., \":6060\", \"[::1]:6060\"]\n      --gops                    Enable the \"gops\" diagnostic agent\n                                    (see https://github.com/google/gops)\n      --mdns                    Enable mDNS (Multicast DNS Service Discovery)\n                                    (i.e., Bonjour, Avahi) announcements\n      --log-dir string          Base directory for logs (default \"log\")\n      --no-log                  Disable all session logging\n                                    (for console logging see \"--console-log\")\n      --console-log string      Enable console logging [\"quiet\", \"noquiet\"]\n                                    (disabled by default)\n      --compress-algo string    Compression algorithm [\"gzip\", \"xz\", \"zstd\"]\n                                    (default \"gzip\")\n      --compress-level string   Compression level for gzip and zstd algorithms\n                                    [\"fast\", \"normal\", \"high\"]\n                                    (default \"normal\")\n      --no-compress             Disable session and/or console log compression\n      --log-perm octal          Permissions (octal) for new log files\n                                    [e.g., \"600\", \"644\"] (default 600)\n      --log-dir-perm octal      Permissions (octal) for new log directories\n                                    [e.g., \"755\", \"750\"] (default 750)\n      --db-file string          Path to persistent statistics storage database\n                                    (disabled by default)\n      --db-time uint            Elapsed seconds between database updates\n                                    [0 disables periodic writes] (default 30)\n      --db-perm octal           Permissions (octal) for new database files\n                                    [e.g., \"600\", \"644\"] (default 600)\n      --db-loglevel string      Database engine (BBoltDB) logging output level\n                                    [level: \"0\" - \"6\", or \"none\" - \"debug\"]\n                                    (default \"error\")\n      --idle-max int            Maximum connection idle time allowed [seconds]\n      --time-max int            Maximum connection link time allowed [seconds]\n      --blacklist string        Enable blacklist [filename] (no default)\n      --whitelist string        Enable whitelist [filename] (no default)\n      --utc                     Use UTC (Coordinated Universal Time) for time\n                                    display and timestamping in log files\n      --license                 Show license terms and conditions\n      --version                 Show version information\n      --help                    Show this help and usage information\n\nproxy home page (bug reports): \u003chttps://gitlab.com/dps8m/proxy/\u003e\n```\n\nMost of these command‑line arguments are straightforward with\nusage that should be obvious, and those that require demystification\nare, hopefully, documented here:\n\n* Logging of sessions is *enabled* by default.  Logging of console\n  messages is *disabled* by default.\n\n  * Console logging, if enabled, supports two modes: `quiet` and\n    `noquiet`.  In `quiet` mode, all non‑fatal messages are logged\n    **only** to the log file, where in `noquiet` mode, messages are\n    logged to **both** the console and the log file.\n\n  * By default, the local time zone is used for time display and\n    writing log files.  Users can specify the `‑‑utc` option to use\n    UTC (Coordinated Universal Time) instead.  Additionally, on\n    Unix-like systems, the `TZ` environment variable is respected.\n\n  * If the proxy fails to create log directories or files, a warning\n    will be displayed on the console and the session and/or console\n    logging feature *may* be (but is not guaranteed to be) disabled.\n    In a future version, this behavior will be configurable (*e.g.,*\n    allow to either immediately or gracefully exit on logging failure).\n\n* Enabling the database (with the `‑‑db-file` option) persists to disk\n  the connection statistics (viewable with the `s` admin console\n  command) so the stats are not lost when restarting the proxy.  It\n  is customary to use a name ending with the extension `db` (*e.g.,*\n  `proxy.db`).\n\n* All incoming SSH users are connected to the default TELNET target,\n  unless their supplied SSH username matches an alternate target\n  enabled with the `‑‑alt‑host` flag.  The alt‑host syntax is\n  `sshuser@host:port`, where `sshuser` is the SSH username, and the\n  `host:port` is the TELNET target.\n\n* All users connecting with SSH are shown a banner which includes\n  details such as the date and time of the session, their IP address,\n  and possibly a resolved host name.  This can be disabled with\n  `‑‑no‑banner`.\n\n* The `‑‑no‑banner` command disables only those lines described above.\n  It does *not* disable the file‑based banner content.  These are the\n  three primary text files which can be displayed to connecting\n  SSH users:\n\n  | File        | Purpose                                                                   |\n  |------------:|:--------------------------------------------------------------------------|\n  | `block.txt` | Displayed before disconnecting connections matching the blacklist         |\n  | `deny.txt`  | Displayed when denying target sessions (*e.g.*, during graceful shutdown) |\n  | `issue.txt` | Displayed to users before their actual session with the target begins     |\n\n  * When multiple are targets defined using the `‑‑alt‑host`\n    functionality, the system will display a file that matches `‑NAME`\n    before the `.txt` extension.  For example, if you have defined a\n    target as  `oldunix@10.0.5.9:3333` the proxy will look for\n    `block‑oldunix.txt`, `deny‑oldunix.txt`, and `issue‑oldunix.txt`\n    files to serve to the connected user, before beginning their\n    session with the target (via TELNET to `10.0.5.9:3333`).  If any\n    of the target‑specific text files do not exist, then the standard\n    files will be served.\n  * To disable the file‑based banner for specific targets only, you\n    can create empty files using the naming scheme described above.\n    You can also remove *all* of these files if you don’t want to\n    use this functionality.\n\n* You need to start `proxy` using the `‑‑whitelist` and/or\n  `‑‑blacklist` argument to enable the access control functionality.\n  If *only* the whitelist is enabled, then all connections will be\n  denied by default.  Note that if *only* the whitelist is enabled, it\n  will be impossible to exempt individual IP addresses within a range\n  that has been blocked.  It is recommended that you *both* lists\n  when using the access control feature.\n\n  * The format of the whitelist and blacklist is an IPv4 or IPv6\n    address (*e.g.*, `23.215.0.138`, `2600:1406:bc00:53::b81e:94ce`),\n    or a CIDR block (*e.g.*, `123.45.0.0/17` which covers `123.45.0.0`\n    to `123.45.127.255`, or `2600:1408:ec00:36::/64` covering\n    `2600:1408:ec00:36:0000:0000:0000:0000` to\n    `2600:1408:ec00:36:ffff:ffff:ffff:ffff`).\n\n  * The whitelist always takes precedence over the blacklist.\n    If an address is allowed due to a whitelist match that would\n    have otherwise been blocked by the blacklist, it is tagged as\n    `EXEMPTED` in the logs.\n\n* The `‑v` or `‑‑version` command shows detailed version information,\n  including the versions of any embedded dependencies as well as the\n  version of the Go compiler used to build the software:\n\n```plaintext\nDPS8M Proxy v0.1.10 (2025-Aug-13 g3e6e439) [linux/amd64]\n\n+===========================+==================================+\n| Component                 | Version                          |\n+===========================+==================================+\n| dps8m/proxy               | v0.1.10                          |\n| arl/statsviz              | v0.7.1                           |\n| google/gops               | v0.3.29* (2025-May-14, ga2d8f77) |\n| gorilla/websocket         | v1.5.3                           |\n| hashicorp/mdns            | v1.0.6                           |\n| klauspost/compress        | v1.18.0                          |\n| miekg/dns                 | v1.1.68                          |\n| spf13/pflag               | v1.0.7                           |\n| ulikunitz/xz              | v0.5.12                          |\n| go.etcd.io/bbolt          | v1.4.2                           |\n| golang.org/x/crypto       | v0.41.0                          |\n| golang.org/x/net          | v0.43.0                          |\n| golang.org/x/sys          | v0.35.0                          |\n| golang.org/x/term         | v0.34.0                          |\n| kernel.org/.../libcap/cap | v1.2.76                          |\n| kernel.org/.../libcap/psx | v1.2.76                          |\n| Go compiler (gc)          | v1.25.0                          |\n+===========================+==================================+\n```\n\n* If you need to see additional details about the `proxy` binary,\n  you can run `go version ‑m proxy`.\n\n### Port binding\n\n* If you want to listen on the regular SSH port of 22 (without\n  running as `root`, which is strongly discouraged), on Linux systems\n  you can use `setcap` to allow the proxy to bind to privileged ports:\n\n  ```sh\n  sudo setcap 'cap_net_bind_service=+ep' \"/path/to/proxy\"\n  ```\n\n* If this is necessary (*i.e.*, a non‑root user on Linux is attempting\n  to bind an SSH listener to a privileged port and the\n  `CAP_NET_BIND_SERVICE` capability is not currently effective), the\n  software should provide a warning message with the above\n  instructions.\n\n### Admin interaction\n\n* The running proxy can be controlled interactively with the following\n  admin console commands:\n  * `?` — Show help text\n  * `c` — Show proxy configuration\n  * `v` — Show version details\n  * `s` — Show connection statistics\n  * `l` — List active connections\n  * `k` — Kill a connection\n  * `d` — Deny new connections\n  * `r` — Reload access control lists\n  * `q` — Graceful shutdown\n  * `Q` — Immediate shutdown (also via `^C`)\n[]()\n\n[]()\nMost of these admin console commands are straightforward and should\nbe self‑explanatory, although there are a few options that merit\nfurther clarification:\n\n* When the **Graceful shutdown** mode is active, all new connections\n  are denied (and are served an appropriate `deny.txt` banner).  Once\n  all clients have disconnected, the proxy software will exit.  Note\n  that new *monitoring sessions* can still connect to observe active\n  users, as these sessions are automatically closed when their\n  observation target disconnects.\n\n* When the **Deny new connections** mode is active, all new connections\n  are denied (and are served an appropriate `deny.txt` banner).  In\n  addition, *all logging* of new connection attempts, including any\n  denied and/or rejected connections, is suppressed.  This can be\n  useful when the logs or admin console are overwhelmed with activity\n  (such as during bot attacks, busy periods, or when troubleshooting).\n  Activating this mode can help reduce console noise, making it easier\n  to perform admin actions such as viewing the configuration, or\n  listing and killing active connections.\n\n* The `k` command, which kills a connection, takes either a\n  *Session ID* as an argument (shown when listing active connections\n  with the `l` command) or `*`, which kills *all* active connections.\n\nIf it is detected that you have a UTF-8 capable terminal, then some\nconsole output will be augmented with icons or emoji glyphs (and in\na future version, UTF-8 box drawing symbols will be used for drawing\ntables).\n\n### Signals\n\n* The proxy also acts on the following signals (on systems where\n  signals are supported):\n\n  |      Signal | Action                                                             |\n  |------------:|:-------------------------------------------------------------------|\n  |    `SIGINT` | Enables the **Immediate shutdown** mode                            |\n  |   `SIGQUIT` | Enables the **Immediate shutdown** mode                            |\n  |   `SIGUSR1` | Enables the **Graceful shutdown** mode                             |\n  |   `SIGUSR2` | Enables the **Deny new connections** mode                          |\n  |    `SIGHUP` | Reloads *access control lists* (`‑‑whitelist`, `‑‑blacklist`)      |\n  | `SIGDANGER` | Attempts to immediately free as much memory as possible (AIX‑only) |\n\n### Management with systemd\n\nIf you’re running the proxy on a Linux system, you can use `systemd`\nto manage the service (while maintaining access to the interactive\nadmin console).\n\n* The `systemd` integration requires `systemd` version **247** or\n  later (Nov. 2020), and a *recent* version of\n  [`tmux`](https://github.com/tmux/tmux).\n[]()\n\n[]()\n* With minor changes 🔧 to the unit file, this setup can also work\n  with `systemd` as old as version **229** (Feb. 2016).\n* See the detailed instructions in the\n  [`systemd/dps8m‑proxy.service`](systemd/dps8m-proxy.service)\n  file for full installation instructions.\n\n### User interaction\n\nUsers connected via SSH can send `^]` (*i.e.*, `Control + ]`) during\ntheir session to access the following following TELNET control\nfeatures:\n\n* `]` — sends a literal `Control‑]` to the target TELNET host\n\n* `0` — sends a literal `NUL` to the target TELNET host\n\n* `A` — sends an IAC `AYT` (*Are You There?*) to the target TELNET host\n\n* `B` — sends an IAC `BREAK` signal to the target TELNET host\n\n* `I` — sends an IAC `INTERRUPT` signal to the target TELNET host\n\n* `K` — toggles the transparent key remapping mode, which translates\n  modern `xterm`/`VT320` movement key inputs to Emacs sequences:\n\n  |             Input | Output        |\n  |------------------:|:--------------|\n  | `Control + Up`    | `Escape, [`   |\n  | `Control + Down`  | `Escape, ]`   |\n  | `Control + Right` | `Escape, f`   |\n  | `Control + Left`  | `Escape, b`   |\n  | `Home`            | `Control + A` |\n  | `Delete`          | `Control + D` |\n  | `End`             | `Control + E` |\n  | `Up`              | `Escape + v`  |\n  | `Down`            | `Control + V` |\n  | `Up`              | `Control + P` |\n  | `Down`            | `Control + N` |\n  | `Right`           | `Control + F` |\n  | `Left`            | `Control + B` |\n\n* `N` — sends an IAC `NOP` (*No Operation*) to the target TELNET host\n\n* `S` — displays the status the session, sharing information, and some\n  statistics:\n\n  ```plaintext\n  \u003e\u003e LNK ‑ The username '_gRSyWHxPcMp2MWvtmWWF' can be used to share this session.\n  \u003e\u003e SSH ‑ in:   58 B,   out: 4.82 KiB, in rate:   4 B/s, out rate: 381 B/s\n  \u003e\u003e NVT ‑ in: 4.82 KiB, out:   57 B,   in rate: 381 B/s, out rate:   4 B/s\n  \u003e\u003e LNK ‑ link time: 13s (Emacs keymap enabled)\n  ```\n\n* `X` — disconnects from the target TELNET host (and ends the SSH\n  session)\n\n### Connection sharing\n\n* The user can share 🤝 the username presented above with others,\n  allowing the session to be viewed live 👀 (read‑only) by one or more\n  viewers:\n\n  ```sh\n  $ ssh _gRSyWHxPcMp2MWvtmWWF@proxybox\n\n  CONNECTION from remote.com [18.17.16.15] started at 2025/07/15 08:22:55.\n  This is a READ‑ONLY shared monitoring session.\n  Send Control‑] to disconnect.\n  ```\n\n## Compressed logs\n\n* By default, all session log files are compressed 🗜️ automatically\n  when the session terminates, and console log files are compressed\n  when the log rolls over (*i.e.*, when starting a new day).\n\n* When reviewing logs, administrators often need to search through all\n  the past data, including through the compressed files. We recommend\n  using [`ripgrep`](https://github.com/BurntSushi/ripgrep) (with the\n  `‑z` option) for this task.\n\n## Using OpenSSH host keys\n\nIf you have existing [OpenSSH](https://www.openssh.com/) Ed25519, RSA,\nor ECDSA host keys that you want to use with the proxy, you’ll first\nneed to convert those keys to standard PEM format.\n\n🚨 **NB**: These instructions *do not* include any specific details\nfor safe handling of key file permissions—we assume you are `root`\nand that you know what you’re doing!\n\n1. Make a *copy* of the key files you wish to convert.  Be aware that\n   these copies will be *overwritten* in the conversion process:\n\n   ```sh\n   cp /etc/ssh/ssh_host_ed25519_key ssh_host_ed25519_key.tmp\n   cp /etc/ssh/ssh_host_rsa_key ssh_host_rsa_key.tmp\n   cp /etc/ssh/ssh_host_ecdsa_key ssh_host_ecdsa_key.tmp\n   ```\n\n2. Convert the keys (using `ssh‑keygen`) and rename them appropriately:\n\n   ```sh\n   ssh-keygen -p -m PEM -N '' -P '' -f ssh_host_ed25519_key.tmp\n   ssh-keygen -p -m PEM -N '' -P '' -f ssh_host_rsa_key.tmp\n   ssh-keygen -p -m PEM -N '' -P '' -f ssh_host_ecdsa_key.tmp\n   mv ssh_host_ed25519_key.tmp ssh_host_ed25519_key.pem\n   mv ssh_host_rsa_key.tmp ssh_host_rsa_key.pem\n   mv ssh_host_ecdsa_key.tmp ssh_host_ecdsa_key.pem\n   ```\n\n## History\n\nThis is a from‑scratch re‑implementation (in [Go](https://go.dev/) 🐹)\nof an older legacy program of the same name.\n\nThe original software used a multi‑process architecture and consisted\nof nearly **15,000 lines** of haphazardly constructed code: ≅14,000\nlines of mostly [C‑Kermit](https://www.kermitproject.org/) 🐸 (*yes,\nthe\n[programming language](https://www.kermitproject.org/ckscripts.html)*)\nand [`ksh93`](https://github.com/ksh93/ksh) 🐚 (along with some C 💻,\nPython 🐍, and Perl 🐪) which was difficult to maintain, configure,\nand securely install.\n\nThis new implementation uses many lightweight *Goroutines* 🚀 instead\nof spawning multiple processes, resulting in significantly improved\nperformance and reduced system overhead.\n\n## Code statistics\n\nThe new `proxy` program is considerably simpler than its legacy\npredecessor (code statistics 📈 provided by\n[`scc`](https://github.com/boyter/scc)):\n\n\u003ctable id=\"scc-table\"\u003e\n\u003cthead\u003e\u003ctr\u003e\n\u003cth\u003eLanguage\u003c/th\u003e\n\u003cth\u003eFiles\u003c/th\u003e\n\u003cth\u003eLines\u003c/th\u003e\n\u003cth\u003eBlank\u003c/th\u003e\n\u003cth\u003eComment\u003c/th\u003e\n\u003cth\u003eCode\u003c/th\u003e\n\u003cth\u003eComplexity\u003c/th\u003e\n\u003cth\u003eBytes\u003c/th\u003e\n\u003cth\u003eUloc\u003c/th\u003e\n\u003c/tr\u003e\u003c/thead\u003e\n\u003ctbody\u003e\u003ctr\u003e\n\u003cth\u003eGo\u003c/th\u003e\n\u003cth\u003e16\u003c/th\u003e\n\u003cth\u003e7460\u003c/th\u003e\n\u003cth\u003e1536\u003c/th\u003e\n\u003cth\u003e359\u003c/th\u003e\n\u003cth\u003e5565\u003c/th\u003e\n\u003cth\u003e1319\u003c/th\u003e\n\u003cth\u003e182279\u003c/th\u003e\n\u003cth\u003e3330\u003c/th\u003e\n\u003c/tr\u003e\u003ctr\u003e\n\u003cth\u003eMakefile\u003c/th\u003e\n\u003cth\u003e1\u003c/th\u003e\n\u003cth\u003e435\u003c/th\u003e\n\u003cth\u003e70\u003c/th\u003e\n\u003cth\u003e77\u003c/th\u003e\n\u003cth\u003e288\u003c/th\u003e\n\u003cth\u003e80\u003c/th\u003e\n\u003cth\u003e14543\u003c/th\u003e\n\u003cth\u003e298\u003c/th\u003e\n\u003c/tr\u003e\u003ctr\u003e\n\u003cth\u003eMarkdown\u003c/th\u003e\n\u003cth\u003e1\u003c/th\u003e\n\u003cth\u003e552\u003c/th\u003e\n\u003cth\u003e105\u003c/th\u003e\n\u003cth\u003e0\u003c/th\u003e\n\u003cth\u003e447\u003c/th\u003e\n\u003cth\u003e0\u003c/th\u003e\n\u003cth\u003e26163\u003c/th\u003e\n\u003cth\u003e432\u003c/th\u003e\n\u003c/tr\u003e\u003ctr\u003e\n\u003cth\u003eShell\u003c/th\u003e\n\u003cth\u003e1\u003c/th\u003e\n\u003cth\u003e134\u003c/th\u003e\n\u003cth\u003e27\u003c/th\u003e\n\u003cth\u003e37\u003c/th\u003e\n\u003cth\u003e70\u003c/th\u003e\n\u003cth\u003e17\u003c/th\u003e\n\u003cth\u003e3801\u003c/th\u003e\n\u003cth\u003e90\u003c/th\u003e\n\u003c/tr\u003e\u003ctr\u003e\n\u003cth\u003eSystemd\u003c/th\u003e\n\u003cth\u003e1\u003c/th\u003e\n\u003cth\u003e209\u003c/th\u003e\n\u003cth\u003e35\u003c/th\u003e\n\u003cth\u003e107\u003c/th\u003e\n\u003cth\u003e67\u003c/th\u003e\n\u003cth\u003e0\u003c/th\u003e\n\u003cth\u003e7601\u003c/th\u003e\n\u003cth\u003e135\u003c/th\u003e\n\u003c/tr\u003e\u003ctr\u003e\n\u003cth\u003eYAML\u003c/th\u003e\n\u003cth\u003e1\u003c/th\u003e\n\u003cth\u003e86\u003c/th\u003e\n\u003cth\u003e6\u003c/th\u003e\n\u003cth\u003e10\u003c/th\u003e\n\u003cth\u003e70\u003c/th\u003e\n\u003cth\u003e0\u003c/th\u003e\n\u003cth\u003e3943\u003c/th\u003e\n\u003cth\u003e77\u003c/th\u003e\n\u003c/tr\u003e\u003c/tbody\u003e\n\u003ctfoot\u003e\u003ctr\u003e\n\u003cth\u003eTotal\u003c/th\u003e\n\u003cth\u003e21\u003c/th\u003e\n\u003cth\u003e8876\u003c/th\u003e\n\u003cth\u003e1779\u003c/th\u003e\n\u003cth\u003e590\u003c/th\u003e\n\u003cth\u003e6507\u003c/th\u003e\n\u003cth\u003e1416\u003c/th\u003e\n\u003cth\u003e238330\u003c/th\u003e\n\u003cth\u003e4346\u003c/th\u003e\n\u003c/tr\u003e\u003c/tfoot\u003e\u003c/table\u003e\n\n## Future plans\n\n* Some features of the legacy software are still missing in this\n  implementation and may be added in future updates.  These features\n  include text *CAPTCHA*s, load‑balancing, fail‑over,\n  [flow control](https://www.rfc-editor.org/rfc/rfc1372), SSH\n  targets, and TELNET listeners.\n* When users access an SSH listener, the connecting client may supply\n  a password or present public keys for authentication.  These\n  authentication attempts are currently logged, but are not\n  otherwise used by the proxy.  A future update may allow for\n  passwords and public keys to be used for pre‑authentication or to\n  influence target routing.\n[]()\n\n[]()\n* While TELNET protocol support will improve in the future, there are\n  no plans to support the\n  [linemode](https://www.rfc-editor.org/rfc/rfc1184),\n  [environment](https://www.rfc-editor.org/rfc/rfc1572),\n  [authentication](https://www.rfc-editor.org/rfc/rfc2941),\n  or [encryption](https://www.rfc-editor.org/rfc/rfc2946)\n  features at this time.\n  * If you need these features, you should look into\n    [C‑Kermit](https://kermitproject.org/) or\n    [Kermit 95](https://davidrg.github.io/ckwin/).\n  * Although directly executing programs isn’t something on the\n    roadmap, it’s not difficult to use `socat` creatively to connect\n    C‑Kermit to the proxy (*i.e.*,\n    `socat TCP‑LISTEN:9876,fork,reuseaddr,nodelay EXEC:kermit,pty,setsid,echo=0,rawer,opost=1,icrnl=1,onlcr,cread`).\n  * ⚠️ Be aware that doing this *securely*—safe for public usage—is\n    more involved than one might imagine.  *Safely* configuring the\n    proxy for this type of operation is possible, but beyond the scope\n    of this documentation.\n\n## Development\n\n### Required\n\n* For `proxy` development, along with the most recent version of\n  [Go](https://go.dev/), you’ll also need to have a standard POSIX.1\n  shell environment (at a minimum `sh`, `make`, `grep`, `awk`, \u0026\n  `sed`), and [`reuse`](https://github.com/fsfe/reuse-tool),\n  [`staticcheck`](https://staticcheck.dev/),\n  [`revive`](https://revive.run/),\n  [`errcheck`](https://github.com/kisielk/errcheck),\n  [`gofumpt`](https://github.com/mvdan/gofumpt),\n  [`govulncheck`](https://go.googlesource.com/vuln),\n  [`scc`](https://github.com/boyter/scc),\n  [`scspell`](https://github.com/myint/scspell),\n  [`codespell`](https://github.com/codespell-project/codespell), and\n  [Perl](https://www.perl.org/).\n* If you plan to make any changes to the [`Makefile`](Makefile) (or\n  the [`.cross.sh`](.cross.sh) script), you’ll need to have the\n  [ShellCheck](https://www.shellcheck.net/) and\n  [`shfmt`](https://github.com/mvdan/sh) linters available.\n* Additionally, all modifications to the [`Makefile`](Makefile) and\n  [`.cross.sh`](.cross.sh) scripts must be tested against\n  [`pdpmake`](https://frippery.org/make/)\n  (with `PDPMAKE_POSIXLY_CORRECT` set) and\n  [`yash`](https://magicant.github.io/yash/) to ensure POSIX\n  conformance.\n* The [`Makefile`](Makefile) provides a `lint` convenience target to\n  help you run all this.  You can also examine our\n  [`.gitlab-ci.yml`](.gitlab-ci.yml) file.\n\n### Recommended\n\n* While not absolutely required, it’s a good idea to have the latest\n  [`golangci-lint`](https://golangci-lint.run/) (v2) installed.  We\n  ship a [config file](.golangci.yml) file for it, and try to make\n  sure that all the tests pass when using the most recently released\n  version.\n* It’s also recommended to (*manually*) use\n  [`hunspell`](https://hunspell.github.io/) for spell\n  checking—in addition to using `codespell` and `scspell`.\n\n## Security\n\n* The canonical home of this software is\n  [`https://gitlab.com/dps8m/proxy`](https://gitlab.com/dps8m/proxy),\n  with a mirror on [GitHub](https://github.com/johnsonjh/dps8m-proxy/).\n* This software is intended to be **secure** 🛡️.\n* If you find any security‑related problems, please don’t hesitate to\n  [open a GitLab Issue](https://gitlab.com/dps8m/proxy/-/issues/new)\n  (or send an\n  [email](mailto:contact-project+dps8m-proxy-71601954-issue-@incoming.gitlab.com)\n  to the author).\n\n## Licenses\n\n* The `proxy` program is made available under the terms of the\n  [MIT License](https://opensource.org/license/mit).\n* Some bundled example and miscellaneous files distributed under the\n  terms of the\n  [MIT No Attribution License](https://opensource.org/license/mit-0).\n* All direct and indirect dependencies are licensed under permissive\n  open-source licenses:\n  |                                                                     Dependency | License                                                     |\n  |-------------------------------------------------------------------------------:|:------------------------------------------------------------|\n  |                                [arl/statsviz](https://github.com/arl/statsviz) | [MIT](https://opensource.org/license/mit)                   |\n  |                              [etcd-io/bbolt](https://github.com/etcd-io/bbolt) | [MIT](https://opensource.org/license/mit)                   |\n  |                            [hashicorp/mdns](https://github.com/hashicorp/mdns) | [MIT](https://opensource.org/license/mit)                   |\n  |                            [uber-go/goleak](https://github.com/uber-go/goleak) | [MIT](https://opensource.org/license/mit)                   |\n  |                      [gorilla/websocket](https://github.com/gorilla/websocket) | [BSD-2-Clause](https://opensource.org/license/bsd-2-clause) |\n  |                              [google/go-cmp](https://github.com/google/go-cmp) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                  [google/gops](https://github.com/google/gops) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                    [klauspost/compress](https://github.com/klauspost/compress) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  | [libcap/cap](https://pkg.go.dev/kernel.org/pub/linux/libs/security/libcap/cap) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  | [libcap/psx](https://pkg.go.dev/kernel.org/pub/linux/libs/security/libcap/psx) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                      [miekg/dns](https://github.com/miekg/dns) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                  [spf13/pflag](https://github.com/spf13/pflag) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                [ulikunitz/xz](https://github.com/ulikunitz/xz) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                        [x/crypto](https://golang.org/x/crypto) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                              [x/mod](https://golang.org/x/mod) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                              [x/net](https://golang.org/x/net) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                            [x/sync](https://golang.org/x/sync) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                              [x/sys](https://golang.org/x/sys) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                            [x/term](https://golang.org/x/term) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n  |                                          [x/tools](https://golang.org/x/tools) | [BSD-3-Clause](https://opensource.org/license/bsd-3-clause) |\n\n\u003c!-- vim: set ft=markdown expandtab cc=72 : --\u003e\n\u003c!-- EOF --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnsonjh%2Fdps8m-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnsonjh%2Fdps8m-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnsonjh%2Fdps8m-proxy/lists"}