3

I'd like to be able to encode maintenance scripts to run on-demand remotely.

edit: Good use-case: webhooks. e.g. trigger CI + staging deployment whenever someone pushes code to github.

If I was to encrypt a shell command using a secure cipher like aes128 + pass phrase:

e.g. 'mysecretwords cd ~ && mkdir ./something' -> 'm4tpWsuiOJT0naKkyWDdNQUKMQ7',

and then allow that command to be executed via a url:

e.g. 'https://myserver.com/script/m4tpWsuiOJT0naKkyWDdNQUKMQ7'

The url itself contains the encoded command to run on the server, which can be decoded only by the target server, with the pass phrase.

I'm pretty certain this is a horribly bad idea: but out of interest how could this be secured?

The act of asking this question is probably evidence I don't know enough to do this safely.

4
  • 2
    +1 for your last sentence :).
    – larsks
    Aug 16, 2012 at 15:24
  • 1
    ...why? Why wouldn't you do it via SSH? Or even have a local script you call that SSHs into the remote server and executes the code? Aug 16, 2012 at 16:07
  • +1 for wanting to do the right thing (automation/remote control), even though you're thinking about doing it in the wrong way :)
    – voretaq7
    Aug 16, 2012 at 17:13
  • why? Webhooks. For example, triggering CI/CD builds etc whenever code is pushed to github or using cron.io
    – timoxley
    Aug 17, 2012 at 1:30

1 Answer 1

4

First lets address your more important core question:

I'd like to be able to encode maintenance scripts to run on-demand remotely.

This sounds like a job for (trumpets sound) Automation Tools!
puppet springs immediately to mind, but there are many others.
You can also home-grow a system which uses passwordless SSH keys to log in to the remote systems and run commands on them, which is a time-honored way of doing this sort of stuff from the days before puppet and the like.


Now let's talk about your HTTP-based idea -- you came right out and said it:

I'm pretty certain this is a horribly bad idea: but out of interest how could this be secured?

and you're right: it is a horrible idea. DO NOT do this in a production environment, especially if the URL is accessible on the Big Bad Public Internet.

Allow me to enumerate the horror in grisly detail:

  • You are using a pre-shared key (mysecretwords). Anyone can shoulder-surf this (or guess it) and run commands.
  • You are using security through obscurity ("Nobody will ever figure out that https://myserver.com/script is the URL that lets you run stuff!").
  • You are running commands as the web server user.
    This is probably not what you want, which means the web server user will need to have some sort of elevated privileges - running as root, able to sudo, etc.
  • You are using a stateless protocol (http) to run commands which probably expect a terminal, login environment, etc. -- This can be done, but doing anything but the most trivial tasks means you'll have to hack up a back-end to maintain state.
  • You are doing what ssh is supposed to do.
    Do not try to re-invent the wheel. I promise your oval wheel is not as good as the circle (ssh).
    If you can't use traditional SSH there are many web-based SSH clients,and even more Java clients. Use one of those. You can even put them behind HTTP authorization (username/password, certificates, etc.)

As for how this can be secured - you've already done pretty much everything you can: The pre-shared key acts as authentication (combined username and password) and gives a layer of encryption, though it's not necessary.
https:// encrypts your data in transit and eliminates the chance of someone sniffing the magic URL (though not the chance of them deducing it themselves).
As long as your server only allows access to the magic URL over https:// connections, and your SSL configuration on your web server is secure, you can't do much better.

Having said that, any effort you might put forth to make this more secure can't eliminate the fundamental flaws of what you're trying to do -- you may get away with it forever and never be compromised, but why add an attack surface you don't need when there are already tools that do what you want? (I might add that those tools have been written by experts, thoroughly vetted/tested by other experts, and are in wide use so if a security problem surfaces it gets fixed in a hurry...)

3
  • Great answer. A big use case for the idea is webhooks, which rules out ssh as an option. The idea was to encode unique urls for the commands you want to run, that only work on the machine you generated them from. The encrypted command url would be long and obscure enough that it should be impossible to guess (in reasonable time). Isn't that "secure"? The need to store the shared key in plaintext somewhere so the webserver can use it to decrypt sucks (but how else can it decrypt without user intervention?), and using the webserver user to execute commands also sucks.
    – timoxley
    Aug 17, 2012 at 1:47
  • 1
    There are better ways to do webhooks (poller daemons, post-commit hooks for git, a web page that creates a flag file rather than running arbitrary commands). In general any vector that allows arbitrary remote command execution is security hole, and allowing your web server to escalate its privileges is a BAD idea (This is part of why Apache won't run as root). What you're proposing does both of those things, albeit behind some security (PSK, SSL). Can you do it? Sure, if you're comfortable with the idea. Would I do it in my environment (HIPPA-regulated healthcare)? Not for love or money.
    – voretaq7
    Aug 17, 2012 at 2:27
  • Excellent point: I'm not comfortable with it. Will set a flag file and monitor that instead. Thanks for the reasoning.
    – timoxley
    Aug 17, 2012 at 2:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .