Debian - Cloudimage

Debian Template on Proxmox

Cloud Image with SSH Key

on the Proxmox Host

Create Installer Key

# cd /your/working/dir
ssh-keygen -o -a 100 -t ed25519 -C "User: installer, $(date '+%Y-%m-%d %H:%m')" -f installer

Build Template

apt install libguestfs-tools -y;
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2

virt-customize --install qemu-guest-agent -a debian-12-generic-amd64.qcow2
qm create 9001 --name debian-12-generic --memory 2048 --cores 2 --net0 virtio,bridge=vmbr0 --agent 1 
qm importdisk 9001 debian-12-generic-amd64.qcow2 local-lvm

qm set 9001 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9001-disk-0
qm set 9001 --ide2 local-lvm:cloudinit
qm set 9001 --boot c --bootdisk scsi0
qm set 9001 --serial0 socket
qm set 9001 --ipconfig0 ip=dhcp
qm set 9001 --cpu cputype=x86-64-v2-AES

qm set 9001 --sshkeys installer.pub
qm set 9001 --ciuser installer

qm resize 9001 scsi0 32G
qm template 9001

Create VM

in the GUI, you can create an new VM based on the Template 9001. You have to login with user “installer” and it’s private key!

Fasthtml

Single Click Todo App with sqlite db

Source

  • needy python & poetry installed

copy/paste

poetry init -n
poetry add python-fasthtml fastsql

cat << 'EOF' > main.py
from fasthtml.common import *
from fastsql import *
from sqlite_minutils.db import NotFoundError

app,rt,todos,Todo = fast_app(
    'data/todos.db',
    id=int, title=str, pk='id')

def tid(id): return f'todo-{id}'


@app.delete("/delete_todo", name='delete_todo')
async def delete_todo(id:int): 
    try: todos.delete(id)
    except NotFoundError: pass # If someone else deleted it already we don't have to do anything

@patch
def __ft__(self:Todo):
    show = Strong(self.title, target_id='current-todo')
    delete = A('delete',
               hx_delete=delete_todo.to(id=self.id).lstrip('/'), 
               hx_target=f'#{tid(self.id)}',
               hx_swap='outerHTML')
    return Li(show, ' | ', delete, id=tid(self.id))

def mk_input(**kw): return Input(id="new-title", name="title", placeholder="New Todo", **kw)

@rt
async def index():
    add =  Form(Group(mk_input(), Button("Add")), 
                post="insert_todo", target_id='todo-list', hx_swap="beforeend")
    card = Card(Ul(*todos(), id='todo-list'), header=add, footer=Div(id='current-todo')),
    title = 'Todo list'
    return Title(title), Main(H1(title), card, cls='container')

@rt
async def insert_todo(todo:Todo): return todos.insert(todo), mk_input(hx_swap_oob='true')

serve()
EOF

poetry run python main.py

Any Comments ?

sha256: d920811503afe4ef9a1e579531cfaa5a7694082b66547ea9a24c77dac005876a

Fastapi - Ratelimiting

Fastapi & Rate Limiting

Let’s test a simple Rate Limiting Function found on the Net …

main.py

Main App with Rate Limiting Function

# main.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware
from Token_bucket import TokenBucket

app = FastAPI()

class RateLimiterMiddleware(BaseHTTPMiddleware):
    def __init__(self, app, bucket: TokenBucket):
        super().__init__(app)
        self.bucket = bucket

    async def dispatch(self, request: Request, call_next):
        if self.bucket.take_token():
            return await call_next(request)

        # Return a JSON response for rate limit exceeded
        return JSONResponse(status_code=429, content={"detail": "Rate limit exceeded"})

# Token bucket with a capacity of 3 and refill rate of 1 token per second
bucket = TokenBucket(capacity=3, refill_rate=3)

# Apply the rate limiter middleware
app.add_middleware(RateLimiterMiddleware, bucket=bucket)

@app.get("/")
async def read_root():
    return {"message": "Hello World"}

Token_bucket.py

# Token_bucket.py
import time

class TokenBucket:
    def __init__(self, capacity, refill_rate):
        self.capacity = capacity
        self.refill_rate = refill_rate
        self.tokens = capacity
        self.last_refill = time.time()

    def add_tokens(self):
        now = time.time()
        if self.tokens < self.capacity:
            tokens_to_add = (now - self.last_refill) * self.refill_rate
            self.tokens = min (self.capacity, self.tokens + tokens_to_add)
        self.last_refill=now

    def take_token(self):
        self.add_tokens()
        if self.tokens >= 1:
            self.tokens -=1
            return True
        return False

Test Script

Let’s produce some requests …

HTML - Center Div

3 Ways to Center a < div >

Credits to https://twitter.com/BilliCodes

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Centering a Div - Three Methods</title>
    <style>
        .container {
            height: 100vh; /* Full height */
            position: relative; /* Required for absolute positioning */
            background-color: #f0f0f0;
        }

        /* (1) Flexbox Method */
        .flexbox {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh; /* Full viewport height */
        }

        /* (2) Grid Method */
        .grid {
            display: grid;
            place-items: center; /* Center using grid */
            height: 100vh; /* Full viewport height */
        }

        /* (3) Absolute Positioning Method */
        .absolute {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%); /* Offset to center */
        }      
    </style>
</head>

<body>
    <div class="container">
        <!-- Flexbox Method -->
        <div class="centered flexbox">Centered with Flexbox</div>

        <!-- Grid Method -->
        <div class="centered grid">Centered with CSS Grid</div>
        
        <!-- Absolute Positioning Method -->
        <div class="centered absolute">Centered with Absolute Positioning</div>
    </div>
</body>

</html>

Any Comments ?

sha256: 85678db9aeded3bf6ba6bce5bf56014023c834cdd99b62f0d8427f3c12a65360

Python - Decorator

how to use Python Decorator

Sample Code

main.py

cat << 'EOF' > main.py
#!/usr/bin/env python3

# Sample from https://blog.stoege.net/posts/python_decorator/

# Vars
a = 3
b = 8

# Decorator which logs start and end of a function
def log_function_call(func):
    def wrapper(*args, **kwargs):
        print(f"\nCalling function '{func.__name__}' with {args=} & {kwargs=}")
        result = func(*args, **kwargs)
        print(f"Function '{func.__name__}' finnished\n")
        return result
    return wrapper

@log_function_call
def add(a=int, b=int) -> int:
    result = a + b
    return result

@log_function_call
def sub(a=int, b=int) -> int:
    result = a - b
    return result

@log_function_call
def prod(a=int, b=int) -> int:
    result = a * b
    return result

@log_function_call
def div(a=int, b=int) -> int:
    result = a / b
    return result

if __name__ == "__main__":
    print("Result:", add(a, b))
    print("Result:", sub(a, b))
    print("Result:", prod(a, b))
    print("Result:", div(a, b))

EOF
chmod u+x main.py

##### RUN #####

# ./main.py

###############

Running Code

user@host% ./main.py 

Calling function 'add' with args=(3, 8) & kwargs={}
Function 'add' finnished

Result: 11

Calling function 'sub' with args=(3, 8) & kwargs={}
Function 'sub' finnished

Result: -5

Calling function 'prod' with args=(3, 8) & kwargs={}
Function 'prod' finnished

Result: 24

Calling function 'div' with args=(3, 8) & kwargs={}
Function 'div' finnished

Result: 0.375

Any Comments ?

sha256: ab6641b101cea8ac7eb6517fcefb029380644a56203723973fa1bc957fafbafb

OpenBSD 7.6 - Python Crypto Library

OpenBSD 7.6 / LibreSSl 4.0.0 / cryptography 43.0.1

seems that cryptography library is broken / not yet ready for libressl 4.0.0

Problems adding Crypto

cd /tmp
poetry new test_crypto
cd test_crypto/
poetry add cryptography
root@host /bin# cd tmp

root@host /tmp# poetry new test_crypto

Created package test_crypto in test_crypto
root@host /tmp# cd test_crypto/

root@host /tmp/test_crypto# poetry add cryptography                                                                                                                                                  
Creating virtualenv test-crypto in /tmp/test_crypto/.venv
Using version ^43.0.1 for cryptography

Updating dependencies
Resolving dependencies... (0.2s)

Package operations: 3 installs, 0 updates, 0 removals

  - Installing pycparser (2.22)
  - Installing cffi (1.17.1)
  - Installing cryptography (43.0.1): Failed

  ChefBuildError

  Backend subprocess exited when trying to invoke build_wheel
  
  Running `maturin pep517 build-wheel -i /tmp/tmpm4f6kesa/.venv/bin/python --compatibility off`
  📦 Including license file "/tmp/tmpzw46sfn4/cryptography-43.0.1/LICENSE"
  📦 Including license file "/tmp/tmpzw46sfn4/cryptography-43.0.1/LICENSE.APACHE"
  📦 Including license file "/tmp/tmpzw46sfn4/cryptography-43.0.1/LICENSE.BSD"
  🍹 Building a mixed python/rust project
  🔗 Found pyo3 bindings with abi3 support for Python ≥ 3.7
  🐍 Not using a specific python interpreter
  📡 Using build options features, locked from pyproject.toml
     Compiling proc-macro2 v1.0.86
     Compiling target-lexicon v0.12.15
     Compiling unicode-ident v1.0.12
     Compiling pyo3-build-config v0.22.2
     Compiling quote v1.0.36
     Compiling cc v1.1.6
     Compiling syn v2.0.71
     Compiling vcpkg v0.2.15
     Compiling pkg-config v0.3.30
     Compiling once_cell v1.19.0
     Compiling openssl-sys v0.9.103
  error: failed to run custom build command for `openssl-sys v0.9.103`
  
  Caused by:
    process didn't exit successfully: `/tmp/tmpzw46sfn4/cryptography-43.0.1/src/rust/target/release/build/openssl-sys-b9cf452982f5d9f0/build-script-main` (exit status: 101)
    --- stdout
    cargo:rustc-check-cfg=cfg(osslconf, values("OPENSSL_NO_OCB", "OPENSSL_NO_SM4", "OPENSSL_NO_SEED", "OPENSSL_NO_CHACHA", "OPENSSL_NO_CAST", "OPENSSL_NO_IDEA", "OPENSSL_NO_CAMELLIA", "OPENSSL_NO_RC4", "OPENSSL_NO_BF", "OPENSSL_NO_PSK", "OPENSSL_NO_DEPRECATED_3_0", "OPENSSL_NO_SCRYPT", "OPENSSL_NO_SM3", "OPENSSL_NO_RMD160", "OPENSSL_NO_EC2M", "OPENSSL_NO_OCSP", "OPENSSL_NO_CMS", "OPENSSL_NO_COMP", "OPENSSL_NO_SOCK", "OPENSSL_NO_STDIO"))
    cargo:rustc-check-cfg=cfg(openssl)
    cargo:rustc-check-cfg=cfg(libressl)
    cargo:rustc-check-cfg=cfg(boringssl)
    cargo:rustc-check-cfg=cfg(libressl250)
    cargo:rustc-check-cfg=cfg(libressl251)
    cargo:rustc-check-cfg=cfg(libressl252)
    cargo:rustc-check-cfg=cfg(libressl261)
    cargo:rustc-check-cfg=cfg(libressl270)
    cargo:rustc-check-cfg=cfg(libressl271)
    cargo:rustc-check-cfg=cfg(libressl273)
    cargo:rustc-check-cfg=cfg(libressl280)
    cargo:rustc-check-cfg=cfg(libressl281)
    cargo:rustc-check-cfg=cfg(libressl291)
    cargo:rustc-check-cfg=cfg(libressl310)
    cargo:rustc-check-cfg=cfg(libressl321)
    cargo:rustc-check-cfg=cfg(libressl332)
    cargo:rustc-check-cfg=cfg(libressl340)
    cargo:rustc-check-cfg=cfg(libressl350)
    cargo:rustc-check-cfg=cfg(libressl360)
    cargo:rustc-check-cfg=cfg(libressl361)
    cargo:rustc-check-cfg=cfg(libressl370)
    cargo:rustc-check-cfg=cfg(libressl380)
    cargo:rustc-check-cfg=cfg(libressl381)
    cargo:rustc-check-cfg=cfg(libressl382)
    cargo:rustc-check-cfg=cfg(libressl390)
    cargo:rustc-check-cfg=cfg(libressl400)
    cargo:rustc-check-cfg=cfg(ossl101)
    cargo:rustc-check-cfg=cfg(ossl102)
    cargo:rustc-check-cfg=cfg(ossl102f)
    cargo:rustc-check-cfg=cfg(ossl102h)
    cargo:rustc-check-cfg=cfg(ossl110)
    cargo:rustc-check-cfg=cfg(ossl110f)
    cargo:rustc-check-cfg=cfg(ossl110g)
    cargo:rustc-check-cfg=cfg(ossl110h)
    cargo:rustc-check-cfg=cfg(ossl111)
    cargo:rustc-check-cfg=cfg(ossl111b)
    cargo:rustc-check-cfg=cfg(ossl111c)
    cargo:rustc-check-cfg=cfg(ossl111d)
    cargo:rustc-check-cfg=cfg(ossl300)
    cargo:rustc-check-cfg=cfg(ossl310)
    cargo:rustc-check-cfg=cfg(ossl320)
    cargo:rustc-check-cfg=cfg(ossl330)
    cargo:rerun-if-env-changed=X86_64_UNKNOWN_OPENBSD_OPENSSL_LIB_DIR
    X86_64_UNKNOWN_OPENBSD_OPENSSL_LIB_DIR unset
    cargo:rerun-if-env-changed=OPENSSL_LIB_DIR
    OPENSSL_LIB_DIR unset
    cargo:rerun-if-env-changed=X86_64_UNKNOWN_OPENBSD_OPENSSL_INCLUDE_DIR
    X86_64_UNKNOWN_OPENBSD_OPENSSL_INCLUDE_DIR unset
    cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR
    OPENSSL_INCLUDE_DIR unset
    cargo:rerun-if-env-changed=X86_64_UNKNOWN_OPENBSD_OPENSSL_DIR
    X86_64_UNKNOWN_OPENBSD_OPENSSL_DIR unset
    cargo:rerun-if-env-changed=OPENSSL_DIR
    OPENSSL_DIR unset
    cargo:rerun-if-env-changed=OPENSSL_NO_PKG_CONFIG
    cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-openbsd
    cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_openbsd
    cargo:rerun-if-env-changed=HOST_PKG_CONFIG
    cargo:rerun-if-env-changed=PKG_CONFIG
    cargo:rerun-if-env-changed=OPENSSL_STATIC
    cargo:rerun-if-env-changed=OPENSSL_DYNAMIC
    cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
    cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
    cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-openbsd
    cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_openbsd
    cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
    cargo:rerun-if-env-changed=PKG_CONFIG_PATH
    cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-openbsd
    cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_openbsd
    cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
    cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
    cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-openbsd
    cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_openbsd
    cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
    cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
    cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
    cargo:rerun-if-env-changed=SYSROOT
    cargo:rerun-if-env-changed=OPENSSL_STATIC
    cargo:rerun-if-env-changed=OPENSSL_DYNAMIC
    cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
    cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
    cargo:rustc-link-lib=ssl
    cargo:rustc-link-lib=crypto
    cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-openbsd
    cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_openbsd
    cargo:rerun-if-env-changed=HOST_PKG_CONFIG
    cargo:rerun-if-env-changed=PKG_CONFIG
    cargo:rerun-if-env-changed=OPENSSL_STATIC
    cargo:rerun-if-env-changed=OPENSSL_DYNAMIC
    cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
    cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
    cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-openbsd
    cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_openbsd
    cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
    cargo:rerun-if-env-changed=PKG_CONFIG_PATH
    cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-openbsd
    cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_openbsd
    cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
    cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
    cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-openbsd
    cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_openbsd
    cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
    cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
    cargo:rerun-if-changed=build/expando.c
    OPT_LEVEL = Some(3)
    TARGET = Some(x86_64-unknown-openbsd)
    OUT_DIR = Some(/tmp/tmpzw46sfn4/cryptography-43.0.1/src/rust/target/release/build/openssl-sys-69c53327ca178616/out)
    HOST = Some(x86_64-unknown-openbsd)
    cargo:rerun-if-env-changed=CC_x86_64-unknown-openbsd
    CC_x86_64-unknown-openbsd = None
    cargo:rerun-if-env-changed=CC_x86_64_unknown_openbsd
    CC_x86_64_unknown_openbsd = None
    cargo:rerun-if-env-changed=HOST_CC
    HOST_CC = None
    cargo:rerun-if-env-changed=CC
    CC = None
    cargo:rerun-if-env-changed=CC_ENABLE_DEBUG_OUTPUT
    RUSTC_WRAPPER = None
    cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
    CRATE_CC_NO_DEFAULTS = None
    DEBUG = Some(false)
    cargo:rerun-if-env-changed=CFLAGS_x86_64-unknown-openbsd
    CFLAGS_x86_64-unknown-openbsd = None
    cargo:rerun-if-env-changed=CFLAGS_x86_64_unknown_openbsd
    CFLAGS_x86_64_unknown_openbsd = None
    cargo:rerun-if-env-changed=HOST_CFLAGS
    HOST_CFLAGS = None
    cargo:rerun-if-env-changed=CFLAGS
    CFLAGS = None
    cargo:rustc-cfg=osslconf="OPENSSL_NO_BUF_FREELISTS"
    cargo:rustc-cfg=osslconf="OPENSSL_NO_COMP"
    cargo:rustc-cfg=osslconf="OPENSSL_NO_EC2M"
    cargo:rustc-cfg=osslconf="OPENSSL_NO_ENGINE"
    cargo:rustc-cfg=osslconf="OPENSSL_NO_KRB5"
    cargo:rustc-cfg=osslconf="OPENSSL_NO_PSK"
    cargo:rustc-cfg=osslconf="OPENSSL_NO_SRP"
    cargo:rustc-cfg=osslconf="OPENSSL_NO_SSL3_METHOD"
    cargo:rustc-cfg=osslconf="OPENSSL_NO_SEED"
    cargo:rustc-cfg=osslconf="OPENSSL_NO_SCRYPT"
    cargo:conf=OPENSSL_NO_BUF_FREELISTS,OPENSSL_NO_COMP,OPENSSL_NO_EC2M,OPENSSL_NO_ENGINE,OPENSSL_NO_KRB5,OPENSSL_NO_PSK,OPENSSL_NO_SRP,OPENSSL_NO_SSL3_METHOD,OPENSSL_NO_SEED,OPENSSL_NO_SCRYPT
    cargo:rustc-cfg=openssl
    cargo:rustc-cfg=libressl
    cargo:rustc-cfg=libressl251
    cargo:rustc-cfg=libressl252
    cargo:rustc-cfg=libressl261
    cargo:rustc-cfg=libressl270
    cargo:rustc-cfg=libressl271
    cargo:rustc-cfg=libressl273
    cargo:rustc-cfg=libressl280
    cargo:rustc-cfg=libressl281
    cargo:rustc-cfg=libressl291
    cargo:rustc-cfg=libressl310
    cargo:rustc-cfg=libressl321
    cargo:rustc-cfg=libressl332
    cargo:rustc-cfg=libressl340
    cargo:rustc-cfg=libressl350
    cargo:rustc-cfg=libressl360
    cargo:rustc-cfg=libressl370
    cargo:rustc-cfg=libressl380
    cargo:rustc-cfg=libressl381
    cargo:rustc-cfg=libressl382
    cargo:rustc-cfg=libressl390
    cargo:rustc-cfg=libressl400
    cargo:libressl_version_number=4000000f
  
    --- stderr
    thread 'main' panicked at /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/openssl-sys-0.9.103/build/main.rs:420:5:
  
  
    This crate is only compatible with OpenSSL (version 1.0.1 through 1.1.1, or 3), or LibreSSL 2.5
    through 3.9.x, but a different version of OpenSSL was found. The build is now aborting
    due to this version mismatch.
  
  
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
  warning: build failed, waiting for other jobs to finish...
  💥 maturin failed
    Caused by: Failed to build a native library through cargo
    Caused by: Cargo build finished with "exit status: 101": `env -u CARGO PYO3_ENVIRONMENT_SIGNATURE="cpython-3.11-64bit" PYO3_PYTHON="/tmp/tmpm4f6kesa/.venv/bin/python" PYTHON_SYS_EXECUTABLE="/tmp/tmpm4f6kesa/.venv/bin/python" "cargo" "rustc" "--features" "pyo3/abi3-py37" "--message-format" "json-render-diagnostics" "--locked" "--manifest-path" "/tmp/tmpzw46sfn4/cryptography-43.0.1/src/rust/Cargo.toml" "--release" "--lib"`
  Error: command ['maturin', 'pep517', 'build-wheel', '-i', '/tmp/tmpm4f6kesa/.venv/bin/python', '--compatibility', 'off'] returned non-zero exit status 1
  

  at ~/.local/lib/python3.11/site-packages/poetry/installation/chef.py:164 in _prepare
      160│ 
      161│                 error = ChefBuildError("\n\n".join(message_parts))
      162│ 
      163│             if error is not None:
    → 164│                 raise error from None
      165│ 
      166│             return path
      167│ 
      168│     def _prepare_sdist(self, archive: Path, destination: Path | None = None) -> Path:

Note: This error originates from the build backend, and is likely not a problem with poetry but with cryptography (43.0.1) not supporting PEP 517 builds. You can verify this by running 'pip wheel --no-cache-dir --use-pep517 "cryptography (==43.0.1)"'.

root@host 1 /tmp/test_crypto#

Install LibreSSL 3.9.2

cd /root
ftp https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-3.9.2.tar.gz
tar xzf libressl-3.9.2.tar.gz
cd libressl-3.9.2
./configure
make
make install DESTDIR=/tmp/
root@host /libressl-3.9.2# ./configure
checking build system type... x86_64-unknown-openbsd7.6
checking host system type... x86_64-unknown-openbsd7.6
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /usr/local/bin/gmkdir -p
checking for gawk... no
checking for mawk... no
checking for nawk... no

...

config.status: creating libssl.pc
config.status: creating libtls.pc
config.status: creating openssl.pc
config.status: executing depfiles commands
config.status: executing libtool commands
root@host /libressl-3.9.2#

root@host /libressl-3.9.2# make        
Making all in include
Making all in openssl
echo "generating opensslconf.h ..."
generating opensslconf.h ...
cp ../../include/arch/amd64/opensslconf.h opensslconf.h
make  all-am
Making all in crypto
echo "generating crypto_portable.sym ..."
generating crypto_portable.sym ...
cp ../crypto/crypto.sym crypto_portable.sym
chmod u+w crypto_portable.sym
make  all-am
  CPPAS    aes/libcrypto_la-aes-elf-x86_64.lo
  CPPAS    aes/libcrypto_la-bsaes-elf-x86_64.lo
  CPPAS    aes/libcrypto_la-vpaes-elf-x86_64.lo

...

  CC       netcat.o
  CC       socks.o
  CC       compat/socket.o
  CC       compat/base64.o
  CCLD     nc
ld: warning: netcat.c:470(netcat.o:(main)): warning: mktemp() possibly used unsafely; consider using mkstemp()
Making all in man
Making all in tests
  CC       empty.lo
  CCLD     libtest.la
root@host /libressl-3.9.2#


root@host /libressl-3.9.2# make install DESTDIR=/tmp/
Making install in include
Making install in openssl
make  install-am
 /usr/local/bin/gmkdir -p '/tmp//usr/local/include/openssl'
 /usr/bin/install -c -m 644 opensslconf.h aes.h asn1.h asn1t.h bio.h blowfish.h bn.h buffer.h camellia.h cast.h chacha.h cmac.h cms.h comp.h conf.h conf_api.h crypto.h ct.h curve25519.h des.h dh.h dsa.h dtls1.h ec.h ecdh.h ecdsa.h engine.h err.h evp.h hkdf.h hmac.h idea.h kdf.h lhash.h md4.h md5.h modes.h obj_mac.h objects.h ocsp.h '/tmp//usr/local/include/openssl'
 /usr/bin/install -c -m 644 opensslfeatures.h opensslv.h ossl_typ.h pem.h pem2.h pkcs12.h pkcs7.h poly1305.h posix_time.h rand.h rc2.h rc4.h ripemd.h rsa.h safestack.h sha.h sm3.h sm4.h srtp.h ssl.h ssl2.h ssl23.h ssl3.h stack.h tls1.h ts.h txt_db.h ui.h ui_compat.h whrlpool.h x509.h x509_vfy.h x509v3.h '/tmp//usr/local/include/openssl'
 /usr/local/bin/gmkdir -p '/tmp//usr/local/include'
 /usr/bin/install -c -m 644 tls.h '/tmp//usr/local/include'
Making install in crypto
make  install-am
 /usr/local/bin/gmkdir -p '/tmp//usr/local/lib'
 /bin/sh ../libtool   --mode=install /usr/bin/install -c   libcrypto.la '/tmp//usr/local/lib'
libtool: install: /usr/bin/install -c -m 644 .libs/libcrypto.so.53.0 /tmp//usr/local/lib/libcrypto.so.53.0
libtool: install: /usr/bin/install -c -m 644 .libs/libcrypto.lai /tmp//usr/local/lib/libcrypto.la
libtool: install: /usr/bin/install -c .libs/libcrypto.a /tmp//usr/local/lib/libcrypto.a

...

ln -sf "x509_verify.3" "/tmp//usr/local/share/man/man3/x509_verify_ctx_set_purpose.3"
Making install in tests
make  install-exec-hook
 /usr/local/bin/gmkdir -p '/tmp//usr/local/lib/pkgconfig'
 /usr/bin/install -c -m 644 libtls.pc libcrypto.pc libssl.pc openssl.pc '/tmp//usr/local/lib/pkgconfig'
root@host /libressl-3.9.2# 

Build Cryptography with LibreSSL 3.9.2

export OPENSSL_DIR="/tmp/usr/local/"; time poetry add cryptography@43
root@host /tmp/gugus# export OPENSSL_DIR="/tmp/usr/local/"; time poetry add cryptography@43 
Creating virtualenv gugus in /tmp/gugus/.venv

Updating dependencies
Resolving dependencies... (0.3s)

Package operations: 3 installs, 0 updates, 0 removals

  - Installing pycparser (2.22)
  - Installing cffi (1.17.1)
  - Installing cryptography (43.0.0)

Writing lock file
    1m40.77s real     2m31.68s user     0m15.74s system

root@host /tmp/gugus#

have phun!

OpenBSD 7.6

OpenBSD 7.6 released

The 57th Release of OpenBSD was announced. My Upgrade Script is available here.

Highlights

  • UDP parallel input has been enabled
  • pfctl(8) and systat(1) now display fragment reassembly statistics
  • dhcp6leased(8), a DHCPv6 client daemon for IPv6 PD has been added
  • and lot more

see the Post on Undeadly for more Details, or the OpenBSD Page

Script

doas su -
cd /root
ftp https://blog.stoege.net/scripts/{.helpers,upgrade_to_76.sh}
chmod u+x upgrade_to_76.sh

Execute

do the Upgrade

SSH - Legacy Devices

Intro

sometime, one have to access to old and legacy devices. they may do not support the current ciphers and key algorithms, so, we have to modify the “.ssh/config” File or provide some additional cli arguments.

If you have todo this regualary, you may wanna extend the current parameters with the legacy ones like this:

Backup old config

you never know ;)

mv /etc/ssh/ssh_config /etc/ssh/ssh_config-$(date "+%s")

Install Updated Version

you have to copy/paste as root

Apibench

Benchmark API’s

i like to work with fastapi. “FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints.”. i also know that scripting languages like python are ways slower than compiled languages like c, c++, rust, …

why not build a little “hello world” api, running it on localhost, and then do a benchmark …

Rust

let’s start with rust.

Code

src/main.rs

Knot

KNOT DNS

some information related to knot dns / knot-dnsutils. Tested with ‘knotd (Knot DNS), version 3.3.3’ running on OpenBSD 7.5.

Install Knot

pkg_add knot

Build Config

we’re configure this server as “slave” which get’s it’s config from a Primary Nameserver

# /etc/knot/knot.conf 

server:
    rundir: "/var/run/knot"
    user: _knot:_knot
    automatic-acl: on
    listen: [ xx.xx.xx.xx@53, xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx@53 ]

log:
  - target: syslog
    any: info

database:
    storage: "/var/db/knot"

key:
  - id: mykey
    algorithm: hmac-sha256
    secret: xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx=

remote:
  - id: primary
    address: [ xx.xx.xx.xx@53, xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx@53 ] # IP Address of Primary Nameserver
    key: mykey

template:
  # default
  - id: default
    storage: "/var/db/knot"
    file: "%s.zone"
    global-module: mod-stats
    semantic-checks: on

zone:

  # Slave Zones
  - domain: your-domain.ch
    master: primary
  - domain: your-other-domain.de
    master: primary
  - domain: your-last-domain.com
    master: primary

enable and start service

rcctl enable knot
rcctl restart knot

zone backup

folder="/tmp/knot"
mkdir $folder
chown -R _knot $folder
knotc zone-backup +backupdir $folder

Build query File

cat ${folder}/zonefiles/stoege.net.zone |awk "{print \$1,\$3}" |grep -E "(NS|DS|A|AAAA|PTR|MX|SOA)$" |\
  sort -u -R > ${folder}/queries.txt 

StressTests (from a Debian Box)

apt install knot-dnsutils
cd /tmp
scp root@45.32.159.233:/tmp/knot/queries.txt .

5k Queries

kxdpgun -i queries.txt 45.32.159.233
using interface ens18, XDP threads 1, UDP, native mode
thread#00: sent 5010, received 5010
total queries:     5010 (1002 pps)
total replies:     5010 (1002 pps) (100%)
average DNS reply size: 63 B
average Ethernet reply rate: 842459 bps (0.84 Mbps)
responded NOERROR:   5010
duration: 5 s

100k Queries

time kxdpgun -t 20 -Q 5000 -i queries.txt -b 20 -p 8853 45.32.159.233
using interface ens18, XDP threads 1, UDP, native mode
thread#00: sent 100020, received 0
total queries:     100020 (5001 pps)
total replies:     0 (0 pps) (0%)
average DNS reply size: 0 B
average Ethernet reply rate: 24 bps (0.00 Mbps)
duration: 20 s

real	0m22.052s
user	0m0.092s
sys	0m0.183s

khost – Simple DNS lookup utility¶

# khost stoege.net
stoege.net. has IPv4 address 159.69.214.12
stoege.net. has IPv6 address 2a01:4f8:c0c:fff7::2
stoege.net. mail is handled by 10 ideo.noflow.ch.
# khost stoege.net -t SOA
stoege.net. start of authority is ns1.noflow.ch. hostmaster.noflow.ch. 2024052701 3600 900 1209600 1800

kdig – Advanced DNS lookup utility¶

# kdig stoege.net A    
;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 57426
;; Flags: qr rd ra; QUERY: 1; ANSWER: 1; AUTHORITY: 0; ADDITIONAL: 0

;; QUESTION SECTION:
;; stoege.net.         		IN	A

;; ANSWER SECTION:
stoege.net.         	1800	IN	A	159.69.214.12

;; Received 44 B
;; Time 2024-07-10 19:27:20 CEST
;; From 108.61.10.10@53(UDP) in 1.4 ms

short answer

# kdig +short stoege.net AAAA
2a01:4f8:c0c:fff7::2

output in json

# kdig +json stoege.net AAAA
{
  "dateString": "2024-07-10T19:28:01+0200",
  "dateSeconds": 1720632481,
  "msgLength": 56,
  "ID": 27609,
  "QR": 1,
  "Opcode": 0,
  "AA": 0,
  "TC": 0,
  "RD": 1,
  "RA": 1,
  "AD": 0,
  "CD": 0,
  "RCODE": 0,
  "QDCOUNT": 1,
  "ANCOUNT": 1,
  "NSCOUNT": 0,
  "ARCOUNT": 0,
  "QNAME": "stoege.net.",
  "QTYPE": 28,
  "QTYPEname": "AAAA",
  "QCLASS": 1,
  "QCLASSname": "IN",
  "answerRRs": [
    {
      "NAME": "stoege.net.",
      "TYPE": 28,
      "TYPEname": "AAAA",
      "CLASS": 1,
      "CLASSname": "IN",
      "TTL": 1800,
      "rdataAAAA": "2a01:4f8:c0c:fff7::2",
      "RDLENGTH": 16,
      "RDATAHEX": "2A0104F80C0CFFF70000000000000002"
    }
  ]
}

Any Comments ?

sha256: 4034db839fb307e487b0188f378a9bc142ededf7de783788811c270f126f03f5