4 ms·
Show HN: Only today: Visit my SSH ASCII lavalamp
ssh 85.27.249.130 -p 2222
username / password does not matter
Enjoy asci[l]icious lava lamp action right in your console.
Quickly hacked together in node, using a fifo file, hasciicam and the ssh2 library, running in docker for "security"
:)
- Blahah 6y agoconnection refused
- wfee2020 6y agoWorks for everyone else. You just have to downgrade your cipher-preferences: ssh -c chacha20-poly1305@openssh.com -p 2222 85.27.249.130 Unable to negotiate with 85.27.249.130 port 2222: no matching cipher found. Their offer: aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm,aes128-gcm@openssh.com,aes256-gcm,aes256-gcm@openssh.com Have to choose the strongest, latter'est, of the accepted shit ciphers. Cool show. 2 people were watching while you ctrl+c 10/10 would watch again!
- dusted 6y agoyou probably hit those two minutes when it was offline :)
- devenblake 6y agoWorks for me. Are you gonna post the source code for it? Sharing is caring ;)
- dusted 6y agoyah, here's the code, I'm not going to excuse it being terrible, it's mostly copy-pasta from the ssh2 readme :) // Main.js var fs = require('fs'); var crypto = require('crypto'); var inspect = require('util').inspect; var ssh2 = require('ssh2'); var utils = ssh2.utils; var allowedUser = Buffer.from('foo'); var allowedPassword = Buffer.from('bar'); var allowedPubKey = utils.parseKey(fs.readFileSync('foo.pub')); const EventEmitter = require('events'); let watchers=0; class Framer extends EventEmitter { constructor() { super(); const borderline = '*----------------------------------------------------------------------*\r\n'; const fd = fs.openSync('./cam', 'r+'); const stream = fs.createReadStream(null, {fd}); let frame = ''; const len = 160*60+60; stream.on('data', (d)=> { if (d.toString().trim() === '[stdin end]') { console.log('stdin end?'); } else { const bytes = d.toString(); frame = frame+bytes; if(frame.length > len) { const out = frame.substr(0,len); frame = frame.substr(len); let lines = out.split('\n'); lines.pop(); lines = lines.map ( (l)=> '|'+l.substr(40, 70) +'|'); const fin = borderline + lines.join('\r\n') + '\r\n' + borderline + '\u001b['+(lines.length+2)+'A\u001b[32D'; this.emit('frame', fin); } } }); } } const grabber = new Framer(); new ssh2.Server({ hostKeys: [fs.readFileSync('foo.key')] }, function(client) { client.on('authentication', function(ctx) { var user = Buffer.from(ctx.username); console.log(new Date().toISOString()+ ' username:',ctx.username,' watching:', watchers); ctx.accept(); }).on('ready', function() { client.on('session', function(accept, reject) { var session = accept(); session.on('pty', (accept)=>{ accept(); }); session.on('shell', (accept)=>{ const stream = accept(); const listener = (frame)=>{stream.write(frame);}; grabber.on('frame', listener); watchers++; stream.on('data', (d)=>{ console.log('data:',d); if(d[0] === 0x03 || d[0] === 0x1b || d[0] == 0x71) { console.log('client left peacefully'); stream.write('\r\n Thanks for watching, have a nice day, there were '+watchers+' watching when you logged off. \r\n'); grabber.removeListener('data', listener); stream.exit(0); stream.end(); watchers--; } }); }); }); }).on('end', function(test) { console.log(new Date().toISOString()+' Client disconnected', test); }); }).listen(2222, '0.0.0.0', function() { console.log('Listening on port ' + this.address().port); }); // running it takes two terminals, one for node, one for the hasciicam: mkdir lava && cd java npm install --save while true do node main.js done // camera: cd lava mkfifo cam hasciicam -m text -o cam
- ludocode 6y agoNeat. I spent a while trying to figure out how you simulated a lava lamp before realizing HasciiCam takes a video feed as input, so I assume this is a real lava lamp. Very cool. It said there were -2 watching when I logged off. I'm guessing that's a bug in your login counter :)
- dusted 6y agoThanks! Yeah, it's literally just my old logitech pointed at a lava lamp :) I have a bug in the login counter, I fixed it, but I've found that someone can crash it by logging in with an unsupported encryption algo, I should catch that (I didn't just wrapped the node run command in a while true loop ;))
- dusted 6y agoTakeaway from this short experiment: A LOT of people are sending the username "root". Hopefully they are merry pranksters hoping to have a bit of fun on my behalf. Hopefully they are not people who are actually just running everything as root :)
- alexellisuk 6y agoI got here too late to watch it, but in the future if you want to expose a local service like this, the OSS inlets project has an add-on for TCP services like SSH and Mongo etc. Might be of use instead of doxing your home IP / location (are you in North Denmark on SEF?) https://docs.inlets.dev/ https://docs.inlets.dev/