Files
openvpncertupdate/CLAUDE.md
2026-06-24 00:24:30 +03:00

2.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this is

openvpncertupdate is a single-file Python + curses TUI tool for managing OpenVPN user certificates via EasyRSA 3.2.x. It lists expiring/expired certs, re-issues them with fresh keys, creates new certs, and delivers configs via Cryptgeon (one-time password URL) and email.

Running

pip install -r requirements.txt   # just: cryptography>=41
python3 openvpncertupdate.py

Edit the SETTINGS block at the top of openvpncertupdate.py before first run.

Tests

python3 -m pytest tests/ -v
python3 -m pytest tests/test_password.py -v            # single file
python3 -m pytest tests/test_pki.py::test_sorted_ascending -v  # single test

File layout — sections inside openvpncertupdate.py

Section Key symbols
SETTINGS all-caps constants
PKI CertInfo, load_expiring_certs(), _parse_index_line()
PASSWORD generate_password()
EASYRSA EasyRSAError, revoke_issued(), build_client_full(), gen_crl(), copy_crl()
METADATA load_metadata(), save_email(), get_email()
CONFIG build_ovpn()vpn-configs/<CN>_<date>/<CONFIG_NAME>
CRYPTGEON CryptgeonError, create_note()
MAILER send_email()
TUI WIDGETS InputField, clamp(), draw_box(), init_colors(), COLOR_*
TUI DIALOGS show_confirm(), show_cert_form(), CertFormResult
TUI SCREEN show_main_screen(), Action, ScreenResult
APP CursesApp
ENTRY POINT main()

Re-issue workflow

  1. revoke-issued <CN> — archives old key + CSR to pki/revoked/
  2. build-client-full <CN> --passout=pass:<pw> — generates new key + cert
  3. CRL not auto-updated during renewal; use "Regenerate CRL" menu item or r hotkey

Key constraints

  • EasyRSA called with --batch; --passin=pass:<CA_PASSPHRASE> omitted when CA_PASSPHRASE=""
  • Cryptgeon: raw_key=os.urandom(32), aes_key=SHA-256(raw_key), AES-256-GCM, URL fragment=base64url(raw_key)
  • copy_crl() does chmod 644 after copy
  • Password: pos 1=uppercase, pos 2=lowercase (no j), pos 3-27=alphanumeric, pos 28=lowercase (no j); oO01lI banned everywhere
  • Inline file path: <PKI_DIR>/inline/private/<CN>.inline
  • User emails stored in <PKI_DIR>/openvpncertupdate-metadata.json