# Virtual Personal Network (VPN)

# OpenVPN



# OpenVPN client on OpenWRT

```
install \
    openvpn-openssl \
    luci-app-openvpn
```

navigate to
```
https://(openwrt)/cgi-bin/luci/admin/vpn/openvpn
```

# OPNsense



# Update and/or upgrade of OPNsense in GCP

## Considerations:
Time: from v24 to v25 it took around two-three hours to complete upgrades.

## Prepare
Console
```bash
gcloud config set disable_usage_reporting true
gcloud config set accessibility/screen_reader false

gcloud auth login
? gcloud auth login --no-browser
gcloud auth list
gcloud config set account (account)

gcloud projects list
gcloud config set project (project)
gcloud config list project

gcloud compute regions list
gcloud config set compute/region europe-north1

gcloud compute zones list
gcloud config set compute/zone europe-north1-c


```

## Backup
Take a snapshot
```bash
gcloud compute disks list
? gcloud compute disks list --filter="users:instance='gcp1fw1'" --zone=europe-north1-c
# no dots allowed in the name
gcloud compute snapshots create gcp1fw1-2025-05-03-1256 --source-disk='gcp1fw1' 
gcloud compute snapshots list
```

## Perform update
This can be performed over WebUI or CLI:

### WebUI
screenshots here



### CLI
Connect to OPNsense console (in my case, I do it from jumphost within GCP)
```bash
ssh root@10.166.0.x
```
Choose ```8) Shell```
```bash
# Unlock to permit updates
opnsense-update -U

uname -a
opnsense-version
# seelct and update base
opnsense-update -b
opnsense-update -B
# select and update kernel
opnsense-update -k
opnsense-update -K

? pkg clean -a
? pkg update -f
pkg upgrade -n
pkg upgrade
opnsense-shell reboot
? reboot


pkg info


# Lock to avoid updates
opnsense-update -L
```

After







## Clean
```bash
gcloud compute snapshots list
gcloud compute snapshots delete gcp1fw1-2025-05-03-1256
gcloud compute snapshots list
```





## for archive
ASCII logo changed
```
Last login: Mon Apr  7 15:23:47 2025 from 10.166.0.x
----------------------------------------------
|      Hello, this is OPNsense 25.1          |         @@@@@@@@@@@@@@@
|                                            |        @@@@         @@@@
| Website:     https://opnsense.org/         |         @@@\\\   ///@@@
| Handbook:    https://docs.opnsense.org/    |       ))))))))   ((((((((
| Forums:      https://forum.opnsense.org/   |         @@@///   \\\@@@
| Code:        https://github.com/opnsense   |        @@@@         @@@@
| Reddit:      https://reddit.com/r/opnsense |         @@@@@@@@@@@@@@@
----------------------------------------------
```
to
```

Last login: Sat May  3 14:05:23 2025 from 10.166.0.x
------------------------------------------------
|       Hello, this is OPNsense 25.1           |           :::::::.
|                                              |           :::::::::.
|  Website:     https://opnsense.org/          |        :::        :::
|  Handbook:    https://docs.opnsense.org/     |        :::        :::
|  Forums:      https://forum.opnsense.org/    |        :::        :::
|  Code:        https://github.com/opnsense    |         `:::::::::
|  Reddit:      https://reddit.com/r/opnsense  |           `:::::::
------------------------------------------------
```

# Determine the best server for OPNsense updates and upgrades

Wherever you are on the planet, there is a need to determine, which server out of many is accessible and which has the lowest latency.

Let's create a mirros list

```bash
vi mirrors.list
```
Mirrors (this one was reverse engineered from official OPNsense page)
```list
https://ftp.cc.uoc.gr/mirrors/opnsense/
https://mirror-opnsense.serverbase.ch/
https://mirror.aarnet.edu.au/pub/opnsense/
https://mirror.ams1.nl.leaseweb.net/opnsense/
https://mirror.catalyst.net.nz/opnsense/
https://mirror.cedia.org.ec/opnsense/
https://mirror.cloudfence.com.br/opnsense/
https://mirror.cs.odu.edu/opnsense/
https://mirror.distly.kr/opnsense
https://mirror.dns-root.de/opnsense/
https://mirror.eliv.digital/opnsense/
https://mirror.fra10.de.leaseweb.net/opnsense/
https://mirror.hemino.net/opnsense/
https://mirror.init7.net/opnsense/
https://mirror.keiminem.com/opnsense/
https://mirror.koreapixel.kr/opnsense/
https://mirror.krfoss.org/opnsense/
https://mirror.leitecastro.com/opnsense/
https://mirror.level66.network/opnsense-dist/
https://mirror.marwan.ma/opnsense/
https://mirror.meowsmp.net/opnsense/
https://mirror.mtl2.ca.leaseweb.net/opnsense/
https://mirror.ntct.edu.tw/opnsense/
https://mirror.pangkin.com/opnsense/
https://mirror.raiolanetworks.com/opnsense/
https://mirror.serverion.com/opnsense/
https://mirror.sfo12.us.leaseweb.net/opnsense/
https://mirror.techlabs.co.kr/opnsense/
https://mirror.ueb.edu.ec/opnsense/
https://mirror.uvensys.de/opnsense/
https://mirror.venturasystems.tech/opnsense/
https://mirror.verinomi.com/opnsense/
https://mirror.vraphim.com/opnsense/
https://mirror.wdc1.us.leaseweb.net/opnsense/
https://mirror.winsub.kr/opnsense/
https://mirror.zyner.org/mirror/opnsense/
https://mirror.zzunipark.com/opnsense/
https://mirror1.isatisidc.ir/opnsense/
https://mirrors.dotsrc.org/opnsense/
https://mirrors.hopbox.net/opnsense/
https://mirrors.komogoto.com/opnsense/
https://mirrors.nycbug.org/pub/opnsense/
https://mirrors.ocf.berkeley.edu/opnsense/
https://mirrors.pku.edu.cn/opnsense/
https://opnsense-mirror.hiho.ch/
https://opnsense.aivian.org/
https://opnsense.c0urier.net/
https://opnsense.org/download/
https://pkg.opnsense.org/
https://www.mirrorservice.org/sites/opnsense.org/
```

Once that done, let's create a script to ping all of them

```bash
vi url-speed-rank.sh
```
bash code
```bash
#!/usr/bin/env bash
# url-speed-rank.sh
# Combines:
#  - ICMP RTT average per host (ping)
#  - HTTP(S) total time per URL (curl)
# Outputs a sorted table + summary with the fastest N URLs (default 3).

set -o pipefail

VERBOSE=0
TOPN=3

# Ping knobs
PING_COUNT=3
PING_TIMEOUT=1   # seconds (best-effort portable)

# Curl knobs
CURL_TIMEOUT=5  # seconds

usage() {
  cat >&2 <<EOF
Usage: $0 [-v] [-n TOPN] [-c PING_COUNT] [-p PING_TIMEOUT] [-t CURL_TIMEOUT] <urls_file>

  -v              verbose progress (stderr)
  -n TOPN         how many fastest URLs to summarize (default: ${TOPN})
  -c PING_COUNT   ping packets per host (default: ${PING_COUNT})
  -p PING_TIMEOUT ping timeout per packet, seconds (default: ${PING_TIMEOUT})
  -t CURL_TIMEOUT curl max time per URL, seconds (default: ${CURL_TIMEOUT})

Input file:
  - one URL/host per line
  - empty lines and lines starting with # are ignored
  - if scheme missing, https:// is assumed
EOF
  exit 1
}

log() { [[ "$VERBOSE" -eq 1 ]] && echo "$*" >&2; }

while getopts ":vn:c:p:t:" opt; do
  case "$opt" in
    v) VERBOSE=1 ;;
    n) TOPN="$OPTARG" ;;
    c) PING_COUNT="$OPTARG" ;;
    p) PING_TIMEOUT="$OPTARG" ;;
    t) CURL_TIMEOUT="$OPTARG" ;;
    *) usage ;;
  esac
done
shift $((OPTIND - 1))

INPUT="$1"
[[ -z "$INPUT" ]] && usage
[[ ! -r "$INPUT" ]] && { echo "Error: cannot read file '$INPUT'" >&2; exit 1; }

tmp_urls="$(mktemp)"
tmp_hosts="$(mktemp)"
tmp_ping="$(mktemp)"
tmp_results="$(mktemp)"

cleanup() { rm -f "$tmp_urls" "$tmp_hosts" "$tmp_ping" "$tmp_results"; }
trap cleanup EXIT

# 1) Normalize input → list of URLs (deduped)
#    - skip empty/comments
#    - prepend https:// if missing scheme
awk '
  /^[[:space:]]*$/ { next }
  /^[[:space:]]*#/ { next }
  {
    gsub(/^[[:space:]]+|[[:space:]]+$/, "", $0)
    url=$0
    if (url !~ /^https?:\/\//) url="https://" url
    if (!seen[url]++) print url
  }
' "$INPUT" > "$tmp_urls"

TOTAL_URLS="$(wc -l < "$tmp_urls" | tr -d ' ')"
[[ "$TOTAL_URLS" -eq 0 ]] && { echo "No URLs to test (after filtering comments/empty lines)." >&2; exit 1; }

# 2) Extract unique hosts from URLs
#    host = strip scheme, then cut at first /, :, ?, #
sed -E 's|^[a-zA-Z]+://||; s|[/?#].*$||; s|:.*$||' "$tmp_urls" | sort -u > "$tmp_hosts"

# 3) Ping each host once → avg RTT (ms) or 999999 on failure
ping_avg_ms() {
  local host="$1"
  local out

  # Try Linux-style first, then alternate (some environments differ).
  if out="$(ping -c "$PING_COUNT" -W "$PING_TIMEOUT" "$host" 2>/dev/null)"; then
    :
  elif out="$(ping -c "$PING_COUNT" -t "$PING_TIMEOUT" "$host" 2>/dev/null)"; then
    :
  else
    echo "999999"
    return 0
  fi

  # Linux: "rtt min/avg/max/mdev = 10.1/11.2/..."
  # macOS: "round-trip min/avg/max/stddev = 10.1/11.2/..."
  awk -F'/' '/round-trip|rtt/ {print $5; found=1} END{ if(!found) print "999999" }' <<<"$out"
}

log "[*] Pinging hosts ($(wc -l < "$tmp_hosts" | tr -d ' ') unique) ..."
while IFS= read -r host; do
  [[ -z "$host" ]] && continue
  log "    ping: $host"
  avg="$(ping_avg_ms "$host")"
  printf "%s\t%s\n" "$host" "$avg" >> "$tmp_ping"
done < "$tmp_hosts"

# 4) Test each URL with curl → time_total + http_code; join ping by host
log "[*] Curling URLs (${TOTAL_URLS}) ..."
while IFS= read -r url; do
  log "    curl: $url"

  host="$(sed -E 's|^[a-zA-Z]+://||; s|[/?#].*$||; s|:.*$||' <<<"$url")"
  ping_ms="$(awk -F'\t' -v h="$host" '$1==h{print $2; found=1} END{if(!found) print "999999"}' "$tmp_ping")"

  # We capture both time_total and http_code. On hard error, curl prints nothing; treat as failure.
  curl_out="$(curl \
    --silent \
    --output /dev/null \
    --location \
    --max-time "$CURL_TIMEOUT" \
    --write-out "%{time_total}\t%{http_code}" \
    "$url" 2>/dev/null || true)"

  curl_time="$(awk -F'\t' '{print $1}' <<<"$curl_out")"
  http_code="$(awk -F'\t' '{print $2}' <<<"$curl_out")"

  if [[ -z "$curl_time" || "$curl_time" == "0.000"* ]]; then
    curl_time="999.999"
    http_code="${http_code:-000}"
    status="FAIL"
  else
    # Consider 2xx/3xx as OK
    if [[ "$http_code" =~ ^2|^3 ]]; then
      status="OK"
    else
      status="HTTP_$http_code"
    fi
  fi

  # Sort key first (curl seconds), then printable columns
  # Columns: CURL_S  PING_MS  HTTP  STATUS  URL
  printf "%08.3f\t%10.2f\t%3s\t%-8s\t%s\n" \
    "$curl_time" "$ping_ms" "$http_code" "$status" "$url" >> "$tmp_results"
done < "$tmp_urls"

# 5) Print ranked table
echo
echo "Ranked (fastest → slowest) by HTTP total time:"
printf "%-10s %-10s %-4s %-8s %s\n" "CURL_S" "PING_MS" "HTTP" "STATUS" "URL"
printf "%-10s %-10s %-4s %-8s %s\n" "------" "-------" "----" "------" "---"
sort -n "$tmp_results" | awk -F'\t' '{printf "%-10s %-10s %-4s %-8s %s\n",$1,$2,$3,$4,$5}'

# 6) Summary stats + fastest TOPN URLs
echo
echo "Summary:"
unique_hosts="$(wc -l < "$tmp_hosts" | tr -d ' ')"
ping_fail_hosts="$(awk -F'\t' '$2>=999999 {c++} END{print c+0}' "$tmp_ping")"
curl_fail_urls="$(awk -F'\t' '$1>=999.999 || $4=="FAIL" {c++} END{print c+0}' "$tmp_results")"
ok_urls="$(awk -F'\t' '$4=="OK" {c++} END{print c+0}' "$tmp_results")"

# Average curl time across successful URLs (status OK)
avg_ok_curl="$(awk -F'\t' '$4=="OK"{sum+=$1; n++} END{ if(n) printf "%.3f", sum/n; else print "n/a" }' "$tmp_results")"

echo "  URLs tested:           $TOTAL_URLS"
echo "  Unique hosts:          $unique_hosts"
echo "  OK URLs (2xx/3xx):     $ok_urls"
echo "  Curl failures/timeout: $curl_fail_urls"
echo "  Ping failures:         $ping_fail_hosts"
echo "  Avg curl time (OK):    ${avg_ok_curl}s"

echo
echo "Fastest ${TOPN} URL(s) to use for update fetching (by HTTP total time):"
sort -n "$tmp_results" | head -n "$TOPN" | awk -F'\t' '{printf "  %s  (curl=%ss, ping=%sms, http=%s, %s)\n",$5,$1,$2,$3,$4}'
```


Make executale
```bash
chmod +x ./url-speed-rank.sh
```

And run it
```bash
./url-speed-rank.sh -v mirrors.list
```

Results:

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/s pS8yKNK62YGtaw5z-image-1775619083551.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/pS8yKNK62YGtaw5z-image-1775619083551.png)



Let's see result more closer

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/87fYjU2o4GeubS0u-image-1775619215979.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/87fYjU2o4GeubS0u-image-1775619215979.png)

First column indicates what time it took to load the webpage,
There are hosts with 999999 ms of ping , which simply means ICMP is not permitted.
Hosts with codes 404 are empty or incorrect.


Short summary in the end gives an idea, which mirrors to focus on


Same script can be used to determine any other mirrors' list reachability.

Let's perform manual verification

```bash
curl https://mirror.verinomi.com/opnsense/
```
Page is accessible, good.
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/k8VyLn0nTK9PLISn-image-1775619537707.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/k8VyLn0nTK9PLISn-image-1775619537707.png)






On the day of writing (2026-04-08), current major version is 26 running on FreeBSD v14

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/4b91AwzQDXPuguXK-image-1775619611555.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/4b91AwzQDXPuguXK-image-1775619611555.png)


Let's check that mirror will have recent upgrades available on that paricular mirror


This tells me, that packages are two weeks old, which is good.

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/Jcchflwe7Pt7Srl3-image-1775619801082.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/Jcchflwe7Pt7Srl3-image-1775619801082.png)


Some servers are located on CDN and protected, might be challenge to reach them or opposite (that depends on the region).

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/8Dh5qnnRn57LZVZt-image-1775620017110.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/8Dh5qnnRn57LZVZt-image-1775620017110.png)


To configure selected server, navigate to System, Firmware, Settings, Mirror, choose (custom) from dropdown, type the server URL

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/zvB2Nke3tc4Js4Mn-image-1775620219196.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/zvB2Nke3tc4Js4Mn-image-1775620219196.png)



Back to Status page will indicate that repository mirror is successfully configured

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/zDta1M4aLp71DwWZ-image-1775620288869.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/zDta1M4aLp71DwWZ-image-1775620288869.png)


Should see dialog with fetching the packages and back to the Status, timestamp for latest update should be changed

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/LyWqzdfv008fHMhz-image-1775620352538.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/LyWqzdfv008fHMhz-image-1775620352538.png)

Once you see newer base is available and packages will be upgraded, it is a good sign

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/Wdb6z6g3qMsrMkk8-image-1775620475186.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/Wdb6z6g3qMsrMkk8-image-1775620475186.png)

Upgrade itself

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/dZDiz2ENGSojEz4Y-image-1775620515062.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/dZDiz2ENGSojEz4Y-image-1775620515062.png)


System config has an option to restart server, once upgraded, once that is enable, it will restart

After reboot.

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/gf8Ikb2oaxYSiqZO-image-1775620740952.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/gf8Ikb2oaxYSiqZO-image-1775620740952.png)




Nothing to update. Good.


[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/Zfgit29Euo8ueTQt-image-1775620873005.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/Zfgit29Euo8ueTQt-image-1775620873005.png)

# IPSEC



# Obtain and activate free 3DES-AES license for Cisco ASA5505 from Cisco?

Get free license from Cisco

Proceed with normal registration to get Cisco ID. 

```url
https://software.cisco.com/software/swift/lrp/#/pak
```

Add device

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-10/scaled-1680-/4GJGwS0qfAwakwre-image-1760030242714.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-10/4GJGwS0qfAwakwre-image-1760030242714.png)

Choose in 'Product Family'

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-10/scaled-1680-/ZKOw7u1f1hRrTVMH-image-1760030314229.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-10/ZKOw7u1f1hRrTVMH-image-1760030314229.png)

Enter serial

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-10/scaled-1680-/r7jftJUNUqrKUAty-image-1760030484544.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-10/r7jftJUNUqrKUAty-image-1760030484544.png)

or

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/scaled-1680-/3taY6subV0HSC3b1-image-1758306524577.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/3taY6subV0HSC3b1-image-1758306524577.png)

Enter serial

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/scaled-1680-/uPD3nuvodbB7HbEt-image-1758306734256.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/uPD3nuvodbB7HbEt-image-1758306734256.png)

Approve agreement


[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/scaled-1680-/SqAtwgqNEL9mrQpM-image-1758306845627.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/SqAtwgqNEL9mrQpM-image-1758306845627.png)

Add device

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/scaled-1680-/EjcOzvlplmfsHjxz-image-1758307595131.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/EjcOzvlplmfsHjxz-image-1758307595131.png)

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/scaled-1680-/eU1b9qfJYjSegPVr-image-1758307556546.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/eU1b9qfJYjSegPVr-image-1758307556546.png)

Download licenses

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/scaled-1680-/cA4Wzn8nuVARv7NQ-image-1758307667508.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/cA4Wzn8nuVARv7NQ-image-1758307667508.png)

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/scaled-1680-/mqwOePUNxzPPgkLJ-image-1758307723615.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/mqwOePUNxzPPgkLJ-image-1758307723615.png)

Unpack archive

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/scaled-1680-/c9EGt0boJD0DJcxc-image-1758307871648.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2025-09/c9EGt0boJD0DJcxc-image-1758307871648.png)

Activate license on the device
```cisco
activation key xxx xxx xxx xxx xxx
```

Enable SSH version 2 immedeately
```cisco
ssh version 2
wr m
```