5 ms·
Pure Bash Web Server
- VWWHFSfQ 3y agoA long time ago I made a similarly pure bash version of something like tcpdump just parsing various packets and protocols off a raw socket. I wish I still had that code somewhere. It was pretty much the slowest and least-robust thing of all time but was kind of fun to play around with. cool project
- h4sh 3y agotheres literally c files in that repo how is that pure bash
- daef 3y agodid you even bother reading the readme?
- simultsop 3y agoShouldn't a program's name be sufficient?
- rovr138 3y agoThey're digging through code. The least they could do is read the readme.
- tekla 3y agoIn the same way that Hacker News is not news for hackers, no.
- bhaney 3y agoIt's not?
- nosefurhairdo 3y agoAs a hacker, this is news to me.
- scoopertrooper 3y agoThe project patches accept to handle multiple requests. However, the project works without the patch being applied, so it's fair to say that this is a pure bash web server.
- 000ooo000 3y agoYep, there's a .csv file as well so clearly Microsoft Excel is in play too. /s
- AdamJacobMuller 3y agoand it's not even a CSV, not a comma in sight! I feel lied to and I want a refund.
- skywhopper 3y agoThe C file is a patch to Bash to fix a bug in an existing Bash builtin that will be included in the next Bash release.
- cduzz 3y agoI suspect lots of people have written a "use tcpserver or inetd and feed stdout to a shell script" antics. The thing is, shell can't cope with nulls -- if you do something like n=$(gzip -9 < /etc/passwd) gzip -9 < /etc/passwd | sum echo "$n" | sum This falls apart because shell just can't deal with nulls. You can probably hack around all those issues, and may not run into this too much, at first, in a web server, but golly you'll pretty quickly fall into a pit.
- mike_d 3y agotr -dc '[[:print:]]' Will sanitize strings of non-printable characters. While it is true that you can't have nulls inside bash variables, your example actually contains the correct syntax if you just remove the first and last lines.
- cduzz 3y agowell, sure, you can use some external program do process the stdout; then it's no longer "pure bash" which is fine, nobody grades ingots of script based on if they're 90% or 99% or 70% "pure" shell. But -- importantly -- running n=$(gzip -9 < /etc/passwd | tr -dc '[[:print:]]') may process the nulls, but is it reversible? Can I now send $n into gzip -d and get whatever I put into it out? I can do things that are reversible -- n=$(gzip -9 < /etc/passwd | base64 ) But now I can't process the output "natively" except by calling base64 every time. And maybe I've gotten myself into this hole because sometimes the contents of $n have nulls and other times not? Pure shell is a road to madness. Don't ask me how I know...
- mike_d 3y agoYou are in this mess because you are supposed to be piping binary data or using temp files, not putting it in variables. Also bash scripts are just glue between external programs. I mentioned the sanitization in the context of taking user input (since we are talking about a bash web server) because I thought you were pointing out a user could do bad things by feeding in nulls.
- solatic 3y agoProjects like this reiterate just how important it is, from a security perspective, to ensure your production services are running in containers without an included shell. If an attacker can get a shell, they can do pretty much anything. Debug containers are now a stable feature in Kubernetes. It honestly boggles my mind how companies will throw so much time, money, and effort into the cybersecurity product du jour when they can get the vast majority of the value by moving everything into distroless, shell-less containers running on managed VMs that are optimized for container workloads.
- robinhoodexe 3y agoOut of curiosity, how would you run Python or R workloads in kubernetes without a distro or shell?
- jonhohle 3y agoPython needs an ld.so and libc (minimally) but not a shell or other external utilities. Shebang scripts are loaded by ld.so, not the shell.
- khrbtxyz 3y agoShebang scripts are supported directly by the kernel via the exec family of system calls, so ld.so shouldn't be involved. https://github.com/torvalds/linux/blob/master/fs/Kconfig.binfmt#L100 https://github.com/torvalds/linux/blob/master/fs/Kconfig.bin... config BINFMT_SCRIPT tristate "Kernel support for scripts starting with #!" default y help Say Y here if you want to execute interpreted scripts starting with #! followed by the path to an interpreter.
- thecodedmessage 3y agoYeah, I remember reading the code in the kernel that handles shebang a long time ago. ld.so is not involved.
- usr1106 3y agoPython with batteries included, doesn't that mean exploit tools included? No personal attack intended, I am wondering this about my own embedded product which contains Python.
- gtroja 3y agoThe conectiva Linux distro had a programmer that wrote a book on Shell Script in which he implemented a bash server, but as apache cgi scripts. I learned to properly program with that book https://www.amazon.com.br/Script-Profissional-Aurelio-Marinho-Jargas/dp/8575221523 https://www.amazon.com.br/Script-Profissional-Aurelio-Marinh...
- dzove855 3y agoCreator here: I'm really happy to see somebody shared it on hackernews :D If you have some questions, feel free to ask me
- zamadatix 3y agoHey, great work! Reading through I started wonder how necessary the loadables are? It'd be fun to have one that's not dependent on loadbales, even if it's not as clean. E.g. could mktemp be replaced with a timestamp named directory or something? Can rm be avoided by just allowing garbage to pile up? Is finfo something that can be worked around in some way?
- QuadmasterXLII 3y agoFor your consideration, the jukebox from my old CS club: #!/bin/bash cd songs if [[ ! -p q ]]; then mkfifo q fi (while true; do echo "playing" | nc -l 10000 | head -n 1 | cut -f 2 -d " " | cut -b 2- | grep -E "^[a-zA-Z0-9/:.?=-]{1,}$" > q; done) & while true; do if read a <q; then echo $a; fn=$(youtube-dl -f m4a --id --get-filename $a); youtube-dl -f m4a --id $a echo $fn mplayer $fn fi done To queue up a song, we'd find it on youtube and prepend "http://jukebox.local:10000/ http://jukebox.local:10000/" to the url
- zamadatix 3y agoMore nc, cut, grep, head, mkfifo, youtube-dl, and mplayer than anything about Bash.
- NegativeLatency 3y agoIf bash is passing and handling input from an http request that’s pretty much good enough for me.
- zamadatix 3y agoIt's not really doing that though. Nc+head/cut/grep are and youtube-dl is grabbing the data. Bash in this case is just orchestrating the order of communication between the tools doing the actual work, as a normal Bash script. The post is about doing all of this in pure bash builtins like /dev/tcp and bash functions. Not about gluing together tools which do the work.
- gtroja 3y agoNonetheless pretty wicked app made with bash
- zamadatix 3y agoYeah, it's a nifty little tool. On the other hand when a really interesting post on pure bash exposition comes up the comments section turns to talking about plain bash scripts they've made or know of instead. There are several normal scripts replied in this post and a few others via links, more than actual conversation around what the post is actually about (so far). That's all I was commenting on, not the value of the tool. It's a hill :).
- recursivedoubts 3y agosee also https://bashsta.cc https://bashsta.cc
- calvinmorrison 3y agoOf course 9front ships a rc based http server https://werc.cat-v.org/docs/web-server-setup/rc-httpd https://werc.cat-v.org/docs/web-server-setup/rc-httpd
- cf100clunk 3y agoRelated to this? https://news.ycombinator.com/item?id=7614718 https://news.ycombinator.com/item?id=7614718
- goombacloud 3y agoWhen socat is around a simple server can also be constructed with it: tee /tmp/server > /dev/null <<'EOF' #!/bin/bash set -euo pipefail SERVE="$1" TYPE="$2" read -a WORDS if [ "${#WORDS[@]}" != 3 ] || [ "${WORDS[0]}" != "GET" ]; then echo -ne "HTTP/1.1 400 Bad request\r\n\r\n"; exit 0 fi # Subfolders are not supported for security reasons as this avoids having to deal with ../../ attacks FILE="${SERVE}/$(basename -- "${WORDS[1]}")" if [ -d "${FILE}" ] || [ ! -e "${FILE}" ]; then echo -ne "HTTP/1.1 404 Not found\r\n\r\n" ; exit 0 fi echo -ne "HTTP/1.1 200 OK\r\n" echo -ne "Content-Type: ${TYPE};\r\n" LEN=$(stat -L --printf='%s\n' "${FILE}") echo -ne "Content-Length: ${LEN}\r\n" echo -ne "\r\n" cat "${FILE}" EOF chmod +x /tmp/server # switch from "text/plain" to "application/octet-stream" for file downloads socat TCP-LISTEN:8000,reuseaddr,fork SYSTEM:'/tmp/server /tmp/ text-plain' # test: curl -v http://localhost:8000/server http://localhost:8000/server
- cf100clunk 3y agoThere are other such tiny web server tricks out there too, but his GitHub README says: A purely bash web server, no socat, netcat, etc...
- dang 3y agoRelated: Show HN: A pure bash web server. No netcat, socat, etc. - https://news.ycombinator.com/item?id=29794979 https://news.ycombinator.com/item?id=29794979 - Jan 2022 (97 comments)
- cyclotron3k 3y agoYour scientists were so preoccupied with whether they could, they didn't stop to think if they should