justinlillico.com

Jan 07, 2023

On Chat GPT

Hi.

So everyone has been banging on about this ChatGPT AI system and I thought I might weigh in on my thoughts.

In case you don't know, ChatGPT is a new AI model by OpenAI. You know, those crazy cats who made the computers draw weird pictures so you can insult your friends with them or what have you.

I played around with it for a while and my mind was racing for use cases for something like it. It is like no AI you have ever interacted with. Anything you say to it is responded to with perfect grammar and I rarely got any nonsense from it. It can write stories, poems essays and code. And I am sure many more things. The code part I was particularly interested in so I have an anecdote about it:

I was at work and I was doing some task that required me to go through a list and pair all of the elements. I could do this, but it would have taken me 15 minutes and probably been buggy as all heck. So I thought I'd as ChatGPT to take a stab at it. And a stab it took. Within three seconds, I had a lovely python function that did exactly what was required.

I think it is difficult to overstate the significance of a tool like this. The number of industries and markets that will be disrupted is staggering. Anyone that uses language in some way is vulnerable to the change which is everyone. If they put it behind a paywall, OpenAI will become our new overlords: potentially even bringing Google to their proverbial knees.

If they make it open source, as cool as it will be, the sheer volume of unethical actors using it for evil will be staggering. Imagine the elderly people it could trick into giving credit card information? My imagination is coming up with no other examples at this time, but let me list off a bunch of examples the bot gave me:

Fair call

That took less than ten seconds to produce. It's scary. I'm going to say it now so I can refer everyone back to my ancient blog post from back when humans wrote them:

This technology is going to change the way we live in the very near future.

Justin Lillico - The Prophet

For better or worse is yet to be seen.

PS: this whole thing was revised by AI.

A revision from the AI master race.

Jan 03, 2023

Containerized Application with SSL

This drives me nuts so I more or less favour cloud builds now to get away from having to setup HTTPS. The problem is, its just so necessary.

So I am documenting here how to do this using docker compose, nginx and certbot. One resource that helped me greatly was this excellent tutorial:

https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71

So here is how we do it:

You are going to need somewhere to host this. I used Linode.

Once you have a cheap instance spun up (Ubuntu 20ish should do), run the following:

sudo apt update && sudo apt upgrade -y

sudo apt install docker-io docker-compose

This will get you the magical docker.

Now, create yourself a docker-compose.yml that looks like this:

version: "3"



services:

  yourapplication:

    container_name: yourapplication

    image: yourapplication/yourapplication:latest





  nginx:

    image: nginx

    volumes:

      - ./data/certbot/conf:/etc/letsencrypt

      - ./data/certbot/www:/var/www/certbot

      - ./nginx.conf:/etc/nginx/conf.d/default.conf



    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"



    ports:

      - "80:80"

      - "443:443"



  certbot:

    image: certbot/certbot

    volumes:

      - ./data/certbot/conf:/etc/letsencrypt

      - ./data/certbot/www:/var/www/certbot

    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

There is a lot going on here. I am assuming you have some application you want to give SSL to. So replace yourapplication with that. Expose port 80 or whatever port you are going to tell nginx to forward requests to.

./nginx.conf:/etc/nginx/conf.d/default.conf

The above line maps a file in your current directory to a directory in the nginx container. Lets make that file!

sudo nano nginx.conf

Paste in the following:

server {

    listen 80;

    server_name YOURDOMAIN;

    location / {

        return 301 https://$host$request_uri;

    }

    location /.well-known/acme-challenge/ {

        root /var/www/certbot;

    }

}



server {

    listen                  443 ssl;

    listen                  [::]:443 ssl;

    server_name             YOURDOMAIN;



    ssl_certificate /etc/letsencrypt/live/YOURDOMAIN/fullchain.pem;

    ssl_certificate_key /etc/letsencrypt/live/YOURDOMAIN/privkey.pem;



    include /etc/letsencrypt/options-ssl-nginx.conf;

    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;



    location / {

        proxy_pass "http://YOURAPPLICATIONCONTAINERNAME:THEPORTYOUEXPOSED";

        proxy_http_version 1.1;

        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header Connection "upgrade";

        proxy_set_header Host $host;

    }



    error_page   500 502 503 504  /50x.html;



}

So basically you are saying (I think)

Hey, nginx, if anyone navigates to YOURDOMAIN using http, redirect it to https. And if anyone shows up there, you can find the SSL stuff in this location to provide a cert and forward that to the docker application at http://YOURAPPLICATIONCONTAINERNAME:THEPORTYOUEXPOSED

Justin Lillico

There is a good chance I am misunderstanding this, but I had a crack!

So as the tutorial I am basing this on mentioned, there is a bit of a chicken or egg situation in that nginx needs the cert to start and the cert needs nginx to be obtained. So they have this neat little script to take care of business:

#!/bin/bash



if ! [ -x "$(command -v docker-compose)" ]; then

  echo 'Error: docker-compose is not installed.' >&2

  exit 1

fi



domains=(example.org www.example.org)

rsa_key_size=4096

data_path="./data/certbot"

email="" # Adding a valid address is strongly recommended

staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits



if [ -d "$data_path" ]; then

  read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision

  if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then

    exit

  fi

fi





if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then

  echo "### Downloading recommended TLS parameters ..."

  mkdir -p "$data_path/conf"

  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"

  curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"

  echo

fi



echo "### Creating dummy certificate for $domains ..."

path="/etc/letsencrypt/live/$domains"

mkdir -p "$data_path/conf/live/$domains"

docker-compose run --rm --entrypoint "\

  openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\

    -keyout '$path/privkey.pem' \

    -out '$path/fullchain.pem' \

    -subj '/CN=localhost'" certbot

echo





echo "### Starting nginx ..."

docker-compose up --force-recreate -d nginx

echo



echo "### Deleting dummy certificate for $domains ..."

docker-compose run --rm --entrypoint "\

  rm -Rf /etc/letsencrypt/live/$domains && \

  rm -Rf /etc/letsencrypt/archive/$domains && \

  rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot

echo





echo "### Requesting Let's Encrypt certificate for $domains ..."

#Join $domains to -d args

domain_args=""

for domain in "${domains[@]}"; do

  domain_args="$domain_args -d $domain"

done



# Select appropriate email arg

case "$email" in

  "") email_arg="--register-unsafely-without-email" ;;

  *) email_arg="--email $email" ;;

esac



# Enable staging mode if needed

if [ $staging != "0" ]; then staging_arg="--staging"; fi



docker-compose run --rm --entrypoint "\

  certbot certonly --webroot -w /var/www/certbot \

    $staging_arg \

    $email_arg \

    $domain_args \

    --rsa-key-size $rsa_key_size \

    --agree-tos \

    --force-renewal" certbot

echo



echo "### Reloading nginx ..."

docker-compose exec nginx nginx -s reload

I know its a monster, so you can use the below command to create it on your linux box without copy and pasting:

curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh

In any case, pay attention to these lines:

domains=(example.org www.example.org)

email="" # Adding a valid address is strongly recommended

Add your email and a space delimited list of the domains you are verifying. You are probably only doing one and that is okay!

Now, make the file executable and run it!

chmod +x init-letsencrypt.sh

./init-letsencrypt.sh

Once it has done its thing, you should be ready to fully launch this sucker!

docker-compose up -d

Test all is well. If I have messed anything up, let me know!

Jan 01, 2023

Raspberry Pi Dashboard

I got bored and thought it might be nice to have a simple way for my partner and I to see what is coming up next in our lives.

The finished product

So I'm not going to go over the exact setup here, it is pretty easy to do with a free account at dakboard.com. I'll just tell you the commands you need to do what I did. Just get yourself a fresh Raspberry Pi and input the following commands:

sudo apt update

sudo apt upgrade

That will get the old girl up-to-date and ready to do cool stuff.

You'll need to grab your Private URL for the board you have no doubt created at dakboard by now:

Get your URL from here.

So you are gonna need to setup chromium to launch when the pi boots. To do that, first ensure the following directory path exists:

~/.config/lxsession/LXDE-pi/

Once it does, run the following:

sudo nano ~/.config/lxsession/LXDE-pi/autostart

This file will tell your raspberry pi what to do instead of its normal boot process. Inside this file, we can paste this:

@xset s off

@xset -dpms

@xset s noblank

@chromium-browser --noerrdialogs --kiosk YOUR_URL_HERE

Make sure to replace YOUR_URL_HERE with your board URL.

Let's also get the pesky cursor to go back into the fiery chasm from whence it came:

sudo sed -i -- "s/#xserver-command=X/xserver-command=X -nocursor/" /etc/lightdm/lightdm.conf

That will pretty much do the job.

Bonus Round 1: .sh script to refresh the browser

If you don't want to wait the default one hour for the dashboard to update, you can install xdotool to help.

sudo apt install xdotool

Once this is installed, make yourself a nice .sh script and put this goodness within:

export DISPLAY=":0"

WID=$(xdotool search --onlyvisible --class chromium|head -1)

xdotool windowactivate ${WID}

xdotool key ctrl+F5

That should refresh the page when you run it. If it doesn't, let me know!

Bonus Round 2: Scheduling

To go the extra mile and save the planet, you can add a cronjob for disabling the monitor on a schedule.

To do this, we will need to disable DRM VC4 V3D driver. Not 100% sure what that is, but it gets in the way of turning the monitors on and off.

sudo nano /boot/config.txt

In that file, find the line dtoverlay=vc4-kms-v3dand comment it out.

This sucka

With that bad boy disabled, the following two commands can be used to turn the display on and off:

vcgencmd display_power 0

vcgencmd display_power 1

For all of you non-nerds (I assume that will be roughly none of you) 0 if off and 1 is on.

So to do this in crontab, first open the sudo crontab:

sudo crontab -e

If it asks you some nonsense about VIM and Nano, pick Nano. VIM is for the master race and I can't do it.

Then, paste this gear in there:

0 19 * * * /usr/bin/vcgencmd display_power 0

0 7 * * * /usr/bin/vcgencmd display_power 1

This is set to have it on from 7am to 7pm. You can probably figure out what to change to get the time you want, but if you need help, crontab-guru is a great resource!

Conclusion

Oh my god, that was longer than I wanted it to be. Hope that was helpful. If not, just let me know and I will likely do nothing about it. Peace.

← Previous Next → Page 7 of 12