Thursday, September 27, 2018

Sending an email with many embedded images

I recently needed to send an email that needed to include many (~10) high-resolution images, and I wanted to have thumbnails of those images inline with the email text so that I could comment on them.

The images could not be embedded directly because they exceeded the email size limit of most email servers, and simply inserting links makes it difficult to understand the email.

So to draft an email with inline thumbnails linking to high-resolution images, I did the following:

 1. Create thumbnails of the images in the desired size for embedding in the email.
 2. Find a service with static link support to host all the images.
 3. Upload all the images (original and thumbnails) to the service.
 4. For each image in the email, insert an image tag sourcing the thumbnail surrounded by an anchor tag referencing the full sized image.

 Detailed Steps

Below you will find detailed steps of how I carried out the steps listed above.

1. Create Thumbnails

I used a handy node.js package that provide a command line interface. It's called node-thumbnail and works great.

Pre-Requisites: node.js
  1. Install node-thumbnail: npm install --global node-thumbnail
  2. Ensure only images are in the directory containing your images; node-thumbnail can't handle other file types.
  3. Open the image directory in a command prompt
  4. Generate thumbnails for the current directory and put them in the current directory with _thumb append to the names, using 250 pixels for the width: thumb .\ .\ -w 250


 2. Setup Static Linking Host

For this I used Azure Blob Storage with the Static Website feature enabled. Here are the step to do that:
  1. Sign up or log in to
  2. Click "Storage Accounts" on the left menu
  3. Click Add or select an existing account
  4. Use default settings for everything and pick a name that will be part of the domain where your files are accessible to the internet.
  5. After creating and opening the storage account, click on the "static website (preview)" setting.
  6. Enable it
  7. Open the $web Storage Container linked to on the same page
  8. This is where you'll upload your images
I wouldn't worry too much about cost here since blob storage costs on the order of cents per mb of data transfer. So likely it'll be covered by the free credits Azure offers to new signups.


3. Upload Images

I just used the Azure website for uploading the files but there are probably other ways.
  1. Open the $web Storage Container inside the Storage Account you set up earlier
  2. Click Upload
  3. blah blah blah


4. Embedding Images in an Email

This part should be pretty easy but varies wildly between email clients. Here's how to do it in Thunderbird:
  1. Start a new email
  2. Click into the body of the email
  3. Click the image icon in the upper right directly above the body
  4. Choose "image" from the drop-down menu
  5. Go into the Azure $web storage container
  6. Select the thumbnail image you'd like to insert into the email
  7. Click the copy url button
  8. Paste that into the Image Location box in Thunderbird
  9. Enter "alternate text" describing the image
  10. Open the Link tab
  11. Repeat steps 6-8 but select the full sized image instead
  12. Repeat steps 3-11 for each image you want to insert
This process can be quite a bit faster if you're not afraid of HTML:
  1. Start a new email
  2. Click into the body of the email
  3. Click Insert>HTML in the menus at the top of the window
  4. Insert a series of statements like the following but replacing the links with what you get from Azure:   
<a href="$web/imagename.jpg">
  <img src="$web/imagename_thumb.jpg" />

Monday, July 23, 2018

Secure HTTPS Web Interface for ASUS Routers

ASUS is kind enough to provide Let's Encrypt to their newer routers but for those of us that have an older model we can still use it after quite a bit of hackery.


  • You own a domain
  • You have DDNS enabled for that domain and it's pointed at your network
  • You have Linux, Windows Subsystem for Linux, or MacOSX installed on your computer
  • You have git installed
  • You have telnet installed

Getting The Certificate

I recomend using a CA that has longer lived certs than LetsEncrypt due to the renewal process taking about 30 minutes of your time, each time; LetsEncrypt certs only last three months. By comparison, you can buy a year long cert from for $9. So, is 2 hours of your time worth $9?

From NameCheap
  1. Buy a cert from, such as the really cheap PositiveSSL cert.
  2. Generate a CSR and private key by following this guide 
    • Make sure to specify the specific domain you've assigned to your network, for the "Common Name".
  3.  Submit the CSR to Namecheap to complete your cert purchase

From Let's Encrypt

  1. Configure router to forward HTTP/S connections to your computer
    1. Navigate to; that's your router btw.
    2. Login
    3. Add two entries to the port forward list:
      1. HTTP,,80,your computer's ip address,80,tcp
      2. HTTPS,,443,your computer's ip address,443,tcp
    4. Apply changes
  2. Configure your computer's firewall to allow inbound connections to the HTTP/S ports
    1. Windows
      1. Press the Windows key or click on the icon in the lower left of the screen
      2. Type: Advanced Security
      3. Press enter or click on the firewall option in the search results
      4. Click Inbound Rules on the left
      5. Click New Rule.. on the right
      6. Fill in the same info as in step 1.3 above without specifying your computer obviously.
  3. Install letsencrypt:
    1. git clone
    2. sudo ~/letsencrypt/letsencrypt-auto --test-cert -d your.domain.address
    3. Fix any errors that come up, like installing apache if you don't have it installed
  4. Request a real certificate from LetsEncrypt
    1. sudo ~/letsencrypt/letsencrypt-auto -d your.domain.address
  5. Enable Telnet while you're in here
  6. Stop accepting HTTP/S connections to your computer
  7. Stop forwarding HTTP/S connections to your computer through your router

 Installing The Certificate

  1. Open a terminal, comand prompt, or whatever
  2. remotely access the router terminal via:
    • ssh
    • telnet
  3. enter your usual credentials for accessing the router web interface
  4. Enable certificate persistance by running this command: nvram set https_crt_save=1
  5. Copy the certs to your router by using good old fashioned copy/paste
    1. open your private key locally, it'll be in "/etc/letsencrypt/live/your.domain.address/" if you used Let's Encrypt.
    2. copy all of the text in the key file
    3. open your router's private key remotely: vi /etc/key.pem
    4. use the delete everything command: ":%d"
    5. enter insert mode using the "i" key
    6. right-click to paste
    7. repeat the same steps for cert.pem
  6. Restart the router's web server: service restart_httpd

 Using The Certificate

  1. Enable HTTPS Local Access Config (aka Web Interface) on your router if you have not already done so.
  2. Forward HTTPS connections to your router's web interface by adding this entry to your port forward list:
    1. HTTPS,,443,,443,tcp.

You should now be able to securely access your router's web interface from anywhere in the world using https://your.domain.address.

This post was inspired by