diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | README.rst | 21 | ||||
-rw-r--r-- | config/0x0.service | 18 | ||||
-rw-r--r-- | config/cleanup_0x0 | 5 | ||||
-rw-r--r-- | config/nginx.conf | 56 | ||||
-rwxr-xr-x | fhost.py | 160 | ||||
-rw-r--r-- | requirements.txt | 33 |
7 files changed, 247 insertions, 49 deletions
@@ -1,2 +1,5 @@ __pycache__/ .py[cod] +db.sqlite +up/ +*.pyc @@ -2,7 +2,7 @@ The Null Pointer ================ This is a no-bullshit file hosting and URL shortening service that also runs -`0x0.st <https://0x0.st>`_. Use with uWSGI. +`envs.sh <https://envs.sh>`_. Use with uWSGI. If you are running nginx, you should use the ``X-Accel-Redirect`` header. To make it work, include this in your nginx config’s ``server`` block:: @@ -36,16 +36,23 @@ the following: * ``ffmpegthumbnailer`` executable in ``$PATH`` +INSTALL +------- +:: + + apt update + apt install python3-pip nginx uwsgi uwsgi-plugin-python3 certbot + git clone https://github.com/envs-net/0x0.git /srv/0x0 + + cd /srv/0x0 + pip3 install --user `cat requirements.txt` + ./fhost.py db upgrade + + FAQ --- Q: - Will you ever add a web interface with HTML forms? -A: - No. This would without a doubt make it very popular and quickly exceed - my hosting budget unless I started crippling it. - -Q: What about file management? Will I be able to register an account at some point? A: diff --git a/config/0x0.service b/config/0x0.service new file mode 100644 index 0000000..ace57c0 --- /dev/null +++ b/config/0x0.service @@ -0,0 +1,18 @@ +# /etc/systemd/system/0x0.service +[Unit] +Description=null pointer +After=network.target + +[Service] +Type=simple +User=0x0 +Group=0x0 +WorkingDirectory=/srv/0x0/ +ExecStart=/usr/bin/uwsgi_python3 --socket 127.0.0.1:3031 --wsgi-file fhost.py --callable app --processes 4 --threads 2 --master +Restart=always +RestartSec=5 +StartLimitInterval=60s +StartLimitBurst=3 + +[Install] +WantedBy=default.target diff --git a/config/cleanup_0x0 b/config/cleanup_0x0 new file mode 100644 index 0000000..2278eaa --- /dev/null +++ b/config/cleanup_0x0 @@ -0,0 +1,5 @@ +# /etc/cron.d/cleanup_0x0 +SHELL=/bin/sh +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +5 0 * * * root python3 /srv/0x0/cleanup.py >/dev/null 2>&1 diff --git a/config/nginx.conf b/config/nginx.conf new file mode 100644 index 0000000..001f903 --- /dev/null +++ b/config/nginx.conf @@ -0,0 +1,56 @@ +server { + listen 80; +# listen [::]:80; + server_name 0x0.envs.net; + + access_log /var/log/nginx/0x0.envs.net-access.log; + error_log /var/log/nginx/0x0.envs.net-error.log; + + location / { + return 307 https://$host$request_uri; + } + + location /.well-known/acme-challenge/ { + alias /var/lib/letsencrypt/.well-known/acme-challenge/; + } +} + +server { + listen 443 ssl http2; + server_name 0x0.envs.net; + + ssl_certificate /etc/letsencrypt/live/0x0.envs.net/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/0x0.envs.net/privkey.pem; + ssl_protocols TLSv1.2; + ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_verify_depth 3; + ssl_dhparam /etc/ssl/certs/envs_dhparam.pem; + + ssl_session_tickets off; + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate /etc/letsencrypt/live/0x0.envs.net/chain.pem; + + add_header X-XSS-Protection "1; mode=block"; + add_header X-Content-Type-Options nosniff; + # add_header X-Frame-Options "SAMEORIGIN"; + + access_log /var/log/nginx/0x0.envs.net-access.log; + error_log /var/log/nginx/0x0.envs.net-error.log; + + root /srv/0x0; + + location / { + include uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + + # make sure this matches the port you're running uwsgi on + uwsgi_pass 127.0.0.1:3031; + } + + location /up { + internal; + } +} @@ -37,7 +37,7 @@ app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///db.sqlite" # "postgresql://0x0@/0x0" app.config["PREFERRED_URL_SCHEME"] = "https" # nginx users: make sure to have 'uwsgi_param UWSGI_SCHEME $scheme;' in your config -app.config["MAX_CONTENT_LENGTH"] = 256 * 1024 * 1024 +app.config["MAX_CONTENT_LENGTH"] = 512 * 1024 * 1024 app.config["MAX_URL_LENGTH"] = 4096 app.config["FHOST_STORAGE_PATH"] = "up" app.config["FHOST_USE_X_ACCEL_REDIRECT"] = True # expect nginx by default @@ -151,6 +151,12 @@ def is_fhost_url(url): return url.startswith(fhost_url()) or url.startswith(fhost_url("https")) def shorten(url): + # handler to convert gopher links to HTTP(S) proxy + gopher = "gopher://" + length = len(gopher) + if url[:length] == gopher: + url = "https://gopher.envs.net/{}".format(url[length:]) + if len(url) > app.config["MAX_URL_LENGTH"]: abort(414) @@ -252,6 +258,12 @@ def store_file(f, addr): return sf.geturl() def store_url(url, addr): + # handler to convert gopher links to HTTP(S) proxy + gopher = "gopher://" + length = len(gopher) + if url[:length] == gopher: + url = "https://gopher.envs.net/{}".format(url[length:]) + if is_fhost_url(url): return segfault(508) @@ -337,14 +349,17 @@ def dump_urls(start=0): @app.route("/", methods=["GET", "POST"]) def fhost(): if request.method == "POST": - sf = None + out = None if "file" in request.files: - return store_file(request.files["file"], request.remote_addr) + out = store_file(request.files["file"], request.remote_addr) elif "url" in request.form: - return store_url(request.form["url"], request.remote_addr) + out = store_url(request.form["url"], request.remote_addr) elif "shorten" in request.form: - return shorten(request.form["shorten"]) + out = shorten(request.form["shorten"]) + + if not out == None: + return Response(out, mimetype="text/plain") abort(400) else: @@ -360,27 +375,93 @@ def fhost(): if maxsizehalf.is_integer(): maxsizehalf = int(maxsizehalf) - return """<pre> -THE NULL POINTER -================ - + return """<!DOCTYPE html> +<html lang="en"> + <head> + <title>{6}</title> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + <meta name="description" content="envs.sh | Null Pointer" /> + <link rel="stylesheet" href="https://envs.net/css/css_style.css" /> + </head> + <body id="body" class="dark-mode"> + <div class="clear" style="min-width: 1150px;"> + + <div id="main"> +<div class="block"> +<h1><em>envs.sh | THE NULL POINTER</em></h1> +<h2><em>file hosting and URL shortening service.</em></h2> +<br /> +</div> + +<h2>USAGE</h2> +<pre> HTTP POST files here: - curl -F'file=@yourfile.png' {0} -You can also POST remote URLs: - curl -F'url=http://example.com/image.jpg' {0} -Or you can shorten URLs: - curl -F'shorten=http://example.com/some/long/url' {0} - -File URLs are valid for at least 30 days and up to a year (see below). -Shortened URLs do not expire. - -Maximum file size: {1} -Not allowed: {5} + <code>curl -F'file=@yourfile.png' {0}</code> +post your text directly: + <code>echo "text here" | curl -F'file=@-;' {0}</code> +you can also POST remote URLs: + <code>curl -F'url=https://example.com/image.jpg' {0}</code> +or you can shorten URLs: + <code>curl -F'shorten=http://example.com/some/long/url' {0}</code> + +file URLs are valid for at least 30 days and up to a year (see below). +shortened URLs do not expire. +not allowed: {5} +maximum file size: {1} +</pre> +<br /> +<h2>ACCEPTABLE USE POLICY</h2> +<pre> +please do not post any informations that +may violate law (login/password lists, email lists, personal information). -FILE RETENTION PERIOD ---------------------- +envs.sh is NOT a platform for: +</pre> +<br /> +<ul> + <li>child pornography</li> + <li>malware, including “potentially unwanted applications”</li> + <li>botnet command and control schemes involving this service</li> + <li>anything even remotely related to crypto currencies</li> + <li>hosting your backups</li> + <li>spamming the service with CI build artifacts</li> + <li>piracy</li> + <li>alt-right shitposting</li> +</ul> +<br /> +<h2>REQUIREMENTS</h2> +<pre> +there is only one thing you need to use this service - curl. +curl is available on most platforms, including Windows, Mac OS X and Linux. + +if you run a server and like this site, clone it! centralization is bad. +<small><a href="https://github.com/envs-net/0x0" target="_blank">https://github.com/envs-net/0x0</a></small> +you can also support it financially via liberapay. +<a href="https://en.liberapay.com/envs.net/donate" target="_blank" style="border-bottom-color: transparent;"><img src="https://img.shields.io/liberapay/receives/envs.net.svg?logo=liberapay" alt="img_shield_receives_via_liberapay"></a> +</pre> +<br /> + +<h2>ALIAS</h2> +<pre> +to make your life easier, you can add aliases to your <code>.bash_aliases</code> on Linux +and <code>.bash_profile</code> on Mac OS X. just remember to reset your terminal session after that. +<code>0file() { curl -F"file=@$1" {0} ; } +0pb() { curl -F"file=@-;" {0} ; } +0url() { curl -F"url=$1" {0} ; } +0short() { curl -F"shorten=$1" {0} ; }</code> + +now you can use: +<code>0file "yourfile.png" +# or +echo "text here" | 0pb</code> + +<em>if you want a nice wrapper, try <a href="https://git.envs.net/envs/pb">~tomasino's pb</a></em> +</pre> +<br /> +<h2>FILE RETENTION PERIOD</h2> +<pre> retention = min_age + (-max_age + min_age) * pow((file_size / max_size - 1), 3) days @@ -404,20 +485,41 @@ retention = min_age + (-max_age + min_age) * pow((file_size / max_size - 1), 3) 30 | .................... 0{2}{3} {4} +</pre> +<br /> + +<h2>ABUSE</h2> +<pre> +if you would like to request permanent deletion, please +send an email to <a href="mailto:hostmaster@envs.net?subject=Abuse%200x0%20-%20envs.sh" target="_blank">hostmaster@envs.net</a>. +please allow up to 24 hours for a response. +</pre> + </div> -ABUSE ------ +<!-- UPLOAD --> -If you would like to request permanent deletion, please contact lachs0r via -IRC on Freenode, or send an email to lachs0r@(this domain). + <div id="sidebar"> +<div class="block"> +<h2>UPLOAD DIRECTLY</h2> +<br /> +<form action="{0}" method="POST" enctype="multipart/form-data"> +<label>File:</label><br /> +<input class="form-control" type="file" name="file" style="width:250px;"><br /> +<input class="form-control" type="submit" value="Submit"> +</form> +</div> + </div> + + </div> + + </body> +</html> -Please allow up to 24 hours for a response. -</pre> """.format(fhost_url(), maxsize, str(maxsizehalf).rjust(27), str(maxsizenum).rjust(27), maxsizeunit.rjust(54), - ", ".join(app.config["FHOST_MIME_BLACKLIST"])) + ", ".join(app.config["FHOST_MIME_BLACKLIST"]),fhost_url().split("/",2)[2]) @app.route("/robots.txt") def robots(): diff --git a/requirements.txt b/requirements.txt index 7168db6..3004091 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,20 @@ -alembic -numpy -SQLAlchemy -tqdm -Flask_SQLAlchemy -Flask -humanize -requests -flask_migrate -flask_script -python_magic -short_url -validators +alembic==0.8.8 +click==6.6 +decorator==4.0.10 +Flask==0.11.1 +Flask-Migrate==2.0.0 +Flask-Script==2.0.5 +Flask-SQLAlchemy==2.1 +humanize==0.5.1 +itsdangerous==0.24 +Jinja2==2.8 +Mako==1.0.4 +MarkupSafe==0.23 +python-editor==1.0.1 +python-magic==0.4.12 +requests==2.11.1 +short-url==1.2.2 +six==1.10.0 +SQLAlchemy==1.1.3 +validators==0.11.0 +Werkzeug==0.11.11 |