From dba1def448440d49179f5dbb51b7b1990b4a01bf Mon Sep 17 00:00:00 2001
From: Raoni Meira Gabriel <2515360+raonigabriel@users.noreply.github.com>
Date: Tue, 8 Dec 2020 15:41:06 -0300
Subject: [PATCH] First version
---
Dockerfile | 26 +++++++++
README.md | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 177 insertions(+)
create mode 100644 Dockerfile
create mode 100644 README.md
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..5c57942
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,26 @@
+FROM alpine:edge
+
+# Whenever possible, install tools using the distro package manager
+RUN apk add --no-cache tini ttyd socat nginx unzip openssl openssh ca-certificates && \
+# Do some configuration for nginx
+ echo "daemon off;" >> /etc/nginx/nginx.conf && \
+ mkdir /run/nginx && \
+ echo "server { listen 80 default_server; root /var/www/localhost/htdocs; location / { try_files \$uri /index.html; } }" > /etc/nginx/conf.d/default.conf && \
+ echo "
Welcome to NginxNginx works!
" > /var/www/localhost/htdocs/index.html && \
+ chown -R 0:82 /var/www/localhost/htdocs && \
+# Download, install and configure ngrok
+ wget -q https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip && \
+ unzip ngrok-stable-linux-amd64.zip && \
+ mv ngrok /bin/ngrok && \
+ rm ngrok-stable-linux-amd64.zip && \
+ echo "web_addr: 0.0.0.0:4040" > /root/ngrok.yml && \
+# Configure a nice terminal
+ echo "export PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '" >> /etc/profile && \
+# Fake poweroff (stops the container from the inside by sending SIGTERM to PID 1)
+ echo "alias poweroff='kill 1'" >> /etc/profile
+
+ENV TINI_KILL_PROCESS_GROUP=1
+
+EXPOSE 7681 4040 80
+ENTRYPOINT ["/sbin/tini", "--"]
+CMD [ "ttyd", "-s", "3", "-t", "titleFixed=/bin/sh", "-t", "rendererType=webgl", "-t", "disableLeaveAlert=true", "/bin/sh", "-i", "-l" ]
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a509b2b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,151 @@
+# web-terminal
+
+## What is this?
+This is a lightweight (~43MB) alpine based docker image that comes pre-packaged with 2 wonderful tools:
+* [ttyd](https://github.com/tsl0922/ttyd): is a simple command-line tool for sharing terminal over the web, using websockets.
+* [ngrok](https://ngrok.com/): Creates reverse tunnels that allow access to your box from the internet.
+
+On top of those, I've added socat, nginx, openssh and openssl.
+This allows you to quickly provision an isolated (docker container) that can serve as a base for a lot of tunelling solutions. Use your imagination. :wink:
+
+If you run this with docker option **--rm** (as bellow), keep in mind that docker will remove the container once it gets stopped. This is good if you don't want to leave any garbage behind.
+
+---
+# Usage
+```sh
+# docker run --rm -d -p 7681:7681 raonigabriel/web-terminal:latest
+```
+Then access http://localhost:7681 to have a web-based shell. There is no enforced limit on the number of shells, but you can do that if needed, by customizing the ttyd daemon process.
+
+See [here](https://github.com/tsl0922/ttyd#command-line-options) and [here](https://github.com/tsl0922/ttyd/wiki/Client-Options) for more help and the **CMD** line of this image's Dockerfile.
+
+---
+# Advanced Usage
+Things start shining when you pair ttyd with ngrok. On one active shell, start nrgrok:
+
+```sh
+ngrok http -region=sa -bind-tls=true -inspect=false localhost:7681
+```
+Check its running:
+```
+ngrok by @inconshreveable (Ctrl+C to quit)
+
+Session Status online
+Session Expires 7 hours, 59 minutes
+Version 2.3.35
+Region South America (sa)
+Forwarding https://e0075a2a0966.ngrok.io -> http://localhost:7681
+```
+
+See the **Forwarding** line? You now have your docker-container, web-based ttyd shell exposed (over HTTPS) by ngrok to the Internet.
+
+Notice that on this example weŕe using a custom region (sa) and that weŕe only exposing HTTPS tunnel (no HTTP) and that we have disabled the ngrok admin console (usually it listens on port 4040).
+
+Now, let's try that with nginx. First, run the embedded nginx in the background (notice the ampersand) then start ngrok:
+```sh
+# nginx &
+# ngrok http 80
+
+ngrok by @inconshreveable (Ctrl+C to quit)
+
+Session Status online
+Session Expires 7 hours, 59 minutes
+Version 2.3.35
+Region United States (us)
+Web Interface http://127.0.0.1:4040
+Forwarding http://cf96bd9d722e.ngrok.io -> http://localhost:80
+Forwarding https://cf96bd9d722e.ngrok.io -> http://localhost:80
+```
+And now you have your nginx exposed to the internet over HTTP and HTPS. On this example, the web interface is also enabled on port 4040.
+
+Keep in mind that you can also use any other TCP based service server because ngrok supports not only HTTP/HTTPS but also raw TCP tunnels.
+
+---
+## Extras
+To terminate the container (and all its shells) from inside, run this aliased version of **poweroff**:
+```sh
+# poweroff
+```
+It **WILL NOT** shut down the host, but the container instead.
+
+---
+## Docker options (ports and volumes)
+By default, ttyd runs on port 7681 and ngrok opens and admin console on port 4040.
+
+If you want to have access to the ngrok admin console, remember to add **-p 4040:4040** to the docker call:
+```sh
+# docker run --rm -d -p 4040:4040 -p 7681:7681 raonigabriel/web-terminal:latest
+```
+
+If you know you will need access to the container internal ports, (nginx, openssh-server) just use add **-p** to the docker call, for an example:
+```sh
+# docker run --rm -d -p 80:80 -p 7681:7681 raonigabriel/web-terminal:latest
+```
+
+If you want to keep the container after it exits, remove the **--rm** from the call:
+```sh
+# docker run -d -p 7681:7681 raonigabriel/web-terminal:latest
+```
+
+If you want to use any volume(s) from the host, just bind mount it with **-v**, for an example:
+```sh
+# docker run --rm -d -v /var/run/docker.sock:/var/run/docker.sock -p 7681:7681 raonigabriel/web-terminal:latest
+```
+
+---
+## Custom (derived) image
+You can create your own custom Docker image, inherit from this one then add the tools you want and a non-root user (recomended). See the sample **Dockerfile** bellow for a custom developer image tha could be used as standard-sandboxed-environment by javascript developers:
+```docker
+FROM raonigabriel/web-terminal:latest
+RUN apk add --no-cache curl nano git g++ make npm docker-cli && \
+ npm install -g yarn typescript @angular/cli && \
+ addgroup -g 1000 docker && \
+ adduser -s /bin/sh -u 1000 -D -G docker developer && \
+ mkdir /home/developer/.ngrok2 && \
+ echo "web_addr: 0.0.0.0:4040" > /home/developer/.ngrok2/ngrok.yml && \
+ echo "tunnels:" >> /home/developer/.ngrok2/ngrok.yml && \
+ echo " nodejs:" >> /home/developer/.ngrok2/ngrok.yml && \
+ echo " proto: http" >> /home/developer/.ngrok2/ngrok.yml && \
+ echo " addr: 3000" >> /home/developer/.ngrok2/ngrok.yml && \
+ chown -R developer:docker /home/developer/.ngrok2
+
+USER developer
+WORKDIR /home/developer
+CMD [ "ttyd", "-c", "developer:password", "-s", "3", "-t", "titleFixed=/bin/sh", "-t", "rendererType=webgl", "-t", "disableLeaveAlert=true", "/bin/sh", "-i", "-l" ]
+```
+Build, then run it:
+ ```sh
+# docker build . -t js-box
+# docker run --rm --hostname jsbox -d -p 7681:7681 js-box
+```
+Because we configured the **~/.ngrok2/ngrok.yml** on this custom image, you can start the ngrok tunnel by name inside the container as following:
+ ```sh
+# ngrok start nodejs
+```
+
+And since this image has the docker-cli, you could even bind-mount the host docker socket to use it from inside the container:
+ ```sh
+# docker run --rm --hostname jsbox -v /var/run/docker.sock:/var/run/docker.sock -d -p 7681:7681 js-box
+```
+We could also use have used socat, openssh tunnels or event ngrok to forward the local docker port (2375) to another host.
+
+---
+## ngrok account and plans
+ngrok suports TLS, TCP tunnels, certs, built-in fileserver, forwarding to another machines so please take a look on https://ngrok.com/docs for more help.
+
+Keep in mind that some of the advanced features require you to create a (free) account then use the provided auth token. See https://ngrok.com/docs#getting-started-authtoken for more info.
+
+ngrok is free but also has paid plans that allow custom domains, reserved tunnels and greater control. See https://ngrok.com/pricing for plans.
+
+---
+## Licenses
+
+[Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
+
+---
+## Disclaimer
+* I am not affiliated in any way with ngrok.
+* This image comes with no warranty. Use it at your own risk.
+* I don't like Apple. Fuck off, fan-boys.
+* I don't like left-winged snowflakes. Fuck off, code-covenant.
+* I will call my branches the old way. Long live **master**, fuck-off renaming.
\ No newline at end of file