Borrowing a VLAN for Windows Tools That Need the Same L2
The problem is not that I cannot reach the devices, but that the program sends broadcast queries, and broadcasts do not travel across routers. The fix is therefore not to add more routes, but to put the one asking in the same network as the one answering.
I needed to use a camera manufacturer's device discovery tool, which only runs on Windows. Its job is to find newly unboxed devices that do not yet have usable IP addresses and configure them for the first time. The problem was that my workstation was somewhere else, away from the site. Even after connecting over a VPN and opening the program, I still got an empty screen without a single device, even though I could ping them all.
The IP addresses, hostnames, VLAN numbers, and passwords in this article are examples. The commands, configuration filenames, and symptoms are real, from machines I maintain myself.
Why devices are still invisible over a VPN
These programs do not discover devices by pinging each address in turn. They send out a broadcast query and wait for a reply, which is the only way to talk to devices whose IP addresses are not yet correct. But broadcasts belong to layer two; they do not cross routers. A VPN that assigns an IP address and routes traffic to the destination therefore does not help at all.
On the same L2 network
The computer and devices are in the same broadcast domain. The query reaches the devices, and their replies reach me. This works even when a device still has its factory IP address on a different subnet from mine.
Across L3, by any route
VPNs of any kind, routers, and port forwarding do not help, because what is missing is broadcast delivery, not a route. The destination may respond to ping, but the program still cannot find it.
The most direct fix is to put the computer running the program in that network. The site I maintain already had a Proxmox host in the same rack as the switch, connected to a trunk port carrying several VLANs. I therefore did not need any extra cabling, just a small Windows VM with its interface assigned to the right VLAN.
The advantage that made me choose this approach was that I did not have to touch a single switch port. No downtime requests, no risk of misconfiguring a VLAN and disconnecting an entire floor. Everything happens on the Proxmox host, and when I do not need the VM, I leave it shut down and start it when needed.
Make the bridge VLAN-aware first
The first requirement is that the bridge the VM attaches to must be vlan-aware and explicitly allow the VLANs that can pass through it. If I do not declare them and then set a tag on the VM, it stays silent: no error, but no traffic either.
# /etc/network/interfaces
auto vmbr0
iface vmbr0 inet static
address 192.168.10.6/24
gateway 192.168.10.1
bridge-ports bond0
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 20 30 99
bridge-vids is the list of allowed VLANs. When I added a new VLAN, I just appended its number to that line.
The familiar command after editing this file is ifreload -a, which brings the entire set of interfaces up again. Running VMs briefly lose network connectivity, and some do not recover on their own. I therefore only add entries without removing existing ones, back up the file every time, and wait for an agreed maintenance window before reloading, or for the node's next reboot if the work is not urgent.
cp /etc/network/interfaces /etc/network/interfaces.bak-vlan20
# แก้ไฟล์ แล้วตรวจไวยากรณ์ก่อน อย่าเพิ่ง reload
ifquery -a --check
# ดูว่า bridge ตอนนี้ยอมให้ VLAN ไหนผ่านบ้างจริงๆ
bridge vlan show dev bond0
Create the VM and put its interface in the required VLAN
The virtual machine does not need to be large. Device discovery tools use very few resources. What needs attention is that newer versions of Windows require TPM and UEFI boot.
qm create 102 --name win-l2tool --ostype win11 \
--memory 16384 --cores 8 --cpu host \
--bios ovmf --machine q35 \
--efidisk0 local-lvm:1,efitype=4m,pre-enrolled-keys=1 \
--tpmstate0 local-lvm:1,version=v2.0 \
--scsihw virtio-scsi-single \
--scsi0 local:64,discard=on,ssd=1 \
--net0 virtio,bridge=vmbr0,tag=20 \
--ide2 local:iso/windows.iso,media=cdrom \
--ide0 local:iso/virtio-win.iso,media=cdrom
qm start 102
The key is that single tag=20 setting. This VM's interface appears in VLAN 20 just as if a cable were plugged into an access port for that network. From the devices' perspective, there is no difference.
discard=on matters too; I explain why in the next section. And the virtio disc attached with --ide0 is not there for decoration.
Without knowing this beforehand, I would get stuck right at the start of installation, because the installer does not recognize virtio-scsi. I have to click Load driver and point it to the vioscsi folder for the matching version and architecture on the virtio disc before the disk appears. Then, after installation, on the first boot into Windows, there will still be no network adapter. I have to install the virtio guest tools from the same disc before there is an interface to use.
Verify that the VM's interface really is in that VLAN
I do not assume that configuring it means it works. Twice I have had commands succeed without the VLAN actually carrying traffic. Once I forgot to add the number to bridge-vids; the other time, the switch port connected to the node did not allow that VLAN through the trunk. From inside the VM, both cases look exactly the same: an interface is present, but nobody replies.
# ฝั่ง Proxmox: ดูว่า tag ที่ตั้งไว้ตรงกับที่ตั้งใจ
qm config 102 | grep -E '^net|^scsi'
# ดูว่า tap ของ VM ตัวนี้ถูกผูกกับ VLAN ไหนจริง
bridge vlan show | grep -A2 "tap102"
# ดูว่า bridge ยอมให้ VLAN นั้นผ่านฝั่ง uplink ด้วยไหม
bridge vlan show dev bond0 | grep -w 20
If all three commands show matching settings and there is still silence, I go down to the packet level. The quickest way is to capture whatever arrives at the VM's tap interface. If it is completely silent, the problem is upstream, not in the VM.
# ดักดู ARP กับ broadcast ที่เข้าถึงขาของ VM ตัวนี้
tcpdump -ni tap102i0 -e 'arp or broadcast' -c 20
# เทียบกับที่วิ่งอยู่บน uplink ของโหนด กรองเฉพาะ VLAN ที่สนใจ
tcpdump -ni bond0 -e vlan 20 -c 20
Traffic visible at bond0 but not at tap102i0 means the problem is in my bridge. Traffic visible at both, with the program still unable to find devices, means the devices themselves are not replying; it is no longer a network problem. No traffic at either means the switch is not sending that VLAN through, and I need to talk to whoever manages the switch.
When these programs find nothing, they provide no explanation, just an empty screen, which is useless for troubleshooting. I therefore always scan the whole network with ARP using standard tools first. If the scan shows the device's MAC address, layer two connectivity is working, leaving only the program itself to investigate. Separating these two issues from the start can save half a day.
The most expensive trap is in storage, not the network
When I created this VM, it nearly took down other production VMs because the thin pool ran out of space.
A thin pool allocates storage flexibly. Each VM sees a disk of the configured size, but only consumes physical space as it writes data. That is great for planning, but it means the total allocated capacity can exceed the physical space available. And when it actually fills up, the result is not just an inability to create new VMs: running VMs suddenly encounter I/O errors.
# ดูว่า thin pool ใช้ไปเท่าไหร่แล้ว ดูคอลัมน์ Data%
lvs -a
# ยังมีที่เหลือใน volume group ให้ขยายไหม
vgs
# ขยาย pool ถ้ายังมีที่เหลือ
lvextend -L +15G /dev/pve/data
I managed to expand it by 15 GB, leaving just 1 GB in the volume group. That meant no further expansion, so I had to reclaim space instead. The easiest things to reclaim were forgotten ISO files and disks left behind by deleted VMs. Deleting those two types of leftovers recovered over ten gigabytes.
The largest allocation, consuming 307 GB and unavailable to reclaim, was the disk of a VM created without discard enabled. Space deleted from the filesystem inside the VM was therefore never reported back to the pool as reclaimable. The fix was to enable discard, run fstrim inside, and reboot that VM. Since it was a production machine, I had to wait for a maintenance window agreed with the service owner. It ended up staying on my to-do list.
When creating a new VM, include discard=on and ssd=1 from the start. This does not cause a significant slowdown on SSDs, but allows space deleted inside the VM to actually return to the pool. The setting can be changed later, but it requires a VM reboot, which means scheduling downtime for a production machine. Getting it right on day one costs much less.
Set up IP and RDP before closing the console
Nobody will be sitting at this VM's screen, so I need to make sure RDP works before closing the console. I have made the mistake of closing it first and then being unable to connect, which meant reopening the console and clicking through the whole setup again.
# ตั้ง IP คงที่ในวงของ VLAN นั้น อย่าปล่อย DHCP ลอย
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.20.50 `
-PrefixLength 24 -DefaultGateway 192.168.20.1
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 192.168.20.1
# เปิด RDP แล้วเปิดช่องในไฟร์วอลล์ของ Windows ให้เฉพาะวงที่ใช้เข้า
Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\Terminal Server" `
-Name fDenyTSConnections -Value 0
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
Get-NetFirewallRule -DisplayGroup "Remote Desktop" |
Set-NetFirewallRule -RemoteAddress 192.168.10.0/24
Do not skip the last line. It restricts which networks RDP accepts connections from. Otherwise, I have just placed a Windows machine with broadly accessible RDP in the camera network, which was deliberately isolated to improve security.
On the Proxmox side, I also configure it not to start automatically when the node restarts, because I intend to keep it shut down by default.
qm set 102 --onboot 0 # ไม่ต้องขึ้นมาเองตอนโหนดบูต
qm set 102 --description "เครื่องมือ L2 เปิดเฉพาะตอนใช้ ปิดทุกครั้งที่เสร็จ"
qm start 102 && sleep 60 && qm status 102
qm shutdown 102 # สั่งปิดแบบสุภาพ ไม่ใช่ qm stop
Accessing the VM and getting files out
- Give the VM a reserved IP address instead of leaving it to a changing DHCP assignment, because I will always connect over RDP and do not want to hunt for its address each day.
- Enable RDP in Windows and create an account dedicated to this task, with a password not used elsewhere, stored in a password manager.
- Connect to the VM through RDP as usual. Use the Proxmox web console to watch it boot or when RDP is unavailable.
- Run the device discovery program there, finish the work that requires L2 access, and shut down the VM when it is no longer needed.
- For files that need to come out, use RDP drive sharing and copy them through
\\tsclient\C\..., without uploading them anywhere else.
That last point is a small tip, but it helps a lot. The Proxmox web console cannot copy text or files out. If I connect that way and need to retrieve results, I have to retype them or photograph the screen, which is ridiculous. With RDP and drive sharing enabled, I can drag files straight out.
What I have just done is put a Windows machine in a deliberately isolated network, which really does reduce that isolation. My rules are therefore to shut down the VM when it is not in use, install only necessary software, use a separate account from other machines, update it before each use, and record it in the inventory. The most dangerous machine of this kind is the one everyone has forgotten is still running.
Personally, I see this approach as suitable only for occasional work. For regular work that needs a constant presence in that network, a small physical machine on site with clear firewall rules would be easier to manage and audit. If there is no Proxmox host at the site, a small machine plugged into an access port for that network and accessed over RDP achieves the same result. Use what is available.
Still on my plan is a script that creates this VM in one command, sets the VLAN from an input value, and tracks how many hours it has been left running before reminding me to shut it down. If I have left anything out or made a typo, I will come back and correct it later.
Hit something like this? Stuck somewhere?
Come trade notes on the LinuxThai board



Comments 0
No comments yet — be the first