Compare commits

..

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

5 changed files with 41 additions and 104 deletions

View File

@ -1,7 +1,5 @@
# pve-fake-subscription # pve-fake-subscription
![JavaScript free](https://img.shields.io/badge/JavaScript-free-%09%23f7df1e "No JavaScript is involved in this project. ")
Disables the "No valid subscription" dialog on all Proxmox products. 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 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: 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 Mail Gateway (5.x or later)
- Proxmox Backup Server (1.x or later) - Proxmox Backup Server (1.x)
Highlights: Highlights:
@ -22,9 +20,7 @@ Highlights:
- Comes with standard Debian package, easy to manage and automate - 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 - **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. [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. Install: run `dpkg -i pve-fake-subscription_*.deb` as root on every node
@ -32,6 +28,8 @@ Highlights:
Notes: 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. 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: 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 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) - [Proxmox Backup Server (PBS)](https://pbs.proxmox.com/docs/installation.html#proxmox-backup-no-subscription-repository)
### Uninstallation ## Uninstallation
Run as root: Run as root:
@ -50,49 +48,10 @@ apt purge pve-fake-subscription
This will revert your system to a "no subscription key" status. 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: Install [nFPM](https://nfpm.goreleaser.com/install/), then:
```shell ```shell
./package.sh ./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
```

View File

@ -1,14 +1,14 @@
name: "pve-fake-subscription" name: "pve-fake-subscription"
arch: "all" arch: "all"
platform: "linux" platform: "linux"
version: "0.0.11" version: "0.0.9"
version_schema: "semver" version_schema: "semver"
version_metadata: "git" version_metadata: "git"
epoch: 0 epoch: 0
release: 1 release: 1
section: "admin" section: "admin"
priority: "optional" priority: "optinal"
maintainer: "Nobody <nobody@example.com>" maintainer: "Nobody <nobody@example.com>"

View File

@ -3,7 +3,6 @@
after_upgrade() { after_upgrade() {
: :
if command -v systemctl >/dev/null; then
systemctl --system daemon-reload >/dev/null || true systemctl --system daemon-reload >/dev/null || true
debsystemctl=$(command -v deb-systemd-invoke || echo systemctl) debsystemctl=$(command -v deb-systemd-invoke || echo systemctl)
if ! systemctl is-enabled pve-fake-subscription.timer >/dev/null if ! systemctl is-enabled pve-fake-subscription.timer >/dev/null
@ -14,9 +13,6 @@ after_upgrade() {
else else
$debsystemctl restart pve-fake-subscription.timer >/dev/null || true $debsystemctl restart pve-fake-subscription.timer >/dev/null || true
fi fi
else
ln -sf /usr/bin/pve-fake-subscription /etc/cron.hourly/pve-fake-subscription
fi
pve-fake-subscription pve-fake-subscription
} }
@ -24,14 +20,10 @@ after_upgrade() {
after_install() { after_install() {
: :
if command -v systemctl >/dev/null; then
systemctl --system daemon-reload >/dev/null || true systemctl --system daemon-reload >/dev/null || true
debsystemctl=$(command -v deb-systemd-invoke || echo systemctl) debsystemctl=$(command -v deb-systemd-invoke || echo systemctl)
systemctl preset pve-fake-subscription.timer >/dev/null || true systemctl preset pve-fake-subscription.timer >/dev/null || true
$debsystemctl start 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 pve-fake-subscription
} }

View File

@ -6,8 +6,6 @@ after_remove() {
rm -f /etc/subscription rm -f /etc/subscription
rm -f /etc/pmg/subscription rm -f /etc/pmg/subscription
rm -f /etc/proxmox-backup/subscription rm -f /etc/proxmox-backup/subscription
rm -f /etc/cron.hourly/pve-fake-subscription
} }
after_purge() { after_purge() {

View File

@ -3,8 +3,6 @@
# Pollute Proxmox software subscription cache so it won't alert you on dashboard login # 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 # 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 # 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 hashlib
import base64 import base64
import json import json
@ -12,6 +10,7 @@ import time
import re import re
import sys import sys
import os import os
from typing import List
from datetime import datetime, timedelta from datetime import datetime, timedelta
# PVE & PMG: /usr/share/perl5/PVE/Subscription.pm # PVE & PMG: /usr/share/perl5/PVE/Subscription.pm
@ -19,40 +18,30 @@ from datetime import datetime, timedelta
shared_key_data = "kjfdlskfhiuewhfk947368" shared_key_data = "kjfdlskfhiuewhfk947368"
server_key_file = "/etc/ssh/ssh_host_rsa_key.pub" server_key_file = "/etc/ssh/ssh_host_rsa_key.pub"
# Default license keys def get_timestamp() -> int:
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():
return int(time.time()) return int(time.time())
# Perl's md5_base64 implementation # 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() return base64.b64encode(hashlib.md5(x.encode()).digest()).strip(b'=').decode()
# Rust's `base64::encode(tools::md5sum("something")?);` # 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() 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() 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) 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 = { localinfo = {
"checktime": get_timestamp(), "checktime": get_timestamp(),
"status": "Active", "status": "Active",
"key": key, "key": key,
"validdirectory": ",".join(server_ids), "validdirectory": ",".join(server_ids),
"productname": product_name, "productname": "YajuuSenpai",
"regdate": dt_string("%Y-%m-%d %H:%M:%S"), "regdate": dt_string("%Y-%m-%d %H:%M:%S"),
"nextduedate": dt_string("%Y-%m-%d", 1296000), "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" return key + "\n" + csum + "\n" + data + "\n"
# key_pattern can be find in /usr/share/perl5/{PVE,PMG}/API2/Subscription.pm # key_pattern can be find in /usr/share/perl5/{PVE,PMG}/API2/Subscription.pm
# PVE5+: r'pve([1248])([cbsp])-[0-9a-f]{10}' # PVE: r'pve([1248])([cbsp])-[0-9a-f]{10}'
# PVE3/4: r'pve([124])([cbsp])-[0-9a-f]{10}'
# PMG: r'pmg([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 # check if the key format is correct
# pattern = re.compile(key_pattern) # pattern = re.compile(key_pattern)
# if not pattern.match(key): # 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()) server_id = generate_server_id(f.read())
# generate a license file # 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 # write license file
with open(subscription_file, "w") as f: with open(subscription_file, "w") as f:
f.write(subscription) 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 = { localinfo = {
"status": "active", # PBS: `new`, `notfound`, `active`, `invalid` "status": "active", # PBS: `new`, `notfound`, `active`, `invalid`
"serverid": ",".join(server_ids), "serverid": ",".join(server_ids),
"checktime": get_timestamp(), "checktime": get_timestamp(),
"key": key, "key": key,
"message": message, "message": "Yajuu Senpai has got your back",
"productname": product_name, "productname": "YajuuSenpai",
"regdate": dt_string("%Y-%m-%d %H:%M:%S"), "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 "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() 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" return key + "\n" + csum + "\n" + data + "\n"
# Key pattern: pbst-xxxxxxxxxx # Key pattern: pbst-xxxxxxxxxx
def activate_pbs(key, subscription_file, *args, **kwargs): def activate_pbs(key: str, subscription_file: str) -> None:
# get machine ID # get machine ID
server_id = "" server_id = ""
with open(server_key_file, "r") as f: with open(server_key_file, "r") as f:
server_id = generate_server_id(f.read()) server_id = generate_server_id(f.read())
# generate a license file # generate a license file
subscription = generate_subscription_pbs(key, [server_id], *args, **kwargs) subscription = generate_subscription_pbs(key, [server_id])
# write license file # write license file
with open(subscription_file, "w") as f: with open(subscription_file, "w") as f:
@ -123,14 +111,14 @@ if __name__ == "__main__":
# Proxmox VE # Proxmox VE
if os.path.exists("/etc/pve"): if os.path.exists("/etc/pve"):
print("Activating Proxmox VE...") print("Activating Proxmox VE...")
activate_pve_pmg(lic_pve, "/etc/subscription") activate_pve_pmg("pve8p-1145141919", "/etc/subscription")
# Proxmox Mail Gateway # Proxmox Mail Gateway
if os.path.exists("/etc/pmg"): if os.path.exists("/etc/pmg"):
print("Activating Proxmox Mail Gateway...") print("Activating Proxmox Mail Gateway...")
activate_pve_pmg(lic_pmg, "/etc/pmg/subscription") activate_pve_pmg("pmgp-1145141919", "/etc/pmg/subscription")
# Proxmox Backup Server # Proxmox Backup Server
if os.path.exists("/etc/proxmox-backup"): if os.path.exists("/etc/proxmox-backup"):
print("Activating Proxmox Backup Server...") print("Activating Proxmox Backup Server...")
activate_pbs(lic_pbs, "/etc/proxmox-backup/subscription") activate_pbs("pbst-1145141919", "/etc/proxmox-backup/subscription")