Category: Dev Stuff

  • Quick Tip: Looping a command in bash

    Quick Tip: Looping a command in bash

    I recently came across the need to watch my disk space while running a slow program to make sure I didn’t run out. If I did, the command would fail silently and I’d have to start over again.

    This can easily be done with this short snippet:

    watch -n10 bash -c "df -h | ack disk1s5"Code language: JavaScript (javascript)
    Every 10.0s: bash -c df -h | ack disk1s5                                                                                  mbp.local: Mon Jul 20 15:09:51 2020
    
    /dev/disk1s5           488245288  10940872 144033352     8%   488237 4881964643    0%   /

    The important part here is disk1s5, which is the device file for the partition I wanted to watch. If you need to find this, it can be done simply by running the df as a whole:

    $ df
    Filesystem             1K-blocks      Used Available Capacity  iused      ifree %iused  Mounted on
    /dev/disk1s5           488245288  10940872 144035124     8%   488237 4881964643    0%   /
    devfs                        191       191         0   100%      662          0  100%   /dev
    /dev/disk1s1           488245288 331456068 144035124    70%  1379027 4881073853    0%   /System/Volumes/Data
    /dev/disk1s4           488245288   1048596 144035124     1%        1 4882452879    0%   /private/var/vm
    map auto_home                  0         0         0   100%        0          0  100%   /System/Volumes/Data/home
    /dev/disk1s3           488245288    516448 144035124     1%       48 4882452832    0%   /Volumes/RecoveryCode language: PHP (php)

    That is all.

    Photo by Wendy Wei from Pexels

  • Open source ngrok alternative

    Open source ngrok alternative

    During a client onsite last year, I was first introduced to ngrok. Ngrok provides “secure introspectable tunnels to localhost.” The free tier of ngrok provides temporary, random subdomains to use. This is fine most of the time, but kind of causes problems for things like Jetpack that require persistent domain names for connecting.

    While I could shell out the $5/month for the lowest paid tier of ngrok, I would still be limited to a certain number of domains and connections.

    While looking for an alternative to ngrok, I came across sish. Sish is “an open source serveo/ngrok alternative. HTTP(S)/WS(S)/TCP Tunnels to localhost using only SSH.” To be honest, I don’t understand most of those words, but that won’t stop me!

    I of course needed a server somewhere to run this on, so I ran over to DigitalOcean and decided to spend my $5/month on a general purpose VPS instead (Here’s my DigitalOcean referral link if you’re so inclined).

    What follows is my notes I took to install sish and get it up and running. I can’t guarantee they’re perfect, and I don’t feel like deleting my VPS and starting over again just to make sure 🙂 If you see something wrong, feel free to comment me a correction or question.

    Step 1: Make a wildcard subdomain (ex *.sish.example.com)

    Step 2: Set up a DigitalOcean droplet.

    Step 3. Log in and run:

    # Make a house a home
    echo "export PS1=\"\\[\\033[38;5;33m\\]\\u\\[\$(tput sgr0)\\]\\[\\033[38;5;11m\\]@\\[\$(tput sgr0)\\]\\[\\033[38;5;33m\\]\\H\\[\$(tput sgr0)\\]\\[\\033[38;5;15m\\]:\\[\$(tput sgr0)\\]\\[\\033[38;5;11m\\]\\w\\[\$(tput sgr0)\\]\\[\\033[38;5;15m\\]\\\\$ \\[\$(tput sgr0)\\]\"" >> ~/.bashrc
    source ~/.bashrc
    apt update
    apt upgrade
    apt install ack-grep mc byobu git curl locate
    updatedb
    
    # Security
    ufw allow http
    ufw allow https
    ufw allow ssh
    ufw allow 2222
    ufw --force enable
    apt install fail2ban
    
    # Create swapfile
    fallocate -l 1G /swapfile
    chmod 600 /swapfile
    mkswap /swapfile
    swapon /swapfile
    echo '/swapfile none swap sw 0 0' | tee -a /etc/fstab
    
    # Install Docker
    apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu/ $(lsb_release -cs) stable"
    apt update
    apt install docker-ce docker-ce-cli containerd.io
    
    # Install Certbot
    certbot-auto certonly --manual -d *.sish.example.com --agree-tos --no-bootstrap --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
    certbot certonly –manual -d *.sish.example.com –agree-tos –no-bootstrap –manual-public-ip-logging-ok –preferred-challenges dns-01 –server https://acme-v02.api.letsencrypt.org/directory
    
    # Install Keys
    curl https://github.com/my_github_username.keys > ~/sish/pubkeys/my_github_username
    cp -f /etc/letsencrypt/live/sish.example.com-0001/* ~/sish/ssl/
    ssh-keygen
    ln -s ~/.ssh/id_rsa ~/sish/ssh_key
    
    # Run Sish
    cat << "EOF" > /root/sish/docker-start.sh
    /usr/bin/docker run --name sish \
      -v ~/sish/ssl:/ssl \
      -v ~/sish/keys:/keys \
      -v ~/sish/pubkeys:/pubkeys \
      --restart unless-stopped \
      --net=host antoniomika/sish:latest \
      -sish.addr=sish.example.com:2222 \
      -sish.adminenabled=true \
      -sish.auth=false \
      -sish.bindrandom=false \
      -sish.domain=sish.example.com \
      -sish.forcerandomsubdomain=false \
      -sish.http=:80 \
      -sish.https=:443 \
      -sish.httpsenabled=true \
      -sish.httpspems=/ssl \
      -sish.keysdir=/pubkeys \
      -sish.pkloc=/keys/ssh_key \
      -sish.redirectrootlocation=https://example.com/ \
      -sish.serviceconsoleenabled=true
    EOF
    
    cat << EOF > /etc/systemd/system/docker-sish.service
    # Thanks to https://blog.container-solutions.com/running-docker-containers-with-systemd
    
    [Unit]
    Description=Sish container
    Requires=docker.service
    After=docker.service
    
    [Service]
    TimeoutStartSec=0
    Restart=always
    ExecStartPre=-/usr/bin/docker stop sish
    ExecStartPre=-/usr/bin/docker rm sish
    ExecStartPre=/usr/bin/docker pull antoniomika/sish:latest
    ExecStart=/bin/bash /root/sish/docker-start.sh
    ExecStop=/usr/bin/docker stop sish
    RemainAfterExit=true
    
    [Install]
    WantedBy=default.target
    EOF
    
    systemctl enable docker-sish
    systemctl start docker-sishCode language: PHP (php)

    From here, I can now set up a shortcut program to run locally to start a tunnel:

    cat << "EOF" > /usr/local/bin/sish
    #/bin/bash
    ssh -p 2222 -R $1:80:localhost:80 root@sish.example.com
    EOF
    chmod +x /usr/local/bin/sishCode language: PHP (php)

  • Quick Tip: Viewing Headers With Curl

    Quick Tip: Viewing Headers With Curl

    Something that I do often at work is to check HTTP headers for random things such as redirects, cache headers, proxies, ssl, etc.

    A common way this is done is by using the -I (--header) switch:

    $ curl -I http://example.com/
    HTTP/1.1 200 OK
    Content-Encoding: gzip
    Accept-Ranges: bytes
    Cache-Control: max-age=604800
    Content-Type: text/html
    Date: Wed, 27 Jun 2018 22:03:57 GMT
    Etag: "1541025663+gzip"
    Expires: Wed, 04 Jul 2018 22:03:57 GMT
    Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
    Server: ECS (atl/FC94)
    X-Cache: HIT
    Content-Length: 606
    Code language: JavaScript (javascript)

    The downside to this is that it uses an HTTP HEAD request, which can sometimes return different headers or different information than a standard GET request. This can be fixed by using the -X (--request) switch. This overrides the default HEAD?request with whatever you choose:

    $ curl -I -XGET http://example.com/
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Cache-Control: max-age=604800
    Content-Type: text/html
    Date: Wed, 27 Jun 2018 22:07:47 GMT
    Etag: "1541025663"
    Expires: Wed, 04 Jul 2018 22:07:47 GMT
    Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
    Server: ECS (atl/FC90)
    Vary: Accept-Encoding
    X-Cache: HIT
    Content-Length: 1270
    Code language: JavaScript (javascript)

    I like to just combine them into one quick command: curl -IXGET http://example.com/