DuetWifi HTTPS Proxy and Camera Using RaspberryPi Zero W

The DuetWifi (and DuetEthernet) are 3D printer and CNC/Laser machine control boards made by Duet3D to upgrade your printer to the latest on offer. A few advantages of these boards include: upload print files over wifi/ethernet using your browser, print monitoring through your browser, advanced control options etc. For more information, please go to their website:

https://www.duet3d.com/

The Issue we are facing

The Duet mainboards come with a web interface called Duet Web Control, and this is what one use to control and monitor your prints, however this interface is only available over plain unsecured HTTP. It is highly discouraged to expose your printer to the Internet directly (without some good VPN software that will relay the traffic to the Duet), so using unsecured HTTP is not a high risk in terms of security: as long as you only connect the printer to networks you control, that have the required security everything is fine.

The issue that is creeping up, is browsers have started giving warnings about entering passwords on unsecured websites, does not matter if that website, is running on the Duet inside your printer, located just a few centimeters away from the computer. In future browsers will probably disallowing one to enter passwords into unsecured websites, and later probably even refuse to connect to unsecured websites. Since the Duet's web interface is seen as a website, it is unsecured and it uses a password (highly recommended to set it up) to enable control over the printer, this issue will be affecting more and more people using these Duet mainboards.

We simply can't stop using our printers because our browsers think it is "unsafe" - and for someone who just got the Duet Mainboard, it may be a source of frustration to find out your browser does not really like your new shiny mainboard.

This topic have been debated in the Duet Forums (https://forum.duet3d.com/post/185) and in short, the current hardware simply does not support an efficient way to implement HTTPS/SSL, it will require extra steps to get it setup and it draws a lot of processing power away from the printer's main job: to print. HTTPS/SSL is made difficult for computers to make it more secure, and have an extremely complicated handshake (when a computer connect to the server, the exchange that happens there). Bottom line, in current (mid 2018) hardware, it is simply not going to be implemented. It may be implemented in future hardware, like perhaps the Duet version 3 hardware (currently in development), but that is not confirmed at the time of writing.

It should be noted that the "unsecured HTTP" mentioned here, does not mean it is bad. In essence our proxy will simply sit between the Duet and your computer, for the sole purpose to keep your browser happy - the traffic into and out of the Duet will still be unencrypted, and the proxy could get bypassed (useful if your proxy have any issue).

Our Options

  • Setup a Proxy server, on some computer/device on the network (like a RaspberryPi)
    • This guide will use a RaspberryPi Zero W, but it can be done on a computer or device running Linux (some commands may be slightly different).
  • Keep using the unsecured HTTP Duet Web Control, for as long as it works.
  • Wait for the new hardware to be released - for us right now, not an option.
  • Move away from the Duet Mainboards or not get one - not an option: once you are hooked on the convenience of the Duet mainboards I would not go back to what they were before.

Useful Information:

In this guide I will be running the RaspberryPi in Headless mode, this means that I only need the power connected (with micro USB) - no screen, no keyboard or mouse.

Communication between your computer and the Raspberry Pi will happen over wifi, which we will pre-setup (you will need your wifi SSID and password) and the communication protocol will be SSH (on Windows, you will need software like PUTTY to handle the SSH communication). SSH is a command line interface (CLI and not a GUI - Graphical User Interface), which works by entering commands. While having experience using CLI will be beneficial, I will include all the commands with full instructions to help novice users.

This guide will also include an optional section where we can add a camera (Raspberry Pi Camera), that will stream its images for the Duet Web Control interface. This will allow print monitoring from within your local network.

So lets start setting up our proxy server.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: What You Will Need

This is the list of everything we will need and use during this setup:

  • A Raspberry Pi (any model is supported in this guide):
    • Raspberry Pi 3B - slightly overkill for only this guide, but if you have extra work for it, a good choice.
    • Raspberry Pi Zero - the standard Pi Zero will require an adapter to get wifi, with a USB on the Go cable, and this one can't run a camera.
    • Raspberry Pi Zero W - this one comes with built-in wifi and a camera port, and is what I used.
    • Alternatively, if you have a Linux computer on your network, you can even use that (though the camera part won't work, but there are more than enough guides to get you up and running with a USB camera).
  • MicroSD card:
    • I do not recommend smaller than 8GB, proxy might be able to work with 4GB.
    • If you want to record long videos (using the camera and the web interface we will be using), you might also want to increase your storage on the Pi (after the videos are recorded, they can be downloaded to your computer and deleted to free storage on the Pi).
    • This card is the Hard Drive / SSD equivalent on the Pi.
  • MicroUSB cable, for power to the Pi
  • Optional Raspberry Pi Camera:
    • I had a Camera v1.3 available, and used that.
    • The newer v2 cameras have advantages above mine, but any will do.
    • My camera is a standard camera, but you might consider the NoIR version if your printer is in low light (NoIR, does not have an Infra Red filter, allowing use of IR fill lights to see in the dark; but images looks more washed out).
  • Optional Pi Cam Cable:
    • If using a Pi camera, you will need a cable between it and your Pi, just make sure they fit (the Pi Zero W connector is smaller than the wire that came with my camera, so I had to buy a new one).

If you want to run the Pi with an interface, you will need a screen, keyboard and mouse all connected to the Pi.

That concludes the hardware list.

For software requirements and downloads (on your computer):

  • Etcher - https://etcher.io/
    • We will use this cross-platform utility to prepare our MicroSD Card. There are alternatives, but this one is simple and easy.
  • Raspbian - https://www.raspberrypi.org/downloads/raspbian/
    • Download the latest version of Raspbian (currently in Stretch).
    • If you want the User Interface, get the "with Desktop" version; I used the "Lite" version - Lite is a smaller download, since it does not have the user interface parts.
  • Adafruit Pi Finder - https://github.com/adafruit/Adafruit-Pi-Finder/re...
    • This software is slightly old, but it still works. Very useful to quickly get the IP address of your Pi, in a headless setup (where your router or DHCP server randomly assigned an IP address).
  • Putty SSH Client - https://www.putty.org/
    • This is Windows only, for other Unix or Linux based OSs, you can simply use your Terminal.
    • Technically Windows Command Prompt can also do this, but compared to the Terminals of Mac and Linux it is far behind. Putty makes the SSH connection easier (with copy and paste options).

With all of this ready, lets get started to setup our Proxy Server.

Step 2: Setup Your Raspberry Pi

We will start with the Pi, getting everything setup like we need.

Flash Raspbian to the MicroSD Card, using Etcher

  1. Insert the MicroSD card into a card reader and connect it to your computer. If the card have any content, please copy it off, as the card will be formatted.
  2. Run Etcher.
  3. Inside Etcher, select the Raspbian download as the image to use,
  4. and select your MicroSD card as the drive (ensure you select the correct drive)
  5. finally click the Flash button. Etcher should now be busy formatting and flashing the card.
  6. Windows might, during the flashing process, give popups that a drive is corrupted and needs to be formatted, ignore these - Windows can't read the file system used by Raspbian.
  7. When the flashing is done, you should have a new small drive called "boot"

Prepare the Raspbian OS for SSH and allow it to connect to your Wifi

  1. Inside the new "boot" drive, in its root (not in a sub directory), create a file called "ssh" or "ssh.txt" - on Windows I simply right click > New > Text File and call it "SSH"
    1. If this file exists, even if it is empty, it will allow SSH communication (otherwise we need a display and keyboard to enable SSH).
  2. Also inside the new "boot" drive, we need to create another file called "wpa_supplicant.conf" and insert the following content inside of it:

country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="xxxxxxxxx" scan_ssid=1 psk=yyyyyyyyyy }

Ensure to change the country to your own country's code, and your SSID and Password for your Wifi. This file is removed when done, so even if someone gets hold of your card, they can't see this file in the boot drive, and use it to get your wifi details.

Insert the card into your Raspberry Pi and power it on.

The initial startup may take a few minutes, while it installs itself and set itself up like it want to be.

The lights will stop flashing when it is done,

  1. Using Pi Finder, locate the IP address of the Raspberry Pi. If you have more than 1 Pi on your network, the Pi Finder will find all of them, and list them inside the dropdown for the IP address.
  2. Start Putty, it will ask you some information to connect to the Pi:
    1. Host Name (or IP address)
    2. Optionally save the session, for quick connect at later stages.
    3. Click the open button. The terminal will load and ask you for a login:
      1. Username: pi
      2. Password: raspberry
    4. If successful it will display a welcome message and also the last login date and time.

  3. You are now connected to the Pi using SSH.

Update and perform Pi Setup

It is important to keep your Pi up to date with the latest software packages and patches.

Run the following commands:

sudo apt-get update

sudo apt-get dist-upgrade

The first command will get a list of packages that are available, and the second command will install the update packages (may ask for permission to continue). The "sudo" simply tells the Pi you need to escalate this process' permissions to root (administrator on Windows) in order for it to accomplish its task - similarly to Windows asking Administrator permissions to install software, but this simply forces the command to be as root (on some setups root may have a password, in which case this command will request the password to continue).

These 2 commands can be run regularly during the operation of your Proxy server to keep everything updated.

Next we run the following command:

sudo raspi-config

This will load the Configuration Interface for a Raspberry Pi, as a grey box inside a blue screen. More details about this screen at https://www.raspberrypi.org/documentation/configu...

In essence we want to do the following:

  • Advanced Options > Expand Filesystem (so the Pi can use the whole card)
  • Advanced Options > Memory Split (this is how much RAM is used as graphics memory)
  • Change User Password (for security)
    • This will ask for the current password, and then the new password twice (remember this password, as losing it will lock you out).
  • Interfacing Options > Camera (if you will use it)
  • Network Configuration > Hostname
    • This allows an easier name when connecting to the pi, rather than via IP address. use something simple, does not allow spaces and are only ascii characters.
  • Localization Options (if you use a language different than English, default)

Using the arrow keys, you can navigate and Enter to select.

When done, it will ask to reboot, let it reboot. You will need to reconnect your terminal as the connection will close.

Optional: Set Static IP address

The default configuration of the Pi is to use a DHCP server (usually a router) to assign it an IP address, but that IP address may change depending on settings on the DHCP server, making it hard to locate your Pi. You can also do this directly from the DHCP server, if it supports assigning static IP addresses to specific MAC addresses (hardware address used to identify the device).

We start by running the following command:

ifconfig

This will give us information about the current configuration of your network settings. Mine gace 2 networks (lo and wlan0; wlan0 is what we want to see). Make a note of the information there (I copied it to a text file).

Next we run the command:

sudo nano /etc/dhcpcd.conf

This code loads the Nano text editor inside your terminal, with root access and will open the file located at "/etc/dhcpcd.conf". If the file is empty, you might have a spelling mistake, use Ctrl+X to exit and try again. Navigate in the file, using the arrow keys (don't scroll with your mouse, it does not work).

For anyone not familiar with the block cursor, it adds content to the left of it and not where it is at (this was confusing to me in the beginning).

Move down into the file until you find the "Example static IP configuration" part. The next line is "#interface eth0", replace it with "interface wlan0"

Now for each of the next lines that you want to modify, remove the "#" from the line start, and change the value as you need (if you don't know what value to use, refer back to the note of current configuration you have made). IP6 is not required yet.

When you are done, use Ctrl + X to exit. It will ask if you want to Save modified buffer, type "Y" for Yes. Now it will ask what name you want to use (using the default one will overwrite it - as we need), so press Enter.

Now we reboot the Pi with:

sudo reboot

Running the "ifconfig" now, should produce a result that it is on the static IP address.

Next we will install Nginx and do basic proxy setup.

Step 3: Install Nginx and Basic Proxy Setup

Install and configure Nginx (initial configuration)

For the Proxy, we will use Nginx as it is light weight, fast and easy to setup as a proxy.

Run the command

sudo apt-get nginx 

This will start the installation process for Nginx, and it will ask you to confirm the installation along with the amount of storage it will use. When it is done, Nginx will be started as a service, and be configured to run automatically on startup - all good, except we need a small change in the configuration, so we stop the service with:

sudo service nginx stop

The service should now be stopped, allowing us to make configuration changes.

The file we will be editing is located in /etc/nginx/sites-available, so I find it easiest to run the following commands:

cd /etc/nginx/sites-available

sudo nano default

"default" is the filename for the default site configuration of Nginx, and we will simply edit it to become our proxy (you can remove everything in the file).

Here is my proxy server configuration, with what we will need at this point:

server{ #proxy
listen 80 default_server; #ipv4 listen on port 80 listen [::]:80 default_server; #ipv6 listen on port 80 server_name <raspberrypiname>.local localhost; #servers that can be used index index.php index.html index.htm; #files used as the index error_log /var/log/nginx/proxy.<raspberrypiname>.local.log; #where to save our log #auth_basic "Printer Name"; #if you use HTTP basic Auth, the name #auth_basic_user_file /etc/nginx/.htpasswd; # where to find the basic auth users and passwords location / { #this handles all the proxied requests proxy_pass http://duetname.local; #where should it be forwarded to proxy_set_header Host $host; proxy_http_version 1.1; #http protool for the destination proxy_set_header Upgrade $http_upgrade; #allow upgrading the connection proxy_set_header Connection "upgrade"; client_max_body_size 0; #this is required to allow uploading the gcode files proxy_request_buffering off; #prevents buffers, for best performance } location ~/\.ht{ #deny any request to possible snooping for the passwords in basic auth deny all; } }

Anything after a "#" is a comment, so I start it out by naming this server as the proxy (makes it easier to know what it is related to, and you need to edit it again).

Replace the "<raspberrypiname>" with whatever your called your Raspberry Pi, and the "duetname" with what you have called your Duet mainboard.

Save this file, overwriting the existing, by pressing Ctrl + X, "Y" and Enter.

Now we start the Nginx service again, so that we can test.

sudo service nginx start

If everything is working, and your printer is on, and you point your browser to <raspberrypiname>.local, it should now load the Duet Web Control and ask for the password to it. Go through everything, upload files and confirm that it is all working before we continue the setup. It is easier to debug issues when it is still simple HTTP, compared to the complexity of debugging things when encryption is a part of it.

The next part will be about getting a self-signed SSL capable certificate.

Step 4: Getting Your Own SSL Capable Certificate

Since we did not buy a domain name just for our Raspberry Pi, we don't qualify for a certificate signed by a trusted Certificate Authority, like Let's Encrypt (free) or any of the many paid CAs. This means we will need to use a self-signed certificate.

When you use a self-signed certificate, you will need to tell your browser that it can be trusted, otherwise it will refuse to connect (by default). Remember that you should only trust self-signed certificates created by yourself or a trusted individual (which is not a stranger on the phone or other side of email): trusting a forged certificate can compromise the security of your browser.

Since mostly you will visit your printer as a site, using self-signed certificates is not an issue. Other people will first have to trust your certificate before they can use your proxy to access the printer. Note that if they really want, they can bypass the proxy all together and go straight to the printer's url.

we start in our own directory on the Pi, by entering a empty change directory command.

cd

In the following commands, replace the "piname" with the name of your Pi:

sudo nano piname.conf

This will create an empty file, and open it to edit. Add the following content, only changing the "piname":

[req]
default_bits = 2048 default_keyfile = localhost.key distinguished_name = req_distinguished_name req_extensions = req_ext x509_extensions = v3_ca [req_distinguished_name] countryName = Country Name (2 letter code) countryName_default = US stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = New York localityName = Locality Name (eg, city) localityName_default = Rochester organizationName = Organization Name (eg, company) organizationName_default = localhost organizationalUnitName = organizationalunit organizationalUnitName_default = Development commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = localhost commonName_max = 64 [req_ext] subjectAltName = @alt_names [v3_ca] subjectAltName = @alt_names [alt_names] DNS.1 = localhost DNS.2 = 127.0.0.1 DNS.3 = piname.local

This file will be used to configure the settings for your certificate, for the names etc, it will be asked when we run the next command.

Exit Nano text editor, and save the file right there.

Now we create the certificate with the following command (replace "piname" as needed):

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout piname.key -out piname.crt -config piname.conf

This will start a script to generate your certificate, using the configuration file. It will ask you a few questions at the top, and then generate 2 files (a .key and .crt file). This certificate is valid for 365 days, after which you will need to do this command again, for a new one.

Now, if we run the command "ls" (LS in lowercase; list files), is should show the 2 new files, next to the configuration file.

In order for Nginx to use it, we will copy these 2 output files to their final destination:

sudo cp piname.crt /etc/ssl/certs/piname.crt

sudo cp piname.key /etc/ssl/private/piname.key

As you can see, the .key is our private key, and the .crt is the public key (that browsers will use). This provides very good security, with verification capabilities.

Finally, we need to tell Nginx where to find these certificates and how to use them.

For this, we go to the nginx/sites-available:

cd /etc/nginx/sites-available

sudo nano default

The file should now look something like:

server{ #proxy
listen 80 default_server; listen [::]:80 default_server; listen 443 ssl http2; listen [::]:443 ssl http2; server_name piname.local localhost; index index.php index.html index.htm; error_log /var/log/nginx/proxy.piname.local.log; ssl_certificate /etc/ssl/certs/piname.crt; ssl_certificate_key /etc/ssl/private/piname.key; ssl_protocols TLSv1.2 TLSv1.1 TLSv1; #auth_basic "Printer Name"; #auth_basic_user_file /etc/nginx/.htpasswd; location / { proxy_pass http://duetname.local/; proxy_set_header Host $host; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; client_max_body_size 0; proxy_request_buffering off; } location ~/\.ht{ deny all; } }

Save the file again and restart Nginx.

sudo service nginx restart

If you visit your Pi now, using HTTPS, it should once again load the Duet Web Control. To test it, enter https://piname.local into your browser.

If it works, congratualations you have a working proxy.

You can now edit the nginx configuration file again, this time adding a "#" before the lines for "listen 80" and "listen [::]80" - since we will only allow HTTPS/SSL communication on this side, disable the plain HTTP.


As a further security, you can also enable the Basic Authentication, but that is beyond the scope of this guide.

Adding the camera section will come slightly later, as the main purpose of this guide is first to get a proxy.

Step 5: Information Sources Used

The essence of this Instructable is taken from many different websites, each trying to accomplish a specific task. I have compiled this information for the purpose as set out in the start of the Instructble in a logical order for this task.

The information in this instructable can also be separated, should you wish.

Here are links to the different sources I used:

Thank you for following my Instructable. If you have any questions, suggestion etc, please add them to the comments.

Share

    Recommendations

    • Indoor Lighting Contest

      Indoor Lighting Contest
    • Metal Contest

      Metal Contest
    • Make It Fly Challenge

      Make It Fly Challenge

    Discussions

    Hello there!

    We're glad you want to share something with the Instructables community!

    And we’re here to help you out.

    In order to be published live on the site, Instructables must consist of the following things:

    - Multiple steps showing how you made your project

    - Written instructions in each step

    - Your own original images

    Beyond making your Instructable simply publishable, this guide (https://www.instructables.com/id/How-to-Create-a-Feature-Worthy-Instructable/) explains what is required to have your Instructables featured by our site editors. It’s very helpful, and definitely worth checking out.

    We would love to review your project again after you have made the necessary edits, and we will publish your project if it is eligible.

    If you have any questions, please feel free to ask right here or send us an email at service@instructables.com.

    Best,

    Instructables Community Manager