Quick and dirty VPN key manager for jfkerman.me. Written over 2 evenings. Use at your own risk!
- Allows users to create Outline VPN keys for configured servers.
- Also supports Marzban VLESS keys.
- Very basic admin interface for managing servers and keys.
- Hacky integration with OIDC for user authentication.
- The code stinks. Even vibecoding it would be an improvement, sigh...
- OIDC integration relies on hardcoded
jfkerman-ssoprovider ID in templates. - Direct user authentication is not implemented, users are expected to log in via OIDC. All wiring should be there, though.
- A lot of code duplication between Outline and Marzban views.
- VPN API calls block processing while waiting for a response, which is not ideal.
- Key storage is insecure, keys are stored in plaintext in the database. Not really a big issue since who cares, this is just to watch Youtube in Russia, but still.
- Small bugs here and there, I didn't test everything thoroughly. Again, this was thrown together over a couple evenings.
- Only keys added via user/admin interface are managed, there is no way to import existing keys from the server as they would not be linked to any user. As a consequence, deleting keys directly on the server (with Outline Manager / Marzban) will not remove them from the database (orphaned keys).
License: MIT
Moved to settings.
The following details how to deploy this application. This is a pretty standard Django deployment, most guides should work.
NOTE
I never bothered to set up Docker. Please send me a PR if you figure it out.
- Clone the repository. Create venv, install requirements with
pip install -r requirements/production.txt. - Configure the settings for your production server (see settings).
- Add your server's IP to
ALLOWED_HOSTSinconfig/settings/production.py. - Set
DEBUG = False. - Create a production database and user, and update the
DATABASE_URLinconfig/settings/production.py. - Create necessary directories for media and static files, and update
MEDIA_ROOTandSTATIC_ROOTinconfig/settings/production.py. - Run
python manage.py collectstatic. - Run
python manage.py migrate. - For translations, run
python manage.py compilemessages. - Create a superuser with
python manage.py createsuperuser. - Install a web server (such as Nginx) and configure it to serve the application using WSGI/ASGI.
- Create systemd service files for the application and the web server (I forgot to add example files, you are on your own ¯\_(ツ)_/¯). Systemd should point to the
start.shfile. - Create another systemd service for the scheduler, and point it at
schedule.sh. - Pray & start your services.
To add a server, log in to the admin interface and create a new Outline Server object. Outline Server object has the following fields:
| Field | Description |
|---|---|
| Name | A human-readable name for the server. |
| Slug | A unique identifier for the server. |
| Country | Country where the server is located; this field is used to display flags. See possible options in jfkerman_outline/static/images/country |
| Url | URL of the server for client connections. |
| Port | Port of the server for client connections. |
| API URL | URL of the server for API connections, you can find it in installation logs or in Outline Manager. |
| API Cert | SHA256 fingerprint of the server's API certificate (self-signed). |
| Keys per user | Number of keys a user can generate for this server. |
| Max data per key | Max monthly data limit for a single key in megabytes. |
Command to obtain API Cert SHA256 fingerprint:
openssl s_client -connect <API URL> < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin