Compare commits

..

13 Commits

Author SHA1 Message Date
Jamesits
31cd2b8746
bump version to 0.0.11 2024-10-26 16:05:05 +08:00
Jamesits
499d00a81a
bump release to 0.0.10-2 2024-10-26 16:04:35 +08:00
Jamesits
d80468779e
fix #14 2024-10-26 16:04:12 +08:00
Jamesits
945b9247ef
update doc 2024-10-25 16:08:08 +08:00
Jamesits
bcb1fe671c
update doc 2024-10-25 16:05:35 +08:00
Jamesits
6a5aa2f026
update doc 2024-10-25 16:03:39 +08:00
Jamesits
21a8e7eb5f
update doc 2024-10-25 15:59:09 +08:00
Jamesits
b4dd87c236
make the script compatible with Python 2.7 and 3.18 2024-10-25 15:53:01 +08:00
Jamesits
2414d822ee
Update support status for PBS 3.x 2024-10-09 15:59:57 +08:00
Jamesits
380c479f24
update doc for #10 2023-07-28 01:40:20 +08:00
James Swineson
7a7048a575
fix typo 2023-06-11 01:47:03 +08:00
James Swineson
7f8200b83a doc: binary is now automatically invoked during post install, so no need to wait 2022-12-19 17:35:35 +08:00
James Swineson
6168590598
Update README.md 2022-12-19 17:33:04 +08:00
5 changed files with 104 additions and 41 deletions

View File

@ -1,5 +1,7 @@
# 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.
> I am really poor and I can't afford a license. I just want to get rid of the annoying dialog.
@ -8,9 +10,9 @@ Disables the "No valid subscription" dialog on all Proxmox products.
Works for:
- Proxmox VE (5.x or later, tested up to 7.2)
- Proxmox VE (5.x or later; 3.x and 4.x [require some manual actions](#compatibility-information-for-old-proxmox-ve-versions))
- Proxmox Mail Gateway (5.x or later)
- Proxmox Backup Server (1.x)
- Proxmox Backup Server (1.x or later)
Highlights:
@ -20,7 +22,9 @@ 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
## Installation
## Usage
### 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
@ -28,8 +32,6 @@ 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:
@ -38,7 +40,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:
@ -48,10 +50,49 @@ apt purge pve-fake-subscription
This will revert your system to a "no subscription key" status.
## Building the Package
## Development Notes
### 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
```

View File

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

View File

@ -3,15 +3,19 @@
after_upgrade() {
:
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
then
: # Ensure this if-clause is not empty. If it were empty, and we had an 'else', then it is an error in shell syntax
systemctl preset pve-fake-subscription.timer >/dev/null || true
$debsystemctl start pve-fake-subscription.timer >/dev/null || true
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
then
: # Ensure this if-clause is not empty. If it were empty, and we had an 'else', then it is an error in shell syntax
systemctl preset pve-fake-subscription.timer >/dev/null || true
$debsystemctl start pve-fake-subscription.timer >/dev/null || true
else
$debsystemctl restart pve-fake-subscription.timer >/dev/null || true
fi
else
$debsystemctl restart pve-fake-subscription.timer >/dev/null || true
ln -sf /usr/bin/pve-fake-subscription /etc/cron.hourly/pve-fake-subscription
fi
pve-fake-subscription
@ -20,10 +24,14 @@ after_upgrade() {
after_install() {
:
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
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
}

View File

@ -6,6 +6,8 @@ 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() {

View File

@ -3,6 +3,8 @@
# 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
@ -10,7 +12,6 @@ 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
@ -18,30 +19,40 @@ from datetime import datetime, timedelta
shared_key_data = "kjfdlskfhiuewhfk947368"
server_key_file = "/etc/ssh/ssh_host_rsa_key.pub"
def get_timestamp() -> int:
# 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():
return int(time.time())
# Perl's md5_base64 implementation
def md5_base64_perl(x: str) -> str:
def md5_base64_perl(x):
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:
def md5_base64_rs(x):
return base64.b64encode(hashlib.md5(x.encode()).digest()).decode()
def generate_server_id(key: str) -> str:
def generate_server_id(key):
return hashlib.md5(key.encode()).hexdigest().upper()
def dt_string(format: str, offset_secs: int = 0) -> str:
def dt_string(format, offset_secs=0):
return (datetime.now() + timedelta(seconds=offset_secs)).strftime(format)
def generate_subscription_pve_pmg(key: str, server_ids: List[str]) -> str:
def generate_subscription_pve_pmg(key, server_ids, product_name=ui_product_name):
localinfo = {
"checktime": get_timestamp(),
"status": "Active",
"key": key,
"validdirectory": ",".join(server_ids),
"productname": "YajuuSenpai",
"productname": product_name,
"regdate": dt_string("%Y-%m-%d %H:%M:%S"),
"nextduedate": dt_string("%Y-%m-%d", 1296000),
}
@ -53,9 +64,10 @@ def generate_subscription_pve_pmg(key: str, server_ids: List[str]) -> str:
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}'
# PVE5+: 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}'
def activate_pve_pmg(key: str, subscription_file: str) -> None:
def activate_pve_pmg(key, subscription_file, *args, **kwargs):
# check if the key format is correct
# pattern = re.compile(key_pattern)
# if not pattern.match(key):
@ -68,23 +80,23 @@ def activate_pve_pmg(key: str, subscription_file: str) -> None:
server_id = generate_server_id(f.read())
# generate a license file
subscription = generate_subscription_pve_pmg(key, [server_id])
subscription = generate_subscription_pve_pmg(key, [server_id], *args, **kwargs)
# write license file
with open(subscription_file, "w") as f:
f.write(subscription)
def generate_subscription_pbs(key: str, server_ids: List[str]) -> str:
def generate_subscription_pbs(key, server_ids, product_name=ui_product_name, message=ui_message, url=ui_url):
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",
"message": message,
"productname": product_name,
"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": "https://github.com/Jamesits/pve-fake-subscription",
"url": url,
}
data = base64.standard_b64encode(json.dumps(localinfo).encode()).decode()
@ -94,14 +106,14 @@ def generate_subscription_pbs(key: str, server_ids: List[str]) -> str:
return key + "\n" + csum + "\n" + data + "\n"
# Key pattern: pbst-xxxxxxxxxx
def activate_pbs(key: str, subscription_file: str) -> None:
def activate_pbs(key, subscription_file, *args, **kwargs):
# 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])
subscription = generate_subscription_pbs(key, [server_id], *args, **kwargs)
# write license file
with open(subscription_file, "w") as f:
@ -111,14 +123,14 @@ if __name__ == "__main__":
# Proxmox VE
if os.path.exists("/etc/pve"):
print("Activating Proxmox VE...")
activate_pve_pmg("pve8p-1145141919", "/etc/subscription")
activate_pve_pmg(lic_pve, "/etc/subscription")
# Proxmox Mail Gateway
if os.path.exists("/etc/pmg"):
print("Activating Proxmox Mail Gateway...")
activate_pve_pmg("pmgp-1145141919", "/etc/pmg/subscription")
activate_pve_pmg(lic_pmg, "/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")
activate_pbs(lic_pbs, "/etc/proxmox-backup/subscription")