Giter Club home page Giter Club logo

ssh-chat's Introduction

Build Status GoDoc Downloads Bountysource

ssh-chat

Custom SSH server written in Go. Instead of a shell, you get a chat prompt.

Demo

Join the party:

$ ssh ssh.chat

Please abide by our project's Code of Conduct while participating in chat.

The host's public key is ssh.chat ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKPrQofxXqoz2y9A7NFkkENt6iW8/mvpfes3RY/41Oyt and the fingerprint is SHA256:yoqMXkCysMTBsvhu2yRoMUl+EmZKlvkN+ZKmL3115xU (as of 2021-10-13).

If you see something different, you might be MITM'd.

(Apologies if the server is down, try again shortly.)

Downloading a release

Recent releases include builds for MacOS (darwin/amd64) and Linux (386, amd64, and ARM6 for your RaspberryPi).

Grab the latest binary release here.

Play around with it. Additional deploy examples are here.

Compiling / Developing

Most people just want the latest binary release. If you're sure you want to compile it from source, read on:

You can compile ssh-chat by using make build. The resulting binary is portable and can be run on any system with a similar OS and CPU arch. Go 1.8 or higher is required to compile.

If you're developing on this repo, there is a handy Makefile that should set things up with make run.

Additionally, make debug runs the server with an http pprof server. This allows you to open http://localhost:6060/debug/pprof/ and view profiling data. See net/http/pprof for more information about pprof.

Quick Start

Usage:
  ssh-chat [OPTIONS]

Application Options:
  -v, --verbose    Show verbose logging.
      --version    Print version and exit.
  -i, --identity=  Private key to identify server with. (default: ~/.ssh/id_rsa)
      --bind=      Host and port to listen on. (default: 0.0.0.0:2022)
      --admin=     File of public keys who are admins.
      --whitelist= Optional file of public keys who are allowed to connect.
      --motd=      Optional Message of the Day file.
      --log=       Write chat log to this file.
      --pprof=     Enable pprof http server for profiling.

Help Options:
  -h, --help       Show this help message

After doing go get github.com/shazow/ssh-chat/... on this repo, you should be able to run a command like:

$ ssh-chat --verbose --bind ":22" --identity ~/.ssh/id_dsa

To bind on port 22, you'll need to make sure it's free (move any other ssh daemons to another port) and run ssh-chat as root (or with sudo).

Frequently Asked Questions

The FAQs can be found on the project's Wiki page. Feel free to submit more questions to be answered and added to the page.

License

MIT

ssh-chat's People

Contributors

42wim avatar alvinlai avatar crosbymichael avatar dmitshur avatar fjarlq avatar goose121 avatar iqandreas avatar jazzychad avatar kealper avatar lawrencecraft avatar leonklingele avatar magisterquis avatar mcroydon avatar mikitsu avatar millerlogic avatar mvrilo avatar nickpresta avatar ograff avatar pataquets avatar pavelz avatar peterhellberg avatar sammauldin avatar shazow avatar sleibrock avatar songgao avatar tyrelsouza avatar ulissemini avatar voldyman avatar wedow avatar wpovell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ssh-chat's Issues

Compiling source gives error about server lock

When building source the following error is outputted:

# _/Users/puzzel/Documents/Git/ssh-chat
./server.go:240: s.lock undefined (type *Server has no field or method lock)
./server.go:242: s.lock undefined (type *Server has no field or method lock)

The error seems to be due to the change in commit e3e46f9, will look into fixing shortly.

Persist whitelist state across restarts

The whitelist should add to the specified file, if you agree, I think this will be a great learning example for me and Go.

Also, there should be a /dewhitelist as well.

Thoughts?

Installing and running ssh-chat on Raspberry Pi

Hello,

I attempted to install ssh-chat on my Raspberry Pi but ran into problems quickly.

I am using Raspbian distro.

I ran sudo apt-get install golang. go version reports:

go version go1.0.2

Next, I added a new account on my system to be used for trying out ssh-chat sudo adduser ssh-chat and switched to that user by doing sudo su - ssh-chat.

I attempted to install ssh-chat by doing export GOPATH=$HOME and then go get github.com/shazow/ssh-chat. Then it says:

# github.com/jessevdk/go-flags
src/github.com/jessevdk/go-flags/group_private.go:245: method g.scanSubGroupHandler is not an expression, must be called
src/github.com/jessevdk/go-flags/parser.go:176: method p.showBuiltinHelp is not an expression, must be called
# golang.org/x/crypto/ssh
src/golang.org/x/crypto/ssh/cipher.go:241: undefined: cipher.AEAD

I was hoping to use ssh-chat to understand a bit about how software is developed in Go but to have such trouble right away is a bit too much for me to be able to handle on my own.

Any help would be greatly appreciated.

/nick message shows the nickname before sanitization

[aquilax] /nick 63:d2:d6:02:95:cf:03:1f:c2:a0:49:cd:f7:8f:89:8e
 * aquilax is now known as 63:d2:d6:02:95:cf:03:1f:c2:a0:49:cd:f7:8f:89:8e.
[63d2d60295cf031fc2a049cdf78f898e] /nick aquilax
 * 63d2d60295cf031fc2a049cdf78f898e is now known as aquilax.

The message says the new nickname is 63:d2:d6:02:95:cf:03:1f:c2:a0:49:cd:f7:8f:89:8e, while it really is 63d2d60295cf031fc2a049cdf78f898e.

panic: runtime error: send on closed channel

panic: runtime error: send on closed channel

goroutine 2535 [running]:
runtime.panic(0x716500, 0xb3fe7e)
        /usr/lib/go/src/pkg/runtime/panic.c:266 +0xb6
main.(*Server).Privmsg(0xc2100aec40, 0xc210472905, 0x5, 0xc21047290b, 0x4, ...)
        /home/shazow/ssh-chat/server.go:129 +0x27c
main.(*Client).handleShell(0xc2104fa140, 0x7f14a5ed7da8, 0xc2104170c0)
        /home/shazow/ssh-chat/client.go:365 +0x1b24
created by main.(*Client).handleChannels
        /home/shazow/ssh-chat/client.go:459 +0x66d

Graceful server reloading

So many new features, sad to drop all connections to restart the server.

There are lots of posts about how to do this for http servers, but not sure how much more complicated it would be to do for an ssh tcp socket. Any investigating/resources appreciated.

Relevant links:

These seem to work by keeping two processes open until the old connections finish. This won't work for upgrading existing connections.

I'd also entertain a failover proxy frontend but I suspect that might not be possible without breaking ssh-chat into two big chunks (one of which could not be gracefully reloaded).

Another possibility is if there was some ssh protocol to request the client to reconnect.

Find and fix memory leak

When users join/leave over time, the memory usage goes up even though the total connected users stay the same.

It went up from ~6mb to ~16mb to ~42mb of RSS in 24 hours of uptime, hovering around 40 connected users.

Anecdotally, I feel it should be sitting under 10mb of memory at that load. I suspect we're not releasing the clients' message buffers after they leave or something similar.

Probably want to use something like http://golang.org/pkg/net/http/pprof/.

Would be cool if we had a load testing tool to reproduce this.

Non-human (bot) interface

I'm sure I saw a bot known as Hubot last time I logged in, amongst the now-frequent spam from various miscreants.

I wonder, is it using the regular human interface?

Perhaps we could have some kind of API to make a bot, remote or local.

User 'registrations'

At the moment, whilst whitelisting pubkeys is supported, within the whitelist anyone can assume any identity.

Perhaps it would be good to associate a username with keys in the whitelist (which could become a YAML file) or perhaps simply register the username with the key on the first pubkey user login -- first come first serve.

Tests

Need more tests, of anything and everything. Pretty please.

Release v1.0

  • Separate chat-specific stuff into a chat submodule that knows nothing about the transport.
  • Separate ssh server specific stuff into an sshd submodule that knows nothing about chat.
  • Feature parity with the current master.
  • Tests!
  • Even more tests (maybe >80% coverage?)

Nice to haves:

  • Bind on port 2022 by default, and print port binded.
  • Generate keypair if one doesn't exist? (Make sure to print this fact)

/ignore command

People get frustrated with spammers or hubot or whatever.

Load whitelist/admins from a file

Maybe something like...

<fingerprint or pubkey>          # This whitelists the fingerprint
<nick> <fingerprint or pubkey>   # This reserves the nick to fingerprint
admin: <fingerprint or pubkey>   # This marks fingerprint as admin

Then we can have a --whitelist <file> flag, and a --whitelistOnly flag which disallows people to join if not on the whitelist.

/cc @jazzychad

Panic: send on closed channel

While developing check-ssh-chat I managed to crash my test server with the dreaded panic: send on closed channel

I was doing very short (a few tens of ms) connect/disconnect cycles at the time, not sure if related though.

Example crash on pi.c7.se

2014-12-17 23:35:29.180 INFO Connection #35 from: 192.168.1.1:61085, check-ssh-chat, SSH-2.0-Go
2014-12-17 23:35:45.140 INFO Connection #36 from: 192.168.1.1:61090, check-ssh-chat, SSH-2.0-Go
2014-12-17 23:37:24.934 ERROR Failed to handshake: ssh: unexpected message type 1 (expected 50)
2014-12-17 23:41:57.790 INFO Connection #37 from: 192.168.1.1:61135, check-ssh-chat, SSH-2.0-Go
2014-12-17 23:42:06.080 INFO Connection #38 from: 192.168.1.1:61140, check-ssh-chat, SSH-2.0-Go
panic: send on closed channel

goroutine 574 [running]:
main.(*Client).Send(0x1075cea0, 0x10784230, 0x50)
        /Users/peter/Go/src/github.com/peterhellberg/ssh-chat/client.go:121 +0x60
main.(*Client).SysMsg(0x1075cea0, 0x397600, 0x20, 0x10779fb4, 0x2, 0x2)
        /Users/peter/Go/src/github.com/peterhellberg/ssh-chat/client.go:97 +0xe0
main.(*Client).handleShell(0x1075cea0, 0xb6f85ba0, 0x107dc500)
        /Users/peter/Go/src/github.com/peterhellberg/ssh-chat/client.go:204 +0x1c2c
created by main.(*Client).handleChannels
        /Users/peter/Go/src/github.com/peterhellberg/ssh-chat/client.go:472 +0x728

goroutine 1 [chan receive, 1372 minutes]:
main.main()
        /Users/peter/Go/src/github.com/peterhellberg/ssh-chat/cmd.go:95 +0xe10

goroutine 7 [IO wait]:
net.(*pollDesc).Wait(0x107a82b8, 0x72, 0x0, 0x0)
        /usr/local/Cellar/go/1.4/libexec/src/net/fd_poll_runtime.go:84 +0x3c
net.(*pollDesc).WaitRead(0x107a82b8, 0x0, 0x0)
        /usr/local/Cellar/go/1.4/libexec/src/net/fd_poll_runtime.go:89 +0x38
net.(*netFD).accept(0x107a8280, 0x0, 0xb6f83b48, 0x1073b588)
        /usr/local/Cellar/go/1.4/libexec/src/net/fd_unix.go:419 +0x390
net.(*TCPListener).AcceptTCP(0x1071c400, 0xb6f72000, 0x0, 0x0)
        /usr/local/Cellar/go/1.4/libexec/src/net/tcpsock_posix.go:234 +0x50
net.(*TCPListener).Accept(0x1071c400, 0x0, 0x0, 0x0, 0x0)
        /usr/local/Cellar/go/1.4/libexec/src/net/tcpsock_posix.go:244 +0x3c

UI – commands too different from IRC

A really minor issue, but it'd be more convenient if commands were closer to those used by most IRC clients:

  • /quit to leave (yes, some clients do have /exit, but kinda rare)
  • /names to list users (since there's only one channel, /list makes no sense)

Only search comment body for username to highlight

screenshot_2014-12-15-21-10-36

Hello, I am the user 2 and when someone has 2 in their color escape code, it highlights the number two.

Something similar might also affect a user whos name is a substring of the name of another user?

Add host fingerprint to README

the readme file should have the servers fingerprint so that the people who are trying to connect are certain that they are connecting to the right host.

Hanging bug #1,003

Server stopped accepting connections after these happened:

2014-12-17 19:44:19.338 ERROR Failed to handshake: read tcp 124.117.18.242:60395: connection reset by peer
2014-12-17 19:44:20.716 ERROR Failed to handshake: read tcp 124.117.18.242:60396: connection reset by peer
2014-12-17 19:44:21.385 ERROR Failed to handshake: read tcp 124.117.18.242:60397: connection reset by peer

Not sure how to reproduce, maybe our Chinese friends can enlighten us.

Install inpossible

I tried to install it like mentioned in the README.md:

 root@debian [~]#: go get github.com/shazow/ssh-chat
# github.com/jessevdk/go-flags
/usr/lib/go/src/pkg/github.com/jessevdk/go-flags/group_private.go:245: method g.scanSubGroupHandler is not an expression, must be called
/usr/lib/go/src/pkg/github.com/jessevdk/go-flags/parser.go:176: method p.showBuiltinHelp is not an expression, must be called
# golang.org/x/crypto/ssh
/usr/lib/go/src/pkg/golang.org/x/crypto/ssh/cipher.go:241: undefined: cipher.AEAD

How to resolve that? I am not very used to GO, so pardon please.

Import Cycle Not Allowed

go get github.com/shazow/ssh-chat/
package github.com/shazow/ssh-chat
        imports runtime: C source files not allowed when not using cgo: atomic_386.c defs.c float.c heapdump.c lfstack.c malloc.c mcache.c mcentral.c mem_linux.c mfixalloc.c mgc0.c mheap.c msize.c os_linux.c os_linux_386.c panic.c parfor.c proc.c runtime.c signal.c signal_386.c signal_unix.c stack.c string.c sys_x86.c vlrt.c
import cycle not allowed
package github.com/shazow/ssh-chat
        imports golang.org/x/crypto/ssh
        imports crypto/x509
        imports net
        imports runtime/cgo
        imports runtime/cgo

Above is the command I run and output of the build failing at import cycle not allowed.

Linux 3.2.0-4-686-pae #1 SMP Debian 3.2.63-2+deb7u2 i686 GNU/Linux

go version go1.4 linux/386

Any thoughts or suggestions? I am new to go.

feature request: chatroom channels

There is a lot of traffic on the chat server, making following the discussion very hard. Private conversations are also not easy.

Since the server borrows protocols anyway, it could be a nice idea to borrow more protocols. The directory metaphor could be a good match for listing and navigating channels:

  • pwd shows the current channel you're in
  • ls shows the available sub-channels
  • cd enters an available channel
  • mkdir and rmdir create and remove channels

Rewrite how messages are stored

I would like to re-write messages to store them as Message instances rather than a strings. This will allow us to add properties to them such as "target", and some other changes I have planned which will make themes much easier to implement.

As the change is a bit larger, so I mention my intentions first to double check if you agree with the changes. I also think it would be a good idea to merge anything that needs merging to avoid conflicts, as the changes are going to affect many lines.

Decide and implement a persistent storage for state

Options to consider (sorted vaguely in order of current preference):

  • flat file (possibly multiple append-only files?)
  • BoltDB (native golang)
  • badgerdb (native golang)
  • leveldb
  • sqlite

Things we'd want to store:

  • message history (log)
  • registered identities (against pubkey)
  • whitelisted pubkeys
  • admin pubkeys
  • identity settings (theme? last message seen? etc)
  • what else?

Note: Need to make sure persistence doesn't collide if multiple instances are run on multiple ports.

lsh 2.9 – hangs after authentication

Out of curiosity, I tried the GNU lsh client, and it hangs after authentication unless I specify --no-pty.

┌ rain ~
┘ lsh --version
lsh (lsh 2.9.1-exp)

┌ rain ~
┘ lsh -v chat.shazow.net
lsh: Enabling default escape character `~'
lsh: Could not open gateway: No such file or directory.
lsh: Starting /usr/lib/lsh/lsh-transport.
lsh-transport: Connecting to chat.shazow.net:22....
lsh-transport: ... connected.
lsh-transport: Server version string: SSH-2.0-Go
lsh-transport: Received KEXINIT message. Key exchange initated.
lsh-transport: Selected keyexchange algorithm: diffie-hellman-group14-sha1
  with hostkey algorithm:       ssh-rsa
lsh-transport: Selected bulk algorithms: (client to server, server to client)
  Encryption:             (aes128-ctr, aes128-ctr)
  Message authentication: (hmac-sha1, hmac-sha1)
  Compression:            (none, none)
lsh-transport: SPKI host authorization successful!
lsh-transport: Requesting authentication of user `grawity' using the `publickey' method.
lsh-transport: Received USERAUTH_SUCCESS.
lsh: Allocated local channel number 0
[...time passes...]
^C

Implement time stamps?

Would it be possible to implement timestamps for every message sent to the chat room?

Handle passworded server identity keys better

Right now there's an uninformative error:

ERROR Failed to create server: asn1: structure error: length too large

Better would be to catch that the keys are passworded and write a more descriptive error.

Best would be to interface with ssh-agent and unlock the keys to use with the server.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.