Custom Prusa IKEA Lack Enclosure Parts

Earlier this year, Prusa released their take on a 3D printer enclosure made from the famous IKEA Lack tables and printable parts.

There are a wealth of printable accessories for this enclosure.  I’ve found these ones really nice:

I’ve designed a few parts of my own that I’m pretty happy with.  I would not be surprised to learn there are equivalent or better alternatives to these.  I did try looking, but not too hard.  I was happy to have the design challenge.

Fan Mount

Thingiverse link.

Enclosures get hot enough to screw with PLA print quality.  I added a ventilation fan which is capable of keeping the temperature in safe ranges (~27 C).

This is a mount for a standard 120x120mm computer case fan.  I’m using this Corsair AF120 fan*.

The mount slides into a centered cutout approximately 129x129mm on one of the acrylic sheets (I’m using the rear one).  

I had intended for the cutout in my sheet to be closer to 122x122mm, but the company I bought the sheet from didn’t get the measurements exactly right.  It was nice to be able to easily resize the part in Fusion 360 and print it out to-size.

1″ Grommet

Thingiverse link.

I drilled a 1″ hole through the bottom table to feed these cables through:

  • Two Logitech C270 * USB cables
  • LCD ribbon cables
  • 24v cables from the PSU

To make the hole look nicer I “designed” a grommet to fit the crappy hole my 1″ drill made.

Birdseye Mount for Logitech C270

Thingiverse link.

The Logitech C270* is a super cheap (~$20) 720p USB webcam that works really well with Octoprint.

I have two of them in my setup.  First, the aforementioned x-axis mounted camera.  Great for making sure the print is looking good where it’s at.  Example view:

And the one placed in this mount, which gives a birds-eye view of the whole print bed.  Example view:

Modified Door Handles

Thingiverse link.

I redesigned the included door handles from scratch, mostly in order to improve my Fusion 360 design skills.

There are a few aesthetic differences, but the functional difference is that there are recesses appropriately sized for some 20x10x2mm N50 magnets* I had laying around.

Control

I’ll share how I’m controlling the fan and lights in a future post.  Long story short, it’s an ESP8266 with some MOSFETs and ancillary circuitry.

[*] Contains affiliate link

Reusable Dash Button Case

I use Dash Buttons* in quite a few places around my home — mostly as a substitute for a light switch where one is inconveniently located, or not present at all.

I prefer them to alternative options like the Flic Button* because they’re dramatically cheaper (a Dash is $5, compared to $35 for a Flic).  They’re also occasionally on sale for $0.99.

My only frustration with Dash buttons is that they’re meant to be disposable, despite being powered by a replaceable AAA battery.  The electronics are encased by two pieces of welded plastic.  It’s easy to break the weld, but difficult to reassemble in a pretty way.

Having recently started dabbling in 3D design and printing, I decided to create a reusable case.  The humble fruit of my efforts is here:

https://www.thingiverse.com/thing:3079607

I’m happy with how this turned out — it’s easy to open the case and replace the battery without damaging anything.

(Dis-)assembly

Pretty straightforward.  I took apart the stock case using some channel locks to break the welds:

With a little bit of elbow grease, and a T5 screwdriver to remove the battery enclosure, it comes apart like so:

A pry tool can be used to remove the PCB if it doesn’t come off by itself.

Assembly is straightforward.  First, put the plastic button and the rubber seal in place.

Then the PCB is placed back on the pegs, battery enclosure placed on top, and T5 screws added back.  Do not over-tighten the screws!  The printed pegs are quite fragile and will break under too much pressure.

After adding the battery back, the lid can be pressed onto the body:

And that’s it!  Fully assembled Dash case.

Update: Sept 4, 2018

I’ve uploaded a slightly modified version.  The main change makes it harder to over-tighten screws making the button unpressable.

[ * ] Contains Amazon affiliate link

Security Hardening Octoprint/Octopi

Octoprint is a great web frontend for 3D printers. Octopi is a raspbian-based image for a Raspberry Pi that comes with everything you need set up and configured.

Octoprint is an extremely convenient way to manage your 3D printer.  However, it’s capable of a lot of spooky things:

  1. If you have them, provides access to webcams showing prints
  2. Can set temperatures of both the tool and the heatbed
  3. Start whatever print you feel like
  4. Control steppers

In the best case, Octoprint gives whoever can access it the ability to see into your house and what’s going on with your printer.  In the worst case, someone with malicious intent could burn down your house, or at least wreck your printer.

The smartest approach here is probably to put Octoprint on a trusted network and refrain from poking holes in your router to allow access from the Internet.

But I’m not that smart.

In this post I’m going to outline a couple of things I did that make me feel better about exposing my Octoprint instance to the Internet.

Prior Art

First of all, Octoprint has builtin access controls.  And you should definitely use those.

I feel strongly that these are not sufficient, however:

  1. Unauthenticated users can do way too much.  Most importantly, they can view webcam feeds.  Yikes!
  2. There have been bugs with the builtin access controls.

Secondly, others have done things similar to what I’ve done.  However, there are a couple of things I’m going to do differently, and there are a few additional things I want to do.

Requirements

  1. Every interaction with Octoprint should go through a reverse proxy.  It should not be possible to access any part of Octoprint except through the reverse proxy.
  2. The last requirement should apply even if you’re on my local network.  Something about unauthenticated Webcam feeds gives me the jeebies.  Even if they’re pointed at a corner.
  3. I’m not going to run a web-facing nginx instance on Octoprint.  I want to use my main server as an entry point.
  4. Use client certificates for auth (I covered this in a previous post).
  5. TLS via letsencrypt.

Close down the ports

By default, Octopi exposes the Octoprint web interface on port 80 (via haproxy), and the webcam feed via mjpeg_streamer on port 8080.

I didn’t want these ports accessible except through loopback.  This is easy enough to change.

To shut down access to the Octoprint instance, just disable haproxy:

The Octoprint instance itself listens on port 5000 by default, and is bound to loopback.

To shut down access to mjpeg_streamer, we’ll have to fiddle with the script stored at /root/bin/webcamd :

This tells mjpeg_streamer’s http plugin to bind itself to loopback.  For it to take effect, make sure to restart the webcamd service (or just reboot the pi to be safe).

To test that this worked, try accessing http://octopi.local and http://octopi.local:8080.  You should get connection refused errors for both.

Open up the ports (on nginx server)

If you plan on running nginx on the pi, you can skip this step.  I have a different server running nginx.

In the last step, we shut down the ports to Octoprint.  Now we need to give the server running nginx a way to access them.

An easy way to accomplish this is with local SSH tunnels.  Setting this up is easy enough:

  1. Create a user on the octopi instance.  I called mine something to the effect of “ssh-proxy”
  2. Create a corresponding user on the server running nginx.  Generate an SSH key.
  3. Add the public key for ssh-proxy@nginx-server to ssh-proxy@octopi:~/.ssh/authorized_keys
  4. Set up autossh to establish a persistent SSH tunnel.  This will reestablish the tunnel when the pi reboots or connectivity is broken for any reason.  This is the command I used:
  5. Execute the above command on boot.  I accomplished this by putting it in /etc/rc.local.

Now Octoprint should be available on the nginx server via port 25000.  Same deal for the webcam feed on 28080 (I have another webcam accessible via 28081).

Note that these should be bound to loopback because of the way the tunnel is set up.  No point in all of this noise if that’s not the case.

Make ’em accessible

Now we can go about this if it were a standard reverse proxy setup.  The backends are accessible by loopback on ports local to the nginx server.

You can set up authentication however you like.  It’s probably easy and safe to use TLS, HTTP auth, and something like fail2ban.

I like client certificates, and already had them set up for other stuff I run, so I’m using those.

This is my config:

What’s this access_by_lua hocus pocus?

I covered this in a previous post.  The problem is that modern web applications don’t really play nicely with client certificates, and this seemed to include Octoprint.  There’s a bunch of wizardry with web sockets and service workers that don’t send the client cert when they’re supposed to.

The basic idea behind the solution is to instead authenticate by a couple of cookies with an HMAC.  When these cookies aren’t present, nginx redirects to a domain that requires the client certificate.  If the certificate is valid, it generates and drops the appropriate cookies, and the client is redirected to the original URL.

See the aforementioned post for more details.

Goes without saying, but…

The Raspberry Pi itself should be secured as well.  Change the default password for the pi user.