Compare commits

..

No commits in common. "master" and "v0.0.3" have entirely different histories.

5 changed files with 50 additions and 124 deletions

View File

@ -1,48 +1,26 @@
Disables the "No valid subscription" dialog on all Proxmox products.
> I am really poor and I can't afford a license. I just want to get rid of the annoying dialog.
I am really poor and I really can't afford a license. I just want to get rid of the annoying dialog on every login.
## Features
Works for:
- Proxmox VE (5.x or later, tested up to 7.0)
- Proxmox Mail Gateway (5.x or later)
- Proxmox Backup Server (1.x)
Highlights:
- Non-intrusive: zero modification of any system file
- Future-proof: persists between system updates & major upgrades
- Hassle-free: you can uninstall at any time
- Comes with standard Debian package, easy to manage and automate
- **No JavaScript is involved** in the whole process, as I believe JavaScript is harmful to developers
* Works for any version >=5 (we've tested this from 5.3 to 6.0 without any changes in the code)
* Non-intrusive, no changes to any system file, persists between system updates
* Comes with standard Debian package, easy to manage and automate
* You can uninstall at any time (you might need to wait a week for the cache to be invalidated because of https://github.com/jordansissel/fpm/issues/1472 )
## Installation
1. [Download the latest release](https://github.com/Jamesits/pve-fake-subscription/releases/latest)
1. Install: run `dpkg -i pve-fake-subscription_*.deb` as root on every node
1. (Optional) `echo "127.0.0.1 shop.maurer-it.com" | sudo tee -a /etc/hosts` to prevent fake keys from being checked against the Proxmox servers
Notes:
The initial run will be scheduled within 1 minute of the installation. If you don't want to wait, you can invoke it immediately by executing `pve-fake-subscription`.
After installation, please refrain yourself from clicking the "check" button on the "Subscription" page. It will invalidate the cache and temporary revert your instance into an unlicensed status.
The fake subscription status doesn't grant you free access to the enterprise repository. You should switch to the no-subscription repository if not already done. Use the following method:
- [Proxmox VE (PVE)](https://pve.proxmox.com/wiki/Package_Repositories#sysadmin_no_subscription_repo)
- [Proxmox Mail Gateway (PMG)](https://pmg.proxmox.com/pmg-docs/pmg-admin-guide.html#pmg_package_repositories)
- [Proxmox Backup Server (PBS)](https://pbs.proxmox.com/docs/installation.html#proxmox-backup-no-subscription-repository)
* Go to [release](https://github.com/Jamesits/pve-fake-subscription/releases/latest) to download the latest release
* Run `dpkg -i pve-fake-subscription_*.deb` as root on every Proxmox VE node
## Uninstallation
Run as root:
Run everything as root:
```shell
apt purge pve-fake-subscription
rm /etc/subscription
```
This will revert your system to a "no subscription key" status.
## Building the Package
Run everything as root on a Debian 10 system:
@ -52,3 +30,4 @@ apt-get install ruby ruby-dev rubygems build-essential
gem install --no-ri --no-rdoc fpm
./package.sh
```

View File

@ -4,18 +4,16 @@ cd "$( dirname "${BASH_SOURCE[0]}" )"
fpm -s dir -t deb --force \
-n pve-fake-subscription \
--description "Pollute the subscription cache of Proxmox VE (>=5.0), Proxmox Mail Gateway (>=5.0) & Proxmox Backup Server (>=1.0) so it won't alert you on dashboard login" \
--description "Pollute Proxmox VE (>=5.0) subscription cache so it won't alert you on dashboard login" \
--url "https://github.com/Jamesits/pve-fake-subscription" \
-v 0.0.7 \
-v 0.0.3 \
--license "GLWTS(Good Luck With That Shit) Public License" \
--depends "python3" \
--depends "libpve-common-perl" \
--architecture all \
--deb-dist "unstable" \
--deb-priority "optional" \
--deb-systemd "usr/lib/systemd/system/pve-fake-subscription.timer" \
--deb-systemd-enable --deb-systemd-auto-start --deb-systemd-restart-after-upgrade \
--after-remove "scripts/purge" \
--deb-after-purge "scripts/purge" \
./usr
# temporary removed as of https://github.com/jordansissel/fpm/issues/1472
#--deb-after-purge "scripts/purge" \

View File

@ -1,3 +1 @@
rm -f /etc/subscription
rm -f /etc/pmg/subscription
rm -f /etc/proxmox-backup/subscription
rm /etc/subscriptions

View File

@ -1,38 +1,39 @@
#!/usr/bin/env python3
# Pollute Proxmox software subscription cache so it won't alert you on dashboard login
# Should be scheduled to run every few hours with a timer to prevent cache from expiring
# If you need to prevent it checking keys against a server, please block "shop.maurer-it.com" in your hosts file
# Pollute Proxmox VE 5.x subscription cache so it won't alert you on dashboard login
# If you need to prevent it checking keys against a server, please block "shop.maurer-it.com"
import hashlib
import base64
import json
import time
import re
import sys
import os
from typing import List
from datetime import datetime, timedelta
# PVE & PMG: /usr/share/perl5/PVE/Subscription.pm
# PBS: /usr/lib/x86_64-linux-gnu/proxmox-backup/* (source code at `https://git.proxmox.com/git/proxmox-backup.git`)
# an 8-socket fake key which should be good for all situations
key = "pve8p-1145141919"
# key format
# /usr/share/perl5/PVE/API2/Subscription.pm
subscription_pattern = r'pve([1248])([cbsp])-[0-9a-f]{10}'
# /usr/share/perl5/PVE/Subscription.pm
shared_key_data = "kjfdlskfhiuewhfk947368"
server_key_file = "/etc/ssh/ssh_host_rsa_key.pub"
subscription_file = "/etc/subscription"
def get_timestamp() -> int:
return int(time.time())
# Perl's md5_base64 implementation
def md5_base64_perl(x: str) -> str:
return base64.b64encode(hashlib.md5(x.encode()).digest()).strip(b'=').decode()
# Rust's `base64::encode(tools::md5sum("something")?);`
def md5_base64_rs(x: str) -> str:
return base64.b64encode(hashlib.md5(x.encode()).digest()).decode()
# perl's md5_base64 implementation
def md5_base64(x: str) -> str:
return base64.b64encode(hashlib.md5(x.encode()).digest()).strip(b'=')
def generate_server_id(key: str) -> str:
return hashlib.md5(key.encode()).hexdigest().upper()
def generate_subscription_pve_pmg(key: str, server_ids: List[str]) -> str:
def generate_subscription(key: str, server_ids: List[str]) -> str:
localinfo = {
"checktime": get_timestamp(),
"status": "Active",
@ -45,77 +46,26 @@ def generate_subscription_pve_pmg(key: str, server_ids: List[str]) -> str:
data = base64.standard_b64encode(json.dumps(localinfo).encode()).decode()
cat = str(localinfo["checktime"]) + data + "\n" + shared_key_data
csum = md5_base64_perl(cat)
csum = md5_base64(cat).decode()
return key + "\n" + csum + "\n" + data + "\n"
# key_pattern can be find in /usr/share/perl5/{PVE,PMG}/API2/Subscription.pm
# PVE: r'pve([1248])([cbsp])-[0-9a-f]{10}'
# PMG: r'pmg([cbsp])-[0-9a-f]{10}'
def activate_pve_pmg(key: str, subscription_file: str) -> None:
# check if the key format is correct
# pattern = re.compile(key_pattern)
# if not pattern.match(key):
# print("key format error", file=sys.stderr)
# sys.exit(1)
# get machine ID
server_id = ""
with open(server_key_file, "r") as f:
server_id = generate_server_id(f.read())
# generate a license file
subscription = generate_subscription_pve_pmg(key, [server_id])
# write license file
with open(subscription_file, "w") as f:
f.write(subscription)
def generate_subscription_pbs(key: str, server_ids: List[str]) -> str:
localinfo = {
"status": "active", # PBS: `new`, `notfound`, `active`, `invalid`
"serverid": ",".join(server_ids),
"checktime": get_timestamp(),
"key": key,
"message": "Yajuu Senpai has got your back",
"productname": "YajuuSenpai",
"regdate": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"nextduedate": (datetime.now() + timedelta(seconds=1296000)).strftime("%Y-%m-%d"), # 1296000: MAX_LOCAL_KEY_AGE in src/tools/subscription.rs
"url": "https://github.com/Jamesits/pve-fake-subscription",
}
data = base64.standard_b64encode(json.dumps(localinfo).encode()).decode()
cat = str(localinfo["checktime"]) + data + shared_key_data
csum = md5_base64_rs(cat)
return key + "\n" + csum + "\n" + data + "\n"
# Key pattern: pbst-xxxxxxxxxx
def activate_pbs(key: str, subscription_file: str) -> None:
# get machine ID
server_id = ""
with open(server_key_file, "r") as f:
server_id = generate_server_id(f.read())
# generate a license file
subscription = generate_subscription_pbs(key, [server_id])
# write license file
with open(subscription_file, "w") as f:
f.write(subscription)
if __name__ == "__main__":
# Proxmox VE
if os.path.exists("/etc/pve"):
print("Activating Proxmox VE...")
activate_pve_pmg("pve8p-1145141919", "/etc/subscription")
# check if the key format is correct
pattern = re.compile(subscription_pattern)
if not pattern.match(key):
print("key format error", file=sys.stderr)
sys.exit(1)
# get machine ID
server_id = ""
with open(server_key_file, "r") as f:
server_id = generate_server_id(f.read())
# generate a license file
subscription = generate_subscription(key, [server_id])
# write license file
with open(subscription_file, "w") as f:
f.write(subscription)
# Proxmox Mail Gateway
if os.path.exists("/etc/pmg"):
print("Activating Proxmox Mail Gateway...")
activate_pve_pmg("pmgp-1145141919", "/etc/pmg/subscription")
# Proxmox Backup Server
if os.path.exists("/etc/proxmox-backup"):
print("Activating Proxmox Backup Server...")
activate_pbs("pbst-1145141919", "/etc/proxmox-backup/subscription")

View File

@ -10,3 +10,4 @@ Persistent=true
[Install]
WantedBy=timers.target