<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[from dusk till dawn]]></title><description><![CDATA[notes from wasted nights]]></description><link>https://wasted.gerdez.net/</link><image><url>https://wasted.gerdez.net/favicon.png</url><title>from dusk till dawn</title><link>https://wasted.gerdez.net/</link></image><generator>Ghost 5.8</generator><lastBuildDate>Thu, 14 May 2026 23:48:12 GMT</lastBuildDate><atom:link href="https://wasted.gerdez.net/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Configuring EdgeRouters]]></title><description><![CDATA[I like things to do what they are supposed to do, so in my home network I have a separate device for every task. When it comes to home routers, I think the Ubiquiti EdgeRouter X is pretty unbeatable in the price vs. features category.]]></description><link>https://wasted.gerdez.net/edgerouterx/</link><guid isPermaLink="false">623cb37ab124660001df6dc1</guid><category><![CDATA[ubiquiti]]></category><category><![CDATA[router]]></category><category><![CDATA[edgerouter]]></category><category><![CDATA[ER-X]]></category><category><![CDATA[configure]]></category><dc:creator><![CDATA[gerdez]]></dc:creator><pubDate>Fri, 06 Mar 2026 18:43:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1554098415-4052459dc340?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fHJvdXRlcnxlbnwwfHx8fDE3NzI4MzY1MDh8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1554098415-4052459dc340?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fHJvdXRlcnxlbnwwfHx8fDE3NzI4MzY1MDh8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="Configuring EdgeRouters"><p><strong><em>Update 2026:</em></strong> Firmware 3.0.1 released. With new UI and Wireguard support. Wow. For a +10 year router... Installation is the same.</p><p>If you are like me, you don&apos;t call an all-in-one spaceship a router. I like things to do what they are supposed to do, so in my home network I have a separate device for every task. When it comes to home routers, I think the <a href="https://store.ui.com/collections/operator-edgemax-routers/products/edgerouter-x"><strong>Ubiquiti EdgeRouter X</strong></a> is pretty unbeatable in the price vs. features category. I won&apos;t sing odes about how nice the interface or how great the command line is. All I will say is that this little piece of hardware is probably one of the most reliable devices I&apos;ve ever had. Too bad they discontinued it.</p><p>Nevertheless, I did find an <strong>EdgeRouter X SFP</strong>,<strong> </strong>which is basically the same. It&apos;s always nice to have a backup, in case my trusty old one decides to go sleep with the fishes. I used the wizard to set up the basic operating mode, then since it runs Linux (<a href="https://en.wikipedia.org/wiki/Vyatta">vyatta</a> on 1.x), I went for the command line &#x1F92A; The official documentation on Ubiquiti&apos;s site is great, but I gathered all I needed in one place. I hope you&apos;ll also find it useful. Here we go!</p><h2 id="update-the-edgerouter-firmware">Update the EdgeRouter firmware</h2><p>Check if there is enough space in /tmp directory (as of now 80-90 MB should be enough)</p><pre><code class="language-bash">show system storage
# check /tmp space</code></pre><p>Download the firmware to /tmp</p><pre><code class="language-bash">curl https://dl.ui.com/firmwares/edgemax/v1.10.11/ER-e50.v1.10.11.5274269.tar &gt; /tmp/ER-e50.v1.10.11.5274269.tar</code></pre><p>Checksum the file, just to be sure</p><pre><code class="language-bash">sha256sum /tmp/ER-e50.v1.10.11.5274269.tar</code></pre><p>Check to see if enough space on / (root) for the new firmware</p><pre><code class="language-bash">show system storage</code></pre><p>Check if you have a backup image (older version)</p><pre><code class="language-bash">show system image storage</code></pre><p>If there is not enough space, you can delete the backup image (the one without <em>default boot</em>)</p><pre><code class="language-bash">delete system image</code></pre><p>Install the new firmware</p><pre><code class="language-bash">add system image /tmp/ER-e50.v1.10.11.5274269.tar</code></pre><p>Check if the new image is selected for the default boot image</p><pre><code class="language-bash">show system image</code></pre><p>If something goes wrong during the upgrade, you can swap between boot images</p><pre><code class="language-bash">set system image default-boot</code></pre><p><strong>Now you should wait 3-5 minutes.</strong> Trust me on this. Then, reboot the router</p><pre><code class="language-bash">reboot</code></pre><p>Check if the upgrade was successfull</p><pre><code class="language-bash">show version</code></pre><blockquote>Note - Other ways to get the latest firmware:</blockquote><pre><code class="language-bash"># Download the image directly from the Ubiquiti website using HTTPS
add system image https://dl.ui.com/.../firmware.tar

# Downloading the image from a remote server using TFTP, FTP or SCP
add system image tftp://ip-address/firmware.tar
add system image scp://ip-address/firmware.tar
add system image ftp://ip-address/firmware.tar

# Copying the firmware from another machine to the router
scp -P &lt;ssh port&gt; ~/Downloads/ER-e50.v3.0.1.5862409.tar user@&lt;router-ip&gt;:/tmp</code></pre><h2 id="upgrading-the-edgerouter-bootloader">Upgrading the Edgerouter bootloader</h2><p>After rebooting the router for the firmware upgrade, you may encounter a similar MOTD like the one below:</p><pre><code class="language-bash">Boot image can be upgraded to version [ e50_002_4c817 ].
Run &quot;add system boot-image&quot; to upgrade boot image.
</code></pre><p>This is because, on most EdgeRouter models, the bootloader version is not updated automatically with a firmware upgrade and must be updated manually. The EdgeRouter bootloader controls functions such as the LED boot behavior, configuration/driver loading and much more.</p><p>To upgrade the bootloader version run</p><pre><code class="language-bash">add system boot-image</code></pre><p>Reboot the router again</p><pre><code class="language-bash">reboot</code></pre><p>Check if the upgrade was successfull or a boot-image update is available</p><pre><code class="language-bash">show system boot-image</code></pre><p>Configure the default firewall</p><p>Enter configuration mode.</p><pre><code class="language-bash">configure</code></pre><p>Configure the <strong>WAN_IN</strong> firewall policy (already created by wizard).</p><pre><code>set firewall name WAN_IN default-action drop
set firewall name WAN_IN description &apos;WAN to internal LAN&apos;
set firewall name WAN_IN rule 10 action accept
set firewall name WAN_IN rule 10 description &apos;Allow established/related&apos;
set firewall name WAN_IN rule 10 state established enable
set firewall name WAN_IN rule 10 state related enable
set firewall name WAN_IN rule 20 action drop
set firewall name WAN_IN rule 20 description &apos;Drop invalid state&apos;
set firewall name WAN_IN rule 20 state invalid enable
</code></pre><p>Configure the <strong>WAN_LOCAL</strong> firewall policy (already created by wizard).</p><pre><code>set firewall name WAN_LOCAL default-action drop
set firewall name WAN_LOCAL description &apos;WAN to router&apos;
set firewall name WAN_LOCAL rule 10 action accept
set firewall name WAN_LOCAL rule 10 description &apos;Allow established/related&apos;
set firewall name WAN_LOCAL rule 10 state established enable
set firewall name WAN_LOCAL rule 10 state related enable
set firewall name WAN_LOCAL rule 20 action drop
set firewall name WAN_LOCAL rule 20 description &apos;Drop invalid state&apos;
set firewall name WAN_LOCAL rule 20 state invalid enable
</code></pre><p>Configure the <strong>WAN_OUT</strong> firewall policy</p><pre><code>set firewall name WAN_OUT default-action accept
set firewall name WAN_OUT description &apos;Internal LAN to WAN&apos;
set firewall name WAN_OUT rule 20 action reject
set firewall name WAN_OUT rule 20 description &apos;Reject invalid state&apos;
set firewall name WAN_OUT rule 20 state invalid enable
</code></pre><p>Attach the firewall policies to the WAN interface in the inbound and local direction.</p><pre><code>set interfaces ethernet eth0 firewall in name WAN_IN
set interfaces ethernet eth0 firewall local name WAN_LOCAL
set interfaces ethernet eth0 firewall out name WAN_OUT
</code></pre><p><strong>or for PPPoE</strong> (in PPPoE scenario <code>eth0</code> only carries ppp encapsulated packets. These packets won&apos;t hit the routing engine at all, so an iptables rule on <code>eth0</code> would be futile). In this example the PPPoE interface is on <code>eth0</code></p><pre><code>set interfaces ethernet eth0 pppoe 0 firewall in name WAN_IN
set interfaces ethernet eth0 pppoe 0 firewall local name WAN_LOCAL
set interfaces ethernet eth0 pppoe 0 firewall out name WAN_OUT
</code></pre><blockquote>Note: EdgeRouter firewall policies only become active when they are attached to an interface + direction.</blockquote><p>Commit the changes and save the configuration</p><pre><code class="language-bash">commit ; save</code></pre><h2 id="other-useful-commands">Other useful commands</h2><p>Create new user and delete the default</p><pre><code>set system login user &lt;username&gt; authentication plaintext-password &lt;password&gt;
set system login user &lt;username&gt; level admin
delete system login user ubnt
sudo rm -r /home/ubnt
</code></pre><p>Set the router hostname</p><pre><code class="language-bash">set system host-name YourNewHostname</code></pre><p>Set timezone</p><pre><code class="language-bash">set system time-zone Europe/Athens</code></pre><p>Change default HTTPS GUI port</p><pre><code class="language-bash">set service gui https-port 60443</code></pre><p>Change default SSH port</p><pre><code class="language-bash">set service ssh port 60022</code></pre><p>Set pre-login SSH banner</p><pre><code class="language-shell">set system login banner pre-login &quot;\n\t-~===__._Welcome_to_MyRouter_.__===~-\n\n\tThis system is restricted to authorized users only.\n\tYour data and all activities on this system are logged.\n\tUnauthorized access will be fully investigated and reported\n\tto the appropriate law enforcement agencies.\n\n&quot;</code></pre><p>Delete pre-login banner, go back to default</p><pre><code class="language-bash">delete system login banner ; set system login banner</code></pre><p>Set post-login SSH banner</p><pre><code class="language-bash">set system login banner post-login &quot;\nMessage of the day\n&quot;</code></pre><p>Delete post-login banner, go back to default</p><pre><code class="language-bash">delete system login banner post-login &quot;\nMessage of the day\n&quot;</code></pre><p>Set system DNS servers</p><pre><code class="language-bash">set system name-server &lt;ip-address1&gt;
set system name-server &lt;ip-address2&gt;</code></pre><p>Check DNS servers used by the router and statistics</p><pre><code class="language-bash">show dns forwarding nameservers
show dns forwarding statistics</code></pre><p>Set router to only use the system DNS servers (without those from ISP)</p><pre><code class="language-bash">set service dns forwarding system</code></pre><p>Set subnet domain-name</p><pre><code class="language-bash">set service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 domain-name mylan.local</code></pre><p>Disable ipv6</p><pre><code class="language-bash">set system ipv6 disable</code></pre><p>Reconnect PPPoE</p><pre><code class="language-bash">disconnect interface pppoe0
connect interface pppoe0</code></pre><p>This is set by the wizard for PPPoE - Below commands will &apos;fix&apos; connectivity to remote sites where ICMP is blocked and PMTU is broken:</p><pre><code class="language-bash"># if you don&apos;t know your connection type for sure - sets it on all if&apos;s
set firewall options mss-clamp interface-type all

# for pppoe use
set firewall options mss-clamp interface-type pppoe

# set mss
set firewall options mss-clamp mss 1452</code></pre><p>See System Logs</p><pre><code class="language-bash">dmesg
# or
cat /var/log/messages</code></pre><p>Bandwidth test with iperf (though not relevant when run from the EdgeRouter)</p><pre><code class="language-bash">iperf3 -c public.iperf.server -p &lt;port&gt;
# add -R for reverse</code></pre><p>Show config (and also export them)</p><pre><code class="language-bash">show configuration
# or add &quot;| tee config.txt&quot; to also export them to you home folder</code></pre><p>Check hardware offloading status</p><pre><code class="language-bash">show ubnt offload</code></pre><p>Enable (disable) hardware offload</p><pre><code class="language-bash">set system offload hwnat enable # or disable
set system offload ipsec enable # or disable</code></pre><ul><li><strong>WARNING:</strong> IPsec offload on ER-X platform is causing problems to L2TP remote-access VPN and IPV6 site-to-site IPSec VPN. You should <strong>not</strong> enable IPsec offload if you are using any of above. IPv4 site-to-site IPsec VPN is <strong>working correctly</strong> with IPsec offload. PPTP VPN is <strong>working correctly</strong> with IPsec offload. Only ER-X/ER-X-SFP/EP-R6 models are affected by this issue. This issue is to be fixed in future release.</li></ul><h2 id="links-you-may-need">Links you may need</h2><p><a href="https://help.ui.com/hc/en-us/articles/204950294-EdgeRouter-L2TP-IPsec-VPN-Server">Configure L2TP IPsec VPN Server</a></p><p><a href="https://help.ui.com/hc/en-us/articles/360019289113" rel="noopener noreferrer nofollow">Official guide for EdgeRouter TFTP recovery</a></p><p><a href="https://help.ui.com/hc/en-us/articles/360009103974" rel="noopener noreferrer nofollow">EdgeRouter - Device LED Statuses</a></p><p>That is all for this note. And one more thing...</p><blockquote>If you cannot do great things, do small things in a great way.</blockquote>]]></content:encoded></item><item><title><![CDATA[Shoving ads where the sun never shines with Pi-hole]]></title><description><![CDATA[Since I recently upgraded the case of my trusty Pi to an Argon ONE, I thought it's a good time to share the procedure of installing one of the best pieces of software I have ever used: namely Pi-hole]]></description><link>https://wasted.gerdez.net/shoving-ads-where-the-sun-never-shines-with-pi-hole/</link><guid isPermaLink="false">61ed096fc0945b0001a8ec2f</guid><category><![CDATA[raspberrypi]]></category><category><![CDATA[docker]]></category><category><![CDATA[cloudflared]]></category><category><![CDATA[pi-hole]]></category><dc:creator><![CDATA[gerdez]]></dc:creator><pubDate>Wed, 26 Jan 2022 21:03:12 GMT</pubDate><media:content url="https://wasted.gerdez.net/content/images/2022/01/DSCF4231.JPG" medium="image"/><content:encoded><![CDATA[<img src="https://wasted.gerdez.net/content/images/2022/01/DSCF4231.JPG" alt="Shoving ads where the sun never shines with Pi-hole"><p>Since I recently upgraded the case of my trusty Raspberry Pi to an <a href="https://www.argon40.com/argon-one-v-2-case-for-raspberry-pi-5.html">Argon ONE</a> (the last Pi case you&apos;ll ever need, really), I thought it&apos;s a good time to share the procedure of installing one of the best pieces of software I have ever used: namely <a href="https://pi-hole.net">Pi-hole</a>. This little DNS server whacks most of the ads before the request even leaves your network, making internet browsing a much better experience. Great thing is, once put in place, it&apos;s set and forget. You will realize how much you love it when you surf the net without it &#x1F92A;</p><p>I like things organized and my Pi runs other things besides Pi-hole so I&apos;ll use Docker. Instructions are for <strong>Raspbian</strong> (Raspberry Pi OS), but should be similar on other OS&apos;s as Pi-hole is not exclusive to the Raspberry.</p><h2 id="get-docker">Get Docker</h2><pre><code class="language-shell">curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh</code></pre><p>... and docker compose:</p><pre><code class="language-shell">sudo mkdir -p /usr/local/lib/docker/cli-plugins
sudo curl -SL https://github.com/docker/compose/releases/download/v2.1.1/docker-compose-linux-armv7 -o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose</code></pre><h2 id="setting-up-pi-hole">Setting up Pi-hole</h2><p>Create a directory for Pi-hole persistent files and edit the docker compose file:</p><pre><code class="language-shell">mkdir -p ~/pihole/pihole ~/pihole/dnsmasq.d
cd ~/pihole
nano docker-compose.yml</code></pre><p>Paste the following into <em>docker-compose.yml</em></p><pre><code>version: &quot;3&quot;

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:2021.12
    restart: unless-stopped
    network_mode: host
    #ports:
      #- &quot;53:53/tcp&quot;
      #- &quot;53:53/udp&quot;
      #- &quot;67:67/udp&quot; #needed only if you want PiHole-DHCP
      #- &quot;80:80/tcp&quot;
    dns:
      - 127.0.0.1 #Sets your container&apos;s resolve settings to localhost - may fix resolution errors on container restart.
      - 1.1.1.1 #Sets a backup server of your choosing in case DNSMasq has problems starting
    environment:
      TZ: &apos;Europe/Athens&apos;
      # Set to your server&apos;s LAN IP, used by web block modes and lighttpd bind address.
      #FTLCONF_REPLY_ADDR4: &apos;YOUR.SERVER.IP&apos; #called ServerIP in the past
      ServerIP: YOUR.SERVER.IP # Will be deprecated
      WEBPASSWORD: &apos;&apos; #blank
      # to reset afterwards run docker exec -it pihole_container_name pihole -a -p
      PIHOLE_DNS_: &apos;127.0.0.1#5053;127.0.0.1#5053&apos;
    volumes:
      - &apos;./pihole/:/etc/pihole/&apos;
      - &apos;./dnsmasq.d/:/etc/dnsmasq.d/&apos;</code></pre><p>A few explanations here - I choose to run the container in <em>host</em> network mode as it is easier in my setup. If you want to define required ports for bridge mode, I&apos;ve left the ports in the config, just comment <code>network_mode</code> and uncomment the <code>ports</code> section. Regarding Pi-hole, version 2022.01 (latest as of now) was having problems with FTL on my Pi, so I use the 2021.12 version, but you can try <em>latest</em>.</p><p>In the <code>environment</code> section you should change:</p><ul><li><code>TZ</code>: Your timezone</li><li><code>ServerIP</code>: your hosting server&apos;s IP. Although the documentation states that <em>ServerIP</em> variable will be deprecated and you should use <code>FTLCONF_REPLY_ADDR4</code>, I couldn&apos;t get it to work with the new setting. Maybe in future versions.</li><li><code>WEBPASSWORD</code>: should be changed to whatever you like.</li><li><code>PIHOLE_DNS_</code>: is the upstream DNS that Pi-hole uses. These can be set up also in the web interface of Pi-hole later, so it&apos;s optional to specify them here. I always define two, because if not, it will auto-pick <em>EvilEmpire</em> for the second one and we don&apos;t want that. You may notice I point it to localhost port 5053, that&apos;s where <em>cloudflared</em> runs for DNS-over-HTTPS. More on that later.</li></ul><p>Now you can fire up the Pi-hole container.</p><pre><code class="language-shell">cd ~/pihole
sudo docker compose up -d</code></pre><h2 id="finishing-up">Finishing up</h2><p>After you started the Pi-hole container, you must configure your DHCP server (or client) to point to Pi-hole&apos;s IP as DNS server. Then navigate to <a href="http://pi.hole/admin/">http://pi.hole/admin/</a> and you are greated by the Pi-hole login screen. Here, use your pass to log in and configure your ad-black-hole.</p><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2022/01/Screenshot-2022-01-26-at-21.44.03.png" class="kg-image" alt="Shoving ads where the sun never shines with Pi-hole" loading="lazy" width="2500" height="796"></figure><p>The first thing you should do, is check that FTL is running normally. You can do this by looking for the green <em>Active</em> status top-left of Pi-hole&apos;s web interface. Then configure your blocklists by clicking <strong>Group Management -&gt; Adlists</strong>. The best collection of blacklists I found is on <a href="https://firebog.net">firebog.net</a>. Check it out.</p><p>If you haven&apos;t configured your upstream DNS servers, go to <strong>Settings -&gt; DNS</strong>. As you will see, there is a wide range of options to select from like Google, Cloudflare, Quad9 and so on.</p><p>Happy browsing! &#x1F609;</p><h2 id="if-you-want-dns-over-https-doh">If you want DNS-over-HTTPS (DoH)</h2><p>For this, we will need to configure <em><strong>cloudflared</strong></em> on our Pi so Pi-hole can use it as upstream DNS. There is a very good guide on how to do this in the <a href="https://docs.pi-hole.net/guides/dns/cloudflared/">Pi-hole documentation</a>. Below the configuration for <em>armhf 32-bit</em>.</p><pre><code>wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm
sudo cp ./cloudflared-linux-arm /usr/local/bin/cloudflared
sudo chmod +x /usr/local/bin/cloudflared
cloudflared -v</code></pre><p>The last command above is to test the version of the daemon. If all is good, proceed with creating a <strong>cloudflared</strong> user to run the daemon and a configuration file.</p><pre><code class="language-shell">sudo useradd -s /usr/sbin/nologin -r -M cloudflared
sudo nano /etc/default/cloudflared</code></pre><p>This file contains the command-line options that get passed to <strong>cloudflared</strong> on startup. I have mine like this, comment/uncomment it to fit your needs. I know which line you will touch first &#x1F913;.</p><pre><code class="language-config"># Commandline args for cloudflared

# Normal resolver
#CLOUDFLARED_OPTS=--port 5053 --upstream https://1.1.1.1/dns-query --upstream https://1.0.0.1/dns-query

# Malware off - 1.1.1.2/1.0.0.2
#CLOUDFLARED_OPTS=--port 5053 --upstream https://security.cloudflare-dns.com/dns-query

# Malware and pr0n off - 1.1.1.3/1.0.0.3
CLOUDFLARED_OPTS=--port 5053 --upstream https://family.cloudflare-dns.com/dns-query</code></pre><p>Malware and pr0n off will not work with IP&apos;s. I got it working with the URL&apos;s and cloudflared -v 2021.11. To test when setup is done: <code>dig @127.0.0.1 -p 5053 nudity.testcategory.com</code> (or phishing.testcategory.com). Should resolve to 0.0.0.0</p><p>Next, update the permissions for the configuration file and <em>cloudflared</em> binary to allow access for the <em>cloudflared</em> user:</p><pre><code class="language-shell">sudo chown cloudflared:cloudflared /etc/default/cloudflared
sudo chown cloudflared:cloudflared /usr/local/bin/cloudflared</code></pre><p>Then create the <em>systemd</em> script to control running of the service:</p><pre><code class="language-shell">sudo nano /etc/systemd/system/cloudflared.service</code></pre><p>Paste the following into it:</p><pre><code class="language-config">[Unit]
Description=cloudflared DNS over HTTPS proxy
After=syslog.target network-online.target

[Service]
Type=simple
User=cloudflared
EnvironmentFile=/etc/default/cloudflared
ExecStart=/usr/local/bin/cloudflared proxy-dns $CLOUDFLARED_OPTS
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target
</code></pre><p>Enable the service to run on startup, then start the service and check its status:</p><pre><code class="language-shell">sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo systemctl status cloudflared</code></pre><p>Finally, go to <strong>Pi-hole</strong> settings and set the upstream DNS like this:</p><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2022/01/Screenshot-2022-01-26-at-22.53.00.png" class="kg-image" alt="Shoving ads where the sun never shines with Pi-hole" loading="lazy" width="982" height="520"></figure><p>You are all done. YAY!</p><p>And one more thing ...</p><blockquote>Simplicity is the ultimate sophistication.</blockquote><p>Hmm ... hmm ... I just can&apos;t get enough of my ArgonONE case ... &#x1F924;</p><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2022/01/DSCF4216.JPG" class="kg-image" alt="Shoving ads where the sun never shines with Pi-hole" loading="lazy" width="2000" height="1333"></figure>]]></content:encoded></item><item><title><![CDATA[Set up an FTP server to use with your friends]]></title><description><![CDATA[I've been itching to set up an FTP server on my VPS, so that when one of my friend asks for some files, I have a quick way of meeting their needs. I ended up setting up a vsftpd server.]]></description><link>https://wasted.gerdez.net/set-up-an-ftp-server-to-use-with-your-friends/</link><guid isPermaLink="false">61d9d131b13ce600019e3e81</guid><category><![CDATA[vsftpd]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[gerdez]]></dc:creator><pubDate>Sat, 08 Jan 2022 19:47:27 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1640494828784-8d535fd40558?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDQxfHx0cmFuc2ZlciUyMGZpbGVzfGVufDB8fHx8MTY0MTY2NTI3NQ&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1640494828784-8d535fd40558?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDQxfHx0cmFuc2ZlciUyMGZpbGVzfGVufDB8fHx8MTY0MTY2NTI3NQ&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Set up an FTP server to use with your friends"><p>I&apos;ve been itching to set up an FTP server on my CentOS VPS, so that whenever one of my friend asks for some files, I have a quick way of meeting their needs. I ended up setting up a <strong>vsftpd</strong> server. As inspiration I used <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-vsftpd-for-a-user-s-directory-on-ubuntu-20-04">this</a> great tutorial from digitalocean. However the problem with it is that it was set up for a separate directory for each user. Not what I wanted. So I dived deep.</p><p>First things first - install the FTP server. It&apos;s a lot easier to set this whole thing up if you become root.</p><pre><code class="language-bash">sudo -i
dnf install vsftpd</code></pre><p>Next the firewall. Don&apos;t ever forget the firewall. &#x1F602; Now here, you have some choices to make. Do you want to expose port 21, so that every bot on the planet will try and violate your port or you choose a custom one. I went with the latter. You will need a port for FTP commands (default 21) and a port range for actual data transfer in <em>passive mode</em> (server decides the port). If confused, <a href="https://www.jscape.com/blog/bid/80512/active-v-s-passive-ftp-simplified">click</a>.</p><p>The default firewall (called <a href="https://firewalld.org">firewalld</a>) on RedHat and the like ... <a href="https://www.youtube.com/watch?v=HaF-nRS_CWM">really whips the llama&apos;s ass</a>. Not only that the control commands make a lot of sense, but you can create your own <em>services </em>to easily add to the rules. Which we are going to do now, since we are here. To set up a service definition for <strong>firewalld</strong> all you have to do is edit an <code>*.xml</code> in a certain location.</p><pre><code class="language-bash">nano /usr/lib/firewalld/services/vsftpd-custom.xml</code></pre><p>Add the following lines and save.</p><pre><code class="language-xml">&lt;service&gt;
  	&lt;short&gt;VSFTPD-custom&lt;/short&gt;
  	&lt;description&gt;VSFTPD custom port settings&lt;/description&gt;
  	&lt;port port=&quot;33021&quot; protocol=&quot;tcp&quot;/&gt;
  	&lt;port port=&quot;33030-33050&quot; protocol=&quot;tcp&quot;/&gt;
&lt;/service&gt;</code></pre><p>All you have to do afterwards is to reload the firewall so it recognizes the freshly defined service, add the service as permanent and reload <strong>firewalld</strong> again.</p><pre><code class="language-bash">firewall-cmd --reload
firewall-cmd --add-service=vsftpd-custom --permanent
firewall-cmd --reload
firewall-cmd --list-all</code></pre><p>Running the last command should reveal all your active firewall entries and you should see <em>VSFTPD-custom</em> among services. I think it&apos;s nice that definitions have a name so you don&apos;t have to remember the reason for each of the 4937 ports you opened.</p><p>Okay, now with the firewall out of the way, let&apos;s get on with the FTP server. First we back up the default configuration (just in case) and create our own.</p><pre><code class="language-bash">mv /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bkp
nano /etc/vsftpd/vsftpd.conf</code></pre><p>Next thing, paste the below configuration. The default has some pretty clear comments and I also added my own, so I won&apos;t repeat myself here.</p><pre><code class="language-config"># Config guide: https://web.mit.edu/rhel-doc/5/RHEL-5-manual/Deployment_Guide-en-US/s1-ftp-vsftpd-conf.html
#
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
write_enable=YES
#
# Default umask for local users is 077. You may wish to change this to 022,
# if your users expect that (022 is used by most other ftpd&apos;s)
#022=755; 002=775 (to calculate 777-what you need)
local_umask=022
#local_umask=002
#
# Activate directory messages - messages given to remote users when they
# go into a certain directory.
dirmessage_enable=YES
#
# Activate logging of uploads/downloads.
xferlog_enable=YES
#
# Make sure PORT transfer connections originate from port 20 (ftp-data).
connect_from_port_20=YES
#
# You may override where the log file goes if you like. The default is shown
# below.
#xferlog_file=/var/log/xferlog
#
# If you want, you can have your log file in standard ftpd xferlog format.
# Note that the default log file location is /var/log/xferlog in this case.
xferlog_std_format=YES
#
# You may change the default value for timing out an idle session.
#idle_session_timeout=600
#
# You may change the default value for timing out a data connection.
#data_connection_timeout=120
#
# You may fully customise the login banner string:
#ftpd_banner=Welcome to blah FTP service.
#
# When &quot;listen&quot; directive is enabled, vsftpd runs in standalone mode and
# listens on IPv4 sockets. This directive cannot be used in conjunction
# with the listen_ipv6 directive.
listen=NO
# with ipv6 it listens also to ipv4
listen_ipv6=YES
#
# Port for FTP server to listen on; comment to use default 21
listen_port=33021
#
pam_service_name=vsftpd
#
# Only allow users on list
userlist_enable=YES
userlist_file=/etc/vsftpd/vsftpd.userlist
# However, userlist_deny=NO alters the setting, meaning that only users explicitly listed in userlist_file=/etc/vsftpd/vsftpd.userlist will be permitted to login.
userlist_deny=NO
#
# (Warning! chroot&apos;ing can be very dangerous. If using chroot, make sure that
# the user does not have write access to the top level directory within the
# chroot)
#
# Jail ftp users to ftp root
chroot_local_user=YES
#
# writeable local root
#allow_writeable_chroot=YES
#
# define local root
local_root=/var/ftp/pub
#
# Ports used for PASsiVe mode
pasv_min_port=33030
pasv_max_port=33050
#
#for users to have ftp go to their home dir
#user_sub_token=$USER
#local_root=/home/$USER/ftp
#
# Securing with TLS/SSL (uncomment all bellow)
#rsa_cert_file=/etc/pki/tls/private/vsftpd.pem
#rsa_private_key_file=/etc/pki/tls/private/vsftpd.pem
#ssl_enable=YES
#allow_anon_ssl=NO
#force_local_data_ssl=YES
#force_local_logins_ssl=YES
#ssl_tlsv1=YES
#ssl_sslv2=NO
#ssl_sslv3=NO
#require_ssl_reuse=NO
#ssl_ciphers=HIGH</code></pre><p>As you can see I also left the settings for running the server secured with TLS in and also the settings for &#xA0;running the server with the FTP root defaulting to the user&apos;s home folder. Lines after <code>pasv_max_port</code> are safe to delete if you don&apos;t care. To <em>securing with TLS</em> I&apos;ll get back later.</p><p>Back to our setup. Paranoia sets in and I create a user that I specially use only for FTP. The <em>digitalocean</em> article had a nice tip on doing this by defining a custom shell for FTP users. Here is how to set it up:</p><pre><code class="language-bash">nano /bin/ftponly</code></pre><p>Add lines:</p><pre><code>#!/bin/sh
echo &quot;This account is limited to FTP access only.&quot;</code></pre><p>Make it xecutable:</p><pre><code class="language-bash">chmod a+x /bin/ftponly</code></pre><p>Then, edit <code>/etc/shells</code> and add <code>/bin/ftponly</code> at the end.</p><p>Now let&apos;s create the user, add him to the FTP group (your choice) and give him no shell:</p><pre><code class="language-bash">useradd -g ftp -s /bin/ftponly ftpuser
passwd ftpuser</code></pre><p>After creating the user, we have to add it to the file referenced in <code>vsftpd.conf</code>. Only users included in this file will be able to access the server.</p><pre><code>echo &quot;ftpuser&quot; | tee -a /etc/vsftpd/vsftpd.userlist</code></pre><p>In order to allow people and the recently created user to upload files to our FTP server, we need to define a writable folder, because the way we secured our local root ftp directory, nobody is able to write it. And that is the way it should be.</p><pre><code class="language-bash">chmod a-w /var/ftp/pub
mkdir /var/ftp/pub/uploads
chown ftpuser:ftp /var/ftp/pub/uploads
chmod g+w /var/ftp/pub/uploads</code></pre><p>The only thing that is left to do is to start the <strong>vsftpd</strong> service and then enable it so it starts automatically when the server reboots.</p><pre><code class="language-bash">systemctl start vsftpd
systemctl enable vsftpd</code></pre><p>After this is done you should be able to access your own FTP server and put files in the <strong>uploads</strong> folder. Great success &#x1F60E;.</p><p>Giving access to your FTP to a friend is easy as:</p><pre><code>sudo -i
useradd -g ftp -s /bin/ftponly newftpuser
passwd newftpuser
echo &quot;newftpuser&quot; | tee -a /etc/vsftpd/vsftpd.userlist</code></pre><p><strong>A note on SELinux</strong>: this is a topic that I am no expert in, the only way I got my server working correctly was by modifying it like this - maybe you know a more secure way:</p><pre><code class="language-bash">setsebool ftpd_full_access on</code></pre><p><strong>Optional:</strong> If you want to secure your server with TLS, you have to generate certificates (these will be valid for 1 year if you don&apos;t change the <code>days</code>)</p><pre><code class="language-bash">openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/pki/tls/private/vsftpd.pem -out /etc/pki/tls/private/vsftpd.pem</code></pre><p>With the certificates generated, it&apos;s time to comment out the related lines in <code>vsftpd.conf</code> and restart the FTP server. You should be good to go!</p><p>And one more thing ...</p><blockquote>Keep away from people who try to belittle your ambitions. Small people always do that, but the really great make you feel that you, too, can become great. - Twain</blockquote>]]></content:encoded></item><item><title><![CDATA[Running Ghost with nginx and certbot in a Docker stack]]></title><description><![CDATA[In this note you will learn to run a blog with popular CMS Ghost in Docker contaniers. As a matter of fact, I will show you how you can run multiple Ghost blogs and nginx proxy in the same stack. So you just pop a docker-compose and everything is up... well, not really. But almost 🙃.]]></description><link>https://wasted.gerdez.net/running-a-ghost-blog-with-nginx-and-certbot-on-docker/</link><guid isPermaLink="false">61c1aed5f388140001b6b3c1</guid><category><![CDATA[ghost]]></category><category><![CDATA[blog]]></category><category><![CDATA[nginx]]></category><category><![CDATA[docker]]></category><category><![CDATA[Linux]]></category><dc:creator><![CDATA[gerdez]]></dc:creator><pubDate>Tue, 21 Dec 2021 19:27:32 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1515550962725-a254324472e9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE2fHxjb2xvciUyMHNtb2tlfGVufDB8fHx8MTY0MDExOTMxNg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1515550962725-a254324472e9?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE2fHxjb2xvciUyMHNtb2tlfGVufDB8fHx8MTY0MDExOTMxNg&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Running Ghost with nginx and certbot in a Docker stack"><p>In this note you will learn to run a blog with popular CMS Ghost in Docker contaniers. As a matter of fact, I will show you how you can run multiple Ghost blogs and nginx proxy in the same stack. So you just pop a docker-compose and everything is up... well, not really. But almost &#x1F643;.</p><h2 id="prerequisites">Prerequisites</h2><ul><li>a linux server (or other flawour), but let&apos;s be serious here...</li><li>don&apos;t forget to open required ports in the firewall (http/s)</li><li>a domain name</li><li>a little time</li></ul><h2 id="install-docker">Install Docker</h2><p>My server is CentOS, so commands are for this breed. Please visit the <a href="https://docs.docker.com/engine/install/">official Docker documentation</a> for your breed.</p><pre><code class="language-bash">dnf config-manager --add repo=https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker.service
sudo systemctl enable docker.service</code></pre><p>For convenience you can add your user to the <em>docker</em> group, so you don&apos;t have to type <code>sudo</code> before every docker command to drive you nuts and you should also test the Docker installation.</p><pre><code class="language-bash">sudo usermod -aG docker YOURUSER
docker run hello-world</code></pre><p>We want to get fancy, so let&apos;s also install Docker Compose:</p><pre><code class="language-bash">sudo curl -L &quot;https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)&quot; -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
#test
docker-compose --version</code></pre><p>Now, if you would like to run Ghost in a container we would just execute:</p><pre><code class="language-bash">docker run -d \
--name ghost \
-p 2368:2368 \
-v /path/to/your/local/ghost:/var/lib/ghost/content \
-e url=http://localhost:2368 \
ghost</code></pre><p>You should be able to pop up a browser and visit your Ghost site at localhost:2368. You could also create an external environment file, if you have more variables (like mail settings) and call it with <code>--env-file /srv/ghost/env.list \</code> - but we ain&apos;t gonna do that.</p><h2 id="preparing-the-environment">Preparing the environment</h2><p>Let&apos;s create the directory structure. Main directory is <strong>ghost-blog</strong> in our home folder.</p><pre><code class="language-bash">cd
mkdir -p ~/ghost-blog/ghost/content ghost-blog/letsencrypt ghost-blog/nginx</code></pre><p>For nginx to run, we need to run a temporary nginx container, extract some files and delete the temporary container. There might be a better way to do this, if you happen to know one, drop me a line.</p><pre><code class="language-bash">docker run --rm --name nginxtmp -it -v ~/ghost-blog/nginx:/tmp/nginx nginx:1.21 cp -rv /etc/nginx/conf.d/ /tmp/nginx/</code></pre><p>Now we need to create the initial config file for nginx, which we we&apos;ll do with</p><pre><code class="language-bash">cd ghost-blog
nano nginx/conf.d/ghost.conf</code></pre><p>and add the following:</p><pre><code class="language-conf">server {
        server_name your.domain.com;
        listen 80;
        
        location / {
                proxy_pass	 http://ghost-prd:2368;
                proxy_set_header    X-Real-IP $remote_addr;
                proxy_set_header    Host      $http_host;
                proxy_set_header X-Forwarded-Proto https;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        
        #maximum upload file size
        client_max_body_size 10M;
        
}</code></pre><p>CTRL+O to save and CTRL+X to exit <code>nano</code>.</p><p>After this we are going to create the <em>docker-compose</em> file. This file is used to control our <strong>ghost-nginx</strong> stack.</p><pre><code class="language-bash">nano docker-compose.yml</code></pre><p>Copy and paste the below config in your docker-compose.yml</p><!--kg-card-begin: markdown--><pre><code>version: &quot;3.9&quot;
# Compose file reference: https://docs.docker.com/compose/compose-file/compose-file-v3/

services:
  ghost-prd:
    image: ghost:4.32
    container_name: ghost-prd
    hostname: ghost
    restart: unless-stopped
#    ports:
#      - 2368:2368
    #with the expose option only the stack can see the port
    expose:
      - &quot;2368&quot;
    environment:
      #change to site url
      url: https://your.domain.com
      #set email option or comment out
      mail__transport: SMTP
      mail__from: Sender &lt;no-reply@yourdomain.com&gt;
      mail__options__service: Mailgun
      mail__options__host: smtp.mailgun.org
      mail__options__port: 465
      mail__options__auth__user: postmaster@xxx.mailgun.org
      mail__options__auth__pass: pass
      mail__option__secure: &quot;true&quot;
      #logging (info, warn, error)
      logging__level: info
      #logging__rotation__enabled: &quot;true&quot;
      #logging__rotation__count: 10
      #logging__rotation__period: 1d
    volumes:
      - ./ghost/content:/var/lib/ghost/content

  nginx-prd:
     image: nginx:1.21
     container_name: nginx-prd
     hostname: nginx
     restart: unless-stopped
     depends_on:
       - ghost-prd
     ports:
       - 80:80
       - 443:443
     volumes:
       - ./nginx/conf.d:/etc/nginx/conf.d
       - ./letsencrypt:/etc/letsencrypt</code></pre>
<!--kg-card-end: markdown--><p>Just to note some things here, I use <a href="https://www.mailgun.com">Mailgun</a> for these sort of things, but email settings should work with gmail or any other mail service.</p><p>I usually set the Ghost logging option to <code>warn</code> as nginx also logs and Ghost logs can get out of hand.</p><p>Using <code>expose</code> setting for the port makes it visible inside the stack, but it won&apos;t map it to the host. Which in my opinion is cleaner and because KISS &#x1F61B;</p><p>After the docker-compose.yml is saved we should take a deep breath and pray... then run the stack:</p><pre><code class="language-bash">docker-compose up -d</code></pre><p>It should start pulling the images and setting everything up. When it is finished, you have a working Ghost blog powered by nginx in a stack, in two separate containers. The only thing that is left is installing <strong>certbot</strong> for certificates and securing the site. Certbot will do all that it is needed, install certificates and modify your <em>ghost.conf</em> file. To install Certbot, we need to go into our <strong>nginx</strong> container and do some mambo.</p><pre><code class="language-bash">docker exec -it nginx-prd /bin/bash</code></pre><p>Once inside the matrix, run:</p><pre><code class="language-bash">apt-get update &amp;&amp; apt-get install certbot python3-certbot-nginx -y
certbot --nginx</code></pre><p>Pay attention when <strong>certbot</strong> requires input from you, so that you add a valid email address and secure your correct site. Now the only thing that remains is to restart the stack.</p><pre><code class="language-bash">docker-compose stop
docker-compose up -d</code></pre><p>Logs can be checked with <code>docker-compose logs</code>. Your stack and also your secured site should be up at https://your.domain.com. Hooray!!! That wasn&apos;t so hard now, was it? To unleash the dormant philosopher upon the world, check out https://your.domain.com/ghost</p><p>If for any reason you want to destroy your stack and set everything on fire you can run <code>docker-compose down</code> and your containers will be gone. You would just need to &#xA0; also delete the <em>ghost-blog</em> folder in your <em>home</em> and you can start from scratch.</p><h2 id="updating">Updating</h2><p>I like to control stuff, so in my <strong>docker-compose.yml</strong> I use fixed image tags instead of <em>latest</em>. Both can be set to latest. There is only one caveat, to which I haven&apos;t &#xA0;figured out a solution yet. When upgrading <strong>nginx</strong>, <strong>certbot</strong> will be bye-bye, so you&apos;ll have to reinstall it. The certificates and site settings are safe, as there is a mapping for those in the <em>letsencrypt</em> folder.</p><p>One more thing ...</p><hr><h2 id="how-to-run-multiple-ghost-blogs-in-the-same-stack">How to run multiple Ghost blogs in the same stack</h2><p>If you want to add another Ghost instance in the same stack, you just have to add another service to your <strong>docker-compose.yml</strong>. Like this - note the <em>exposed</em> port and <em>container_name</em>:</p><pre><code class="language-conf">ghost2-prd:
    image: ghost:4.32
    container_name: ghost2-prd
    hostname: ghost2
    restart: unless-stopped
    expose:
      - &quot;2369&quot;
    environment:
      #change to site url
      url: https://someother.domain.com
      #set if you want Ghost to run on non-default port
      server__port: 2369
      #set email option or comment out
      mail__transport: SMTP
      mail__from: Buster &lt;no-reply@someother.domain.com&gt;
      mail__options__service: Mailgun
      mail__options__host: smtp.mailgun.org
      mail__options__port: 465
      mail__options__auth__user: postmaster@xyz.mailgun.org
      mail__options__auth__pass: passW0Rd
      mail__option__secure: &quot;true&quot;
      #logging (info, warn, error)
      logging__level: warn
      #logging__rotation__enabled: &quot;true&quot;
      #logging__rotation__count: 10
      #logging__rotation__period: 1d
    volumes:
      - ./ghost2/content:/var/lib/ghost/content</code></pre><p>Create folder to hold the contents of the second blog and also make another <em>nginx</em> config file for it:</p><pre><code class="language-bash">cd
mkdir -p ghost-blog/ghost2/content
nano ghost-blog/nginx/conf.d/ghost2.conf</code></pre><p>ghost2.conf should look like this:</p><pre><code class="language-conf">server {
        server_name someother.domain.com;
        listen 80;

        location / {
                proxy_pass	 http://ghost2-prd:2369;
                proxy_set_header    X-Real-IP $remote_addr;
                proxy_set_header    Host      $http_host;
                proxy_set_header X-Forwarded-Proto https;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }
}</code></pre><p>Then:</p><pre><code class="language-bash">docker-compose up -d
docker exec -it nginx-prd /bin/bash
	#inside the nginx container set up the second site
    	certbot --nginx</code></pre><p>Stop and start your stack and you should have both sites running.</p><p>Phew. That was a long one. I hope it all makes sense &#x1F602; I might put it all up on Github and then it will be easier. But that&apos;s a story for another day.</p><blockquote>Do or do not. There is no try.</blockquote>]]></content:encoded></item><item><title><![CDATA[Backup Mac OS Photos library to NAS with rsync]]></title><description><![CDATA[I like to have a backup copy of my important files and for this I use NAS backups for pretty much everything. I used Carbon Copy Cloner in the past, but I’ve had some free time and put together a nice little solution for my backups, with rsync as backup tool and scheduling with launchd.]]></description><link>https://wasted.gerdez.net/backup-mac-os-photos-library-to-nas-with-rsync/</link><guid isPermaLink="false">5e5ec7fe7036a300017ba3ae</guid><category><![CDATA[Backup]]></category><category><![CDATA[Mac]]></category><category><![CDATA[Rsync]]></category><dc:creator><![CDATA[gerdez]]></dc:creator><pubDate>Sat, 04 Feb 2017 21:32:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1529466118190-c09bf0ccb222?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<blockquote>2021 edit: This is no longer the case since MacOS Catalina as these chimps decided to scrap the Masters photo folder, call it Originals and sort the files as their algorithms see fit.</blockquote><img src="https://images.unsplash.com/photo-1529466118190-c09bf0ccb222?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Backup Mac OS Photos library to NAS with rsync"><p>I started using Mac OS&#x2019;s Photos recently. Photos is not perfect, but I like to use it as it is integrated with my photo editors and maybe the most important thing, it has a &#x201C;Masters&#x201D; folder where it organizes the untouched photo files in a nice manner &#x2013; pretty much the same way I would manually.</p><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2020/03/screen-shot-2017-02-05-at-16-42-34.png" class="kg-image" alt="Backup Mac OS Photos library to NAS with rsync" loading="lazy"></figure><p>I like to have a backup copy of my important files and for this I use NAS backups for pretty much everything. I used Carbon Copy Cloner in the past, but I&#x2019;ve had some free time and put together a nice little solution for my backups, with <strong><strong>rsync</strong></strong> as backup tool and scheduling with <strong><strong>launchd</strong></strong>.</p><p>So let&#x2019;s get on with it. We are going to backup the content of the &#x201C;Masters&#x201D; folder to a network share / backup location. First thing we do is define the share path and a mount point for it on your computer. I like to use my Public folder for these things.</p><pre><code class="language-shell">SHARE=&quot;192.x.x.x/share/folder&quot;
MOUNTPOINT=&quot;/Users/YourUser/Public/backup&quot;</code></pre><p>After this I would ping the NAS once, just to wake it up because it has power saving features and mount would fail if the NAS was sleeping when the mount command was issued &#x2013; I could make it retry after a few seconds, but this is easier &#x1F609; . You can just leave it out of the script if you don&#x2019;t need it.</p><pre><code class="language-shell">echo Starting backup on $(date)
ping -c 1 192.x.x.x
sleep 10
echo Mounting photo backup disk
mount_smbfs //&apos;WORKGROUP;NasUsername:N@sPassw0rd&apos;@$SHARE $MOUNTPOINT</code></pre><p>The NasUsername and N@sPassw0rd gets sent as URL, so you might want to encode them properly. For this, you can use this <a href="http://www.w3schools.com/tags/ref_urlencode.asp">link</a>. Note how our <strong><strong>N@sPassw0rd</strong></strong> becomes <strong><strong>N%40sPassw0rd</strong></strong>.</p><p>OK, now we check if the share is mounted. It can happen that you are not on the network with your NAS, so there is no use for the backup to run. If it cannot mount the share, it will give you feedback and quit the script.</p><pre><code class="language-shell">if mount | grep &quot;on $MOUNTPOINT&quot; &gt; /dev/null; then
...
else
echo Photo backup disk cannot be mounted. Exiting.
fi</code></pre><p>If everything is OK, then we go on with the backup:</p><pre><code class="language-shell">rsync -abhP --backup-dir=_rsyncbck --delete --exclude=_rsyncbck --stats ~/Pictures/Photos\ Library.photoslibrary/Masters/ $MOUNTPOINT/
echo Unmounting photo backup disk
umount $MOUNTPOINT
echo Photo backup finished on $(date)</code></pre><p>This is what the rsync command does: It backs up files as archive (<strong><strong>a</strong></strong>), it creates backup of deleted files from source (<strong><strong>b</strong></strong>), it makes the output human readable (<strong><strong>h</strong></strong>), it saves progress (<strong><strong>P</strong></strong>). The backup directory is defined, it&#x2019;s also excluded so rsync doesn&#x2019;t recreate it every time leaving you with a mess of a folder structure and <strong><strong>&#x2013;stats</strong></strong>is added so we have a nice little log about everything rsync did. You can also add <strong><strong>z</strong></strong> so it uses compression and save some bandwidth (at the cost of CPU).</p><p>Below is the whole script, save it as <em><em>photos_backup.sh</em></em>. Of course, make adjustments to reflect your own environment.</p><pre><code class="language-shell">#!/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

SHARE=&quot;192.x.x.x/photo/Masters&quot;
MOUNTPOINT=&quot;/Users/YourUser/Public/backup&quot;

echo -en &apos;\n&apos;
echo Starting backup on $(date)
ping -c 1 192.x.x.x
sleep 10
echo -en &apos;\n&apos;
echo Mounting photo backup disk
mount_smbfs //&apos;WORKGROUP;NasUsername:N%40sPassw0rd&apos;@$SHARE $MOUNTPOINT
if mount | grep &quot;on $MOUNTPOINT&quot; &gt; /dev/null; then
echo -en &apos;\n&apos;
echo Backing up Photos Library
rsync -abhP --backup-dir=_rsyncbck --delete --exclude=_rsyncbck --stats ~/Pictures/Photos\ Library.photoslibrary/Masters/ $MOUNTPOINT/
echo -en &apos;\n&apos;
echo Unmounting photo backup disk
umount $MOUNTPOINT
echo Photo backup finished on $(date)
echo =====================================================================
else
echo -en &apos;\n&apos;
echo Photo backup disk cannot be mounted. Exiting.
echo =====================================================================
fi</code></pre><p>The many echo lines are there just so the log file generated looks nice &#x1F609; Note the trailing &#x201C;/&#x201D; in the paths in the rsync command! With how this is set up it would sync the content of the Masters folder into a Masters folder on the NAS backup drive!</p><p>Now we set the proper permissions on the *.sh file we created. Pop Terminal, navigate to where you saved your script and:</p><pre><code class="language-shell">chmod a+x photos_backup.sh</code></pre><p>You could execute this script manually and it should work fine</p><pre><code class="language-shell">./photos_backup.sh</code></pre><p>But we want the script to execute automatically with <strong><strong>launchd</strong></strong>. First we need to create a *.plist file. Mine is set up to run every Sunday at 22:00. You can play around with the occurrence by defining other values below StartCalendarInterval. Save it as <em><em>com.backup.photos.plist </em></em>&#x2013; adjust to your environment.</p><pre><code class="language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot;
 &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;dict&gt;
 &lt;key&gt;Label&lt;/key&gt;
 &lt;string&gt;com.backup.photos&lt;/string&gt;
 &lt;key&gt;ProgramArguments&lt;/key&gt;
 &lt;array&gt;
 &lt;string&gt;/Path/to/your/script/photos_backup.sh&lt;/string&gt;
 &lt;/array&gt;
 &lt;key&gt;StandardErrorPath&lt;/key&gt;
 &lt;string&gt;/Path/to/your/error.log&lt;/string&gt;
 &lt;key&gt;StandardOutPath&lt;/key&gt;
 &lt;string&gt;/Path/to/your/success.log&lt;/string&gt;
 &lt;key&gt;StartCalendarInterval&lt;/key&gt;
 &lt;dict&gt;
 &lt;key&gt;Minute&lt;/key&gt;
 &lt;integer&gt;00&lt;/integer&gt;
 &lt;key&gt;Hour&lt;/key&gt;
 &lt;integer&gt;22&lt;/integer&gt;
 &lt;key&gt;Weekday&lt;/key&gt;
 &lt;integer&gt;7&lt;/integer&gt;
 &lt;/dict&gt;
&lt;/dict&gt;
&lt;/plist&gt;</code></pre><p>Now we move the *.plist file created to it&#x2019;s proper location and we register it so it runs when defined. Open Terminal and execute:</p><pre><code class="language-shell">cp ~/Path/to/your/com.backup.photos.plist ~/Library/LaunchAgents
launchctl load -w ~/Library/LaunchAgents/com.backup.photos.plist</code></pre><p>All done! You should also get nice log files in the place you specified.</p><p>This was tested on OS X El Capitan and MacOS High Sierra but it also should work on other versions. You can modify the script to backup other things too!</p>]]></content:encoded></item><item><title><![CDATA[Creating an SSH tunnel for SOCKS proxy]]></title><description><![CDATA[Let’s say you are on a trip and want a secure connection while you check your e-mail or you want to have secure access to home computers. Let’s say you work in a corporate environment and you want to access restricted sites. That’s where SSH tunneling comes into play.]]></description><link>https://wasted.gerdez.net/creating-an-ssh-tunnel/</link><guid isPermaLink="false">5e6c9bc6e22d81000196c8fa</guid><category><![CDATA[ssh]]></category><category><![CDATA[tunnel]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Mac]]></category><category><![CDATA[Windows]]></category><category><![CDATA[PuTTy]]></category><dc:creator><![CDATA[gerdez]]></dc:creator><pubDate>Wed, 29 May 2013 08:56:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1489156738372-c2698f0f54d7?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1489156738372-c2698f0f54d7?ixlib=rb-1.2.1&amp;q=80&amp;fm=jpg&amp;crop=entropy&amp;cs=tinysrgb&amp;w=2000&amp;fit=max&amp;ixid=eyJhcHBfaWQiOjExNzczfQ" alt="Creating an SSH tunnel for SOCKS proxy"><p>Let&#x2019;s say you are on a trip and want a secure connection while you check your e-mail or you want to have secure access to home computers. Let&#x2019;s say you work in a corporate environment where the network admin is overzealous with connection rules and you want to access restricted sites (though tempering with those rules can get you fired). Let&#x2019;s say you live in a shithole country like I do and want to access Pandora, Spotify or Hulu. That&#x2019;s where SSH tunneling comes into play.</p><p>First you need some kind of SSH server. You can use a free or paid service that offers SSH services (like silenceisdefeat.com), you can run it on your home computer (any OS) or have a router that has an SSH server. In my case, I have a really nice <a href="http://store.linksys.com/Routers/linksys-WRT54GL_stcVVproductId53934619VVcatId554675VVviewprod.htm">Linksys WRT54GL</a> router with <a href="http://www.polarcloud.com/tomato">Tomato</a> firmware on it and its SSH server works pretty well and it&#x2019;s also cost efficient.</p><h3 id="about-router-configuration-and-port-forwarding">About router configuration and port forwarding</h3><p>Normally SSH runs on port 22, but it&#x2019;s somewhat unwise to leave it open on the WAN side. For example if you run your SSH server off off a Windows machine with <a href="http://www.freesshd.com/?ctt=overview">freeSSHd</a>, it will run on the machine&#x2019;s IP and on port 22 inside your LAN. Now you need to forward that port to the internet so you can access the SSH server remotely from outside. The screenshot is from a WRT54GL, but it should be similar on your router too.</p><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2020/03/screen-shot-2013-05-29-at-21.png" class="kg-image" alt="Creating an SSH tunnel for SOCKS proxy" loading="lazy"></figure><p>Now that we forwarded port 443 to the internet (you can choose any random port to forward port 22 to), we know that we can access our server from that port. We also need to have some means to access our home router from the internet. Most likely you have a dynamic IP allocated to you by your ISP, so we have to nail that IP somehow. The most straightforward method is to use a service like <a href="http://www.dyndns.com/">dyndns.com</a>, a free DNS service that can translate your allocated IP to an address you can easily remember (ex. testssh.someserver.com). You need to set this thing in your router once and then it updates your associated IP automatically. Look for DDNS (Dynamic DNS) setting on your router or something similar. In this example we would access our server at <em><em>testssh.someserver.com:443</em></em></p><p>When the SSH server part is out of the way, you need an SSH client to access the server remotely. If your client machine runs Mac or Linux, you don&#x2019;t have to worry, because the SSH client is built-in. If you are on Windows you need a neat little program like <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">PuTTY</a>.</p><h3 id="the-windows-way-setting-up-putty">The Windows way &#x2013; setting up PuTTY</h3><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2020/03/putty01-good.png" class="kg-image" alt="Creating an SSH tunnel for SOCKS proxy" loading="lazy"></figure><p>Now go to SSH and select tunnels there. Type the port number you want your tunnel to work on in the source port field, select Dynamic and click Add, go back to Sessions menu and click Save to save the connection. If you go back to the SSH menu, it should look like this &#x2013; I have chosen port 8080 for my tunnel:</p><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2020/03/putty02.png" class="kg-image" alt="Creating an SSH tunnel for SOCKS proxy" loading="lazy"></figure><p>If you happen to be behind a firewall, you may need to specify a proxy setting also for things to work, this can be done in the Proxy menu on the left. So now that we configured our client we test the connection and open the SSH tunnel &#x2013; click on Session &gt; Open in putty. The server will ask for your username and password in a terminal window. Log into your SSH server and the tunnel is open. Do not close the PuTTY window as with closing it, you close the tunnel also. Now that we have the tunnel, it&#x2019;s time to configure our system to use it. You can apply it system-wide from Internet Options, going to Connections -&gt; LAN settings -&gt; Advanced and configuring the SOCKS proxy (enter <em><em>localhost</em></em> and the port you chose in PuTTY&#x2019;s Tunnel settings):</p><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2020/03/scoks-win-proxy.png" class="kg-image" alt="Creating an SSH tunnel for SOCKS proxy" loading="lazy"></figure><p>You can also use the tunnel in a browser that you only keep for this purpose (so your environment still works, but you can visit restricted sites). In Firefox it would look like this:</p><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2020/03/firefoxproxy.png" class="kg-image" alt="Creating an SSH tunnel for SOCKS proxy" loading="lazy"></figure><h3 id="ssh-tunnel-on-mac-os-x-linux">SSH Tunnel on Mac OS X / Linux</h3><p>If you are on Mac OS X or Linux then it&#x2019;s nothing more to do then fire up a Terminal window and type:</p><pre><code>ssh -D 8080 -C -N username@testssh.someserver.com</code></pre><p>If you need to specify a remote port other than the default port 22 (like in our example above) we add the <em><em>-p</em></em> switch while specifying the port :</p><pre><code>ssh -D 8080 -p 443 -C -N username@testssh.someserver.com</code></pre><p>The <em><em>-C</em></em> (compression) switch is useful if you are on a modem or bad connection, otherwise drop it. The <em><em>-N</em></em> switch is useful for port forwarding (doesn&#x2019;t allow remote execution), like in our case. The rest of the configuration goes just as in Windows for browser settings. For system-wide usage go to Proxies in System Preferences and set it there.</p><figure class="kg-card kg-image-card"><img src="https://wasted.gerdez.net/content/images/2020/03/screen-shot-2013-05-29-at-21-17-49.png" class="kg-image" alt="Creating an SSH tunnel for SOCKS proxy" loading="lazy"></figure><p>As you can see you can use the tunnel for any means you see fit, basically once you open up the SSH tunnel and tell your system to use it, it&#x2019;s like you are in the LAN you open the tunnel to &#x2013; this means that if you download something, it will use your home bandwidth also (assuming your SSH server runs on your home network).</p>]]></content:encoded></item></channel></rss>