mirror of
https://github.com/Jamesits/pve-fake-subscription
synced 2025-12-06 11:07:00 -05:00
Compare commits
No commits in common. "master" and "v0.0.9" have entirely different histories.
55
README.md
55
README.md
@ -1,7 +1,5 @@
|
||||
# pve-fake-subscription
|
||||
|
||||

|
||||
|
||||
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.
|
||||
@ -10,9 +8,9 @@ Disables the "No valid subscription" dialog on all Proxmox products.
|
||||
|
||||
Works for:
|
||||
|
||||
- Proxmox VE (5.x or later; 3.x and 4.x [require some manual actions](#compatibility-information-for-old-proxmox-ve-versions))
|
||||
- Proxmox VE (5.x or later, tested up to 7.2)
|
||||
- Proxmox Mail Gateway (5.x or later)
|
||||
- Proxmox Backup Server (1.x or later)
|
||||
- Proxmox Backup Server (1.x)
|
||||
|
||||
Highlights:
|
||||
|
||||
@ -22,9 +20,7 @@ Highlights:
|
||||
- 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
|
||||
|
||||
## Usage
|
||||
|
||||
### Installation
|
||||
## 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
|
||||
@ -32,6 +28,8 @@ Highlights:
|
||||
|
||||
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:
|
||||
@ -40,7 +38,7 @@ The fake subscription status doesn't grant you free access to the enterprise rep
|
||||
- [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)
|
||||
|
||||
### Uninstallation
|
||||
## Uninstallation
|
||||
|
||||
Run as root:
|
||||
|
||||
@ -50,49 +48,10 @@ apt purge pve-fake-subscription
|
||||
|
||||
This will revert your system to a "no subscription key" status.
|
||||
|
||||
## Development Notes
|
||||
|
||||
### Building the Package
|
||||
## Building the Package
|
||||
|
||||
Install [nFPM](https://nfpm.goreleaser.com/install/), then:
|
||||
|
||||
```shell
|
||||
./package.sh
|
||||
```
|
||||
|
||||
### Compatibility Information for Old Proxmox VE Versions
|
||||
|
||||
#### PVE 4.x
|
||||
|
||||
After installation or updates, run:
|
||||
```shell
|
||||
sed -i'' -e's/pve8p/pve4p/g' /usr/bin/pve-fake-subscription
|
||||
pve-fake-subscription
|
||||
```
|
||||
|
||||
#### PVE 3.x
|
||||
|
||||
Installation with `dpkg -i` will not work because of missing dependencies. Use the following script to install manually:
|
||||
```shell
|
||||
# extract the deb package
|
||||
mkdir -p /tmp/pve-fake-subscription
|
||||
dpkg-deb -x pve-fake-subscription_*.deb /tmp/pve-fake-subscription
|
||||
|
||||
# patch and install the script
|
||||
sed -i'' -e's/python3/python/g' -e's/pve8p/pve4p/g' /tmp/pve-fake-subscription/usr/bin/pve-fake-subscription
|
||||
mv /tmp/pve-fake-subscription/usr/bin/pve-fake-subscription /usr/local/bin/
|
||||
|
||||
# install the timer
|
||||
ln -sf /usr/local/bin/pve-fake-subscription /etc/cron.hourly/pve-fake-subscription
|
||||
|
||||
# invoke it once
|
||||
/usr/local/bin/pve-fake-subscription
|
||||
|
||||
# remove temporary files
|
||||
rm -rf /tmp/pve-fake-subscription
|
||||
```
|
||||
|
||||
Removal:
|
||||
```shell
|
||||
rm -f /usr/local/bin/pve-fake-subscription /etc/cron.hourly/pve-fake-subscription /etc/subscription
|
||||
```
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
name: "pve-fake-subscription"
|
||||
arch: "all"
|
||||
platform: "linux"
|
||||
version: "0.0.11"
|
||||
version: "0.0.9"
|
||||
version_schema: "semver"
|
||||
version_metadata: "git"
|
||||
|
||||
epoch: 0
|
||||
release: 1
|
||||
section: "admin"
|
||||
priority: "optional"
|
||||
priority: "optinal"
|
||||
|
||||
maintainer: "Nobody <nobody@example.com>"
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
after_upgrade() {
|
||||
:
|
||||
|
||||
if command -v systemctl >/dev/null; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
debsystemctl=$(command -v deb-systemd-invoke || echo systemctl)
|
||||
if ! systemctl is-enabled pve-fake-subscription.timer >/dev/null
|
||||
@ -14,9 +13,6 @@ after_upgrade() {
|
||||
else
|
||||
$debsystemctl restart pve-fake-subscription.timer >/dev/null || true
|
||||
fi
|
||||
else
|
||||
ln -sf /usr/bin/pve-fake-subscription /etc/cron.hourly/pve-fake-subscription
|
||||
fi
|
||||
|
||||
pve-fake-subscription
|
||||
}
|
||||
@ -24,14 +20,10 @@ after_upgrade() {
|
||||
after_install() {
|
||||
:
|
||||
|
||||
if command -v systemctl >/dev/null; then
|
||||
systemctl --system daemon-reload >/dev/null || true
|
||||
debsystemctl=$(command -v deb-systemd-invoke || echo systemctl)
|
||||
systemctl preset pve-fake-subscription.timer >/dev/null || true
|
||||
$debsystemctl start pve-fake-subscription.timer >/dev/null || true
|
||||
else
|
||||
ln -sf /usr/bin/pve-fake-subscription /etc/cron.hourly/pve-fake-subscription
|
||||
fi
|
||||
|
||||
pve-fake-subscription
|
||||
}
|
||||
|
||||
@ -6,8 +6,6 @@ after_remove() {
|
||||
rm -f /etc/subscription
|
||||
rm -f /etc/pmg/subscription
|
||||
rm -f /etc/proxmox-backup/subscription
|
||||
|
||||
rm -f /etc/cron.hourly/pve-fake-subscription
|
||||
}
|
||||
|
||||
after_purge() {
|
||||
|
||||
@ -3,8 +3,6 @@
|
||||
# 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
|
||||
|
||||
from __future__ import print_function
|
||||
import hashlib
|
||||
import base64
|
||||
import json
|
||||
@ -12,6 +10,7 @@ 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
|
||||
@ -19,40 +18,30 @@ from datetime import datetime, timedelta
|
||||
shared_key_data = "kjfdlskfhiuewhfk947368"
|
||||
server_key_file = "/etc/ssh/ssh_host_rsa_key.pub"
|
||||
|
||||
# Default license keys
|
||||
lic_pve = "pve8p-1145141919"
|
||||
lic_pmg = "pmgp-1145141919"
|
||||
lic_pbs = "pbst-1145141919"
|
||||
|
||||
# UI customization
|
||||
ui_product_name = "YajuuSenpai"
|
||||
ui_message = "Yajuu Senpai has got your back"
|
||||
ui_url = "https://github.com/Jamesits/pve-fake-subscription"
|
||||
|
||||
def get_timestamp():
|
||||
def get_timestamp() -> int:
|
||||
return int(time.time())
|
||||
|
||||
# Perl's md5_base64 implementation
|
||||
def md5_base64_perl(x):
|
||||
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):
|
||||
def md5_base64_rs(x: str) -> str:
|
||||
return base64.b64encode(hashlib.md5(x.encode()).digest()).decode()
|
||||
|
||||
def generate_server_id(key):
|
||||
def generate_server_id(key: str) -> str:
|
||||
return hashlib.md5(key.encode()).hexdigest().upper()
|
||||
|
||||
def dt_string(format, offset_secs=0):
|
||||
def dt_string(format: str, offset_secs: int = 0) -> str:
|
||||
return (datetime.now() + timedelta(seconds=offset_secs)).strftime(format)
|
||||
|
||||
def generate_subscription_pve_pmg(key, server_ids, product_name=ui_product_name):
|
||||
def generate_subscription_pve_pmg(key: str, server_ids: List[str]) -> str:
|
||||
localinfo = {
|
||||
"checktime": get_timestamp(),
|
||||
"status": "Active",
|
||||
"key": key,
|
||||
"validdirectory": ",".join(server_ids),
|
||||
"productname": product_name,
|
||||
"productname": "YajuuSenpai",
|
||||
"regdate": dt_string("%Y-%m-%d %H:%M:%S"),
|
||||
"nextduedate": dt_string("%Y-%m-%d", 1296000),
|
||||
}
|
||||
@ -64,10 +53,9 @@ def generate_subscription_pve_pmg(key, server_ids, product_name=ui_product_name)
|
||||
return key + "\n" + csum + "\n" + data + "\n"
|
||||
|
||||
# key_pattern can be find in /usr/share/perl5/{PVE,PMG}/API2/Subscription.pm
|
||||
# PVE5+: r'pve([1248])([cbsp])-[0-9a-f]{10}'
|
||||
# PVE3/4: r'pve([124])([cbsp])-[0-9a-f]{10}'
|
||||
# PVE: r'pve([1248])([cbsp])-[0-9a-f]{10}'
|
||||
# PMG: r'pmg([cbsp])-[0-9a-f]{10}'
|
||||
def activate_pve_pmg(key, subscription_file, *args, **kwargs):
|
||||
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):
|
||||
@ -80,23 +68,23 @@ def activate_pve_pmg(key, subscription_file, *args, **kwargs):
|
||||
server_id = generate_server_id(f.read())
|
||||
|
||||
# generate a license file
|
||||
subscription = generate_subscription_pve_pmg(key, [server_id], *args, **kwargs)
|
||||
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, server_ids, product_name=ui_product_name, message=ui_message, url=ui_url):
|
||||
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": message,
|
||||
"productname": product_name,
|
||||
"message": "Yajuu Senpai has got your back",
|
||||
"productname": "YajuuSenpai",
|
||||
"regdate": dt_string("%Y-%m-%d %H:%M:%S"),
|
||||
"nextduedate": dt_string("%Y-%m-%d", 1296000), # 1296000: MAX_LOCAL_KEY_AGE in src/tools/subscription.rs
|
||||
"url": url,
|
||||
"url": "https://github.com/Jamesits/pve-fake-subscription",
|
||||
}
|
||||
|
||||
data = base64.standard_b64encode(json.dumps(localinfo).encode()).decode()
|
||||
@ -106,14 +94,14 @@ def generate_subscription_pbs(key, server_ids, product_name=ui_product_name, mes
|
||||
return key + "\n" + csum + "\n" + data + "\n"
|
||||
|
||||
# Key pattern: pbst-xxxxxxxxxx
|
||||
def activate_pbs(key, subscription_file, *args, **kwargs):
|
||||
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], *args, **kwargs)
|
||||
subscription = generate_subscription_pbs(key, [server_id])
|
||||
|
||||
# write license file
|
||||
with open(subscription_file, "w") as f:
|
||||
@ -123,14 +111,14 @@ if __name__ == "__main__":
|
||||
# Proxmox VE
|
||||
if os.path.exists("/etc/pve"):
|
||||
print("Activating Proxmox VE...")
|
||||
activate_pve_pmg(lic_pve, "/etc/subscription")
|
||||
activate_pve_pmg("pve8p-1145141919", "/etc/subscription")
|
||||
|
||||
# Proxmox Mail Gateway
|
||||
if os.path.exists("/etc/pmg"):
|
||||
print("Activating Proxmox Mail Gateway...")
|
||||
activate_pve_pmg(lic_pmg, "/etc/pmg/subscription")
|
||||
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(lic_pbs, "/etc/proxmox-backup/subscription")
|
||||
activate_pbs("pbst-1145141919", "/etc/proxmox-backup/subscription")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user