# Git Basic import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; ## Installing Git Download from git-scm and Install. Install with homebrew package manager brew install git For debian based like ubuntu sudo apt install git-all For RPM based os like fedora or cent-os sudo dnf install git-all ## Create a new repository create a new folder and then ```bash git init ``` ## Clone the repository ### https method ```bash git clone [url of repo] ./ ``` ### ssh method ```bash git clone username@host:user/reponame ./ ``` ## Add & Commit ### Add sepecifc file/s to change index ```bash git add [filename] ``` ### Add all changed files to change index ```bash git add . ``` ### Commit the message for changes in files ```bash git commit -m "Commit message" ``` ## Pushing changes ### Push local head changes to remote master ```bash git push origin master ``` ### Add remote server to repo ```bash git remote add origin [repo url] ``` ## Branching ### Create new branch from local head (current state of changes) ```bash git checkout -b [new branch name] ``` ### Switch back to master or other branch ```bash git checkout master ``` ### Delete the branch with merged changes (safe delete) ```bash git branch -d [branch name] ``` the branch with unmerged changes (force delete) ```bash git branch -D [branch name] ``` ### Push changes ```bash git push origin [branch name] ``` ## Merge and update ### Update the local repo to latest commit from remote ```bash git pull ``` ### Merge other branch into current branch ```bash git merge [branch name] ``` ### Check diff between two branches ```bash git diff [source branch] [target branch] ``` ## Logs ### All log ```bash git log ``` ### Commit log by author ```bash git log --author=[username] ``` ### Log for changed files ```bash git log --name-status ``` ## Tags ### Add tag (locally) to specific commit ```bash git tag [tag name] [commmit] ``` ### Delete tag (locally) ```bash git tag --delete [tag name] ``` ### Push specific tag to remote ```bash git push origin [tag name] ``` ### Push all local tags to remote ```bash git push origin --tags ``` ### Create empty branch without history (no previous commits) ```bash git checkout --orphan [new branch name] ``` ## Reset ### Reset/Rollback to specific commit ``` git reset --hard ``` or ``` git reset --hard HEAD~n ``` replace n with last n commits ``` git push -f origin master ``` ## Tweaks ### Showing colorful output of command results (works only in local repo.) ```bash git config color.ui true ``` ### Auto setup remote when pushing to new branch ```bash git config --global --add --bool push.autoSetupRemote true ``` ### Open repository in browser #### Prerequisites Before proceeding with the Git commands and aliases in this guide, ensure you have the following installed: 1. GitHub CLI (gh): Required for some advanced features like opening repositories in the browser. To install GitHub CLI, visit the official website: [https://cli.github.com/](https://cli.github.com/) Follow the installation instructions for your operating system. After installation, authenticate with your GitHub account by running: ```bash gh auth login ``` Add a global alias to open the current repository in the browser: ```bash git config --global alias.open '!gh repo view -w' ``` Usage: ```bash git open ``` This command will open the current repository's page in your default web browser. Note that this requires the GitHub CLI (gh) to be installed and authenticated. ### .gitignore [Generate .gitignore with gitingnore.io](http://gitignore.io/) --- # Awesome Lists | List | Description | | --- | --- | | [Awesome Mac](https://github.com/jaywcjlove/awesome-mac) | Awesome list of MacOS apps and tools | | [Awesome SelfHosted](https://github.com/awesome-selfhosted/awesome-selfhosted) | Awesome list of self-hosted apps and tools | | [Awesome React](https://github.com/enaqx/awesome-react) | A collection of awesome things regarding React ecosystem | | [Awseome VSCode](https://github.com/viatsko/awesome-vscode) | 🎨 A curated list of delightful VS Code packages and resources. | | [Awseome DataScience](https://github.com/academic/awesome-datascience) | 📝 An awesome Data Science repository to learn and apply for real world problems. | | [Awesome Actions](https://github.com/sdras/awesome-actions) | A curated list of awesome actions to use on GitHub | | [Awesome Kubernetes](https://github.com/ramitsurana/awesome-kubernetes) | A curated list for awesome kubernetes sources 🚢🎉 | | [Awesome OSS Alternatives](https://github.com/RunaCapital/awesome-oss-alternatives) | Awesome list of open-source startup alternatives to well-known SaaS products 🚀 | | [Awesome Next.js](https://github.com/unicodeveloper/awesome-nextjs) | 📔 📚 A curated list of awesome resources : books, videos, articles about using Next.js (A minimalistic framework for universal server-rendered React applications) | | [Awesome ML for Cybersecurity](https://github.com/jivoi/awesome-ml-for-cybersecurity) | 🐙 Machine Learning for Cyber Security | | [Awesome Tunneling](https://github.com/anderspitman/awesome-tunneling) | List of ngrok alternatives and other ngrok-like tunneling software and services. Focus on self-hosting. | | [Awesome Uses](https://github.com/wesbos/awesome-uses) | A list of /uses pages detailing developer setups, gear, software and configs. | | [Awesome Audio Visualization](https://github.com/willianjusten/awesome-audio-visualization) | A curated list about Audio Visualization. | | [Awesome Home Assistant](https://github.com/frenck/awesome-home-assistant) | A curated list of amazingly awesome Home Assistant resources. | | [Awesome Terraform](https://github.com/shuaibiyy/awesome-terraform) | Curated list of resources on HashiCorp's Terraform | | [Awesome Bots](https://github.com/DopplerHQ/awesome-bots) | The most awesome list about bots ⭐️🤖 | | [Awesome AWS Cloud Development Kit (CDK)](https://github.com/kolomied/awesome-cdk) | A collection of awesome things related to the AWS Cloud Development Kit (CDK) | | [Awesome Baremetal](https://github.com/alexellis/awesome-baremetal) | Bare-metal is awesome. Let's share our favourite tools. | | [Awesome Minio](https://github.com/minio/awesome-minio) | A curated list of Awesome MinIO community projects. | | [Awesome GraphViz](https://github.com/CodeFreezr/awesome-graphviz) | A curated list of GraphViz related resources | | [Awesome Spark AR](https://github.com/Spark-AR-Community/awesome-spark-ar) | A curated list of awesome Spark AR resources, assets, and more. | --- # Graphics Tools ### Sketch/Diargram - ExceliDraw [🔗](https://excalidraw.com/) [🐙](https://github.com/excalidraw/excalidraw) --- # Clear WordPress Records ## Delete Media Files Data Sometime you want to delete only the database records Each file in your media library has one row in the `wp_posts` table and two rows in the `wp_postmeta` table. ```sql DELETE FROM `wp_posts` WHERE `post_type` = "attachment"; ``` ```sql DELETE FROM `wp_postmeta` WHERE `meta_key` = "_wp_attached_file"; ``` ```sql DELETE FROM `wp_postmeta` WHERE `meta_key` = "_wp_attachment_metadata"; ``` ## Delete MainWP Records ```sql DELETE FROM `wp_options` where option_name like '%mainwp_%' ``` --- # Docker Basics ### Install docker with script ```bash curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh ``` ### Manage Docker as a non-root user > The docker group grants privileges equivalent to the root user. 1. Create the docker group. ```bash sudo groupadd docker ``` 2. Add your user to the docker group. ```bash sudo usermod -aG docker $USER ``` 3. Log out and log back in so that your group membership is re-evaluated. ### Configure Docker to start on boot ```bash sudo systemctl enable docker ``` ### List all containers (only IDs) ```bash docker ps -aq ``` ### Stop all running containers ```bash docker stop $(docker ps -aq) ``` ### Remove all containers ```bash docker rm $(docker ps -aq) ``` ### Remove all images ```bash docker rmi $(docker images -q) ``` ### Checking logs of container ```bash docker logs ``` for live log pass `-f` or `--follow` ```bash docker logs -f ``` --- # Accessing Docker Engine API Using a Proxy Container # How to Set Up a Docker Proxy Using tecnativa/docker-socket-proxy ## Introduction When running Docker in production, you typically don't want to expose the Docker daemon socket to external networks. This poses a challenge for tools and apps that need access to the Docker API. One solution is to set up a proxy that controls and secures access to the Docker API. In this guide, we'll use the open source [tecnativa/docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) project to set up a proxy for the Docker socket. ## Prerequisites Before we begin, you'll need: - Docker installed and running on the host machine - Docker Compose installed This guide assumes you have a basic understanding of Docker and Docker Compose. If not quick refresh your knowledge with [docker basics](./docker-basics.mdx) ## Step 1 - Create Compose File First, we'll create a `docker-compose.yml` file to run the proxy: ```yaml version: '3.8' services: proxy: image: tecnativa/docker-socket-proxy volumes: - '/var/run/docker.sock:/var/run/docker.sock:ro' environment: - LOG_LEVEL=info # debug,info,notice,warning,err,crit,alert,emerg - CONTAINERS: 1 - SERVICES: 1 - IAMGES: 1 - INF0: 1 - NETWORKS: 1 - TASKS: 1 - NODES: 0 ``` This runs the `tecnativa/docker-socket-proxy` image and mounts the host Docker socket into the container. :::info The `environment` section specifies access controls - we've allowed access to containers, services, iamges, info, tasks and networks API endpoints. **(0 = no access, 1 = access) ** ::: See the tecnativa/docker-socket-proxy [README](https://github.com/Tecnativa/docker-socket-proxy/blob/master/README.md) for full options. ## Step 2 - Run the Proxy Run the proxy with: ```bash docker-compose up -d ``` The proxy is now running in the background, proxying requests to the Docker socket! ## Step 3 - Test the Proxy We can test it by accessing the proxy API: ```bash curl http://localhost:2375/version ``` This should return the Docker version, confirming the proxy is working correctly. ## Step 4 - Secure the Proxy For production deployments, you'll want to add authentication and SSL encryption to secure the proxy. The tecnativa/docker-socket-proxy project supports this via environment variables. See the project [README](https://github.com/Tecnativa/docker-socket-proxy/blob/master/README.md) for details on: - Basic auth ## Wrap Up That's it! With a few simple steps we have a Docker socket proxy set up to securely manage API access. The docker-socket-proxy container provides secure access to the Docker API from outside the host. This is useful for tools that need access to remotely control Docker, like CI/CD pipelines. The proxy container method is more secure than opening the port directly. Let me know in the comments if you have any other tips for accessing Docker remotely! --- # How to remove labels from Kubernetes Resource import Gist from 'react-gist'; This guide is about how to remove labels from Kubernetes Resource. In some cases, when you're rearchitecting the label naming convention in your Kubernetes, you may come up with this issue where you want to clear up the old labels in bulk, but very few docs have examples of how to do it with CLI or API. In this guide, I'm using [kubectl](../kubectl) CLI and python [Kubernetes SDK](https://kubernetes.io/docs/reference/using-api/client-libraries/) to remove labels from Kubernetes Resource, but you can choose any supported SDK or even directly use API. For example, you have deployments with the following labels: ```json { "app": "nginx", "env": "production" } ``` and you want to update all the deployments to have the following new labels: ```json { "app.yourdomain.com/name": "nginx", "app.yourdomain.com/env": "production" } ``` ## Add New Labels to Kubernetes Resource For this you can easily use the kubectl patch api add new labels to the resource ```bash kubectl patch deployment -n default -l app=nginx -p '{"metadata":{"labels":{"app.yourdomain.com/name":"nginx","app.yourdomain.com/env":"production"}}}' ``` But this only adds new labels or updates existing ones with the same key in the deployment, not removing the old ones. ## Remove Old Labels from Kubernetes Resource To remove the old labels, you can use the kubectl patch api: ```bash kubectl patch deployment -n default -l app.yourdomain.com/name=nginx -p '{"metadata":{"labels":{"app": None,"env": None}}}' ``` ## Using Python Script --- # Helm Basic Commands ## Install and Uninstall Apps Install an app: ```bash helm install [app-name] [chart] ``` Install an app in a specific namespace: ```bash helm install [app-name] [chart] --namespace [namespace] ``` Override the default values with those specified in a file of your choice: ```bash helm install [app-name] [chart] --values [yaml-file/url] ``` Run a test installation to validate and verify the chart: ```bash helm install [app-name] --dry-run --debug ``` Uninstall a release: ```bash helm uninstall [release] ``` ## App Upgrade and Rollback Upgrade an app: ```bash helm upgrade [release] [chart] ``` Rollback changes if the upgrade fails: ```bash helm upgrade [release] [chart] --atomic ``` Upgrade a release. If it does not exist on the system, install it: ```bash helm upgrade [release] [chart] --install ``` Upgrade to a specified version: ```bash helm upgrade [release] [chart] --version [version-number] ``` Rollback a release: ```bash helm rollback [release] [revision] ``` ## Download Release Information Download all the release information: ```bash helm get all [release] ``` Download all hooks: ```bash helm get hooks [release] ``` Download the manifest: ```bash helm get manifest [release] ``` Download the notes: ```bash helm get notes [release] ``` Download the values file: ```bash helm get values [release] ``` Fetch release history: ```bash helm history [release] ``` ## Add, Remove, and Update Repositories Add a repository from the internet: ```bash helm repo add [repository-name] [url] ``` Remove a repository from your system: ```bash helm repo remove [repository-name] ``` Update repositories: ```bash helm repo update ``` ### List and Search Repositories ```bash helm repo list ``` Generate an index file containing charts found in the current directory: ```bash helm repo index ``` Search charts for a keyword: ```bash helm search [keyword] ``` ```bash helm search repo [keyword] ``` Search Helm Hub: ```bash helm search hub [keyword] ``` ## Release Monitoring List all available releases in the current namespace: ```bash helm list ``` List all available releases across all namespaces: ```bash helm list --all-namespaces ``` List all releases in a specific namespace: ```bash helm list --namespace [namespace] ``` List all releases in a specific output format: ```bash helm list --output [format] ``` Apply a filter to the list of releases using regular expressions: ```bash helm list --filter '[expression]' ``` See the status of a specific release: ```bash helm status [release] ``` ### Display the release history helm history [release] See information about the Helm client environment: ```bash helm env ``` ## Plugin Management Install plugins: ```bash helm plugin install [path/url1] [path/url2] ... ``` View a list of all installed plugins: ```bash helm plugin list ``` Update plugins: ```bash helm plugin update [plugin1] [plugin2] ... ``` Uninstall a plugin: ```bash helm plugin uninstall [plugin] ``` ## Chart Management ```bash helm create [name] ``` Package a chart into a chart archive: ```bash helm package [chart-path] ``` Run tests to examine a chart and identify possible issues: ```bash helm lint [chart] ``` Inspect a chart and list its contents: ```bash helm show all [chart] ``` Display the chart’s definition: ```bash helm show chart [chart] ``` Display the chart’s values: ```bash helm show values [chart] ``` Download a chart: ```bash helm pull [chart] ``` Download a chart and extract the archive’s contents into a directory: ```bash helm pull [chart] --untar --untardir [directory] ``` Display a list of a chart’s dependencies: ```bash helm dependency list [chart] ``` Get Help and Version Information Display the general help output for Helm: ```bash helm --help ``` Show help for a particular helm command: ```bash helm [command] --help ``` See the installed version of Helm: ```bash helm version ``` --- # Helm Setup ## Installation ### Linux ```bash curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash ``` ## Troubleshooting ### --name flag not found Helm 3 uses new command syntax ` helm install [NAME] [CHART] [flags]` ```bash helm install stable/nginx-ingress --name my-nginx ``` --- # kubectl ## Installation ### Linux ```bash curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" ``` ```bash chmod +x ./kubectl && sudo mv ./kubectl /usr/local/bin/kubectl ``` ### Delete all the failed pods ```bash kubectl delete pods -A --field-selector=status.phase=Failed ``` ### Apply label to Kubernetes Resources ```bash kubectl label [resourcetype] [resourcename] -n [namespace] mylabel=myvalue mylabel2=myvalue2 ``` ### Remove label from Kubernetes Resources ```bash kubectl label [resourcetype] [resourcename] -n [namespace] mylabel- ``` --- # How to reset LXC password # How to Reset Your Proxmox LXC Container Root Password 1. Grab the container ID First you need to grab the container ID, which is the number next to the container name in the Proxmox node. For example, if the container name is “monitor”, the ID will be the number next to it. 2. Open up a shell Next, open up a shell (as root) into the container from the Proxmox host. You can do this by running the command “lxc-attach -n [container_id]”, with the appropriate container ID in place of the placeholder. For example, if the container ID is 150, the command would be: ```bash lxc-attach -n 150 ``` 3. Change your password Finally, change your password by running the command “passwd”. This will prompt you to enter a new password for your container. ```bash passwd ``` Once you’ve changed your password, you’ve successfully reset your LXC container in Proxmox. ### References - https://linuxcontainers.org/lxc/manpages/man1/lxc-attach.1.html - https://forums.engineerworkshop.com/t/forgot-your-lxc-container-password-in-proxmox-heres-how-to-reset-it/282 --- # Reset Portainer admin password import CodeBlock from '@theme/CodeBlock'; # Reset Portainer admin password If your Portainer admin forgets their password, follow these steps to reset it. There are two methods depending on your Portainer environment. ## Method 1: Resetting the admin password if Portainer runs as a container You would typically use this method if you run the Portainer Server on Docker Standalone. First, go to our reset password container helper in GitHub, then stop the Portainer container by running this command: docker stop "id-portainer-container" Next, run the helper using the following command (you'll need to mount the Portainer data volume): docker run --rm -v portainer_data:/data portainer/helper-reset-password If successful, the output should look like this: ```bash 2020/06/04 00:13:58 Password successfully updated for user: admin 2020/06/04 00:13:58 Use the following password to login: &\_4#\3^5V8vLTd)E"NWiJBs26G\*9HPl1 ``` Finally, use this command to start the Portainer container then try logging in with the new password: docker start "id-portainer-container" ## Method 2: Resetting the admin password if Portainer runs as a stack/service You would typically use this method if you run the Portainer Server on Docker Swarm. First, scale the Portainer service to zero using this command: docker service scale portainer_portainer=0 Next, run the reset password container helper using the same bind-mount/volume as the data volume: docker run --rm -v portainer_portainer_data:/data portainer/helper-reset-password If successful, the output should look like this: ```bash 2020/06/04 00:13:58 Password successfully updated for user: admin 2020/06/04 00:13:58 Use the following password to login: &\_4#\3^5V8vLTd)E"NWiJBs26G\*9HPl1 ``` Finally, start up the Portainer service scaling using this command then try logging in with the new password: docker service scale portainer_portainer=1 --- # Cleaning the Node ## My Script ```bash #!/bin/bash echo "About to destroy Rancher 2.x install" echo "5s to cancel with ^c" echo sleep 5 containers=$(docker ps -a | grep -E "rancher|k8s" | awk '{print $1}') if [ "${containers}x" != "x" ] then docker rm -f $containers else echo "No containers - ignoring docker rm" fi images=$(docker images -a | grep -E "rancher|k8s" | awk '{print $3}') if [ "${images}x" != "x" ] then docker rmi $images else echo "No images - ignoring docker rmi" fi docker volume prune cleanupdirs="/var/lib/etcd /etc/kubernetes /etc/cni /opt/cni /var/lib/cni /var/run/calico /opt/rke" for dir in $cleanupdirs; do echo "Removing $dir" rm -rf $dir done ``` ## Other https://gist.github.com/superseb/06539c6dcd377e118d72bfefdd444f81#file-extended-cleanup-rancher2-sh ```bash #!/bin/sh # Backup your data # Use at your own risk # Usage ./extended-cleanup-rancher2.sh # Include clearing all iptables: ./extended-cleanup-rancher2.sh flush docker rm -f $(docker ps -qa) docker rmi -f $(docker images -q) docker volume rm $(docker volume ls -q) for mount in $(mount | grep tmpfs | grep '/var/lib/kubelet' | awk '{ print $3 }') /var/lib/kubelet /var/lib/rancher; do umount $mount; done cleanupdirs="/etc/ceph /etc/cni /etc/kubernetes /opt/cni /opt/rke /run/secrets/kubernetes.io /run/calico /run/flannel /var/lib/calico /var/lib/etcd /var/lib/cni /var/lib/kubelet /var/lib/rancher/rke/log /var/log/containers /var/log/pods /var/run/calico" for dir in $cleanupdirs; do echo "Removing $dir" rm -rf $dir done cleanupinterfaces="flannel.1 cni0 tunl0" for interface in $cleanupinterfaces; do echo "Deleting $interface" ip link delete $interface done if [ "$1" = "flush" ]; then echo "Parameter flush found, flushing all iptables" iptables -F -t nat iptables -X -t nat iptables -F -t mangle iptables -X -t mangle iptables -F iptables -X /etc/init.d/docker restart else echo "Parameter flush not found, iptables not cleaned" ``` https://gist.github.com/superseb/06539c6dcd377e118d72bfefdd444f81#gistcomment-3341085 ```bash #!/bin/bash # Backup your data # Use at your own risk # Usage ./extended-cleanup-rancher2.sh # Include clearing all iptables: ./extended-cleanup-rancher2.sh flush containers=$(docker ps -qa) [[ ! -z "$containers" ]] && docker rm -f $containers images=$(docker images -q) [[ ! -z "$images" ]] && docker rmi -f $images volumes=$(docker volume ls -q) [[ ! -z "$volumes" ]] && docker volume rm $volumes for mount in $(mount | grep '/var/lib/kubelet' | awk '{ print $3 }') /var/lib/kubelet /var/lib/rancher; do umount $mount; done cleanupdirs="/etc/ceph /etc/cni /etc/kubernetes /opt/cni /opt/rke /run/secrets/kubernetes.io /run/calico /run/flannel /var/lib/calico /var/lib/etcd /var/lib/cni /var/lib/kubelet /var/lib/rancher/rke/log /var/log/containers /var/log/pods /var/run/calico" for dir in $cleanupdirs; do echo "Removing $dir" rm -rf $dir done cleanupinterfaces="flannel.1 cni0 tunl0" for interface in $cleanupinterfaces; do echo "Deleting $interface" ip link delete $interface done if [ "$1" = "flush" ]; then echo "Parameter flush found, flushing all iptables" iptables -F -t nat iptables -X -t nat iptables -F -t mangle iptables -X -t mangle iptables -F iptables -X service docker restart else echo "Parameter flush not found, iptables not cleaned" fi ``` Ref: - https://rancher.com/docs/rancher/v2.x/en/cluster-admin/cleaning-cluster-nodes/ - https://medium.com/@krisadas/remove-rancher-node-without-delete-vm-b7218d8ae76c --- # Rancher CLI ## Installing Rancher CLI ### Linux ```bash #!/bin/bash # Download rancher and rancher-compose command line tools wget -O rancher-cli.tar.gz $(curl -s https://api.github.com/repos/rancher/cli/releases/latest | grep browser_download_url | grep 'linux-amd64' | head -n 1 | cut -d '"' -f 4) wget -O rancher-compose.tar.gz $(curl -s https://api.github.com/repos/rancher/rancher-compose/releases/latest | grep browser_download_url | grep 'linux-amd64' | head -n 1 | cut -d '"' -f 4) # extract the binaries from the tar archive sudo tar -xzvf rancher-cli.tar.gz -C /usr/local/bin --strip-components=2 sudo tar -xzvf rancher-compose.tar.gz -C /usr/local/bin --strip-components=2 # Remove the archive rm rancher-cli.tar.gz rancher-compose.tar.gz -f ``` --- # Rancher Manager Installation ### Install Docker Rancher requires Docker to be installed on the host. You can install Docker by following the script by Rancher or by following the official Docker documentation. ```bash curl https://releases.rancher.com/install-docker/20.10.sh | sh ``` ### Rancher - Docker Installation ```bash docker run -d --restart=unless-stopped \ -p 80:80 -p 443:443 \ --privileged \ rancher/rancher:latest \ --acme-domain ``` --- # Longhorn ## Installing Longhorn Storage Engine in Rancher Official Doc: https://longhorn.io/docs/1.7.2/deploy/install/install-with-rancher/ ### Troubleshooting: #### Uninstall: https://longhorn.io/docs/1.7.2/deploy/uninstall/ #### Bug: "cannot list the content of the src directory /var/lib/rancher/longhorn/engine-binaries for the copy, will do nothing:" https://github.com/longhorn/longhorn/issues/1663 --- # References Rancher HA Selfsigned cert installation: https://gist.github.com/superseb/4ce52616d57dce8b58835d19c1a2b1b7 Rancher node cleanup: https://gist.github.com/superseb/2cf186726807a012af59a027cb41270d HAProxy: https://www.haproxy.com/documentation/hapee/latest/installation/rancher/ Rancher Cert Manager Upgrade: https://itnext.io/rancher-cert-manager-upgrade-bd15468bac9c Rancher 2 and letencrypt: https://www.2stacks.net/blog/rancher-2-and-letsencrypt/ Kubernetes With Rancher 2.x and Let’s Encrypt Free Certificates: https://medium.com/better-programming/rancher-2-x-lets-encrypt-dns-01-challenge-and-route53-c636c8966aab Let’s Encrypt and Rancher 2.0 with cert-manager: https://github.com/joaoverissimo/letsencrypt-rancher-cert-manager-config --- # Rancher Single Node Installation --- # Rancher Console - View Logs Bug # How to fix the Rancher Console View Logs Bug 1. Log in to the Rancher 2. Go to the `/v3/preferences/logs-range` 3. Send delete request to the endpoint 4. Refresh the page 5. Now you should be able to see the logs ### Reference - https://github.com/rancher/dashboard/issues/6122#issuecomment-1152394027 --- # How to Import/Export MySQL Database ## Exporting MySQL Database ```bash mysqldump -u username -p database_name > database_dump_name.sql ``` ## Importing MySQL Database ```bash mysql -u username -p database_name < database_dump_name.sql ``` --- # PostgreSQL Basic Operations ### Create a new database ```sql CREATE DATABASE ; ``` ### Rename a database ```sql ALTER DATABASE RENAME TO ; ``` ### Listing databases A single Postgres server process can manage multiple databases at the same time. You can view all of the defined databases on the server by using the `\list` meta-command or its shortcut `\l`. ```sql \l ``` ### Switch to a specific database To swtich to different database in postgresql, use the `\connect` meta-command or its shortcut `\c`. ```sql \c ``` ### Listing tables To list all tables in your current database, use the `\dt` meta-command. ```sql \dt ``` ### Listing all users Use `\du` to list all users accounts (or roles) in the connected PostgreSQL server. ```sql \du ``` To get more information in all users, use `\du+`. ```sql \du+ ``` #### Listing users using SQL Statement ```sql SELECT usename AS role_name, CASE WHEN usesuper AND usecreatedb THEN CAST('superuser, create database' AS pg_catalog.text) WHEN usesuper THEN CAST('superuser' AS pg_catalog.text) WHEN usecreatedb THEN CAST('create database' AS pg_catalog.text) ELSE CAST('' AS pg_catalog.text) END role_attributes FROM pg_catalog.pg_user ORDER BY role_name desc; ``` ### Creating user ```sql CREATE USER WITH ENCRYPTED PASSWORD ; ``` ### Giving all permission to a user on a specific database ```sql GRANT ALL PRIVILEGES ON DATABASE TO ; ``` ### Changing the owner of the PostgreSQL Database ```sql ALTER DATABASE OWNER TO ; ``` ### Checking active connections to postgresql server ```sql select pid as process_id, usename as username, datname as database_name, client_addr as client_address, application_name, backend_start, state, state_change from pg_stat_activity; ``` --- # Invalid resource manager ID in primary checkpoint record error :::warning Be aware there may be data loss if you follow the steps below and your system is heavily corrupted. Please make sure you have a backup of your data before proceeding. ::: 1. Get access to Container shell using following command: ```bash kubectl exec -it -n -- /bin/sh ``` In docker container, you can use following command: ```bash docker exec -it /bin/sh ``` If you cannot get access to container shell, because of the crashloop, make following changes in the deployment manifest and apply it again. ```yaml spec: containers: - name: postgres image: postgres:13.2 imagePullPolicy: IfNotPresent command: ["/bin/sh"] args: ["-c", "while true; do sleep 30; done;"] ``` 2. Run following command to reset WAL log files: You will need be run following commands as postgres user. ```bash su - postgres ``` ```bash # dry run pg_resetwal --dry-run /var/lib/postgresql/data ``` ```bash pg_resetwal -f /var/lib/postgresql/data ``` 3. Restart the PostgreSQL container and remove the command and args from the deployment manifest if you have made any changes in the previous step. ## Reference - https://stackoverflow.com/questions/71258094/invalid-resource-manager-id-in-primary-checkpoint-record --- # How to migrate from MySQL Database to PostgreSQL Database ## Using pgloader ```bash pgloader mysql://user:password@mysql:3306/database postgresql://postgres:root@postgres:5432/postgres ``` ### with docker-compose ```yaml version: '3.6' services: postgres: image: postgres:9.6 container_name: postgres.db ports: - '5432:5432' restart: always volumes: - 'postgres_db_data:/var/lib/postgresql/data' environment: POSTGRES_PASSWORD: postgres mysql: image: mysql container_name: mysql.db ports: - '3306:3306' volumes: - /var/lib/mysql - './your-db-sql-folder-or-file.sql:/docker-entrypoint-initdb.d' environment: MYSQL_DATABASE: database MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: secretpassword pgloader: image: dimitri/pgloader container_name: pgloader depends_on: ['postgres', 'mysql'] command: > pgloader mysql://user:password@mysql:3306/database postgresql://postgres:root@postgres:5432/postgres volumes: postgres_db_data: ``` --- # PostgreSQL Setup ## Installing the PostgreSQL To install PostgreSQL using homebrew, run the following command: :::info Make sure you have homebrew installed and updated. if not run the following command to update: ```bash brew update ``` ::: ```bash brew install postgresql ``` ### Installing the libpq client library [1](#references) :::caution You do not need to install `libpq` if you already have PostgreSQL installed using above command. Ony install libpq if you do not have postgresql installed and want to use psql and pg_dump clients. ::: To install **libpq** using homebrew, use the following command: ```bash brew install libpq ``` This will give you access to utilities such as **psql** and **pg_dump** without having to install the full Postgres package. However, since homebrew provides some of the same utilities as Postgres, it is installed as `"keg-only"` by default. This means that it is not in the `PATH` by default. Homebrew will provide instructions on how to add it to the PATH after installation. In my case, it was this: ```bash echo 'export PATH="/usr/local/opt/libpq/bin:$PATH"' >> ~/.zshrc ``` Alternatively, you can create symlinks for the utilities you need, for example: ```bash ln -s /usr/local/Cellar/libpq/14.3/bin/psql /usr/local/bin/psql ``` :::note replace 14.3 with the version of libpq that is installed. ::: Alternatively, you could instruct homebrew to "link all of its binaries to the PATH anyway" ```bash brew link --force libpq ``` but then **you would not be able to install the Postgres package later**. ## Managing the PostgreSQL As we have installed postgresql with homebrew, we will use homebrew to start and stop the service. ### Start the postgres service ```bash brew services start postgresql ``` ### Stop the postgres service ```bash brew services stop postgresql ``` Once it is up and running, you can create a new user to log in and interact with the database. ```bash psql postgres ``` After you have logged in, you can create a new user and database: ```sql CREATE USER WITH PASSWORD ''; ``` Add `CREATE DATABASE` permission to the user ```sql ALTER ROLE WITH CREATEDB; ``` #### References: 1. [Stackoverflow](https://stackoverflow.com/questions/44654216/correct-way-to-install-psql-without-full-postgres-on-macos) 2. [Homebrew - PostgreSQL wiki](https://wiki.postgresql.org/wiki/Homebrew) 3. [Homebrew Formulae](https://formulae.brew.sh/formula/postgresql@15) --- # BC Tax Info ## Calculation of British Columbia Tax The following explanation simplifies the calculation of the tax by displaying only the final result of the Net Income. ### For an employee `Net Income = Taxable Income - Federal Tax - British Columbia Tax - CPP - EI` ### For self-employed workers The same calculation must be made for the self-employed worker. Individuals are resident in the CPP. The self-employed must pay more than an employee. ## Formula for Calculating Net Salary In BC The annual net income is calculated by subtracting the amounts related to the tax (Canada Tax and British Columbia Tax), the Canadian Pension Plan, the Employment Insurance. `Gross annual income - Taxes - CPP - EI = Net annual salary` `Net annual salary / Weeks of work per year = Net weekly income` `Net weekly income / Hours of work per week = Net hourly wage` ### CPP calculation For and employee or employer `CPP contribution = (The smallest number between: Gross revenue and: Year's maximum pensionable earnings YMPE in 2021 - Basic exemption) x (Employee or Employer rate / 100)` ## Frequency Or Periods Of Payment In British Columbia, the frequency or pay cycle is usually every 2 weeks. However, it is quite possible that you need to know the other pay periods that may be following them (based on an entire year of 52 weeks): Annual (year-round, only once a year) Monthly (a month, 12 periods per year) Semimonthly (2 x per month, 24 periods per year) Biweekly (every 2 weeks, 26 periods a year) weekly (once per week, 52 periods a year) Schedule (per hour, 52 weeks x number of hours per week) --- # Building Cloudflared agent from source on mips64 architecture Are you trying to set up Cloudflared on your mips64 OS router, such as the UniFi Edge Router? Unfortunately, Currently Cloudflare does not provide a binary for mips64 architecture. However, you can still build and install the Cloudflared agent from source. This guide will walk you through the steps to build and install Cloudflared on your mips64 router. Let's get started! ## Prerequisites - [Go](https://go.dev/doc/install) 1.20 or later - [Git](../version-control/git/basic.mdx) (optional, if you want to clone the repository) - SSH access to your router - Cloudflare account with a zone configured - Token from [Cloudflare Tunnel page](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/install-and-setup/tunnel-guide/remote/#1-create-a-tunnel) ## Steps :::info Replace `[router_username]`, `[router_ip]`, and `[token-from-cloudflare]` with your actual values. ::: 1. Clone the Cloudflared repository: ```bash git clone https://github.com/cloudflare/cloudflared.git ``` 2. Change to the cloned directory: ```bash cd cloudflared ``` 3. Build the binary for mips64 architecture: ```bash GOOS=linux GOARCH=mips64 go build github.com/cloudflare/cloudflared/cmd/cloudflared ``` This will create a binary named `cloudflared` in the current directory. 4. Copy the binary to your router: ```bash scp cloudflared [router_username]@[router_ip]:/tmp/ ``` 5. SSH into your router: ```bash ssh [router_username]@[router_ip] ``` 6. Change to the `/tmp` directory: ```bash cd /tmp ``` 7. Change the owner of the binary to root: ```bash sudo chown root:root cloudflared ``` 8. Make the binary executable: ```bash sudo chmod +x cloudflared ``` 9. Move the binary to a directory in your PATH: ```bash sudo mv cloudflared /usr/bin/ ``` 10. Create the cloudflared config directory: ```bash sudo mkdir /etc/cloudflared ``` 11. Create the cloudflared config file: ```bash sudo vi /etc/cloudflared/config.yml ``` 12. Add the following content to `config.yml` file: ```yaml title="config.yml" proxy-dns: true proxy-dns-upstream: - https://1.1.1.1/dns-query - https://1.0.0.1/dns-query proxy-dns-port: 8853 ``` 13. Start the cloudflared service: ```bash sudo /usr/bin/cloudflared service install [token-from-cloudflare] ``` That's it! You have successfully installed Cloudflared on your mips64 router. You can now configure your router to use Cloudflare DNS. :::info Please note that after every firmware upgrade on your router, you will need to re-install Cloudflared on your router as the firmware upgrade will remove the binary from your router. ::: --- # How to Generate a CSR (Certificate Signing Request) import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; ## Prerequisites Before you begin, make sure you have OpenSSL installed on your system. You can check if OpenSSL is installed by running the following command: ```bash openssl version ``` If OpenSSL is not installed, you can install it using your system's package manager.
  1. Download the OpenSSL installer from the{' '} OpenSSL website .
  2. Run the installer and follow the prompts to install OpenSSL on your system. You can choose the default options, or customize the installation as needed.
  3. Once the installation is complete, you can use the OpenSSL command-line tools in the "bin" directory of the installation directory.
  1. Open a terminal window.
  2. Install Homebrew package manager by running the following command: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  3. Once Homebrew is installed, run the following command to install OpenSSL: brew install openssl
  4. After installation, you can access OpenSSL command-line tools by running the following command: openssl or /usr/local/opt/openssl/bin/openssl

Ubuntu or Debian

  1. Open a terminal window.
  2. Run the following command to install OpenSSL: sudo apt-get install openssl

CentOS or Fedora

  1. Open a terminal window.
  2. Run the following command to install OpenSSL: sudo yum install openssl

Arch Linux

  1. Open a terminal window.
  2. Run the following command to install OpenSSL: sudo pacman -S openssl
  3. After installation, you can access OpenSSL command-line tools by running the following command: openssl
That's it! You should now have OpenSSL installed on your system. ## Method 1: Using a configuration file Create a configuration file with the SANs you want to include in the CSR. For example, let's create a file called san.cnf with the following contents: ```bash [req] req_extensions = v3_req [v3_req] subjectAltName = DNS:example.com, DNS:*.example.com ``` This configuration file specifies that the CSR should include the SANs `example.com` and `*.example.com`. Generate the CSR using the openssl req command, specifying the configuration file with the `-config `option. For example: ```bash openssl req -new -newkey rsa:2048 -nodes -out example.csr -keyout example.key -subj "/C=US/ST=California/L=San Francisco/O=Example Inc./CN=example.com" -config san.cnf ``` This command generates a CSR for example.com with the SANs example.com and \*.example.com. ## Method 2: Using command-line options Generate the CSR using the openssl req command, specifying the SANs using the -addext option. For example: ```bash openssl req -new -newkey rsa:2048 -nodes -out example.csr -keyout example.key -subj "/C=US/ST=California/L=San Francisco/O=Example Inc./CN=example.com" -addext "subjectAltName = DNS:example.com, DNS:*.example.com" ``` This command generates a CSR for example.com with the SANs `example.com` and `*.example.com`. :::info Note that the `-addext` option was added in OpenSSL version 1.1.1. If you're using an older version of OpenSSL, you may need to use a different option such as `-config` to specify the SANs. ::: ## Method 3: Using a combination of configuration file and command-line options Create a configuration file with the SANs you want to include in the CSR. For example, let's create a file called san.cnf with the following contents: ```bash [req] req_extensions = v3_req [v3_req] subjectAltName = DNS:example.com, DNS:*.example.com ``` This configuration file specifies that the CSR should include the SANs `example.com` and `*.example.com`. Generate the CSR using the openssl req command, specifying the configuration file with the `-config` option and adding additional SANs using the `-addext` option. For example: ```bash openssl req -new -newkey rsa:2048 -nodes -out example.csr -keyout example.key -subj "/C=US/ST=California/L=San Francisco/O=Example Inc./CN=example.com" -config san.cnf -addext "subjectAltName = DNS:foo.example.com, IP:192.0.2.1" ``` This command generates a CSR for example.com with the SANs example.com, `*.example.com`, `foo.example.com`, and `192.0.2.1`. The first two SANs are specified in the `san.cnf` file, and the last two are added using the `-addext` option. ## Method 4: Using OpenSSL configuration file Edit OpenSSL configuration file `/etc/pki/tls/openssl.cnf` on your server. Under the `[v3_ca]` section, add the following line: ```bash subjectAltName = DNS:example.com, DNS:*.example.com ``` This configuration specifies that the certificate should include the SANs `example.com` and `*.example.com`. Generate the CSR using the `openssl req` command, specifying the `-config` option and `-new` option, like below: ```bash openssl req -new -newkey rsa:2048 -nodes -out example.csr -keyout example.key -subj "/C=US/ST=California/L=San Francisco/O=Example Inc./CN=example.com" -config /etc/pki/tls/openssl.cnf ``` This command generates a CSR for `example.com` with the SANs example.com and `*.example.com`. In this guide, I have covered four different methods to generate a CSR with SANs using OpenSSL. Choose the method that works best for your use case, and ensure that you test your configuration before deploying it in a production environment. --- # Setting Up an Access List on a Cisco - FS Switch # Setting Up an Access List on a Cisco/FS Switch Access lists are a way to control network traffic on a Cisco device, and can be used to specify which IP addresses are allowed to access the switch. In this article, I'll show you how to set up an access list on a Cisco/FS switch. ## Prerequisites Before you begin, you'll need the following: - A terminal emulator program, such as PuTTY - The IP address and login credentials for your Cisco/FS switch - The name of the interface that connects the switch to the internet ## Step 1: Log in to the switch To log in to the switch, follow these steps: 1. Open your **terminal emulator** program. 2. Enter the IP address of the switch in the **"Host Name"** field. 3. Select the **"SSH"** protocol. 4. Click **"Open"** to connect to the switch. 5. When prompted, enter the username and password for the switch. ## Step 2: Enter privileged mode To enter privileged mode, follow these steps: 1. At the command prompt, type `enable` and press Enter. 2. You may be prompted for a password. If so, enter the password and press Enter. ## Step 3: Enter global configuration mode To enter global configuration mode, follow these steps: 1. At the command prompt, type `configure` or `configure terminal` and press Enter. ```bash configure ``` 2. You will now be in global configuration mode, and the command prompt will change to reflect this. ## Step 4: Create an access list To create an access list, follow these steps: 1. At the command prompt, type `ip access-list [type] [name]` and press Enter. Replace **[name]** with a name for your access list. ```bash ip access-list standard my-access-list ``` this will create a standard access list. If you want to create an extended access list, type `ip access-list extended [name]` instead. 2. To add an entry to the access list, type `permit` or `deny` and press Enter. Replace **[permit/deny]** with either `permit` or `deny` depending on whether you want to allow or block the specified IP address. ```bash permit host [ip address] ``` ```bash deny host [ip address] ``` Allow/Block IP range by typing `permit` or `deny` and press Enter. ```bash permit [ip address] [wildcard mask] ``` **Example**: to deny `10.10.10.1/29` IP range - [Wildcard Mask List](https://en.wikipedia.org/wiki/Wildcard_mask) ```bash deny 10.10.10.1 0.0.0.7 ``` **Quick shortcut:** Type `ip access-list [type] [name] [permit/deny] [IP address]` and press Enter. Replace **[name]** with a name for your access list, **[permit/deny]** with either `permit` or `deny` depending on whether you want to allow or block the specified IP address, and **[IP address]** with the IP address you want to allow or block. For example, to create an access list named **"my-access-list"** that blocks the IP address 10.0.0.1, you would type `ip access-list standard my-access-list deny 10.0.0.1` and press Enter. ```bash ip access-list standard my-access-list deny 10.0.0.1 ``` ## Step 5: Apply the access list to the internet interface To apply the access list to the interface that connects the switch to the internet, follow these steps: 1. At the command prompt, type `interface [interface type] [interface name]` and press Enter. Replace [interface name] with the name of the interface you want to apply the access list to. For example, if the name of the interface that connects the switch to the internet is **"GigabitEthernet 0/1"**, you would type **"interface GigabitEthernet 0/1"** and press Enter. ```bash interface GigabitEthernet 0/1 ``` 3. Create an access group by typing `ip access-group [name] [in/out]` and pressing Enter. Replace **[name]** with the name of the access list you created in **step 4**, and **[in/out]** with either **"in"** or **"out"** depending on whether you want to apply the access list to incoming or outgoing traffic on the interface. For example, if the name of the access list you created in **step 4** is **"my-access-list"** and you want to apply it to incoming traffic on the interface, you would type `ip access-group my-access-list in` and press Enter. ```bash ip access-group my-access-list in ``` ## Step 6: Save your changes To save your changes so that the access list remains in place even if the switch is restarted, follow these steps: 1. Exit global configuration mode by typing `exit` and pressing Enter. 2. At the command prompt, type `write memory` or `copy running-config startup-config` and press Enter. 3. This will save your changes to the startup configuration of the switch. ## Step 7: Verify that the access list is working To verify that the access list is working, follow these steps: 1. At the command prompt, type `show access-lists` and press Enter. ```bash show access-lists ``` if set using group then type `show access-group` and press Enter. ```bash show access-group ``` 2. This will display a list of all access lists on the switch, including the one you created in step 4. --- # Allowing OPNsense Updates Through an Upstream DNS Filter # Allowing OPNsense Updates Through an Upstream DNS Filter If OPNsense sits behind an upstream router, ISP gateway, or corporate DNS filtering appliance, that upstream device is what must be configured to allow OPNsense update traffic - not OPNsense itself. This applies to any setup where OPNsense is not the edge device: for example, OPNsense running behind a carrier-grade NAT router, a corporate perimeter firewall, or a blocking gateway such as Pi-hole, AdGuard Home, or a managed DNS provider with domain filtering. ## Domains to Allow on the Upstream Device OPNsense contacts three domains to fetch firmware and package updates. Add all three to the allowlist on your **upstream router or DNS filter**: | Domain | Purpose | |---|---| | `pkg.opnsense.org` | Primary repository for software packages and plugins | | `firmware.opnsense.org` | Core base system and kernel updates | | `mirror.opnsense.org` | Geo-aware redirector that routes to the fastest available mirror | If you selected a specific regional mirror under **System > Firmware > Settings**, also add that mirror's domain - the generic `mirror.opnsense.org` redirector will not cover it. ## Why IP Allowlisting Will Not Work OPNsense uses CDNs and a global network of community mirrors. The IP addresses behind these domains change constantly based on geography and server availability. Hardcoded IP rules on your upstream device will break over time. Always allowlist by domain name (FQDN), not by IP address. ## Where to Make the Change The exact steps depend on what sits upstream of OPNsense: | Upstream device | Where to add the allowlist | |---|---| | Home/ISP router with DNS filtering | DNS allowlist or parental controls section | | Pi-hole | **Whitelist** under **Domains** | | AdGuard Home | **Filters > Custom filtering rules** - add `@@||pkg.opnsense.org^` etc. | | Corporate DNS / Umbrella / Zscaler | Domain bypass or exception list in the admin console | ## Local Caching Mirror (Proxy Environments) If your network uses an internal caching mirror or HTTP proxy for software downloads, configure the upstream DNS to resolve the OPNsense update domains to your proxy's internal IP instead of the public internet. This is a Host Override at the DNS layer - not a firewall rule - and should be applied on whichever DNS server OPNsense queries for resolution. ## References - [OPNsense Firmware Updates - official docs](https://docs.opnsense.org/manual/updates.html) --- # Reset pfsense admin password # Forgotten Password with a Locked Console If the console is password protected, all is not lost. It takes two reboots to accomplish, but the password can be reset with physical access to the console: 1. Connect to the console 2. Reboot the firewall 3. Choose the Boot Single User option `(2)` from the loader menu with the ASCII logo 4. Press Enter when prompted to start `/bin/sh` 5. Remount all partitions as rewritable: - The specific commands vary based on the filesystem. - For devices installed using UFS, see [Re-mount UFS Volumes as Read/Write][pfsense-docs-single-user-mode-ufs]. - For devices installed using ZFS, see [Re-mount ZFS Volumes as Read/Write][pfsense-docs-single-user-mode-zfs]. 6. Run the built-in password reset command: ```sh /etc/rc.initial.password ``` 7. Follow the prompts to reset the password 8. Run `/sbin/reboot` to reboot. When the firewall reboots, login with the [Default Username and Password][pfsense-docs-default-creds]. Ref: [pfsense docs][pfsense-docs-forgotten-password] [pfsense-docs-forgotten-password]: https://docs.netgate.com/pfsense/en/latest/troubleshooting/locked-out.html?highlight=locked#forgotten-password-with-a-locked-console 'Pfsense Docs: Troubleshooting Access when Locked Out of the Firewall' [pfsense-docs-default-creds]: https://docs.netgate.com/pfsense/en/latest/usermanager/defaults.html 'Default Username and Password' [pfsense-docs-single-user-mode-ufs]: https://docs.netgate.com/pfsense/en/latest/troubleshooting/single-user-mode.html#single-user-mode-ufs 'Troubleshooting in Single User Mode - UFS' [pfsense-docs-single-user-mode-zfs]: https://docs.netgate.com/pfsense/en/latest/troubleshooting/single-user-mode.html#single-user-mode-zfs 'Troubleshooting in Single User Mode - ZFS' --- # How to flush DNS cache import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; ## Clear System DNS cache
  1. Click Start.
  2. Type cmd in the search field.
  3. Right-click Command Prompt and select Run as Administrator.
  4. Type the following command: ipconfig /flushdns 
  5. Press Enter.

If the command succeeds, the system returns the following message: 'Windows IP configuration successfully flushed the DNS Resolver Cache.

  1. Launch the Terminal App
    1. Press cmd + Space on your keyboard.
    2. Type Terminal and press Return.
  2. Type the following into the terminal: sudo killall -HUP mDNSResponder
  3. Press Return.
  4. Type your administrator password and press Return.
  5. Quit Terminal by pressing cmd + Q on your keyboard.
To find out whether the service is running use the following command: sudo systemctl is-active systemd-resolved.service
## Clear Browser DNS Cache Most modern Web browsers have a built-in DNS client to prevent repetitive queries each time the website is visited. But sometime this cached results can be issue when you have recently updated the dns as it still serves from the dns cache untill expiry as per ttl. To clear Google Chrome’s DNS cache, perform the following steps:
  1. Open a new tab and type chrome://net-internals/#dns in Chrome’s address bar.
  2. Click the “Clear host cache” button.
If that doesn’t work for you, try to clear the cache and cookies.
  1. Open the “Clear browsing data” dialog window with CTRL+ Shift+Del in windows or cmd+Shift+ Del in mac.
  2. Choose a time range
  3. Select “All time” to delete everything.
  4. Check the “Cookies and other site data” and “Cached images and files” boxes.
  5. Click the “Clear data” button.
To clear Microsoft Edge’s DNS cache, perform the following steps:
  1. Open a new tab and type edge://net-internals/#dns in Edge’s address bar.
  2. Click the “Clear host cache” button.
If that doesn’t work for you, try to clear the cache and cookies.
  1. Open the “Clear browsing data” dialog window with CTRL+ Shift+Del in windows or cmd+ Shift+Del in mac.
  2. Choose a time range. Select “All time” to delete everything.
  3. Check the “Cookies and other site data” and “ Cached images and files” boxes.
  4. Click the “Clear data” button.
To clear Firefox’s DNS cache, perform the following steps:
  1. In the upper right-hand corner, click on the hamburger icon ☰ to open Firefox’s menu:
  2. Click on the ⚙ Options (Preferences) link.
  3. Click the Privacy & Security or Privacy tab on the left.
  4. Scroll down to the History section and click on the Clear History  button.
  5. Choose a time range to clear. Select “Everything” to delete everything.
  6. Select all boxes and click “Clear Now”.
If that doesn’t work for you, try the following method and temporally disabled the DNS cache.
  1. Open a new tab and type about:config in Firefox’s address bar.
  2. Search for network.dnsCacheExpiration, temporally set the value to 0 and click OK. Afterward, change back the default value and click OK.
  3. Search for network.dnsCacheEntries, temporally set the value to 0 and click OK. Afterward, change back the default value and click OK.
--- # Telus NAH Bypass Exploration (Part 1) :::warning ⚠️ **Disclaimer:** This documentation is for educational purposes/last resort only. Bypassing ISP-provided hardware may violate your service agreement and could lead to service termination. Proceed at your own risk. As a author i'm not responsible for any consequences resulting from attempting the procedures outlined herein. ::: ## 🤷 Problem Statement: Frustration Driving the Project This guide chronicles my personal technical journey and exploration into bypassing the **Telus Network Access Hub (NAH)**. This project is fueled by the frustration of persistent network instability, high latency, and intermittent **packet loss** that Telus technicians were consistently unable to diagnose or resolve, repeatedly stating, "everything is good on our end." My initial residential 1 Gbps plan experienced these issues, which worsened after upgrading to a **Business 1.5 Gbps PureFibre** plan in hopes of better service and support. The core hypothesis is that the root cause of the packet loss and instability lies within the **Telus-provided hardware** (the NAH/NH120/NH20A) and its restricted, proprietary configuration. The ultimate solution is to fully offload all network processing and routing to a dedicated, high-performance solution like the **Ubiquiti Dream Machine Pro (UDM Pro)**. ## 🛠️ Phase 1: Direct SFP Access and Configuration Retrieval The first major hurdle was to prove that the **ONT (Optical Network Terminal)** functionality, which terminates the fibre signal, could be divorced from the NAH. This was achieved by directly accessing the **Alcatel-Lucent 3FE48541AAFA GPON SFP module** and extracting its identity. ### 1.1 Network Topology: Before and After Bypass Attempt The fundamental change is moving the point of failure from the Telus NAH to the UDM Pro. #### Current Topology (NAH Required for Static IP) ```mermaid graph TD A[Telus OLT/Core] -->|Fibre| B(Telus NAH - NH120/NH20A); B -->|Proprietary Routing| C(NAH Router/NAT Function); C -->|Ethernet| D(UDM Pro WAN Port 9); D --> E(UDM Pro LAN/Internal Network); style B fill:#f9f,stroke:#333 style C fill:#9f9,stroke:#333 ```` #### Bypass Topology (Targeted Goal) ```mermaid graph TD A[Telus OLT/Core] -->|Fibre| B(Alcatel-Lucent SFP - UDM Pro Port 10); B -->|Ethernet| D(UDM Pro WAN Port 10); D --> E(UDM Pro LAN/Internal Network); style D fill:#9f9,stroke:#333 ``` ### 1.2 Physical Connection and Interface Activation The Telus-supplied SFP module was inserted into the **UDM Pro SFP+ WAN Port (Port 10)**. **Key Technical Detail:** Since the SFP is a 1 Gbps GPON device and the UDM Pro port is 10 Gbps SFP+, the link speed **must be forced** to ensure a stable connection. **UDM Pro CLI Command (`eth10` confirmed for Port 10/11 depending on firmware):** ```bash # SFP link check confirmed the link state: root@UDM-Pro:~# ethtool eth10 ... Speed: 1000Mb/s Duplex: Full Link detected: yes ``` ### 1.3 Gaining SSH Access to the SFP Management OS The SFP module runs its own embedded operating system (based on OpenWRT/Lantiq) accessible via SSH on a private management IP of **`192.168.1.10`**. To reach this hidden IP from the UDM Pro's standard LAN, temporary routing rules were required. **UDM Pro CLI Commands for Routing Injection:** 1. **Assign Temporary IP to SFP Interface:** This places the UDM Pro on the SFP's management subnet. ```bash ip addr add dev eth10 192.168.1.2/24 ``` 2. **Add NAT Rule for Traffic:** Ensures traffic from the UDM Pro's internal network is correctly source-NAT'd when directed to the SFP. ```bash iptables -t nat -A POSTROUTING -o eth10 -d 192.168.1.10 -j MASQUERADE ``` **SFP SSH Connection (Client Mac/Terminal):** Modern SSH clients refuse connections due to the SFP's reliance on outdated security algorithms. This was bypassed by explicitly allowing the legacy methods: ```bash # Force legacy key exchange and host key algorithms ssh -o KexAlgorithms=+diffie-hellman-group1-sha1 -o HostKeyAlgorithms=+ssh-rsa ONTUSER@192.168.1.10 ``` * **Credentials:** `ONTUSER` / `SUGAR2A041` * **Result:** **Success.** Full command-line access was achieved. ### 1.4 Configuration Dump and Credential Extraction Once logged in, the `ritool dump` command provided a definitive dump of the device's GPON configuration, officially confirming the authentication parameters. **Command Output Analysis (`ritool dump`):** ```bash ONTUSER@SFP:~# ritool dump ... the G984Serial:fd043625 the SLID:30303030303030303030303030303030 ... ``` | Parameter | Raw Hex Value | Decoded Value | Significance | | :--- | :--- | :--- | :--- | | **GPON S/N** | `ALCL` + `fd043625` | `ALCLfd043625` | The unique ID of the device registered with the OLT. | | **SLID (PLOAM PWD)** | `30...30` (16x) | `0000000000000000` (16x Zeroes) | The password used for service authentication. | ## 🛑 Phase 2: The Static IP Roadblock—Identifying the Proprietary Handshake With the SFP successfully authenticated, the UDM Pro was tested for full bypass capabilities. The results highlighted the core issue: | Connection Type | Authentication/Configuration | Bypass Status | Conclusion | | :--- | :--- | :--- | :--- | | **Dynamic IP** | DHCP | **SUCCESS** | SFP's inherent authorization is sufficient for basic service. | | **Static IP Subnet** | Static IP Configuration | **FAILURE** | **Proprietary routing protocol is missing.** | ### 2.1 The Technical Limitation The failure of the Static IP Subnet configuration points to a crucial gap in the bypass: * **SFP's Role:** The SFP handles **L1/L2 (Physical and Data Link)** authentication (using the S/N and SLID). * **NAH's Role:** The Telus NAH handles the **L3 (Network)** routing authorization required for the static IP block. This involves a custom, unpublished routing handshake (likely a form of dynamic routing or OMCI command sequence) that tells the Telus core network: "This static subnet is now reachable at this specific physical location." * **The Roadblock:** The UDM Pro cannot replicate this proprietary protocol. Therefore, Telus's backbone routers never correctly update their routing tables to send the static subnet traffic to your fibre line, resulting in a silent failure. ### 2.2 The Challenge Ahead The only way to achieve a complete, *unrestricted* bypass is to understand and replicate this proprietary protocol. ## 🔜 Future Exploration: Figuring out the Protocol (Part 2) **The core goal of the subsequent documentation will be to solve the Static IP Subnet routing failure.** **Part 2 of this guide will document the experimental steps to:** 1. **Network Monitoring Setup:** Implement a dedicated monitoring solution (e.g., Man-in-the-Middle configuration or dedicated managed switch mirroring) to capture all traffic between the NAH and the wider network when the Static IP service is initialized. 2. **Protocol Analysis:** Use tools like Wireshark to analyze the captured packets for non-standard routing protocol traffic (e.g., looking for custom BGP, IS-IS, or specific DHCP option codes) that are unique to the Telus NAH. 3. **Replication Attempt:** Utilize the UDM Pro's advanced routing capabilities (e.g., using its internal Linux OS) to attempt to craft and send the necessary packets to successfully advertise the static IP subnet and achieve a true, full bypass. ### References and Citations The following sources informed the technical details of this exploration: * **[1] Alcatel-Lucent G-010S-A SFP Technical Data:** Details on management IP, SSH credentials, and `onu` / `ritool` commands. (Source: https://hack-gpon.org/ont-nokia-g-010s-a) * **[2] UniFi UDM Pro SFP+ Port Behavior:** Confirmation of required link speed settings (1000 FDX) and Linux interface naming (`eth10`). (Source: *Ubiquiti community forums*) * **[3] Telus Static IP Subnet Bypass Consensus:** Documentation of the Static IP bypass failure and the necessity of the proprietary protocol run by the NAH. (Source: *Reddit r/telus and DSLReports forums* https://www.reddit.com/r/telus/comments/1hsbtez/seeking_docs_on_bridging_technicolor_nh20t_so_i/) * **[4]** https://community.ui.com/questions/UFiber-GPON-SFP-on-UDM-Pro/03e052d8-85fd-4444-8910-914384453e48 * **[5]** https://github.com/hwti/G-010S-A * **[6]** https://www.al-enterprise.com/-/media/assets/internet/documents/nokia-ont-g-010s-s-datasheet-en.pdf * **[7]** https://www.reddit.com/r/telus/comments/1hsc6e1/trying_to_bypass_the_telus_gateway_hub_nh20a/ * **[8]** https://pon.wiki/category/nh20t/ * **[9]** https://www.youtube.com/watch?v=ib0XVeCJanM --- # dig ## Installing Dig util ### Ubuntu ```bash apt-get install dnsutils ``` ### Check Installation ```bash dig -v ``` ## Get All DNS Record Types ```bash dig example.com ANY ``` ## Get A Records ```bash dig EXAMPLE.COM +noall +answer ``` ## Get NS Records ```bash dig @8.8.8.8 +short NS domain.com ``` ## Search For Record Type ```bash dig example.com MX ``` ``` dig example.com txt (Query TXT record) dig example.com cname (Query CNAME record) dig example.com ns (Query NS record) dig example.com A (Query A record) ``` ## Trace DNS Path ```bash dig example.com +trace ``` ## Reverse DNS Lookup ```bash dig +answer -x 192.168.0.1 ``` ## Batch Queries ``` vi domain_list.txt example.com google.com ubuntu.com ``` ```bash dig -f domain_list.txt +short ``` --- # SSH Basic ## Installing SSH Agent Install openssh with homebrew ```bash brew install openssh ``` ## Generating & Setting up ### Mac Open Terminal & paste this with your email ```bash ssh-keygen -t rsa -b 4096 -C "your_email@example.com" ``` Start ssh-agent if not running ```bash eval "$(ssh-agent -s)" ``` Open to ssh config file (woks on **macOS Sierra 10.12.2** or **later**) ```bash open ~/.ssh/config ``` Update the `config` with this (add at bottom) #### paste this if you want to use key for all server ```bash Host * AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_rsa ``` #### paste this if you want to use key for specific server ```bash Host [example.com] //server-name here HostName git.example.com //actual server address User sshuser //username IdentityFile ~/.ssh/id_rsa //file location UseKeychain yes AddKeysToAgent yes ForwardAgent yes ``` #### Store passphrase to your keychain ( optional) if you don't want to input passpharse everytime ```bash ssh-add -K ~/.ssh/id_rsa ``` ## Copy public key to clipboard ```bash pbcopy < ~/.ssh/id_rsa.pub ``` --- # How to add/update SSH Login Banner Learn how to setup pre-login and post-login banner for ssh session. ## Prerequisites 1. You have access to the root shell to the remote system that you're trying to setup message. 2. You are familiar with a Linux text editor like nano, vim, etc. ## Pre-login Message Banner The pre-login message banner sends a message to the remote user who attempts to log in to the system using SSH. The pre-login message banner is useful for enforcing security policy; for example, to inform the remote user all activities are logged. ### Setup pre-login 1. Login to ssh shell of the remote system. 2. edit the file `/etc/issue.net` using your prefered text editor: ```bash nano /etc/issue.net ``` 3. Add your message to above file to add/update the pre-login message for **Remote/tty** shells. :::info Most of the systems requires to use of escape characters in the message instead of return, tabs etc,. Use `\n` , `\t` instead. ::: ```text \nALERT! You are entering into a secured area!\nYour IP, Login Time, Username has been noted and has been sent to the server administrator!This service is restricted to authorized users only. All activities on this system are logged.\nUnauthorized access will be fully investigated and reported to the appropriate law enforcement agencies.\n ``` Other Examples: [LEGAL Notices for Login/MOTD unix banners](https://gist.github.com/hvmonteiro/7f897cd8ae3993195855040056f87dc6) 4. edit file `/etc/ssh/sshd_config` and enable/uncomment Banner: ```diff -- #Banner /etc/issue.net ++ Banner /etc/issue.net ``` ## Post-login Message Banner (Message of the Day) The post-login message banner appears after a user successfully authenticates to the advance shell access on the system, either using SSH or the serial console. This message banner is useful to inform your users about the system; for example, to inform users of an upcoming scheduled maintenance. ### Setup post-login 1. Login to ssh shell of the remote system. 2. edit the file `/etc/motd` using your prefered text editor: ```bash sudo nano /etc/motd ``` 3. Add your message to above file to add/update the post-login message (Message of the Day). :::info Most of the systems requires to use of escape characters in the message instead of return, tabs etc,. Use `\n` , `\t` instead. ::: ```text \nWelcome to the XYZ Systems.\n ``` --- # Replacing Failed USB Flash on Ubiquiti EdgeRouter: A Recovery Guide *When your EdgeRouter dies silently, it's probably the USB flash. Here's how I recovered from yet another flash failure.* ## The Problem If you're experiencing any of these issues with your Ubiquiti EdgeRouter: - **Router keeps running** but **fails to boot after a reboot** - **Boot loops** or **kernel panic on startup** - **System appears to work** but logs errors about missing configuration files - **Can't SSH in** after rebooting, but was fine before - **DHCP or firewall rules** suddenly not applying after a restart ...your internal USB flash drive has likely failed. ## The Solution The recovery process involves creating a new bootable USB drive with EdgeOS. While Ubiquiti provides the OS tarball, you can't just extract it to a USB stick – it needs proper partitioning, formatting, and careful placement of the boot files. Fortunately, **[mkeosimg](https://github.com/deimosfr/mkeosimg)** Orignally by [sowbug](https://github.com/sowbug) exists to automate most of the process. This bash script takes an EdgeOS tarball and produces a ready-to-use disk image. :::warning Double-check remote scripts, i'm not affiliated with Ubiquiti or the script author. Use at your own risk. You should always verify the contents of any script before running it with elevated privileges. ::: ## What You'll Need Before you start, make sure you have: - A **machine** running any Debian/Ubuntu-based Linux distribution - An **EdgeOS tarball** (the release image from Ubiquiti) --> you can download it from [Ubiquiti's website](https://ui.com/download) - A **USB drive or SD card** (at least 2GB; 4GB+ is safer) - **About 4GB of free disk space** on your machine - The **mkeosimg script** (or you can clone it from GitHub) ## Step 1: Install the Required Tools The mkeosimg script depends on several command-line utilities. Let's verify they're installed: ```bash which losetup parted mkfs.msdos mkfs.ext3 tar dd ``` You should see paths for all of these commands. If not, install the missing ones: ```bash sudo apt update sudo apt install -y parted e2fsprogs dosfstools ``` These packages provide: - **parted** – for disk partitioning - **e2fsprogs** – includes `mkfs.ext3` for ext3 filesystems - **dosfstools** – includes `mkfs.msdos` for FAT32 - The others (`losetup`, `tar`, `dd`) are part of the base OS Quick verification: ```bash parted --version mkfs.msdos -h 2>&1 | head -1 mkfs.ext3 -h 2>&1 | head -1 ``` ## Step 2: Prepare Your EdgeOS Tarball Get the EdgeOS release image ready: ```bash ls -lh *.tar ``` You should see something like: ``` edgeos-v2.1.10-amd64-20250101.tar (100-500MB typically) ``` If you have a custom EdgeOS config you want to include: ```bash ls -l edgeos_config.tar.gz ``` If this file exists, the script will apply it when creating the image (and add a `-configured` suffix to the output filename). ## Step 3: Identify Your USB Drive (The Critical Part) This is where you need to be careful. Identifying the wrong device could be destructive. ### List all disks: ```bash lsblk ``` Example output: ``` NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 1 14.9G 0 disk ├─sda1 8:1 1 512M 0 part └─sda2 8:2 1 14.4G 0 part sdb 8:16 0 931.5G 0 disk ├─sdb1 8:17 0 256M 0 part /boot └─sdb2 8:18 0 931.2G 0 part / ``` ### How to identify your USB drive: - **Look for a device in `/dev/sdX`** (where X is a letter like `a`, `b`, `c`) - **Check the size** – your USB drive should be smaller than your Pi's main storage - **Check RM column** – removable media will show `1` - **Check MOUNTPOINT** – USB drives are often unmounted (empty) In the example above, `/dev/sda` (14.9G) is likely the USB drive, while `/dev/sdb` (931.5G) is the Pi's main storage. ### Verify before proceeding: ```bash sudo fdisk -l /dev/sdX ``` Replace `sdX` with your identified device. Check: - The size matches your USB drive - It's not your Pi's system drive **If you're unsure, stop here and double-check.** Writing to the wrong device is irreversible. ## Step 4: Run the mkeosimg Script ### Get the script: You can clone it from GitHub or copy it directly: ```bash git clone https://github.com/deimosfr/mkeosimg.git cd mkeosimg ``` Or if you already have it: ```bash cd /path/to/mkeosimg chmod +x mkeosimg.sh ``` ### Run it with your tarball: ```bash sudo ./mkeosimg.sh edgeos-v2.1.10-amd64-20250101.tar ``` Replace the filename with your actual EdgeOS tarball. ### What it does: 1. **Creates a 2GB disk image** file (`.img`) 2. **Partitions it** into boot (150MB) and root (1750MB) sections 3. **Formats the partitions** with FAT32 and ext3 4. **Extracts the EdgeOS release** into the image 5. **Verifies checksums** to ensure nothing got corrupted 6. **Applies your custom config** (if you have one) 7. **Creates data directories** for EdgeOS's writable files The whole process takes a few minutes. You'll see output like: ``` Creating edgeos-v2.1.10-amd64-20250101.img 2048+0 records in 2048+0 records out ... Unpacking EdgeOS release image Verifying EdgeOS kernel Copying EdgeOS kernel to boot partition ... Done. ``` When you see "Done." at the end, your image is ready. ## Step 5: Write the Image to Your USB Drive Now comes the moment of truth. **Triple-check your device name one more time:** ```bash lsblk ``` ### Unmount the USB drive: ```bash sudo umount /dev/sdX* ``` This ensures nothing is locked while we write to it. ### Write the image: ```bash sudo dd if=edgeos-v2.1.10-amd64-20250101.img of=/dev/sdX bs=4M status=progress ``` **Important notes:** - `if=` is the input file (your `.img` file) - `of=` is the output device (your USB drive—**not a partition number**, just `/dev/sda`, not `/dev/sda1`) - `bs=4M` writes in 4MB chunks for speed - `status=progress` shows you how far along it is Wait for it to complete. You'll see something like: ``` 15728640000 bytes (15.7 GB) copied, 45.2 s, 348 MB/s ``` ### Sync to ensure everything is written: ```bash sudo sync echo "Write complete" ``` The `sync` command flushes any buffered data to disk. Don't unplug the USB drive until this completes. ## Step 6: Replace the Failed USB in Your EdgeRouter ### For EdgeRouter Lite (internal USB): The original EdgeRouter Lite units have an internal USB flash drive. To replace it: 1. **Power off** the EdgeRouter completely 2. **Open the case** (remove screws on the bottom) 3. **Locate the internal USB** (it's a small USB stick plugged into the internal header) 4. **Remove the dead USB** and **insert your new one** 5. **Close the case** and power on The router should boot from the new USB flash drive. ### For external USB recovery: If you're using this as an external recovery drive: 1. **Eject safely** from your Pi: ```bash sudo eject /dev/sdX ``` 2. **Insert the USB** into your EdgeRouter 3. **Power on** and access the boot menu (DEL/F12/ESC depending on model) 4. **Select the USB** as the boot device 5. EdgeOS should load from your new drive ## Troubleshooting ### "Must run as root or with sudo" Make sure you're using `sudo`: ```bash sudo ./mkeosimg.sh your-image.tar ``` ### "parted: command not found" Install it: ```bash sudo apt install parted ``` ### "mkfs.ext3: No such file or directory" Install e2fsprogs: ```bash sudo apt install e2fsprogs ``` ### "Kernel in image is corrupted!" Your EdgeOS tarball is damaged. Try: ```bash md5sum edgeos-v2.1.10*.tar ``` Compare the checksum with the official EdgeOS release. If it doesn't match, re-download the tarball. ### "Device busy" when writing The USB drive is still mounted. Unmount it: ```bash sudo umount /dev/sdX* ``` ### Not enough disk space Free up space on your Pi: ```bash df -h sudo apt clean rm -rf ~/Downloads/* ``` ## Why Use mkeosimg? Instead of manually: - Creating a disk image with `dd` - Partitioning with `parted` - Formatting each partition - Extracting and positioning kernel and filesystem images - Verifying checksums - Setting ownership and permissions ...mkeosimg handles all of this in one command. When you're dealing with a failed router at a client site (or in a data center), you want a reliable, tested process—not a series of manual steps where one typo could waste an hour. ## Credits This guide uses the **[mkeosimg](https://github.com/deimosfr/mkeosimg)** script, modified version of the original by [sowbug](https://github.com/sowbug). Huge thanks to both authors for making EdgeRouter recovery easier for all of us. ## Next Steps Once your EdgeRouter is booted with the new USB flash: 1. **Restore your configuration backup** (you have one, right?) 2. **Update to the latest EdgeOS** version 3. **Test all network interfaces** and routes 4. **Verify firewall rules** are working 5. **Set up automated config backups** to prevent future headaches If you don't have a config backup, you'll need to reconfigure from scratch. This is a painful lesson learned once—always keep recent backups of your router configs. ## Final Thoughts The EdgeRouter Lite is a solid piece of hardware, but those internal USB flash drives are its Achilles' heel. If you manage multiple EdgeRouter units, keep a few spare USB drives pre-imaged and ready to go. Your future self (or your on-call engineer at 2 AM) will thank you. --- # How to upgrade the Unifi Controller Virtual Machine Installation import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; ## Prerequisites - Access to Virtual Machine via SSH or Console - Read [release notes](https://community.ui.com/releases) for any active bugs and issues. :::caution It's recommended to take the any form of backup, either snapshot of the vm or full backup. ::: ## Downloading the new version You can download the new version from Ubiquiti's website [here](https://ui.com/download/). 1. In there switch tab to **Unifi**. 2. Look for **Unifi Network Application** (Previously Unifi Network Controller) in Software section. 3. Click **Download** and accepts the terms of download. 4. Download the file or copy the file url. ### Download URL URL Replace the https://dl.ui.com/unifi/version/filename with the version you want to download. https://dl.ui.com/unifi/7.1.65/UniFi-installer.exe https://dl.ui.com/unifi/7.1.65/UniFi.pkg https://dl.ui.com/unifi/7.1.65/unifi_sysvinit_all.deb ## Upgrade 1. SSH or Console to the Virtual Machine. 2. Upload the file or download the file into the Virtual Machine. In PowerShell, type the following command: Invoke-WebRequest -OutFile UniFi-installer.exe -Uri https://dl.ui.com/unifi/7.1.65/UniFi-installer.exe Or you can use the browser to download the file. wget https://dl.ui.com/unifi/7.1.65/UniFi.pkg wget https://dl.ui.com/unifi/7.1.65/unifi_sysvinit_all.deb 3. Run the file. Open the file from explorer. Open the file from finder. sudo dpkg -i unifi_sysvinit_all.deb --- # BSD Troubleshooting ## Installing qemu-guest-agent on BSD ### Install qemu-guest-agent package 1 ```bash pkg install -y qemu-guest-agent echo 'qemu_guest_agent_enable="yes"' >> /etc/rc.conf.local echo 'qemu_guest_agent_flags="-d -v -l /var/log/qemu-ga.log"' >> /etc/rc.conf.local ``` ### Create a script to start the qemu-guest-agent service on boot 1 ```bash echo 'service qemu-guest-agent start' > /usr/local/etc/rc.d/qemu-guest-agent.sh chmod +x /usr/local/etc/rc.d/qemu-guest-agent.sh ``` #### Alternatively, run following remote script with curl 1 :::caution **Always verify before running remote scripts!** ::: ```bash curl -s https://gist.githubusercontent.com/dipakparmar/2736f1952a3b3d46526d857b5452e58d/raw/965903e32e63c219d44197254aca56162d5c06a2/1-Install-setup-qemu-guest-agent.sh | sh ``` #### Reference: 1. https://forum.netgate.com/topic/162083/pfsense-vm-on-proxmox-qemu-agent-installation/15 2. https://pve.proxmox.com/wiki/Qemu-guest-agent 3. https://docs.netgate.com/pfsense/en/latest/development/boot-commands.html 4. https://www.explorelinux.com/start-stop-or-restart-a-service-in-freebsd/ --- # certbot ### certbot register a email ```shell certbot register -m abc@example.com --work-dir ./ --logs-dir=./logs/ ``` ### generate a ssl cert with cerbot (let's encrypt) ```shell certonly -d "*.xyz.com" -d "www.xyz.com" --manual ``` ### generate a ssl cert with certbot (let's encrypt) with dns challenge ```sh certonly --preferred-challenges dns --manual -d "*.xyz." ``` --- # Certificates and Keys ## Convert .pem key to RSA private key The PEM format is the most common format that Certificate Authorities issue certificates in. PEM certificates usually have extensions such as .pem, .crt, .cer, and .key. They are Base64 encoded ASCII files and contain `"-----BEGIN CERTIFICATE-----"` and `"-----END CERTIFICATE-----"` statements. Server certificates, intermediate certificates, and private keys can all be put into the PEM format. Apache and other similar servers use PEM format certificates. Several PEM certificates, and even the private key, can be included in one file, one below the other, but most platforms, such as Apache, expect the certificates and private key to be in separate files. ```sh openssl rsa -in key.pem -out id_rsa ``` ## Convert x509 formatted files ### Convert x509 .crt certificate file to PEM format ```sh openssl x509 -in cert.pem -out cert.pem ``` ### Convert x509 .cer certificate file to PEM format ```sh openssl x509 -in cert.cer -out cert.pem ``` ### Convert x509 .der certificate file to PEM format The DER format is simply a binary form of a certificate instead of the ASCII PEM format. It sometimes has a file extension of .der but it often has a file extension of .cer so the only way to tell the difference between a DER .cer file and a PEM .cer file is to open it in a text editor and look for the BEGIN/END statements. All types of certificates and private keys can be encoded in DER format. DER is typically used with Java platforms. ```sh openssl x509 -inform der -in cert.der -out cert.pem ``` ## Convert P7B The PKCS#7 or P7B format is usually stored in Base64 ASCII format and has a file extension of .p7b or .p7c. P7B certificates contain `"-----BEGIN PKCS7-----"` and `"-----END PKCS7-----"` statements. A P7B file only contains certificates and chain certificates, not the private key. Several platforms support P7B files including Microsoft Windows and Java Tomcat. ### Convert P7B to PEM format ```sh openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer ``` ### Convert P7B to PFX format ```sh openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer ``` ```sh openssl pkcs12 -export -in certificate.cer -inkey privateKey.key -out certificate.pfx -certfile CACert.cer ``` ## Convert the certificate and private key to a PFX file The PKCS#12 or PFX format is a binary format for storing the server certificate, any intermediate certificates, and the private key in one encryptable file. PFX files usually have extensions such as .pfx and .p12. PFX files are typically used on Windows machines to import and export certificates and private keys. ```sh openssl pkcs12 -export -in cert.pem -inkey key.pem -out cert.pfx ``` You will be asked for the pass-phrase for the private key if needed, and also to set a pass-phrase for the newly created .pfx file too. When converting a PFX file to PEM format, OpenSSL will put all the certificates and the private key into a single file. You will need to open the file in a text editor and copy each certificate and private key (including the BEGIN/END statements) to its own individual text file and save them as certificate.cer, CACert.cer, and privateKey.key respectively. --- # curl ### Curl run remote script ```shell curl --compressed -o- -L https://yarnpkg.com/install.sh | bash ``` ### ping and retrieve ssl info of the host ```shell curl -gkvLI -H 'User-Agent: your-agent-name daemon 2.4' -H 'Accept: */*' -H 'Connection: Close' -H 'Accept-Language: en' -m 30 --connect-timeout 10 https://xyx.com ``` --- # Debian default sources list This should be found in the `/etc/apt/sources.list` file. If you're customizing or adding any additional you should add that to `/etc/apt/sources.list.d` directory. ## Debian 10 - Buster sources ``` deb http://deb.debian.org/debian buster main contrib non-free deb-src http://deb.debian.org/debian buster main contrib non-free deb http://deb.debian.org/debian buster-updates main contrib non-free deb-src http://deb.debian.org/debian buster-updates main contrib non-free deb http://deb.debian.org/debian buster-backports main contrib non-free deb-src http://deb.debian.org/debian buster-backports main contrib non-free deb http://security.debian.org/debian-security/ buster/updates main contrib non-free deb-src http://security.debian.org/debian-security/ buster/updates main contrib non-free ``` --- # How to install QEMU Agent on Debian/Ubuntu ### Install qemu-guest-agent package ```bash apt -y install qemu-guest-agent ``` ### Enable QEMU guest agent ```bash systemctl enable qemu-guest-agent ``` ### Start QEMU guest agent ```bash systemctl start qemu-guest-agent ``` ### Check QEMU guest agent status running ```bash systemctl status qemu-guest-agent ``` --- # Disk Management ### Check Partations ```bash sudo lsblk ``` Output ```bash Output NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop0 7:0 0 91.1M 1 loop /snap/core/6531 loop1 7:1 0 56.7M 1 loop /snap/google-cloud-sdk/75 sda 8:0 0 10G 0 disk ├─sda1 8:1 0 9.9G 0 part / ├─sda14 8:14 0 4M 0 part └─sda15 8:15 0 106M 0 part /boot/efi sdb 8:16 0 10G 0 disk ``` ### Format the disk (ext4) ```bash sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/DEVICE_ID ``` ### Mount the new disk Create a new directory ```bash sudo mkdir -p /folder/directory ``` Mount disk to the directory ```bash sudo mount -o discard,defaults /dev/sdb /folder/directory ``` Set read write permission ```bash sudo chmod a+w /folder/directory ``` ### Set up auto mount on Restart Creating backup of current fstab (failsafe 😉) ```bash sudo cp /etc/fstab /etc/fstab.backup ``` Get the UUID of the disk ```bash sudo blkid /dev/DEVICE_ID ``` Create an entry in /etc/fstab to mount the /dev/sdb persistent disk at /folder/directory using its UUID. ```bash echo UUID=`sudo blkid -s UUID -o value /dev/sdb` /folder/directory ext4 discard,defaults,nofail 0 2 | sudo tee -a /etc/fstab ``` **Note: Replace dev/sdb if your disk id is different** ## Verify entry ```bash cat /etc/fstab ``` ## Unmounting a File System This section doc is from (Reference: [Linuxize](https://linuxize.com/post/how-to-mount-and-unmount-file-systems-in-linux/#unmounting-a-file-system)) To detach a mounted file system, use the umount command followed by either the directory where it has been mounted (mount point) or the device name: ```bash umount DIRECTORY ``` ```bash umount DEVICE_NAME ``` If the file system is in use the umount command will fail to detach the file system. In those situations, you can use the fuser command to find out which processes are accessing the file system: ```bash fuser -m DIRECTORY ``` Once you determine the processes you can stop them and unmount the file system. Lazy unmount Use the `-l (--lazy)` option to unmount a busy file system as soon as it is not busy anymore. ```bash umount -l DIRECTORY ``` Force unmount Use the `-f (--force)` option to force an unmount. This option is usually used to unmount an unreachable NFS system. ```bash umount -f DIRECTORY ``` Generally not a good idea to force unmount as it may corrupt the data on the file system. --- # Enable Serial Terminal for Ubuntu/Linux VM Enabling a serial terminal for Ubuntu or Linux VMs allows you to access the VM console via a serial port, which is supported by most hypervisors (Proxmox, VMware, VirtualBox, etc.). This guide walks you through the process. ## Prerequisites - A hypervisor (Proxmox, VMware, VirtualBox, etc.) with an Ubuntu/Linux VM - Access to the VM via SSH or Console ## Steps ### 1. Add a Virtual Serial Port 1. Open your hypervisor's management interface. 2. Select your VM. 3. Add a **Serial Port** to the VM hardware. 4. Confirm and restart the VM if required. ### 2. Enable Serial Console in Ubuntu/Linux 1. Log in to your Ubuntu/Linux VM (via SSH or Console). 2. Enable and start the serial-getty service for the serial port (usually `ttyS0`): ```bash sudo systemctl enable serial-getty@ttyS0.service sudo systemctl start serial-getty@ttyS0.service ``` :::info **Single command alternative:** ```bash sudo systemctl enable --now serial-getty@ttyS0.service ``` ::: If your serial port uses a different device (e.g., `ttyS1`), adjust the command accordingly. ### 3. Access the Serial Terminal 1. Use your hypervisor's console feature (e.g., xterm.js in Proxmox, Serial Console in VMware/VirtualBox). 2. You should now see the Ubuntu/Linux login prompt via the serial terminal. ## Example: Proxmox VE If you are using Proxmox VE, follow these steps: 1. Open the Proxmox Web GUI. 2. Select your VM. 3. Go to **Hardware**. 4. Click **Add** → **Serial Port**. 5. Confirm and restart the VM. 6. After enabling the serial-getty service as described above, go to **Console** and select **xterm.js**. 7. You should see the Ubuntu/Linux login prompt via the serial terminal. --- # Networking ### Find the process of service running/using port #### Using lsof ```bash lsof -i :22 ``` #### Using ss ```bash ss -ltnup 'sport = :22' ``` #### Using netstat ```bash netstat -ltnup ``` - l – show only listening sockets - t – show TCP connections - n – show addresses in a numerical form - u – show UDP connections - p – show process id/program name --- # Reset Ubuntu Server Password from GRUB ## Resetting a Forgotten Ubuntu Password via GRUB If you've forgotten your Ubuntu server password, you can reset it using the GRUB boot menu. You can reset via one of these two methods: using recovery mode or editing the GRUB boot parameters. ## Method 1: Using Recovery Mode This method is recommended for most users as it is more straightforward. 1. **Reboot the server.** 2. While the server is starting, press and hold Shift (or Esc for UEFI systems) to display the GRUB menu. 3. In the GRUB menu, select **Advanced options for Ubuntu** and press Enter. 4. Choose the entry that includes (recovery mode) and press Enter to boot into the recovery menu. 5. Select **root: Drop to root shell prompt** and press Enter. 6. By default, the file system is mounted as read-only. Remount it with read-write permissions: ```bash mount -rw -o remount / ``` 7. To find your username (if you don't know it), list the home directories: ```bash ls /home ``` 8. Reset the user's password: ```bash passwd ``` Replace `` with your actual username. Follow the prompts to set the new password. 9. Type `exit` to return to the recovery menu. 10. Select **resume: Resume normal boot** to restart your server. :::info After reboot, you can log in with the new password. ::: ## Method 2: Editing GRUB Boot Parameters This method boots directly into a root shell, skipping the recovery menu. 1. Reboot and hold Shift or Esc to enter the GRUB menu. 2. Select the standard Ubuntu boot entry and press e to edit. 3. Find the line starting with linux /boot/vmlinuz-.... 4. Remove the parameters `ro quiet splash` and append: ```bash rw init=/bin/bash ``` 5. Press F10 or Ctrl+X to boot. 6. The system will boot to a passwordless root shell. Set the password: ```bash passwd ``` 7. After resetting the password, reboot the system: ```bash exec /sbin/init ``` :::caution Use these methods only on systems you are authorized to access. ::: --- # Rsync ## Syntax ```bash rsync [options] source [destination] ``` **Options**: - `-a, --archive` copy all metadata with sync (symbolic links, file permissions, user & group ownership and timestamps etc.) - `-v, --verbose` will give you summary of process - `-h, --human-readable format` Outputs in a human readable format. - `-z, --compress` compress file data during the transfer ## Local ### Copy data from `foo` to `bar` ```bash rsync -avh foo/ bar/ ``` ## Remote ### Basics ```bash rsync local-file user@remote-host:remote-file ``` ### Rsync using ssh ```bash rsync -avhze ssh /foo user@remote-host:/tmp/ ``` ### Rsync with particular file permissions ```bash rsync -avhe ssh --chown=USER:GROUP /foo user@remote-host:/tmp/ ``` ### Rsync with --ignore-existing-files Does not ignore directory ```bash rsync --ignore-existing -avhe /foo user@remote-host:/tmp/ ``` ### Show progress during transfer ```bash rsync -avhe ssh --progress /foo user@remote-host:/tmp/ ``` ### Update the remote only if there is a newer version is on the local filesystem ( timestampz based ) ```bash rsync -avhe ssh --progress --update /foo root@remote-host:/tmp/ ``` ### Automatically delete files from local-host after successful transferring delete only files not directories ```bash rsync -avhe ssh --remove-source-files /foo user@backup-server:/tmp ``` ### Performing a Dry run with rsync ```bash rsync -avhe ssh --dry-run --chown=USER:GROUP /foo user@remote-host:/ ``` --- # System Information Check Hardware info of machine ```bash sudo lshw ``` --- # User Permission Management in Linux/Ubuntu ## To list ### To list all local users you can use: ```bash cut -d: -f1 /etc/passwd ``` ## To add ### To add a new user you can use: ```bash sudo adduser new_username ``` or: ```bash sudo useradd new_username ``` ## To remove/delete ### To remove/delete a user, first you can use: ```bash sudo userdel username ``` Then you may want to delete the home directory for the deleted user account : ```bash sudo rm -r /home/username ``` ### add new user in linux ```bash sudo adduser new_username ``` ## To modify ### To modify the username of a user: ```bash usermod -l new_username old_username ``` ### To change the password for a user: ```bash sudo passwd username ``` ### To change the shell for a user: ```bash sudo chsh username ``` ### To change the details for a user (for example real name): ```bash sudo chfn username ``` ### To add a user to the sudo group: ```bash adduser username sudo ``` or ```bash usermod -aG sudo username ``` And, of course, see also: `man adduser`, `man useradd`, `man userdel`... and so on. --- # Releasing pre-release versions of your npm package Releasing pre-release versions of your npm package can be a great way to get feedback on new features or improvements before making a final release. In this article, I'll explain how to create and publish pre-release versions of your package using npm. ## Creating a pre-release version To create a prerelease version, first update your package's version number to include a prerelease identifier, such as **"beta"** or **"alpha**. You can use the **premajor**, **preminor**, or **prepatch** commands to increment the version number accordingly. For example, if you are currently on version **1.0.0** and want to release a beta version, you would use the preminor command with the `--preid=beta` flag. This will update your version number to `1.1.0-beta.0`. Once your package is ready for release, run the `npm publish` command with the appropriate prerelease tag to make it available for testing. ```bash # this will take you to 2.0.0-rc.0 npm version premajor --preid=rc # this will take you to 1.1.0-beta.0 npm version preminor --preid=beta # this will take you to 1.0.1-alpha.0 npm version prepatch --preid=alpha ``` ## Bump the prerelease version If you need to make changes to your package after releasing a pre-release version, you can use the **prerelease** command to bump the prerelease version number. This will increment the prerelease version number by 1, and will also increment the patch version number if the prerelease version number reaches 10. ```bash # this will take you to 1.0.1-alpha.1 npm version prerelease # this will take you to 1.0.1-alpha.2 npm version prerelease # this will take you to 1.0.1-alpha.3 (and so on) npm version prerelease ``` ## Promote the prerelease to a release Once you have thoroughly tested your prerelease version and are ready to make it available to the general public, you will need to promote it to a release. This involves updating the version number and running the appropriate npm command. For example, if you started with a preminor version, you will need to run the `npm version minor` command to promote it to a minor release. This will update the version number and allow the package to be installed without specifying the prerelease tag. :::caution careful Make sure to thoroughly test your prerelease versions before promoting them to ensure a smooth transition to the release version. ::: ```bash # this will take you to 1.1.0 npm version minor # this will take you to 1.1.1 npm version patch # this will take you to 2.0.0 npm version major ``` --- # Global Protect VPN ### Prevent Auto Starting Global Protect VPN 🌏 1. Open Finder and press cmd + shift + G . 2. Go to directory `~/Library/LaunchAgents/` or run following command in terminal. ```bash open ~/Library/LaunchAgents/ ``` 3. Change value for following `RunAtLoad` & `KeepAlive` to **false** (Line. 12 & 14). ```xml {12,14} showLineNumbers Label com.paloaltonetworks.gp.pangpa LimitLoadToSessionType Aqua Program /Applications/GlobalProtect.app/Contents/MacOS/GlobalProtect RunAtLoad KeepAlive ``` --- # Allow app access to the keychain login item manually import KeyChainScreenshot from '/img/docs/troubleshooting-fixes/macos/keychain-01.png'; import KeyChainPromptScreenshot from '/img/docs/troubleshooting-fixes/macos/keychain-prompt-01.png'; import Admonition from '@theme/Admonition'; macOS Keychain Prompt 1. Open Keychain Access in **Applications > Utilities > Keychain Access** 2. Highlight **"Login"** Keychain macOS Keychain 3. Find the key or keys you wish to allow your application to access 4. Right-click the key item, and select **"Get Info"** 5. Click on the **"Access Control"** tab 6. Select **"Allow all application to access this item"** or **"Always Allow"**

If you select "Allow all application to access this item", this will allow all applications to access the keychain item.

7. Press **"Save Changes"** to confirm the change 8. Enter your password you use to login to the server to authenticate. --- # Fixing Universal Clipboard Issue after OnVUE Proctoring Tool Installation ## Issue After installing the OnVUE proctoring tool for the AWS Pearson Vue exam on macOS Ventura 13.5 (22G74), the Universal Clipboard (copy-paste functionality between Mac iPhone) stops working. Even after uninstalling the OnVUE tool, the Universal Clipboard remains non-functional. ## Solution Follow the steps below to resolve the Universal Clipboard issue: 1. Ensure that you're **logged in** to iCloud with the **same account** on both the Mac and iPhone. 2. Verify that **Handoff** is enabled in the system preferences. 3. Open the **Terminal** application on your Mac. 4. Enter and run the following command: ```bash defaults delete ~/Library/Preferences/com.apple.coreservices.useractivityd.plist ClipboardSharingEnabled ``` After that, enter and run the subsequent command: ```bash defaults write ~/Library/Preferences/com.apple.coreservices.useractivityd.plist ClipboardSharingEnabled 1 ``` The Universal Clipboard functionality should now be restored. ### Reference - [https://discussions.apple.com/thread/253274114](https://discussions.apple.com/thread/253274114) --- # macOS Dock changes position ## Dock changes position on two screens 🖥 It was so annoying when dock keeps jumping from my main screen to another screen. for the first few times, I ignored but, it started frustrated me so went to google to find out some solution I'm the only one or some other two screen geeks is having the same issue. And found that I'm not the one, found a few solutions that I'm mentioning here. #### 1. Apple's Mission control uses a separate space thing which distinguishes your screens ⚠️ try disabling displays have separate spaces **Pro**: that fixes the moving dock, yay 🤩 but here is the con **Con**: you lose the multi-desktop feature, it's kinda a second screen presenter mode for your screen so for this was a workaround > I checked **Mission Control** and **Display has separate Spaces** is checked. - "Felix Hernandez" #### 2. For some people it's a bug and but for apple, it's a feature ✅ _you can move dock from one screen to another screen by pointing arrow at the very bottom of the screen for 2-4 seconds! ✨_ Found interesting reply by [SputnikTechnologies](https://discussions.apple.com/thread/5527972?answerId=23831944022#23831944022) > Hey guys, So apparently, this is an actual feature and not a bug. It's been **\*\*\*** me off as well as I use 3 monitors, but I read on a different forum how to actually make it appear on a different monitor and **all you have to do is actually move your mouse to the center of the screen, and move it all the way down as if you're trying to drive into the bottom of the screen.** you'll see it appears on any monitor you do this to (clearly being a feature). I think it's stupid and would love to have the option to disable this without losing my separate spaces for each monitor, but I guess this is the Apple way. What can ya do? Hope this helps. Orignal Discussion: https://discussions.apple.com/thread/5527972?answerId=23674095022#23674095022 ### Reseting macOS Dock copy and paste this on terminal ```bash defaults delete com.apple.dock; killall Dock ``` ### macOS maintenance fix with custom hidden features https://www.titanium-software.fr/ --- # Clear Microsoft Teams Cache import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import Admonition from '@theme/Admonition'; import CodeBlock from '@theme/CodeBlock';

Be aware that clearing the cache will require your system to download all the data again. This may take a while depending on your internet connection speed.

  1. If Teams is still running, right-click the Teams icon in the dock, and then select Quit, or press Command ⌘ + Q.
  2. In the Finder, open the /Applications/Utilities folder, and then double-click Terminal.
  3. Enter the following command, and then press Return

    rm -r ~/Library/Application\ Support/Microsoft/Teams
  4. Navigate to Keychain Access. Search for ‘Microsoft Teams’ and delete the entry. Open Teams and wait for it to download required files.
  5. Restart Teams.
  1. If Teams is still running, right-click the Teams icon in the taskbar, and then select Quit.
  2. Open the Run dialog box by pressing the Windows logo key + R.
  3. In the Run dialog box, enter %appdata%\Microsoft\Teams, and then select OK.
  4. Delete all files and folders in the %appdata%\Microsoft\Teams directory.
  5. Restart Teams.
--- # Github Actions Ref: https://github.com/peaceiris/actions-gh-pages --- # Github Pages ## Setting apex/root domain with github pages Add A/ANAME/ALIAS records to your root domain ``` 185.199.108.153 185.199.109.153 185.199.110.153 185.199.111.153 ``` ## Set 404 Page In root directory create 404.html page or 404.md ``` --- permalink: /404.html --- ``` --- # Git GPG ## Installing gpg client ### mac Installing with HomeBrew Client ``` brew install gpg ``` ## Setting up default GPG Client ``` git config --global gpg.program gpg2 ``` ## Setting up GPG Key Better to use gpg2 instead of gpg in all below commands ### Generating a new pgp key ``` gpg --gen-key ``` maybe you need some random work in your OS to generate a key. so run this command: ``` find ./* /home/username -type d | xargs grep some_random_string > /dev/null ``` ### Checking current keys ``` gpg --list-secret-keys --keyid-format LONG ``` ### See your gpg public key ``` gpg --armor --export YOUR_KEY_ID ``` **YOUR_KEY_ID** is the hash in front of `sec` in previous command. (for example `sec 4096R/234FAA343232333` => key id is: **234FAA343232333**) ### Set a gpg key for git ``` git config --global user.signingkey your_key_id ``` ### To sign a single commit ``` git commit -S -a -m "Test a signed commit" ``` ### Auto-sign all commits globaly ``` git config --global commit.gpgsign true ``` ### If your GPG Key has a passphrase Add this to your `~/.bashrc` or `~/.zshrc` or `powerlevel10k` config file ``` export GPG_TTY=$(tty) ``` Ref: https://github.com/keybase/keybase-issues/issues/2798 --- # Git lfs ```bash git clone --mirror ${BITBUCKET_REPO_URL} local_folder && pushd local_folder git lfs migrate import --everything --verbose --include="*.wav,*.psd,*.tif" git reflog expire --expire-unreachable=now --all && git gc --prune=now --aggressive git push --mirror ${GITHUB_REPO_URL} ``` --- # Clean Ceph from ProxmoxVE Node To clean Ceph from a ProxmoxVE node, follow these steps: 1. Stop all remaining Ceph services: ```bash systemctl stop ceph-mon.target systemctl stop ceph-mgr.target systemctl stop ceph-mds.target systemctl stop ceph-osd.target ``` 2. Avoid Ceph services being restarted by systemd the next boot by removing the following files: ```bash rm -rf /etc/systemd/system/ceph* ``` 2. Be sure that Ceph services are stopped by running the following command: ```bash killall -9 ceph-mon ceph-mgr ceph-mds ``` 3. Remove the following directories: ```bash rm -rf /var/lib/ceph/mon/ rm -rf /var/lib/ceph/mgr/ rm -rf /var/lib/ceph/mds/ ``` 3. Retry the Ceph purge: ```bash pveceph purge ``` 5. Finally, uninstall Ceph: ```bash apt purge ceph-mon ceph-osd ceph-mgr ceph-mds ``` This completes the process of cleaning Ceph from a ProxmoxVE node. Reference: 1. https://forum.proxmox.com/threads/how-to-clean-up-a-bad-ceph-config-and-start-from-scratch.68949/ --- # How to Import a Disk on Proxmox VM In Proxmox, importing a disk onto a virtual machine (VM) can only be done through the command line interface (CLI). This guide will walk you through the steps on how to import a disk onto a Proxmox VM. Please note that you need access to the command line interface (CLI) of Proxmox and a running virtual machine with the disk that you want to import. ## Prerequisites Before proceeding with the disk import process, make sure you have the following: - A Proxmox VE server with at least one VM configured and running - Access to the command line interface (CLI) of Proxmox. - A disk image file in one of the supported formats, such as qcow2, raw, vmdk, or vhd - Sufficient free disk space on the storage where you want to import the disk ## Importing a Disk on Proxmox VM Follow the steps below to import a disk on a Proxmox VM: 1. Open a shell session on the Proxmox server and log in as root. 2. Determine the ID of the VM that you want to import the disk onto by running the command below (Skip this step if you already know the VM ID): ```bash qm list ``` 3. Now Change directory to the directory where the disk image is stored and run the following command to import the disk image: ```bash qm disk import VMID disk_name storage_name --format format ``` :::info Replace the following variables in the command above: - `VMID` with the ID of the VM that you want to import the disk onto (e.g. 100) - `disk_name` with the name of the disk image file (e.g. disk1.qcow2) - `storage_name` with the name of the storage where you want to import the disk image file (e.g. local, nfs, or ceph) - `format` with the format of the disk image file (e.g. qcow2, raw, vmdk, or vhd) ::: For example, to import a disk named `vm-200-disk-0` from storage `local-lvm` to virtual machine with ID `200`, run the following command: ```bash qm disk import 200 vm-200-disk-0 local-lvm --format qcow2 ``` 4. Verify that the disk has been imported by running the following command: ```bash qm config VMID ``` :::info Replace the `VMID` variable in the command above with the ID of the VM that you want to import the disk onto (e.g. 100) ::: For example, to verify that the disk has been imported on VM with ID `200`, run the following command: ```bash qm config 200 ``` The output of the command above should show the disk that you just imported: ```bash ... scsi1: local-lvm:vm-200-disk-0,size=8G ... ``` 🎊 Congratulations! You have successfully imported a disk onto a Proxmox virtual machine. ## Attach the Disk to the VM To attach the disk to the VM, follow the steps below: 1. Open a shell session on the Proxmox server and log in as root. 3. Run the following command to attach the disk to the VM: ```bash qm set VMID --scsihw SCSI-HW --scsi0 STORAGE_TYPE:DISK-NAME,size=DISK-SIZE ``` :::info Replace the following variables in the command above: - `VMID` with the ID of the VM that you want to import the disk onto (e.g. 100) - `SCSI-HW` with the SCSI hardware type of the VM (e.g. lsi | lsi53c810 | megasas | pvscsi | virtio-scsi-pci | virtio-scsi-single> (default = lsi)) - `STORAGE_TYPE` with the type of storage where you want to import the disk image file (e.g. local, nfs, or ceph) - `DISK-NAME` with the name of the disk image file (e.g. vm-200-disk-0) - `DISK-SIZE` with the size of the disk image file (e.g. 8G) ::: You can also attach the disk using the Proxmox web interface. ## References - [Proxmox VE Documentation - qm(1)](https://pve.proxmox.com/pve-docs/qm.1.html) --- # How to Clean up Disk on Proxmox that are Throwing Error "Disk in Use" Proxmox is an open-source virtualization platform that allows you to create and manage virtual machines and containers. One common issue faced by users is the "Disk in Use" error when trying to clean up a disk. This error occurs when a device is still in use by the system, preventing you from removing or modifying it. In this guide, we will show you how to resolve this issue by using a few simple commands. ## Step 1: Check the Physical Volumes The first step is to check the physical volumes (PVs) of the disks. To do this, open a terminal on your Proxmox server and run the following command: ```bash pvs ``` If there are any physical volumes that are still in use, you will see an error message stating "File descriptor XX (pipe:[XXXXXX]) leaked on pvs invocation." and the output will look like this: ```bash PV VG Fmt Attr PSize PFree /dev/sda3 pve-OLD-2EC01C62 lvm2 a-- 1.09t 15.99g /dev/sdg3 pve lvm2 a-- 1.09t 16.00g ``` :::info In this example, the disk `"/dev/sda3"` is still in use. ::: ## Step 2: Remove the Volume Group The next step is to remove the volume group (VG) of the disk that is still in use. To do this, run the following command: ```bash vgremove ``` In our example, the command would be: ```bash vgremove pve-OLD-2EC01C62 ``` This command will remove the volume group and any logical volumes associated with it. Once this is done, you can proceed to remove the physical volume. ## Step 3: Remove the Logical Volumes After removing the volume group, you need to remove any logical volumes that are associated with it. To do this, run the following command: ```bash dmsetup ls ``` This command will list all the logical volumes currently in use. Look for the logical volume that corresponds to the disk you want to remove. In our example, the output would look like this: ```bash ceph--74481fa3--29b6--4637--8e7a--5beb59d19bb4-osd--block--671de3d2--8b37--41df--b614--c0941b8e645a (253:6) ceph--8b821916--8ea6--4391--9e2e--0a40d6edf530-osd--block--8e2e189b--ce22--4c13--a908--911044034f68 (253:0) ceph--d3e7bad5--8be0--41bf--b374--19d52750addd-osd--block--e235e5a3--9395--47e9--9460--ecfd35596f9a (253:8) ceph--e6545bfd--8b1f--4bd9--accd--dbae738fd29b-osd--block--c1a01ba3--1062--4b1f--a1a1--b5b5b5b5b5b5 (253:4) ``` This command lists all active device-mapper devices. In the output, you will see the names of the logical volumes. Identify the logical volumes that belong to the removed VG and remove them using the following command: ```bash dmsetup remove LV-name ``` Replace `LV-name` with the name of the logical volume that you want to remove. Repeat this command for all LVs that belong to the removed VG. Once you have removed all the problematic LVs, you can run the pvs command again to check if the issue has been resolved. ## Conclusion In this guide, we have learned how to clean up the disk on Proxmox that is throwing an error of being in use after a new installation. We identified the problematic VG and removed it, followed by removing all the associated LVs. By following these steps, you should be able to resolve the issue and use your Proxmox installation without any problems. ## Reference 1. https://forum.proxmox.com/threads/sda-has-a-holder.97771/ --- # Separate the proxmox cluster joined node without resinstall ### Separate a Node Without Reinstalling First, stop the corosync and pve-cluster services on the node: ```bash systemctl stop pve-cluster systemctl stop corosync ``` Start the cluster file system again in local mode: ```bash pmxcfs -l ``` Delete the corosync configuration files: ```bash rm /etc/pve/corosync.conf rm -r /etc/corosync/* ``` You can now start the file system again as a normal service: ```bash killall pmxcfs systemctl start pve-cluster ``` The node is now separated from the cluster. You can delete it from any remaining node of the cluster with: ```bash pvecm delnode oldnode ``` And then repeat the `pvecm delnode` command. Now switch back to the separated node and delete all the remaining cluster files on it. This ensures that the node can be added to another cluster again without problems. ```bash rm /var/lib/corosync/* ``` As the configuration files from the other nodes are still in the cluster file system, you may want to clean those up too. After making absolutely sure that you have the correct node name, you can simply remove the entire directory recursively from `/etc/pve/nodes/NODENAME`. ```bash rm -r /etc/pve/nodes/NODENAME ``` :::caution The node’s SSH keys will remain in the authorized_key file. This means that the nodes can still connect to each other with public key authentication. You should fix this by removing the respective keys from the /etc/pve/priv/authorized_keys file. ```bash ssh-keygen -R oldnodeip ``` ::: 🎉 Now you can add the node to another cluster again. Reference: 1. https://forum.proxmox.com/threads/proxmox-ve-6-removing-cluster-configuration.56259/ 2. https://pve.proxmox.com/pve-docs/pve-admin-guide.html#pvecm_separate_node_without_reinstall --- # Unlock Virtual Machine in Proxmox # How to Unlock a Virtual Machine in Proxmox ## Method 1: Using qm command 1. Log in to Proxmox host using SSH. 2. Identify the VM ID of the VM that needs to be unlocked. You can list all VMs by running `qm list`. 3. Unlock the VM by executing the following command: ```bash qm unlock {VM-ID} ``` 4. Verify that the VM is unlocked by running the command `qm list`. ## Method 2: Using Web Interface 1. Log in to the Proxmox web interface. 2. Navigate to the page for the VM that needs to be unlocked. 3. Click on the "Unlock" button. 4. Verify that the VM is unlocked by navigating to the same page. The "Unlock" button should be replaced by "Lock" button. ## Method 3: Manually deleting the lock 1. Log in to Proxmox host using SSH. 2. Identify the VM ID of the VM that needs to be unlocked. 3. Navigate to the directory `/var/lock/qemu-server/`. 4. Delete the lock file corresponding to the VM ID. The file will have the same name as the VM ID. 5. Verify that the VM is unlocked by running the command `qm list`. --- # ESXi Troubleshooting ### Changing from passthrough to non-passthrough devices fails to take effect after a reboot 1. Edit the `/etc/vmware/esx.conf` file by changing the owner of the PCI device from passthru to vmkernel. Example of the edit: Change from: `/device/000:02.0/owner = "passthru"` Change to: `/device/000:02.0/owner = "vmkernel"` Replace 000.02.0 with the PCI address of the device. You can it fro ESXi Dashboard. 2. Reboot the ESXi host. > Note: for some reason if the line is not there, adding it does not work. Ref.: https://www.reddit.com/r/vmware/comments/k7p6zc/unable_to_disable_passthrough_for_ehci_controllers/ --- # How to Detect browser tab state # How to Detect browser tab state import CodeBlock from '@theme/CodeBlock'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; {`window.addEventListener("blur", () => { // your logic for when user leaves the tab }); window.addEventListener("focus", () => { // your logic for when user is back to the tab again });`} The blur event fires when an element has lost focus. The main difference between this event and focusout is that focusout bubbles while blur does not. The opposite of blur is focus. The focus event fires when an element has received focus. {`document.addEventListener("visibilitychange", () => { // your logic to handle visible or hidden elements state });`} The visibilitychange event is fired at the document when the contents of its tab have become visible or have been hidden.

Examples

  1. Pausing music on transitioning to hidden

    This example begins playing a music track when the document becomes visible, and pauses the music when the document is no longer visible. {`document.addEventListener("visibilitychange", () => { if (document.visibilityState === 'visible') { backgroundMusic.play(); } if else (document.visibilityState === 'hidden') { backgroundMusic.pause(); } }); `}
Reference:{' '} Document - Web APIs | MDN{' '} {' '} --- # Generate SQL from migration files ## Use the migrate command You can add the --pretend flag when you run `php artisan migrate` to output the queries to the terminal: ```bash php artisan migrate --pretend ``` This will look something like this: ```bash Migration table created successfully. CreateUsersTable: create table "users" ("id" integer not null primary key autoincrement, "name" varchar not null, "email" varchar not null, "password" varchar not null, "remember_token" varchar null, "created_at" datetime not null, "updated_at" datetime not null) CreateUsersTable: create unique index users_email_unique on "users" ("email") CreatePasswordResetsTable: create table "password_resets" ("email" varchar not null, "token" varchar not null, "created_at" datetime not null) CreatePasswordResetsTable: create index password_resets_email_index on "password_resets" ("email") CreatePasswordResetsTable: create index password_resets_token_index on "password_resets" ("token") ``` ### To save this to a file, just redirect the output without ansi: ```bash php artisan migrate --pretend --no-ansi > migrate.sql ``` This command only include the migrations that hasn't been migrated yet. Reference: 1. https://stackoverflow.com/a/31263746/8374162 --- # PHP Troubleshooting #### Checking if php module is installed or not ```php php -r 'echo "imagick is ".(extension_loaded("imagick")?"":"not ")."installed\n";' ``` --- # React Basic ## Start a react boilerplate project ```bash npx create-react-app --template typescript ```