Skip to content

Instantly share code, notes, and snippets.

@stefan2904
Created October 5, 2016 15:49
Show Gist options
  • Save stefan2904/ac01e6502600c3a44faa9e2ae9848390 to your computer and use it in GitHub Desktop.
Save stefan2904/ac01e6502600c3a44faa9e2ae9848390 to your computer and use it in GitHub Desktop.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
#!/bin/sh
<<\EOF
<!--
Hey, you found the source code!
That is a sign you hopefully know better than to blindly run unknown commands
from the internet and/or are a curious person. We like you already.
What this command will actually do, is set you up with a free "shell" account
on one of our servers, that you can use as you see fit. It will also set you
up with email, IRC, and other things on your shell, so you can keep in touch
and learn/make awesome things with us.
Don't trust us? Good! You probably don't know us (yet) so you shouldn't.
To help address this we GPG sign this shell-setup script so you can verify
it has not been changed by a third party before you run it by doing:
> gpg --verify <(curl https://hashbang.sh)
The safest method of running a script from a source you don't trust is to:
Download and verify integrity with GnuPG
> gpg --recv-keys 0xD2C4C74D8FAA96F5
> curl https://hashbang.sh | gpg -o hashbang.sh
Inspect source code
> less hashbang.sh
Run
> chmod +x hashbang.sh
> ./hashbang.sh
As an advanced alternative you can bypass using this script and hit our user
provisioning API directly with an SSH Public Key and desired username:
> curl https://hashbang.sh/server/stats
{ "server.hashbang.sh": { infos ...}, ... }
> curl -d '{"user":"someuser","key":"'"$(cat ~/.ssh/id_rsa.pub)"'","host":"someHost.hashbang.sh"}' -H 'Content-Type: application/json' https://hashbang.sh/user/create
We look forward to seeing you on the other side.
Note: #! has never provided user data to any government agency.
Pay close attention to the removal of this notice.
- -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>&lrm;</title>
<meta name="viewport" content="initial-scale = 1, maximum-scale=1, user-scalable = 0"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<meta name="HandheldFriendly" content="true"/>
<meta name="MobileOptimized" content="320"/>
<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'>
<style type="text/css">
* {
text-indent:-9999px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
html {
background:black;
color:black;
}
body {
display:block;
position:fixed;
top:50%;
left:50%;
margin-top:-160px;
margin-left:-160px;
width:320px;
height:320px;
color:#DDD;
overflow:hidden;
}
h1 {
text-indent:0px;
font-family: 'Montserrat', cursive;
position:absolute;
top:-50px;
left:10px;
right:0px;
line-height:0px;
font-size:280px;
}
a {
color:white;
text-decoration:none;
}
code {
text-indent:0px;
display:block;
position:absolute;
bottom:0px;
left:0px;
right:0px;
text-align:center;
font-size:20px;
}
</style>
</head>
<body>
<script>
window.location="#!"
var link = document.createElement("link");
link.type = "image/png";
link.rel = "icon";
link.href = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQAAAAA3iMLMAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAd2KE6QAAAAYSURBVAjXY2CAAck+EKp/B0II9gMoGwYA4+MJkeae/NUAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTQtMDUtMTdUMTM6MzI6MTMtMDQ6MDB7pieOAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE0LTA1LTE3VDEzOjMxOjQ4LTA0OjAwqyt+rwAAAABJRU5ErkJggg==";
document.getElementsByTagName("head")[0].appendChild(link);
</script>
<h1>#!</h1>
<a href="view-source:https://hashbang.sh">
<code>curl hashbang.sh | gpg > hashbang.sh</code>
</a>
</body>
</html>
<!--
EOF
#!/bin/sh
# This script first and foremost attempts to be POSIX compliant.
# Secondly, it attempts to be compatible with as many shell implementations as
# possible to provide an easy gateway for new users.
# If we're using bash, we do this
if [ -n "$BASH" ]; then
shopt -s extglob
set -o posix
# Bail out if any curl fails
set -o pipefail
fi
# POSIX doesn't specify mktemp(1).
# This was checked against manpages for:
# - OpenBSD: http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/mktemp.1?query=mktemp&sec=1
# - FreeBSD: https://www.freebsd.org/cgi/man.cgi?query=mktemp&sektion=1
# - OS X 10.9: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/mktemp.1.html
# - Todd Miller's mktemp: http://www.mktemp.org/manual.html
# - Solaris 10: https://docs.oracle.com/cd/E23823_01/html/816-5165/mktemp-1.html
# - HP Tru64 UNIX: https://web.archive.org/web/20120117215524/http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/V51B_HTML/MAN/MAN1/0251____.HTM
# - GNU coreutils: https://www.gnu.org/software/coreutils/manual/html_node/mktemp-invocation.html#mktemp-invocation
tmp_hb_dir="$(mktemp -d -t hashbang.XXXXXX)"
trap 'rm -rf -- "${tmp_hb_dir}"' EXIT
# Fetch host data for later.
# If this fails there is no point in proceeding
host_data="${tmp_hb_dir}/server_stats"
curl -sfH 'Accept:text/plain' https://hashbang.sh/server/stats > "$host_data"
err=$?
echo >> "$host_data"
bail() {
echo " "
echo " If you think this is a bug, please report it to ";
echo " -> https://github.com/hashbang/hashbang.sh/issues/";
echo " ";
echo " The installer will not continue from here...";
echo " ";
exit 1
}
[ $err -ne 0 ] && bail
# check if can write to file
checkutil() {
printf '%s' " * Checking for $1..."
if command -v "$1" >/dev/null; then
printf "ok!\n";
return 0;
else
printf "not found!\n";
return 1;
fi
}
# This function can be called with two parameters:
#
# First is obligatory, and is the "question posed".
# For instance, one may ask "is pizza your favorite meal?", to which the
# responder may answer Y (yes) or N (no).
#
# Second parameter is optional, and can be either Y or N.
# The reasoning behind this is to have a default answer to the question,
# resulting in the responder being able to simple press [enter] and skip
# pressing Y or N, giving the default answer instead.
ask() {
while true; do
prompt=""
default=""
if [ "${2}" = "Y" ]; then
prompt="Y/n"
default=Y
elif [ "${2}" = "N" ]; then
prompt="y/N"
default=N
else
prompt="y/n"
default=
fi
# Ask the question
echo " "
printf "%s [%s] " "$1" "$prompt"
read REPLY
# Default?
if [ -z "$REPLY" ]; then
REPLY=$default
fi
# Check if the reply is valid
case "$REPLY" in
Y*|y*) return 0 ;;
N*|n*) return 1 ;;
esac
done
echo " "
}
# generate ssh kypair
makekey() {
( checkutil ssh-keygen && checkutil ssh ) || bail
if [ ! -e "$1" ]; then
ssh-keygen -t rsa -C "#! $username" -f "$1"
if [ $? -ne 0 ]; then
echo " Unable to make key with that location"
else
chmod 600 "$1"
echo " Successfully generated key"
return
fi
else
if ask " Unable to generate key, do you want to delete the file?" N; then
rm -f "$1"
if [ $? -ne 0 ]; then
echo " Unable to delete file, resetting"
else
echo " File deleted"
ssh-keygen -t rsa -C "#! $username" -f "$1"
if [ $? -ne 0 ]; then
echo " Unable to generate key, resetting"
fi
fi
else
echo " Unable to make key with that path, resetting"
fi
fi
}
clear;
echo " _ _ __ ";
echo " _| || |_ | | Welcome to #!. This network has three rules:";
echo "|_ __ _|| | ";
echo " _| || |_ | | 1. When people need help, teach. Don't do it for them";
echo "|_ __ _||__| 2. Don't use our resources for closed source projects";
echo " |_||_| (__) 3. Be excellent to each other";
echo " ";
echo " We are a diverse community of people who love teaching and learning.";
echo " Putting a #! at the beginning of a \"script\" style program tells a ";
echo " computer that it needs to \"do something\" or \"execute\" this file.";
echo " Likewise, we are a community of people that like to \"do stuff\".";
echo " ";
echo " If you like technology, and you want to learn to write your first";
echo " program, learn to use Linux, or even take on interesting challenges";
echo " with some of the best in the industry, you are in the right place.";
echo " ";
echo " The following will set you up with a \"shell\" account on one of our";
echo " shared systems. From here you can run IRC chat clients to talk to us,";
echo " access to personal file storage and web hosting, and a wide range of";
echo " development tools. ";
echo " ";
echo " Everything should work perfectly, unless it doesn't";
echo " ";
echo " Please report any issues here: ";
echo " -> https://github.com/hashbang/hashbang.sh/issues/";
echo " ";
printf " If you agree with the above and wish to continue, hit [Enter] ";
read _
clear
echo " ";
echo " ";
printf -- ' %72s\n' | tr ' ' -;
echo " ";
echo " First, your system must be properly configured with the required";
echo " utilities and executables.";
echo " We will perform a short check for those now.";
echo " NOTE: If you see this message, it is likely because something is";
echo " not installed. Check the list below, and install any";
echo " missing applications.";
checkutil expr || bail
checkutil gpg || bail
( checkutil ssh-keygen && checkutil ssh ) || bail
checkutil curl || bail
clear;
echo " ";
echo " ";
printf -- ' %72s\n' | tr ' ' -;
echo " ";
echo " To create your account we first need a username.";
echo " ";
echo " A valid username must:";
echo " * be between between 1 and 31 characters long";
echo " * consist of only 0-9 and a-z (lowercase only)";
echo " * begin with a letter";
echo " ";
echo " Traditional unix usernames are first initial, optional middle initial,";
echo " and the first 6 characters of the last name, but feel free to use ";
echo " whatever you want";
echo " ";
while [ "x$username" = "x" ]; do
printf " Username: ";
read input;
# Keep in sync with the description and
# https://github.com/hashbang/provisor/blob/master/provisor/utils.py#L77
if echo "$input" | grep -E "^[a-z][a-z0-9]{0,30}$" >/dev/null; then
username="$input"
else
echo " ";
echo " \"$input\" is not a valid username."
echo " Please read the instructions and try again"
echo " ";
fi
done
echo " ";
printf -- ' %72s\n' | tr ' ' -;
echo " ";
echo " Now we will need an SSH Public Key."
echo " ";
echo " SSH Keys are a type of public/private key system that let you identify";
echo " yourself to systems like this one without ever sending your password ";
echo " over the internet, and thus by nature we won't even know what it is";
for keytype in id_ed25519 id_ecdsa id_rsa id_dsa; do
if [ -e ~/.ssh/${keytype}.pub ] && [ -e ~/.ssh/${keytype} ]; then
if ask " We found a public key in [ ~/.ssh/${keytype}.pub ]. Use this key?" Y; then
private_keyfile="${HOME}/.ssh/${keytype}"
public_key="$(cat ~/.ssh/${keytype}.pub)"
break
fi
fi
done
if [ -z "$public_key" ]; then
echo " No SSH key for login to server found, attempting to generate one"
while true; do
echo " "
printf " Path to new or existing connection key (~/.ssh/id_rsa): "
read private_keyfile
if [ -z "$private_keyfile" ]; then
private_keyfile="$HOME/.ssh/id_rsa"
fi
private_keyfile=$(echo "$private_keyfile" | sed "s@~@$HOME@")
echo " "
if [ ! -e "$private_keyfile" ] && [ ! -e "$private_keyfile.pub" ]; then
if ask " Do you want us to generate a key for you?" Y; then
if [ -e "$private_keyfile" ]; then
if ask " File exists: $private_keyfile - delete?" Y; then
rm "$private_keyfile"
if [ -e "${private_keyfile}.pub" ]; then
rm "${private_keyfile}.pub"
fi
makekey "$private_keyfile"
fi
else
makekey "$private_keyfile"
fi
public_key=$(cat "${private_keyfile}.pub")
fi
elif [ ! -e "$private_keyfile" ] && [ -e "${private_keyfile}.pub" ]; then
if ask " Found public keyfile, missing private. Do you wish to continue?" N; then
echo " Using public key ${private_keyfile}.pub"
break
else
echo " Resetting"
fi
elif [ ! -e "${private_keyfile}.pub" ]; then
echo " Unable to find public key ${private_keyfile}.pub"
else
echo " Using public key ${private_keyfile}.pub"
break
fi
done
public_key=$(cat "${private_keyfile}.pub")
fi
n=0
echo
printf -- ' %72s\n' | tr ' ' -;
echo
echo " Please choose a server to create your account on."
echo
printf -- ' %72s\n' | tr ' ' -;
printf -- ' %-1s | %-4s | %-36s | %-8s | %-8s\n' \
"#" "Host" "Location" "Users" "Latency"
printf -- ' %72s\n' | tr ' ' -;
while IFS="|" read host _ location current_users max_users; do
host=$(echo "$host" | sed 's/\([a-z0-9]\+\)\..*/\1/g')
latency=$(ping -c 1 "${host}.hashbang.sh" | awk -F'=' '/time=[0-9]+/ { print $NF }')
n=$((n+1))
printf -- ' %-1s | %-4s | %-36s | %8s | %-8s\n' \
"$n" \
"$host" \
"$location" \
"$current_users/$max_users" \
"$latency"
done < "$host_data"
printf -- ' %72s\n' | tr ' ' -;
echo
while true; do
printf ' Enter Number 1-%i : ' "$n"
read choice
number=$(echo "$choice" | awk '/[^0-9]/ { print "no" }')
if [ "$number" != "no" ] && \
[ "$choice" -ge 1 ] && \
[ "$choice" -le $n ]; then
break;
fi
done
host=$(head -n "$choice" "$host_data" | tail -n1 | cut -d \| -f1)
if [ -n "$public_key" ] && [ -n "$username" ]; then
echo " ";
printf -- ' %72s\n' | tr ' ' -;
echo " ";
echo " We are going to create an account with the following information";
echo
echo " Username: $username";
echo " Public Key: ${private_keyfile}.pub";
echo " Host: $host";
echo
if ask " Does this look correct?" Y ; then
echo
printf ' Creating your account... '
format="{\"user\":\"$username\",\"key\":\"$public_key\",\"host\":\"$host\"}"
headers="${tmp_hb_dir}/create_headers"
output=$(curl -H "Content-Type: application/json" -d "$format" https://hashbang.sh/user/create -D "$headers" 2>&-)
status=$(awk 'NR == 1 { print $2; exit }' "$headers")
if [ "$status" -eq 200 ]; then
echo " Account Created!"
else
echo " Account creation failed: $(echo "$output" | sed -e 's/.*\"message\": \?\"\([^\"]\+\)\".*/\1/')";
bail
fi
if ask " Would you like to add trusted/signed keys for our servers to your .ssh/known_hosts?" Y ; then
echo " Downloading GPG keys"
echo " "
gpg --keyserver keys.gnupg.net \
--recv-keys 0xD2C4C74D8FAA96F5
echo " "
echo " Downloading key list"
echo " "
curl -s 'https://hashbang.sh/static/known_hosts.asc' |
gpg --decrypt --output "${tmp_hb_dir}/known_hosts"
if [ $? -ne 0 ]; then
echo " "
echo " Unable to verify keys"
bail
fi
cat "${tmp_hb_dir}/known_hosts" >> ~/.ssh/known_hosts
echo " "
echo " Keys downloaded and saved"
fi
if ask " Would you like an alias (shortcut) added to your .ssh/config?" Y ; then
printf '\nHost hashbang\n HostName %s\n IdentitiesOnly yes\n User %s\n IdentityFile %s\n' \
"${host}" "$username" "$private_keyfile" \
>> ~/.ssh/config
echo " You can now connect any time by entering the command:";
echo " ";
echo " > ssh hashbang";
else
echo " You can now connect any time by entering the command:";
echo " ";
echo " > ssh ${username}@${host}";
fi
else
echo " Please re-run script to make corrections.";
bail
fi
if ask " Do you want us to log you in now?" Y; then
if [ -e "$private_keyfile" ]; then
ssh -i "$private_keyfile" "${username}@${host}"
else
ssh "${username}@${host}"
fi
fi
fi
# exit [n]. if [n] is not specified, then exit shall use the return code of the
# last command.
exit 0
-----BEGIN PGP SIGNATURE-----
iQIcBAEBCgAGBQJXIQWpAAoJENLEx02Pqpb1N4gQAKaOrKVqA7jcmfZKZGvqSmBe
ZxuOZ11GOVCy9y6DmXa2LHxW5npO/WJOXuzAWrGC/RwM02jozebeiVklc9RSDEz2
obnK4XGVlkXKRCgSbrJBX9/7Jw+u0v1QMfUOuSde1IzsLWZJ6Rwq216qSy+ClTY8
QvABh5Ej9C2lwkG/N+5Y1VUmCsTD50DXtX8VwS21BjexJ+4vajKCnaAH5gMRDLQx
GFzHUM92hdMAI+UegbmtAjbj6ORrfwjFGhXmeBxXdh0TIBDFm72mHhZdLx+OcTFQ
Rd3R1XnnUx9aeb5PsYTcmc6Qp4jU5F9oK4v5YBE5A91qsUGfX0LkHyAG+kM3T5gj
NUI33LoAS44+fc5EUZy//v3H103Mszwc9j51gFZA/RnfSHvrCIUmPKOA5Um8LFKJ
aby6yXcP6ODqgmsYfmSiCywfoYAinlZpC7KsM3Hg4b6zKdZX7jaomBqeAORoNImU
aMCEgA1PKqVPFQ2q4yApW9me5Jkn/tnNzjYyFUqMzWtEtXeQ6Ts1EuurrzK9XTyn
iFO/gDyIdhHZY4L73g/Kiogeru8jw43sjicXfdqIv7/Ihz7D2sP2EYSQM6sXYRbZ
aN+YnlUF3wP9tloUv/2Qj5nY6++TCm7bpCUHJFNj0qYIlO8O908jAAkXq+/IfXjf
wrDdeLVX7X5579pzHwHY
=E663
-----END PGP SIGNATURE-----
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment