{"id":19855,"date":"2024-12-19T13:12:45","date_gmt":"2024-12-19T18:12:45","guid":{"rendered":"https:\/\/nuxx.net\/blog\/?p=19855"},"modified":"2025-03-08T09:12:30","modified_gmt":"2025-03-08T14:12:30","slug":"bambu-lab-p1s-on-iot-vlan","status":"publish","type":"post","link":"https:\/\/nuxx.net\/blog\/2024\/12\/19\/bambu-lab-p1s-on-iot-vlan\/","title":{"rendered":"Bambu Lab P1S on IoT VLAN"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"alignright size-medium\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/PXL_20241218_194258392-scaled.jpeg\"><img loading=\"lazy\" decoding=\"async\" width=\"226\" height=\"300\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/PXL_20241218_194258392-226x300.jpeg\" alt=\"\" class=\"wp-image-19867\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/PXL_20241218_194258392-226x300.jpeg 226w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/PXL_20241218_194258392-771x1024.jpeg 771w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/PXL_20241218_194258392-768x1020.jpeg 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/PXL_20241218_194258392-1157x1536.jpeg 1157w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/PXL_20241218_194258392-1542x2048.jpeg 1542w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/PXL_20241218_194258392-scaled.jpeg 1928w\" sizes=\"auto, (max-width: 226px) 100vw, 226px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>I recently picked up a <a href=\"https:\/\/us.store.bambulab.com\/products\/p1s\">Bambu Lab P1S 3D Printer<\/a> for around the house. After staying away from 3D printing for years, the combination of a friend&#8217;s experience with this printer (thanks, <a href=\"https:\/\/www.instagram.com\/make_with_jake\/\">@make_with_jake<\/a>!), holiday sales, looking for a hobby, wanting some one-off tools, and a handful of projects where it&#8217;d be useful finally got me to buy one. Having done half a dozen prints, thus far I&#8217;m pretty satisfied with the output and think it&#8217;ll be a nice addition to the house.<\/p>\n\n\n\n<p>This printer, like many other modern devices, is an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Internet_of_things\">Internet of Things (IoT)<\/a> device; something smart which uses a network to communicate. Unfortunately, these can come with a bunch of security risks, and is best isolated to a less-trusted place on a home network. In my case, a separate network,or  <a href=\"https:\/\/en.wikipedia.org\/wiki\/VLAN\">VLAN<\/a>, called <code>IoT<\/code>.<\/p>\n\n\n\n<p>Beyond the typical good-practice of isolating IoT devices to a separate network, I&#8217;m also wary of cloud-connected devices because of the possibility of remote exploit or bugs. For example, <a href=\"https:\/\/blog.bambulab.com\/cloud-temporary-outage-investigation\/\">back in 2023 Bambu Lab themselves had an issue which resulted in old print jobs being started on cloud-connected printers<\/a>. Since these printers get hot and move without detecting if they are in a completely safe and ready-to-go state, this was bad. I&#8217;d rather avoid the chance of this. And really, when am I going to want to submit a print job from my phone or anywhere other than my home network?<\/p>\n\n\n\n<p>Bambu Lab has a <a href=\"https:\/\/wiki.bambulab.com\/en\/knowledge-sharing\/enable-lan-mode\">LAN Mode<\/a> available for their printers which ostensibly disconnects it from the cloud, but unfortunately it still expects everything to be on the same network.<\/p>\n\n\n\n<p>I was unable to find clear info on working around this in a simple fashion without extra utilities, but digging into and solving this kind of stuff is something I like to do. So this post documents how I put a <em>Bambu Lab P1S<\/em> on a separate VLAN from the house&#8217;s main network, getting it to work otherwise normally.<\/p>\n\n\n\n<p>The network here uses <a href=\"https:\/\/opnsense.org\/\">OPNsense<\/a>, a pretty typical open source firewall, so all the configuration mentioned revolves around it. <a href=\"https:\/\/www.pfsense.org\/\">pfSense<\/a> is similar enough that everything likely applies there as well, and the basic technical info can also be used to make this work on numerous other firewalls.<\/p>\n\n\n\n<p>As of this writing (2024-Dec-19), this works with <a href=\"https:\/\/bambulab.com\/en\/download\/studio\">Bambu Studio<\/a> v1.10.1.50 and firmware v01.07.00.00 on the P1S printer. This also works with <a href=\"https:\/\/github.com\/SoftFever\/OrcaSlicer\">OrcaSlicer<\/a> <a href=\"https:\/\/github.com\/SoftFever\/OrcaSlicer\/releases\/tag\/v2.2.0\">v2.2.0<\/a> and whatever version of the <em>Bambu Network Plug-in<\/em> it installs. I suspect this works for other <em>Bambu Lab<\/em> printers, as the <em>P1S<\/em> has all the same features as the higher end ones (eg: camera) but I can&#8217;t test to say for sure. Also, everything here covers the <em>P1S<\/em> running in <em>LAN Mode<\/em>. It&#8217;s possible that things would work differently with cloud connectivity, but I did not explore this. So, insert the standard disclaimer here about past performance and future results&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why can&#8217;t I just point the software at the printer?<\/h2>\n\n\n\n<p>To start, <a href=\"https:\/\/wiki.bambulab.com\/en\/software\/bambu-studio\/release\/release-note-1-10-0\">the release notes for Bambu Studio v1.10.0<\/a> have a section that says a printer can be added with just it&#8217;s IP, allowing it to cross networks:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>Subnet binding support: Users can now bind printers across different subnets by directly entering the printer&#8217;s IP address and Access Code<\/em><\/p>\n<\/blockquote>\n\n\n\n<p>This sounds like it&#8217;d solve the problem, and is a typical way for printers to work, but no&#8230; it just doesn&#8217;t work.<\/p>\n\n\n\n<p>Despite having the required <em>Studio<\/em> and printer firmware versions I just couldn&#8217;t make it work. When trying this feature I&#8217;d see <em>Bambu Studio<\/em> trying to connect to the printer on <code>3002\/tcp<\/code>, but the printer would only respond with a <code>RST<\/code> as if that port wasn&#8217;t listening. Something&#8217;s broken with this feature, probably in the printer firmware. Maybe this&#8217;ll work in the future, but for now we needed another way&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Atypical SSDP?<\/h2>\n\n\n\n<p>On a single network the printer sends out <a href=\"https:\/\/en.wikipedia.org\/wiki\/Simple_Service_Discovery_Protocol\">Simple Service Discovery Protocol (SSDP)<\/a>-ish messages detailing its specs, <em>Studio<\/em> receives these and lists the printer. But, SSDP is based on UDP broadcasts, so these don&#8217;t cross over to the other VLAN (subnet).<\/p>\n\n\n\n<p>The SSDP part of a packet looks similar to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>NOTIFY * HTTP\/1.1\\r\\n\nHOST: 239.255.255.250:1900\\r\\n\nServer: UPnP\/1.0\\r\\n\nLocation: 192.168.1.105\\r\\n\nNT: urn:bambulab-com:device:3dprinter:1\\r\\n\nUSN: xxxxxxxxxxxxxxx\\r\\n\nCache-Control: max-age=1800\\r\\n\nDevModel.bambu.com: C12\\r\\n\nDevName.bambu.com: Bambu Lab P1S\\r\\n\nDevSignal.bambu.com: -30\\r\\n\nDevConnect.bambu.com: lan\\r\\n\nDevBind.bambu.com: free\\r\\n\nDevseclink.bambu.com: secure\\r\\n\nDevVersion.bambu.com: 01.07.00.00\\r\\n\nDevCap.bambu.com: 1\\r\\n\n\\r\\n<\/code><\/pre>\n\n\n\n<p>When <em>Bambu Studio<\/em> receives this packet it gets the address (<code>Location:<\/code>) of the printer from the Location section, connects, and all works. But in a multi-VLAN environment we have different networks and different broadcast domains and a firewall in between, so we need two things to work around this: getting the SSDP broadcasts shared across networks, and firewall rules to allow the requisite communication.<\/p>\n\n\n\n<p>These also don&#8217;t seem to be normal SSDP packets, as they are sent to destination port <code>1910\/udp<\/code> or <code>2021\/udp<\/code>. It&#8217;s all just kinda weird&#8230; And <a href=\"https:\/\/forum.bambulab.com\/t\/use-ssdp-standards\/7173\/2\">this thread on the Bambu Lab Community Forum<\/a> makes it seem even stranger and like it might vary between printer models?<\/p>\n\n\n\n<p>Regardless, here&#8217;s how I made this work with the <em>P1S<\/em>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Static IP<\/h2>\n\n\n\n<p>The <em>P1S<\/em> (and I presume other <em>Bambu Lab<\/em> printers) have very little on-device network configuration, receiving network addressing from DHCP. I suggest that you set a DHCP reservation for your printer so that it always receives the same (static) IP address. This will make firewall rules much easier to manage.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">SSDP Broadcast Relay<\/h2>\n\n\n\n<p>To get the SSDP broadcasts passed between VLANs a bridge or relay is needed, and <a href=\"https:\/\/github.com\/marjohn56\/udpbroadcastrelay\">marjohn56\/udpbroadcastrelay<\/a> works great. This is available as a plugin in <em>OPNsense<\/em> under <em>System<\/em> \u2192 <em>Firmware<\/em> \u2192 <em>Plugins<\/em> \u2192 <em>os-udpbroadcastrelay<\/em>, is also available in <em>pfSense<\/em>, or could be run standalone if you use something else.<\/p>\n\n\n\n<p>After installing, on <em>OPNsense<\/em> go to <em>Services<\/em> \u2192 <em>UDP Broadcast Relay<\/em> and create a new entry with the following settings:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>enabled: <code>\u2713<\/code><\/li>\n\n\n\n<li>Relay Port: <code>2021<\/code><\/li>\n\n\n\n<li>Relay Interfaces: <code>IoT, LAN<\/code> (Choose each network you wish to bridge the printer between.)<\/li>\n\n\n\n<li>Broadcast Address: <code>239.255.255.250<\/code><\/li>\n\n\n\n<li>Source Address: <code>1.1.1.2<\/code> (This uses a special handler to ensure the packet reaches <em>Studio<\/em> in the expected form.)<\/li>\n\n\n\n<li>Instance ID: <code>1<\/code> (or higher, if you have more rules)<\/li>\n\n\n\n<li>Description: <code>Bambu Lab Printer Discovery<\/code><\/li>\n<\/ul>\n\n\n\n<p>On my OPNsense firewall, where <code>igb1_vlan2<\/code> is my IoT network and <code>igb1<\/code> is my LAN network, the running process looks like: <code>\/usr\/local\/sbin\/udpbroadcastrelay --id 1 --dev igb1_vlan2 --dev igb1 --port 2021 --multicast 239.255.255.250 -s 1.1.1.2 -f<\/code><\/p>\n\n\n\n<p>(Of course, in the event you have any firewall rules preventing packets from getting from the printer or IoT VLAN to the firewall itself &#8212; say if you <em>completely<\/em> isolate your IoT VLAN &#8212; you&#8217;ll need to allow those.)<\/p>\n\n\n\n<p>Now when going into <em>Bambu Studio<\/em> under <em>Devices<\/em> then expanding <em>Printers<\/em>, the printer will show up.  It may take a few moments as the printer to appear as the SSDP are only periodically sent, so be patient if it doesn&#8217;t appear immediately.<\/p>\n\n\n\n<p>(Note that if other models of printers aren&#8217;t working, it may be useful to also relay port <code>1910<\/code>. The <em>P1S<\/em> works fine with just <code>2021<\/code>, so for now that&#8217;s all I&#8217;ve done.)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Firewall Rules<\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignright size-medium\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"67\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/image-300x67.png\" alt=\"\" class=\"wp-image-19868\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/image-300x67.png 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/image-1024x229.png 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/image-768x172.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/image-1536x344.png 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/image.png 1884w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>With <em>Studio<\/em> seeing the printer, and presuming that your regular and IoT VLANs are firewalled off from each other, rules need to be added to allow the printer to work. While <em>Bambu Studio<\/em> has a <a href=\"https:\/\/wiki.bambulab.com\/en\/general\/printer-network-ports\">Printer Network Ports article<\/a>, it seems wrong. I am able to print successfully without opening all the ports listed for <em>LAN Mode<\/em>, but I also needed to add one more that wasn&#8217;t listed: <code>2024\/tcp<\/code>.<\/p>\n\n\n\n<p>Here&#8217;s everything I needed to allow from the regular VLAN to IoT VLAN to have <em>Bambu Studio<\/em> print to the P1S, along with what I believe each port to handle:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>990\/tcp (FTP)<\/li>\n\n\n\n<li>2024\/tcp to 2025\/tcp (Unknown, but seems to be FTP?)<\/li>\n\n\n\n<li>6000\/tcp (LAN Mode Video)<\/li>\n\n\n\n<li>8883\/tcp (MQTT)<\/li>\n<\/ul>\n\n\n\n<p>Nothing needs to be opened from the IoT VLAN, everything seems to be TCP and the stateful firewall seems to handle the return path. (Even though the <em>Printer Network Ports<\/em> article with it&#8217;s 50000~50100 range for <em>LAN mode FTP<\/em> implies <a href=\"https:\/\/en.wikipedia.org\/wiki\/File_Transfer_Protocol#Communication_and_data_transfer\">active mode FTP<\/a>&#8230;)<\/p>\n\n\n\n<p>And with that, it just works. I can now have my <em>Bambu Lab P1S<\/em> on the isolated IoT VLAN from a client on the normal\/regular\/LAN VLAN, printer found via autodiscovery, with only the requisite ports opened up.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Missing Functionality? Leaky Data?<\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignright size-medium\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/Screenshot-2024-12-19-at-1.10.57\u202fPM.png\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"204\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/Screenshot-2024-12-19-at-1.10.57\u202fPM-300x204.png\" alt=\"\" class=\"wp-image-19871\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/Screenshot-2024-12-19-at-1.10.57\u202fPM-300x204.png 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/Screenshot-2024-12-19-at-1.10.57\u202fPM-1024x695.png 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/Screenshot-2024-12-19-at-1.10.57\u202fPM-768x522.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/Screenshot-2024-12-19-at-1.10.57\u202fPM-1536x1043.png 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2024\/12\/Screenshot-2024-12-19-at-1.10.57\u202fPM.png 1876w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Note that there are a few functions &#8212; like browsing the contents of the SD card for timelapse videos or looking at the job history &#8212; which only work when connected to the cloud service. This really surprises me, as I can think of no rational reason why this data should need to be brokered by <em>Bambu Lab<\/em>.<\/p>\n\n\n\n<p>Unless they want to snarf up the data about what you print and video of it happening and when and&#8230; and&#8230;?<\/p>\n\n\n\n<p>Digging into that sounds worthy, but is a project for another time. It&#8217;s a pretty good reminder of why isolating IoT devices is good practice, though. For now I&#8217;ll just manually remove the SD card if I want access to these things. And consider if maybe I should completely isolate the printer from sending data out to the internet&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Citations<\/h2>\n\n\n\n<p>Big, big thanks to <a href=\"https:\/\/github.com\/Rdiger-36\/StudioBridge\">Rdiger-36\/StudioBridge<\/a> and very specifically the contents of <a href=\"https:\/\/github.com\/Rdiger-36\/StudioBridge\/blob\/main\/src\/main\/java\/rdiger36\/StudioBridge\/UDPPackage.java\">UDPPackage.java<\/a>. This utility which helps find Bambu Lab printers cross-VLAN by generating an SSDP packet, and sending it to loopback, saved me a bunch of time in figuring out how Bambu Lab&#8217;s non-standard SSDP works.<\/p>\n\n\n\n<p>All the discussion around <a href=\"https:\/\/github.com\/bambulab\/BambuStudio\/issues\/702\">issue #702, Add printer in LAN mode by IP address<\/a> was incredibly helpful in understanding what was going on and why this printer didn&#8217;t seem to Just Work in a multi-VLAN environment. This thread, and watching what <em>StudioBridge<\/em> did, made understanding the discovery process pretty simple.<\/p>\n\n\n\n<p>And as much as I dislike the <a href=\"https:\/\/www.gnu.org\/licenses\/agpl-3.0.en.html\">AGPL<\/a> in general, it worked out really well here. I wouldn&#8217;t expect a company like <em>Bambu Lab<\/em> to release their software so openly, but with the AGPL they had to. <a href=\"https:\/\/github.com\/Slic3r\/Slic3r\">Slic3r<\/a> begat <a href=\"https:\/\/github.com\/prusa3d\/PrusaSlicer\">PrusaSlicer<\/a> which begat <a href=\"https:\/\/github.com\/bambulab\/BambuStudio\/\">Bambu Studio<\/a> which begat <a href=\"https:\/\/github.com\/SoftFever\/OrcaSlicer\">OrcaSlicer<\/a> giving us a rich library of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Slicer_(3D_printing)\">slicers<\/a>&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Updates<\/h2>\n\n\n\n<p><strong>2024-Dec-22:<\/strong> After this worked fine for a few days I ran into problems printing from <em>OrcaSlicer<\/em> where jobs wouldn&#8217;t send. Digging I found that 2025\/tcp was needed as well, so I updated the article above. It seems this is another FTP port? It&#8217;d sure be nice if this was documented.<\/p>\n\n\n\n<p><strong>2025-Jan-10:<\/strong> I have further isolated the P1S by disallowing it access to the internet at all. Now, beyond having its SSDP requests forwarded to other VLANs, it&#8217;s wholly isolated to the IoT VLAN. This works great, and is basically a true LAN-only mode.<\/p>\n\n\n\n<p><strong>2025-Mar-08:<\/strong> After not printing anything for a while I ran into a problem with uploads would fail with a 500 error or so. I&#8217;m suspecting the printer lost it&#8217;s time and thus TLS was failing, as when I allowed the printer to talk DNS and NTP to the public internet everything got better. On every boot the printer resolves <code>time.cloudflare.com<\/code> and then queries it to set its time. (Unfortunately I didn&#8217;t save a screenshot of the error.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently picked up a Bambu Lab P1S 3D Printer for around the house. After staying away from 3D printing for years, the combination of&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/nuxx.net\/blog\/2024\/12\/19\/bambu-lab-p1s-on-iot-vlan\/\">Continue reading<span class=\"screen-reader-text\">Bambu Lab P1S on IoT VLAN<\/span><\/a><\/div>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23,16,13,11],"tags":[],"class_list":["post-19855","post","type-post","status-publish","format-standard","hentry","category-acquired-things","category-around-the-house","category-computers","category-making-things","entry"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19855","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/comments?post=19855"}],"version-history":[{"count":17,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19855\/revisions"}],"predecessor-version":[{"id":19910,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19855\/revisions\/19910"}],"wp:attachment":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/media?parent=19855"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/categories?post=19855"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/tags?post=19855"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}