Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Bashttpd - An http server in bash (github.com/avleen)
74 points by alpb on Sept 16, 2012 | hide | past | favorite | 36 comments


Some other cool guy wrote this (https://github.com/tlrobinson/wwwoosh) sinatra framework in bash. I am using it to control the lights in my house with my phone.

A very simple js frontend sends get requests to wwwoosh, and some bash commands get executed to control a relays board that turns the lights on and of.

It's very simple, consumes almost no memory and is very reliable.


How about ddshttpd (http://dd-sh.intercal.org.uk/web-server/)? A web server written using only sh(1), dd(1), and echo(1). It even supports running server side scripts ("ddsh-bin") and setting content type based on file extension.

I'm somewhat saddened to see that they don't own dd.sh domain anymore. It was at least twice as cute as no.de is :)


I went to university (Edinburgh) with the author of dd.sh. I remember him as a crazy Italian in the classic mold. As a first-year undergraduate in the computer science department he convinced me to forkbomb the department's main 30-way computer server. What he didn't mention was that the head of department was running a bunch of stuff on there at the time. My resulting heart rate was eclipsed only by the load average on the host, which if memory serves pegged at 512. Now I knew how the sorcerer's apprentice felt.

In a demonstration of genius he then proceeded to shutdown this particular forkbomb, using - you guessed it - only dd and sh ...


You should clean the data from the user before passing it to the shell. There is a trivial remote command execution vulnerability in the URL ("echo 'GET /;$(cat /etc/passwd)'|nc ..."). I assume there are more.


There are likely many MANY more :-) I suppose I should cook up a sanitising method. Fortunately, stackoverflow to the rescue! http://stackoverflow.com/questions/89609/in-a-bash-script-ho...


We have basic filtering now :-)


You shouldn't have to sanitize if you quote your variables properly. If general, the rules for "$foo" are "parse first, expand afterwards" while those for $foo are "parse, expand, parse again", so

  foo="hello    world"
  echo $foo # prints "hello world" [2 arguments]
  echo "$foo" # prints "hello    world" [1 argument]
Note that you can't trivially inject a command this way, though you can inject arbitrary arguments:

  foo="; ls"
  echo $foo # prints "; ls"
I would recommend never using test ([) with more than three arguments. Once you start doing -a and -o, then people can inject confusing values for variables, making it impossible to parse:

  foo='!'
  bar='2'
  [ "$foo" = 1 -a "$bar" = 2 ] # -bash: [: too many arguments
Since test runs a subprocess, it can't tell the difference between data and arguments. Instead, you should do something like this:

  foo='!'
  bar='2'
  [ "$foo" = 1 ] && [ "$bar" = 2 ]
(This also has the advantage of being way more legible.)


You can also solve that problem with double square brackets:

  [[ "$foo" = 1 && "$bar" = 2 ]]


Really, we should be using double square brackets. We're not aiming for POSIX compliance and double square solves a lot of problems.


Why not using /bin/sh? Didn't saw a bash specific tool (except the function syntax which is easy to convert). And if you really want to use bash, please use #!/usr/bin/env bash so that it is more compatible.


It's likely I'll want to do some more complex stuff in bash, rather than pure sh. My preferred shell is zsh but of the more advanced shells, bash is the most prevalent.

I've pushed the change to use /usr/bin/env bash :-)


What kind of environments contain bash in a different location than /bin/bash, and why is it done that way?


FreeBSD for example does not have bash installed by default since bash is not part of FreeBSD operating system and when it is installed (using ports or packages) it's installed into /usr/local where all other 3rd party software is installed.


Some systems use /bin and /sbin as directories containing binaries capable of being used in single-user mode (where only / is mounted), meaning a pretty bare experience. root's shell would probably not be bash in this case and bash would probably be optional/a package and would be installed elsewhere.


FreeBSD users have bash added in and so is located at /usr/local/bin/bash


Correct, in my case its OpenBSD which stores all "third-party" packages in /usr/local


> please use #!/usr/bin/env bash so that it is more compatible.

Presuming env is in /usr/bin, thus obviating the compatible argument somewhat.


Apart from when you're on red hat or a derived distro, where the command would need to be "#!/bin/env bash"...


These kind of projects are always so damn cool, but so utterly useless :(


I don't think they are useless. They keep the 'mystery' out of web servers. It is self limiting for folks when they see a piece of software and think of it as an impenetrable wall which cannot be breached or changed.

I proposed an internal web api at work for some hardware that needed to call out and test an address against a database of known problems. The initial response was the pain of setting up the infrastructure of a web server just for this one thing, was "huge" except it isn't really huge, its like 12 lines of perl or python code. People need to know that you can do that to see the pocket web server as a neat solution.


completely disagree. Want to create a quick file server to test a design or an html page in a browser? Yes you could use python SimpleHTTP but python is a dependency that not all times we have access too.


Do you have OpenSSL? I assume you do. Look at the man page for s_server and gape in awe at the -www -WWW and -HTTP options.

The only catch is that you need to rig up a key, it being SSL and all. -nocert probably won't play nicely with your browser.



Simplehttp Does the trick well enough. It exists on all Linux and OSX we use. I think he is implying that these projects won't have an industrial use.


I am also wondering the scenarios that I may need.


I think this one has a better name, Bash on Balls.

https://github.com/jayferd/balls


Excellent!

People might say that this is utterly useless, but actually in one big companies I worked for we had something like this (not really http but still bash server) to execute and control tests running on the machine. The beauty of the bash is that runs on 100% clean servers which is great for product testing.


This is an interesting novelty, but it can't ever be used in the real world, no matter how far along it gets, because bash is much more susceptible to security holes than normal programming languages.


There are many benefits to projects like this. I would argue that this thread is the biggest benefit - people are sharing knowledge on shell scripting, and I'll bet you one hamburger that at least 5 people learn something new as a result.

That makes it worth it :-)

It also gets people thinking, being creative and doing something "fun". Sometimes you just have to do fun things and see where they lead.


"Yes, but", it's kind of unfortunate that at the time of writing your comment is placed next to a comment by y0ghur7_xxx, who is actually using a bash based web server to control lights with his iPhone. It's hard to argue that this is not 'real life'. On the other hand, you are right.


But real world doesn't need to mean production level, it's useful for another set of reasons.


Don't let the perfect be the enemy of the good.


How does this differ from the cgi-bins of yesteryear?

Also, regarding environment sandboxing: it's probably worth looking at the direction the CGI spec went in.


It depends where you draw the line. CGI's were passed many variables and an environment by the web server. In that respect, this is closer to a web server - the only thing it doesn't handle is the very lowest level network listening.


>the only thing it doesn't handle is the very lowest level network listening.

Which makes it a bit imprecise to call it a web server made with bash (as it requires netcat). I clicked on the title already wondering how would it be possible to open a socket with bash only.


I think you're being a little overly pedantic.




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

Search: