Skip to main content

Commands

cli

cli öffnet die eigentliche Switch-CLI, also die FastPath-/Switching-Ebene.

Dort arbeitest du mit Dingen wie:

show vlan
show running-config
configure
interface 0/1
switchport mode access
vlan database
write memory

Das ist die Cisco-ähnliche Oberfläche für:

  • VLANs
  • Ports
  • Trunks
  • Layer-2/teilweise Layer-3
  • laufende Switch-Konfiguration

Das Problem: Diese CLI verwaltet hauptsächlich den laufenden FastPath-Zustand. write memory meldet zwar Erfolg, aber die UniFi-Firmware baut FastPath beim Start wieder aus /tmp/system.cfg beziehungsweise der von ubntconf erzeugten Startup-Konfiguration auf. Deshalb verschwinden die Änderungen nach einem Reboot.




mca-cli-op

mca-cli-op gehört zur UniFi-Management-Ebene.

Auf deinem Switch ist es nur ein Symlink:

/usr/bin/mca-cli-op -> mcad

Es startet also das Programm mcad in einem speziellen Betriebsmodus.

mcad kümmert sich um Dinge wie:

  • Adoption
  • Controller-Kommunikation
  • Inform-Nachrichten
  • Provisionierung
  • Managementstatus
  • Werksreset
  • Speichern und Laden von UniFi-Konfiguration
  • mgmt.is_default
  • mgmt.is_setup_completed

Mit Argumenten wird es normalerweise als interner Einzelbefehl verwendet, zum Beispiel:

mca-cli-op inform
mca-cli-op set-inform http://controller:8080/inform
mca-cli-op set-default

Der Firmware-Wrapper ruft solche Befehle selbst auf. set-inform wird beispielsweise direkt an mca-cli-op weitergereicht, während set-default einen Werksreset einleitet.

Ohne Argument:

mca-cli-op

öffnet es die interaktive Management-CLI:

UniFi#

Das ist keine Linux-Shell und auch nicht dieselbe CLI wie cli. Deshalb kennt sie kein echo, awk, find oder Shell-Pipes.

Vereinfacht dargestellt

SSH-Shell
│
├── cli
│   └── FastPath-Switch-CLI
│       ├── VLANs
│       ├── Ports
│       ├── Trunks
│       └── running-config
│
└── mca-cli-op / mcad
    └── UniFi-Management-Stack
        ├── Adoption
        ├── Provisionierung
        ├── Controller/Inform
        ├── mgmt-Konfiguration
        └── Default-/Setup-Status


USW-Pro-48-US.7.5.6# mca-cli-op help 2>&1
UniFi Command Line Interface - Ubiquiti Networks

   info                      display device information
   set-default               restore to factory default
   set-inform <inform_url>   attempt inform URL (e.g. set-inform http://192.168.0.8:8080/inform)
   upgrade <firmware_url>    upgrade firmware (e.g. upgrade http://192.168.0.8/unifi_fw.bin)
   fwupdate --url <firmware_url|firmware_name> [--dl-only] [--md5sum <sum_of_fw>]
            [--keep-firmware] [--keep-running] [--reboot-sys] 
                                   new firmware update command
   reboot                    reboot the device

USW-Pro-48-US.7.5.6# printf 'Rückgabecode: %s\n' "$?"
Rückgabecode: 0
USW-Pro-48-US.7.5.6# mca-cli-op info

Model:       USW-Pro-48
Version:     7.5.6.17090
MAC Address: f4:e2:c6:c0:ec:22
IP Address:  172.16.1.22
Hostname:    USW-Pro-48
Uptime:      3893 seconds
NTP:         Not synchronized

Status:      Unable to resolve (http://unifi:8080/inform)
USW-Pro-48-US.7.5.6# echo '=== Managementwerte ==='
=== Managementwerte ===
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# for datei in \
>     /tmp/system.cfg \
>     /tmp/default.cfg \
>     /etc/persistent/cfg/mgmt
> do
>     if [ -r "$datei" ]; then
>         echo
>         echo "--- $datei ---"
> 
>         awk -F= '
>             $1 == "mgmt.is_default" ||
>             $1 == "mgmt.is_setup_completed" ||
>             $1 == "mgmt.cfgversion" ||
>             $1 == "mgmt.selfrun" ||
>             $1 ~ /^mgmt\.servers\.[0-9]+\.url$/ ||
>             $1 ~ /^mgmt\.led_/ {
>                 printf "%d: %s\n", NR, $0
>             }
>         ' "$datei"
>     else
>         echo
>         echo "--- $datei fehlt oder ist nicht lesbar ---"
>     fi
> done

--- /tmp/system.cfg ---
2: mgmt.is_default=true

--- /tmp/default.cfg ---
2: mgmt.is_default=true

--- /etc/persistent/cfg/mgmt fehlt oder ist nicht lesbar ---
USW-Pro-48-US.7.5.6# 

USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# awk '
> {
>     text[NR] = $0
> }
> 
> /set_cfg_save/ {
>     for (nummer = NR - 15; nummer <= NR + 20; nummer++) {
>         if (nummer > 0) {
>             zeigen[nummer] = 1
>         }
>     }
> }
> 
> END {
>     for (nummer = 1; nummer <= NR; nummer++) {
>         if (zeigen[nummer]) {
>             printf "%5d: %s\n", nummer, text[nummer]
>         }
>     }
> }
> ' /usr/etc/syswrapper.sh
 1030:          export SSH_CLIENT=""
 1031:          export UI_SSH_SAFE_CONTEXT="$LOG $TAIL_PID"
 1032:          setsid "$SCRIPT" "$cmd" "$@" >>$LOG 2>&1 </dev/null 3<&- &
 1033:          wait $TAIL_PID
 1034:          cat <&3 # Dump anything that tail might have missed
 1035:          exit 0
 1036:  fi
 1037: 
 1038:  set -- $UI_SSH_SAFE_CONTEXT
 1039:  [ $# -eq 2 ] || return
 1040:  local LOG=$1
 1041:  local TAIL_PID=$2
 1042:  local CLEAN_UP="kill $TAIL_PID 2>/dev/null; rm -f $LOG"
 1043:  trap "$CLEAN_UP; exit 0" HUP INT QUIT TERM EXIT
 1044: }
 1045: set_cfg_save() {
 1046:  if [ ! -e "$NEED_CFG_SAVE_FILE" ]; then
 1047:          log "Creating $NEED_CFG_SAVE_FILE"
 1048:          touch "$NEED_CFG_SAVE_FILE"
 1049:  fi
 1050: 
 1051:  pidof $SYSMON || syswrapper.sh cfg_save_check
 1052: 
 1053:  state_reload
 1054: }
 1055: 
 1056: # mac2serial <mac>
 1057: mac2serial() {
 1058:  echo $1 | sed -e 's/://g' -e 'y/ABCDEF/abcdef/'
 1059: }
 1060: 
 1061: # pkill_generic <process_name> [signal] [args]
 1062: pkill_generic() {
 1063:  local process=$1
 1064:  local signal=$2
 1065:  shift; shift;
 2975:  if type 'is_support_stacking' 2> /dev/null | grep -q 'function' && is_support_stacking ; then
 2976:          role="$(swctrl mgmt stack-info | sed -n 's/role=\([a-z]*\),.*/\1/p')"
 2977: 
 2978:          if [ "$role" = "controller" ]; then
 2979:                  log "[Stack] $cmd remote unit $unit_number"
 2980:                  swctrl mgmt stack-run -b "$unit_number" "syswrapper.sh $cmd"
 2981:          fi
 2982:  fi
 2983:  ;;
 2984: set-etherlight-mode)
 2985:  exit_if_busy $cmd $*
 2986:  exit_if_state_lock_failed $cmd $*
 2987:  _set_etherlight_mode "$1"
 2988:  rc=$?
 2989:  if [ $rc -eq 1 ]; then
 2990:          set_cfg_save
 2991:  fi
 2992:  state_unlock
 2993:  ;;
 2994: set-stack-unit-etherlight-mode)
 2995:  exit_if_busy $cmd $*
 2996:  exit_if_state_lock_failed $cmd $*
 2997:  _set_etherlight_mode "$1"
 2998:  rc=$?
 2999:  if [ $rc -eq 1 ]; then
 3000:          set_cfg_save
 3001:  fi
 3002:  state_unlock
 3003:  ;;
 3004: set-etherlight-device-type)
 3005:  exit_if_busy $cmd $*
 3006:  exit_if_state_lock_failed $cmd $*
 3007:  pkill_generic led_locate.sh -f
 3008: 
 3009:  led_device_type_mode=3
 3010:  _set_etherlight_mode $led_device_type_mode
 3011:  _set_port_bitmap_color $led_device_type_mode $@
 3012: 
 3013:  state_unlock
 3014:  ;;
 3015: set-port-locate)
 3016:  exit_if_busy $cmd $*
 3017:  exit_if_state_lock_failed $cmd $*
 3018:  pkill_generic led_locate.sh -f
 3019: 
 3020:  led_port_locate_mode=4
 3136:  if [ "$2" = "nopersist" ]; then
 3137:          persist=0
 3138:          log "[apply-config] persist=false - config will not be saved to flash"
 3139:  fi
 3140:  state_lock
 3141:  before=$(sed "s/\..*//" /proc/uptime)
 3142:  before_mca_pid=$(cat_file /var/run/mcad.0.pid)
 3143:  full_provision=0
 3144:  if ! do_fast_apply; then
 3145:          lockfile_retry 60 "$NEED_CFG_SAVE_LOCK_FILE" || exit 1
 3146:          full_provision=1
 3147:          /usr/etc/rc.d/rc restart
 3148:          unlockfile "$NEED_CFG_SAVE_LOCK_FILE"
 3149:  fi
 3150:  if [ "$persist" = 1 ]; then
 3151:          pidof $SYSMON && set_cfg_save
 3152:  fi
 3153:  state_reload
 3154:  now=$(sed "s/\..*//" /proc/uptime)
 3155:  delta=$((now - before))
 3156:  log "Provision took $delta sec, full=$full_provision, persist=$persist"
 3157:  # Remove deltas that may be due to time syncs, etc.
 3158:  if [ "$delta" -ge 0 -a "$delta" -lt 300 ]; then
 3159:          if [ "$full_provision" = 1 ]; then
 3160:                  add_stat /var/run/provision_time.total $delta
 3161:                  add_stat /var/run/provision_time.count 1
 3162:          else
 3163:                  add_stat /var/run/fast_apply_time.total $delta
 3164:                  add_stat /var/run/fast_apply_time.count 1
 3165:          fi
 3166:  fi
 3167:  # Update fw auto-rollback flag based on controller config
 3168:  # Default is enabled — only disable when explicitly set to "disabled"
 3169:  if [ "$(get_config_value /tmp/system.cfg switch.fw_auto_rollback.status)" = "disabled" ]; then
 3170:          touch /var/run/fw_auto_rollback_disabled
 3171:  else
 3195:  if [ ! -f /tmp/previous.cfg ]; then
 3196:          log "[apply-previous-config] previous.cfg not found, skipping rollback"
 3197:          state_unlock
 3198:          exit 1
 3199:  fi
 3200:  log "[apply-previous-config] reverting to previous configuration"
 3201:  cp -f /tmp/previous.cfg /tmp/system.cfg
 3202:  before=$(sed "s/\..*//" /proc/uptime)
 3203:  full_provision=0
 3204:  if ! do_fast_apply; then
 3205:          lockfile_retry 60 "$NEED_CFG_SAVE_LOCK_FILE" || exit 1
 3206:          full_provision=1
 3207:          /usr/etc/rc.d/rc restart
 3208:          unlockfile "$NEED_CFG_SAVE_LOCK_FILE"
 3209:  fi
 3210:  pidof $SYSMON && set_cfg_save
 3211:  state_reload
 3212:  now=$(sed "s/\..*//" /proc/uptime)
 3213:  delta=$((now - before))
 3214:  log "[apply-previous-config] Rollback took $delta sec, full=$full_provision"
 3215:  state_unlock
 3216:  ;;
 3217: apply-stack-unit-config)
 3218:  run_ssh_safe "$@"
 3219:  if type 'is_support_stacking' 2> /dev/null | grep -q 'function' && is_support_stacking ; then
 3220:          unit="$1"
 3221:          systemcfg_path="$2"
 3222:          role="$(swctrl mgmt stack-info | sed -n 's/role=\([a-z]*\),.*/\1/p')"
 3223:          before=$(sed "s/\..*//" /proc/uptime)
 3224:          STACKING_PATH="/tmp/stacking"
 3225: 
 3226:          if [ ! -f "$systemcfg_path" ]; then
 3227:                  log "[error] Configuration file not found: $systemcfg_path."
 3228:                  exit 1
 3229:          fi
 3230: 
 3269:          /bin/sh /var/run/if_up_hook.$ifname
 3270:  fi
 3271:  ;;
 3272: soft-restart)
 3273:  exit_if_busy $cmd $*
 3274:  run_ssh_safe "$@"
 3275:  state_lock
 3276:  lockfile_retry 30 "$NEED_CFG_SAVE_LOCK_FILE" || exit 1
 3277:  /usr/etc/rc.d/rc restart
 3278:  unlockfile "$NEED_CFG_SAVE_LOCK_FILE"
 3279:  state_reload
 3280:  state_unlock
 3281:  ;;
 3282: save-config)
 3283:  state_lock
 3284:  set_cfg_save
 3285:  state_unlock
 3286:  ;;
 3287: reload)
 3288:  exit_if_busy $cmd $*
 3289:  exit_if_state_lock_failed $cmd $*
 3290:  state_reload
 3291:  state_unlock
 3292:  ;;
 3293: set-ready)
 3294:  # called by mcagent
 3295:  state_lock
 3296:  set_state_ready
 3297:  state_unlock
 3298:  # Mark boot as successful for auto-rollback (once per boot)
 3299:  if [ ! -f /var/run/boot_success_marked ] && [ -x /sbin/ubntbox ] && \
 3300:     grep -q "ubnt_active_slot=" /proc/cmdline 2>/dev/null; then
 3301:          ubntbox bootsel mark-success && touch /var/run/boot_success_marked
 3302:  fi
 3303:  # Update fw auto-rollback flag based on controller config
 3304:  # Default is enabled — only disable when explicitly set to "disabled"
 3656:  ble_stp $@
 3657:  ;;
 3658: ble-check)
 3659:  ble_check $@
 3660:  ;;
 3661: kick-sta)
 3662:  kick_sta $1
 3663:  ;;
 3664: kick-sta-on)
 3665:  kick_sta_on $2 $1 $3
 3666:  ;;
 3667: block-sta)
 3668:  driver_kick_block_sta $1
 3669:  add_mac /etc/persistent/cfg/blocked_sta "$1"
 3670:  state_lock
 3671:  set_cfg_save
 3672:  state_unlock
 3673:  ;;
 3674: unblock-sta)
 3675:  del_mac /etc/persistent/cfg/blocked_sta "$1"
 3676:  driver_unblock_sta $1
 3677:  state_lock
 3678:  set_cfg_save
 3679:  state_unlock
 3680:  ;;
 3681: apply-blocked-sta)
 3682:  driver_apply_blocklist
 3683:  ;;
 3684: apply-blocked-sta-ifup)
 3685:  driver_apply_blocklist_ifup $1
 3686:  ;;
 3687: redirector-init)
 3688:  guest_redirector_init_iptables "$@"
 3689:  ;;
 3690: redirector-deinit)
 3691:  guest_redirector_deinit_iptables "$@"
 3692:  ;;
 3693: authorize-guest)
 3694:  guest_authorize "$@"
 3695:  ;;
 3696: unauthorize-guest)
 3697:  guest_unauthorize "$@"
 3698:  kick_sta $1
USW-Pro-48-US.7.5.6#

Das ist der bisher wichtigste Fund. Die Firmware besitzt tatsächlich einen vorgesehenen internen Speicherweg:

syswrapper.sh save-config
        ↓
set_cfg_save
        ↓
/var/run/need_cfg_save
        ↓
sysmon
        ↓
syswrapper.sh cfg_save_check
        ↓
sanitize_cfg
        ↓
cfgmtd -w -p /etc /tmp/system.cfg

save-config ist also etwas anderes als FastPaths write memory. Es speichert die UniFi-Systemkonfiguration, aus der beim Boot anschließend /tmp/.startup-config für den Switch erzeugt wird. Genau diese Bootkette wurde in deinen bisherigen Tests sichtbar.

Der Haken bleibt: cfg_save_check schreibt nur, wenn nach sanitize_cfg eine nichtleere Datei /etc/persistent/cfg/mgmt existiert. Ohne sie versucht es lediglich, eine alte Managementdatei aus dem Flash wiederherzustellen.

USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# rm -rf /tmp/usw-flash-read
USW-Pro-48-US.7.5.6# mkdir -p /tmp/usw-flash-read
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# cfgmtd -r \
>     -p /tmp/usw-flash-read \
>     -f /tmp/usw-flash-read/system.cfg

USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# printf 'cfgmtd Rückgabecode: %s\n' "$?"
cfgmtd Rückgabecode: 0
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo

USW-Pro-48-US.7.5.6# echo '=== Gelesene Dateien ==='
=== Gelesene Dateien ===
USW-Pro-48-US.7.5.6# find /tmp/usw-flash-read \
>     -maxdepth 4 \
>     -type f \
>     -exec ls -l {} \;
-rw-------    1 ui       admin         1018 Jun 22 10:03 /tmp/usw-flash-read/system.cfg
-rw-------    1 ui       admin           83 Jan  1  1970 /tmp/usw-flash-read/persistent/dropbear_ed25519_host_key
-rw-------    1 ui       admin           89 Jan  1  1970 /tmp/usw-flash-read/persistent/dropbear_ed25519_host_key.pub
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo

USW-Pro-48-US.7.5.6# echo '=== Managementdatei ==='
=== Managementdatei ===
USW-Pro-48-US.7.5.6# if [ -r /tmp/usw-flash-read/persistent/cfg/mgmt ]; then
>     awk -F= '
>         $1 == "mgmt.is_default" ||
>         $1 == "mgmt.is_setup_completed" ||
>         $1 == "mgmt.cfgversion" ||
>         $1 == "mgmt.selfrun" ||
>         $1 ~ /^mgmt\.servers\.[0-9]+\.url$/ ||
>         $1 ~ /^mgmt\.led_/ {
>             printf "%d: %s\n", NR, $0
>         }
>     ' /tmp/usw-flash-read/persistent/cfg/mgmt
> else
>     echo 'Keine persistente Managementdatei im gelesenen Flash-Stand'
> fi
Keine persistente Managementdatei im gelesenen Flash-Stand
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo

USW-Pro-48-US.7.5.6# echo '=== Managementwerte aus system.cfg ==='
=== Managementwerte aus system.cfg ===
USW-Pro-48-US.7.5.6# if [ -r /tmp/usw-flash-read/system.cfg ]; then
>     awk -F= '
>         $1 == "mgmt.is_default" ||
>         $1 == "mgmt.is_setup_completed" ||
>         $1 == "mgmt.cfgversion" ||
>         $1 == "mgmt.selfrun" ||
>         $1 ~ /^mgmt\.servers\.[0-9]+\.url$/ ||
>         $1 ~ /^mgmt\.led_/ {
>             printf "%d: %s\n", NR, $0
>         }
>     ' /tmp/usw-flash-read/system.cfg
> else
>     echo 'Keine system.cfg gelesen'
> fi
2: mgmt.is_default=true
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# rm -rf /tmp/usw-mgmt-runtime-test
USW-Pro-48-US.7.5.6# mkdir -p /tmp/usw-mgmt-runtime-test
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# if [ -d /etc/persistent/cfg ]; then
>     cp -a /etc/persistent/cfg /tmp/usw-mgmt-runtime-test/cfg.before
> else
>     echo 'cfg war nicht vorhanden' > /tmp/usw-mgmt-runtime-test/cfg-was-missing
> fi
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# mkdir -p /etc/persistent/cfg
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# cat > /etc/persistent/cfg/mgmt <<'EOF'
> mgmt.is_default=false
> mgmt.is_setup_completed=true
> EOF
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# chmod 600 /etc/persistent/cfg/mgmt
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo '=== Angelegte Laufzeitdatei ==='
=== Angelegte Laufzeitdatei ===
USW-Pro-48-US.7.5.6# cat /etc/persistent/cfg/mgmt
mgmt.is_default=false
mgmt.is_setup_completed=true
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo

USW-Pro-48-US.7.5.6# echo '=== Interner Adoptionstest ==='
=== Interner Adoptionstest ===
USW-Pro-48-US.7.5.6# /sbin/syswrapper.sh check-is-adopted
sh: false: unknown operand
USW-Pro-48-US.7.5.6# printf 'Rückgabecode: %s\n' "$?"
Rückgabecode: 2
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo

USW-Pro-48-US.7.5.6# echo '=== Laufzeitstatus ==='
=== Laufzeitstatus ===
USW-Pro-48-US.7.5.6# printf 'IsDefault='
IsDefault=USW-Pro-48-US.7.5.6# cat /proc/ubnthal/status/IsDefault
true
USW-Pro-48-US.7.5.6# printf 'LED-Pattern='
LED-Pattern=USW-Pro-48-US.7.5.6# cat /proc/gpio/led_pattern
2
USW-Pro-48-US.7.5.6#

Der Fehler kommt nicht von deiner mgmt-Datei. Der Firmware-Code ist schlicht schlampig geschrieben:


[ $(get_fw_env is_default) = false -o $(get_mgmt_cfg mgmt.is_default) = false ]

Da get_fw_env is_default auf diesem Switch leer zurückkommt, entsteht sinngemäß:


[ = false -o false = false ]

BusyBox antwortet darauf mit:


sh: false: unknown operand

Die Funktion check-is-adopted ist auf diesem Modell also kaputt, weil Ubiquiti Variablen nicht in Anführungszeichen gesetzt hat. Ein Klassiker: Milliardenunternehmen, Shellcode wie aus einem Freitagnachmittag.

IsDefault=true und LED-Muster 2 bleiben zunächst unverändert, weil das Anlegen der Datei den laufenden mcad-Status nicht automatisch neu lädt.

Die Ausgabe zeigt etwas Wichtiges: state_reload() liest nur /proc/ubnthal/status/IsDefault. Unsere neue mgmt-Datei wird dabei gar nicht beachtet. Deshalb bleiben LED-Muster 2 und IsDefault=true unverändert.

Offiziell ist für UniFi-Switches nur die Adoption über UniFi Network dokumentiert; einen unterstützten Standalone-Modus beschreibt Ubiquiti nur für bestimmte andere Geräteklassen. Wir arbeiten hier also bewusst unterhalb der offiziell vorgesehenen Verwaltungsschicht.

Jetzt machen wir einen automatisch rückgängig gemachten Laufzeittest. Er schreibt nichts in den Flash und stellt IsDefault nach 45 Sekunden wieder auf den bisherigen Wert zurück:

NODE=/proc/ubnthal/status/IsDefault

cat "$NODE" > /tmp/isdefault.before

setsid /bin/sh -c '
    sleep 45
    BEFORE="$(cat /tmp/isdefault.before 2>/dev/null)"
    [ -n "$BEFORE" ] || BEFORE=true
    printf "%s\n" "$BEFORE" > /proc/ubnthal/status/IsDefault
    /sbin/syswrapper.sh reload
' >/tmp/isdefault-restore.log 2>&1 </dev/null &

printf 'false\n' > "$NODE" || {
    echo 'IsDefault konnte nicht geschrieben werden'
    exit 1
}

/sbin/syswrapper.sh reload

echo '=== Testzustand ==='
printf 'IsDefault='
cat "$NODE"

printf 'LED-Pattern='
cat /proc/gpio/led_pattern

printf 'System-State='
cat /var/run/system.state 2>/dev/null || echo 'nicht vorhanden'

printf 'Uplink='
cat /var/run/system.uplink 2>/dev/null || echo 'nicht vorhanden'

  • write memory speichert die FastPath-CLI, hat auf diesem Modell aber bereits nachweislich keinen Reboot überlebt.
  • syswrapper.sh save-config speichert /tmp/system.cfg und /etc/persistent über cfgmtd.
  • Daraus folgt: Wenn die CLI-Änderungen nicht in /tmp/system.cfg übernommen werden, speichert save-config weiterhin den alten Defaultzustand. Die Firmware erzeugt beim Boot ihre FastPath-Konfiguration nämlich aus /tmp/system.cfg über ubntconf.


USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo '=== Gesicherte Portzustände ==='
=== Gesicherte Portzustände ===
USW-Pro-48-US.7.5.6# cat /tmp/usw-before-vlan-test/ports-before.txt
===== PORT 1 =====
                         Packets                  Bytes
Port(Phy)  Link  Rate    Receive   Transmit     Receive     Transmit   state    STP     1x Ctrl Mode  1x Status    Anomaly      LAG    
---------  ---- ------ ---------- ---------- ------------ ------------ ----- ---------- ------------ ------------ ------------ --------
   1(  1)  U/D      0H          0          0            0            0       disabled   unknown                   0x0                  



===== PORT 2 =====
                         Packets                  Bytes
Port(Phy)  Link  Rate    Receive   Transmit     Receive     Transmit   state    STP     1x Ctrl Mode  1x Status    Anomaly      LAG    
---------  ---- ------ ---------- ---------- ------------ ------------ ----- ---------- ------------ ------------ ------------ --------
   2(  2)  U/D      0H          0          0            0            0       disabled   unknown                   0x0                  



===== PORT 47 =====
                         Packets                  Bytes
Port(Phy)  Link  Rate    Receive   Transmit     Receive     Transmit   state    STP     1x Ctrl Mode  1x Status    Anomaly      LAG    
---------  ---- ------ ---------- ---------- ------------ ------------ ----- ---------- ------------ ------------ ------------ --------
  47( 47)  U/D      0H          0          0            0            0       disabled   unknown                   0x0                  



===== PORT 48 =====
                         Packets                  Bytes
Port(Phy)  Link  Rate    Receive   Transmit     Receive     Transmit   state    STP     1x Ctrl Mode  1x Status    Anomaly      LAG    
---------  ---- ------ ---------- ---------- ------------ ------------ ----- ---------- ------------ ------------ ------------ --------
  48( 48)  U/D      0H          0          0            0            0       disabled   unknown                   0x0                  



===== PORT 49 =====
                         Packets                  Bytes
Port(Phy)  Link  Rate    Receive   Transmit     Receive     Transmit   state    STP     1x Ctrl Mode  1x Status    Anomaly      LAG    
---------  ---- ------ ---------- ---------- ------------ ------------ ----- ---------- ------------ ------------ ------------ --------
  49( 49)  U/U  10000F      56743       4742      5468881       719162  N    forwarding unknown      disabled     0x0                  

Port state: Not auto negotiation


===== PORT 50 =====
                         Packets                  Bytes
Port(Phy)  Link  Rate    Receive   Transmit     Receive     Transmit   state    STP     1x Ctrl Mode  1x Status    Anomaly      LAG    
---------  ---- ------ ---------- ---------- ------------ ------------ ----- ---------- ------------ ------------ ------------ --------
  50( 50)  U/D  10000F          0          0            0            0  N    disabled   unknown                   0x0                  

Port state: Not auto negotiation


===== PORT 51 =====
                         Packets                  Bytes
Port(Phy)  Link  Rate    Receive   Transmit     Receive     Transmit   state    STP     1x Ctrl Mode  1x Status    Anomaly      LAG    
---------  ---- ------ ---------- ---------- ------------ ------------ ----- ---------- ------------ ------------ ------------ --------
  51( 51)  U/D  10000F          0          0            0            0  N    disabled   unknown                   0x0                  

Port state: Not auto negotiation


===== PORT 52 =====
                         Packets                  Bytes
Port(Phy)  Link  Rate    Receive   Transmit     Receive     Transmit   state    STP     1x Ctrl Mode  1x Status    Anomaly      LAG    
---------  ---- ------ ---------- ---------- ------------ ------------ ----- ---------- ------------ ------------ ------------ --------
  52( 52)  U/D  10000F          0          0            0            0  N    disabled   unknown                   0x0                  

Port state: Not auto negotiation


USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo

USW-Pro-48-US.7.5.6# echo '=== Aktuelle Managementdatei ==='
=== Aktuelle Managementdatei ===
USW-Pro-48-US.7.5.6# if [ -r /etc/persistent/cfg/mgmt ]; then
>     cat /etc/persistent/cfg/mgmt
> else
>     echo 'Keine Managementdatei vorhanden'
> fi
mgmt.is_default=false
mgmt.is_setup_completed=true
USW-Pro-48-US.7.5.6# 










USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# cli

Entering character mode
Escape character is '^]'.

Warning!
The changes may break controller settings and only be effective until reboot.

(UBNT) >ena

(UBNT) #conf

(UBNT) (Config)#vlan database

Incorrect input! Use 'vlan  <vlan-range | all>'.

(UBNT) (Config)#exit 

(UBNT) #vlan database 

(UBNT) (Vlan)#vlan name 20

Command not found / Incomplete command. Use ? to list commands.

(UBNT) (Vlan)#vlan 20

(UBNT) (Vlan)#vlan name 20 ESXi_Connection

(UBNT) (Vlan)#exit 

(UBNT) #show vlan brief

VLAN ID VLAN Name                        VLAN Type
------- -------------------------------- -------------------
1       default                          Default
20      ESXi_Connection                  Static

(UBNT) #
(UBNT) #vlan database

(UBNT) (Vlan)#
(UBNT) (Vlan)#vlan 40

(UBNT) (Vlan)#vlan name 40 Extern

(UBNT) (Vlan)#
(UBNT) (Vlan)#vlan 60

(UBNT) (Vlan)#vlan name 60 Drucker

(UBNT) (Vlan)#
(UBNT) (Vlan)#vlan 100

(UBNT) (Vlan)#vlan name 100 IoT

(UBNT) (Vlan)#
(UBNT) (Vlan)#vlan 300

(UBNT) (Vlan)#vlan name 300 Modem

(UBNT) (Vlan)#
(UBNT) (Vlan)#vlan 320

(UBNT) (Vlan)#vlan name 320 Escape

(UBNT) (Vlan)#
(UBNT) (Vlan)#exit

(UBNT) #show vlan brief

VLAN ID VLAN Name                        VLAN Type
------- -------------------------------- -------------------
1       default                          Default
20      ESXi_Connection                  Static
40      Extern                           Static
60      Drucker                          Static
100     IoT                              Static
300     Modem                            Static
320     Escape                           Static

(UBNT) #
(UBNT) #configure

(UBNT) (Config)#interface 0/1

(UBNT) (Interface 0/1)#switchport mode access

(UBNT) (Interface 0/1)#switchport access vlan 40

(UBNT) (Interface 0/1)#exit

(UBNT) (Config)#exit

(UBNT) #show running-config

!Current Configuration:
!
!System Description "USW-Pro-48, 7.5.6.17090, Linux 3.6.5"
!System Software Version "7.5.6.17090"
!System Up Time          "0 days 1 hrs 38 mins 3 secs"
!Additional Packages     QOS,IPv6 Management,Routing
!
network parms 172.16.1.22 255.240.0.0 0.0.0.0
snmp-server port 0
vlan database
vlan 20,40,60,100,300,320
vlan name 20 "ESXi_Connection"
vlan name 40 "Extern"
vlan name 60 "Drucker"
vlan name 100 "IoT"
vlan name 300 "Modem"
vlan name 320 "Escape"
exit

configure
dos-control port-ddisable


line console
exit

line telnet
exit

spanning-tree bpduguard
spanning-tree mode rstp
snmp-server sysname "USW-Pro-48"
!
set igmp known-multicast-proto flood none
set igmp reportforward lldp
no set igmp forward-unknown-rtr-ports
set mld reportforward lldp
no set mld forward-unknown-rtr-ports
ip dhcp snooping light
ip dhcp snooping vlan 1
keepalive

interface 0/1
description 'Port 1'
switchport mode access
switchport access vlan 40
vlan ingressfilter
port-security max-dynamic 0
keepalive action both
lldp transmit
lldp receive
lldp transmit-tlv port-desc
lldp transmit-tlv sys-name
lldp transmit-tlv sys-desc
lldp transmit-tlv sys-cap
lldp transmit-mgmt
lldp med
exit





LCM Screen

USW-Pro-48-US.7.5.6# echo '=== LCM-Dump ==='
=== LCM-Dump ===
USW-Pro-48-US.7.5.6# lcm-ctrl -t dump 2>&1
{
    "backlight": true,
    "brightness": 80,
    "burnin_touch_count": 0,
    "color_borders": "0x0139FF",
    "custom_event": false,
    "dfu": 10473,
    "fw_fallback_active": false,
    "fw_fallback_reason": "none",
    "fw_last_fail_ts": 0,
    "fw_log_level": 0,
    "fw_target_attempted_hash": "",
    "fw_target_attempted_version": "",
    "hash": "2252795598443a52f164e322c061dbf6",
    "hostname": "USW-Pro-48",
    "id": 3953,
    "idle": 12,
    "inform_url": "http://unifi:8080/inform",
    "ip": "172.16.1.22",
    "last_control_event": "",
    "last_sync_event": "",
    "main_dev": "eth0",
    "night_mode": false,
    "orientation": 0,
    "orientation_saved": 0,
    "rc": "ok",
    "screen": "throughput",
    "screen_changed_times": 54,
    "screen_sync": true,
    "screen_sync_count": 0,
    "sfp_idx": "49-52",
    "state": "ready",
    "test_touch_count": 0,
    "upgrade_fail": 0,
    "upgrade_good": 0,
    "upgrade_outer_rounds": 0,
    "uplink_port": 1,
    "uplink_rx_bytes": 0,
    "uplink_rx_r_bytes": 0,
    "uplink_tx_bytes": 0,
    "uplink_tx_r_bytes": 0,
    "uptime": 6798,
    "version": "v5.4.4-0-g9aa6f80"
}
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo

USW-Pro-48-US.7.5.6# echo '=== Relevante Funktionen im LCD-Dienst ==='
=== Relevante Funktionen im LCD-Dienst ===
USW-Pro-48-US.7.5.6# strings /bin/lcmd 2>/dev/null |
> awk '
> BEGIN {
>     IGNORECASE = 1
> }
> /throughput|uplink|port.*stat|stat.*port|rx.*rate|tx.*rate|stacking[.]ports|screen/ {
>     print
> }
> '
throughput
stacking.ports
screen
noscreen
Unsupport screen, cmd [%s...]
lcm_event_screen
Disabled screen sync and custom event, skip
screen.changed
Touch event, screen:%s timestamp:%.0lf
screensaver
ubnt_screen_wevent_send
Send lcm-sync wevent, screen:%s mac:%02x:%02x:%02x:%02x:%02x:%02x timestamp:%s
screen:%s mac:%02x:%02x:%02x:%02x:%02x:%02x timestamp:%s
rport.status
uplink-to-primary
update_uplink_port_id
is_lcm_screen_event_match
Reset uplink stat, uplink port %d -> port %d
     -b <0-100>         screen brightness
     -i <timeout>       screen idle timeout
     -s                 enable screen sync
get_lcm_screen_cmd not match %d %s
screen_sync
screen_changed_times
screen_sync_count
uplink_tx_bytes
uplink_rx_bytes
uplink_tx_r_bytes
uplink_rx_r_bytes
[stacking] stacking.ports: Failed to parse JSON: %s
[stacking] stacking.ports: Invalid or missing 'ports' array
[stacking] stacking.ports: Maximum port count reached
[stacking] stacking.ports: Invalid port data at index %zu
[stacking] stacking.ports: Parsed port[%d]: port_id=%u, status=%u
[stacking] stacking.ports: Updated %d stacking ports
[stacking] stacking.ports: %d stacking ports unchanged
[stacking] stacking.ports: No value provided
Disabled screen sync, skip
special case, screen:%s
Unknown special screen:%s
Unknown screen:%s
Sync event, screen:%s mac:%s timestamp:%.0lf
touchscreen.update.time
screen.timeout
/var/run/system.uplink_port
Failed to get uplink info
Failed to get port %d PoE stat
uplink.port
uplink.tx
uplink.rx
Send screen sync custom event, screen:%s timestamp:%s
Wrap %s signal from touch screen, exec syswrapper %s
Unable to set LCM screen caps
USW-Pro-48-US.7.5.6#



USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# echo '=== ubntconf-Schlüssel für LLDP, Discovery und sFlow ==='
=== ubntconf-Schlüssel für LLDP, Discovery und sFlow ===
USW-Pro-48-US.7.5.6# 
USW-Pro-48-US.7.5.6# for BIN in \
>     /sbin/ubntconf \
>     /usr/sbin/ubntconf \
>     /usr/bin/mcad \
>     /usr/sbin/mcad
> do
>     [ -r "$BIN" ] || continue
> 
>     echo
>     echo "=== $BIN ==="
> 
>     strings "$BIN" 2>/dev/null | awk '
>     {
>         text=tolower($0)
>     }
> 
>     text ~ /lldp|sflow|snmp|discovery|discoverable|10001|6343/ {
>         print
>     }
>     '
> done

=== /sbin/ubntconf ===
ubnt_get_lldp_info
ubnt_free_lldp_list
switch.lldp.status
switch.lldp.timer_interval
switch.lldpmed.opmode
switch.lldpmed.faststartrepeat
switch.lldpmed.topology_notify
switch.lldpmed.tlvs.%s
switch.lldpubnt.adopthelper.status
switch.lldpubnt.txtlvs.status
switch.snmp.status
switch.snmp.version
switch.snmp.contact
switch.snmp.location
switch.snmp.community.private.host
switch.snmp.community.public.name
switch.snmp.user.1.name
switch.snmp.user.1.password
switch.snmp.user.1.proto
switch.snmp.user.1.encrypt
switch.port.%d.lldpmed.opmode
switch.port.%d.lldpmed.tlvs.%s
switch.port.%d.lldpmed.topology_notify
switch.port.%d.lldp.opmode
switch.port.%d.lldpubnt.adopthelper.status
switch.port.%d.lldpubnt.txtlvs.status
snmp-server port 161
snmp-server port 0
snmp-server contact "%s"
no snmp-server contact
snmp-server location "%s"
no snmp-server location
no snmp-server community "private"
no snmp-server community "%s"
snmp-server community "private" rw ipaddress %s
snmp-server community "%s" ro
no snmp-server group "Ubnt" v3 priv
no snmp-server user "%s"
snmp-server group "Ubnt" v3 priv read "Default"
snmp-server user "%s" Ubnt %s "%s" %s "%s"
lldp timers interval %d
lldp med all
no lldp med all
lldp med faststartrepeatcount %d
no lldp med faststartrepeatcount
%slldp med confignotification all
%slldp ubnt adopt-header all
%slldp ubnt transmit-tlvs all
%sflowcontrol
%slldp transmit-tlv port-desc sys-name sys-desc sys-cap
%slldp transmit-mgmt
%slldp receive
%slldp transmit
lldp med
lldp med transmit-tlv ex-pse
no lldp med transmit-tlv ex-pse
no lldp med
%slldp med transmit-tlv capabilities
%slldp med transmit-tlv network-policy
%slldp med confignotification
%slldp med transmit-tlv ubnt-ex-pse
%slldp ubnt adopt-helper
%slldp ubnt transmit-tlvs
Usage: swctrl lldp show                 show lldp neighbors
where  FUNCTION  := { port | poe | env | mac | sfp | led | vlan | lldp | mgmt | relay }
where  FUNCTION  := { port | poe | env | mac | sfp | led | vlan | lldp | relay }
lldp
no snmp-server community "public"
lldp med confignotification all
lldp ubnt adopt-helper all
lldp ubnt transmit-tlvs all
lldp transmit-tlv port-desc sys-name sys-desc sys-cap
lldp transmit-mgmt
lldp transmit
lldp receive
lldp med confignotification
no lldp med transmit-tlv capabilities
no lldp med transmit-tlv network-policy
lldp med transmit-tlv ubnt-ex-pse
no lldp ubnt adopt-helper
no lldp ubnt transmit-tlvs
%s/snmpd.conf
        kill `pidof tinysnmpd`
/etc/snmp.conf
pidfile /var/run/snmpd.pid
snmp.listen
snmp.allow.
snmp.community
snmp.contact
snmp.location
/bin/tinysnmpd
/lib/tinysnmp
null::respawn:%s /etc/snmp.conf %s
snmp.status
snmpd
# Failed to apply snmp config: %d
lldpd.status
/bin/lldpd
lldpd.interface.
/etc/lldpd.conf
        sed -i '\`/bin/lldpd`d' %s
                killall lldpd
lldpd
lldpd.interface.%d.status
lldpd.poemdi.
lldpd.dot3poemdi.
lldpd.poemdi.status
/bin/lldpcli
lldpd.poemdi.type
lldpd.poemdi.source
lldpd.poemdi.value
lldpd.poemdi.priority
lldpd.dot3poemdi.status
lldpd.dot3poemdi.type
lldpd.dot3poemdi.suported
lldpd.dot3poemdi.enabled
lldpd.dot3poemdi.paircontrol
lldpd.dot3poemdi.powerpairs
lldpd.dot3poemdi.class
lldpd.dot3poemdi.powertype
lldpd.dot3poemdi.source
lldpd.dot3poemdi.priority
lldpd.dot3poemdi.requested
lldpd.dot3poemdi.allocated
        %s="$%s lldpd"
snmp
)(NATDISCOVERY)

=== /usr/sbin/ubntconf ===
ubnt_get_lldp_info
ubnt_free_lldp_list
switch.lldp.status
switch.lldp.timer_interval
switch.lldpmed.opmode
switch.lldpmed.faststartrepeat
switch.lldpmed.topology_notify
switch.lldpmed.tlvs.%s
switch.lldpubnt.adopthelper.status
switch.lldpubnt.txtlvs.status
switch.snmp.status
switch.snmp.version
switch.snmp.contact
switch.snmp.location
switch.snmp.community.private.host
switch.snmp.community.public.name
switch.snmp.user.1.name
switch.snmp.user.1.password
switch.snmp.user.1.proto
switch.snmp.user.1.encrypt
switch.port.%d.lldpmed.opmode
switch.port.%d.lldpmed.tlvs.%s
switch.port.%d.lldpmed.topology_notify
switch.port.%d.lldp.opmode
switch.port.%d.lldpubnt.adopthelper.status
switch.port.%d.lldpubnt.txtlvs.status
snmp-server port 161
snmp-server port 0
snmp-server contact "%s"
no snmp-server contact
snmp-server location "%s"
no snmp-server location
no snmp-server community "private"
no snmp-server community "%s"
snmp-server community "private" rw ipaddress %s
snmp-server community "%s" ro
no snmp-server group "Ubnt" v3 priv
no snmp-server user "%s"
snmp-server group "Ubnt" v3 priv read "Default"
snmp-server user "%s" Ubnt %s "%s" %s "%s"
lldp timers interval %d
lldp med all
no lldp med all
lldp med faststartrepeatcount %d
no lldp med faststartrepeatcount
%slldp med confignotification all
%slldp ubnt adopt-header all
%slldp ubnt transmit-tlvs all
%sflowcontrol
%slldp transmit-tlv port-desc sys-name sys-desc sys-cap
%slldp transmit-mgmt
%slldp receive
%slldp transmit
lldp med
lldp med transmit-tlv ex-pse
no lldp med transmit-tlv ex-pse
no lldp med
%slldp med transmit-tlv capabilities
%slldp med transmit-tlv network-policy
%slldp med confignotification
%slldp med transmit-tlv ubnt-ex-pse
%slldp ubnt adopt-helper
%slldp ubnt transmit-tlvs
Usage: swctrl lldp show                 show lldp neighbors
where  FUNCTION  := { port | poe | env | mac | sfp | led | vlan | lldp | mgmt | relay }
where  FUNCTION  := { port | poe | env | mac | sfp | led | vlan | lldp | relay }
lldp
no snmp-server community "public"
lldp med confignotification all
lldp ubnt adopt-helper all
lldp ubnt transmit-tlvs all
lldp transmit-tlv port-desc sys-name sys-desc sys-cap
lldp transmit-mgmt
lldp transmit
lldp receive
lldp med confignotification
no lldp med transmit-tlv capabilities
no lldp med transmit-tlv network-policy
lldp med transmit-tlv ubnt-ex-pse
no lldp ubnt adopt-helper
no lldp ubnt transmit-tlvs
%s/snmpd.conf
        kill `pidof tinysnmpd`
/etc/snmp.conf
pidfile /var/run/snmpd.pid
snmp.listen
snmp.allow.
snmp.community
snmp.contact
snmp.location
/bin/tinysnmpd
/lib/tinysnmp
null::respawn:%s /etc/snmp.conf %s
snmp.status
snmpd
# Failed to apply snmp config: %d
lldpd.status
/bin/lldpd
lldpd.interface.
/etc/lldpd.conf
        sed -i '\`/bin/lldpd`d' %s
                killall lldpd
lldpd
lldpd.interface.%d.status
lldpd.poemdi.
lldpd.dot3poemdi.
lldpd.poemdi.status
/bin/lldpcli
lldpd.poemdi.type
lldpd.poemdi.source
lldpd.poemdi.value
lldpd.poemdi.priority
lldpd.dot3poemdi.status
lldpd.dot3poemdi.type
lldpd.dot3poemdi.suported
lldpd.dot3poemdi.enabled
lldpd.dot3poemdi.paircontrol
lldpd.dot3poemdi.powerpairs
lldpd.dot3poemdi.class
lldpd.dot3poemdi.powertype
lldpd.dot3poemdi.source
lldpd.dot3poemdi.priority
lldpd.dot3poemdi.requested
lldpd.dot3poemdi.allocated
        %s="$%s lldpd"
snmp
)(NATDISCOVERY)

=== /usr/bin/mcad ===
ubnt_get_lldp_info
ubnt_free_lldp_list
ubnt_lldp_get_table
"op":"set-discovery_response"
"discovery_response":%d
set-discovery_response
discovery_establish
mgmt.discovery.status
[MCAD] Discovery Response %s
"msg":"Started ETH discovery beaconing on %s interface!"
"msg":"Stopped ETH discovery beaconing"
[MCAD] Discovery Response %s !
"msg":"discovery_response=%d"
lldp_table
WAN discovery and adoption are not possible due to incorrect network configuration!
Starting WAN discovery on the interface %u
Stopping WAN discovery on the interface %u

=== /usr/sbin/mcad ===
ubnt_get_lldp_info
ubnt_free_lldp_list
ubnt_lldp_get_table
"op":"set-discovery_response"
"discovery_response":%d
set-discovery_response
discovery_establish
mgmt.discovery.status
[MCAD] Discovery Response %s
"msg":"Started ETH discovery beaconing on %s interface!"
"msg":"Stopped ETH discovery beaconing"
[MCAD] Discovery Response %s !
"msg":"discovery_response=%d"
lldp_table
WAN discovery and adoption are not possible due to incorrect network configuration!
Starting WAN discovery on the interface %u
Stopping WAN discovery on the interface %u
USW-Pro-48-US.7.5.6#