webtty icon indicating copy to clipboard operation
webtty copied to clipboard

10kb.site certificate is expired

Open Jo-Blade opened this issue 1 year ago • 3 comments

Hello, the ssl certificate of 10kb.site is expired making the webtty -o command to fail.

Is there a way to redeploy myself the same website on my own domain ? It could be cool to not hardcode the ten-kilobyte website url I think ?

Thank you for your tool

Jo-Blade avatar May 06 '24 14:05 Jo-Blade

Whoops! I will work on fixing 10kb.site's cert and would be very down to expose that as a configurable value.

Will work on that soon, feel free to nudge me here if you don't hear back within a week or so.

maxmcd avatar May 06 '24 16:05 maxmcd

I made a solution to selfhosted 10kb.site on my domain on my machine. Use your domain instead of 10kb.my-site.ru.

Correct the WebTTY sources in ten_kb_site.go and don't forget to rebuild: Replacing this with:

var tenKbUpURL = “https://up.10kb.site/”
var tenKbURL = “https://www.10kb.site/”

To this:

var tenKbUpURL = “https://10kb.my-site.ru/” 
var tenKbURL = “https://10kb.my-site.ru/”

Next, let's configure the “server” part, which is on the original 10kb.site, but with some minor changes, since we'll do without AWS. To do this, we will need Python:

sudo apt update && sudo apt install -y python3 python3-pip && \
sudo pip3 install flask gunicorn --break-system-packages

And the directories where everything will work:

mkdir -p /var/www/10kb.my-site.ru && \
mkdir -p /var/www/10kb.my-site.ru/uploads && \
sudo chown -R www-data:www-data /var/www/10kb.my-site.ru && \
sudo chown -R www-data:www-data /var/www/10kb.my-site.ru/uploads && \
sudo chmod -R 755 /var/www/10kb.my-site.ru && \
sudo chmod -R 755 /var/www/10kb.my-site.ru/uploads

And create index.html, uploader.py, nginx-config and systemd-service. index.html

cat > /var/www/10kb.my-site.ru/index.html << EOF
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>10kb.site</title>
    <style>
      body {
        margin: 50px;
      }
      input {
        font-family: monospace;
        font-size: 12px;
      }
      a {
        text-decoration: none;
        color: black;
        border-bottom: 1px solid black;
        display: inline-block;
        line-height: 0.85;
      }
    </style>
  </head>
  <body>
    <pre style="font-size: 20px">
<a href="/">10kb.site</a> 
    </pre>
    <pre>
10kb.site is a write-only public text server.
You can upload any text you want at any file
path, as long as it's less than 10kb.


Files can never be changed or updated (except this one).

Try it out:

Uploading file to https://10kb.my-site.ru/<input id="path" type="text" value="random-filename" /> 
with body: <input id="body" type="text" />
<input id="submit" type="submit" onclick="window.onsubmit()">
<a id="out"></a>

    </pre>

    <script>
      let gbid = (d) => document.getElementById(d);
      let path = gbid("path");
      let body = gbid("body");
      let out = gbid("out");
      let submit = gbid("submit");
      path.value = Math.random().toString(35).substring(2);
      body.value = "Type something here";
      window.onsubmit = () => {
        submit.value = "loading...";
        fetch("/" + path.value, {
          method: "POST",
          body: body.value,
        })
          .then((resp) => resp.json())
          .then((resp) => {
            out.href = resp.url;
            out.innerText = resp.url;
            submit.remove();
          });
      };
    </script>
  </body>
</html>
EOF

uploader.py

cat > /var/www/10kb.my-site.ru/uploader.py << EOF
from flask import Flask, request, jsonify
import os
import datetime
import mimetypes

app = Flask(__name__)
UPLOAD_FOLDER = '/var/www/10kb.my-site.ru/uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

@app.route('/', methods=['GET'])
def index():
    return '10kb.site is a write-only public text server.\nFiles are deleted after 1 day.'

@app.route('/<path:filename>', methods=['POST'])
def upload_file(filename):
    if filename.startswith('.'):
        return jsonify({"error": "No paths that start with a ."}), 422
    if not request.data:
        return jsonify({"error": "No body"}), 422
    if len(request.data) > 1e4:
        return jsonify({"error": "File size exceeds limit"}), 422

    file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
    if os.path.exists(file_path):
        return jsonify({"error": "File already exists"}), 409

    with open(file_path, 'wb') as f:
        f.write(request.data)

    # Set file to be deleted after 1 day
    future_time = (datetime.datetime.now() + datetime.timedelta(days=1)).timestamp()
    os.utime(file_path, (int(future_time), int(future_time)))

    return jsonify({"url": f"https://10kb.my-site.ru/{filename}"}), 201

@app.route('/<path:filename>', methods=['GET'])
def get_file(filename):
    file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
    if not os.path.exists(file_path):
        return '', 404

    mime_type, _ = mimetypes.guess_type(file_path)
    with open(file_path, 'rb') as f:
        content = f.read()

    return content, 200, {'Content-Type': mime_type or 'text/plain'}

if __name__ == '__main__':
    app.run(port=5000, debug=False, use_reloader=False)
EOF

Configuration for NGINX (don't forget to create the necessary domain entries): nano /etc/nginx/sites-available/10kb.my-site.ru

server {
  listen 80;
  server_name 10kb.my-site.ru;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;
  http2 on;

  ssl_certificate /etc/letsencrypt/live/my-site.ru/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/my-site.ru/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/my-site.ru/fullchain.pem;

  root /var/www/10kb.my-site.ru;
  index index.html;

  location / {
    try_files $uri $uri/ @flask;
  }

  location @flask {
    proxy_pass http://127.0.0.1:5000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}
sudo ln -s /etc/nginx/sites-available/10kb.my-site.ru /etc/nginx/sites-enabled/ && \
sudo nginx -t && \
sudo service nginx reload && \
sudo systemctl restart nginx

Systemd-service (we will run uploader.py via gunicorn):

cat > /etc/systemd/system/10kb.my-site.ru-uploader.service << EOF
[Unit]
Description=10kb.my-site.ru-uploader Gunicorn Service
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/10kb.my-site.ru
ExecStart=/usr/local/bin/gunicorn -w 4 -b 127.0.0.1:5000 uploader:app
Restart=always

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload &&
sudo systemctl start 10kb.my-site.ru-uploader &&
sudo systemctl enable 10kb.my-site.ru-uploader &&
sudo systemctl status 10kb.my-site.ru-uploader

VladislavGatsenko avatar Sep 02 '24 21:09 VladislavGatsenko