{"id":19513661,"url":"https://github.com/ryanwoodsmall/netclip","last_synced_at":"2026-05-18T04:40:55.068Z","repository":{"id":82301331,"uuid":"208883559","full_name":"ryanwoodsmall/netclip","owner":"ryanwoodsmall","description":"netclip","archived":false,"fork":false,"pushed_at":"2024-03-07T06:46:59.000Z","size":55,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-25T23:30:43.983Z","etag":null,"topics":["alpine","clipboard","docker","dropbear","netclip","ssh","stdin","stdout","xclip","xsel","xvfb"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ryanwoodsmall.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2019-09-16T19:42:33.000Z","updated_at":"2023-01-28T03:57:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"a97c39e2-32fb-43ba-a1ab-c1ffeb006921","html_url":"https://github.com/ryanwoodsmall/netclip","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ryanwoodsmall/netclip","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanwoodsmall%2Fnetclip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanwoodsmall%2Fnetclip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanwoodsmall%2Fnetclip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanwoodsmall%2Fnetclip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ryanwoodsmall","download_url":"https://codeload.github.com/ryanwoodsmall/netclip/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanwoodsmall%2Fnetclip/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274291351,"owners_count":25258156,"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-09-09T02:00:10.223Z","response_time":80,"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":["alpine","clipboard","docker","dropbear","netclip","ssh","stdin","stdout","xclip","xsel","xvfb"],"created_at":"2024-11-10T23:31:51.755Z","updated_at":"2026-05-18T04:40:50.034Z","avatar_url":"https://github.com/ryanwoodsmall.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# netclip\n\nnetwork clipboard built on docker with\n\n- alipine linux\n- bash\n- dropbear ssh\n- xclip x11 clipboard client\n- xvfb virtual frame buffer x server\n- x11vnc vnc server (for debugging)\n- those perennial favorites, _**stdin**_ and _**stdout**_\n- \"last in, only out, maybe\" technology\n\n## usage\n\nthe `install` command will setup some scripts in `${HOME}/bin`\n\n- `netclip`: netclip service interaction/control\n- `sc`: shared clipboard copy\n- `sp`: shared clipboard paste\n- `localclip`: local clipboard manager\n- `localclipin`: copy to local clipboard\n- `localclipout`: paste from local clipboard\n- `copysync`: copy stdin to both network and local clipboards\n\nenvironment variables\n\nvar | purpose | default\n--- | --- | ---\n`clipuser` | netclip ssh user | *clippy*\n`clipport` | netclip ssh port | *11922*\n`cliphost` | netclip hostname/IP | docker container id\n`clipinst` | netclip script installation path | `${HOME}/bin`\n`clipssh` | netclip ssh command to use | `ssh`\n`clipsshopts` | netclip ssh options | `-l ${clipuser} -p ${clipport}`\n\n```\n# netclip help\nusage: /netclip [cmd]\n\n  basics:\n    export cliphost=hostname.domainname\n    ssh -l clippy -p 11922 ${cliphost} /netclip install | bash\n    cat ~/.ssh/id_rsa.pub | netclip addkey\n    echo hello | sc\n    sp\n    cat /tmp/in.txt | netclip copy ; ssh remote 'netclip paste \u003e /tmp/out.txt'\n\n  commands:\n          addkey: add an ssh key from stdin\n           clear: clear the contents of the clipboard\n       clearhist: clear all history entries\n     clipboardin: manipulate clipboard selection stdin (abbrev: ci)\n    clipboardout: manipulate clipboard selection stdout (abbrev: co)\n            copy: copy stdin to the clipboard\n        copysync: show script to copy to both network and local clipboard\n             cut: alias for copy\n         delhist: read a history entry from stdin and delete it\n          delkey: read a key number from stdin and delete it\n         delpass: delete the stored password file\n     disautolock: disable autolocking the clipboard before copying\n         dishist: disable capturing clipboard history\n        dumpkeys: copy and paste ssh keys to stdout\n      enautolock: enable autolocking the clipboard before copying\n          enhist: enable capturing clipboard history\n         gethist: read a history entry from stdin and show it\n            help: show this help\n         install: show install script for netclip/sc/sp\n        listhist: list any existing history entries\n        listkeys: show known ssh authorized keys\n     listrawkeys: show ssh authorized_keys file\n       localclip: show localclip script\n     localclipin: show localclip stdin script\n    localclipout: show localclip stdout script\n            lock: mark the clipboard as read-only\n         netclip: show netclip control script\n           paste: paste the clipboard to stdout\n       primaryin: manipulate primary selection stdin (abbrev: pi)\n      primaryout: manipulate primary selection stdout (abbrev: po)\n            reap: kill any lingering xclip processes\n              sc: show network copy script\n     secondaryin: manipulate secondary selection stdin (abbrev: si)\n    secondaryout: manipulate secondary selection stdout (abbrev: so)\n         setpass: read new password from stdin\n    showautolock: show the clipboard autolocking status\n        showhist: show the clipboard history status\n        showlock: show the clipboard lock status\n        showpass: show password\n        showport: show the ssh clipboard port\n        showuser: show the ssh clipboard user\n              sp: show network paste script\n          unlock: mark the clipboard as read-write\n          update: update netclip scripts\n```\n\n## build\n\n```\ndocker build --tag netclip .\n```\n\n## run\n\n```\ndocker run -d --restart always --name netclip -p 11922:11922 netclip\n```\n\n## username/password\n\nthe username/password for ssh access is dumped to the logs at startup\n\n```\ndocker logs netclip | awk -F: '/^user:/{print $NF}' | head -1 | tr -d ' '\ndocker logs netclip | awk -F: '/^pass:/{print $NF}' | head -1 | tr -d ' '\n```\n\nthe ssh/vnc password can be shown using the `showpass` command as well\n\n```\ndocker exec --user clippy netclip /netclip showpass\n```\n\nthe ssh password can be reset from the docker host where netclip is running\n\n```\ndocker exec --user clippy netclip sh -c 'echo SuperSecretNEWp@55W0rD+ | /netclip setpass'\n```\n\nthe password file can be removed\n\n```\ndocker exec --user clippy netclip /netclip delpass\n```\n\n## add an ssh key\n\nsubstitute username/port/hostname below\n\nenter password when prompted\n\n```\ncat ~/.ssh/id_rsa.pub | ssh -l clippy -p 11922 hostname /netclip addkey\n```\n\ntest keys with\n\n```\nssh -l clippy -p 11922 hostname /netclip help\n```\n\n## get scripts\n\nautomatic install\n\n```\nexport cliphost=hostname\nssh -l clippy -p 11922 ${cliphost} /netclip install | bash\n```\n\nmanual install\n\n```\nexport cliphost=hostname\nssh -l clippy -p 11922 ${cliphost} /netclip netclip \u003e ~/bin/netclip\nchmod 755 ~/bin/netclip\n~/bin/netclip sc \u003e ~/bin/sc\n~/bin/netclip sp \u003e ~/bin/sp\nchmod 755 ~/bin/s{c,p}\nwhich -a netclip sc sp\n```\n\n## use scripts\n\nset a hostname for `${cliphost}` and copy/paste to your heart's content\n\n```\nexport cliphost=hostname\necho something | sc\nsp\n```\n\nthat's it!\n\nonce a host's key is in place it has full copy/paste powers as long as the cliphost is reachable\n\n## set up a bunch of keys at once\n\nbootstrapping keys is relatively simple assuming they're exchanged with the netclip host\n\n```\ngit clone https://github.com/ryanwoodsmall/dockerfiles.git\ngit submodule init\ngit submodule update\ncd alpine-netclip\ngit checkout master\ngit pull\ndocker build --tag netclip .\ndocker run -d --restart always --name netclip -p 11922:11922 netclip\ndocker exec --user clippy netclip /netclip delpass\ndocker cp ~/.ssh/id_rsa.pub netclip:/tmp/key.pub\ndocker exec --user clippy netclip bash -c 'cat /tmp/key.pub | /netclip addkey'\ndocker exec --user clippy netclip /netclip install | bash\nfor h in h01 h02 h03 ; do\n  ssh $h cat .ssh/id_rsa.pub | netclip addkey\n  netclip install | ssh $h\ndone\n```\n\n### uses\n\n- system monitor?\n  - htop/iostat/ifstat/etc. output on secondary\n  - aggregate views w/tmux\n- ring buffer with sponge\n- ripple i/o loops\n- broadcast/subscription/todo system?\n- daemon/service/plugins for whatever programs for centralized clipping\n\n### todo\n\n- probably need a `clipproxycmd` setting\n  - `nc`, `socat`, or similar to encapsulate SSH in HTTPS, act as VPN, etc.\n    - anonymous (insecure!) tls server: `socat openssl-listen:11944,reuseaddr,fork,cert=/cert.pem,verify=0 tcp4-connect:${cliphost}:11922`\n    - anonymous (insecure!) tls client: `socat - openssl-connect:${tlsserver}:11944,verify=0`\n  - can do this easily with `ProxyCommand` in `~/.ssh/config` for OpenSSH, Dropbear with `-J` option\n  - wrapper script might be enough and is much simpler\n    - works better with `dbclent -J...` as well without having to do coprocess/filedescriptor stuff\n- debug environment var - run vs build time\n- debug x11vnc should run as debug user connecting to clippy xvfb? xhost?\n- just remove vnc stuff for now?\n- watch a fifo?\n- read-only flag? write-host check? \"only host with IP #.#.#.# can copy\"\n- or read-only user? read-only port?\n- lock down ssh command (requires openssh) similar to git\n- remove root user requirement after setup, run as regular user\n- ability to turn ssh password auth off\n- ability to update: netclip script, startup .sh scripts, and dropbear packages\n- peel out unnecessary/big packages\n- clear on read, i.e. delete the clipboard when paste\n- something more \"enterprise-y\" on centos/rhel w/auth (pam, ldap, kerberos, ...) stuff built in\n- service discovery for user/host/port (mdns? other broadcast?)\n- gui???\n- real supervisor instead of shell loops?\n- network of clipboards? local service, master service with broadcast, distribution?\n- actual c/go/rust service process?\n  - ssh replacement to gen a single binary?\n  - i/o is the easy part\n  - go: crypto/ssh and https://github.com/gliderlabs/ssh\n    - garbage collection?\n  - c: libssh2\n- libssh2 server?\n- multiple clipboards?\n  - multiple copy/paste is ugh, complicates input\n  - use as undo? implicit/explicit?\n  - if clipboard is text, automatically copy to primary?\n  - xclip supports primary/secondary/clipboard/buffer-cut\n  - xsel supports primary/secondary/clipboard\n  - clipboard is any data type, cut buffer is old, primary is \"text only\", secondary is underdefined\n- xclip `-verbose`?\n- xsel?\n  - more features than xclip\n  - `--append` option for stdin to selection\n  - `--follow` option for tail-like stdin\n  - `--exchange` option for primary/secondary\n  - `--logfile` for logging errors\n  - `--keep` option for primary/secondary persistence\n  - `--verbose` option\n- sselp\n  - suckless simple x selection printer\n  - works on primary, out only\n  - https://tools.suckless.org/x/sselp/\n- case-generation for function expansion\n  - pipes are parsed BEFORE vars in $v1|$v2|$v3) ... case examples\n  - ugh\n- explicit file copy support?\n  - would require \"client\" code\n  - no\n- volumes for docker stuff\n  - dropbear\n  - settings\n  - history/log files\n- localclip/localclipin/localclipout\n  - windows/wsl: clip.exe, `powershell.exe Get-Clipboard`, winclip from putty, doit\n    - https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-clipboard\n    - https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-clipboard\n    - probably need raw fo Get-Clipboard\n    - clip.exe -\u003e `powershell.exe Set-Clipboard -Value \"...\"`?\n    - of course\n  - screen/tmux: copy buffers?\n- loadkeys (import keys from dumpkeys)\n- history - separation in to YYYY/MM/DD/HH/MM/SS/N nanosecond format\n  - UUID for filename?\n  - sqlite db w/sha256sum/index for dedupe?\n- ssh keys - show fingerprints\n  - use fingerprints for trusted pubkey removal instead of jank number system thing\n  - `ssh-keygen -l -f - \u003c /tmp/individual.pubkey`\n  - also works with `~/.ssh/authorized_keys` or other textual key lists\n- make sc/sp/etc. script symlinks to netclip client\n- base64 encode everything?\n- gpg sign history?\n- associate clip with ssh pubkey some how\n- stack: clipboard-\u003eprimary-\u003esecondary\n- private keys? for external sync\n- zero clipboards on xvfb start with `echo -n`\n- move to `rbash`\n  - disable compound execution, i.e... `netclip 'sp ; ls -lA /'`\n  - just make netclip a valid shell and deal with ';' casing there?\n- limit sudo usage to specific commands\n  - apk, chown, chmod, sponge, etc.\n- dumpkeys is copying but not pasting, not sure why\n- ability to connect to \"real\"/existing x-window display via custom `DISPLAY=` setting \u0026 no xvfb\n- default cincmd/coutcmd to sc/sp in localclip script?\n- convert to 9p w/c9 (https://git.sr.ht/~ft/c9) and/or 9pro (https://git.sr.ht/~ft/9pro)\n- rename `copy` and `paste` with \"net\" prefix to avoid conflict with `/usr/bin/paste`\n- host key dump - `/etc/dropbear` in .tar?\n- full backup/restore - `/data/clip` and `/data/vnc`(?) and `/home/clippy` and `/etc/dropbear` and ??? in .tar?\n- pastebin-like web+url generation w/history\n  - expiry is ugly\n  - content-addressable (ish) with sha-256 (-512? b2sum? b3sum?) sums as key, data as value\n    - i.e., `/data/persist/$sum/content`\n    - combine w/cliphistory dated log dir files+symlinks for historical-ish tracking\n    - current clipboard, primary, secondary aliases for in-memory clipboard\n  - store uuid along with hash?\n    - every file only has one sha-### sum\n    - uuid is equally unique\n    - but a uuid with a collection of sums could represent a bundle of files - i.e., .tar or similar\n  - version with `.#` extension?\n    - only makes sense with uuid/hash sum mapping\n    - would have to do tombstones when a file is removed from a bundle at a version\n    - woof\n  - just use venti, man\n    - or nix or guix or...\n  - wow: https://github.com/golang-design/clipboard and https://github.com/changkun/midgard\n- i need to rip some of this shit out\n- ooh, small xclipd/xclipin/xclipout: https://github.com/phillbush/xcliputils\n- stripped down container with only bash+xvfb+tinysshd+xclipd+tr+fold+printf+tee+sponge+...\n  - replace as much as possible w/pure bash; `echo` -\u003e `\u003e\u003e\u003e` ???\n  - ed25519 only!\n    - ssh keys are the _only_ state; negative features.\n    - dropbearkey for generation\n  - other utilities? date, tee, grep, ...\n  - decrease attack surface significantly\n\n### links\n\n- https://github.com/danielguerra69/alpine-vnc\n- https://github.com/jkuri/alpine-xfce4\n- https://wiki.archlinux.org/index.php/Clipboard\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanwoodsmall%2Fnetclip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryanwoodsmall%2Fnetclip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanwoodsmall%2Fnetclip/lists"}