
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
        
            
        
            
        
        
            
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        [{"categories":[],"content":"I\u0026rsquo;m currently working on a project to provide secure connectivity from multiple locations to a centralized server in an organization\u0026rsquo;s headquarters. I contemplated using several firewall solutions, or building one using Debian. After building some containers on Alpine, I figured why not just use Alpine itself as the gateway with WireGuard. The setup was done on a QEMU Virtual Machine on Ubuntu 24.04. I’ll then move the VM to the devices on each premises to have an always-on, auto-connected virtual tunnel that is secure. This lightweight setup allows me to spin up a gateway that does what I need quickly and efficiently with minimal hassle.\nAlpine Gateway with WireGuard The Alpine Linux gateway will have two interfaces: one for the LAN (192.168.11.0/24) running dnsmasq with IP forwarding and NAT, and another for the public-facing internet. The internet connection will come from a provider via the same interface on the Virtual Machine (VM) host. Since the client is still deciding between Linux or Windows for the VM host, my VM must run flawlessly on both, without creating extra setup work for their maintenance staff.\nInstalling Alpine Linux I am using Cockpit to perform the setup of the gateway so I can do the needful from the comfort of my laptop.\nAlpine VM configuration With the VM booted up, log in using the root user and run the setup-alpine script to prepare the system for installation. Take note of the following key items:\nSet a strong password for the root user when prompted. Create a new user to log in and manage the gateway. Choose openssh as the SSH server for maximum compatibility. Choose the correct disk and select sys as the disk mode. This installs Alpine to disk like a regular OS, ensuring all changes are persistent. The other configuration details are pretty self-explanatory. A reboot now uses the disk install of Alpine, allowing us to move on to the next step of the setup\nInstalling packages on Alpine Linux After a complete reboot and logging in as the root user, the first thing I do is to enable the community repo in /etc/apk/repositories. After that, I run apk update \u0026amp;\u0026amp; apk upgrade to make sure the new repo is added and the system is brought up to date. After this, I can install the necessary packages on Alpine.\napk add bash shadow micro dnsmasq iproute2 sudo nftables WireGuard-tools I install the following packages right after enabling the community repo:\nbash – I prefer it over the default BusyBox sh, so installing it gives me a familiar shell environment to work with. micro – My go-to text editor; I prefer it over vim, so it’s one of the first packages I add. dnsmasq – Needed to act as a DHCP server for the LAN, so we might as well install it early. shadow – Provides GNU user management tools like chsh, usermod, and passwd with more options than BusyBox. In this setup, it’s what lets me change a user’s shell without manually editing /etc/passwd. iproute2 – Adds full-featured networking tools like ss, ip link, and ip route beyond the BusyBox versions. I use ss often to check listening ports and services. sudo – Allows a normal user to run commands as root or escalate privileges when needed. nftables – Modern packet filtering framework that replaces iptables. I recently started to use it in place of iptables and this is the firewall I\u0026rsquo;m leaning with for the Alpine gateway. WireGuard-tools – Provides the wg and wg-quick commands to configure and manage WireGuard VPN tunnels, which will be the core of secure connectivity from this gateway. chsh -s /bin/bash root chsh -s /bin/bash user Replace user with the username entered during installation. The remaining setup is done over SSH, so get the IP address of the VM using ip address show\nBy default root is NOT allowed to log in via SSH so the normal user we created will be necessary to log into Alpine.\nThis is my $HOME/.bash_profile for both user and root\n[ -f ~/.bashrc ] \u0026amp;\u0026amp; . ~/.bashrc # Stop here for non-interactive shells case $- in *i*) ;; # interactive *) return ;; # non-interactive esac # ───── Color definitions ───── RED=\u0026#39;\\[\\e[0;31m\\]\u0026#39; GREEN=\u0026#39;\\[\\e[0;32m\\]\u0026#39; YELLOW=\u0026#39;\\[\\e[0;33m\\]\u0026#39; BLUE=\u0026#39;\\[\\e[0;34m\\]\u0026#39; MAGENTA=\u0026#39;\\[\\e[0;35m\\]\u0026#39; CYAN=\u0026#39;\\[\\e[0;36m\\]\u0026#39; WHITE=\u0026#39;\\[\\e[1;37m\\]\u0026#39; # bright white for typed commands RESET=\u0026#39;\\[\\e[0m\\]\u0026#39; # ───── Prompt (PS1) ───── # Note: we *do not* RESET at the end so your typed command stays WHITE. if [ \u0026#34;$EUID\u0026#34; -eq 0 ]; then # root: username red, host yellow, cwd blue, then type in white, end with # PS1=\u0026#34;${RED}\\u${RESET}@${YELLOW}\\h${RESET}:${BLUE}\\w${WHITE}# \u0026#34; else # user: username green, host yellow, cwd blue, then type in white, end with $ PS1=\u0026#34;${GREEN}\\u${RESET}@${YELLOW}\\h${RESET}:${BLUE}\\w${WHITE}\\$ \u0026#34; fi alias ls=\u0026#39;ls --color\u0026#39; alias ll=\u0026#39;ls -l\u0026#39; alias vi=\u0026#39;micro\u0026#39; alias vim=\u0026#39;micro\u0026#39; Configure sudo to allow passwordless escalation This next step is mainly for convenience so I allow my user to become root without password. This is NOT RECOMMENDED for a production environment, but I have it enabled for development and testing. It gets turned off before heading to production.\nUsing visudo make sure the following line exists, uncommenting it if it is commented out with a hash (#)\n%wheel ALL=(ALL:ALL) NOPASSWD: ALL Configure Alpine for gateway functionality The first step in ensuring Alpine works as a gateway is to enable IP Forwarding. For this we create a file named /etc/sysctl.d/99-ip_forward.conf with the following contents\nnet.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1 Next up is to configure a static IP address for the LAN interface for us to manage the LAN interface. For this, edit the /etc/network/interfaces file and configure the interfaces. The typical layout will be as follows\nauto lo iface lo inet loopback auto eth0 iface eth0 inet dhcp auto eth1 iface eth1 inet static address 192.168.11.1 netmask 255.255.255.0 In this case eth0 uses DHCP so it can get the address from an upstream provider. If the address is static, modify the config to set a static address. eth1 on the other hand is the LAN-facing interface so we definitely require a static IP address.\nFinal step of the process is to configure dnsmasq to issue out IP addresses for the LAN portion. I created a file named /etc/dnsmasq.d/dhcp.conf with the following contents\n#log-dhcp #log-facility=/var/log/dnsmasq.log # hardening dhcp-authoritative domain-needed bogus-priv # Listen only on LAN interface=eth1 bind-interfaces port=53 # enable DNS for clients resolv-file=/etc/resolv.conf # DHCP pool: .100–.200, 12h leases dhcp-range=192.168.11.101,192.168.11.199,12h # Gateway IP for clients dhcp-option=3,192.168.11.1 # DNS servers handed to clients dhcp-option=6,192.168.11.1 After saving this file, enable the dnsmasq service using rc-update add dnsmasq default.\nWireGuard setup For this, I use the WireGuard Peer as a reference to setup the Alpine gateway as a WireGuard peer. The WireGuard server is running on an Amazon EC2 instance that generates peer configuration. With the configuration on hand, I write the contents of the file to /etc/WireGuard/wg0.conf\nIn Alpine, to auto-start wg0, we need to perform the following steps\nln -s /etc/init.d/wg-quick /etc/init.d/wg-quick.wg0 rc-update add wg-quick.wg0 default rc-service wg-quick.wg0 start Enable nftables firewall Configuring nftables is pretty straightforward, and I can split up the rules for each component into its own file for easier reference. Enable nftables to start on Alpine boot up using rc-update add nftables default\nNAT NFT rules Create the file /etc/nftables.d/nat.nft with the following contents\ntable ip nat { chain postrouting { type nat hook postrouting priority 100; policy accept; oifname \u0026#34;eth0\u0026#34; masquerade } } table inet filter { chain input { type filter hook input priority 0; policy drop; iif \u0026#34;lo\u0026#34; accept ct state established,related accept # Allow DHCP on LAN iifname \u0026#34;eth1\u0026#34; udp dport 67 accept iifname \u0026#34;eth1\u0026#34; udp sport 68 accept # Allow DNS over UDP from LAN iifname \u0026#34;eth1\u0026#34; udp dport 53 accept comment \u0026#34;Allow DNS (UDP) from LAN\u0026#34; # Allow DNS over TCP from LAN iifname \u0026#34;eth1\u0026#34; tcp dport 53 ct state new,established accept comment \u0026#34;Allow DNS (TCP) from LAN\u0026#34; } chain forward { type filter hook forward priority 0; policy drop; # LAN → Internet iifname \u0026#34;eth1\u0026#34; oifname \u0026#34;eth0\u0026#34; accept # Internet → LAN (established) iifname \u0026#34;eth0\u0026#34; oifname \u0026#34;eth1\u0026#34; ct state established,related accept } } If your interface name for the LAN-facing is something other than eth1, replace it in the file above.\nSSH NFT rules Create the file /etc/nftables.d/ssh.nft with the following contents\ntable inet filter { chain input { tcp dport 22 accept } } If the SSH port is running on another port, replace the port number here.\nWireGuard NFT rules Create the file /etc/nftables.d/wireguard.nft with the following contents\ntable inet filter { chain input { # Allow incoming WireGuard udp dport 51820 ct state new accept comment \u0026#34;Allow WG on eth0\u0026#34; } chain forward { type filter hook forward priority 0; policy drop; # VPN → LAN iifname \u0026#34;wg0\u0026#34; oifname \u0026#34;eth1\u0026#34; accept comment \u0026#34;WG→LAN\u0026#34; # VPN → Internet iifname \u0026#34;wg0\u0026#34; oifname \u0026#34;eth0\u0026#34; accept comment \u0026#34;WG→WAN\u0026#34; # Internet → VPN (established) iifname \u0026#34;eth0\u0026#34; oifname \u0026#34;wg0\u0026#34; ct state established,related accept # LAN → VPN iifname \u0026#34;eth1\u0026#34; oifname \u0026#34;wg0\u0026#34; accept # VPN → LAN (established) iifname \u0026#34;wg0\u0026#34; oifname \u0026#34;eth1\u0026#34; ct state established,related accept } } table ip nat { chain postrouting { type nat hook postrouting priority 100; policy accept; # Masquerade VPN client Internet traffic oifname \u0026#34;eth0\u0026#34; masquerade comment \u0026#34;Masq WG→WAN\u0026#34; # masquerade LAN client traffic going out wg0 oifname \u0026#34;wg0\u0026#34; masquerade comment \u0026#34;Masq LAN→VPN via WireGuard\u0026#34; } } The above rules allow traffic between the LAN (eth1) and VPN (wg0) which includes performing IP Masquerade over the VPN.\nNow we can reboot the Alpine gateway and we should be able to ping the WireGuard tunnel endpoint from a client on the LAN side.\nAfter rebooting, you can view the nftables rules using nft list ruleset\n(Optional) - Custom Message of the Day (MotD) I prefer to have a custom motd when I log in, purely for aesthetic reasons. To have it implemented in Alpine, I installed the figlet package and have this script located in\n/etc/profile.d/10-banner.sh\n#!/bin/sh # Show a cyan ASCII hostname and a dim-white default IPv4/CIDR # Only when attached to a TTY [ -t 1 ] || return HOST=\u0026#34;$(hostname)\u0026#34; # Figure out terminal width (fallback 80) cols=\u0026#34;$(stty size 2\u0026gt;/dev/null | awk \u0026#39;{print $2}\u0026#39;)\u0026#34; ; [ -n \u0026#34;$cols\u0026#34; ] || cols=80 # Find default interface and its IPv4/CIDR defif=\u0026#34;$(ip route show default 2\u0026gt;/dev/null | awk \u0026#39;/default/ {print $5; exit}\u0026#39;)\u0026#34; if [ -n \u0026#34;$defif\u0026#34; ]; then cidr=\u0026#34;$(ip -o -4 addr show dev \u0026#34;$defif\u0026#34; 2\u0026gt;/dev/null | awk \u0026#39;{print $4; exit}\u0026#39;)\u0026#34; else cidr=\u0026#34;$(ip -o -4 addr show scope global 2\u0026gt;/dev/null | awk \u0026#39;{print $4; exit}\u0026#39;)\u0026#34; fi [ -n \u0026#34;$cidr\u0026#34; ] || cidr=\u0026#34;no IPv4\u0026#34; # Colors CYAN=\u0026#39;\\033[1;36m\u0026#39; DIM=\u0026#39;\\033[2;37m\u0026#39; RST=\u0026#39;\\033[0m\u0026#39; # Print banner printf \u0026#34;%b\u0026#34; \u0026#34;$CYAN\u0026#34; figlet -w \u0026#34;$cols\u0026#34; \u0026#34;$HOST\u0026#34; printf \u0026#34;%b\u0026#34; \u0026#34;$RST\u0026#34; printf \u0026#34;%bDefault IPv4: %s (%s)\\n\\n%b\u0026#34; \u0026#34;$DIM\u0026#34; \u0026#34;$cidr\u0026#34; \u0026#34;${defif:-unknown}\u0026#34; \u0026#34;$RST\u0026#34; Make sure to chmod 0755 /etc/profile.d/10-banner.sh so it can be read and executed during login.\n(Optional) - Disable root login from terminal Once I know everything is working, I disable root login by executing passwd -l root so no one can log in to the gateway from the terminal as root. The only way to log in will be to use the user account and then use sudo to escalate privileges.\nHappy Alpine-ing.\n","permalink":"https://vicknesh.info/articles/2025/08/wireguard/","tags":[{"LinkTitle":"Guides","RelPermalink":"/tags/guides/"},{"LinkTitle":"Linux","RelPermalink":"/tags/linux/"},{"LinkTitle":"Alpine","RelPermalink":"/tags/alpine/"},{"LinkTitle":"Network","RelPermalink":"/tags/network/"}],"title":"Alpine Gateway WireGuard"},{"categories":[],"content":"Following Part 3 of the series, the final component to be set up is the Caddy reverse proxy. I previously used traefik and while it worked, there were a few hiccups I encountered. I can\u0026rsquo;t recall the exact issues I ran into, but they were enough for me to switch things up this time. On this particular VPS, I won\u0026rsquo;t be running many services so auto-discovery is irrelevant. I’m binding each service to a specific IP and port, then using Caddy to reverse proxy to them, which simplifies a lot of the management and admin. Caddy also handles automatic certificate renewal with my custom CA using the ACME endpoint I set up earlier, so that\u0026rsquo;s an added bonus.\nFor this specific use case, I am using Caddy to accept all incoming requests meant for AdGuard DNS and Smallstep CA and proxying them to the correct services. Each of these services will have their own private certificate that is generated by Caddy from our local Certificate Authority.\nDocker Compose The Docker Compose file and configuration of Caddy is located in /containers/caddy base folder.\n/containers/caddy/docker-compose.yaml\nservices: caddy: image: caddy:latest container_name: caddy restart: unless-stopped volumes: - /containers/smallstep/data/certs/root_ca.crt:etc/ssl/certs/root_ca.crt:ro # load our root CA into caddy - /containers/caddy/config:/etc/caddy - /containers/caddy/data:/data ports: - \u0026#39;192.168.200.1:80:80/tcp\u0026#39; # listen for HTTP on wireguard interface (tcp) - \u0026#39;192.168.200.1:443:443/tcp\u0026#39; # listen for HTTPS on wireguard interface (tcp) networks: - webproxy networks: webproxy: external: true Configure Caddy Create the file /containers/caddy/config/Caddyfile and add the following information to it\n{ acme_ca https://smallstep-vps:9000/acme/handletec-vps/directory acme_ca_root /etc/ssl/certs/root_ca.crt email info@handletec.my } import /etc/caddy/config.d/*.conf This config specifies we want to use our custom CA to generate certificates and with all our configuration in place, the Smallstep service will be able to connect back to Caddy for verification. We also allow including individual files for our services to more tidily manage them without cluttering the Caddyfile. We use the container name smallstep-vps to connect to the Smallstep service.\nWe create another file /containers/caddy/config/config.d/service.conf with the following contents\nca.vps.homelab.my { reverse_proxy https://smallstep-handletec-vps:9000 } dns.vps.homelab.my { reverse_proxy http://adguardhome:8000 } This is all that\u0026rsquo;s needed for our Caddy to automatically generate certificates per domain name. Notice how we use the container names as Docker can resolve these names using its internal DNS. The reverse_proxy directive is responsible for forwarding requests from each domain to the correct service.\nFirewall The final step is to allow the Docker network to connect to our Caddy and perform the validation of the domain name targets. Since our Caddy is listening on our specific Wireguard interface, we can create a rather lax rule to prevent any issues.\nufw allow proto tcp from any to any port 80 And that concludes our series on setting up a personal Certificate Authority for our own use. While I use this primarily for my own homelab, I can envision this being used in companies and organizations that want to utilize end-to-end TLS security for their own needs.\nHappy reading!\n","permalink":"https://vicknesh.info/articles/2025/08/ca-series-part-4-caddy/","tags":[{"LinkTitle":"Guides","RelPermalink":"/tags/guides/"},{"LinkTitle":"Linux","RelPermalink":"/tags/linux/"},{"LinkTitle":"Archlinux","RelPermalink":"/tags/archlinux/"},{"LinkTitle":"Network","RelPermalink":"/tags/network/"}],"title":"Part 4 - Setting up Caddy Reverse Proxy"},{"categories":[],"content":"Following Part 2 of the series, the second component to be set up is the Smallstep Certificate Authority server. Smallstep is a lightweight CA I use to issue and manage TLS certificates for my internal services. It makes it easy to automate cert handling without relying on external CAs such as Let\u0026rsquo;s Encrypt, nor do I have to reveal details about my domain names to the public.\nDocker Compose The Docker Compose file and configuration of Smallstep is located in /containers/smallstep base folder.\n/containers/smallstep/docker-compose.yaml\nservices: smallstep-handletec-vps: image: smallstep/step-ca:latest container_name: smallstep-handletec-vps restart: unless-stopped env_file: /containers/smallstep/vps.env volumes: - /containers/smallstep/data:/home/step ports: - 127.0.0.1:9000:9000/tcp healthcheck: test: - CMD - curl - -k - https://localhost:9000/health interval: 60s retries: 5 start_period: 10s timeout: 10s networks: - webproxy networks: webproxy: external: true Create a /containers/smallstep/vps.env environment variable file with the contents\nDOCKER_STEPCA_INIT_NAME=Name of the VPS to be displayed in certificates DOCKER_STEPCA_INIT_DNS_NAMES=localhost,stepca.internal,ca.mydomain.com,ip address this instance is reachable DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true DOCKER_STEPCA_INIT_PROVISIONER_NAME=homelab where\nEnvironment Variable Description DOCKER_STEPCA_INIT_NAME Sets the CA’s display name (e.g., \u0026ldquo;Internal CA\u0026rdquo;) DOCKER_STEPCA_INIT_DNS_NAMES Comma-separated DNS SANs for the CA’s TLS certificate DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT Enables remote management via step CLI (true or false) DOCKER_STEPCA_INIT_PROVISIONER_NAME Name of the initial provisioner used for issuing certs (e.g., \u0026ldquo;homelab\u0026rdquo;) For DOCKER_STEPCA_INIT_DNS_NAMES, since we are binding Smallstep to a specific IP, make sure that IP is listed in this environment variable, otherwise when you attempt to connect to this instance, it will give an error.\nBring up the container via docker compose up -d and jot down the randomly generated password with the default username step. This will be shown only ONCE and is important when we want to perform administrative tasks to our CA.\nThe difference between the step username and the admin provisioner is that step is the default admin account used to manage the CA itself — like creating provisioners — while homelab is the provisioner used to actually request and sign certificates.\nThe healthcheck in docker-compose.yaml is there to give Docker a clear indicator if the service is healthy. While I could leave it out, I prefer to include it so I can monitor the status via docker ps.\nWe bind port 9000 to localhost to allow bootstrapping of our CA and to manage it easily.\nWith the config done, it\u0026rsquo;s time to bring the Smallstep container up using docker compose up -d, and use docker compose logs -f to get the automatically generated password\nSmallstep CA initialization with username `step` and automatically generated password Setup Smallstep CA With smallstep running, let\u0026rsquo;s bootstrap this CA on your VPS. Bootstrapping allows management of the Smallstep CA from this local system and installs the newly minted root certificate to the OS trust store.\nCA_FINGERPRINT=$(docker run -v /containers/smallstep/data:/home/step smallstep/step-ca step certificate fingerprint /home/step/certs/root_ca.crt) step ca bootstrap --ca-url https://127.0.0.1:9000 --fingerprint $CA_FINGERPRINT --install Now whenever your computer tries to communicate with this Smallstep instance, it will be trusted because the step client can validate the certificate using the installed CA in our trust store. Below is an example output from a previous instance I had running\nThe root certificate has been saved in /home/ubuntu/.step/certs/root_ca.crt. The authority configuration has been saved in /home/ubuntu/.step/config/defaults.json. Installing the root certificate in the system truststore... done. Initialize ACME The Automatic Certificate Management Environment (ACME) protocol is what\u0026rsquo;s used by Lets Encrypt to issue a domain you control a certificate. In essence, it is signs the certificate request IF you can prove you control the domain name. Use this if you want to use traefik or certbot to generate and manage certificates for domains you control.\nFrom the local system, create a new ACME provisioner with a maximum of 45 days cert lifetime, instead of the default 24 hours, as follows\nstep ca provisioner add vps --type ACME -x509-default-dur=1080h -x509-min-dur=5m -x509-max-dur=1080h Here, I am creating a new provisioner named vps and I have set the default duration to 45 days (1080 hours) so all my certs that are created using default values will have a certificate with 45 days validity. The minimum duration indicates what is the lowest duration certificate that can be created, in this case 5 minutes. For the max, it is also set to 45 days. I chose 45 days due to a policy coming into effect after 15 March 2029, which limits all newly issued certificates to a maximum validity of 47 days.\nWhen prompted for password, enter the username step and generated password during CA initialization.\nIf there is a need to update this provisioner at a later date, run the following command\nstep ca provisioner update vps -x509-default-dur=1080h -x509-min-dur=5m -x509-max-dur=1080h Initialize JWK This approach is used to generate server certificate and key to be used for services that cannot use the ACME protocol as above, such as postgres TLS or for generating mTLS certificates. You can obtain a valid certificate for your services using this approach without needing to listen on port 80 for an ACME challenge response before the certificate is generated.\nFrom the local system, create a new JWK provisioner with a maximum of 45 days cert lifetime, instead of the default 24 hours, as follows\nstep ca provisioner add service --type JWK --create -x509-default-dur=1080h -x509-min-dur=5m -x509-max-dur=1080h Here, I am creating a new provisioner named service with a certificate validity of 45 days. The explanation is the same as above for ACME. Notice the --create flag which creates a new private key for this provisioner. step will prompt for a password to encrypt this key, you can either let step generate a random password or you can provide a password of your choosing.\nFollowing this, when prompted for password, enter the username step and generated password during CA initialization.\nGenerating certificate using JWK To generate a certificate using the JWK approach, ensure it is done on a local system that has been bootstrapped. We need this to communicate with our Smallstep instance to do the certificate signing and renewal.\nstep-cli ca certificate --provisioner service --san ${san1} --san ${san2} --not-after=1080h ${domain} ${base_dir}/server.crt ${base_dir}/server.key Here, we are explicitly defining the provisioner service to sign our certificate using the SAN and domain name, and storing the output certificate and key into a location of our choice.\nRenewing certificate To renew a certificate, I use the following systemd service file to renew certificates for my servives that do not use traefik\n$HOME/.config/systemd/user/renew-cert.service\n[Unit] Description=Certificate renewer for service After=network-online.target Documentation=https://smallstep.com/docs/step-ca/certificate-authority-server-production StartLimitIntervalSec=0 [Service] Type=oneshot Environment=STEPPATH=/home/user/.step \\ CERT_LOCATION=/containers/mailpit/data/server.crt \\ KEY_LOCATION=/containers/mailpit/data/server.key \\ CONTAINER_NAME=mailpit ; ExecCondition checks if the certificate is ready for renewal, ; based on the exit status of the command. ExecCondition=/usr/bin/step-cli certificate needs-renewal ${CERT_LOCATION} --expires-in 75% ; ExecStart renews the certificate, if ExecStartPre was successful. ExecStart=/usr/bin/step-cli ca renew --exec \u0026#34;docker restart ${CONTAINER_NAME}\u0026#34; --force ${CERT_LOCATION} ${KEY_LOCATION} [Install] WantedBy=default.target $HOME/.config/systemd/user/renew-cert.timer\n[Unit] Description=Run certificate renewal check at scheduled time Requires=renew-cert.service [Timer] Unit=renew-cert.service OnCalendar=Sat *-*-* 01:00:00 [Install] WantedBy=timers.target Replace /home/user with your own username and update the location of your container accordingly. I have configured the service to check if the certificate is nearing expiry if its within 75% of the expiry time, which is the recommended timeframe for certificate renewal by Lets Encrypt.\nStart and enable the timer using the following command\nsystemctl --user enable renew-cert.timer systemctl --user start renew-cert.timer This guide specifically focuses on using Smallstep as a TLS certificate issuer. It can also be used to issue SSH certificates, which I might cover in a future post.\nWith the earlier tasks done, we can proceed to Part 4 of the guide, the final part in this series, where we set up the Caddy reverse proxy.\n","permalink":"https://vicknesh.info/articles/2025/08/ca-series-part-3-smallstep-ca/","tags":[{"LinkTitle":"Guides","RelPermalink":"/tags/guides/"},{"LinkTitle":"Linux","RelPermalink":"/tags/linux/"},{"LinkTitle":"Archlinux","RelPermalink":"/tags/archlinux/"},{"LinkTitle":"Network","RelPermalink":"/tags/network/"}],"title":"Part 3 - Setting up Smallstep CA"},{"categories":[],"content":"Following Part 1 of the series, the first component to be set up is the AdGuard Home DNS server. I chose this because it also blocks ads and unwanted services which enables my VPN clients to have a better web browsing experience. Aside from this, I get a useful GUI to view resolutions requests and to configure custom domains in an easy-to-use manner. I did contemplate utilizing dnsmasq but finally decided on AdGuard Home.\nDocker Compose The Docker Compose file and configuration of AdGuard Home is located in /containers/adguardhome base folder.\n/containers/adguardhome/docker-compose.yaml\nservices: adguardhome: image: adguard/adguardhome:latest container_name: adguardhome restart: unless-stopped volumes: - \u0026#39;/containers/adguardhome/work:/opt/adguardhome/work\u0026#39; - \u0026#39;/containers/adguardhome/config:/opt/adguardhome/conf\u0026#39; networks: - webproxy ports: - \u0026#39;192.168.200.1:3000:30003/tcp\u0026#39; # initial setup port - \u0026#39;192.168.250.1:53:53/tcp\u0026#39; # listen for DNS on webproxy interface (tcp) - \u0026#39;192.168.250.1:53:53/udp\u0026#39; # listen for DNS on webproxy interface (udp) - \u0026#39;192.168.200.1:53:53/tcp\u0026#39; # listen for DNS on wireguard interface (tcp) - \u0026#39;192.168.200.1:53:53/udp\u0026#39; # listen for DNS on wireguard interface (udp) networks: webproxy: external: true In this setup, I decided to have AdGuard Home listen on 3 interfaces - the Docker webproxy interface so I can force Docker to route all DNS requests to THIS DNS. - the wireguard interface so I can give the option for all my Wireguard clients to route all DNS requests to THIS DNS.\nWith this done, I run docker compose up to bring this container up and for it to create the necessary folders. With that out of the way, from my Wireguard client, I connect to http://192.168.200.1:3000/ allowing me to configure AdGuard Home. I always change the Admin Web Interface listen port from 80 to 8000. Ensure the DNS server is set to listen on ALL interfaces port 53. The last step is to choose a strong username and password combination. Continue with the setup until the launch dashboard option. Since we haven\u0026rsquo;t exposed port 8000, our attempt to connect to it will fail.\nAdGuard Home Initial Setup With the setup done, I terminate this container using CTRL+C and edit /containers/adguardhome/docker-compose.yaml again to remove the '192.168.200.1:3000:30003/tcp'. I no longer need it since I will be using caddy to access the AdGuard Home Admin UI.\nI start the container back up using docker compose up -d to have it running perpetually.\nFirewall My VPS runs ufw as the firewall frontend so I have a rule that allows DNS traffic to traverse between the interfaces without being blocked. As the DNS server is not exposed on any of the public IP, this approach ensures there is no situation where a service or container will not be able to resolve any DNS queries\nufw allow proto udp from any to any port 53 ufw allow proto tcp from any to any port 53 The next step is to force Docker to use our new DNS server for all its requests. This is a key item to ensure any resolution to custom domain names succeeds and returns the correct IP address for the domain.\nDNS for Docker Create or edit the file /etc/docker/daemon.json and ensure a similar line to the following exists in it\n{ \u0026#34;dns\u0026#34;: [ \u0026#34;192.168.250.1\u0026#34; ] } using the IP address of the webproxy interface to force all containers to use this specific DNS instance. Make sure to restart Docker for these changes to take effect.\nDNS for VPS The last step is to force the VPS to route all DNS requests to this AdGuard Home instance. My instance uses systemd-networkd with systemd-resolved to set the IP address so I modified my existing network configuration file at /etc/systemd/network/20-wired.network with the following contents\n[Match] Name=enp1s0 [Network] DHCP=yes IPv6PrivacyExtensions=yes Address=2404:1:2:3::1001/128 Address=2404:1:2:3::9999/128 DNS=192.168.250.1 # IP address of the `webproxy` interface I prefer to reboot my VPS after all these changes to make sure there is nothing lingering in the background. After a successful reboot, I verify the availability by using the dig command to resolve a domain of my choice and checking the AdGuard home logs for the query.\nAfter this, my VPS will use AdGuard Home for all its DNS resolution. With this in place, we can move on to\nNow we can proceed to Part 3 of the guide, setting up the Smallstep Certificate Authority server.\n","permalink":"https://vicknesh.info/articles/2025/08/ca-series-part-2-adguard/","tags":[{"LinkTitle":"Guides","RelPermalink":"/tags/guides/"},{"LinkTitle":"Linux","RelPermalink":"/tags/linux/"},{"LinkTitle":"Archlinux","RelPermalink":"/tags/archlinux/"},{"LinkTitle":"Network","RelPermalink":"/tags/network/"}],"title":"Part 2 - Setting up AdGuard Home"},{"categories":[],"content":"I am in the process of rebuilding my personal Certificate Authority using Smallstep on a cloud VPS. My previous VPS was running for a few years but I didn\u0026rsquo;t document how I got the whole concept working. This time around, I decided to jot my notes down so I can replicate this back in the future if needed. This time, I also decided to make a little change to my setup, that is changing from traefik to caddy, not because traefik doesn\u0026rsquo;t work but I just wanted consistency across all my public-facing web servers.\nThis private CA manages custom domains that are not exposed over the global Internet and is only accessible from my wireguard tunnels.\nFor this setup, I have 4 primary components.\nwireguard - provides secure tunnel capabilities. AdGuard Home - acts as a DNS server, that returns results for my custom domains and also blocks ads and such for the clients that connect over wireguard. Smallstep CA - issues TLS certificates to the services that need it. Caddy - serves as the reverse proxy for AdGuard Home and Smallstep CA. I am breaking this guide into 5 parts to cover each area so I don\u0026rsquo;t miss out on anything important later. While I have an Ansible playbook to automate this now, having a manual record of how I did it would be beneficial when I want to explore new ideas using this same concept.\nSmallstep CA Infrastructure In the above diagram, the VPS has a public IP of 1.2.3.4, the wireguard interface has 192.168.200.1 and the webproxy docker network has the IP 192.168.250.1. I have a guide on setting up Wireguard which is crucial for this particular project.\nIn this setup, I actually created a new docker network with a specific set of IP range so I can have my adguardhome container listening on both the wireguard and webproxy network. Create a new network with the command\ndocker network create dns --subnet=192.168.250.1/24 This network interface will also be used by caddy that acts as a reverse proxy to forward all requests to the correct container as they would all sit on the same network.\nNow we can proceed to Part 2 of the guide, setting up AdGuard Home DNS server.\n","permalink":"https://vicknesh.info/articles/2025/07/ca-series-part-1-custom-ca-with-smallstep-on-vps/","tags":[{"LinkTitle":"Guides","RelPermalink":"/tags/guides/"},{"LinkTitle":"Linux","RelPermalink":"/tags/linux/"},{"LinkTitle":"Archlinux","RelPermalink":"/tags/archlinux/"},{"LinkTitle":"Network","RelPermalink":"/tags/network/"}],"title":"Part 1 - Custom CA with Smallstep on a VPS"},{"categories":[],"content":"I’ve been using SSH certificates for years to connect to my servers no matter where they are, and they’ve always worked perfectly. I’ve used both client and server certificates, but since I automated the setup I sometimes forget the steps. This guide records the process for future reference.\nWhat are SSH Certificates? Just as HTTPS certificates verify our websites, SSH certificates confirm the identity of both server and user before any connection begins. When you first connect to a new SSH server, you’ve no doubt seen that warning about an unknown host key and clicked “yes” because you just created the machine and assume it’s safe. SSH certificates remove that guesswork. A trusted authority signs the server’s public key in advance, and your client automatically checks that signature on every connection. On the flip side, the server only accepts user keys that carry a valid signature from the same authority. Certificates can include expiration dates and be revoked if necessary, giving you precise control over who can connect and for how long. With SSH certificates in place, there’s no need to blindly trust that initial prompt.\nSSH Certificate Authority An SSH Certificate Authority (CA) is the single trusted entity that issues and manages SSH certificates for both servers and users. Instead of copying individual public keys to every machine, you rely on your CA to vouch for them all.\nKey responsibilities of an SSH CA\nKey generation\nThe CA creates a dedicated key pair. The private key remains securely stored. The public key becomes your root of trust. You distribute it to every SSH client and server.\nCertificate issuance\nWhenever a user or host key needs certification, the CA signs that public key. The certificate embeds details such as allowed usernames, a validity period and any additional restrictions.\nTrust distribution\nServers declare the CA public key as trusted for user certificates by setting TrustedUserCAKeys in sshd_config and accept only certificates signed by that CA. Clients add the CA public key to known_hosts or a global known hosts file so any host certificate issued by the CA is automatically recognised.\nExpiry and revocation\nAll certificates carry an expiration date. Once that date passes the certificate is invalid. If a certificate must be revoked before expiry, you maintain a revocation list that servers check to deny compromised certificates.\nBy using an SSH Certificate Authority you gain central control over who can connect to your servers, reduce administrative overhead and enforce time limited access. Certificates remove the need to distribute or revoke individual public keys on every machine.\nFor verifying both servers and users you can use a single CA or maintain separate CAs. I prefer to keep them distinct—one CA for host certificates and another for user certificates. This makes trust boundaries clear and simplifies revocation. To generate a new SSH CA key pair, run:\nssh-keygen -t ed25519 -f $HOME/ssh/ca -C \u0026#34;SSH Certificate Authority\u0026#34; Change the path for the public and private key for the CA as needed, with an easy to recognize comment.\nWhen prompted, pick a strong passphrase and store it in a secure location. You can leave the CA key unencrypted, but protecting it with a passphrase is strongly recommended.\nThe output is a private key at $HOME/ssh/ca and public key at $HOME/ssh/ca.pub\nSSH CA for Hosts We require the SSH public key from the host we are interested in, which is stored in the /etc/ssh/ssh_host_{ecdsa,ed25519,rsa}_key. I typically choose the ed25519 key for my host certificate as that\u0026rsquo;s my preferred key type. Alternatively, we can obtain the public key via the ssh-keyscan command\nssh-keyscan -t ed25519 -p 10022 host.example.com where 10022 is the post SSH is listening on and host.example.com is the address of the host (this can be an IP address or fully qualified domain name). This approach saves us the trouble of logging into the server to get a copy of the public key.\nWith a copy of the host public key, we can start to create a certficate for it using the command\nssh-keygen -s $HOME/ssh/ca -I key_id -V +52w -h /path/to/host_key.pub where\nFlag Description -s path to the CA for signing the host public key. -I identifier that will appear in the logs, i usually give it the host name. -V +52w how long is this certificate valid for, I typically rotate my certificates after a year (52 weeks). -h indicate the public key being signed is a host key. The output will be named host_key-cert.pub, where it will take the name and extension provided and append the word -cert.\nWith our new cert ready, copy the contents of host_key-cert.pub and save it to /etc/ssh/server.crt on the host, that is readable only by the host via the chmod 0400 /etc/ssh/server.crt. Now create a file /etc/ssh/sshd_config.d/00-cert.conf and add\nHostCertificate /etc/ssh/server.crt This explicitly tells our SSH server to present this certificate to the client when it connects for verification. Restart the SSH service for this changes to take effect immediately.\nOn the client side, they need to trust the certificate offered by the host. The way to do this is to add it to the known_hosts file and adding the line\n@cert-authority * ssh-ed25519 \u0026lt;CA public key\u0026gt; where\nFlag Description @cert-authority indicates anything following is information about the certificate authority. * indicates which domain or IP to apply this CA is for, it\u0026rsquo;s the hostname defined in the ssh_config on the clients machine. ssh-ed25519 key type of the CA public key. contents of the CA public key we generated, in this example its at $HOME/ssh/ca.pub Ideally, this setup would be done via Ansible or some other approach during server setup and intialization. That way, the client will never be shown the prompt on first connect. Not only that, the known_hosts file will no longer be filled with old server signatures.\nHappy SSH-ing!!\n","permalink":"https://vicknesh.info/articles/2025/07/ssh-certificates/","tags":[{"LinkTitle":"Guides","RelPermalink":"/tags/guides/"},{"LinkTitle":"Linux","RelPermalink":"/tags/linux/"},{"LinkTitle":"Archlinux","RelPermalink":"/tags/archlinux/"},{"LinkTitle":"Network","RelPermalink":"/tags/network/"},{"LinkTitle":"Security","RelPermalink":"/tags/security/"}],"title":"SSH Certificates"},{"categories":[],"content":" About This Build\nThis build explores the design of Tharn Wildvein, a Half-Orc Barbarian in Dungeons \u0026amp; Dragons 5e inspired by the essence of Wolverine — the feral loner, the unstoppable survivor, the relentless fury in the face of overwhelming odds.\nRather than a direct adaptation, this is a fantasy reinterpretation: a savage warrior whose power is not bestowed by science or sorcery, but awakened by rage, trauma, and unrelenting instinct. His body is the weapon — muscle, claw, and willpower forged through countless battles.\nThis build embraces the Path of the Beast from Tasha’s Cauldron of Everything, reflecting a character who transforms in rage, not into a monster, but into a more authentic version of himself. When the beast inside stirs, claws sprout, wounds close, and enemies fall. He doesn’t fight for glory or vengeance — he fights because it’s all he knows.\nThese first three levels lay the groundwork for that narrative: a creature of primal fury and brutal resilience. The mechanics support a wild, unarmored juggernaut with claws sharp enough to tear plate and a soul too stubborn to die.\n🪓 Step-by-Step Build Reasoning – Tharn Wildvein, Half-Orc Barbarian (Path of the Beast, Levels 1–3) Race: Half-Orc\nClass: Barbarian\nBackground: Outlander\nAlignment: Neutral\nSubclass (Level 3): Path of the Beast\nPlaystyle: Rage-fueled brawler with natural weapons, self-healing, and relentless tenacity\n📊 Ability Scores (Point Buy + Half-Orc ASI) Stat Score Modifier STR 15 + 2 = 17 +3 DEX 13 +1 CON 14 + 1 = 15 +2 INT 8 -1 WIS 10 +0 CHA 10 +0 🧬 Race Features – Half-Orc Darkvision (60 ft) Relentless Endurance (Drop to 1 HP once per long rest) Savage Attacks (Crits deal extra weapon die) Intimidation proficiency (Unnerving presence) 🧭 Background – Outlander Skills: Athletics, Survival Tools: One musical instrument (e.g., bone flute) Feature: Wanderer – natural explorer and forager 💢 Barbarian – Class Features by Level 🩸 LEVEL 1 – The Survivor Hit Points: 15 (12 + CON) Rage (2/day): +2 melee damage, resistance to B/P/S Unarmored Defense: 10 + DEX + CON = AC 15 Proficiencies: Athletics, Perception Gear: Greataxe, handaxes, explorer’s pack, no armor A feral brawler who shrugs off wounds and thrives in the wild. Built to keep moving forward no matter how many times he\u0026rsquo;s knocked down.\n⚔️ LEVEL 2 – Reckless Fury Reckless Attack: Gain advantage on STR melee attacks — enemies get advantage against you Danger Sense: Advantage on DEX saves vs visible effects (traps, spells) Always swing first, always swing hard. Risk is just another word for “motivation.”\n🧬 LEVEL 3 – Awaken the Beast Subclass: Path of the Beast\nForm of the Beast (choose on each rage):\nClaws (Default): 1d6 + STR slashing, and make an extra claw attack (3 attacks total at Lv5) Bite: 1d8 + STR; heal for prof. bonus if below half HP Tail: 1d8 + STR; add 1d8 to AC as reaction Rage Damage: +2\nRages per Day: 3\nClaws for combat, bite for survival, tail for defense. All aspects of a creature who refuses to die cleanly.\n🧠 Skills (Proficient) Athletics (STR) Perception (WIS) Intimidation (CHA) Survival (WIS) 🪓 Combat Routine Open combat with a roar and Rage → Choose Claws Use Reckless Attack for advantage and go all-in Rely on Unarmored Defense + half damage resist + Relentless Endurance to stay in the fight Switch to Bite when heavily wounded to self-heal mid-battle 🎒 Inventory Highlights Greataxe (ceremonial, rarely used) Handaxes (flavored as backup weapons) Leather wraps for fists and forearms (flavor for natural weapons) Bone flute (keeps him centered between battles) Scavenged mementos from fallen foes 💬 RP Summary Theme: A savage nomad haunted by fragmented memories and blood-soaked instincts. He doesn’t remember his tribe — only the scream of war drums and the cold bite of steel. When rage hits, it’s not just power he unleashes — it’s truth. The beast is who he really is.\n“I’m not here to win. I’m here to make sure you lose.”\n","permalink":"https://vicknesh.info/articles/2025/05/5e-character-wolverine-building/","tags":[{"LinkTitle":"Games","RelPermalink":"/tags/games/"},{"LinkTitle":"Rpg","RelPermalink":"/tags/rpg/"},{"LinkTitle":"Solo","RelPermalink":"/tags/solo/"},{"LinkTitle":"Dnd5e","RelPermalink":"/tags/dnd5e/"},{"LinkTitle":"Fantasy","RelPermalink":"/tags/fantasy/"}],"title":"D 5E Character - Wolverine - Building"},{"categories":[],"content":" About This Build\nThis build explores the design of Jaxen Vantrell, an Armorer Artificer in Dungeons \u0026amp; Dragons 5e inspired by the concept of Iron Man — especially the Heroes Reborn saga, where the character’s brilliance, adaptability, and sheer variety of power suits took center stage.\nRather than a direct conversion, this is a high fantasy reimagining of the archetype: a genius arcane engineer who doesn’t rely on destiny or lineage, but on crafted armor, magical augmentation, and relentless iteration. Every infused item, every armor model, every spell reflects a different version of “the suit” — modular, reactive, and purpose-built.\nJaxen exists in a world where magic and metal intertwine. His workshop is filled with failed prototypes and half-finished schematics. His armor isn\u0026rsquo;t just protection — it\u0026rsquo;s legacy, expression, and escalation. This build is meant for campaigns that celebrate invention as heroism and treat arcane technology as a viable answer to dragons, liches, and war itself.\nThe levels that follow (1–3) lay the foundation for that fantasy, balancing narrative identity with rule-legal mechanics. Each step reinforces the idea of a self-made arcane sentinel — one who doesn’t just wear armor, but becomes it.\n⚙️ Step-by-Step Build Reasoning: – Jaxen Vantrell, Half-Elf Artificer (Armorer, Levels 1-3) Race: Half-Elf\nClass: Artificer (Armorer)\nBackground: Guild Artisan\nAlignment: Neutral Good\nArmor Model (at Level 3): Guardian\nPlaystyle: Arcane-powered brawler with gadgetry, shields, and thunder-powered gauntlets\n📊 Ability Scores (Point Buy + Half-Elf ASI) Stat Score Modifier STR 10 +0 DEX 14 +2 CON 14 +2 INT 17 → 18 +4 WIS 10 +0 CHA 12 +1 ASI: +2 CHA (Half-Elf), +1 INT, +1 CON 🎭 Race Features – Half-Elf +2 CHA, +1 INT, +1 CON Darkvision (60 ft) Fey Ancestry (Adv. vs Charm, immune to magical sleep) Bonus Skills: Investigation, Perception 🧰 Background – Guild Artisan Skills: Insight, Persuasion Tools: Smith’s Tools, Tinker’s Tools, one language Feature: Guild Membership – allies, lodging, and contacts 🎓 Artificer – Class Features by Level 🎖️ LEVEL 1 – The Genius Begins Hit Points: 1d8 + CON = 10 HP Armor: Light, Medium, Shields Weapons: Simple weapons Tools: Tinker’s Tools, Thieves’ Tools, Smith’s Tools Spellcasting: 2 cantrips, 2 prepared 1st-level spells Magical Tinkering: Minor magical effects from devices Cantrips:\nMending (Suit repairs) Mage Hand (Arcane manipulator) Spells (2 slots):\nShield (Emergency defense +5 AC) Faerie Fire (HUD highlight enemies) Cure Wounds (Emergency repairs) Absorb Elements (Energy resistance) ⚒️ LEVEL 2 – Gadgeteer Online Infuse Item (2 infusions active) Infusion Choices: Enhanced Defense (Armor +1 AC) Enhanced Weapon (Boost weapon or thunder gauntlets) Repeating Shot (Crossbow arm?) Mind Sharpener (Helm resilience) Updated Loadout:\nHalf Plate (15 AC) + Infusion = 16 AC Shield = +2 AC (total 18) Thunder Gauntlet = Infused weapon (counts as magical) Spellcasting: Now can prepare INT mod + Artificer level (8 spells)\nAdd Identify, Feather Fall, Grease as optional tech gadgets ⚙️ LEVEL 3 – IRON VANGUARD ACTIVATED Subclass Chosen: Armorer Armor Model: Guardian Features Gained: Arcane Armor: Worn as a second skin Thunder Gauntlets: 1d8 thunder + Disadvantage debuff Defensive Field: Bonus action Temp HP (3/day = 3×3 HP) Updated Equipment:\nThunder Gauntlets (1d8 + INT = 1d8+4 thunder) Armor AC = Half Plate (15) + Infusion + Shield = AC 19 Combat Routine:\nOpen with Defensive Field (Temp HP = 3) Punch with Thunder Gauntlets – impose Disadvantage on enemy Cast Shield or Absorb Elements as reactions Use Faerie Fire for advantage setup 🧠 Skills (Proficient) Arcana (INT) Investigation (INT) Insight (WIS) Perception (WIS) Persuasion (CHA) History (INT) 🎒 Inventory Highlights Half Plate Armor (infused) Shield (infused with repulsion or static) Thunder Gauntlets (as part of Arcane Armor) Smith’s Tools, Tinker’s Tools, Thieves’ Tools Common Clothes + artisan’s insignia 💬 RP Summary Theme: Young genius from a merchant family builds prototype arcane armor to protect others. Inspired by the magic-fueled devastation he\u0026rsquo;s witnessed, he now walks the world encased in an ever-evolving storm-forged suit.\n“Sometimes, the only thing standing between chaos and peace… is a little armor, a little lightning, and a lot of guts.”\n","permalink":"https://vicknesh.info/articles/2025/05/5e-character-iron-man-building/","tags":[{"LinkTitle":"Games","RelPermalink":"/tags/games/"},{"LinkTitle":"Rpg","RelPermalink":"/tags/rpg/"},{"LinkTitle":"Solo","RelPermalink":"/tags/solo/"},{"LinkTitle":"Dnd5e","RelPermalink":"/tags/dnd5e/"},{"LinkTitle":"Fantasy","RelPermalink":"/tags/fantasy/"}],"title":"DND 5E Character - Iron Man - Building"},{"categories":[],"content":" Design Note\nZareth Kael is a personal homage to one of my all-time favorite characters — The Darkness, from the Top Cow comic series. I read the entire run starting from the 1990s, and the idea of a reluctant antihero bound to an ancient, sentient force of shadow left a permanent impression on me.\nIn reimagining this concept within 5E, I wanted to portray the Darkness not just as a weapon or curse, but as a primordial entity — protective and parasitic, elegant and monstrous. Its presence isn\u0026rsquo;t loud or overt, but it shapes every moment Zareth lives through, watching from behind a cracked mirror and whispering between spells.\nMechanically, this build sticks entirely to official content from the Player’s Handbook, Xanathar’s Guide to Everything, and Tasha’s Cauldron of Everything, with strategic reflavoring to evoke the tone of The Darkness. The Great Old One patron represents its unknowable origin; Pact of the Chain manifests the creature’s sentient extensions as a Shadowling familiar. And Armor of Agathys, reimagined as Armor of the Darkness, conjures its iconic necrotic retaliation.\nZareth’s arcane focus is his trinket — the Mirror of the Void, a cracked, obsidian glass that never shows his reflection. When he casts, its surface shimmers with veiled motion, a reminder that something inside always watches.\nThis isn’t just a character — it’s a tribute to a legacy I’ve carried for decades. The power, the corruption, the armor, the voice\u0026hellip; they are all one and the same.\nThe building guide for this character can be found here 🕳️ Character Sheet – Shadowmarked Warlock (Level 3) Zareth Kael - Reflavoured Tiefling Warlock as The Darkness 📛 Name: Zareth Kael Race: Tiefling (Shadowmarked – reflavored via Tasha\u0026rsquo;s Cauldron of Everything)\nClass: Warlock 3\nPatron: The Darkness (reflavored from The Great Old One)\nPact Boon: Pact of the Chain\nBackground: Haunted One (from Curse of Strahd)\nAlignment: Chaotic Neutral\n🧠 Ability Scores (Point Buy) Ability Score Modifier Strength 10 +0 Dexterity 15 +2 Constitution 14 +2 Intelligence 10 +0 Wisdom 10 +0 Charisma 16 +3 ❤️ Vital Stats Hit Points: 24 Armor Class: 13 (Leather) or 15 (Mage Armor) Initiative: +2 Speed: 30 feet Passive Perception: 10 Spell Save DC: 13 Spell Attack Bonus: +5 Spell Slots: 2 (2nd level) Proficiency Bonus: +2 🎯 Proficiencies Saving Throws: Wisdom (+2) Charisma (+5) Armor: Light armor Weapons: Simple weapons Tools: None Languages: Common Deep Speech One other of your choice (e.g., Infernal, Abyssal, or Undercommon) 🧪 Skill Proficiencies Skill Modifier Source Arcana +2 Warlock (INT + Prof) Deception +5 Warlock (CHA + Prof) Investigation +2 Haunted One (INT + Prof) Religion +2 Haunted One (INT + Prof) All other skills use base modifiers only.\n🎭 Race Features – Shadowmarked Tiefling +2 Charisma, +1 Dexterity Darkvision: 60 ft Necrotic Resistance Innate Spells: Minor Illusion (at will) Hellish Rebuke (1/day at 3rd level) Darkness (1/day at 5th level) 🔮 Warlock Features Awakened Mind Speak telepathically to any creature within 30 ft that knows a language. Pact of the Chain Gain a Darkling Familiar (custom-flavored Quasit) Can attack, scout, or deliver touch spells Use Voice of the Chain Master to speak/see through it at any range Eldritch Invocations Invocation Description Eldritch Mind Advantage on concentration saving throws Voice of the Chain Master (or Agonizing Blast, if kept) See/hear/speak through familiar or deal +CHA with Eldritch Blast If you prefer damage early, take Agonizing Blast at level 2 and swap to Voice of the Chain Master at level 3.\n📶 Spell Progression by Level 🧩 Level 1 Cantrips:\nEldritch Blast (main attack) Mage Hand (flavored as a shadow tendril) Minor Illusion (racial) Spells Known (2):\nHex — damage boost and control Armor of Agathys (flavored as Armor of the Darkness) — temp HP and necrotic retaliation Racial Spell:\nHellish Rebuke — 1/day, reaction fire damage on getting hit 🔮 Level 2 +1 Spell Known (Total: 3)\nAdded: Mage Armor — 8-hour defense (AC 15) Invocations:\nEldritch Mind Agonizing Blast (or prep to swap at L3) 👁️ Level 3 +1 Spell Known (Total: 4)\nAdded: Invisibility — become unseen, great for escapes and strikes Pact Boon:\nPact of the Chain — gain your Shadowling familiar 2nd-Level Spell via Warlock Slot:\nMisty Step — teleport 30 ft as a bonus action Technically not on Warlock’s list unless from feat or multiclass. If allowed in your campaign as thematic reflavoring, it fits beautifully. Otherwise, you may choose another control spell like Hold Person, Mirror Image, or Suggestion.\n🧚 Shadowling Familiar A chittering voidling, born from Zareth\u0026rsquo;s soul. Its claws glisten like obsidian glass and its laughter never quite fades.\nType: Tiny Fiend\nSpeed: 20 ft, fly 40 ft\nAC: 13\nHP: 10\nDarkvision: 120 ft\nLanguages: Understands Common, Deep Speech\nMagic Resistance: Advantage on all saves vs spells\nShadowmeld (1/day):\nBecomes invisible in darkness for 1 minute Actions:\nClaw: +5 to hit, 1d4 + 3 slashing Can deliver your touch spells Can scout or attack when commanded 🎒 Equipment Leather armor or robe (for flavor) Arcane Focus: Mirror of the Void A cracked obsidian mirror that never shows your reflection. Used to channel all spellcasting.\nDagger or quarterstaff Scholar’s Pack Custom Trinket: Obsidian mirror (see above) 🛡️ Armor of the Darkness (Custom Spell) The Darkness rises to protect its vessel — a living barrier of voidstuff and vengeance.\nEffect: 10 temp HP Trigger: When hit by melee attack, deal 10 necrotic to attacker Scaling: +5 HP/damage per spell level Duration: 1 hour No concentration 🧪 Combat Summary Cast Mage Armor at start of day (AC 15) Bonus Action Hex → Action Eldritch Blast Use Invisibility to avoid conflict or set up ambushes Use Misty Step to escape, reposition, or surprise When surrounded or ambushed → Armor of Darkness Familiar scouts, distracts, and delivers spells when needed Use Hellish Rebuke reactively if struck 🎭 Roleplay Hooks Never makes direct eye contact — lets the mirror do it Voice is calm, but rarely blinks Doesn’t sleep — just meditates while the Shadowling watches Civilians feel uneasy but sometimes aid him without knowing why 🧚 Darkling Familiar (Reflavored Quasit) Darkling - Reflavoured Quasit A splinter of the Darkness itself, the Darkling is a sentient shadow stitched into a vaguely impish form. Its claws leave no marks, its laughter echoes in silence, and when no one is watching — it’s simply not there.\nTiny fiend (void-born), chaotic neutral\nArmor Class: 13\nHit Points: 10 (4d4)\nSpeed: 40 ft, climb 40 ft\nFly (flavored): Glides through shadows and unseen air currents\n🧠 Abilities STR 5 (−3) DEX 17 (+3) CON 10 (+0) INT 7 (−2) WIS 10 (+0) CHA 10 (+0)\nSaving Throws: Dexterity +5, Wisdom +2 Skills: Stealth +5, Perception +2 Damage Resistances: Cold, Fire, Lightning; Bludgeoning, Piercing, and Slashing from Nonmagical Attacks Damage Immunities: Necrotic Damage (replaces Poison) Condition Immunities: Poisoned Senses: Darkvision 120 ft., Passive Perception 12 Languages: Common, Deep Speech (or Abyssal); understands all you do ✨ Traits Magic Resistance.\nThe Darkling has advantage on saving throws against spells and other magical effects.\nShadowmeld (Invisibility).\nThe Darkling can turn invisible at will, reappearing as a bonus action or when it attacks. While in dim light or darkness, it effectively melts into the shadows.\nTelepathic Link (via Pact Feature).\nThrough Voice of the Chain Master, you can see, hear, and speak through the Darkling at any range, as long as you\u0026rsquo;re on the same plane.\n⚔️ Actions Claw (Void Rend). Melee Weapon Attack: +5 to hit, reach 5 ft., one target.\nHit: 1d4 + 3 slashing damage.\nDread Gaze (1/day).\nOne creature within 20 ft. that can see the Darkling must succeed on a DC 10 Wisdom saving throw or be frightened for 1 minute. The creature may repeat the save at the end of each of its turns.\n🪞 Pact Notes Can deliver touch spells you cast. Can attack if you use your action to command it. Shares initiative, acts on your turn. If destroyed, can be resummoned via Find Familiar (1 hour, no cost). 🖤 Roleplay Flavor Appears only where light falters Perches on your back or shoulders like a living cloak fragment Speaks in whispers when no one else is listening Occasionally seems to act before you think “We’re not alone. You never are. But I am.”\n","permalink":"https://vicknesh.info/articles/2025/05/5e-character-darkness/","tags":[{"LinkTitle":"Games","RelPermalink":"/tags/games/"},{"LinkTitle":"Rpg","RelPermalink":"/tags/rpg/"},{"LinkTitle":"Solo","RelPermalink":"/tags/solo/"},{"LinkTitle":"Dnd5e","RelPermalink":"/tags/dnd5e/"},{"LinkTitle":"Fantasy","RelPermalink":"/tags/fantasy/"}],"title":"DND 5E Character - The Darkness"},{"categories":[],"content":" About This Build\nThis step-by-step breakdown traces the mechanical and narrative design behind Zareth Kael, my reinterpretation of The Darkness comic character in Dungeons \u0026amp; Dragons 5e. As someone who grew up reading The Darkness from the 1990s onward, this project is more than just a character — it’s a tribute to one of my favorite antiheroes.\nI wanted to explore how Jackie Estacado’s cursed, sentient power could be expressed through official 5e mechanics, while leaning into my current interest in flawed, complex protagonists. This build is designed for a homebrew game I may run someday — dark, thematic, and soaked in psychic tension.\nWhat follows is a breakdown of how each level from 1 to 3 was planned and structured, blending narrative fidelity, combat efficiency, and rule-legal choices — no homebrew mechanics, only reflavored official options to reflect The Darkness\u0026rsquo;s living armor, whispering void, and monstrous familiar.\n🧩 Step-by-Step Build Reasoning: Zareth Kael, Shadowmarked Warlock (Levels 1–3) 🎯 Design Goals Thematic core: Inspired by The Darkness (Top Cow) Mechanically sound: Playable, optimized within official rules Visual + narrative cohesion: Living armor, tendrils, whispers, and psychic dread Legal choices: All drawn from Player’s Handbook, Xanathar’s Guide, Tasha’s Cauldron 🪐 Level 1 – Origin of the Darkness 🔹 Race: Tiefling (Tasha’s Cauldron of Everything variant, alt stat distribution) +2 Charisma, +1 Dexterity: Boosts primary stat and survivability Darkvision: For shadow-themed exploration and flavor Necrotic Resistance: Suits the concept of being part-shadow Innate Spells: Minor Illusion — a flicker of shadow or a whisper in the dark Hellish Rebuke — 1/day, a lash of fiery retribution from the void 🔹 Class: Warlock (The Great Old One) Spellcasting with Charisma Feature: Awakened Mind Telepathically speak to any creature within 30 ft that understands a language Ideal for eerie, one-way communication — silent dread, commanding presence 🔹 Background: Haunted One (Curse of Strahd) Skills: Religion, Investigation (lore and supernatural insight) Feature: Heart of Darkness — commoners instinctively fear and respect your presence Trinket / Arcane Focus: Mirror of the Void A small, cracked obsidian mirror that doesn’t show your reflection — instead, it stirs with shadows when you cast a spell.\n🔹 Ability Scores (Point Buy – 27 Points) Stat Final Reasoning STR 10 Neutral baseline (no penalty) DEX 15 Boosts AC and initiative CON 14 Needed for durability and temp HP scaling INT 10 Buffs Investigation and Religion skills WIS 10 Helps perception and saving throws CHA 16 Core stat for spells and invocations 🔹 Spells and Cantrips at Level 1 Cantrips Known: Eldritch Blast — a tendril of shadow force lashes outward Mage Hand — a spectral limb of void manipulates objects Minor Illusion (racial) — a whisper, a flicker, or a phantom echo Spells Known: Hex — curse your enemy, drain their essence Armor of Darkness (reflavored Armor of Agathys) — gain temp HP and deal necrotic backlash when struck 🧠 Why this combo?\nEldritch Blast + Hex is your bread-and-butter offense Mage Hand and Minor Illusion enhance roleplay, stealth, and trickery Armor of Darkness makes you dangerous to hit, and suits the living armor theme 🔮 Level 2 – Dark Awakening 🔹 New Feature: Eldritch Invocations Invocation Description Eldritch Mind Advantage on CON saves to maintain concentration (Hex, Invisibility) Agonizing Blast Add CHA modifier to Eldritch Blast — boosts core damage 🧠 Why this setup?\nAgonizing Blast turns Eldritch Blast into your primary damage engine Eldritch Mind ensures you can hold concentration on Hex or Invisibility 🔹 New Spell Known Mage Armor — passive defense (AC 15 all day, no concentration) 🧠 Why Mage Armor?\nLet your concentration focus on Hex or Invisibility Keeps your AC respectable without gear dependency 🧚 Level 3 – The Darkness Unleashed 🔹 Pact Boon: Pact of the Chain Gain a Darkling Familiar (reflavored Quasit) Can fly, turn invisible (Shadowmeld), scout, and deliver touch spells Reflects the living, lurking aspect of the Darkness 🧠 Why Pact of the Chain?\nZareth’s power is sentient — the familiar manifests that Adds tactical versatility, flavor depth, and spooky utility 🔹 Invocation Update (Optional) Now that your familiar is online: 🔁 Swap Agonizing Blast → Voice of the Chain Master to see/hear/speak through your familiar from any distance Or 💥 Keep Agonizing Blast to maintain stronger ranged damage 🧠 Choose based on playstyle:\nNarrative and recon focus → swap to Voice of the Chain Master Damage-first combat focus → keep Agonizing Blast 🔹 New Spell Known Invisibility — become unseen, set up attacks or escape 🧠 Why Invisibility?\nPerfect thematic fit — disappear into the shadow Ideal for infiltration, retreat, or striking unseen 🔹 2nd-Level Slot Utility (via Warlock casting) Misty Step — bonus action teleport (30 ft) Useful for escape, flanking, or dramatic entrances Fits your theme: vanish into shadow and reappear behind your foe Misty Step isn’t on the Warlock list normally — if allowed via reflavor, it’s a perfect fit. Otherwise, choose another utility spell like Mirror Image or Hold Person.\n🔹 Spells Known (Total: 4) Spell Reason for Inclusion Hex Core offense tool — damage + ability check penalty Mage Armor Passive defense — no concentration needed Invisibility Control, infiltration, or escape Armor of the Darkness Necrotic retaliation — temp HP + punishment for melee 🧪 Playstyle Summary (Level 3) 🧱 Defense Layers Mage Armor always up → AC 15 Armor of the Darkness = burst defense when expecting melee hits Shadowling helps distract, block, or deliver spells ⚔️ Combat Flow Bonus Action: Hex Action: Eldritch Blast (1d10 force + 1d6 necrotic) Use Invisibility or Misty Step to reposition or vanish Familiar can: Scout ahead Turn invisible Attack on command Deliver touch spells (Hellish Rebuke if readied or reflavored) 📌 Summary of Level Milestones Level Key Features Gained Purpose 1 Race, Patron, Hex, Armor of Darkness, Cantrips Establish theme, core mechanics, and survivability 2 Eldritch Mind, Agonizing Blast, Mage Armor Boost damage, concentration, and passive defense 3 Pact of the Chain, Shadowling, Invisibility, Misty Step Unlock full flavor: vanish, manifest, and command the Darkness ","permalink":"https://vicknesh.info/articles/2025/05/5e-character-darkness-building/","tags":[{"LinkTitle":"Games","RelPermalink":"/tags/games/"},{"LinkTitle":"Rpg","RelPermalink":"/tags/rpg/"},{"LinkTitle":"Solo","RelPermalink":"/tags/solo/"},{"LinkTitle":"Dnd5e","RelPermalink":"/tags/dnd5e/"},{"LinkTitle":"Fantasy","RelPermalink":"/tags/fantasy/"}],"title":"DND 5E Character - The Darkness - Building"},{"categories":[],"content":"Earthdawn Reforged – A Heroic Take on a Legendary World What happens when you take the lore-rich world of Earthdawn and explore it through the lens of Age of Sigmar: Soulbound’s heroic engine?\nWelcome to Earthdawn Reforged — a personal design experiment where I’m reimagining the Earthdawn setting using the mechanics of Soulbound. This isn’t a full system rewrite or community project — just something I’m exploring for my own creative enjoyment, to see how the themes of survival, horror, and magical legacy can play out in a more fast-paced, cinematic system.\nI first discovered Earthdawn 1st Edition in 1996, and it immediately captured my imagination with its layered setting, metaphysical magic, and post-apocalyptic tone. Unfortunately, I never had the chance to play it back then. Now, years later, I’ve decided to revisit that fascination — by running a solo campaign using my own unique setting and a hybrid system combining Earthdawn’s lore with Soulbound’s heroic, streamlined ruleset.\nWhy Mix Earthdawn and Soulbound? Earthdawn 1E cover art Earthdawn’s world of post-Scourge recovery, astral threats, and magical Threads has always been one of my favorite RPG settings. But its original system, while deep, can be complex at the table.\nAge of Sigmar Soulbound RPG Soulbound brings a very different energy:\nFast, action-first conflict resolution Narrative-forward play Mechanics that support heroic scale from session one This experiment is about merging the tone and structure of Earthdawn with the momentum and accessibility of Soulbound.\nWhat Have I Done So Far? I’ve converted several of Earthdawn’s core Disciplines into Soulbound-style archetypes I’m using custom spell paths (like a Nether Path) to reflect Earthdawn’s unique flavor I’ve sketched out mechanics for corruption, astral horror, and thread-infused equipment I might continue converting more Disciplines or setting elements as inspiration strikes This is very much a work-in-progress — and entirely for my own use at this stage.\nWhy Share It? Even though this is a solo experiment, I figured others might enjoy seeing how different systems can intersect. Whether you\u0026rsquo;re:\nA fan of Earthdawn’s setting Curious about system hybrids Or just like seeing how rules can be bent and reshaped… \u0026hellip;you might find something here that sparks your own creativity.\nJust for Fun This isn’t meant to replace Earthdawn or Soulbound — just a mash-up that plays to their shared strengths:\nastral danger, heroic legacy, and the journey out of darkness.\nIf I end up building more, I’ll share it here — no promises, no roadmap, just experimentation.\nEarthdawn Reforged is a name I’m using for now, but even that may change as the idea evolves.\nSoulbound Earthdawn 🧭 Earthdawn Disciplines as Soulbound Archetypes While this project is still evolving, one of the most exciting parts has been reimagining the core Disciplines of Earthdawn using Soulbound’s archetype structure. These aren\u0026rsquo;t just class conversions—they\u0026rsquo;re visual and mechanical expressions of what it means to be heroic in a world shaped by Threads, astral scars, and bound legacy.\nBelow, you\u0026rsquo;ll find my interpretations of each Discipline as they might appear in Earthdawn Reforged, grounded in cinematic action, thematic resonance, and a unified setting vision.\n☠️ Nethermancer Elf Nethermancer Role: Mage / Support\nDescription: Necromancer wielding astral and spirit power at a dangerous cost.\nCore Ability – Whispers from Beyond:\nUse the Nether Path spell list. If you fail a casting roll by only 1, the spell still succeeds but you gain 1 Corruption. On critical failure (double 1s), trigger a Minor Astral Intrusion (GM discretion). 🗡️ Swordmaster T'skrang Swordmaster Role: Warrior / Face\nDescription: Flamboyant duelists who use skill and flair to dominate.\nCore Ability – Flourish of Blades:\nOn a successful melee hit, spend 1 Mettle to make a second melee attack on another nearby target. If both attacks hit, gain +1 Defence until your next turn. May Taunt the second target (Mind vs Mind) to impose Disadvantage on their next attack. 🔥 Elementalist Dwarf Elementalist Role: Mage / Controller\nDescription: Masters of fire, water, earth, and air.\nCore Ability – Elemental Attunement:\nChoose one element at character creation. Gain +1 die on all spells of that element. Once per scene, reroll a failed spell roll using your attuned element. 🌀 Illusionist Elf Illusionist Role: Mage / Trickster\nDescription: Weavers of deception who bend reality through belief.\nCore Ability – Trick of the Mind:\nYou may roll Guile instead of Mind to cast Illusion spells. On a successful Illusion spell, one enemy suffers Disadvantage on their next test. 🎼 Troubadour Human Troubador Role: Support / Face\nDescription: Storytellers and historians who inspire, manipulate, and reveal truth.\nCore Ability – Voice of Legend:\nOnce per scene, grant +1 to all tests for 1 round to an ally with a performance. Gain +1 die to Lore or Guile when revealing or recalling hidden knowledge. 🔍 Thief Orc Thief Role: Scout / Utility\nDescription: Agile infiltrators who strike from shadows and bypass obstacles.\nCore Ability – Shadowstep:\nWhen starting your turn in cover, gain +1 to Reflexes. Ignore the first opportunity attack against you each round. 🧙 Wizard Obsidian Wizard Role: Mage / Versatile\nDescription: Scholars who master arcane disciplines with depth and variety.\nCore Ability – Arcane Mastery:\nChoose two Spell Paths at character creation. Once per scene, reduce the Mettle cost of a spell by 1. 🧘 Warrior Troll Warrior Role: Tank / Melee\nDescription: Unyielding defenders and linebreakers on the frontlines.\nCore Ability – Steel Resolve:\nReduce incoming damage by 1 (min 0) once per round. Gain +1 Defence when adjacent to an ally. 🕊 Weaponsmith Human Weaponsmith Role: Support / Crafter\nDescription: Masters of arms and armor, they forge strength into tools of war.\nCore Ability – Imbue Weapon:\nDuring a rest, bless a weapon. Its wielder gains +1 damage with it until the next rest. 🏹 Archer Elf Archer Role: Ranged DPS / Scout\nDescription: Masters of bow and battlefield precision.\nCore Ability – Called Shot:\nSpend 1 Mettle to ignore all cover bonuses or deal +1 damage by targeting a weak point. ⚔️ Sky Raider Orc Skyraider Role: Warrior / Mobility\nDescription: Bold airborne raiders who leap into the fray with devastating impact.\nCore Ability – Stormbound Leap:\nLeap 3 spaces as part of Move without triggering opportunity attacks. Once per scene, leap into enemies and make a free attack. 🐾 Beastmaster Human Beastmaster Role: Scout / Support\nDescription: Wild tamers with bonded animal companions.\nCore Ability – Bonded Companion:\nBegin with a beast companion (wolf, hawk, serpent, etc.). If it dies, perform a day-long ritual to bond with a new one. Where It Goes From Here This is, at its heart, a creative experiment — a way for me to explore two systems I love, and see what emerges when their strengths are combined. Whether it grows into a full campaign framework or simply remains a thought exercise, it’s already been a rewarding way to reconnect with the core ideas behind both Earthdawn and Soulbound: legacy, resilience, and heroism.\nThanks for reading, and if this inspires you to try something similar — even better.\nSee you in the Astral.\n","permalink":"https://vicknesh.info/articles/2025/04/soulbound-earthdawn/","tags":[{"LinkTitle":"Games","RelPermalink":"/tags/games/"},{"LinkTitle":"Rpg","RelPermalink":"/tags/rpg/"},{"LinkTitle":"Solo","RelPermalink":"/tags/solo/"},{"LinkTitle":"Soulbound","RelPermalink":"/tags/soulbound/"},{"LinkTitle":"Earthdawn","RelPermalink":"/tags/earthdawn/"},{"LinkTitle":"Fantasy","RelPermalink":"/tags/fantasy/"}],"title":"Soulbound Earthdawn"},{"categories":[],"content":"Once your server is up and running, you can configure a peer. The process is nearly identical to setting up the server—allowing you to easily replicate these steps for adding multiple peers. As always, ensure that all commands are executed as the root user.\nGenerate keys Each peer requires a unique public/private key pair to establish identity and secure connections, just like the server . Run the following commands to create the required files:\n(umask 0077; wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey) Create configuration file Create a configuration file for the new peer interface. In Wireguard, the configuration file’s name determines the interface name; for example, if you create /etc/wireguard/wg0.conf, the interface will be named wg0.\nOpen your editor and create (or modify) the file (e.g., /etc/wireguard/wg0.conf) with the following content:\n[Interface] Address = 10.201.1.2/24 PrivateKey = CLIENT_PRIVATE_KEY Address: The private network IP assigned to this peer. CLIENT_PRIVATE_KEY: The contents of the file /etc/wireguard/privatekey. Note that the peer configuration does not require PostUp or PostDown options, as these settings are only needed for routing or NAT operations on a server. A ListenPort might be needed if the peer is acting as a proxy for other peers, but this is uncommon in most setups.\nAdd Peer We need the server \u0026rsquo;s SERVER_PUBLIC_KEY and the preshared key (PEER_PSK) provided by your administrator. Add the following peer configuration:\n[Peer] PublicKey = SERVER_PUBLIC_KEY PresharedKey = PEER_PSK AllowedIPs = 10.201.1.0/24 Endpoint = 1.1.1.1:51281 PersistentKeepalive = 30 PublicKey: Identifies the remote peer and is crucial for establishing a secure connection. PresharedKey: Provides an additional layer of security for this specific connection. AllowedIPs: Specifies which IPs or ranges (e.g., /32, /24, /16) are allowed through this connection, serving as both a routing directive and an access control mechanism. If you want to restrict communication to a single IP, specify that IP with a /32 bitmask. Endpoint: Instructs this peer how to reach the remote peer—using an IP address or domain name along with the port number. PersistentKeepalive: Ensures the connection remains active by sending periodic keepalive messages. Also, retain the contents of /etc/wireguard/publickey as PEER_PUBLIC_KEY to pass to the server when configuring its peer.\nStart the Wireguard service To start this Wireguard peer instance, run:\nsystemctl start wg-quick@wg0 Be sure to replace wg0 with the appropriate Wireguard interface name used in your configuration.\nA Note on UFW and Routed Traffic When Using a Peer as a Proxy When using a peer as a proxy to route traffic between two networks, it\u0026rsquo;s important to be aware of UFW’s default behavior regarding forwarded traffic. Even if basic connectivity is established (evidenced by successful pings), routed connections such as SSH or other services may be blocked if not explicitly allowed.\nBy default, UFW denies routed (forwarded) traffic. This means that traffic intended to cross between different subnets or interfaces can be dropped, even if the peers themselves are connected.\nTo address this without compromising overall security, instead of setting UFW’s global forward policy to ACCEPT, you can add specific forwarding rules. For example, if you need to allow traffic from one particular IP (e.g., 10.201.1.1) to another (e.g., 10.222.2.2), you can modify UFW\u0026rsquo;s configuration as follows:\nEdit the UFW before.rules File:\nOpen the file:\nsudo vi /etc/ufw/before.rules Add a Custom Forwarding Rule:\nInsert the following rule in the ufw-user-forward chain before the COMMIT line:\n-A ufw-user-forward -s 10.201.1.1 -d 10.222.2.2 -j ACCEPT Reload UFW:\nsudo ufw reload This targeted rule will permit the necessary routed traffic between the specified IP addresses, ensuring that only the required traffic is allowed while maintaining a secure firewall posture.\nWrapping Up the Peer Setup Your peer configuration is now finalized, ensuring that this node only handles the specific traffic intended for it. Once connected, verify that your routing and connectivity work flawlessly, and that persistent keepalive maintains a stable link. With your secure connection established, you’re ready to integrate this peer into your overall VPN environment.\nStay connected and secure!\n","permalink":"https://vicknesh.info/articles/2025/04/wireguard-peer/","tags":[{"LinkTitle":"Guides","RelPermalink":"/tags/guides/"},{"LinkTitle":"Linux","RelPermalink":"/tags/linux/"},{"LinkTitle":"Archlinux","RelPermalink":"/tags/archlinux/"},{"LinkTitle":"Network","RelPermalink":"/tags/network/"}],"title":"Wireguard Peer"},{"categories":[],"content":"Refer to this article for a brief overview, prerequisites, and server details. Ensure you run all commands as the root user.\nGenerate keys Each server requires a unique public/private key pair to establish identity and secure connections. Run the following commands to create the required files:\n(umask 0077; wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey) wg genpsk # Generates a preshared key for Peer A (adds an extra layer of encryption) Create configuration file Create a configuration for the new interface. In Wireguard, the configuration file\u0026rsquo;s name determines the interface name. For example, if you create /etc/wireguard/wg0.conf, the interface will be named wg0.\nOpen your editor and create or edit the file (e.g., /etc/wireguard/wg0.conf) with the following content:\n[Interface] Address = 10.201.1.1/24 ListenPort = 51281 PrivateKey = SERVER_PRIVATE_KEY PostUp = iptables -I FORWARD 1 -i %i -j ACCEPT; iptables -t nat -I POSTROUTING 1 -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE Address: The private network address assigned to this server instance. ListenPort: The UDP port on which the server listens for incoming connections (used in the client configuration). SERVER_PRIVATE_KEY: The contents of the file /etc/wireguard/privatekey. PostUp/PostDown: These commands set up and tear down NAT and forwarding rules. %i automatically expands to the interface name (e.g., wg0), and eth0 should be replaced with your actual interface responsible for global internet connectivity. To allow the server to route traffic between the VPN and the internet, enable IP forwarding. Create or edit a sysctl configuration file at /etc/sysctl.d/10-ip-forward.conf with these lines:\nnet.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 Then, reload the sysctl settings:\nsysctl --system Configure Firewall Enable the firewall on your server and ensure that both SSH (typically on port 22) and the Wireguard UDP port (51281) are allowed. Replace 1.1.1.1 with your server’s public IP address as needed.\nufw allow proto udp from any to 1.1.1.1 port 22 ufw allow proto udp from any to 1.1.1.1 port 51281 ufw enable Adding Peers Before adding a peer configuration, complete the peer configuration since you\u0026rsquo;ll need the client\u0026rsquo;s private network address and public key. Save a copy of the server’s public key (located in /etc/wireguard/publickey and referred to as SERVER_PUBLIC_KEY) to use when setting up clients. Also, retain the preshared key generated by wg genpsk (PEER_PSK) to enhance security with an extra layer of encryption.\nOnce the peer configuration is ready, edit the /etc/wireguard/wg0.conf file and append the following at the end:\n[Peer] PublicKey = CLIENT_PUBLIC_KEY PresharedKey = PEER_PSK AllowedIPs = 10.201.1.2/32 Here, AllowedIPs is configured to permit only the specific IP address (with a /32 bitmask), ensuring that this peer only handles traffic intended for it.\nStart the Wireguard service To start this Wireguard peer instance, execute:\nsystemctl start wg-quick@wg0 Be sure to replace wg0 with the actual Wireguard interface name used in your configuration.\nVerifying Peer Setup on the Server Once the peer configuration is complete and the service is started, follow these steps on the peer machine to ensure its setup is working as expected:\nCheck the Wireguard Status:\nRun the following command to view active connections and verify the peer is listed with the correct parameters:\nwg show Look for your peer\u0026rsquo;s public key, allowed IPs, and the latest handshake time.\nTest Connectivity:\nFrom the server, ping the peer\u0026rsquo;s VPN IP address to confirm network connectivity. For example:\nping 10.201.1.2 A successful ping indicates that traffic is correctly routed between the server and the peer.\nMonitor Logs:\nCheck the Wireguard log for any errors or anomalies by executing:\njournalctl -u wg-quick@wg0 -f This live log view can help you identify and troubleshoot any issues during the connection.\nBy performing these checks, you can confidently verify that your Wireguard peer is correctly configured and operating as intended.\nWrapping Up the Server Setup Your server configuration is now complete, and your Wireguard server is ready to securely manage and route traffic between your network and the internet. Test the connection to ensure that NAT, IP forwarding, and all related settings function as expected. As your network evolves, remember that you can add more peers to expand your VPN\u0026rsquo;s reach.\nHappy networking!\n","permalink":"https://vicknesh.info/articles/2025/04/wireguard-server/","tags":[{"LinkTitle":"Guides","RelPermalink":"/tags/guides/"},{"LinkTitle":"Linux","RelPermalink":"/tags/linux/"},{"LinkTitle":"Archlinux","RelPermalink":"/tags/archlinux/"},{"LinkTitle":"Network","RelPermalink":"/tags/network/"}],"title":"Wireguard Server"},{"categories":[],"content":"For my VPN setup, I lean towards using Wireguard because it’s straightforward to configure and delivers great performance. This guide serves as a personal reference for when I need to set up Wireguard again—whether as a server or a client. While I typically run Ubuntu on my production servers, my personal homelab runs Archlinux. Although this guide is focused on Archlinux, the process is essentially the same on Ubuntu, aside from the installation details.\nAnother great feature of Wireguard is its flexibility—any host can function as a server or as a peer , and a peer can even act as a proxy for another peer without needing any special configuration.\nI’ve organized the guide into two server and peer easy reference. Before getting started with either setup, ensure Wireguard is installed on both your server and client machines.\nPre-requisites The first step is installing Wireguard. On Archlinux, run the following command as the root user or with sudo:\npacman -Syu --noconfirm wireguard-tools ufw ufw is used to configure iptables on the machines in a much easier to use approach.\nIf you’re setting up Wireguard in a Proxmox LXC container (for either a server or client), follow these steps:\nOpen the container configuration file: /etc/pve/lxc/123.conf (replace 123 with your container ID). Append these lines at the end of the file: lxc.cgroup2.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net dev/net none bind,create=dir Save and close the file. Update the owner of the tun device by running: chown 100000:100000 /dev/net/tun Server Details For this example, here are the details I’m using:\nItem Description Public IP Address 1.1.1.1 Public Facing Interface eth0 Wireguard IP 10.201.1.1/24 Wireguard Port 51281 Wireguard Interface wg0 Wireguard Configuration /etc/wireguard/wg0.conf When following this guide, be sure to replace these placeholder values with your own specific details. The configuration file is named after the interface: for example, if your interface is wg0, the configuration file will be wg0.conf.\nSetup Once everything is installed and your personalized details are in place, proceed with the respective guide for a server or peer setup to get things running.\nHappy networking, and may your connections be fast and secure!\n","permalink":"https://vicknesh.info/articles/2025/04/wireguard/","tags":[{"LinkTitle":"Guides","RelPermalink":"/tags/guides/"},{"LinkTitle":"Linux","RelPermalink":"/tags/linux/"},{"LinkTitle":"Archlinux","RelPermalink":"/tags/archlinux/"},{"LinkTitle":"Network","RelPermalink":"/tags/network/"}],"title":"Wireguard"},{"categories":[],"content":"🛡️ One Hero Engine – Core Rulebook (v 0.12) A solo-focused, narrative-driven RPG for mythic storytelling, bold decisions, and immersive worldbuilding. Designed to be lightweight in mechanics and rich in expression, One Hero Engine puts the story in your hands—no game master required.\nPart I: Creating Your Hero 1. What Is One Hero Engine? One Hero Engine (OHE) is a solo tabletop roleplaying system where you take the role of a single hero facing challenges, enemies, and unknown fates in a dynamic, mythic world.\nKey Points:\nNo game master required Oracle tools resolve uncertainty Lightweight but expressive mechanics Milestone-based leveling Character-first design Quick Reference:\nSolo RPG: Your hero, your adventure. Tools: Oracle and narrative twists. Progression: Milestone and levels guide growth. Character Sheet\n2. Character Creation Overview Assign Stats: Use 14, 13, 12, 11, 11, 11. You may redistribute up to 2 points between any scores. Choose a Race: Provides +1 to any stat, a saving throw specialization, and 1 of 5 racial Traits. Choose a Class: Grants a saving throw specialization and 1 of 5 class Traits. Pick 3 Tags: Narrative keywords that describe your background and skills. Choose a Casting Path (optional): For spellcasting, refer to Section 14. Finalize Derived Stats: Calculate stat bonuses, Soak, MP (if applicable), and record traits and tags. Quick Reference:\nSteps: Assign → Race → Class → Tags → Casting Path → Finalize. Customization: Flexible stat allocation and tag selection. 3. Ability Scores \u0026amp; Saving Throws Stats Stat Role STR Strength – Melee, grapples DEX Dexterity – Reflexes, stealth CON Constitution – Endurance, poison INT Intelligence – Lore, logic WIS Wisdom – Willpower, awareness CHA Charisma – Presence, persuasion Modifier Formula: (Stat - 10) ÷ 2, rounded down\nCombat Statistics Armor Class (AC): Your default AC is 9 plus your Dexterity modifier. To-Hit Bonus: When making attack rolls, use the higher of your Strength or Dexterity modifier. Damage Bonus: For melee attacks, add your Strength modifier; for ranged attacks, add your Dexterity modifier. Quick Reference:\nAC: 9 + Dex modifier. To-Hit: Best of STR or DEX modifier. Damage: STR for melee; DEX for ranged. Saving Throws Roll: 1d20 + modifier. Advantage: Apply if specialized. Disadvantage: Apply when enemies have traits or abilities imposing it. Spell Save TN: Equal to caster’s full stat score (e.g., INT 15 → TN 15). Use the GM or scenario to set difficulty for non-spell saving throws. Quick Reference:\nRoll: d20 + modifier. Bonus: Advantage if specialized. Target Number: Caster’s stat for spell saves. Skill Checks Skill checks use a roll-under mechanic:\nRoll: 1d20; if the result is equal to or lower than your relevant stat (or stat + bonus/penalty), you succeed. Apply Advantage/Disadvantage where relevant: Advantage: Roll two d20s and take the lower result (since lower is better). Disadvantage: Roll two d20s and take the higher result. Important: Non-skill rolls (attacks, saves, etc.) use a “roll-over” system (d20 + bonus vs. Target Number). Always verify which system applies before rolling.\nQuick Reference:\nSkill Check: Roll-under your stat. Advantage/Disadvantage: Lower result benefits; higher result hinders. 4. Races Each race provides:\n+1 to any stat 1 saving throw specialization Choose 1 Trait from 5 options Dwarf Save Specialization: CON\nStubborn Resilience: Soak +1 vs. physical damage. Stonecunning: Ability to sense structural weaknesses. Ale-Born Fortitude: Heal 1 HP (once per day). Iron Grip: Gain Advantage to resist disarm attempts. Cave Whisperer: Effectively detect tunnels or communicate with stone. Dragonborn Save Specialization: CHA\nBreath Weapon: Execute a 1d6 cone attack (usable once per session). Scaleblessed: Benefit from a natural AC of 13. Commanding Roar: Force enemies to test their Morale. Elemental Resistance: Gain Soak +1 vs. a chosen element. Draconic Tongue: Communicate with draconic creatures and gain cultural insights. Elf Subraces:\nDark Elf (Drow) Save Specialization: INT or CHA\nShadow Meld: Advantage on stealth checks in darkness or dim light. Night’s Edge: Bonus to illusion and mind-affecting spells (usable once per scene). Twilight Veil: Enhanced perception in low-light conditions. Umbral Insight: Detect hidden details by gaining insights from the shadows. Night Stalker: Increased speed and agility when moving through darkness. Gold Elf Save Specialization: DEX or INT\nSunlit Grace: Advantage on skill checks in bright light conditions. Radiant Memory: Once per session, recall ancient lore for a bonus on Arcane rolls. Golden Resolve: Bonus on Will saves during daylight. Dawn\u0026rsquo;s Favor: Increase initiative by +1 in outdoor, sunlit environments. Luminous Step: Temporary movement bonus in bright conditions (usable once per scene). Wood Elf Save Specialization: DEX or WIS\nForest’s Whisper: Advantage on stealth and perception checks in natural terrain. Rapid Step: Move silently and quickly through wooded areas (usable once per scene). Leafbound Reflexes: Bonus to DEX saves in forested settings. Natural Camouflage: Improved ability to hide in natural surroundings. Sylvan Empathy: Communicate with woodland creatures for situational advantages. Halfling Save Specialization: DEX\nLucky Dodge: Convert a hit into a miss (usable once per session). Quiet Step: Gain Advantage on stealth checks in natural terrain. Comfort Seeker: Meals restore +1 HP. Hearthborn Heart: Immune to magical fear effects. Quick Fixer: Instantly repair small items or disable traps. Human Save Specialization: Any\nVersatile Soul: +1 to any stat (applied again). Resilient Lineage: Advantage on 1 save per session. Adaptable Mind: Advantage on 1 Oracle roll per session. Quick Study: Learn a Tag mid-session (1/session). Skilled: Start with 1 extra Tag. Tiefling Save Specialization: CHA or INT\nHellfire Touch: Deal an extra +1 fire damage in melee combat. Eyes of the Abyss: Detect lies or magical effects (usable once per session). Shadowmeld: Gain Advantage on stealth checks in darkness. Sin Whisper: Learn an enemy’s secret desire (usable once per session). Infernal Will: When using Oracle rolls with dark forces, gain Advantage. Quick Reference: Race Benefits: +1 stat, saving throw specialization, and 1 Trait (choose from 5 options). Example: Human offers flexibility and extra tags. 5. Classes \u0026amp; Paths Each class provides:\n1 saving throw specialization. 1 Class Trait chosen from 5 options. Select the path that best matches your desired play style.\nFighter Paths Fighters excel in physical combat. Choose from the following specialized paths (listed alphabetically):\nKnight Save Specialization: STR or CON\nShield Valor: Gain +1 AC when adjacent to an ally. Chivalric Stand: Once per combat, negate an attack that would reduce you below 50% HP. Honorable Strike: Deal bonus damage against foes attacking dishonorably. Battle Focus: Gain Advantage on Strength-based attacks when standing firm. Resolute Guard: Once per day, prevent a critical hit against you or an adjacent ally. Martial Artist Save Specialization: STR or DEX\nPrecision Strike: When attacking with Advantage, add an extra damage step (according to the Step Dice system). Technical Mastery: Your focused strikes bypass part of enemy defenses, ignoring the first step of their damage reduction. Counter Expertise: Successfully parrying an attack grants an immediate counterattack with Advantage. Grapple Specialist: Efficiently clinch and restrain foes, limiting their ability to counterattack. Battle Instinct: In critical moments, gain Advantage on your next unarmed attack, reflecting heightened awareness. Monk Save Specialization: DEX or WIS\nInner Flow: Recover a small amount of MP upon a successful unarmed strike (using standard MP recovery). Inner Serenity: Restore modest HP or MP during a short rest through focused meditation. Flurry of Blows: Once per combat, unleash a rapid sequence of unarmed strikes, granting one extra attack on your turn. Spirit Shield: Generate a transient aura that absorbs part of incoming damage for a brief period. Transcendent Focus: Once per session, reroll a failed unarmed attack or skill check. Paladin Save Specialization: STR or CHA\nDivine Smite: Once per combat, add extra radiant damage (Step 3) on a successful melee hit. Aura of Faith: Grant nearby allies a bonus to saving throws (usable once per session). Sacred Protection: When an ally falls, gain temporary HP equal to your level. Holy Rally: Restore a small amount of HP to yourself or an ally after a powerful strike. Divine Judgment: Once per day, force an enemy to re-roll a failed saving throw. Ranger Save Specialization: DEX or WIS\nPrecise Shot: Gain Advantage on ranged attack rolls in natural terrain. Stealthy Pursuit: Move undetected in forests and rugged landscapes. Hunter’s Mark: Mark a foe to increase the damage dealt on subsequent attacks. Quick Reflexes: Gain a bonus to Dexterity saves when facing multiple foes. Nature’s Insight: Once per scene, use environmental factors to gain a tactical edge. Swordmaster Save Specialization: STR or DEX\nPrecision Cut: Increase your chance for critical hits on well-aimed strikes. Parry and Riposte: When you successfully parry an attack, immediately counter with a bonus attack. Flourishing Strike: Execute combo attacks that add extra damage. Blade Dance: Temporarily boost your mobility and attack speed during combat. Edge of Perfection: Once per combat, reroll a failed attack roll for a decisive strike. Magic User Paths Magic Users channel arcane energies. Choose from the following paths (listed alphabetically):\nCleric Save Specialization: WIS or CHA\nDivine Intervention: Once per session, negate an incoming attack entirely. Holy Light: Enhance the healing power of your restorative spells. Sacred Ward: Grant temporary damage resistance to yourself or an ally. Blessing of Faith: Improve saving throws for nearby allies for a brief period. Righteous Fury: Add extra radiant damage to your offensive spells. Necromancer Save Specialization: INT or CHA\nEnhanced Raise Dead: Improve your summoned undead minions’ strength or durability. Life Drain: Heal yourself in proportion to the damage inflicted by your necromantic spells. Deathly Aura: Emit a necrotic aura that deals minor damage over time to nearby enemies. Bone Barrier: Conjure a temporary shield of skeletal fragments. Soul Channel: Convert the life force of defeated foes into bonus MP. Sorcerer Save Specialization: INT, WIS, or CHA\nWild Surge: Spend an extra 1 MP to increase a spell’s damage by one Step. Elemental Affinity: Gain bonus damage when casting spells of your chosen element. Magical Flow: Reduce the MP cost for consecutive spells during combat. Chaos Bolt: Cast a variable-damage bolt with a chance for additional effects. Innate Spark: Recover a small portion of MP when your spell successfully lands. Warlock Save Specialization: INT or CHA\nPact Empowerment: Regain a small MP bonus after each successful spell cast. Eldritch Blast: Enhance your signature ranged spell with extra damage. Dark Bargain: Once per session, sacrifice a small amount of HP to amplify a spell’s effect. Cursed Invocation: Inflict a minor debuff on enemies following a successful spell attack. Pact Resilience: Gain a temporary MP shield when critically wounded. Wizard Save Specialization: INT, WIS, or CHA\nArcane Mastery: Lower the MP cost of one spell per session. Spell Recall: Once per session, recover a recently cast spell at no additional cost. Mystic Archive: Gain bonus effects when recalling arcane knowledge during combat. Ritual Casting: Cast designated spells without spending MP when time permits. Focused Study: Temporarily boost your casting stat for a particularly challenging spell. Rogue Paths Rogues specialize in stealth, subterfuge, and precision. Choose from the following paths (listed alphabetically):\nAssassin Save Specialization: DEX or CHA\nLethal Precision: Increase your critical hit chance on ambush attacks. Silent Takedown: Execute enemies quietly, minimizing detection. Poison Mastery: Apply toxins to your strikes that deal damage over time. Quick Execution: Burst forward to close gaps rapidly for a surprise strike. Death Mark: Once per combat, mark a target to increase damage dealt against it. Spy Save Specialization: DEX\nUrban Camouflage: Excel at blending into crowded urban environments. Eavesdrop: Gather crucial clues about enemy tactics through careful observation. Covert Entrance: Move undetected when infiltrating secure locations. Silent Footsteps: Reduce noise to maintain stealth in cityscapes. Shadow Intel: Acquire actionable information that provides tactical advantages. Thief Save Specialization: DEX\nAgile Fingers: Enhanced ability to pick locks and disarm traps with ease. Quick Escape: Increase movement speed for rapid retreats when in danger. Opportunist: Gain bonus damage when catching enemies off-guard. Sleight of Hand: Improve success rates for pickpocketing or subtle manipulations. Evasive Maneuver: Gain a temporary bonus to AC when making a swift escape. Quick Reference for Classes \u0026amp; Paths:\nFighter: Knight, Martial Artist, Monk, Paladin, Ranger, Swordmaster. Magic User: Cleric, Necromancer, Sorcerer, Warlock, Wizard. Rogue: Assassin, Spy, Thief. Each path provides exactly five unique traits along with a designated saving throw specialization, ensuring that your character’s abilities are both flexible and distinct.\n6. Tags \u0026amp; Traits Tags: Narrative keywords that describe your hero’s background and skills. They grant Advantage on appropriate rolls (whether using the roll-under or roll-over system). Traits: Specific bonuses or abilities from your race, class, or progression. They can affect combat, magic, or narrative events. Quick Reference:\nTags: Use for narrative flair and situational bonuses. Traits: Permanent bonuses or abilities that grow with your character. 7. Advancement \u0026amp; Leveling Level Gains 1 1 Race Trait, 1 Class Trait, 3 Tags 2 Gain 1 Trait 3 +1 to a stat 4 Gain or upgrade a Trait 5 +1 to a stat 6 Gain Trait (any source) 7 +1 to a stat 8 Gain Trait 9 +1 to a stat 10 Capstone or transformation Quick Reference:\nProgression: Incremental stat increases and periodic Trait gains. Capstone: Final transformation at Level 10. Part II: Playing the Game 8. Core Mechanics All non-skill rolls (attacks, saves, etc.) use a “roll-over” approach: roll d20 + bonus vs. a Target Number. Skill checks, however, use a “roll-under” system.\nRoll Type Description Opposed Both sides roll d20 + bonus; highest total wins (ties = Hero wins). Unopposed Roll d20 + bonus vs. TN. Difficulty TN Easy 6 Average 11 Hard 16 Legendary 20 Advantage \u0026amp; Disadvantage:\nAdvantage: Roll 2d20; for roll-over tasks, take the higher; for roll-under tasks, take the lower. Disadvantage: Roll 2d20; for roll-over tasks, take the lower; for roll-under tasks, take the higher. Quick Reference:\nRoll-Over System: d20 + bonus vs. TN. Roll-Under System: Roll below stat. Adv/Disadv: Adjust dice selection accordingly. 9. Turn Structure Start of Turn: Apply Fray and resolve ongoing effects. Actions (2): Options include moving, attacking, casting, interacting, etc. Use 1 Trait: Activate a trait if desired. Resolve Rolls: Perform all necessary dice rolls. Narrate Results: Describe the action outcomes. Enemy Turn or Oracle Twist: Advance the encounter or invoke Oracle twists. Quick Reference:\nPhases: Start → Actions → Trait → Rolls → Narration → Resolution. 10. Combat \u0026amp; Fray Dice Fray: Represents automatic damage dealt to lower-HD foes. Damage Dice: Levels 1–5: 1d6 Levels 6–10: 1d8 Overflow: Excess Fray damage moves to another enemy with equal or lower AC. Quick Reference:\nFray Damage: Automatic damage; increases with level. Overflow: Excess damage may hit additional targets. 11. Damage Scaling \u0026amp; Step Dice Step Die 1 1d4 2 1d6 3 1d8 4 1d10 5 1d12 6 1d20 7+ 1d20 + 1dX Each +1 damage bonus moves you up one Step. The “1dX” cycles back from Step 1 as needed. Quick Reference:\nStep Dice: Determines damage scale. +1 Bonus: Increments the damage step. 12. Damage Conversion Total Roll Converted Damage 0–1 0 2–5 1 6–9 2 10–14 4 15–18 5 19–22 6 +4 +1 more Quick Reference:\nConversion: Map total roll to final damage. +4 Increment: Each extra 4 points increases damage by 1. 13. Soak Formula: Soak = (AC − 10) ÷ 2, rounded down. Apply Soak after damage conversion. A natural 20 bypasses Soak. A natural 1 causes the attacker to take damage instead (no Soak applied). Quick Reference:\nSoak Calculation: (AC – 10) ÷ 2. Nat 20/1: Special rules apply. 14. Spellcasting MP = 5 + your casting stat modifier. Spell Save TN = caster’s full stat score (target’s saving throw). MP Recovery:\nAt the start of each new day (after an 8‑hour long rest), a character automatically recovers 1d4 MP. This represents the natural replenishment of magical energy through rest and focus.\nHP-to-MP Conversion:\nDuring a short rest or as a free action, you may choose to sacrifice a portion of your HP to recover additional MP. Use the conversion:\nFor every 2 HP sacrificed, you recover 1 MP. This optional sacrifice must be used judiciously during encounters when extra MP is needed, balancing the immediate cost of HP loss against the benefit of increased magical capability.\nCasting Paths:\nAsh-Binder: +1 MP, always roll 1 Risk Die. Veilwalker: 1/day ignore a failed spell. Whisperbound: +1 die, take 1 HP. Runesmith: Store 1 spell in an item (1/day). Quick Reference:\nMP \u0026amp; Save: MP = 5 + modifier, TN = casting stat. Recovery: 1d4 MP per day; convert 2 HP → 1 MP optionally. Casting Paths: Specialize for different magical styles. Spells (Ideas) This table lists 50 spells available in One Hero Engine. The Paths column indicates which archetypes or class concepts can adopt the spell (e.g., Arcane for general magic, Necromancer for dark/death magic, Veilwalker for illusions/shadow, Whisperbound for mind/forbidden lore, and a composite group for Cleric/Paladin/Monk/Ranger). MP costs, ranges, and effects are intended as guidelines and may be adjusted to fit your campaign.\nName MP Cost Range Effect Paths (Example Archetypes) Arcane Grasp 2 30 ft Telekinetically pull or push the target; target must succeed on a STR save to resist. Arcane, Ranger Arcane Lance 2 60 ft (line) Fires a line attack that deals Step 3 damage. Arcane, Paladin Arcane Recall 2 Self Recovers a just-cast spell (usable once per session). Whisperbound, Arcane Arcane Shield 1 Self Grants +1 Soak until your next turn. Arcane, Cleric, Paladin Bless 2 30 ft Bestows a +1 bonus on allied rolls for 3 rounds. Cleric, Paladin, Monk Blur 1 Self Forces attackers to roll with Disadvantage until your next turn. Veilwalker, Monk Bone Armor 1 Self Grants +1 Soak for 3 rounds. Cannot be cast if you are wearing physical armor or if another defensive (armor) spell is active. Necromancer, Paladin, Cleric Bone Golem 4 30 ft Summons a large undead ally (2 HD, deals Step 3 damage) for 1 scene. Necromancer, Cleric Bless 2 30 ft Grants Advantage on self or allies’ rolls for 3 rounds Cleric, Paladin, Monk Counterspell 2 30 ft Cancels an enemy spell (check vs. the caster’s stat). Arcane, Cleric Cloak of Silence 1 Self/Area Mutes all sound in a 10 ft radius for 1 minute. Veilwalker, Ranger Compel Truth 2 30 ft Forces target to answer truthfully (target must pass a WIS save, or the effect applies). Whisperbound, Cleric Dazzling Veil 1 30 ft cone Blinds enemies in a cone for 1 round (target must pass a WIS save). Veilwalker, Ranger Deathgate 3 60 ft Opens a portal to summon skeletal arms; restrains target (target must pass a STR save). Necromancer, Cleric Death Whispers 1 60 ft Frightens the target (target must pass a WIS save to avoid panic). Necromancer, Whisperbound Detect Magic 1 30 ft Reveals magical auras around objects and creatures. Arcane, Ranger, Cleric Divine Light 1 30 ft Deals Step 2 radiant damage and slightly heals nearby allies. Cleric, Paladin, Ranger Drain Life 2 30 ft Deals Step 2 damage and heals you for an amount proportional to the damage dealt. Necromancer, Cleric Dream Echo 2 Touch Implants a false memory; the target is confused for 1 round. Veilwalker, Whisperbound Eldritch Bolt 2 60 ft Deals Step 3 psychic damage. Whisperbound, Arcane Eye of the Void 2 Self Grants vision of invisible or magical auras for 1 minute. Whisperbound, Arcane, Ranger Forbidden Words 1 Self Enhances the next spell\u0026rsquo;s Target Number by +1, making it harder for targets to resist. Whisperbound, Cleric Ghoul Claws 2 Melee Deals Step 3 damage; target must succeed on a save or be paralyzed for 1 round. Necromancer Grave Hunger 2 30 ft Summons spectral jaws dealing Step 2 damage per round (requires concentration). Necromancer Healing Word 1 30 ft Restores 1d4 plus stat bonus HP to one ally. Cleric, Paladin Invisibility 3 Touch Grants invisibility for 1 minute, or until you attack. Arcane, Veilwalker Lightning Ray 2 60 ft Fires a ray that deals Step 3 damage and may arc to a second target. Arcane, Paladin Life Ward 2 Self Absorbs up to 1d6 damage for a short duration. Cleric, Paladin Mage Step 1 10 ft Teleports you to a visible point. Arcane, Veilwalker, Ranger Magic Missile 1 60 ft Automatically hits and deals Step 2 damage. Arcane, Paladin, Ranger Mental Probe 1 30 ft Reads surface thoughts; deeper insight requires a WIS save. Whisperbound, Arcane Mirror Image 2 Self Creates 2 illusory duplicates that can confuse attackers. Veilwalker, Arcane Mind Shatter 3 60 ft Deals Step 4 psychic damage and stuns the target on a failed save. Whisperbound, Necromancer Phantom Blade 2 Melee Deals Step 3 damage; bypasses some armor bonuses. Veilwalker, Arcane, Paladin Primal Roar 2 30 ft Forces enemies within 10 ft to make a fear check (WIS save required). Ranger, Paladin Radiant Burst 3 30 ft radius Deals Step 3 radiant damage to all enemies within the area. Cleric, Paladin, Ranger Raise Dead 2 10 ft Animates an undead minion (1 HD, 1 HP); lasts 1 scene. Necromancer, Cleric, Paladin Sacred Barrier 2 Self Grants +3 Soak for 1 minute. Cleric, Paladin Smite 2 Melee Deals extra radiant damage (Step 3) and forces a saving throw. Paladin, Cleric Soul Leech 3 30 ft Deals Step 2 damage; if target dies, you regain 1 MP. Whisperbound, Necromancer Spell Echo 3 Self Recasts your last spell at -1 MP cost (usable once per scene). Arcane, Whisperbound Spirit Sense 1 Self Detects nearby undead and lingering souls. Necromancer, Cleric Shadow Grasp 2 60 ft Deals Step 2 damage and restrains the target (target must pass a STR save). Veilwalker, Necromancer Shadowstep 1 30 ft Teleports you between shadows. Veilwalker, Arcane Thought Thief 2 30 ft Steals a spell from the target (they lose it for 1 hour; target must pass an INT save to resist). Whisperbound, Necromancer Tranquil Mind 1 Self Reduces incoming damage by 1 Step for 1 round. Monk, Ranger Umbral Chains 3 60 ft Binds up to 3 enemies; targets must pass a WIS save to escape. Veilwalker, Necromancer, Ranger Whispering Madness 2 30 ft Confuses the target for 1 round (target must pass a WIS save). Whisperbound MP Boost Ideas To add depth and strategic flexibility during casting, consider these options for \u0026ldquo;overcharging\u0026rdquo; spells:\nOvercharge for Increased Damage:\nSpend 1 extra MP on a damage spell (e.g., Magic Missile) to upgrade its damage one Step higher than normal.\nExtended Duration:\nFor buff or defensive spells (like Arcane Shield or Sacred Barrier), spending an extra MP increases the duration by one round.\nWidened Area:\nFor spells with an area effect (e.g., Radiant Burst or Nature’s Wrath), an additional MP cost may expand the area of effect or allow the spell to affect an extra target.\nChain Casting:\nSome spells (such as Spell Echo or Arcane Recall) can be boosted by extra MP to allow immediate recast or restoration of another cast spell during the same turn.\nEnhanced Save Difficulty:\nFor spells imposing conditions (like Mind Shatter or Forbidden Words), spending extra MP can force targets to suffer a harsher penalty on their saving throws.\nThese MP boost options add a layer of resource management and tactical choice, letting players decide when it is worth sacrificing extra MP for an amplified effect.\nUse this spells table and MP boosting ideas to create a rich and varied magical repertoire for your One Hero Engine games, tailoring spell choices to your character’s flavor and the challenges of your story.\n15. Mythic Spells Use once per session. Cost: 3+ MP. Always succeeds (no roll). Examples:\nChronoseal – Take 2 turns in a row. Ashgate – Open a portal. Wound the World – Corrupt a location. Quick Reference:\nMythic Spells: Rare, powerful spells used once per session. Cost \u0026amp; Effect: 3+ MP; automatic success. Part III: Storytelling Tools 16. Oracle \u0026amp; Twist Points The Oracle resolves yes/no questions and generates narrative twists.\nHow It Works:\nAsk a yes/no question. Roll 2d6: Chance Die represents hope/fortune. Risk Die represents danger/chaos. Add an extra chance or risk die as needed based on Tags or circumstances. Die Interpretation:\nDie Range Meaning 1–3 Low 4–6 High Result Table:\nOutcome Result Chance \u0026gt; Risk Yes Risk \u0026gt; Chance No Both dice 1–3 Yes/No, but… (drawback) Both dice 4–6 Yes/No, and… (extra benefit) Equal values Yes, but… + gain 1 Twist Point Twist Points:\nYou gain 1 Twist Point when dice are equal, a Trait or Spell grants it, or a major failure is narratively impactful. At 3 Twist Points, you must introduce a dramatic twist (e.g., an unexpected NPC, reality warps, or a new threat emerges). You may also spend a Twist Point before reaching 3 to add a complication, alter a scene, or foreshadow danger. Quick Reference:\nOracle: Resolves narrative questions via 2d6. Twist Points: Accumulate for dramatic changes at 3 points. 17. Legacy, Scars \u0026amp; Conditions Scars Permanent drawbacks incurred from trauma or dramatic failure.\nExamples:\nCrippled Arm: Cannot use two-handed weapons. Claustrophobic: Disadvantage in tight spaces. Broken Faith: Unable to benefit from divine powers. Legacy Permanent boons earned from acts of heroism or destiny.\nExamples:\nOracle-Touched: +1 to all Oracle rolls. Ash-Bound Soul: Gain +1 MP per session. Scar of Glory: Forces enemy Morale checks on sight. Conditions Temporary effects that impact your hero’s rolls or overall status.\nExamples:\nPoisoned: Disadvantage on CON Saves. Stunned: Lose one action. Weakened: -1 Step on damage rolls. Quick Reference:\nScars: Permanent drawbacks. Legacy: Permanent enhancements. Conditions: Temporary impairments. 18. Trait Design Guide Design Traits That Are:\nFlavorful \u0026amp; Balanced: Support Combat, Roleplay, or Hybrid play. Timed: Passive, 1/session, or Triggered. Evolvable: Adapt as the character levels. Narrative-Fitting: Reflect your hero’s background and style. Types of Trait Effects:\nBonuses to rolls, stats, or saves. Oracle manipulation. Spellcasting enhancements. Movement, reaction, or status effects. Upgrade Ideas:\nAdd rerolls or extra uses. Increase bonus dice or extra steps. Introduce situational triggers (e.g., “when wounded”). Quick Reference:\nTraits: Define unique abilities and bonuses. Upgrade: Evolve traits as you level. Design: Balance flavor with game mechanics. 19. Example Hero Turns Kael the Assassin\nStarts in stealth; uses Deathstrike on a cultist. Rolls Step 3 (1d8) → converts to 4 damage. The cultist dies; Fray damage takes out a second foe. Oracle (Risk \u0026gt; Chance) returns “No.” Guards are alerted. Mira the Paladin\nActivates Aura of Resolve and casts Warding Circle. Enemies fail their Morale checks. Oracle (Chance \u0026gt; Risk) yields “Yes.” Reinforcements arrive. Naro the Wizard\nUses Blood Price to cast a risky spell. Sacrifices 1 HP for +2 on his cast. Oracle (Equal Dice) yields “Yes, but…” and gains a Twist Point. The spell succeeds, igniting nearby vines. Quick Reference:\nExample Turns: Illustrate tactical and narrative integration. Oracle Impact: Decision-making and storyline twists in action. Part IV: Final Notes 20. Final Words The story begins with you.\nThere is no party to carry you.\nNo game master to guide you.\nNo one to save you but your own courage and choices.\nYou are not just playing a game.\nYou are writing a legend.\nYou are the last light in the dark. A whisper in the storm.\nA name they’ll remember when all others are forgotten.\nPick up your dice. Draw your weapon. Speak your vow.\n🎲 One Hero. One Story. Endless Possibilities.\nQuick Reference:\nFinal Words: Your journey is uniquely yours. Inspiration: Embrace the challenge and forge your legend. ","permalink":"https://vicknesh.info/articles/2025/04/one-hero-engine/","tags":[{"LinkTitle":"Games","RelPermalink":"/tags/games/"},{"LinkTitle":"Rpg","RelPermalink":"/tags/rpg/"},{"LinkTitle":"Solo","RelPermalink":"/tags/solo/"},{"LinkTitle":"Ohe","RelPermalink":"/tags/ohe/"}],"title":"One Hero Engine"},{"categories":[],"content":"For this game, I’ll be using the concept outlined in this post .\n🚀 The Journey Begins Aside from wargaming, RPGs have been a long-time passion of mine. It’s been quite a while since I last ran a proper campaign, and for the past few years, I’ve been drawn to the idea of solo RPGs. My first foray into that space was with Ironsworn by Shawn Tomkin—I loved its gritty tone and mechanics so much that I immediately backed Starforged on Kickstarter when it launched.\nBeing a serial system switcher, I’ve spent years hopping between RPG systems, chasing different ideas and concepts. One campaign idea that’s been rattling around in my head involves characters who were once powerful beings in the world, now stripped of their memories. The adventure? To rediscover who they were and carve out a new identity in a changed world. The concept draws loose inspiration from the power and style of shows like Blood Blockade Battlefront and Solo Leveling. In essence, I wanted to run a singular hero high powered game this time around.\nBlood Blockade Battlefront, one of the inspirations for this solo campaign 💡 Game Idea To that end I have put together a simple system for solo play. It’s based on a myriad of rules I’ve read and played over the years, combining ideas from both RPGs and wargames: streamlined mechanics, flexible character creation, and tools for emergent storytelling. One Hero Engine is a solo-focused, narrative-driven RPG built around a fast, flexible D20 resolution system. Instead of rigid skills or feats, it uses tags to define your hero’s unique traits, with progression tied to story milestones rather than XP. Combat is quick and heroic, using opposed rolls, Fray Dice for ongoing pressure, and dynamic morale checks for enemies. A lightweight oracle system drives narrative choices, while spellcasting and Mythic Spells empower dramatic, cinematic moments.\nIt’s a system built for players who want more than just numbers on a sheet, it\u0026rsquo;s for those who want to become their hero. Whether you’re forging a legacy through fire and battle or unraveling secrets in quiet ruins, the mechanics are there to support your choices and let the story unfold naturally. It’s bold, flexible, and tuned for dramatic pacing, just one hero, one story, and endless possibilities. I\u0026rsquo;m trying out this system and have put the rules up here .\n","permalink":"https://vicknesh.info/articles/2025/04/solo-hero-rpg/","tags":[{"LinkTitle":"Games","RelPermalink":"/tags/games/"},{"LinkTitle":"Rpg","RelPermalink":"/tags/rpg/"},{"LinkTitle":"Solo","RelPermalink":"/tags/solo/"},{"LinkTitle":"Ohe","RelPermalink":"/tags/ohe/"},{"LinkTitle":"Fantasy","RelPermalink":"/tags/fantasy/"}],"title":"Solo Hero RPG"},{"categories":[{"LinkTitle":"Rosd-Hope-Eternal","RelPermalink":"/categories/rosd-hope-eternal/"}],"content":"For this game, I’ll be using the concept outlined in this post .\nThe first wargame I’m trying out solo is Rangers of Shadow Deep (ROSD) by Joseph A. McCullough, the creator of Frostgrave, Stargrave, and Oathmark. I played Frostgrave 1st Edition years ago and had a great time with it. I came across ROSD back in 2018 and was immediately intrigued, but I didn’t actually pick it up until Modiphius released the deluxe edition. I finally got my hands on it, and well, it’s been sitting on my shelf ever since… until now.\nUsing the Red Cover version I got from Modiphious The first thing I did was dig out some models I’ve been wanting to use but never found a reason to. My Ranger will be represented by a Stormcast Eternal Liberator I got ages ago when Age of Sigmar first dropped. Looking at the model, I felt inspired to make some changes to the official lore and craft something that suited the kind of game I wanted to play. When building the backstory, I imagined two sides to the Rangers: a noble, public-facing front and a secretive, behind-the-scenes force, something inspired by real-world espionage agencies and elite military units.\nArt from Age of Sigmar, my chosen Ranger House Rules \u0026amp; Adjustments All my starting characters are locked in, forming a fellowship that sticks together through thick and thin. The bond they share is key to the campaign’s tone. During character creation, I can take multiple copies of a follower class, assuming I have the recruitment points for it. However, once the game begins, things change.\nIf a follower dies during a mission, that class becomes unavailable for the rest of the campaign. I can’t recruit another of that type, no matter what. I can only recruit a new follower after the mission is complete, and it must be a different class. If my Ranger falls in battle, one of the remaining followers will be promoted to Ranger for the next mission.\nHere’s an example: let’s say I start with two knights. If one dies during a scenario, I can’t replace them mid-mission. After the mission ends, I can recruit a new follower, but it can’t be a knight (except the surviving one I already had). This rule is meant to reinforce the idea of loss having weight, and each character’s survival feeling meaningful.\nThe second big change is tonal. Since I’m using a Stormcast model, I wanted to crank up the menace of the Shadow Deep. In this version of the world, the only reason the Ranger and their companions can survive is because they are extraordinary—larger-than-life heroes, powerful enough to face these horrors head-on. This justifies some flair—think flashier spell effects and a more cinematic approach to combat.\nLastly, most of my terrain and minis are sci-fi-themed. So, I decided to reimagine the world of Alledore as a futuristic sci-fi setting, scattered with remnants of lost civilizations—kind of like Numenera meets Rangers of Shadow Deep.\nNumenera is the inspiration, based on the terrains and minis I have on hand Custom Lore The Rangers of Alledore are the kingdom’s elite defenders, warriors with two distinct faces.\nThe first are the Wardens: regal, stoic champions who face threats head-on. Clad in ancient golden armor passed down through generations, their presence alone inspires hope. The armor itself is a relic of a forgotten age, and the secret to forging new sets has long been lost. Each suit is priceless, and if a Warden falls, recovering their armor becomes a top priority—even if it means mounting a dangerous recovery mission.\nThe second are the Veilwalkers: Rangers who operate in the shadows. Despite the name, there’s no dark sorcery here—just mastery in the arts of stealth, infiltration, and intelligence gathering. Their skills are vital in navigating the Shadow Deep, where brute force alone isn’t enough. Veilwalkers slip behind enemy lines, uncover threats before they strike, and bring back information that could turn the tide of war.\nTogether, the Wardens and Veilwalkers represent two halves of the same blade, one shining in the sun, the other hidden in shadow, both ready to defend the realm.\nThe character sheet for the Ranger and his companions can be found here . It’ll be updated as the campaign unfolds and their story takes shape.\n","permalink":"https://vicknesh.info/articles/2025/04/rosd-hope-eternal-start/","tags":[{"LinkTitle":"Games","RelPermalink":"/tags/games/"},{"LinkTitle":"Wargame","RelPermalink":"/tags/wargame/"},{"LinkTitle":"Solo","RelPermalink":"/tags/solo/"},{"LinkTitle":"Rosd","RelPermalink":"/tags/rosd/"},{"LinkTitle":"Fantasy","RelPermalink":"/tags/fantasy/"}],"title":"Rangers of Shadow Deep - Hope Eternal - Starting the Game"},{"categories":[],"content":"So this is my first real effort to turn my RPG and wargame sessions into something coherent, a story I can revisit later. To keep things simple and to prevent confusion, I will break each campaign session into two parts: gameplay and story. Together they give a complete record of what took place.\nEach gameplay entry links to its story counterpart so I can switch between the mechanics and the narrative whenever I need.\nGameplay This is where I log the dice rolls, character sheets, and all the other bits and bobs that make up the mechanics of the session. It helps me keep track of what actually happened. Character sheets will have their own entries and always reflect the most current version of a character in the campaign.\nGameplay Mechanics Story Once a session wraps up, I’ll write the story version, something more fun and cohesive. It’s my chance to turn the gameplay into a proper tale, complete with dialogue, extra flavor, and anything else that makes it more enjoyable to read (especially for me down the line).\nStory from Gameplay Mechanics ","permalink":"https://vicknesh.info/articles/2025/04/gaming-concept/","tags":[{"LinkTitle":"Games","RelPermalink":"/tags/games/"},{"LinkTitle":"Rpg","RelPermalink":"/tags/rpg/"},{"LinkTitle":"Wargame","RelPermalink":"/tags/wargame/"},{"LinkTitle":"Solo","RelPermalink":"/tags/solo/"},{"LinkTitle":"Fantasy","RelPermalink":"/tags/fantasy/"}],"title":"Gaming Concept"},{"categories":[],"content":"I\u0026rsquo;ve been itching to get some gaming going recently, as the last game I had was early this year, where a few of us got together to run a 40K point 2v2 One Page Rules GrimDark game.\nDue to time constraints, finding a gaming group is not practical so I\u0026rsquo;ve been leaning into solo gaming. Whilst I was primarily into solo RPGs, solo wargaming has been in my sights for a few years now. I\u0026rsquo;ve got the books but haven\u0026rsquo;t brought it to the table, until now.\nImage obtained from `vecteezy.com` ","permalink":"https://vicknesh.info/articles/2025/04/phoenix-rising/","tags":[{"LinkTitle":"General","RelPermalink":"/tags/general/"}],"title":"Phoenix Rising"},{"categories":[],"content":"🧙‍♂️ D\u0026amp;D 5E Character Sheet Basic Info Character Name:\nClass \u0026amp; Level:\nRace:\nBackground:\nPlayer Name:\nAlignment:\nExperience Points:\nAbilities Ability Score Modifier Strength Dexterity Constitution Intelligence Wisdom Charisma Proficiency \u0026amp; Saves Proficiency Bonus:\nSaving Throws:\nStrength [ ] Dexterity [ ] Constitution [ ] Intelligence [ ] Wisdom [ ] Charisma [ ] Skills:\nAcrobatics (Dex) [ ] Animal Handling (Wis) [ ] Arcana (Int) [ ] Athletics (Str) [ ] Deception (Cha) [ ] History (Int) [ ] Insight (Wis) [ ] Intimidation (Cha) [ ] Investigation (Int) [ ] Medicine (Wis) [ ] Nature (Int) [ ] Perception (Wis) [ ] Performance (Cha) [ ] Persuasion (Cha) [ ] Religion (Int) [ ] Sleight of Hand (Dex) [ ] Stealth (Dex) [ ] Survival (Wis) [ ] Combat Stats Armor Class (AC): Initiative: Speed: Hit Point Max: Current HP: Temporary HP: Hit Dice: Death Saves: ✅✅✅ ❌❌❌ Attacks \u0026amp; Spellcasting Name Attack Bonus Damage/Type Features \u0026amp; Traits Equipment Currency:\nCP: SP: EP: GP: PP: Personality Personality Traits:\nIdeals:\nBonds:\nFlaws:\nSpellcasting (if applicable) Spellcasting Class:\nSpell Save DC:\nSpell Attack Bonus:\nCantrips: Prepared Spells: Spell Slots:\nLevel 1: [ ] [ ] Level 2: [ ] [ ] Level 3: [ ] [ ] Level 4: [ ] [ ] Level 5: [ ] [ ] Notes ","permalink":"https://vicknesh.info/character/","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/manifest.json","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/search/_index.de/","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/search/_index.es/","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/search/_index.fr/","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/search/_index.hi/","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/search/_index.jp/","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/search/_index.nl/","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/search/_index.pl/","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/search/_index.ru/","tags":[],"title":""},{"categories":[],"content":"","permalink":"https://vicknesh.info/search/_index.zh-cn/","tags":[],"title":""},{"categories":[],"content":"Welcome traveller, to my little corner of cyberspace.\nI’m Vicknesh Suppramaniam, a Solution Architect based in Malaysia, and this is where I document my work, experiments, and the occasional epic dice-fueled gaming session. Whether it’s an obscure networking fix, a solo wargame campaign, or a note-to-self that somehow became a full guide, it lands here.\nIf you want to get in touch—discuss tech, tabletop, or anything in between—send a raven (or just email me) at contact@vicknesh.info.\nSummary I\u0026rsquo;m a systems and security architect with over 20 years of experience turning complex problems into working systems. I specialize in designing secure, scalable architectures and building automation into infrastructure from day one. Whether it\u0026rsquo;s interconnecting cloud-native services or hardening self-hosted stacks, I approach every challenge with a mix of precision and curiosity.\nSkills Overview System Architecture\nBuilding distributed, fault-tolerant infrastructure with multi-cloud and hybrid setups.\nSecurity Engineering\nRolling out security frameworks, TLS infrastructure, VPNs, and open-source controls using repeatable playbooks and zero-trust principles.\nIntegration \u0026amp; Interoperability\nMaking diverse systems talk—whether it’s via APIs, message queues, or custom adapters.\nAutomation \u0026amp; Scripting\nTurning bash scripts and Ansible roles into everyday problem solvers. Infrastructure as code, always.\nProblem Solving\nBreaking down complex, interdependent systems into manageable, testable chunks.\nCollaboration \u0026amp; Communication\nLeading teams with clarity, setting expectations early, and delivering working solutions on time.\nContinuous Learning\nAlways testing new ideas, tools, and protocols—even if it means breaking things (and fixing them better).\nInterests Solo RPGs \u0026amp; Tabletop Wargaming\nRolling dice, writing stories, painting miniatures, and running entire campaigns solo because why not?\nNetworking \u0026amp; Cybersecurity\nTuning WireGuard setups, building SSH CA chains, and following open standards like a religion.\n3D Printing \u0026amp; Hobby Tech\nCustom terrain, tools, and one-off parts that solve real or imagined problems.\nWork Highlights Founder, HandleTec Solutions\nHelped startups and SMEs apply automation and AI to modernize networks, protect data, and simplify compliance.\nSenior Consultant, International Telecommunication Union\nDelivered international frameworks for secure data handling and digital trust—designed for governments, built for real-world implementation.\nIPv6 Consultant, USM Nav6\nDesigned national IPv6 migration strategies and promoted secure IPv6 adoption across Malaysia’s public sector.\nSenior Developer, Infowealth Sdn. Bhd.\nEngineered digital will systems and overhauled legacy enterprise platforms for better security and scale.\nResearch Officer, USM Network Research Group\nDeveloped backend video platforms and led security audits to support national cyber defense initiatives.\n","permalink":"https://vicknesh.info/about/","tags":[],"title":"About Me"},{"categories":[],"content":" 🧍 Ranger Profile - Aeldric Stormcast Name: Aeldric Stormcast\nLevel: 1\nBackground: _____________________\nArmor Type: Magical Warden Armor, treat it as light armor\nWeapons: Hand Weapon - Hammer\n⚔️ Stats Move: 6 Fight: +3 Shoot: +1 Armour: 13 Will: +4 Health: 19 Current HP: 19 🎯 Skills [ +1 ] Acrobatics [ +2 ] Ancient Lore [ +2 ] Armory [ +0 ] Climb [ +2 ] Leadership [ +0 ] Navigation [ +2 ] Perception [ +0 ] Pick Lock [ +2 ] Read Runes [ +0 ] Stealth [ +1 ] Strength [ +2 ] Survival [ +0 ] Swim [ +2 ] Track [ +0 ] Traps Tick the box [ ] and add modifiers as needed (e.g., [+3] Acrobatics).\n🎒 Equipment FREE. Holy Icon (+1 recovery for `Heal` spell, +1 shoot for `Burning Light` spell, -1 against target of `Shield of Light` spell) 1. Hand Weapon - Hammer 2. Light Armor (+1 Armor) 3. Shield (+1 Armor) 4. Rope 5. ______________________________________ 6. ______________________________________ ✨ Spells / Abilities (if any) - Eldritch Recall - regain 1 spell this character has already cast - Powerful Blow - +3 damagemto hand-to-hand if at least 1 damage has been inflicted - _______________________________________ - _______________________________________ - _______________________________________ 💥 Heroic Abilities (if any) - Burning Light - make +3 shoot attack against all undead creatures within 8 inches and line of sight - Enchanted Steel - +1 Fight for the remainder of the scenario - Heal - regain 5 HP to any figure within 6\u0026#34; (including caster) - _______________________________________ - _______________________________________ 🧝 Companion Profile (1) - Xandros Name: Xandros\nClass / Type: Knight\nCost: 35\n⚔️ Stats Move: 5 Fight: +4 Shoot: +0 Armour: 13 Will: +2 Health: 12 Current HP: 12 🎒 Equipment 1. Hand Weapon 2. Shield 3. Heavy Armor 4. ______________________________________ 5. ______________________________________ ✨ Spells / Abilities (if any) 1. Strength +4 2. Acrobatics +3 3. ______________________________________ 4. ______________________________________ 5. ______________________________________ ☠️ Conditions \u0026amp; Progress Poisoned: ___________________________ Diseased: ___________________________ Hunger: ______ / 10 Progress Toward Death: ______ / 10 Cost (Recruitment): ______ Gold 🧝 Companion Profile (2) - Rylox Name: Rylox\nClass / Type: Knight\nCost: 35\n⚔️ Stats Move: 5 Fight: +4 Shoot: +0 Armour: 13 Will: +2 Health: 12 Current HP: 12 🎒 Equipment 1. Hand Weapon 2. Shield 3. Heavy Armor 4. ______________________________________ 5. ______________________________________ ✨ Spells / Abilities (if any) 1. Strength +4 2. Survival +3 3. ______________________________________ 4. ______________________________________ 5. ______________________________________ ☠️ Conditions \u0026amp; Progress Poisoned: ___________________________ Diseased: ___________________________ Hunger: ______ / 10 Progress Toward Death: ______ / 10 Cost (Recruitment): ______ Gold 🧝 Companion Profile (3) - Tarindor Name: Tarindor\nClass / Type: Conjurer\nCost: 30\n⚔️ Stats Move: 5 Fight: +4 Shoot: +0 Armour: 13 Will: +2 Health: 12 Current HP: 12 🎒 Equipment 1. Spells (3) - Purchased extra spell slot 2. Wizard Staff 3. Spellbook 4. ______________________________________ 5. ______________________________________ ✨ Spells / Abilities (if any) 1. Read Runes +3 2. Awareness 3. Heal 4. Strength 5. ______________________________________ ☠️ Conditions \u0026amp; Progress Poisoned: ___________________________ Diseased: ___________________________ Hunger: ______ / 10 Progress Toward Death: ______ / 10 Cost (Recruitment): ______ Gold ","permalink":"https://vicknesh.info/character/rosd-aeldric-stormcast/","tags":[],"title":"Rangers of Shadow Deep - Aeldric Stormcast"}]