Skip to content

Instantly share code, notes, and snippets.

@TheSainEyereg
Last active January 3, 2026 20:41
Show Gist options
  • Select an option

  • Save TheSainEyereg/0c33562960ec0bd67eb658f3b65bf6a3 to your computer and use it in GitHub Desktop.

Select an option

Save TheSainEyereg/0c33562960ec0bd67eb658f3b65bf6a3 to your computer and use it in GitHub Desktop.

Revisions

  1. TheSainEyereg revised this gist Sep 23, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions pterodactyl-upnp.sh
    Original file line number Diff line number Diff line change
    @@ -21,7 +21,7 @@ res=$(curl -s "$PANEL_URL/api/application/nodes/$NODE_ID/allocations" \
    function processRow() {
    ip=$1
    alias=$2
    assigned=$3
    assigned=$3
    port=$4
    }

    @@ -40,7 +40,7 @@ jq -r ".data[].attributes | {ip, alias, assigned, port} | map(.) | @sh" <<< "$re
    label="$ip:$port ($alias)"
    echo "$label is assigned"

    first_word=$(echo "$alias" | awk '{print $1}')
    first_word=$(awk '{print $1}' <<< "$alias")
    if [[ "$first_word" == "TCP" || "$first_word" == "UDP" ]]; then
    proto_array=("$first_word")
    else
  2. TheSainEyereg revised this gist Sep 23, 2025. 1 changed file with 9 additions and 3 deletions.
    12 changes: 9 additions & 3 deletions pterodactyl-upnp.sh
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ PANEL_URL="https://panel.example.com"
    API_KEY="YOUR_TOKEN" # Application API key with read access to allocations
    NODE_ID=1

    IGNORE_ALIAS=("dummy") # array of ignored aliases
    IGNORE_ALIAS=("ignore" "local") # array of ignored aliases
    IGNORE_IP=("127.0.0.1") # array of ignored allocations

    UPNP_DURATION=600 # 10 minutes
    @@ -38,10 +38,16 @@ jq -r ".data[].attributes | {ip, alias, assigned, port} | map(.) | @sh" <<< "$re

    if [[ $assigned == "true" ]]; then
    label="$ip:$port ($alias)"

    echo "$label is assigned"

    for proto in "TCP" "UDP"; do
    first_word=$(echo "$alias" | awk '{print $1}')
    if [[ "$first_word" == "TCP" || "$first_word" == "UDP" ]]; then
    proto_array=("$first_word")
    else
    proto_array=("TCP" "UDP")
    fi

    for proto in "${proto_array[@]}"; do
    upnpc -e "[ptero-upnp] $proto $label" -a $LOCAL_IP $port $port $proto $UPNP_DURATION | tail -n 1
    done
    fi
  3. TheSainEyereg created this gist Sep 20, 2025.
    11 changes: 11 additions & 0 deletions pterodactyl-upnp.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    # Bash script for opening assigned Pterodactyl/Pelican allocation ports via UPnP

    ## Requirements
    - Application API key with read acces to allocations
    - Node ID

    ## How to
    1. Place `pterodactyl-upnp.sh` file to the same system Wings is running on
    0. Edit the `PANEL_URL`, `API_KEY`, `NODE_ID` variables, as well as additional ones if necessary.
    0. `chmod +x pterodactyl-upnp.sh`
    0. Create a cron job to run the script periodically. Note that run interval needs to be smaller than `UPNP_DURATION` as this is time after which port will be closed
    48 changes: 48 additions & 0 deletions pterodactyl-upnp.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,48 @@
    #!/usr/bin/env bash

    PANEL_URL="https://panel.example.com"
    API_KEY="YOUR_TOKEN" # Application API key with read access to allocations
    NODE_ID=1

    IGNORE_ALIAS=("dummy") # array of ignored aliases
    IGNORE_IP=("127.0.0.1") # array of ignored allocations

    UPNP_DURATION=600 # 10 minutes

    set -e

    LOCAL_IP=$(ip route show | head -n 1 | awk '{print $9}')

    res=$(curl -s "$PANEL_URL/api/application/nodes/$NODE_ID/allocations" \
    --request "GET" \
    --header "Accept: application/json" \
    --header "Authorization: Bearer $API_KEY")

    function processRow() {
    ip=$1
    alias=$2
    assigned=$3
    port=$4
    }

    jq -r ".data[].attributes | {ip, alias, assigned, port} | map(.) | @sh" <<< "$res" | while read row; do
    eval processRow $row

    if [[ " ${IGNORE_ALIAS[@]} " =~ " ${alias} " ]]; then
    continue
    fi

    if [[ " ${IGNORE_IP[@]} " =~ " ${ip} " ]]; then
    continue
    fi

    if [[ $assigned == "true" ]]; then
    label="$ip:$port ($alias)"

    echo "$label is assigned"

    for proto in "TCP" "UDP"; do
    upnpc -e "[ptero-upnp] $proto $label" -a $LOCAL_IP $port $port $proto $UPNP_DURATION | tail -n 1
    done
    fi
    done