Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Only today: Visit my SSH ASCII lavalamp
8 points by dusted on Nov 26, 2020 | hide | past | favorite | 9 comments
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"

:)




I 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/


Neat. 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 :)


Thanks! 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 ;))


Takeaway 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 :)


Works for me. Are you gonna post the source code for it? Sharing is caring ;)


yah, 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


connection refused


Works 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!


you probably hit those two minutes when it was offline :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: