Building this blog | sethforprivacy.com


In this post I’ll detail how I spun up my blog specifically and how you can do the same easily



Onion Details



Page Clicks: 1

First Seen: 03/12/2024

Last Indexed: 10/23/2024

Domain Index Total: 84



Onion Content



Table of Contents Introduction Hosting Installing Hugo Starting my new Hugo site Deploying the site publicly with NGINX Installing NGINX from their apt repos Creating a custom server configuration Enabling native Tor support Writing workflow Adding a new blog post Helpful Hugo Pages Next Steps Introduction # I figured the second post I made should be about this blog in general, as it has been a long time coming. I’ve been planning this for months, but due to some life events, I’ve been quite busy and unable to pursue this. Now that I have some more free time, I was inspired to finally take the dive and start it up after SerHack reached out asking for some feedback on his own blog. After chatting with him a bit I decided to dive into the tool he had used to build a clean, static, fast blog; a tool called Hugo . Hugo allows you to simply spin up and host a static blog using (primarily) MarkDown, a format that is familiar to many who have worked with Github in the past. In this post I’ll detail how I spun up my blog specifically and detail some next steps I have planned as well. For the entire source code behind this site, see the Github repo below: https://github.com/sethforprivacy/sethforprivacy.com NOTE: This blog post is a bit outdated now as I have moved to a full Docker + Traefik setup, but I hope to update it soon. Hosting # For hosting my blog I decided to go with a well known cloud provider, Linode , and spin up a basic Debian VM to build on top of. A few of the things that I set up on a new host like this are: UFW for simple firewall setup Oh My ZSH for a better terminal experience Zabbix for operational host monitoring NGINX for a web server Tor for hosting hidden services/SOCKS proxy Once I had these basics installed, it was time to dive into Hugo and learn my way around it. Installing Hugo # While I could have installed Hugo via apt, I decided to compile from the source to get the latest features and improved theme support. Hugo made this simple with their clear and detailed docs, so I simply followed their “Installing” docs. The first step was installing Go : 1 2 3 4 5 6 mkdir build cd ~/build wget https://golang.org/dl/go1.15.5.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.15.5.linux-amd64.tar.gz echo "path+=('/usr/local/go/bin')" >> ~/.zshrc echo "path+=('/home/user/go/bin')" >> ~/.zshrc Once I had Go installed and working (test with go version ), it was time to build Hugo from source: 1 2 3 4 cd ~/build git clone https://github.com/gohugoio/hugo.git cd hugo go install --tags extended The build takes a bit depending on resources, but installs the latest Hugo directly to a directory we just added to $PATH. To update Hugo later on, simply run the following commands: 1 2 3 cd ~/build/hugo git pull go install --tags extended Now it was time to spin up a test site and play around with themes. Starting my new Hugo site # Hugo’s docs again came in handy here, as they have a great quick start guide that makes it easy to get your test site up and running. Once I had simple site up, I tried out a few themes and eventually settled on “Terminal” by @panr . Not only was the theme very minimal and dark by default, but it had a great Monero-like color scheme to choose from. One of the best features of Hugo is that it is extremely simple to test out changes to your site/posts as you go, since you can simply run hugo server -D to serve a copy locally that auto-refreshes with each change you make. All it took to start up a new blog post was: 1 hugo new content/posts/comparing-private-spends.md Then I just edited the MarkDown and alt+tabbed to FireFox to check my changes as I went! Deploying the site publicly with NGINX # The above is all that is needed to see the site for yourself, but obviously the end goal is to share this with others. To do that I chose to deploy NGINX, which is a very simple and easy to use web server that is widely available. This post by Gideon Wolfe came in handy, and gave me the building blocks I needed to customize my NGINX configuration to match the way Hugo works. Installing NGINX from their apt repos # To install NGINX I chose to install the latest from their own repositories, as I wanted to be sure to have compatibility with the latest security standards. Their docs are a great guide here, and should be all you need to get started. Creating a custom server configuration # I like to use Mozilla’s SSL config generator as the core of any NGINX configuration to make sure I have the proper security and SSL settings configured, and this time was no different. Make sure to customize the certificate placement to match your own, and add in the unique lines for your Hugo deployment and hostname to the new site config file (located at /etc/nginx/conf.d/name-me.conf for my NGINX version). My unique lines are similar to the below, and are the core of what I had to add to the generated config from Mozilla: 1 2 3 4 5 6 7 8 9 10 server_name sethforprivacy.com ; root /var/www/sethforprivacy.com/public/ ; #Absolute path to where your hugo site is index.html ; # Hugo generates HTML error_page 404 = /404.html ; location / { try_files $uri $uri / = 404 ; } I navigated to sethforprivacy.com and validated that the blog loaded up. Note: I had SSL certificates for very cheap with my domain purchase and used those, but for most people getting certs from LetsEncrypt is a better choice all around. See “Using Free Let’s Encrypt SSL/TLS Certificates with NGINX” for more details on how to setup LetsEncrypt with NGINX. Enabling native Tor support # I knew from the outset that I wanted to also host my blog as a native Hidden Service on Tor, so I’ll go over how I did that here. Thankfully, it’s very simple with NGINX and only took a few quick configuration edits. I used this old but great blog post as a base to go off of, starting with installing Tor: 1 sudo apt install tor Then I just had to edit the Tor configuration file at /etc/tor/torrc and add in the following lines (replace “sethforprivacy.com” with your site name or other preferred name): 1 2 3 HiddenServiceDir /var/lib/tor/sethforprivacy.com/ HiddenServiceVersion 3 HiddenServicePort 80 127.0.0.1:80 Once that was added, I simply restarted tor ( sudo systemctl restart tor ) and cat the file to get the .onion domain (replace “sethforprivacy.com” with what you chose above as the directory name): 1 2 cat /var/lib/tor/sethforprivacy.com/hostname 6idyd6chquyis57aavk3nhqyu3x2xfrqelj4ay5atwrorfcpdqeuifid.onion The next (and last) step was to add a new server block to my NGINX configuration, telling NGINX to serve a copy of the blog on localhost so that Tor could share it as a hidden service: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 server { listen 127.0.0.1:80 ; server_name 6idyd6chquyis57aavk3nhqyu3x2xfrqelj4ay5atwrorfcpdqeuifid.onion ; root /var/www/sethforprivacy.com/tor/ ; index.html ; error_page 404 = 404.html ; location / { try_files $uri $uri / = 404 ; } Note: To properly serve over Tor you need to set the baseURL to the .onion address while also setting a unique publishDir in a different configuration file for Hugo. You can see my full config.yaml files below. clearnet_config.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 baseURL : 'https://sethforprivacy.com/' languageCode : en-us title : sethforprivacy.com theme : PaperMod enableRobotsTXT : true buildDrafts : false buildFuture : false buildExpired : false minify : disableXML : true minifyOutput : true params : # env: production title : sethforprivacy.com description : "A simple blog about privacy, Monero, and self-hosting" author : sethforprivacy DateFormat : "January 2, 2006" defaultTheme : dark disableThemeToggle : false ShowReadingTime : true ShowShareButtons : false ShowPostNavLinks : true ShowBreadCrumbs : true ShowCodeCopyButtons : true disableSpecial1stPost : false disableScrollToTop : false comments : false hidemeta : false hideSummary : false showtoc : true tocopen : true mainSections : posts assets : disableHLJS : true # disableFingerprinting: true label : text : "Home" icon : /favicon.ico iconHeight : 35 homeInfoParams : Title : "Welcome to Seth For Privacy's blog! \U0001F44B" Content : > - Take a look at "Posts" for blog posts, "Guides" for guides on self-hosting and Monero, and "Opt Out Podcast" for content related to Opt Out. - ***To contact me, use one of the methods below or [an alternative](/about/#how-to-contact-me).*** socialIcons : name : twitter url : "https://x.com/sethforprivacy" - name : github url : "https://github.com/sethforprivacy" - name : monero url : "monero:86JzKKyZvtEC98y6zJxCCVfcA3r75XngPBjpYDE6zRR36keNGMHwZomDjMCv1oCYB2j9myiFqEJQF3JtnhKdfX546T91eaY" - name : bitcoin url : "https://paynym.is/+fallingrecipe6C9" - name : rss url : "/index.xml" cover : hidden : true # hide everywhere but not in structured data hiddenInList : true # hide on list pages and home hiddenInSingle : true # hide on single page editPost : URL : "https://github.com/sethforprivacy/sethforprivacy.com/blob/master/content" Text : "Suggest Changes To This Post" # edit text appendFilePath : true # to append file path to Edit link # for search # https://fusejs.io/api/options.html fuseOpts : isCaseSensitive : false shouldSort : true location : 0 distance : 1000 threshold : 0.4 minMatchCharLength : 0 keys : [ "title" , "permalink" , "summary" , "content" ] outputs : home : HTML - RSS - JSON # is necessary menu : main : identifier : posts name : Posts url : /posts weight : 1 - identifier : guides name : Guides url : /guides weight : 2 - identifier : podcast name : Opt Out Podcast url : "https://dev.optoutpod.com" weight : 3 - identifier : about name : About url : /about weight : 4 - identifier : search name : Search url : /search weight : 5 privacy : disqus : disable : true googleAnalytics : anonymizeIP : false disable : true respectDoNotTrack : false useSessionStorage : false instagram : disable : true simple : false twitter : disable : false enableDNT : false simple : true vimeo : disable : true enableDNT : false simple : false youtube : disable : true privacyEnhanced : false markup : tableOfContents : endLevel : 2 ordered : false startLevel : 1 goldmark : renderer : unsafe : true highlight : # anchorLineNos: true codeFences : true guessSyntax : true lineNos : false # noClasses: false style : solarized-dark tor_config.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59...