shazow / ssh-chat Goto Github PK
View Code? Open in Web Editor NEWChat over SSH.
Home Page: https://shazow.net/posts/ssh-how-does-it-even/
License: MIT License
Chat over SSH.
Home Page: https://shazow.net/posts/ssh-how-does-it-even/
License: MIT License
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.
Announces and kills the server.
Only tab-completes fully lowercased. Need to match either, and complete to proper casing.
Need more tests, of anything and everything. Pretty please.
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.
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
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
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.
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.
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.
Seems most ssh clients disconnect after inactivity by default.
Need to add something equivalent to ClientAliveInterval in sshd, basically send a null packet every $INTERVAL (minute?).
It's possible there is some native functionality for this in golang's ssh lib. Several related issues and comments:
golang/go#5875
https://github.com/golang/crypto/blob/master/ssh/session.go#L421
As easy as it is to pass around go binaries there should be a set of packages.
This would include a sane default configuration and an Init script. Ideally ssh-chat should be in a run-able state straight after installation.
Should be easy with FPM: https://github.com/jordansissel/fpm
Options to consider (sorted vaguely in order of current preference):
Things we'd want to store:
Note: Need to make sure persistence doesn't collide if multiple instances are run on multiple ports.
Just like any other IRC client.
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)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.
[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
.
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.
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
Right now names are unique per connection. If I connect from a second device with the same pubkey, I should be able to claim the same name.
/name makes more sense in IRC parlance.
OpenSSH is doing it, we can too. Could add a little ascii graphic thing while we're at it too.
No idea why. Ideas? Symptoms?
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.
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.
Maybe anyone add BBS functionality to SSH-chat? Like conferencing and file areas?
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.
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 inls
shows the available sub-channelscd
enters an available channelmkdir
and rmdir
create and remove channelsI want to use Sourcegraph code search and code review with ssh-chat. A project maintainer needs to enable it to set up a webhook so the code is up-to-date there.
Could you please enable ssh-chat on @sourcegraph by going to https://sourcegraph.com/github.com/shazow/ssh-chat and clicking on Settings? (It should only take 15 seconds.)
Thank you!
When you type a line longer than your terminal width on the client, the reflow breaks.
Not sure why this is happening; maybe an off-by-one error in our terminal width detection? Or a bug in crypto/ssh/terminal?
Making them impossible to see on a terminal with a black background (without selecting the text, or some other workaround).
Would it be possible to implement timestamps for every message sent to the chat room?
@peterhellberg posted a great example of how to do this: https://gist.github.com/peterhellberg/1765ba74860ebf1df817
IMHO we should use the commit short hash for the version until we have tagged version (1.0+).
Let's add this into our Makefile build target.
--motd <file>
flag.
Also motd broadcasting shouldn't add any extra /*
etc surrounding strings to it.
/cc @jazzychad
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?
People get frustrated with spammers or hubot or whatever.
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.
It's set to ~/.ssh/id_rsa
but golang is being literal with the ~
.
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.
Maybe something like /whitelist github.com/shazow
will fetch my ssh pubkeys and whitelist them.
Maybe same thing with /op ...
.
Later we could accept other identity providers like keybase (we'd have to crawl to their github link if they have one, until keybase hosts ssh pubkeys). Related issue: keybase/keybase-issues#710
/cc @jazzychad
Most terminals don't support italics, and they actively break things like GNU Screen.
/cc @IQAndreas
People can do /nick , which gets announced but the final nick is truncated. Should be truncated/sanitized first, then that version is announced.
Also /nick \0
breaks things. It shouldn't.
For example when running it inside screen it's impossible to scroll up/down to read older messages.
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.
As long as we can get their username without prompting somehow.
chat
submodule that knows nothing about the transport.sshd
submodule that knows nothing about chat.Nice to haves:
Something like /colors
or /plain
, will be useful for bot writers and clients with older terminals.
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.