[{"content":"Hi there 👋 I’m 4rkal. I created this blog as free alternative to my medium\nI usually post about interesting topics I stumble upon, particularly in areas like Linux, Privacy, Crypto, and Programming.\nIf you enjoy my content, consider supporting me with a donation.\nCurrent Projects Here’s what I\u0026rsquo;m currently working on:\nThis Blog - Continuously updating with new content. CypherGoat- A cryptocurrency instant swap aggregator. Videiro - Free video editor portfolio platform Videiro Recruitment - Video editor requirement website. Get in Touch You can reach me on various platforms:\nTwitter: @4rkal_ Email: 4rkal [at] proton [dot] me Shitposting Email: 4rkal [at] horsefucker [dot] org Signal: 4rkal.69 (Link) Matrix: 4rkal:monero.social ","permalink":"https://4rkal.com/about/","summary":"\u003ch3 id=\"hi-there-\"\u003eHi there 👋\u003c/h3\u003e\n\u003cp\u003eI’m \u003cstrong\u003e4rkal\u003c/strong\u003e. I created this blog as free alternative to my \u003ca href=\"https://4rkal.medium.com\"\u003emedium\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eI usually post about interesting topics I stumble upon, particularly in areas like \u003ca href=\"../../tags/linux\"\u003eLinux\u003c/a\u003e, \u003ca href=\"../../tags/privacy\"\u003ePrivacy\u003c/a\u003e, \u003ca href=\"../../tags/crypto\"\u003eCrypto\u003c/a\u003e, and \u003ca href=\"../../tags/programming\"\u003eProgramming\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eIf you enjoy my content, consider supporting me with a \u003ca href=\"../../donate\"\u003edonation\u003c/a\u003e.\u003c/p\u003e\n\u003ch2 id=\"current-projects\"\u003eCurrent Projects\u003c/h2\u003e\n\u003cp\u003eHere’s what I\u0026rsquo;m currently working on:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\".\"\u003eThis Blog\u003c/a\u003e\u003c/strong\u003e - Continuously updating with new content.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\"https://cyphergoat.com?utm_source=4rkal.com\"\u003eCypherGoat\u003c/a\u003e\u003c/strong\u003e- A cryptocurrency instant swap aggregator.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\"https://videiro.com\"\u003eVideiro\u003c/a\u003e\u003c/strong\u003e - Free video editor portfolio platform\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://hire.videiro.com\"\u003eVideiro Recruitment\u003c/a\u003e - Video editor requirement website.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"get-in-touch\"\u003eGet in Touch\u003c/h2\u003e\n\u003cp\u003eYou can reach me on various platforms:\u003c/p\u003e","title":"About"},{"content":"Yesterday I got scammed on a P2P crypto trade. Or at least someone tried to. Here\u0026rsquo;s what happened and how I managed to get Revolut to side with me.\nWhat happened I took a sell order on RoboSats for 3,110,649 sats (~0.031 BTC) in exchange for €2,100 EUR via Revolut. The buyer had listed the order, I took it, the trade went through normally, I confirmed the Revolut payment and released the Bitcoin.\nA few hours later I got a Revolut notification: \u0026ldquo;Verify your transaction.\u0026rdquo; The buyer had filed a recall request on the €2,100 payment. Revolut froze my account pending review.\nClassic P2P chargeback fraud. The buyer received the Bitcoin and then tried to claw back the fiat.\nWhat I did The first thing I did was move my Revolut balance out before the account got fully restricted (this was mostly done by accident but still). That turned out to be the right call Revolut can only chase your Revolut balance, not money that\u0026rsquo;s already elsewhere.\nThen I went through Revolut\u0026rsquo;s dispute flow. They asked for:\nEvidence of communication with the payer Evidence of the source of funds (cryptocurrency) A description of the payment The problem is RoboSats uses an ephemeral encrypted in-app chat. I had no screenshots of the conversation. Most people at this point would have almost nothing to submit.\nThe evidence package What saved me was the RoboSats trade contract JSON file. After every completed trade, RoboSats generates a contract file you can download. Mine contained:\n{ \u0026#34;coordinator\u0026#34;: \u0026#34;Over the Moon\u0026#34;, \u0026#34;order_id\u0026#34;: , \u0026#34;currency\u0026#34;: \u0026#34;EUR\u0026#34;, \u0026#34;maker\u0026#34;: { \u0026#34;sent_fiat\u0026#34;: 2100, \u0026#34;payment_hash\u0026#34;: \u0026#34;33af4009cfdb4cdace...\u0026#34;, \u0026#34;preimage\u0026#34;: \u0026#34;51f63c31b7eb8c479a...\u0026#34; }, \u0026#34;taker\u0026#34;: { \u0026#34;sent_sats\u0026#34;: 3110649, \u0026#34;received_fiat\u0026#34;: 2100 } } The preimage is cryptographic proof the Lightning payment settled. It can only be revealed upon successful payment completion — it\u0026rsquo;s mathematically impossible to fake.\nI put together a PDF declaration with:\nFull trade details (order ID, amounts, dates) The escrow note verbatim (which explicitly named the order ID and trade amount) The payment hash and preimage An explanation of how RoboSats escrow works A signed declaration that the payment was legitimate consideration for Bitcoin delivered I uploaded that PDF, a screenshot from my lightning wallet, a screenshot from robosats of the trade and a screenshot of the JSON contract to Revolut\u0026rsquo;s evidence form. Revolut accepted the dispute within a few hours\nI can\u0026rsquo;t know exactly what tipped it, but the evidence package was as strong as I could make it given the circumstances.\nTemplate If this ever happens to you, I\u0026rsquo;ve put together a ready-to-use PDF template, an exact copy of what I submitted. All the sections are pre-structured, you just fill in your trade details, paste in your payment hash and preimage from the JSON contract, sign it and upload it to your bank\u0026rsquo;s dispute form.\nDownload the dispute template PDF here\nFields to fill in are clearly marked. The document covers:\nParty details (your name, buyer\u0026rsquo;s name, payment tags) Full trade details (order ID, amounts, dates, payment method) Lightning escrow evidence (escrow note verbatim, amounts, fees) Cryptographic proof section (payment hash, preimage, contract timestamp) How RoboSats escrow works — explained for non-technical reviewers Signed declaration The most important fields are the payment_hash and preimage from your RoboSats JSON contract. Download that contract file before you close the order — it expires.\nResult Account unfrozen, €2,100 stays mine.\nLessons A few things I\u0026rsquo;ll do differently going forward:\nUse SEPA/bank transfer instead of Revolut. Revolut payments can be recalled. SEPA Instant is much harder to reverse. Always download the trade contract JSON before closing the RoboSats order. It takes one second and is your strongest evidence if something goes wrong. Screenshot the in-trade chat before the trade closes. Even a single message showing the buyer agreed to the terms helps enormously. Move funds out of Revolut before going through a dispute flow if you think it might go against you. Whatever ultimately swayed Revolut, having thorough documentation clearly didn\u0026rsquo;t hurt. Most people submitting to these dispute flows have very little — putting together a proper evidence package at minimum gives you a fighting chance.\nAvoiding P2P altogether If you’d rather avoid the P2P route entirely, I built CypherGoat — a non-custodial swap aggregator that compares rates across 20+ exchanges.\nIt doesn’t handle fiat, but for crypto-to-crypto swaps it removes the direct counterparty risk you get with P2P (no dealing with individual buyers, chargebacks, etc.). Funds go straight to your wallet, though of course you’re still relying on the execution and reliability of the underlying providers.\n","permalink":"https://4rkal.com/posts/p2p-2k/","summary":"\u003cp\u003eYesterday I got scammed on a P2P crypto trade. Or at least someone tried to. Here\u0026rsquo;s what happened and how I managed to get Revolut to side with me.\u003c/p\u003e\n\u003ch2 id=\"what-happened\"\u003eWhat happened\u003c/h2\u003e\n\u003cp\u003eI took a sell order on \u003ca href=\"https://robosats.com\"\u003eRoboSats\u003c/a\u003e for 3,110,649 sats (~0.031 BTC) in exchange for €2,100 EUR via Revolut. The buyer had listed the order, I took it, the trade went through normally, I confirmed the Revolut payment and released the Bitcoin.\u003c/p\u003e","title":"Someone tried to steal €2k from me on a P2P crypto trade. It didn't work."},{"content":"Backstory I woke up to 200 new subscribers on the newsletter of my site videiro.com, had it finally happened? Did my site finally go viral?\nSadly no. After checking the new subscribers I noticed that none had verified their email addresses, not even one, that\u0026rsquo;s definitely not a confidence.\nAfter some quick research I understood that I had indeed been spammed. But all the emails look legit. Here are some examples:\nkathyolynn@yahoo.com lukeckins@gmail.com dispatch@gonealinc.com doug_fern@hotmail.com After some initial research (entering the emails into haveibeenpwned) it looks like most of these email addresses have been in some kind of hack or breach.\nSo what was happening? How can I prevent it in the future?\nSomeone, decided to use compromised email addresses to spam my form. Either to pollute my newsletter, to see how far they could go or just because they can?\nWhat I learned When making anything publicly available on the internet, there will be spammers, there will be bots and there will be people trying to hack it. That is why you should always be making it as secure as possible.\nIt turns out that this kind of spam attack is more common that you think (especially since my blog\u0026rsquo;s newsletter also got spammed a couple weeks later). Bots crawl the web and look for forms, usually newsletter or contact forms and then start submitting \u0026ldquo;leaked\u0026rdquo; email addresses.\nBut why? Here are some reasons I came up with:\nTo pollute your email list (if this is a personal attack, which I don\u0026rsquo;t think it is in this case) To test the validity of the emails?? To annoy the leaked email addresses owners by having them subscribed to thousands of newsletters To annoy the website owner (me) How I fixed it I have a couple solutions to this problem.\nStep 1: Enable Double Opt-in The fist and most important step is to make sure that all your newsletters are \u0026lsquo;double opt-in\u0026rsquo; meaning that the user has to confirm their email address before getting subscribed\nOn listmonk (the newsletter software I am using) make sure that the list that you are subscribing your users to is double opt in\nThis means that even if your form gets spammed you can just remove all the addresses that haven\u0026rsquo;t verified their email (after a couple of days/weeks).\nWant to learn how to set up your own self-hosted newsletter with Listmonk?\nCheck out my guide: How to set up a self-hosted newsletter using Listmonk\nStep 2: Add Captcha or Cloudflare JS challenge The second step I took was to enable some sort of catcha. Initially I setup an hcaptcha via listmonk. But I don\u0026rsquo;t think that is the best solution as it\u0026rsquo;s kind of annoying. I am however using it for the videiro.com newsletter. If your interested in how to do it here\u0026rsquo;s how:\nOpen the listmonk web-ui Go to settings Under Security, enable captcha and enter an hCaptcha.com API key (you will first have to signup at hcaptcha.com) However with this setup if you are using custom forms (like the email subscription form bellow) the submission process will be kind of broken.\nSo instead what I came up with and I am currently using on 4rkal.com newsletter is to use cloudflare JS Challenge on a specific subdomain.\nThe way that I have setup my email newsletter is that I have listmonk running on newsletter.4rkal.com, a seperate subdomain.\nThis means that I can set that specific subdomain as \u0026ldquo;under attack\u0026rdquo; on cloudflare and prompt users to sometimes complete a catcha.\nTo do this:\nHead to cloudflare.com Login and head to the dashboard of your specific domain Under Security select WAF Then click on Create rule Give it any name Under Field select hostname and under Operator select wildcard, in Value enter the subdomain, in my case that\u0026rsquo;s newsletter.4rkal.com. The expression should look like this (http.host wildcard \u0026quot;newsletter.4rkal.com\u0026quot;) Under Choose action select JS Challenge Click on Save And that\u0026rsquo;s about it\nSummary Getting your website spammed is never fun, but I hope this article might have given clarity to people going through the same problem as me.\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/newsletter-spam/","summary":"\u003ch2 id=\"backstory\"\u003eBackstory\u003c/h2\u003e\n\u003cp\u003eI woke up to 200 new subscribers on the newsletter of my site \u003ca href=\"https;//videiro.com\"\u003evideiro.com\u003c/a\u003e, had it finally happened? Did my site finally go viral?\u003c/p\u003e\n\u003cp\u003eSadly no. After checking the new subscribers I noticed that none had verified their email addresses, not even one, that\u0026rsquo;s definitely not a confidence.\u003c/p\u003e\n\u003cp\u003eAfter some quick research I understood that I had indeed been spammed. But all the emails look legit. Here are some examples:\u003c/p\u003e","title":"Prevent newsletter signup spam"},{"content":"Why I built CypherGoat Ever since I first got into crypto I have been building products to make using crypto easier. In early 2022 I co-founded RubyTrades a (kind of p2p) non kyc fiat on ramp that allowed users to buy and sell crypto using PayPal. Although it was not as successful as we had hoped it still gained some traction and I learned a lot from it. After that I got interested in Monero. I built MoneroOS a plug and play live operating system that mines monero on boot. I also built MoneroNodeMonitor and some other projects.\nI was always fascinated by cross-chain on chain swaps (like rubic.exchange), so I decided to build something similar, but better.\nWhat is CypherGoat? It is a crypto swap aggregator it automatically finds the best exchange rates from our partnered exchange at no extra cost. You can then perform the swap on that exchange, without ever leaving our website!\nWhy it\u0026rsquo;s cool KYC-Free – No personal verification required. Non-Custodial – Direct to wallet trading (on chain swaps) Open Source – Our web UI is open-source. User-Friendly for Everyone – Unlike other aggregators with complex interfaces, CypherGoat has a clean and simple UI, perfect for both beginners and advanced users. Fast \u0026amp; Seamless – Just pick your tokens, swap, and receive. How it works Using CypherGoat is ridiculously simple:\nChoose your tokens – Select the crypto you want to send the one you want to receive and that the amount you want to swap. Get the Best Rate – CypherGoat \u0026ldquo;scans\u0026rdquo; exchanges and finds the best deal for you. Swap \u0026amp; Receive – Confirm the trade, enter your address, send your funds, and get your swapped crypto in your wallet. Final thoughts Crypto swapping shouldn’t be complicated, and I truly believe CypherGoat makes it easier. If you have thoughts, suggestions, or just want to chat about crypto, let’s connect! You can find me and the growing CypherGoat community on Telegram and Twitter .\nHead over to cyphergoat.com, to see the magic ; )\n","permalink":"https://4rkal.com/posts/launching-cyphergoat/","summary":"\u003ch2 id=\"why-i-built-cyphergoat\"\u003eWhy I built CypherGoat\u003c/h2\u003e\n\u003cp\u003eEver since I first got into crypto I have been building products to make using crypto easier. In early 2022 I co-founded \u003ca href=\"https://dsc.gg/rubytrades\"\u003eRubyTrades\u003c/a\u003e a (kind of p2p) non kyc fiat on ramp that allowed users to buy and sell crypto using PayPal. Although it was not as successful as we had hoped it still gained some traction and I learned a lot from it.\nAfter that I got interested in Monero. I built \u003ca href=\"https://github.com/4rkal/moneroos\"\u003eMoneroOS\u003c/a\u003e a plug and play live operating system that mines monero on boot. I also built \u003ca href=\"https://github.com/4rkal/MoneroNodeMonitor\"\u003eMoneroNodeMonitor\u003c/a\u003e and some other projects.\u003c/p\u003e","title":"Introducing CypherGoat - The first open source crypto exchange aggregator"},{"content":"I recently created my very own cryptocurrency exchange aggregator called cyphergoat it finds you the best rate to swap your crypto from different partnered exchanges.\nIt has two parts:\nAn API that interacts with exchanges. Written in go and uses gin The Web UI that is written in go and uses a combination of HTML, HTMX, tailwindcss, CSS and Javascript in templ templates. Aka the GoTTH stack. It interacts with the api in order to find rates etc. What is extremely cool with this stack and setup is that we are able to produce a single binary with everything included for each part and ship it to the server. On the webui side this is possible since the html is compiled into go code using templ and then shipped with the binary.\nIn this article I will be going through my setup to make it easier for you to make something like this.\nSetup I am using a debian 12 server which will expose my application via cloudflare tunnels. All of the static files are being served via nginx and the api and website binaries are ran as systemd services.\nIn this guide I will show you how I set this up.\nThe setup I have a single folder on my dev machine called cyphergoat: It contains\napi/ web/ builds/ The api folder houses the api source code. The web the website source code.\nAnd the builds houses all of the builds that are deployed to the server.\nTailwind The first real challenge comes with setting up tailwindcss correctly.\nIn my web project I have a static folder specifically for static files. Inside of it I have two files\n/web styles.css tailwind.css The styles.css simply contains:\n@import \u0026#34;tailwindcss\u0026#34;; The tailwind.css file is where tailwind-cli will save it\u0026rsquo;s stuff.\nTo build the tailwind stuff I simply run\nnpx @tailwindcss/cli -i ./static/styles.css -o ./static/tailwind.css --watch (assuming you have tailwind-cli installed)\nIn my header.templ file (the header of all the pages) at the top I have\n\u0026lt;link href=\u0026#34;/static/tailwind.css\u0026#34; rel=\u0026#34;stylesheet\u0026#34;\u0026gt; \u0026lt;link href=\u0026#34;/static/styles.css\u0026#34; rel=\u0026#34;stylesheet\u0026#34;\u0026gt; And the files are being served using echo\u0026rsquo;s e.Static (in my main.go file )\nfunc main(){ e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(middleware.Secure()) e.Static(\u0026#34;/static\u0026#34;, \u0026#34;static\u0026#34;) // Serves content from static folder. // Rest of the handlers } Server On my server side I have a debian 12 vm running on proxmox.\nIn my users home directory I have a folder with the following contents:\ncyphergoat/ ├── api ├── static/ └── web The static folder contains all of the static files (including tailwind.css and styles.css) and the web and api are the binaries.\nI then have two systemd services for these exectuables:\nThe cg-api.service /etc/systemd/system/cg-api.service\n[Unit] Description=CypherGoat API After=network.target [Service] User=arkal Group=www-data WorkingDirectory=/home/arkal/cyphergoat ExecStart=/home/arkal/cyphergoat/api Restart=always RestartSec=1 [Install] WantedBy=multi-user.target And cg-web.service /etc/systemd/system/cg-web.service\n[Unit] Description=CypherGoat Web After=network.target [Service] User=arkal Group=www-data WorkingDirectory=/home/arkal/cyphergoat ExecStart=/home/arkal/cyphergoat/web [Install] WantedBy=multi-user.target Both are owned by the group www-data (this is probably not necessary for the api), in order to make it easier to serve them via nginx.\nNginx The website is communicating with the api but I still need to make the web-ui accessible.\nI have setup an nginx site with the following configuration: /etc/nginx/sites-available/cg\nserver { server_name cyphergoat.com; location / { proxy_pass http://127.0.0.1:4200; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /static/ { alias /var/www/static/; expires 30d; } # Optional robots.txt location = /robots.txt { root /var/www/static; access_log off; log_not_found off; } listen 80; } I have also setup certbot to have an ssl cert.\nYou can setup certbot by running:\nsudo apt install certbot python3-certbot-nginx -y Generate the ssl cert:\nsudo certbot --nginx -d cyphergoat.com Read Self host your own website for a more in depth nginx setup.\nCloudflare Tunnels I am currently making my website accessible using cloudflare pages. It is an extremely easy to use port forwarding solution\nTo do this you will need a cloudflare account and a domain pointed to cloudflare.\nFirst head to the Zero Trust Dashboard\nUnder Networks click on Tunnels and then Create a tunnel\nOnce created you should Install and run a connector, follow the instructions on the page for your specific setup.\nAfter the connector is running you should click on the Public Hostname tab and Add a public hostname.\nNow you should see something like this: Fill in the info as I have. The service type should be HTTP and the url should be 127.0.0.1:80 or localhost:80\nObviously there is no reason to make your api publicly accessible when deploying your website.\nDeployment In order to deploy my binaries I went ahead and created a quick bash script:\ncd api go build -o ../builds/ . cd ../web templ generate \u0026amp;\u0026amp; go build -o ../builds/web cmd/main.go cd .. rsync -urvP ./builds/ user@SERVER:/home/user/cyphergoat rsync -urvP ./web/static user@SERVER:/home/user/cyphergoat/ rsync -urvP ./api/coins.json user@SERVER:/user/user/cyphergoat/ The script will build the api, generate the templ files and build the webui and then sends everything over to my server (including the static folder)\nI then ssh into my server\nssh user@ip\nand then restart the services\nsudo systemctl restart cg-api cg-web\nAnd that\u0026rsquo;s it.\nJoin my free newsletter! Subscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. Related Articles Simple Rate Limiting in Go (Gin)\nHow to build a URL shortener in Go\nHow to deploy django to production\n","permalink":"https://4rkal.com/posts/deploy-go-htmx-templ-tailwind-to-production/","summary":"\u003cp\u003eI recently created my very own cryptocurrency exchange aggregator called \u003ca href=\"https://cyphergoat.com\"\u003ecyphergoat\u003c/a\u003e it finds you the best rate to swap your crypto from different partnered exchanges.\u003c/p\u003e\n\u003cp\u003eIt has two parts:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eAn API that interacts with exchanges. Written in go and uses gin\u003c/li\u003e\n\u003cli\u003eThe Web UI that is written in go and uses a combination of HTML, HTMX, tailwindcss, CSS and Javascript in templ templates. Aka the GoTTH stack. It interacts with the api in order to find rates etc.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eWhat is extremely cool with this stack and setup is that we are able to produce \u003cstrong\u003ea single binary\u003c/strong\u003e with everything included for each part and ship it to the server. On the webui side this is possible since the html is compiled into go code using templ and then shipped with the binary.\u003c/p\u003e","title":"Deploying Go + Templ + HTMX + TailwindCSS to production"},{"content":"While working on my CypherGoat project ,when exposing the API, I needed to setup some rate limiting to avoid getting spammed. Since my API uses Gin as its HTTP library, I used for the limiter package to handle the rate limiting.\nSetting up the rate limiting In my implementation I am setting a 30 request/minute limit on each IP interacting with my API.\nHere is some example code:\npackage main import ( \u0026#34;time\u0026#34; \u0026#34;github.com/gin-gonic/gin\u0026#34; \u0026#34;github.com/ulule/limiter/v3\u0026#34; ginlimiter \u0026#34;github.com/ulule/limiter/v3/drivers/middleware/gin\u0026#34; memory \u0026#34;github.com/ulule/limiter/v3/drivers/store/memory\u0026#34; ) func main() { router := gin.Default() rate := limiter.Rate{ Period: 1 * time.Minute, Limit: 30, // 30 Requests/minute limit } store := memory.NewStore() // Create the rate limiter instance := limiter.New(store, rate) // Middleware to apply rate limiting per IP router.Use(ginlimiter.NewMiddleware(instance)) // Example endpoint router.GET(\u0026#34;/\u0026#34;, func(c *gin.Context) { c.JSON(200, gin.H{\u0026#34;message\u0026#34;: \u0026#34;Hello World!\u0026#34;}) }) // Start server router.Run(\u0026#34;:8080\u0026#34;) } We first create a new gin router called router.\nAfter that we setup a rate limiting policy. In this case it is 30 Requests/minute\nAfter that we create an in memory store to store all of the IP\u0026rsquo;s and their request counts.\nThen we create a new rate limiting instance and use it using router.Use\nAfter that we define a standard example route to \u0026ldquo;/\u0026rdquo; that returns Hello World and run it on port 8080\nYou can test this by going to your web browser to localhost:8080/ and send 30 requests (30 refreshes) in one minute and you should see Limit exceeded\nThat\u0026rsquo;s about it.\nJoin my free newsletter Subscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. Related Articles Deploying Go + Templ + HTMX + TailwindCSS to production\nHow to build a URL shortener in Go\nHow to deploy django to production\n","permalink":"https://4rkal.com/posts/go-rate-limit/","summary":"\u003cp\u003eWhile working on my \u003ca href=\"https://cyphergoat.com\"\u003eCypherGoat\u003c/a\u003e project ,when exposing the API, I needed to setup some rate limiting to avoid getting spammed. Since my API uses Gin as its HTTP library, I used for the \u003ccode\u003elimiter\u003c/code\u003e package to handle the rate limiting.\u003c/p\u003e\n\u003ch2 id=\"setting-up-the-rate-limiting\"\u003eSetting up the rate limiting\u003c/h2\u003e\n\u003cp\u003eIn my implementation I am setting a 30 request/minute limit on each IP interacting with my API.\u003c/p\u003e\n\u003cp\u003eHere is some example code:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;\"\u003e\u003ccode class=\"language-go\" data-lang=\"go\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003epackage\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003emain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eimport\u003c/span\u003e (\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;time\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;github.com/gin-gonic/gin\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;github.com/ulule/limiter/v3\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#a6e22e\"\u003eginlimiter\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;github.com/ulule/limiter/v3/drivers/middleware/gin\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#a6e22e\"\u003ememory\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;github.com/ulule/limiter/v3/drivers/store/memory\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e)\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003efunc\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003emain\u003c/span\u003e() {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#a6e22e\"\u003erouter\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e:=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003egin\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eDefault\u003c/span\u003e()\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#a6e22e\"\u003erate\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e:=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003elimiter\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eRate\u003c/span\u003e{\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\u003cspan style=\"color:#a6e22e\"\u003ePeriod\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e1\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e*\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003etime\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eMinute\u003c/span\u003e,\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\u003cspan style=\"color:#a6e22e\"\u003eLimit\u003c/span\u003e:  \u003cspan style=\"color:#ae81ff\"\u003e30\u003c/span\u003e, \u003cspan style=\"color:#75715e\"\u003e// 30 Requests/minute limit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#a6e22e\"\u003estore\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e:=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003ememory\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eNewStore\u003c/span\u003e()\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#75715e\"\u003e// Create the rate limiter\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#a6e22e\"\u003einstance\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e:=\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003elimiter\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eNew\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003estore\u003c/span\u003e, \u003cspan style=\"color:#a6e22e\"\u003erate\u003c/span\u003e)\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#75715e\"\u003e// Middleware to apply rate limiting per IP\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#a6e22e\"\u003erouter\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eUse\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003eginlimiter\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eNewMiddleware\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003einstance\u003c/span\u003e))\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#75715e\"\u003e// Example endpoint\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#a6e22e\"\u003erouter\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eGET\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;/\u0026#34;\u003c/span\u003e, \u003cspan style=\"color:#66d9ef\"\u003efunc\u003c/span\u003e(\u003cspan style=\"color:#a6e22e\"\u003ec\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e*\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003egin\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eContext\u003c/span\u003e) {\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\t\u003cspan style=\"color:#a6e22e\"\u003ec\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eJSON\u003c/span\u003e(\u003cspan style=\"color:#ae81ff\"\u003e200\u003c/span\u003e, \u003cspan style=\"color:#a6e22e\"\u003egin\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eH\u003c/span\u003e{\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;message\u0026#34;\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Hello World!\u0026#34;\u003c/span\u003e})\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t})\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#75715e\"\u003e// Start server\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\t\u003cspan style=\"color:#a6e22e\"\u003erouter\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eRun\u003c/span\u003e(\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;:8080\u0026#34;\u003c/span\u003e)\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eWe first create a new gin router called router.\u003c/p\u003e","title":"Simple Rate Limiting in Go (Gin)"},{"content":"What even is Linux? Linux is a family of free and open source operating systems based on the Linux kernel.\nAlthough being completely free (unlike alternatives) Linux currently only has 4.5% of the global desktop operating system market, a very low percentage.\nWhat makes Linux great? The core difference between Linux and other mainstream desktop operating systems (windows, macOS) is the fact that it is free and open source. This allows it to be:\nHighly performant - Linux is often faster and more efficient than its counterparts. Free from spyware and ads - Unlike Windows 11 which is adding ads to the start menu Arguably more secure - Being open source often makes it more secure Endlessly customizable Completely free forever - Because it is published under a free and open source GPL license. and much much more Read The importance of open source software for more information about open source software and it\u0026rsquo;s superiority.\nIf Windows and macOS are like apartments with rules and restrictions on what you can change, then Linux is like a house that you own that you can renovate, decorate and modify any way you like.\nIf Linux is so great why isn\u0026rsquo;t everyone using it? We (all Linux users) can probably agree that the main drawback of Linux is user-friendliness. The average user never cared and will never care about what bootloader their laptop is using.\nThe fun part however is that most people are using Linux, they just don\u0026rsquo;t know it!\nAndroid Android is the most widely used mobile operating system in the world. With a staggering 71% of the global mobile operating system market\nA lesser known fact is that android is based on the Linux kernel.\nSo basically 71% of smartphones are running Linux!\nServers Linux is the leading operating system on servers (over 96.4% of the top one million web servers\u0026rsquo; operating systems are Linux) It also leads other systems such as mainframe computers, and is used on all of the world\u0026rsquo;s 500 fastest supercomputers.\nThis website is being served from a Linux server.\nThe majority if not all of the websites that you visit every single day are being served from a Linux server.\nIoT and embedded systems Most IoT (Internet Of Things) devices run Linux because of it\u0026rsquo;s lightweight nature and robustness. This article from 2018 suggests that 71% of IoT devices run Linux\nMost embedded systems (smart TV\u0026rsquo;s, routers etc) run Linux\nConclusion Linux is quietly running behind the scenes. It may only capture a small slice of the desktop operating system market but it\u0026rsquo;s a huge player in mobile, server and IoT spaces. In fact a majority of people are using Linux daily without even realizing it! It’s in your phone, your favorite websites and countless devices around you.\nUltimately I highly recommend anyone interested to at least try and play around with Linux (especially if you are in the IT field I feel like it\u0026rsquo;s a must)\nPS: this article was written on a Framework 13 running Fedora 40 (Linux)\nJoin my free newsletter Subscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/linux/","summary":"\u003ch2 id=\"what-even-is-linux\"\u003eWhat even is Linux?\u003c/h2\u003e\n\u003cp\u003eLinux is a family of free and open source operating systems based on the \u003ca href=\"https://kernel.org/\"\u003eLinux kernel\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eAlthough being completely free (unlike alternatives) Linux currently only has \u003ca href=\"https://gs.statcounter.com/os-market-share/desktop/worldwide\"\u003e4.5% of the global desktop operating system market\u003c/a\u003e, a very low percentage.\u003c/p\u003e\n\u003ch2 id=\"what-makes-linux-great\"\u003eWhat makes Linux great?\u003c/h2\u003e\n\u003cp\u003eThe core difference between Linux and other mainstream desktop operating systems (windows, macOS) is the fact that it is \u003cstrong\u003efree and open source\u003c/strong\u003e. This allows it to be:\u003c/p\u003e","title":"If Linux is so great why isn't everyone using it?"},{"content":"In this article I will be going through how to make a url shortener in go. The final result will look something like this shortr, source code\nThis is a great weekend project especially if you\u0026rsquo;re new to go.\nWhat is a url shortener? A URL shortener is a tool that takes a long URL and shrinks it down into something much shorter and easier to share. Instead of copying and pasting a long string of letters, numbers, and symbols, you get a compact version that leads to the same destination. For example, a long URL like www.somelongwebsite.com/articles/this-is-a-super-long-link could become something like bit.ly/abc123. It\u0026rsquo;s super handy for sharing links on social media, in texts, or anywhere space is limited. And most url shorteners provide analytics like link clicks.\nRequirements Go installed on your system. A code editor, eg vs code, neovim In this project I will be using echo as the http server and the standard html library.\nProject Setup Create a new directory to house our project\nmkdir project-name cd project-name Assuming you have golang installed.\nCreate a new go module (project):\ngo mod init project-name Before we start writing any code we first have to install echo:\ngo get github.com/labstack/echo/v4 Now create a new file called main.go\ntouch main.go And open it in your favorite editor.\nCreating url handlers func main() { e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(middleware.Secure()) e.GET(\u0026#34;/:id\u0026#34;, RedirectHandler) e.GET(\u0026#34;/\u0026#34;, IndexHandler) e.POST(\u0026#34;/submit\u0026#34;, SubmitHandler) e.Logger.Fatal(e.Start(\u0026#34;:8080\u0026#34;)) } This will create three different routes/handlers.\nThe /:id, which will redirect the user to the required website\nThe / which will display a url submission form for new urls to be added\nFinally the /submit which will handle url submissions from the form in /\nRedirect Handler The most important part of our application is the redirect handler, which will redirect the user to the url that was specified.\nBefore we create any urls we first have to declare some variables and make a helper function\nIn order to have a random ending to our url. eg /M61YlA, we will create a new function called GenerateRandomString\nconst charset = \u0026#34;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\u0026#34; func generateRandomString(length int) string { seededRand := rand.New(rand.NewSource(time.Now().UnixNano())) var result []byte for i := 0; i \u0026lt; length; i++ { index := seededRand.Intn(len(charset)) result = append(result, charset[index]) } return string(result) } This will select length random characters from the charset. If you want your slugs (urls), to not contain any capital letters, you can remove them from the charset.\nNow we will need to have a place to store all of our links. In this example we will be storing them in memory and not a database.\nCreate a new struct called Link and a map called LinkMap:\ntype Link struct { Id string Url string } var linkMap = map[string]*models.Link{} You can also add some sample data to it.\nvar linkMap = map[string]*Link{ \u0026#34;example\u0026#34;: { Id: \u0026#34;example\u0026#34;, Url: \u0026#34;https://example.com\u0026#34;, }, } Now we can (finally) create our RedirectHandler, which will handle all of the redirects for our url shortener.\nfunc RedirectHandler(c echo.Context) error { id := c.Param(\u0026#34;id\u0026#34;) link, found := linkMap[id] if !found { return c.String(http.StatusNotFound, \u0026#34;Link not found\u0026#34;) } return c.Redirect(http.StatusMovedPermanently, link.Url) } This function will get the id of the link eg /123 and will look for it in the global LinkMap, if it is not available it will return an error that the link was not found. Otherwise it will redirect the user to the specified url using a 301 Permanently Moved http response code.\nRecap #1 The code so far should look something like this:\npackage main import ( \u0026#34;math/rand\u0026#34; \u0026#34;time\u0026#34; \u0026#34;github.com/labstack/echo/v4\u0026#34; \u0026#34;github.com/labstack/echo/v4/middleware\u0026#34; ) type Link struct { Id string Url string } const charset = \u0026#34;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\u0026#34; var linkMap = map[string]*Link{ \u0026#34;example\u0026#34;: { Id: \u0026#34;example\u0026#34;, Url: \u0026#34;https://example.com\u0026#34;, }, } func main() { e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(middleware.Secure()) e.GET(\u0026#34;/:id\u0026#34;, RedirectHandler) //e.GET(\u0026#34;/\u0026#34;, IndexHandler) //e.POST(\u0026#34;/submit\u0026#34;, SubmitHandler) e.Logger.Fatal(e.Start(\u0026#34;:8080\u0026#34;)) } func RedirectHandler(c echo.Context) error { id := c.Param(\u0026#34;id\u0026#34;) link, found := linkMap[id] if !found { return c.String(http.StatusNotFound, \u0026#34;Link not found\u0026#34;) } return c.Redirect(http.StatusMovedPermanently, link.Url) } func generateRandomString(length int) string { seededRand := rand.New(rand.NewSource(time.Now().UnixNano())) var result []byte for i := 0; i \u0026lt; length; i++ { index := seededRand.Intn(len(charset)) result = append(result, charset[index]) } return string(result) } Run the server\ngo run . You might also want to install any missing dependencies:\ngo mod tidy If you head to localhost:8080/example you should be redirected to example.com\nSubmission Handlers We will now define two new routes inside of our main function\ne.GET(\u0026#34;/\u0026#34;, IndexHandler) e.POST(\u0026#34;/submit\u0026#34;, SubmitHandler) These two handlers will handle the default page displayed in / which will contain a form that will be submitted to /submit in a post request.\nFor the IndexHandler our code will look something like this:\nfunc IndexHandler(c echo.Context) error { html := ` \u0026lt;h1\u0026gt;Submit a new website\u0026lt;/h1\u0026gt; \u0026lt;form action=\u0026#34;/submit\u0026#34; method=\u0026#34;POST\u0026#34;\u0026gt; \u0026lt;label for=\u0026#34;url\u0026#34;\u0026gt;Website URL:\u0026lt;/label\u0026gt; \u0026lt;input type=\u0026#34;text\u0026#34; id=\u0026#34;url\u0026#34; name=\u0026#34;url\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;submit\u0026#34; value=\u0026#34;Submit\u0026#34;\u0026gt; \u0026lt;/form\u0026gt; \u0026lt;h2\u0026gt;Existing Links \u0026lt;/h2\u0026gt; \u0026lt;ul\u0026gt;` for _, link := range linkMap { html += `\u0026lt;li\u0026gt;\u0026lt;a href=\u0026#34;/` + link.Id + `\u0026#34;\u0026gt;` + link.Id + `\u0026lt;/a\u0026gt;\u0026lt;/li\u0026gt;` } html += `\u0026lt;/ul\u0026gt;` return c.HTML(http.StatusOK, html) } When we visit / a submission for will be rendered, to submit a new website. Under the form we will see all registered links from our Linkmap\nPS it is not recommended that you use html like this. You should be separating the html file or using a library like templ.\nThe submission handler SubmitHandler should look something like this\nfunc SubmitHandler(c echo.Context) error { url := c.FormValue(\u0026#34;url\u0026#34;) if url == \u0026#34;\u0026#34; { return c.String(http.StatusBadRequest, \u0026#34;URL is required\u0026#34;) } if !(len(url) \u0026gt;= 4 \u0026amp;\u0026amp; (url[:4] == \u0026#34;http\u0026#34; || url[:5] == \u0026#34;https\u0026#34;)) { url = \u0026#34;https://\u0026#34; + url } id := generateRandomString(8) linkMap[id] = \u0026amp;Link{Id: id, Url: url} return c.Redirect(http.StatusSeeOther, \u0026#34;/\u0026#34;) } This handler will take a url from the form that was submitted, do some (simple) input validation and then append it to the linkMap.\nFinal Recap The code for our url shortener is:\npackage main import ( \u0026#34;math/rand\u0026#34; \u0026#34;net/http\u0026#34; \u0026#34;time\u0026#34; \u0026#34;github.com/labstack/echo/v4\u0026#34; \u0026#34;github.com/labstack/echo/v4/middleware\u0026#34; ) type Link struct { Id string Url string } const charset = \u0026#34;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\u0026#34; var linkMap = map[string]*Link{\u0026#34;example\u0026#34;: {Id: \u0026#34;example\u0026#34;, Url: \u0026#34;https://example.com\u0026#34;}} func main() { e := echo.New() e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(middleware.Secure()) e.GET(\u0026#34;/:id\u0026#34;, RedirectHandler) e.GET(\u0026#34;/\u0026#34;, IndexHandler) e.POST(\u0026#34;/submit\u0026#34;, SubmitHandler) e.Logger.Fatal(e.Start(\u0026#34;:8080\u0026#34;)) } func generateRandomString(length int) string { seededRand := rand.New(rand.NewSource(time.Now().UnixNano())) var result []byte for i := 0; i \u0026lt; length; i++ { index := seededRand.Intn(len(charset)) result = append(result, charset[index]) } return string(result) } func RedirectHandler(c echo.Context) error { id := c.Param(\u0026#34;id\u0026#34;) link, found := linkMap[id] if !found { return c.String(http.StatusNotFound, \u0026#34;Link not found\u0026#34;) } return c.Redirect(http.StatusMovedPermanently, link.Url) } func IndexHandler(c echo.Context) error { html := ` \u0026lt;h1\u0026gt;Submit a new website\u0026lt;/h1\u0026gt; \u0026lt;form action=\u0026#34;/submit\u0026#34; method=\u0026#34;POST\u0026#34;\u0026gt; \u0026lt;label for=\u0026#34;url\u0026#34;\u0026gt;Website URL:\u0026lt;/label\u0026gt; \u0026lt;input type=\u0026#34;text\u0026#34; id=\u0026#34;url\u0026#34; name=\u0026#34;url\u0026#34;\u0026gt; \u0026lt;input type=\u0026#34;submit\u0026#34; value=\u0026#34;Submit\u0026#34;\u0026gt; \u0026lt;/form\u0026gt; \u0026lt;h2\u0026gt;Existing Links \u0026lt;/h2\u0026gt; \u0026lt;ul\u0026gt;` for _, link := range linkMap { html += `\u0026lt;li\u0026gt;\u0026lt;a href=\u0026#34;/` + link.Id + `\u0026#34;\u0026gt;` + link.Id + `\u0026lt;/a\u0026gt;\u0026lt;/li\u0026gt;` } html += `\u0026lt;/ul\u0026gt;` return c.HTML(http.StatusOK, html) } func SubmitHandler(c echo.Context) error { url := c.FormValue(\u0026#34;url\u0026#34;) if url == \u0026#34;\u0026#34; { return c.String(http.StatusBadRequest, \u0026#34;URL is required\u0026#34;) } if !(len(url) \u0026gt;= 4 \u0026amp;\u0026amp; (url[:4] == \u0026#34;http\u0026#34; || url[:5] == \u0026#34;https\u0026#34;)) { url = \u0026#34;https://\u0026#34; + url } id := generateRandomString(8) linkMap[id] = \u0026amp;Link{Id: id, Url: url} return c.Redirect(http.StatusSeeOther, \u0026#34;/\u0026#34;) } Closing words This is a great small project if you are new to/learning go.\nIt can be very helpful if you extend beyond this tutorial. For example here are some other ideas that you can add to the project:\nEnhance the input validation Track link clicks + Statistics Page Improve UI (html) Dockerizing the application ++ I did all of those and my url shortener (called shortr) can be accessed under the url app.4rkal.com and the source code is here\nJoin my mailing list Subscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/url-shortener-go/","summary":"\u003cp\u003eIn this article I will be going through how to make a url shortener in go. The final result will look something like this \u003ca href=\"https://app.4rkal.com\"\u003eshortr\u003c/a\u003e, \u003ca href=\"https://github.com/4rkal/shortr\"\u003esource code\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThis is a great weekend project especially if you\u0026rsquo;re new to go.\u003c/p\u003e\n\u003ch2 id=\"what-is-a-url-shortener\"\u003eWhat is a url shortener?\u003c/h2\u003e\n\u003cp\u003eA URL shortener is a tool that takes a long URL and shrinks it down into something much shorter and easier to share. Instead of copying and pasting a long string of letters, numbers, and symbols, you get a compact version that leads to the same destination. For example, a long URL like \u003ccode\u003ewww.somelongwebsite.com/articles/this-is-a-super-long-link\u003c/code\u003e could become something like \u003ccode\u003ebit.ly/abc123\u003c/code\u003e. It\u0026rsquo;s super handy for sharing links on social media, in texts, or anywhere space is limited. And most url shorteners provide analytics like link clicks.\u003c/p\u003e","title":"How to build a URL shortener in Go"},{"content":"I recently deployed my very own django application to production. The website is called videiro.com and was developed in django + HTML/CSS/JS + Tailwind.\nSetup I am using a debian 12 server which will expose my application via cloudflare tunnels. All of the static files are being served via nginx and the Django project is being ran by gunicorn.\nIn this guide I will show you how I set this up.\nPreparing the Django project The first thing you will have to do is open the settings.py and change the following\nDebug = False ALLOWED_HOSTS = [\u0026#39;yourdomain.tld\u0026#39;] CSRF_COOKIE_SECURE = True CSRF_TRUSTED_ORIGINS = [ \u0026#39;yourdomain.tld\u0026#39;, ] You should also change the SECRET_KEY to a long random string, that you should never share with anyone.\nAfter that create a new file called .gitignore and paste the following:\ndb.sqlite3 *.pyc This will make sure that the database is not uploaded to our server and that no pyc files are either.\nNow you can upload your project to a new github repository (or gitea repository). If you don\u0026rsquo;t want everyone to have access to your source code make sure to set the repository as private.\nIf you want to make sure that your source code stays private I recommend you setup a selfhosted gitea instance, read Selfhost your own gitea instance - selfhosted, lightweight github alternative, to learn how to do that.\ngit init git branch -M main git add . git commit -m \u0026#34;initial commit\u0026#34; git remote add origin https://... git push -u origin main Now that you we have done that you should login to your server\nServer setup Before configuring anything make sure that you don\u0026rsquo;t allow any ssh logins with a password. Follow Securing ssh with Key-Based authentication to secure your server from those kinds of attacks.\nLogin to your server\nssh user@server.ip Make sure that your packages are up to data\nsudo apt update \u0026amp;\u0026amp; sudo apt upgrade Now install python, pip, git and nginx\nsudo apt install python3 python3-pip git nginx Now clone your project into your home directory.\ngit clone https://... cd my-project Once you\u0026rsquo;re in install the following:\npip install django django-crispy-forms Now try to run the project:\npython3 manage.py runserver if you get an error that a package is missing install it and re run.\nConfiguring gunicorn Now we will setup gunicorn\nFirst install it\npip install gunicorn Now create a new file called gunicorn.service with your favorite text editor:\nsudo vim /etc/systemd/system/gunicorn.service And paste the following:\n[Unit] Description=gunicorn daemon After=network.target [Service] User=YOURUSER Group=www-data WorkingDirectory=/home/YOURUSER/PROJECT ExecStart=/path/to/gunicorn --access-logfile - --workers 3 --bind 127.0.0.1:8000 PROJECTNAME.wsgi:application [Install] WantedBy=multi-user.target Change YOURUSER to your user.\nTo find the path to gunicorn run:\nwhich gunicorn And your project name is the name of the folder inside of your project that contains the settings.py file.\nNow run the following commands to start and enable gunicorn (start on boot)\nsudo systemctl daemon-reload sudo systemctl start gunicorn.service sudo systemctl enable gunicorn.service Now if you head to 127.0.0.1:8000 you should see your project running.\nBut were not finished yet\nSetting up nginx Now we need to serve our static content via nginx.\nFirst create a new file nginx configuration file with your favorite text editor:\nsudo vim /etc/nginx/sites-available/PROJECT Change PROJECT to whatever you want\nNow paste the following content:\nserver { listen 80; server_name YOURDOMAIN; location /static/ { alias /var/www/staticfiles/; } location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } Just change YOURDOMAIN to the domain that this will be hosted on.\nCreate a symbolic link to enable your website:\nsudo ln -s /etc/nginx/sites-available/PROJECT /etc/nginx/sites-enabled/ Start and enable nginx:\nsudo systemctl start nginx sudo systemctl enable nginx Setup static files The first thing you will have to do is cd into your (django) project\ncd project Now run the following command:\npython3 manage.py collectstatic This will create a new folder called staticfiles\nNow to set up the static files we have two options:\nChange the user in /etc/nginx/nginx.conf to your user (less secure) Copy over the staticfiles to /var/www/ (more secure) I will be doing the 2nd option:\nFirst create a new file called staticfiles in /var/www\nsudo mkdir -p /var/www/staticfiles Now copy over all of the staticfiles from your project there:\nsudo cp staticfiles/* /var/www/staticfiles Now cd into /var/www\ncd /var/www Change the ownership of all the files\nsudo chown www-data:www-data staticfiles sudo chown www-data:www-data staticfiles/* Restart the nginx service:\nsudo systemctl restart nginx Now if you head to:\n127.0.0.1\nYou should see your website running with all of the static files being served!\nExposing via cloudflare tunnels Now to make your website publicly accessible.\nTo do this you will need a cloudflare account and a domain pointed to cloudflare.\nFirst head to the Zero Trust Dashboard\nUnder Networks click on Tunnels and then Create a tunnel\nOnce created you should Install and run a connector, follow the instructions on the page for your specific setup.\nAfter the connector is running you should click on the Public Hostname tab and Add a public hostname.\nNow you should see something like this: Fill in the info as I have. The service type should be HTTP and the url should be 127.0.0.1:80 or localhost:80\nNow if you head to the domain that you specified you should see your app up and running.\nCongratulations!\nIf you enjoyed this post and want to support my (mostly unpaid) work , you can donate here.\nJoin my free newsletter! Subscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/django-prod/","summary":"\u003cp\u003eI recently deployed my very own django application to production. The website is called \u003ca href=\"https://videiro.com\"\u003evideiro.com\u003c/a\u003e and was developed in django + HTML/CSS/JS + Tailwind.\u003c/p\u003e\n\u003ch2 id=\"setup\"\u003eSetup\u003c/h2\u003e\n\u003cp\u003eI am using a debian 12 server which will expose my application via cloudflare tunnels. All of the static files are being served via nginx and the Django project is being ran by gunicorn.\u003c/p\u003e\n\u003cp\u003eIn this guide I will show you how I set this up.\u003c/p\u003e","title":"How to deploy django to production"},{"content":"Join my weekly roundup, where I’ll share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks and more!\nSubscribe Weekly Roundup ","permalink":"https://4rkal.com/newsletter/","summary":"\u003cp\u003eJoin my weekly roundup, where I’ll share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks and more!\u003c/p\u003e\n\u003cstyle\u003e\n  .listmonk-form {\n    max-width: 400px;\n    margin: auto;\n    padding: 20px;\n    border: 1px solid #444;\n    border-radius: 8px;\n    background-color: #333;\n    color: #f9f9f9;\n  }\n  .listmonk-form h3 {\n    margin-bottom: 15px;\n    color: #f9f9f9;\n    text-align: center;\n  }\n  .listmonk-form p {\n    margin-bottom: 15px;\n  }\n  .listmonk-form input[type=\"email\"] {\n    width: 100%;\n    padding: 10px;\n    border: 1px solid #555;\n    border-radius: 4px;\n    background-color: #444;\n    color: #f9f9f9;\n  }\n  .listmonk-form input[type=\"checkbox\"] {\n    margin-right: 10px;\n  }\n  .listmonk-form label {\n    color: #f9f9f9;\n  }\n  .listmonk-form input[type=\"submit\"] {\n    background-color: #007bff;\n    color: #f9f9f9;\n    padding: 10px 20px;\n    border: none;\n    border-radius: 4px;\n    cursor: pointer;\n    font-size: 16px;\n    width: 100%;\n  }\n  .listmonk-form input[type=\"submit\"]:hover {\n    background-color: #0056b3;\n  }\n\u003c/style\u003e\n\u003cform method=\"post\" action=\"https://newsletter.4rkal.com/subscription/form\" class=\"listmonk-form\"\u003e\n    \u003ch3\u003eSubscribe\u003c/h3\u003e\n    \u003cinput type=\"hidden\" name=\"nonce\" /\u003e\n    \u003cp\u003e\u003cinput type=\"email\" name=\"email\" required placeholder=\"E-mail\" /\u003e\u003c/p\u003e","title":"Newsletter"},{"content":"What is listmonk? Listmonk is a selfhosted newsletter and mailing list manager. It is free and opensource, so you have full control over your data. It also offers a super clean webui:\nWhy choose listmonk over mailchimp, buttodown etc For me, running a newsletter means owning my email list.\nWhen people create newsletters they want to break free from the big platforms like Twitter or YouTube. When you use a proprietary service like Mailchimp, you’re still tied down to their rules and limitations. With Listmonk, you get more control and independence, which for me is a huge win.\nThe other reason is that listmonk is completely free (if you don\u0026rsquo;t count electricity bills/vps hosting bills). Even if you include the cost of your email host + hosting fees it is still tiny compared to mailchimp or buttondown.\nListmonk feature overview Analytics - Tracking email opens, link clicks and bounces Templates - Advanced html templates with template variables Public subscription page - See mine here Subscribers import - Import subscribers from other platforms using CSV. Media Uploads - Upload images etc Email lists - Separate lists eg Weekly roundup and new posts. And more\nRequirements for running listmonk A server running linux, either in the cloud or at home. We will be using debian 12, but you can use any other distribution. An email address to send the newsletter from. Can either be a gmail or a custom one. Server Setup Before doing anything I highly recommend that you disable password logins for ssh. See Securing ssh with Key-Based authentication for more info on how to do that.\nLogin to your server via ssh\nssh user@server.ip Make sure that all packages are up to date\nsudo apt update \u0026amp;\u0026amp; sudo apt upgrade You will also have to have docker installed, if you don\u0026rsquo;t install it, instructions for debian\nCreate a new directory to host listmonk\u0026rsquo;s configuration files\nmkdir listmonk \u0026amp;\u0026amp; cd listmonk Download the listmonk docker-compose file\ncurl -O https://github.com/knadh/listmonk/blob/master/docker-compose.yml Run it using docker:\ndocker compose up -d Now if you head to\nlocalhost:9000 You should see listmonk up and running\nBut first we should change some settings in the configuration files\nvim config.toml Here you can change the default admin password. I also changed the address to 0.0.0.0 so that I can access it via the servers ip.\nListmonk customization Now head to the webui at\nlocalhost:9000 Login and head to the settings\nIn the General tab you can customize the default from email, root url, site name, favicon and admin notification emails\nHere\u0026rsquo;s what my settings look like:\nYou can customize the page to your liking.\nSave by clicking on the save button in the top right corner.\nEmail setup For the next part you will either need a gmail account or any other email provider that give you smtp connection\nIf you want a great custom email I recommend ionos, you can get up to 10$ in credits by using my link Ionos - Email \u0026amp; Office 10$ credits that is the provider that I am currently using.\nIn this guide I will show you how to set this up for these two providers, but the setup should be similar for others too.\nIMPORTANT: Both of these hosts have a limit on how many emails can be sent out per hour or per day. For ionos that is 500/hour. Setting up a Sliding Window Limit is very important.\nSetup for gmail I recommend that you use a different gmail account from your personal one.\nThe first thing you will have to do is generate an app password, to do that head to Create and manage app passwords and create a new one called listmonk. Copy the password that is generated and save it somewhere safe.\nNow head over to the listmonk webui\nIn the SMTP tab in settings you will find this:\nClick on the gmail option as circled.\nNow enter your full email address (including @gmail.com) in the username field\nAnd in the password field enter the app password we generated before.\nNow click on the Test connection button in the bottom right corner, enter a test email and click on Send e-mail.\nIf you configured everything correctly you should now get a test message to the email specified.\nDon\u0026rsquo;t forget to save!\nSetup for ionos You should probably generate a new email for the newsletter, eg `newsletter@yourdomain.tld.\nHead over to the listmonk webui\nNow in the SMTP tab in the settings you see this\nThe ionos smtp server settings are:\nHost: smtp.ionos.com\nPort: 465\nTLS: SSL/TLS\nIMPORTANT: If you’re using IONOS UK or another specific regional version, you need to adjust the host name. For example, if you’re on IONOS UK, you should use smtp.ionos.co.uk instead of the global smtp.ionos.com.\nNow in the username field you should enter the full email address newsletter@yourdomain.tld and the password is the normal user password.\nNow to test the connection click on the Test connection button in the bottom right corner, enter a test email and click on Send e-mail.\nIf you configured everything correctly you should now get a test message to the email specified.\nDon\u0026rsquo;t forget to save!\nSliding window limit This is very important to setup when email providers limit the amount of email to be sent per hour or per day. You can access the Sliding window limit in Settings under the performance tab. For ionos I have it set at 500 emails/hour\nExposing via cloudflare tunnels I will be making my instance publicly accessible using cloudflare tunnels.\nTo do this you will need a cloudflare account and a domain pointed to cloudflare.\nFirst head to the Zero Trust Dashboard\nUnder Networks click on Tunnels and then Create a tunnel\nOnce created you should Install and run a connector, follow the instructions on the page for your specific setup.\nAfter the connector is running you should click on the Public Hostname tab and Add a public hostname.\nNow you should see something like this: Fill in the info as I have.\nThe service type should be HTTP and the url should be yourserverurl:9000, in my case that\u0026rsquo;s 127.0.0.1:9000\nNow if you head to the domain that you specified you should see gitea up and running.\nIn my case you can access my newsletter page here\nListmonk feature overview These are all of the features that listmonk offers:\nTemplates Listmonk offers amazing built in template support.\nAll templates are written in HTML.\nYou can access the templates by going to Campaigns \u0026gt; Templates.\nDon\u0026rsquo;t forget to always include {{ template \u0026quot;content\u0026quot; . }} (for the main content) and also an unsubscribe button in all of your templates\nCampaigns You can create a new campaign (email) by going to Campaigns \u0026gt; All Campaigns\nHere you can select a campaign name, subject the list\u0026rsquo;s you want to target and the template\nEmail lists You can create new lists by going to Lists \u0026gt; All Lists.\nFor example I have two lists:\nNew posts - Receive an email every time I post something new on my blog Weekly Roundup - Join my weekly roundup, where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks and more! Not everyone wants to receive an email every time I post a new article, so I created two lists!\nHTML Forms Listmonk also offers embeddable html forms, to subscribe to the email list. You can access the form builder by going to Lists \u0026gt; Forms\nPublic subscription page Except for the HTML forms listmonk also has a public subscription page. For example here is mine.\nIt can also be accessed under `Lists \u0026gt; Forms\nCampaign analytics You can track the views, clicks and bounces of your email campaigns by going to Campaigns \u0026gt; Analytics.\nImport subscribers You can import subscribers from other platforms by going to Subscribers \u0026gt; Import. It currently supports CSV or ZIP files.\nThese are the most important features that listmonk offers (I\u0026rsquo;m sure I forgot some).\nThat\u0026rsquo;s all folks If this article helped you out, consider joining my (listmonk) newsletter bellow:\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/listmonk/","summary":"\u003ch2 id=\"what-is-listmonk\"\u003eWhat is listmonk?\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://listmonk.app\"\u003eListmonk\u003c/a\u003e is a selfhosted newsletter and mailing list manager. It is free and opensource, so you have full control over your data. It also offers a super clean webui:\u003c/p\u003e\n\u003cp\u003e\u003cimg loading=\"lazy\" src=\"/../assets/listmonk.png\" type=\"\" alt=\"Listmonk WebUI\"  /\u003e\u003c/p\u003e\n\u003ch2 id=\"why-choose-listmonk-over-mailchimp-buttodown-etc\"\u003eWhy choose listmonk over mailchimp, buttodown etc\u003c/h2\u003e\n\u003cp\u003eFor me, running a newsletter means owning my email list.\u003c/p\u003e\n\u003cp\u003eWhen people create newsletters they want to break free from the big platforms like Twitter or YouTube. When you use a proprietary service like Mailchimp, you’re still tied down to their rules and limitations. With Listmonk, you get more control and independence, which for me is a huge win.\u003c/p\u003e","title":"How to setup a selfhosted newsletter using listmonk"},{"content":"In this article I\u0026rsquo;ll walk you through how you can run your own gitea instance. But first\nWhat is gitea? Gitea is a painless selfhosted Git service. It is written in Go and is extremely lightweight. I run a gitea instance on my Le Potato and it barely uses any resources.\nWhy use gitea (vs GitHub, GitLab etc) I started running my own Gitea instance because I wanted a private place to host my Obsidian notes. I did not want to have them in a private GitHub repository since it\u0026rsquo;s not on my own hardware. GitLab is harder to spin up and has a lot of features that I do not need.\nIf you want an easy to spin up, private git service gitea is your way to go.\nSetup In this guide I will be using debian 12. The setup should be the same on any other distribution since we will be using docker.\nInstalling and setting up docker The first thing you will need is docker installed on your system.\nInstall docker on debian\nAlso make sure to add your user to the docker group. This will allow you to run docker commands without sudo.\nusermod -aG docker $USER Now reboot\nDocker-compose.yml Once docker is installed. We have to get gitea up and running\nFirst create a new directory. This will host our docker-compose file.\nmkdir gitea\nThen create/edit docker-compose.yml in your favourite text editor.\nvim docker-compose.yml\nThen paste the following content:\nversion: \u0026#34;3\u0026#34; networks: gitea: external: false services: server: image: gitea/gitea:latest container_name: gitea environment: - USER_UID=1000 - USER_GID=1000 restart: always networks: - gitea volumes: - ./gitea:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - \u0026#34;3000:3000\u0026#34; - \u0026#34;222:22\u0026#34; You can change any of the default ports eg switching 3000 to 8000 can be done like this:\nports: - \u0026#34;8080:3000\u0026#34; You can setup gitea using a PostgreSQL or MySQL database. But at least for my needs a simple SQLite3 database is more than enough.\nSince I want my repositories to still exist even if the container is deleted I will use named volumes. The configuration file with named volumes should look something like this:\nversion: \u0026#34;3\u0026#34; networks: gitea: external: false volumes: gitea: driver: local services: server: image: gitea/gitea:latest container_name: gitea restart: always networks: - gitea volumes: - gitea:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - \u0026#34;3000:3000\u0026#34; - \u0026#34;222:22\u0026#34; Starting the container and additional configuration Now you can start the container by typing:\ndocker compose up -d The -d flag will run it in detach mode. If you want to see the logs live you can remove it.\nAfter docker is done pulling, gitea should be up and running.\nNow open up:\nlocalhost:3000 or yourserverip:3000\nAnd you should see something like this:\nFill in all of the required information. Since I will be using my subdomain git.4rkal.com I set the server domain and gitea base url to that.\nHere you will also have the option to enable sending emails for email verification and notifications. I will be enabling that by using a free (shitposting) email from cock.li.\nAfter you have entered all the required info click on Install Gitea.\nAfter the installation is complete you should be up and running\nMake publicly accessible with cloudflare tunnels (optional) I will be making my instance publicly accessible using cloudflare tunnels.\nTo do this you will need a cloudflare account and a domain pointed to cloudflare.\nFirst head to the Zero Trust Dashboard\nUnder Networks click on Tunnels and then Create a tunnel\nOnce created you should Install and run a connector, follow the instructions on the page for your specific setup.\nAfter the connector is running you should click on the Public Hostname tab and Add a public hostname.\nNow you should see something like this: Fill in the info as I have.\nYou can create a new subdomain eg git or gitea\nThe service type should be HTTP and the url should be yourserverurl:3000\nNow if you head to the domain that you specified you should see gitea up and running.\nIn my case you can access my public gitea instance at git.4rkal.com\nCongratulations, you now have your very own gitea instance!\nIf you enjoyed this article, consider supporting me\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/gitea/","summary":"\u003cp\u003eIn this article I\u0026rsquo;ll walk you through how you can run your own gitea instance. But first\u003c/p\u003e\n\u003ch2 id=\"what-is-gitea\"\u003eWhat is gitea?\u003c/h2\u003e\n\u003cp\u003eGitea is a painless selfhosted Git service. It is written in Go and is extremely lightweight. I run a gitea instance on my \u003ca href=\"https://libre.computer/products/aml-s905x-cc/\"\u003eLe Potato\u003c/a\u003e and it barely uses any resources.\u003c/p\u003e\n\u003ch2 id=\"why-use-gitea-vs-github-gitlab-etc\"\u003eWhy use gitea (vs GitHub, GitLab etc)\u003c/h2\u003e\n\u003cp\u003eI started running my own Gitea instance because I wanted a private place to host my \u003ca href=\"https://obsidian.md\"\u003eObsidian\u003c/a\u003e notes. I did not want to have them in a private GitHub repository since it\u0026rsquo;s not on my own hardware. GitLab is harder to spin up and has a lot of features that I do not need.\u003c/p\u003e","title":"Selfhost your own gitea instance - selfhosted, lightweight github alternative"},{"content":"The project I recently started working on a cryptocurrency exchange aggregator. Basically I send out requests to a bunch of different exchanges and compare rates. This has to be made as fast as possible. In this post, I’ll some show some tweaks that I made in order to boost my performance significantly.\nHowever keep in mind that I am not an expert (especially in go) and I am just sharing my findings from my own personal project.\nImprovements These improvements come in order of biggest improvement of runtime.\n1. Using goroutines In any Go program, goroutines are essential for speed. The biggest boost I made was by sending requests concurrently. Since I need to hit up 12 different exchanges, sending these requests at the same time dropped my runtime from around 24 seconds to just ~3.\nGoroutines are amazing and extremely easy to use. You should include them wherever possible. But always be careful of Data Races\n2. Upgrading the JSON Library I swapped out encoding/json for github.com/json-iterator/go. jsoniter is a fast JSON processing library that works as a drop-in replacement for the standard library, so I didn’t have to change any code, just a library switch.\nBenchmark Results\nTo measure the performance improvements, I ran some benchmarks comparing encoding/json and jsoniter. Here’s a summary of the results:\ngoos: linux goarch: amd64 pkg: apiSpeedImprove cpu: AMD Ryzen 5 7640U w/ Radeon 760M Graphics BenchmarkEncodingJSON-12 140383 7381 ns/op BenchmarkJSONIter-12 974605 1217 ns/op PASS ok apiSpeedImprove 3.216s So, jsoniter is about 6 times faster than the standard library.\n3. Reusing HTTP Handlers I started reusing HTTP handlers instead of creating new ones for each request. By setting up a handler once and reusing it, I cut down on the overhead of making new handlers for each request.\nBenchmark Results\nHere are the results of the benchmarks comparing reused handlers versus creating new handlers for each request:\ngoos: linux goarch: amd64 pkg: apiSpeedImprove/httpReuse cpu: AMD Ryzen 5 7640U w/ Radeon 760M Graphics BenchmarkNewHttpClientEachRequest-12 3360 300058 ns/op BenchmarkReuseHttpClient-12 6470 175472 ns/op PASS ok apiSpeedImprove/httpReuse 4.010s Reusing HTTP handlers gave a solid performance boost compared to making a new handler for each request.\nConclusion With these tweaks I managed to cut the time it took to gather all the info from 24 seconds initially to about 2 seconds. Pretty solid improvement!\nIf you are interested the code for my benchmarks, it is available here\nIf you enjoyed this post and want to support my work, you can donate here.\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/goapi/","summary":"\u003ch1 id=\"the-project\"\u003eThe project\u003c/h1\u003e\n\u003cp\u003eI recently started working on a \u003cem\u003ecryptocurrency exchange aggregator\u003c/em\u003e. Basically I send out requests to a bunch of different exchanges and compare rates. This has to be made as fast as possible.\nIn this post, I’ll some show some tweaks that I made in order to boost my performance significantly.\u003c/p\u003e\n\u003cp\u003eHowever keep in mind that I am not an expert (especially in go) and I am just sharing my findings from my own personal project.\u003c/p\u003e","title":"How to Improve Go API request performance"},{"content":"As part of the New Look, new start. I have decided to purchase this amazing domain (4rkal.com).\nAs of today migration has been successful. All links should be redirecting to this domain.\n","permalink":"https://4rkal.com/updates/newdomain/","summary":"\u003cp\u003eAs part of the \u003ca href=\"https://4rkal.com/posts/newlook\"\u003eNew Look, new start\u003c/a\u003e. I have decided to purchase this \u003cem\u003eamazing\u003c/em\u003e domain (4rkal.com).\u003c/p\u003e\n\u003cp\u003eAs of today migration has been successful. All links should be redirecting to this domain.\u003c/p\u003e","title":"New Domain"},{"content":"If you clicked on this article you probably know what Obsidian and Hugo are but if you don\u0026rsquo;t here\u0026rsquo;s a quick explanation:\nObsidian Obsidian is a feature packed markdown editor. But it\u0026rsquo;s not just a markdown editor. It\u0026rsquo;s a way to manage knowledge. It\u0026rsquo;s great for organizing your thoughts in a flexible, non-linear way.\nObsidian works on all platforms. So you can write articles from basically any platform.\nI have been taking all of my notes in it for a couple of months now and it\u0026rsquo;s amazing!\nHugo Hugo is an ultra fast static website generator made in golang. I have been using hugo for my blog for almost 2 years now. I recently switched the theme of my my blog. Read more about the change New Look, new start.\nUsing Obsidian with Hugo In this guide, I’ll show you how to get Obsidian and Hugo working together. I won’t cover the initial setup of either tool, but I’ll explain how to integrate them for a smooth blogging workflow.\nIf you need help setting up Hugo, check out my guide: How I Setup This Blog for Free (Domain, Hosting, SSL) Complete Guide. And if you’re new to Obsidian, check out this Getting Started Guide .\nGoals for Using Hugo with Obsidian My goals for the setup are:\nUsing a single obsidian vault Have an easy to use obsidian template that I can use for my blog posts. Keep my personal vault folders private. Auto publish using obsidian hotkeys. Have all markdown files in a public github repository, so that people can propose changes Existing setup Here’s how my current workflow with Obsidian and Hugo looks:\nI write and edit articles directly in Obsidian, within the content folder of my Hugo project. I run the Hugo command to generate the static site. I push the changes to GitHub. Render.com automatically picks up the changes and deploys the updated site. Journey If you want to skip the journey part you can go straight to The Sauce\nI will be going through a couple of mistakes that I made while setting this up.\nMistake #1 The first idea that I had was to create a simple symlink (I use linux btw) that would link the two folders together.\nBasically I have two folders:\nblog/ vault/ The blog folder contains all the blog folders and the vault is my personal vault.\nThe symlink would link these folders\nblog/content vault/Blog However the problem with a symlink is that the folder content is not visible in my git repo. This means that people can not propose changes to any of my articles\nMistake #2 I wanted to have my folders synced. I tried writing a couple of bash scripts that automatically synced the two folders using a cronjob. However having that constantly running the background is a waste of resources when I am not writing. Simply running the scripts via cli is just not that smooth.\nThe Sauce Basically the way that I have set this up is I have two folders:\nblog vault The blog folder contains all the necessary hugo files and also has a sub directory called content that houses all of the markdown blog files.\nI created a new folder inside of my vault called Blog\nblog/content vault/Blog After that I copied over all of my files from the content directory to the Blog.\nI then started writing this very article\nObsidian templates I needed some way to setup a simple obsidian template to contains all of the required hugo front matter.\nThat is quite easy.\nRead about how to setup templates Templates - obsidian.md\nI created a file called Blog Post in my templates folder\nMy Blog Post template contains the following:\n--- title: \u0026#34;{{Title}}\u0026#34; description: date: \u0026#34;{{date:YYYY-MM-DD}}T{{time:HH:mm:ss}}+00:00\u0026#34; draft: true --- **If you enjoyed this article consider [supporting me](https://4rkal.com/donate)** I have all the required front matter including a title, description and a date in the format that hugo asks.\nI also added a small donation text that I include at the bottom of every article.\nThis means that I can automatically insert this template into any file and start writing!\nFolder Syncing Now I want all of my files in my vault/Blog directory to be copied over to the blog/content. Essentially connecting Hugo and Obsidian.\nThank\u0026rsquo;s to a helpful discord user I found the obsidian-shellcommands plugin.\nNOTE: this plugin does not currently work very well with the flatpak version of obsidian (since flatpak isolates the environment) . Using another alternative (.deb or appimage) seems to work.\nIt allows you to run shell commands in the background with a hotkey.\nThe steps to set this up are the following:\nInstall the plugin Enable the plugin Go to the plugin options Click on New shell command Now you will need to enter a shell command to copy the files from the one folder to the other. On Linux/MacOS that is:\ncp -a ~/folder1/. ~/folder2/\nin my case that is cp -a ~/Documents/vault/Blog/. ~/Documents/blog/content/\nOn windows it most probably is:\nrobocopy \u0026quot;%USERPROFILE%\\folder1\u0026quot; \u0026quot;%USERPROFILE%\\folder2\u0026quot; /E /COPYALL\nAfter that we need to set a hotkey that will run the command\nClick on the (+) icon to go to the hotkey settings and assign a hotkey\nMy hotkey is CTR + 0, simply because that was available.\nNow every time that I run the hotkey it copies over all of my files to the hugo folder ready to be published\nAuto publishing scripts I also want to be able to automatically publish my articles. But I want it to happen when hitting a hotkey.\nI wrote a small script that does exactly that:\n#!/bin/bash cd ~/Documents/blog hugo git add . git commit -m \u0026#34;new\u0026#34; git push -u origin main This script will build my website, commit and push to my github repo, where it is picked up and published. Read How I setup this blog for free (domain, hosting, ssl) Complete Guide to learn how to setup your own blog for free.\nDon\u0026rsquo;t forget to make the script executable by running\nchmod +x ./YOURSCRIPT.sh\nThen create a new shell command for the shellcommand plugin (as we did before) and enter the path to your script.\nIn my case that is:\n~/Documents/blog/push.sh\nThen enter a hotkey and you\u0026rsquo;re done!\nConclusion I can now simply open my obsidian vault, create a new file, insert my template and have all the info automatically entered.\nI then write my article inside of obsidian\nRun my hotkey and copy all the files into the hugo directory\nHit another key and my blog is published!\nIf you enjoyed this article consider supporting me\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/obsidianhugo/","summary":"\u003cp\u003eIf you clicked on this article you probably know what Obsidian and Hugo are but if you don\u0026rsquo;t here\u0026rsquo;s a quick explanation:\u003c/p\u003e\n\u003ch3 id=\"obsidian\"\u003eObsidian\u003c/h3\u003e\n\u003cp\u003e\u003ca href=\"https://obsidian.md\"\u003eObsidian\u003c/a\u003e is a feature packed markdown editor. But it\u0026rsquo;s not just a markdown editor. It\u0026rsquo;s a way to manage knowledge. It\u0026rsquo;s great for organizing your thoughts in a flexible, non-linear way.\u003c/p\u003e\n\u003cp\u003eObsidian works on all platforms. So you can write articles from basically any platform.\u003c/p\u003e\n\u003cp\u003eI have been taking all of my notes in it for a couple of months now and it\u0026rsquo;s amazing!\u003c/p\u003e","title":"My Obsidian + Hugo blogging setup"},{"content":"I recently switched from the hugo LoveIt theme to PaperModX . Why the switch? The LoveIt theme hasn\u0026rsquo;t been updated in 2+ years. PaperModX has a more modern look LoveIt doesn\u0026rsquo;t work that well with obsidian. The overall switch went pretty smoothly. You can see the changes I made in this commit.\nFor anyone wondering this what the website used to look like\nMore articles to come! The theme wasn\u0026rsquo;t the only change that I made. After a pretty long break, I have decided to start publishing articles regularly again!\nI will also start to update any outdated articles\nSo, stay tuned - There\u0026rsquo;s more content to come!\nSubscribe to my RSS feed to stay up to date here\nThere\u0026rsquo;s also going to be a mailing list soon™️\n","permalink":"https://4rkal.com/posts/newlook/","summary":"\u003ch4 id=\"i-recently-switched-from-the-hugo-loveit-theme-to-papermodx-\"\u003eI recently switched from the hugo \u003ca href=\"https://github.com/dillonzq/LoveIt\"\u003eLoveIt\u003c/a\u003e theme to \u003ca href=\"https://github.com/reorx/hugo-PaperModX/\"\u003ePaperModX\u003c/a\u003e .\u003c/h4\u003e\n\u003ch2 id=\"why-the-switch\"\u003eWhy the switch?\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eThe LoveIt theme hasn\u0026rsquo;t been updated in 2+ years.\u003c/li\u003e\n\u003cli\u003ePaperModX has a more modern look\u003c/li\u003e\n\u003cli\u003eLoveIt doesn\u0026rsquo;t work that well with \u003ca href=\"https://obsidian.md\"\u003eobsidian\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe overall switch went pretty smoothly. You can see the changes I made in this \u003ca href=\"https://github.com/4rkal/blog/commit/15e21c2f357f8d3a4e6ba11896d5369ec3ccb315\"\u003ecommit\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eFor anyone wondering this what \u003ca href=\"https://web.archive.org/web/20240615224820/https://4rkal.eu.org/\"\u003ethe website used to look like\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"more-articles-to-come\"\u003eMore articles to come!\u003c/h2\u003e\n\u003cp\u003eThe theme wasn\u0026rsquo;t the only change that I made. After a pretty long break, I have decided to start publishing articles regularly again!\u003c/p\u003e","title":"New look, new start"},{"content":"In this comprehensive guide, I will walk you through the process of easily setting up Monero cold storage using an old computer and your smartphone, using animated QR codes. No USB needed!\nRequirements An old laptop/computer with a webcam (to be kept offline). Called offline or cold computer. An android smartphone. Your main computer Required reads Before starting this article you must read:\nKey concepts Monero offline transaction signing details Cold computer setup Your offline computer/laptop will be signing all of the transactions. It should always be kept offline i.e cold. It can not be used for other tasks.\nI highly recommend that you use a linux distribution and NOT windows for cold storage. Linux is free and opensource. I highly recommend pepermintOS or MX linux as they are lightweight and pretty easy to setup.\nI will not be guiding you on how to install [[linux]]. But here are some resourses to help you get started:\nInstalling PeperMintOS \u0026lt;\u0026ndash; somewhat 32 bit support, lightweight\nInstalling LinuxMint \u0026lt;\u0026ndash; better for newer computers\nInstalling MX Linux \u0026lt;\u0026ndash; 32 bit support, pretty lightweight\nDownloading \u0026amp; Installing necessary software The first thing that we will need to do is download the required software.\nWe will need featherwallet\nand that\u0026rsquo;s about it.\nTaking the device offline It is highly recommended that you disable the wifi and bluetooth modules on your cold computer. This can be by physically detaching the wifi and bluetooth module or disabling it in the bios. The later is less secure if you\u0026rsquo;re going full on tinfoilhat.\nHere\u0026rsquo;s a guide on how to physically disable them from malvarma.org\nA guide on how to disable it via BIOS can be found by searching your specific hardware on your favorite search engine.\nComputer cold wallet setup Now we will have to setup our wallet. Ensure that your device is completely offline and then open featherwallet.\nClick on Create a new wallet. Then click on Next. You will be presented with your seedphrase. Write it down!! on physical paper. Select a name for your wallet and click Next Select a wallet password and click Next. Now that the wallet is open in the bottom right corner there will be a dot. Click on it and select the offline box and then click Disable all network connections (offline) Phone We will now be installing the anonero software. We will be using NERO from the ANON/NERO suite.\nDownload and install fdroid. Apk can be downloaded from the F-Droid website\nDownload and install orbot. Can be installed from google play store here\nOpen orbot. Select VPN Mode, click on the onion logo that says start\nOpen fdroid and in the settings scroll down and enable Use Tor option\nAgain in the settings that click on the repositories section and add the following:\nhttp://anonero5wmhraxqsvzq2ncgptq6gq45qoto6fnkfwughfl4gbt44swad.onion/fdroid/repo?fingerprint=C5705FF724538F6925B6093517F53C6C6BB6CF82518ED40EB4B8CBBB87DC0D1D\nSource: anonero.io\nClick on latest and then search for NERO\nClick on install That\u0026rsquo;s it ; )\nUpdating NERO If you want to update NERO you will have to turn orbot on, open fdroid and refresh the updates tab\nNERO setup To set up NERO, follow these steps:\nOnce NERO is successfully installed, open the application.\nClick on RESTORE WALLET option and select RESTORE FROM KEYS\nProceed to establish a node connection. You can find a lot of Monero nodes here.\nRandom clearnet node:\nhttp://xmr.monopolymoney.eu:18089 Random Tor node:\nhttp://xmrsalty4hg7lq5ci4kzc2xxcic57azapolbunmkiypnmr3wp7uvqnyd.onion:18089 Copy the node address into the node field. By default you shouldn\u0026rsquo;t need a username or password\nBy default tor connectivity is enabled in NERO. You can disable it by going into the proxy settings and deleting everything.\nClick on Connect. It will try connecting. If it fails check your internet connection or try another node Importing view-only wallet Now you will have to import your wallets Primary address , Secret-View key and Restore height into NERO. To import that info to nero:\nOn your offline computer open featherwallet and navigate to Wallet then View-Only. Enter your password and click on the Show QR\nNow in nero in the View only keys screen click on the square icon to scan the qr. Then scan the qr displayed by featherwallet. All the info should be filled in after scanning the qr code. Click Next.\nSet a pin. After that your wallet should be imported into NERO.\nReceiving monero To receive monero you can follow these steps\nOpen NERO and enter your pin Click on the receive tab (the one with the qr code icon) Long hold on the address Select one of the SubAddreses and click on the copy icon. Transfer any amount of monero to that address. After 10 confirmations it should be spendable. Proceed to the next step.\nSigning transactions Signing/Broadcasting transactions is easy with the NERO/Feather duo. No usbs are needed it is all done via animated QR codes.\nTo sign/broadcast a transaction follow these steps On your phone:\nOpen NERO and enter your pin In the send tab enter the desired address and amount Click on continue, you should now see an animated QR code. On your cold computer\nOpen feather and enter your password Click on Tools \u0026gt; Offline transaction signing. You should now see your camera Show your phone to the computers camera so that it can read the QR code. After it has been picked up by your computer you should see a QR code displayed on your computers screen In NERO.\nClick on SCAN KEY IMAGES Scan the QR code from the computer\u0026rsquo;s screen Once it has been picked up you can see the Address, Amount, Fee and Total. Click on confirm You should now see the unsigned TX screen. In feather click on Next. Then scan the QR code displayed by NERO to your computer. Once the bar is at 100%, you should again see the Address, Amount, Fee and Total. If your ok with that click on SIGN.\nIn NERO\nClick on SCAN SIGNED TX Scan the QR displayed by feather wallet. Click on Yes, once asked whether or not to broadcast transaction You have now sent the transaction.\nif this article helped you out consider supporting me\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/feathernero/","summary":"\u003cp\u003eIn this comprehensive guide, I will walk you through the process of easily setting up Monero cold storage using an old computer and your smartphone, using animated QR codes. No USB needed!\u003c/p\u003e\n\u003ch2 id=\"requirements\"\u003eRequirements\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eAn old laptop/computer with a webcam (to be kept offline). Called \u003cstrong\u003eoffline\u003c/strong\u003e or \u003cstrong\u003ecold\u003c/strong\u003e computer.\u003c/li\u003e\n\u003cli\u003eAn android smartphone.\u003c/li\u003e\n\u003cli\u003eYour main computer\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"required-reads\"\u003eRequired reads\u003c/h2\u003e\n\u003cp\u003eBefore starting this article you \u003cstrong\u003emust\u003c/strong\u003e read:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"https://malvarma.org/before_we_start/what_things_mean.html\"\u003eKey concepts\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://monero.stackexchange.com/questions/2426/offline-transaction-signing-what-are-the-details\"\u003eMonero offline transaction signing details\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"cold-computer-setup\"\u003eCold computer setup\u003c/h2\u003e\n\u003cp\u003eYour offline computer/laptop will be signing all of the transactions. It should always be kept offline i.e cold. It can not be used for other tasks.\u003c/p\u003e","title":"Ultimate Monero ColdStorage Guide (Feather X Anonero)"},{"content":"In this article I will show you how to \u0026ldquo;easily\u0026rdquo; generate a live archlinux usb with the monero gui pre-installed.\nRequirements An archlinux install A usb Setup In this guide I will show you how to build a custom archlinux iso with monerogui installed. I will not be providing any pre-built images.\nThe first thing you will have to do is install archuseriso. You can install it from the aur using this command:\nyay -S archuseriso\nNow open a terminal and navigate to any directory. Then run the following command:\nsudo aui-mkiso -m 'img' --add-pkg=monero-gui xfce --verbose\nThis will build a new gpt image with persistense, add the monero-gui package and use xfce as the default desktop. The \u0026ndash;verbose flag is optional.\nAfter that is finished building you can use your favourite image writter to write the image. I will be using dd sudo dd if=out/aui-xfce*.img of=/dev/CHANGEME\nYou will have to write that to your usb, so in /dev/CHANGEME just put your usb. You can find it by running lsblk Don\u0026rsquo;t be stupid If you enter the wrong device this could lead to data loss. Be careful!\nAfter the image is written you will have to boot to your usb.\nFirst however it is recommended that you disconnect any ethernet/other cables plugged in so that it is trully offline.\nYou can also disable wifi and bluetooth from the bios . \u0026ldquo;Advanced\u0026rdquo; users only don\u0026rsquo;t be retarded\nNow only plug in your usb drive and reboot into the usb. You will generaly have to press either F8,F9,F10,F11 upon booting and then select your usb.\nNow you have two options\nBoot into persistent. Boot into memory. When booting into persistent your files will be saved. This however does also involve your wallet file.\nFor the more secure option you can select boot into memory. This will delete all the traces of the wallet after reboot. You will have to write the seed down and manually enter it upon every boot if you want to authorize transactions.\nI will boot into persistent since I will use a strong password and will keep the usb in a safe place. If you want to be extra paranoid use the second option.\nAfter the os has fully booted you will have to click on the Applications icon \u0026gt; internet \u0026gt; Monero GUI. Alternatively open a terminal and type monero-wallet-gui\nYou will now be greated by the monero gui setup guide.\nSelect your language etc.\nSelect advanced \u0026gt; Click on Create a new wallet . You can select whatever you want in the wallet name and location \u0026gt; Click next.\nNow you will be prompted with your recovery phrase. Write it down on PHYSICAL PAPER and keep it in a safe place. Also note the height and or creation date.\nWrite it down! If you don\u0026rsquo;t write down your seed and keep it in a secure place you will lose access to your monero!\nThen click next. Now select a strong password. Alteast 12 chars!. Remeber it!\nClick next. Then click on Connect to a remote node but don\u0026rsquo;t add one, we don\u0026rsquo;t need it.\nThen click on create wallet.\nAfter you have opened your wallet, click on settings and then Create view-only wallet. Then click on ok. Logout of your wallet. Click on Open wallet from file and select the new file called WALLETNAME_viewonly.\nOnce you have logged into your view only wallet click on settings again and select Show seeds and keys. Scroll down to the botton and import your view only wallet via qr to your mobile wallet. Here are some guides for every wallet:\nCake wallet Monerujo What have we acomplished? You now have a cold wallet for offline signing on your usb and a view-only wallet on your phone. Basicly you can view all incoming transactions on your phone but can\u0026rsquo;t spend them there. Only your computer booted into the usb can sign them.\nSigning transactions I won\u0026rsquo;t cover doing this in this article. But you can find out more about how to send transactions from cold storage here\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/coldstorage/","summary":"\u003cp\u003eIn this article I will show you how to \u0026ldquo;easily\u0026rdquo; generate a live archlinux usb with the monero gui pre-installed.\u003c/p\u003e\n\u003ch2 id=\"requirements\"\u003eRequirements\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eAn archlinux install\u003c/li\u003e\n\u003cli\u003eA usb\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"setup\"\u003eSetup\u003c/h2\u003e\n\u003cp\u003eIn this guide I will show you how to build a custom archlinux iso with monerogui installed. I will not be providing any pre-built images.\u003c/p\u003e\n\u003cp\u003eThe first thing you will have to do is install \u003ca href=\"https://github.com/laurent85v/archuseriso\"\u003earchuseriso\u003c/a\u003e. You can install it from the aur using this command:\u003c/p\u003e","title":"Easy monero cold storage"},{"content":"Created the monero archive (tor)\n","permalink":"https://4rkal.com/updates/monero-archive/","summary":"\u003cp\u003eCreated the \u003ca href=\"http://archivetqvrw5cje5alvnpw6xynykae3uaswynheyxxtbwusx72q6nqd.onion/\"\u003emonero archive\u003c/a\u003e (tor)\u003c/p\u003e","title":"Created the monero archive"},{"content":"I am participating in hacktoberfest 2023\nGot a tree planted in my name here\n","permalink":"https://4rkal.com/updates/hacktoberfest23/","summary":"\u003cp\u003eI am participating in hacktoberfest 2023\u003c/p\u003e\n\u003cp\u003eGot a tree planted in my name \u003ca href=\"https://tree-nation.com/trees/view/5247885\"\u003ehere\u003c/a\u003e\u003c/p\u003e","title":"Hacktoberfest 2023"},{"content":"In this article I will show you how I securely connect to my remote machines without having to configure port forwarding.\nRequirements: A computer \u0026ldquo;server\u0026rdquo; (running linux) A internet connection Another computer to connect to your server (running linux) Why? If you want to access your server without portforwarding in a extremely secure fashion you will want to follow this tutorial. You will be connecting to the server via tor which will make it harder for anyone to find the url of the server and ill show you how to setup keybased auth for even more security!\nSetup You will have to install the following packages (ssh, tor)\nOn debian\nsudo apt install openssh-client\nOn arch\nsudo pacman -S openssh\nAfter that enable the ssh service\nDebian:\nsudo systemctl enable ssh\nArch:\nsudo systemctl enable sshd\nIf you want to check if this worked just use another computer and run\nssh USER@IP\nfor example I run\nssh arkal@192.168.1.69\nAfter this you can enable KeyBased authentication for more security\nHere is my article how to enable that :\nEnable keybased authentication\nNow we need to install tor:\nOn debian\nsudo apt install tor\nOn arch\nsudo pacman -S tor\nThen start and enable the tor service with\nsudo systemctl start tor \u0026amp;\u0026amp; sudo systemctl enable tor\nAfter you have done that you want to edit your torrc file. Using your favorite text editor\nsudo vim /etc/tor/torrc\nNow you will want to navigate to the part that says HiddenService. And paste the following\nHiddenServiceDir /var/lib/tor/ssh/ HiddenServicePort 22 127.0.0.1:22 Save your file and exit the editor (for nano cntrl s, cntrl x)\nNow you want will have to restart the tor service\nsudo systemctl restart tor\nAfter that run the following:\nsudo cat /var/lib/tor/ssh/hostname\nYou should see a string of letters and characters ending in .onion Now on your other machine:\nConnecting to the server On your main machine you will have to do the following:\nHave ssh, tor, and socat installed\nAfter you have installed them you will have to edit the ssh config\nvim .ssh/config\nAnd paste the following\nHost NAME Hostname URL.onion User USER Port 22 Proxycommand socat - SOCKS4A:127.0.0.1:%h:%p,socksport=9050 You will have to change the NAME, URL and USER. The user is the user you want to connect as to your server and the url is the url you that ends in .onion from above.\nNow save the file and exit.\nNow edit the torrc file. Using your favorite text editor:\nvim /etc/tor/torrc\nFind the line that says SOCKSPort and uncomment it\nSOCKSPort 9050\nRestart the tor service\nsystemctl restart tor\nTo connect to the server run the following command:\nssh NAME\nWith NAME being the name that you gave to the server in the config file.\nIf this article helped you out consider supporting me\n","permalink":"https://4rkal.com/posts/onionssh/","summary":"\u003cp\u003eIn this article I will show you how I securely connect to my remote machines without having to configure port forwarding.\u003c/p\u003e\n\u003ch2 id=\"requirements\"\u003eRequirements:\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eA computer \u0026ldquo;server\u0026rdquo; (running linux)\u003c/li\u003e\n\u003cli\u003eA internet connection\u003c/li\u003e\n\u003cli\u003eAnother computer to connect to your server (running linux)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"why\"\u003eWhy?\u003c/h2\u003e\n\u003cp\u003eIf you want to access your server without portforwarding in a extremely secure fashion you will want to follow this tutorial. You will be connecting to the server via tor which will make it harder for anyone to find the url of the server and ill show you how to setup keybased auth for even more security!\u003c/p\u003e","title":"SSH Remote Access NO Port-Forwarding NO Cloudflare"},{"content":"In this article I’ll show you how I setup this blog completely for free. I’ll show you how to use hugo to write your blog, Cloudflare and eu.org for your domain and ssl, Render and github for the hosting and even how to get your blog on google.\nWhat is hugo? Hugo is a fast and popular open-source static site generator used for creating static websites without requiring a database or dynamic components.\nHugo setup Download and install hugo\nOn debian type\nsudo apt install hugo\nOn arch type\nsudo pacman -S hugo\nOn fedora type\nsudo dnf install hugo On windows:\nNavigate to https://github.com/gohugoio/hugo/releases/latest\nFind the windows version and download it.\nUnzip the file to your desired directory\nAdd this directory to the PATH environment variable\nRead more: https://gohugo.io/installation/windows/\nCreating the hugo site Open up a terminal and type:\nhugo new site my_website\nAnd then cd into that directory\ncd my_website\nAfter that we will have to install a theme. I will be using the LoveIt theme but you can use any other theme\nAll hugo themes https://themes.gohugo.io/\nNOTE: I now use a completely different theme New look, new start\nFor the LoveIt theme:\nThe first thing we will have to do is type\ngit clone https://github.com/dillonzq/LoveIt.git themes/LoveIt\nYou will have to have git installed if you don’t, follow the instructions on the page to download it.\nNow we will have to create some basic configuration. Every theme has its own so you should first check your themes documentation. Some basic settings work for all themes.\nHere is an example of the most basic settings for the LoveIt theme. (it has to be saved in config.toml)\nbaseURL = \u0026#34;http://example.org/\u0026#34; # Change the default theme to be use when building the site with Hugo theme = \u0026#34;LoveIt\u0026#34; # website title title = \u0026#34;My New Hugo Site\u0026#34; # language code [\u0026#34;en\u0026#34;, \u0026#34;zh-CN\u0026#34;, \u0026#34;fr\u0026#34;, \u0026#34;pl\u0026#34;, ...] languageCode = \u0026#34;en\u0026#34; # language name [\u0026#34;English\u0026#34;, \u0026#34;简体中文\u0026#34;, \u0026#34;Français\u0026#34;, \u0026#34;Polski\u0026#34;, ...] languageName = \u0026#34;English\u0026#34; # Author config [author] name = \u0026#34;xxxx\u0026#34; email = \u0026#34;\u0026#34; link = \u0026#34;\u0026#34; # Menu config [menu] [[menu.main]] weight = 1 identifier = \u0026#34;posts\u0026#34; # you can add extra information before the name (HTML format is supported), such as icons pre = \u0026#34;\u0026#34; # you can add extra information after the name (HTML format is supported), such as icons post = \u0026#34;\u0026#34; name = \u0026#34;Posts\u0026#34; url = \u0026#34;/posts/\u0026#34; # title will be shown when you hover on this menu link title = \u0026#34;\u0026#34; [[menu.main]] weight = 2 identifier = \u0026#34;tags\u0026#34; pre = \u0026#34;\u0026#34; post = \u0026#34;\u0026#34; name = \u0026#34;Tags\u0026#34; url = \u0026#34;/tags/\u0026#34; title = \u0026#34;\u0026#34; [[menu.main]] weight = 3 identifier = \u0026#34;categories\u0026#34; pre = \u0026#34;\u0026#34; post = \u0026#34;\u0026#34; name = \u0026#34;Categories\u0026#34; url = \u0026#34;/categories/\u0026#34; title = \u0026#34;\u0026#34; # Markup related configuration in Hugo [markup] # Syntax Highlighting (https://gohugo.io/content-management/syntax-highlighting) [markup.highlight] # false is a necessary configuration (https://github.com/dillonzq/LoveIt/issues/158) noClasses = false You can find my configuration here\nYou can view your page live by running\nhugo serve\nLet’s move on to the next step.\nAdding articles to our blog The first thing we will have to do is create a new file with any name ending in .md inside of our content folder. I like to separate my posts from other sections so I will create another folder inside of the content one called posts.\nYou can run this command to add the file\nhugo new posts/first_post.md\nNow open the file that was just created using your favorite text editor.\nYou should see something like this:\n--- title: \u0026#34;Epic title\u0026#34; date: 2023-03-23T18:13:03+03:00 draft: true --- If you want the post to be publicly visible on your blog delete the draft line. or set it to false.\nNow if we want to add some content we will have to write it in markdown. Heres a great guide on some basic markdown syntax https://hugoloveit.com/basic-markdown-syntax/\nHeres an example of some content\n--- title: \u0026#34;My First Post\u0026#34; date: 2023-03-23T18:13:03+03:00 draft: false --- # Welcome to my blog! This is my first post. Here\u0026#39;s a picture of my cat: ![My cat](/images/cat.jpg) Using the above steps you can add all of your articles to the blog.\nNow that we are done with that let me show you how we will publish our blog.\nDomain More like a sub-domain. Head to eu.org and get a free domain. Create an account and submit a request for a new domain. It might take some time even months to get accepted.\nI have already registered 4rkal.eu.org from there.\nNow we will have to get some ssl certificates using cloudflare.\nSSL certificates just make your site use https instead of http this is really great for seo and doesn’t make your site look sus.\nHead over to cloudflare.com and create an account for free.\nAfter you are done with that go to your dashboard and select websites and then add a site.\nYou should see something like this\nEnter your websites url and click on add site.\nAfter that select the free plan and continue.\nNow it will review your dns records. Just select continue and confirm\nNow you will have to change your domain’s name servers.\nTo do that head back to eu.org select your domain and click on the nameservers tab and select server names.\nNow in the input fields enter the name servers.\nThe name servers will most probably be:\nnancy.ns.cloudflare.com uriah.ns.cloudflare.com Here’s how it should probably look:\nNow click on the submit button.\nYou should probably get\nNo error, applying changes... Done If you get an error you probably screwed up one of the above steps. Just try again.\nAfter your name servers have been changed and everything is done, in your domain dashboard select SSL/TLS. Just select full encryption.\nHosting our site. First create a github account. Head to github.com for that. You will also have to install git\nAfter you have done that navigate to your blog’s root directory and type:\ngit init hugo git add . git commit -m \u0026#34;first commmit\u0026#34; git branch -M main Now go to github and create a new repository.\nYou should now type:\ngit remote add origin YOURURL\ninstead of YOURURL enter the url to your github repo and add a .git ending\neg\ngit remote add origin https://github.com/4rkal/blog.git\nNow push the changes with\ngit push -u origin main\nAfter that if you refresh the page of your github repo you should see everything there.\nNow head to render.com and create an account\nOn your dashboard select +New and then static site.\nNow you will be prompted to connect a github repository. Just connect your account and add that repository.\neg\nNow enter a service name eg myblog and in the publish directory just add\npublic\nThen click on create static site.\nAfter it has been deployed successfully head over to the settings and in the custom domains tab click on add custom domain.\nIn the field enter the domain that we registered with eu.org previously.\nNow go to cloudflare and in your domain dashboard select dns and click on add a new record.\nIn the type dropdown select CNAME in the name field add @ and in the target add your blog’s url from render. Mine is https://blog-ygtj.onrender.com/. Also untick the proxy status.\nNow we will have to do the same but with the www.\nJust do the same steps as above but instead of @ just add www\nThat’s it. After a couple of minutes your blog should be live.\nSEO Google and bing If you want to get your website on google and bing it’s pretty easy\nIf you want to get your website on google follow the guide listed here https://developers.google.com/search\nFor bing it should be pretty much the same process on https://www.bing.com/webmasters/\n*If you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/thisblog/","summary":"\u003cp\u003eIn this article I’ll show you how I setup this blog completely for free. I’ll show you how to use hugo to write your blog, Cloudflare and eu.org for your domain and ssl, Render and github for the hosting and even how to get your blog on google.\u003c/p\u003e\n\u003ch1 id=\"what-is-hugo\"\u003eWhat is hugo?\u003c/h1\u003e\n\u003cp\u003eHugo is a fast and popular open-source static site generator used for creating static websites without requiring a database or dynamic components.\u003c/p\u003e","title":"How I setup this blog for free (domain, hosting, ssl) Complete Guide"},{"content":"Why you should use Python. Going over the basics of Python.\nIn this course/article I will be talking about why someone should use Python. Later on, I will be tackling the basics of Python. But let\u0026rsquo;s start by explaining what coding is.\nWhat is coding? Coding means writing instructions for computers and a finished set of instructions is known as a program. Computer programs control everything from smartphones to space rockets.\nWhat is Python? Python is a text-based computer language which means it’s made up of words and symbols (such as * and = ). Its language elements and object-oriented approach are meant to assist programmers in writing clear, logical code for both small and large-scale projects.\nWhy Python? Python is one of the most popular computer languages and it’s very concise — that is, you don\u0026rsquo;t need to type much in order to create programs that do a lot.\nAdvantages of python Simple to read, learn, and write Python is a high-level programming language with a syntax that is similar to English. This makes the code easier to read and comprehend.\nPython is really simple to pick up and understand, which is why many people suggest it to newcomers. When compared to other prominent languages like C/C++ and Java, you require fewer lines of code to accomplish the same purpose.\nImproved Productivity Python is an extremely useful programming language. Python’s simplicity allows developers to concentrate on solving the problem.\nThey don’t need to spend a lot of time learning the programming language’s syntax or behaviour. You write less code and accomplish more.\nFree and Open-Source Python comes under the OSI-approved open-source license. As a result, it is both free to use and distribute. You can get the source code, change it, and even share your own Python version.\nPortability In many languages like C/C++, you need to change your code to run the program on different platforms. With Python, however, this is not the case. You only have to write it once and it may be used wherever.\nDownloading Python On Linux You probably already know how to install it but I\u0026rsquo;m gonna show it anyways.\nOpen your terminal and type python or python3; if it does not work then run: (depending on your distro) sudo apt install python3\nWindows 10 1 . First check if you already have Python installed. Go to the ‘Start’ menu and click on the ‘All programs’. If you see the word “Python” it means that you already have it installed. If you don\u0026rsquo;t already have it installed go to https://python.org, download the correct version for your computer and then install it.\nPython comes in different versions. This course uses version 3 and upwards. I recommend always installing the latest version. What is an IDE? IDE stands for the integrated development environment (IDE) and is software for building applications that combine common developer tools into a single Graphical User Interface (GUI).\nThe IDE that we will be using in this series is called VS Code.\nDownloading VS Code Go to https://code.visualstudio.com/ and download the version that you want. Vs Code is available for Windows, Mac, and Linux. Follow the instructions on the website for installation.\nStarting in Python It\u0026rsquo;s traditional in the programming world to make the computer say ‘Hello World’ with your very first piece of code. In Python, this is very simple.\nOpen Vs Code and click on File \u0026gt; New File and name your file helloworld.py. The .py tells the computer that this is a Python program. In your project, in VS Code type : print(\u0026quot;Hello World!\u0026quot;) Save your project and click on the run button at the top of your screen If you have done everything correctly you should see a Hello World message in your terminal. If it didn\u0026rsquo;t work you should get a red error message something like this:\nSyntaxError: invalid syntax\nIf that happens make sure that you have copied it exactly like above.\nPlaying With numbers in Python Python makes it easy to do maths. You just type in a question and get the answer\nAdding Up\nOpen an empty project and type:\nprint(2+2)\nYou should see the answer: 4\nSubtracting(and more) If you want to subtract, use the ‘-’ symbol like this:\nprint(2 - 2)\nTo multiply use the ‘*’ symbol:\nprint(2 * 2)\nTo divide, use the ‘/’ symbol\nprint(2 / 2)\nVariables A variable is like a labelled box that stores information. You can change this information but the label stays the same.\nCreating a variable: To tell the computer what you want your variable to be, you use the = sign. This is called assigning a value to a variable. It’s very simple, here\u0026rsquo;s an example using fish.\nOpen a new VS Code project and type: fish = 5 Imagine a cat gets hungry and eats two fish. To create another variable for the amount eaten, write the following:\nfishEaten = 2\nPress enter and then type:\nprint(fish - fishEaten)\nSave and run your code and you should get the answer: 3\nInput in Python You can use the input() function to ask for information from the user.\nOpen a new VS Code project and type: name = input(\u0026quot;What is your name? \u0026quot;)\nRun the program and you should get the following message: What is your name? 3. Now let\u0026rsquo;s try printing your name.\nAdd the following to your program:\nprint(name)\nYou have successfully created an input field!\nThis can be very useful in creating decision games.\nMaking Decisions To write a program that allows you to make decisions the computer needs to react differently to different answers. For this, you need conditions to compare pieces of information, and conditionals to create different paths through the program.\nWhat are Conditions? A condition is a bit of code that compares two pieces of information. Conditions use operators to make these comparisons. For example, the operator == checks if two pieces of information are the same.\nOpen a new Vs Code project and type: age = 10 if age == 12: print(\u0026#34;True\u0026#34;) else: print(\u0026#34;False\u0026#34;) Save and run and you should get False That is because ‘age’ is set to 10 and not 12\nWhat are conditionals To use a condition in your code you need a command called a condition. Conditionals use conditions. Conditions show if something is True or False.\nIF One important condition is known as an if statement which tests whether a condition is true. If it is, the computer will follow the instructions after the if statement. If not, the computer will just skip it. In Python, if is a keyword. Dont use it as a variable name because the computer will think that it\u0026rsquo;s an if statement and get confused.\nImplementing the if condition Create a new VS Code project and type the following: user_reply = (\u0026quot;Do you like python? (Type yes or no) \u0026quot;)\nThen we will implement the if condition by typing the following: if user_reply == \u0026#34;yes\u0026#34; print(\u0026#34;Python likes you to ! \u0026#34;) ELIF elif is short for else if. If the conditions of the if code isn’t met it “sweeps up” whatever is left.\nNow type the following: elif user_reply == \u0026#34;maybe\u0026#34;: print(\u0026#34;Make up your mind!\u0026#34;) ELSE When conditions for the if and elif code arent met, else goes into action and “sweeps up” whatever is left.\nLet\u0026rsquo;s implement that: 4. Now type the following:\nelse: print(\u0026#34;Well python doesn\u0026#39;t like you either\u0026#34;) The complete code should look something like this:\nuser_reply = (\u0026#34;Do you like python? (Type yes or no) \u0026#34;) if user_reply == \u0026#34;yes\u0026#34; print(\u0026#34;Python likes you to ! \u0026#34;) elif user_reply == \u0026#34;maybe\u0026#34;: print(\u0026#34;Make up your mind!\u0026#34;) else: print(\u0026#34;Well python doesn\u0026#39;t like you either\u0026#34;) Don\u0026rsquo;t forget to press the tab after if statements.\nRandomness in python In python we can use the random function in order to generate random numbers. This can be extremely useful in a variety of things.\nThe first thing we will have to do is import the random function\nimport random\nAfter that we can print out a random number with the following\nprint(random.randint(1,10))\nThis will output a random number from 1–10\nrandint stands for random integer.\nHere is the full code.\nimport random print(random.randint(1,10)) Loops in python There are two types of loops in python\nWhile loop For loop While loops only stop when something changes. If it doesn\u0026rsquo;t change they could go on forever.\nWith for loops on the other hand you can define exactly when you want them to stop\nThe most popular example of a while loop is\nwhile True:\nWhich will run forever eg\nwhile True: print(\u0026#34;hi\u0026#34;) This will run forever.\nWith while loops on the other hand you can define exactly how many times you want the loop to run.\nfor x in range(0,10): print(\u0026#34;Hi\u0026#34;) This will print Hi exactly 10 times\nGuessing game Now lets combine what learned from above and from our previous articles to create a game\nThe computer will select a random number from 1–10 and you will have to guess it.\nThe first thing we will have to do is\nimport random\nAfter that we will create a variable called number\nnumber = random.randint(1,10)\nAfter that we will create another variable called your_guess\nyour_guess = int(input(\u0026quot;Im thinking of a number from 1 to 10, can you guess which one?\u0026quot;))\nWe are using int as you will have to enter a number\nNow we will create a while loop that will keep the game running until you guess the number\nwhile your_guess != number:\nThe code so far is\nimport random number = random.randint(1,10) your_guess = int(input(\u0026#34;Im thinking of a number from 1 to 10, can you guess which one?\u0026#34;)) while your_guess != number: if your_guess \u0026lt; number: print(\u0026#34;Your number was too low\u0026#34;) else: print(\u0026#34;You number was to high\u0026#34;) And the following\nprint(\u0026quot;GG you found it\u0026quot;)\nYou code should now look like this\nimport random number = random.randint(1,10) your_guess = int(input(\u0026#34;Im thinking of a number from 1 to 10, can you guess which one?\u0026#34;)) while your_guess != number: if your_guess \u0026lt; number: print(\u0026#34;Your number was too low\u0026#34;) else: print(\u0026#34;You number was to high\u0026#34;) your_guess = int(input(\u0026#34;Please try again... \u0026#34;)) print(\u0026#34;GG you found it\u0026#34;) Thats it for now\nStay tuned for more\nIf you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/python/","summary":"\u003cp\u003eWhy you should use Python. Going over the basics of Python.\u003c/p\u003e\n\u003cp\u003eIn this course/article I will be talking about why someone should use Python. Later on, I will be tackling the basics of Python. But let\u0026rsquo;s start by explaining what coding is.\u003c/p\u003e\n\u003ch2 id=\"what-is-coding\"\u003eWhat is coding?\u003c/h2\u003e\n\u003cp\u003eCoding means writing instructions for computers and a finished set of instructions is known as a program. Computer programs control everything from smartphones to space rockets.\u003c/p\u003e","title":"Python for Complete Beginners"},{"content":"What is PocketBase PocketBase is an open source backend made in go consisting of embedded database (SQLite) with realtime subscriptions, built-in auth management, convenient dashboard UI and simple REST-ish API.\nInstall PocketBase The first thing that you will have to do is head to https://pocketbase.io and select the file for your operating system. Since I am using linux I will show how to set this up on linux but it should be pretty similar for any other os.\nUnzip the file and open up a terminal to the path that you extracted the file to and type:\n./pocketbase serve\nIf you want to serve some static content you can create a new directory called pb_public\nmkdir pb_public\nThen paste any content into that directory\neg.\n\u0026lt;!DOCTYPE html\u0026gt; \u0026lt;html lang=\u0026#34;en\u0026#34;\u0026gt; \u0026lt;head\u0026gt; \u0026lt;meta charset=\u0026#34;UTF-8\u0026#34;\u0026gt; \u0026lt;meta http-equiv=\u0026#34;X-UA-Compatible\u0026#34; content=\u0026#34;IE=edge\u0026#34;\u0026gt; \u0026lt;meta name=\u0026#34;viewport\u0026#34; content=\u0026#34;width=device-width, initial-scale=1.0\u0026#34;\u0026gt; \u0026lt;title\u0026gt;Epic Website\u0026lt;/title\u0026gt; \u0026lt;/head\u0026gt; \u0026lt;body\u0026gt; \u0026lt;h1\u0026gt;My epic website\u0026lt;/h1\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; And save that as index.html inside of the pb_public folder\nNow if you head to http://127.0.0.1:8090/ you should see the website that we entered above.\nIf you go to http://127.0.0.1:8090/_/ it will take you to an admin portal. There you should create a account. After you have setted up your account you should see something like this.\nHere you can add and create users\nAnd also create custom collections eg\nIf you click on the settings icon you can see that you will be able to add applications, mail settings, file storage (s3) , export/import collections, add or remove auth providers, token options and add/remove admins.\nThat’s it for now if you want to learn more check out https://pocketbase.io/docs/\nIf you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/pocketbase/","summary":"\u003ch1 id=\"what-is-pocketbase\"\u003eWhat is PocketBase\u003c/h1\u003e\n\u003cp\u003ePocketBase is an open source backend made in go consisting of embedded database (SQLite) with realtime subscriptions, built-in auth management, convenient dashboard UI and simple REST-ish API.\u003c/p\u003e\n\u003ch2 id=\"install-pocketbase\"\u003eInstall PocketBase\u003c/h2\u003e\n\u003cp\u003eThe first thing that you will have to do is head to \u003ca href=\"https://pocketbase.io\"\u003ehttps://pocketbase.io\u003c/a\u003e and select the file for your operating system. Since I am using linux I will show how to set this up on linux but it should be pretty similar for any other os.\u003c/p\u003e","title":"PocketBase self-hosted Firebase alternative"},{"content":"In this article, I will tell you why Monero fits my views of what a cryptocurrency should look like.\nWhat is Monero? Monero is a decentralized cryptocurrency. It uses a public distributed ledger with privacy-enhancing technologies that obfuscate transactions to achieve anonymity and fungibility. Observers cannot decipher addresses trading Monero, transaction amounts, address balances, or transaction histories.\nMonero works like any other currency but with some privacy and decentralization innovations.\nMonero uses stealth addresses alongside ring signatures and ring CTs to \u0026ldquo;hide\u0026rdquo; the transaction and transaction amounts, enhancing transaction privacy. To further decentralize the network, Monero uses the RandomX algorithm to discourage the use of ASICs.\nThe Main Problems with Bitcoin and Other Cryptos Bitcoin may seem like a perfect currency. However, under the hood, Bitcoin has many flaws.\nOne of the main problems with Bitcoin is that it isn\u0026rsquo;t actually censorship-resistant. A central bank or government can blacklist your address and block exchanges from accepting it. While there are ways to get around that, it isn\u0026rsquo;t easy. Monero, on the other hand, is censorship-resistant as it doesn\u0026rsquo;t display transaction amounts or receivers.\nAnother problem with Bitcoin and other PoW currencies is that they are actually controlled by a small number of people since they are really hard to mine, among many other factors. Monero is a relatively easy currency to mine and is ASIC-resistant, which makes it even more decentralized as anyone with a computer and an internet connection can start contributing to the network.\nBitcoin has a block size limit, which results in more expensive transactions and longer waiting times. Monero uses a dynamic block size.\nAlso, Bitcoin has a high block time, which means that transactions take longer to be confirmed and executed. Bitcoin\u0026rsquo;s block time is ~10 minutes, while Monero\u0026rsquo;s block time is ~2 minutes.\nBitcoin has halving once every 4 years. The halving halves the amount of mined (printed) Bitcoin in every block. This, by itself, increases price volatility and transaction fee volatility.\nMonero has chosen a 0.6 XMR block reward forever. Any good currency wants to have as little volatility as possible. Monero is a currency, not a \u0026ldquo;number go up coin.\u0026rdquo;\nConclusion Monero is basically what people think Bitcoin is. Here\u0026rsquo;s a great video about it.\nDisclaimer Tech has nothing to do with price. This article reviews the tech of this project and is thus not financial advice. Please DYOR when investing.\nSupport Me If you enjoyed this article, consider supporting me:\nMonero:\n8AztDJtwb7iKaqP4KXRG39VibAacCY1mMfH3bNsVjhYMYbohtT5LKoTSRP6vJGtjeBSPEpFdHZx3ZL3iVowYdkqeQwPAG2o\n","permalink":"https://4rkal.com/posts/whymonero/","summary":"\u003cp\u003eIn this article, I will tell you why Monero fits my views of what a cryptocurrency should look like.\u003c/p\u003e\n\u003ch1 id=\"what-is-monero\"\u003eWhat is Monero?\u003c/h1\u003e\n\u003cp\u003eMonero is a decentralized cryptocurrency. It uses a public distributed ledger with privacy-enhancing technologies that obfuscate transactions to achieve anonymity and fungibility. Observers cannot decipher addresses trading Monero, transaction amounts, address balances, or transaction histories.\u003c/p\u003e\n\u003cp\u003eMonero works like any other currency but with some privacy and decentralization innovations.\u003c/p\u003e","title":"Why Monero is the ultimate form of a cryptocurrency"},{"content":"Whats ventoy? Ventoy is a free and open-source utility used for writing image files such as .iso, .wim, .img, .vhd(x), and .efi files onto storage media to create bootable USB flash drives. Once Ventoy is installed onto a USB drive, there is no need to reformat the disk to update it with new installation files; it is enough to copy the .iso to the USB drive and boot from them directly. Ventoy will present the user with a boot menu to select one of these files.\nWith ventoy, you don’t need to format the disk over and over, you just need to copy the ISO files to the USB drive and boot them directly.\nRequirements a computer a internet connection (pretty hard without one) a usb (min 8gb) Installation Ventoy is available on both linux and windows.\nThe first thing you will have to do is head to ventoy.net . On the download page select your operating system and click on download.\nOn linux After you have extracted the file open the folder and click on the VentoyGUI .\nDepending on your processor type select the file ending in either aarch64 i386 mips64el or x86_64. (It will most probably be x86_64).\nAfter that you should see something like this: Select your device from the devices tab\nThen click on install.\nOn windows Download the file and unzip it\nThen click on the file called Ventoy2Disk.exe\nYou should see something like this\nSelect your usb device from the drop down and click on install.\nUsing ventoy To use ventoy all you have to do is paste your iso files inside of the usb. No need for formatting etc.\nWhen you boot into your usb you will be prompted which of the iso\u0026rsquo;s to use. That\u0026rsquo;s about it.\nEnjoy not having to reformat your usb for each iso/OS.\nJoin my free newsletter! Subscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/ventoy/","summary":"\u003ch2 id=\"whats-ventoy\"\u003eWhats ventoy?\u003c/h2\u003e\n\u003cp\u003eVentoy is a free and open-source utility used for writing image files such as .iso, .wim, .img, .vhd(x), and .efi files onto storage media to create bootable USB flash drives. Once Ventoy is installed onto a USB drive, there is no need to reformat the disk to update it with new installation files; it is enough to copy the .iso to the USB drive and boot from them directly. Ventoy will present the user with a boot menu to select one of these files.\u003c/p\u003e","title":"Create a MultiBoot USB using ventoy"},{"content":"Whether you want to scan your network for vulnerabilities or just want to see which ports you have open, nmap can be extremely useful.\nWhat is nmap Nmap (Network Mapper) is a network scanner created by Gordon Lyon . Nmap sends packets and examines the answers to find hosts and services on a computer network. For probing computer networks, Nmap offers a variety of functionalities, including host discovery, service detection, and operating system detection. Scripts that offer more sophisticated service discovery, vulnerability detection, and other features can extend these features. During a scan, Nmap can adjust to changing network conditions, such as latency and congestion.\nInstallation Nmap is available for linux, windows , mac os and even bsd\nIf you are using linux you can install it using your package manager.\nOn apt\nsudo apt install nmap\nOn dnf\nsudo dnf install nmap\nWith pacman\nsudo pacman -S nmap\nOn windows you have to download the executable from the nmap website.\nhttps://nmap.org/download.html\nThe same goes for mac and any other os\nGetting Started The first thing I will show you how to do is find all the ip addresses connected to your local network.\nThe first thing you will have to do is find your inet ip\nOn Linux type\nip a\nOn windows\nipconfig\nYou should see a lot of information, try to find inet. It should look something like this\ninet 192.168.1.28/24\nand copy the ip\nNow type\nnmap -sn IP\nInstead of ip type the ip we found from above\nNow you should see a large list of all the ips connected to your network.\n-sn flag stands for no port scan\nNow we can also get all the ports open on all the ips on your local network\nTo do that type\nnmap IP\nInstead of ip type the ip we found from above\nNow if you have any computers on your local networks with open ports you should see them now\nEg.\nI have a ssh port open on one of my machines so I can see\nPORT STATE SERVICE 22/tcp open ssh If you are running a web server ports 80 and 443 should be open.\nNow lets say that you want to find out what operating system a specified device on your network is running.\nTo do that type\nsudo nmap -O IP\nEg.\nsudo nmap -O 192.168.1.16\nIn my case my device is running linux and you can even find out what kernel version your device is running\nPORT STATE SERVICE 22/tcp open ssh Device type: general purpose Running: Linux 2.6.X OS CPE: cpe:/o:linux:linux_kernel:2.6.32 OS details: Linux 2.6.32 You can press enter while running a scan to see how much time is left\nLets say that you dont want anyone monitoring a network be able to trace back the scan to you.\nFor that we can use decoy mode\nTo use decoy mode add -D followed by any random ip to any nmap command.\neg\nsudo nmap -D 192.168.1.11 192.168.1.16\nThis will make it so that it looks like both your ip and 192.168.1.11 are performing a port scan on 192.168.1.16\nYou can also add multiple ips by adding commas\neg\nsudo nmap -D 192.168.1.11,192.168.1.12 192.168.1.16\nThats all for now\nGG You have now learnt the basics of nmap ***If you enjoyed this article consider supporting me\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/nmap/","summary":"\u003cp\u003eWhether you want to scan your network for vulnerabilities or just want to see which ports you have open, nmap can be extremely useful.\u003c/p\u003e\n\u003ch1 id=\"what-is-nmap\"\u003eWhat is nmap\u003c/h1\u003e\n\u003cp\u003eNmap (Network Mapper) is a network scanner created by Gordon Lyon . Nmap sends packets and examines the answers to find hosts and services on a computer network. For probing computer networks, Nmap offers a variety of functionalities, including host discovery, service detection, and operating system detection. Scripts that offer more sophisticated service discovery, vulnerability detection, and other features can extend these features. During a scan, Nmap can adjust to changing network conditions, such as latency and congestion.\u003c/p\u003e","title":"Nmap(Network Mapper) For Beginners"},{"content":"Microsoft purchased GitHub in 2018, something many users are not aware of. After Microsoft’s acquisition of GitHub there have been many controversies like blocking private repositories and access to GitHub pages in certain countries and of course, GitHub Copilot.\nWhat is Github Copilot GitHub Copilot is an artificial intelligence tool developed by GitHub and OpenAI to assist users of Visual Studio Code, Visual Studio, Neovim, and JetBrains integrated development environments (IDEs) by autocompleting code. Currently available by subscription to individual developers, the tool was first announced by GitHub on 29 June 2021, and works best for users coding in Python, JavaScript, TypeScript, Ruby, and Go.\nHow does copilot work? GitHub Copilot is powered by the OpenAI Codex, an artificial intelligence model created by OpenAI. The Generative Pre-trained Transformer 3 (GPT-3) language model, which uses deep learning to create text that resembles human speech, is improved and used in production as the OpenAI Codex.\nGithub copilot was trained on a selection of the English language, public GitHub repositories, including 59 gigabytes of Python code sourced from 54 million public GitHub repositories.\nThere still is a lot of controversy about whether GitHub should be allowed to do so, as most open source licences obviously don’t contain anything against analyzing your code with AI and selling it. Also, as AI is analyzing the code base it is not classified as derivative work which seems to be legal. However, it seems quite unethical by Microsoft as Copilot is a paid service that relies on analyzing other people’s code. Read more: https://www.theverge.com/2021/7/7/22561180/github-copilot-legal-copyright-fair-use-public-code\nIf copilot was free to use it would make a lot more sense as it utilizes FOSS(Free and open sourced software) in order to work. However with Microsoft’s decision to make copilot payed they are monetizing most off GitHub\u0026rsquo;s code base which is an illegal grey zone.\nAnalyzing a huge amount of code without any security features has led to many problems like GitHub leaking phone numbers (I even encountered it while testing copilot out).\nhttps://github.com/community/community/discussions/9584?sort=top?sort=top\nLast but not least by using GitHub copilot you agree to the ToS which clearly states\nGitHub Copilot gives you certain choices about how it uses the data it collects. User engagement data, including pseudonymous identifiers and general usage data, is required for the use of GitHub Copilot and will continue to be collected, processed, and shared with Microsoft and OpenAI as you use GitHub Copilot. You can choose whether your code snippets are collected and retained by GitHub and further processed and shared with Microsoft and OpenAI by adjusting your user settings. Conclusion I personally don’t use or will ever use GitHub Copilot or recommend it to anyone for the following reasons:\nDoesn\u0026rsquo;t help you learn. Instead does the opposite. Recommends other peoples’ phone numbers, emails and even aws keys. No features have been implemented to stop this as far as I know. Tracks your usage and collects a lot of data. Like Source code that you are editing, related files and other files open in the same IDE or editor, URLs of repositories and files paths. Is paid and proprietary. (You pay to be tracked) Monetizes Open Source Software in an unethical way. Github CoPilot generates vulnerable code 40% of the time PS if you don’t want GitHub to legally index your code, you could try one of these licenses They might work\n***If you enjoyed this article consider supporting me\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/githubmon/","summary":"\u003cp\u003eMicrosoft purchased GitHub in 2018, something many users are not aware of. After Microsoft’s acquisition of GitHub there have been many controversies like blocking private repositories and access to GitHub pages in certain countries and of course, GitHub Copilot.\u003c/p\u003e\n\u003ch1 id=\"what-is-github-copilot\"\u003eWhat is Github Copilot\u003c/h1\u003e\n\u003cp\u003eGitHub Copilot is an artificial intelligence tool developed by GitHub and OpenAI to assist users of Visual Studio Code, Visual Studio, Neovim, and JetBrains integrated development environments (IDEs) by autocompleting code. Currently available by subscription to individual developers, the tool was first announced by GitHub on 29 June 2021, and works best for users coding in Python, JavaScript, TypeScript, Ruby, and Go.\u003c/p\u003e","title":"How Microsoft is monetizing the GitHub code base"},{"content":"Thinking about setting up your own Git server? There are plenty of perks to doing so instead of relying on platforms like GitHub. For starters, you\u0026rsquo;ll have complete control over your code, ensuring it can’t be used for profit or deleted by anyone but you.\nWhat You’ll Need A Computer for Your Server: Ideally running Linux (Debian is a solid choice). Internet Connection: Pretty essential for accessing your server remotely. Another Computer with Git Installed: This is what you\u0026rsquo;ll use to interact with your server. Step-by-Step Setup Guide 1. Install Git on Your Server First, you need to install Git on your server. Depending on your Linux distribution, use one of these commands:\nFor Debian-based systems (like Ubuntu): sudo apt install git For Fedora-based systems: sudo dnf install git For Arch-based systems: sudo pacman -S git 2. Create a Git User Next, create a dedicated user for Git operations:\nsudo useradd git You\u0026rsquo;ll be prompted to enter some information. Feel free to leave everything blank except for the password.\n3. Secure Your Server with SSH Keys Log in as the new Git user:\nsu git Then, enhance security by setting up SSH keys:\nmkdir .ssh chmod 700 .ssh/ touch .ssh/authorized_keys chmod 600 .ssh/authorized_keys 4. Generate and Add SSH Keys On your main machine (the one you’ll be committing from), generate an SSH key:\nssh-keygen Copy the SSH public key to your server:\nssh-copy-id git@your-server-ip To find your server\u0026rsquo;s IP, use:\nifconfig Now, you should be able to log in to your server without needing a password:\nssh git@your-server-ip 5. Set Up Your Git Repository Directory Create a directory to store your Git repositories. For example:\nmkdir ~/git Give ownership of this directory to the Git user:\nchown git:git ~/git 6. Create a New Repository For each project, create a separate directory:\nmkdir ~/git/my_cool_project.git Initialize the repository as a bare repository (suitable for sharing):\ncd ~/git/my_cool_project.git git init --bare 7. Test Your Setup To test your new Git server, try cloning the repository from another machine:\ngit clone git@your-server-ip:~/git/my_cool_project.git You might see:\nwarning: You appear to have cloned an empty repository. That’s because you haven’t added any files yet. Go ahead and add a file:\ntouch stuff.txt Commit your changes:\ngit add . git commit -m \u0026#34;first commit\u0026#34; Now, try cloning again, and everything should work smoothly.\nCongratulations! You’ve successfully set up your own Git server! Now you have full control over your code and can collaborate without relying on third-party services.\nEnjoyed this guide? Consider supporting me to help me create more content like this!\nSubscribe Weekly Roundup Where I share what I’ve been up to that week, including articles I’ve published, cool finds, tips and tricks, and more! New Posts Receive an email every time I post something new on my blog No spam, no ads. Unsubscribe at any time. ","permalink":"https://4rkal.com/posts/git/","summary":"\u003cp\u003eThinking about setting up your own Git server? There are plenty of perks to doing so instead of relying on platforms like GitHub. For starters, you\u0026rsquo;ll have complete control over your code, ensuring it can’t be used for profit or deleted by anyone but you.\u003c/p\u003e\n\u003ch3 id=\"what-youll-need\"\u003eWhat You’ll Need\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eA Computer for Your Server\u003c/strong\u003e: Ideally running Linux (Debian is a solid choice).\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eInternet Connection\u003c/strong\u003e: Pretty essential for accessing your server remotely.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eAnother Computer with Git Installed\u003c/strong\u003e: This is what you\u0026rsquo;ll use to interact with your server.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"step-by-step-setup-guide\"\u003eStep-by-Step Setup Guide\u003c/h3\u003e\n\u003ch4 id=\"1-install-git-on-your-server\"\u003e1. Install Git on Your Server\u003c/h4\u003e\n\u003cp\u003eFirst, you need to install Git on your server. Depending on your Linux distribution, use one of these commands:\u003c/p\u003e","title":"How to Set Up Your Own Git Server: A Simple Guide"},{"content":"We rely on google more and more, but it’s interesting to know how much data Google is now handling. Alphabet aka Google describes its extensive data collection practices in its privacy policy. The company stores an astounding quantity of data. An estimated 15 exabytes of YOUR data are stored by Google. Google is tracking your every move.\nWhat is searX? Searx is a free and open-source metasearch engine, available under the GNU Affero General Public License version 3, with the aim of protecting the privacy of its users. In order to do this, Searx does not provide the search engines from which it receives results with users’ IP addresses or search histories. Tracking cookies served by the search engines are blocked, preventing user-profiling-based results modification.\nUsers can run private instances of Searx on their own computer, but there are also many public, user-run, Searx instances.\nIn this article i will show you how to run your own searX instance.\nWhat is a metasearch engine? A web search engine’s data is used by a metasearch engine, an online information retrieval tool, to create its own results. Metasearch engines automatically query search engines eg Google after receiving user input. The users are shown sufficient data that has been gathered, sorted, and presented.\nRequirements An computer (preferably running linux). Check out my article on how to install linux here https://4rkal.medium.com/install-a-debian-server-54add9133eec an internet connection Installing on windows To install on windows you will have to install wsl and follow the setup guide for linux bellow\nTo see how to install wsl head to https://docs.microsoft.com/en-us/windows/wsl/install\nInstalling on Linux (debian) First update your system sudo apt-get update \u0026amp;\u0026amp; sudo apt-get upgrade Now install required packages sudo apt install -y python3-dev python3-babel python3-venv uwsgi uwsgi-plugin-python3 git build-essential libxslt-dev zlib1g-dev libffi-dev libssl-dev Now you will have to create a new user called searx\nsudo -H useradd --shell /bin/bash --system \\ --home-dir \u0026#34;/usr/local/searx\u0026#34; \\ --comment \u0026#39;Privacy-respecting metasearch engine\u0026#39; searx sudo -H mkdir \u0026#34;/usr/local/searx\u0026#34; sudo -H chown -R \u0026#34;searx:searx\u0026#34; \u0026#34;/usr/local/searx\u0026#34; Now change user to searx\ngit clone \u0026quot;https://github.com/searx/searx.git\u0026quot; \u0026quot;/usr/local/searx/searx-src\u0026quot;t\nNow create a virtual environment\necho \u0026quot;. /usr/local/searx/searx-pyenv/bin/activate\u0026quot; \u0026gt;\u0026gt; \u0026quot;/usr/local/searx/.profile\u0026quot;\nTo install searx’s dependencies, exit the searx bash session you opened above and restart a new. Before install, first check if your virtualenv was sourced from the login (~/.profile):\nUpdate dependencies\npip install -U pip pip install -U setuptools pip install -U wheel pip install -U pyyaml Jump to searx’s working tree and install searx into virtualenv\ncd \u0026#34;/usr/local/searx/searx-src\u0026#34; pip install -e . Now go back to your default user\nexit\nAnd type sudo -H mkdir -p \u0026quot;/etc/searx\u0026quot;\nThen\nsudo -H cp \u0026#34;/usr/local/searx/searx-src/utils/templates/etc/searx/use_default_settings.yml\u0026#34; \\ \u0026#34;/etc/searx/settings.yml\u0026#34; Now you can edit your settings file\nsudo nano /etc/searx/settings.yml\nYou can change the secret_key\nI will change the port and bind_address but you can change whatever you want.\nNow log back in to your searx user\nsudo -H -u searx -i\nChange directory\ncd /usr/local/searx/searx-src\nExport the settings path\nexport SEARX_SETTINGS_PATH=\u0026#34;/etc/searx/settings.yml\u0026#34; Finally run the web app python searx/webapp.py Now if you head to 127.0.0.1:8888 you should be able to see something like this GG you did it enjoy privacy (in search engines)\n*If you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/searx/","summary":"\u003cp\u003eWe rely on google more and more, but it’s interesting to know how much data Google is now handling. Alphabet aka Google describes its extensive data collection practices in its privacy policy. The company stores an astounding quantity of data. An estimated 15 exabytes of YOUR data are stored by Google. Google is tracking your every move.\u003c/p\u003e\n\u003ch2 id=\"what-is-searx\"\u003eWhat is searX?\u003c/h2\u003e\n\u003cp\u003eSearx is a free and open-source metasearch engine, available under the GNU Affero General Public License version 3, with the aim of protecting the privacy of its users. In order to do this, Searx does not provide the search engines from which it receives results with users’ IP addresses or search histories. Tracking cookies served by the search engines are blocked, preventing user-profiling-based results modification.\u003c/p\u003e","title":"Host your own private search engine — searX"},{"content":"In this article we will talk about what tails is and how to install and more.\nWhat is tails? Tails, or The Amnesic Incognito Live System, is a security-focused Debian-based Linux distribution aimed at preserving privacy and anonymity.It connects to the Internet exclusively through the anonymity network Tor. The system is designed to be booted as a live DVD or live USB, and leaves no digital footprint on the machine unless explicitly told to do so.\nWhat is the tor network? Tor, short for The Onion Router, is free and open-source software for enabling anonymous communication. It directs Internet traffic through a free, worldwide, volunteer overlay network, consisting of more than six thousand relays,to conceal a user’s location and usage from anyone performing network surveillance or traffic analysis. Using Tor makes it more difficult to trace a user’s Internet activity.\nWho is tails intended for? As the tails website states (https://tails.net). Tails is intended for Activists who use Tails to hide their identities, avoid censorship, and communicate securely. Journalists and their sources use Tails to publish sensitive information and access the Internet from unsafe places. Domestic violence survivors use Tails to escape surveillance at home. You whenever you need extra privacy in this digital world.\nRequirements A computer (minimum of 2GB ram , 64-bit x86–64 compatible processor) A usb stick with 8GB+ of space Read more https://tails.boum.org/doc/about/requirements/index.en.html\nInstallation Back up all your files USB files as they will get deleted!\nThe first thing you will have to do is to head to https://tails.boum.org/install/index.en.html Now select your operating system\nIll walk you through the installation for windows and linux. This should probably bethe same with linux After you have clicked on the windows logo you should be prompted with the requirements and a step by step guide.\nThe first thing you will have to do is to download the tails usb image.\nAfter that i highly recommend that you verify your download\nJust click on select and select it.\nNow you will have to download balena etcher. Just click on download balena etcher and double click the installer.\nAt this moment plug in your usb (if you have any important files on the usb you have to back the up or they will be lost)\nNow click the flash from file button and select the file you downloaded (it ends in .img)\nClick the Select target button to select your USB stick.\nAnd now select flash.\nThis could take a while so just sit back and relax.\nUsing tails After your installation is finished just reboot your computer and hit F12 or F2 depending on your computer.\nNow you should see a screen thats says something like please select your boot device. You will have to select your usb and hit enter\nNow you should see the grub loader\nSelect Tails and hit enter\nNow you should be booted into tails\nYou will probably see a screen that looks something like this\nHere you will have to set your language and region. We can also press on the + icon to add a admin password mac address anonymization etc. I will just put the admin password and the unsafe browser. You can select anything you want. However remember that changing some of these settings will make you less anonymous.\nOnce you are ready select start tails\nNow you will see\nHere you can select anything you want. I will just select the first option.\nNow you should see this:\nGG you did it. One more step though\nI like to have a persistent volume so that i don’t lose all my files when i reboot. To do that open the configure persistent volume app and follow the steps there.\nThat’s it for now\n*If you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/tails/","summary":"\u003cp\u003eIn this article we will talk about what tails is and how to install and more.\u003c/p\u003e\n\u003ch1 id=\"what-is-tails\"\u003eWhat is tails?\u003c/h1\u003e\n\u003cp\u003eTails, or The Amnesic Incognito Live System, is a security-focused Debian-based Linux distribution aimed at preserving privacy and anonymity.It connects to the Internet exclusively through the anonymity network Tor. The system is designed to be booted as a live DVD or live USB, and leaves no digital footprint on the machine unless explicitly told to do so.\u003c/p\u003e","title":"Become anonymous and somewhat untraceable with tails os"},{"content":"Support My Work If you enjoy my articles, consider supporting me through any of the following methods:\nCrypto Donations Monero (XMR): 8AztDJtwb7iKaqP4KXRG39VibAacCY1mMfH4bNsVjhYMYbohtT5LKoTSRP6vJGtjeBSPEpFdHZx3ZL3iVowYdkqeQwPAG2 Altcoins: Donate 250+ altcoins via CypherGoat:\nClearnet Tor Other Methods LiberaPay: Buy Me a Coffee: ","permalink":"https://4rkal.com/donate/","summary":"\u003ch1 id=\"support-my-work\"\u003e\u003cstrong\u003eSupport My Work\u003c/strong\u003e\u003c/h1\u003e\n\u003cp\u003eIf you enjoy my articles, consider supporting me through any of the following methods:\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"crypto-donations\"\u003e\u003cstrong\u003eCrypto Donations\u003c/strong\u003e\u003c/h2\u003e\n\u003ch3 id=\"monero-xmr\"\u003e\u003cstrong\u003eMonero (XMR)\u003c/strong\u003e:\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003e8AztDJtwb7iKaqP4KXRG39VibAacCY1mMfH4bNsVjhYMYbohtT5LKoTSRP6vJGtjeBSPEpFdHZx3ZL3iVowYdkqeQwPAG2 \u003c/code\u003e\u003c/p\u003e\n\u003ch3 id=\"altcoins\"\u003e\u003cstrong\u003eAltcoins:\u003c/strong\u003e\u003c/h3\u003e\n\u003cp\u003eDonate 250+ altcoins via CypherGoat:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://cyphergoat.com/pay?amount=1\u0026amp;coin1=xmr\u0026amp;network1=xmr\u0026amp;address=82V3G48DKzy7u2kg89J3SgSmy36S9vdUcTHrQuN3YRkcEGYSW5VWYPTK4KrSDBdvLH5Ctyt9uG8GwKaYe5tcNm7uTG7c4A7\"\u003eClearnet\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"http://cyphergmw4huw7jzhat3misfm5jj2m4nvafockqbj7i5rrlec6mobdid.onion/pay?amount=1\u0026amp;coin1=xmr\u0026amp;network1=xmr\u0026amp;address=82V3G48DKzy7u2kg89J3SgSmy36S9vdUcTHrQuN3YRkcEGYSW5VWYPTK4KrSDBdvLH5Ctyt9uG8GwKaYe5tcNm7uTG7c4A7\"\u003eTor\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"other-methods\"\u003e\u003cstrong\u003eOther Methods\u003c/strong\u003e\u003c/h2\u003e\n\u003ch3 id=\"liberapay\"\u003e\u003cstrong\u003eLiberaPay:\u003c/strong\u003e\u003c/h3\u003e\n\u003cscript src=\"https://liberapay.com/4rkal/widgets/button.js\"\u003e\u003c/script\u003e \u003cnoscript\u003e\u003ca href=\"https://liberapay.com/4rkal/donate\"\u003e\u003cimg alt=\"Donate using Liberapay\" src=\"https://liberapay.com/assets/widgets/donate.svg\"\u003e\u003c/a\u003e\u003c/noscript\u003e\n\u003ch3 id=\"buy-me-a-coffee\"\u003e\u003cstrong\u003eBuy Me a Coffee:\u003c/strong\u003e\u003c/h3\u003e\n\u003cscript type=\"text/javascript\" src=\"https://cdnjs.buymeacoffee.com/1.0.0/button.prod.min.js\" data-name=\"bmc-button\" data-slug=\"support4rkal\" data-color=\"#BD5FFF\" data-emoji=\"\" data-font=\"Cookie\" data-text=\"Buy me a coffee\" data-outline-color=\"#000000\" data-font-color=\"#ffffff\" data-coffee-color=\"#FFDD00\"\u003e\u003c/script\u003e","title":"Donate"},{"content":"In this article, I will show you how to set up Pi-hole. Pi-hole will allow you to block in-app ads, improve your network\u0026rsquo;s performance, and monitor statistics. Pi-hole also allows you to create a VPN.\nWhat is Pi-hole? Pi-hole is a Linux network-level advertisement and Internet tracker blocking application that acts as a DNS sinkhole and optionally a DHCP server, intended for use on a private network. It is designed for low-power embedded devices with network capability, such as the Raspberry Pi, but can be installed on any Linux machine. Pi-hole has the ability to block traditional website advertisements as well as advertisements in unconventional places, such as smart TVs and mobile operating system advertisements.\nRequirements A computer with Linux (preferably something Debian-based) Preferably an Ethernet cable Access to your router\u0026rsquo;s admin portal A static IP An internet connection (it\u0026rsquo;s pretty difficult without one, trust me) Installation The first thing we have to do is download the installer.\nTo do that, type:\nwget -O basic-install.sh https://install.pi-hole.net Now, install it with:\nsudo bash basic-install.sh Now you should see something like this:\nJust press OK.\nJust press OK again.\nAs I said before, you have to have a static IP in order to set up the Pi-hole, so if you have one configured, just press Yes.\nOtherwise, you will have to set one up.\nNow you will be prompted to select your upstream DNS provider. You can select any of the DNS providers on the list. I will just select Google.\nAnd press OK.\nAfter that, you will have to select your list. I will just select the default one.\nNow you will have to select whether you want a web admin interface. Select On and then OK.\nNow just select On and press OK.\nAfter that, you can select if you want to log queries. You can select any option you want.\nNow, I recommend that you leave this as default, but you don’t have to.\nNow it should start installing everything.\nAfter the installation is finished, you should see something like this:\nYou have now successfully installed Pi-hole. You can head to the admin portal by going to the specified IP.\nTo be able to use Pi-hole, you have two options:\nMake the IP the default DNS for your whole network Manually add it on any device I\u0026rsquo;ll go with the second option.\nOn Windows: DNS settings are specified in the TCP/IP Properties window for the selected network connection.\nGo to the Control Panel Click Network and Internet \u0026gt; Network and Sharing Center \u0026gt; Change adapter settings Select the connection for which you want to configure Right-click Local Area Connection \u0026gt; Properties Select the Networking tab Select Internet Protocol Version 4 (TCP/IPv4) or Internet Protocol Version 6 (TCP/IPv6) Click Properties Click Advanced Select the DNS tab Click OK Select Use the following DNS server addresses Replace those addresses with the IP addresses of your Pi Restart the connection you selected in step 3 Repeat the procedure for additional network connections you want to change On Linux: In most modern Linux distributions, DNS settings are configured through Network Manager.\nClick System \u0026gt; Preferences \u0026gt; Network Connections Select the connection for which you want to configure and press Edit Select the IPv4 Settings or IPv6 Settings tab If the selected method is Automatic (DHCP), open the dropdown and select Automatic (DHCP) addresses only instead. If the method is set to something else, do not change it. In the DNS servers field, enter your Pi’s IP addresses Click Apply to save the changes Warning: If you are not using Network Manager, your DNS settings are specified in /etc/resolv.conf.\nNow, if we head over to any websites with ads, you should see that no ads appear.\nLet\u0026rsquo;s try speedtest.net.\nIf you have followed the steps correctly, you should see something like this:\nNO ADS\nEnjoy the ad-free web.\nIf you enjoyed this article, consider supporting me.\n","permalink":"https://4rkal.com/posts/pihole/","summary":"\u003cp\u003eIn this article, I will show you how to set up Pi-hole. Pi-hole will allow you to block in-app ads, improve your network\u0026rsquo;s performance, and monitor statistics. Pi-hole also allows you to create a VPN.\u003c/p\u003e\n\u003ch1 id=\"what-is-pi-hole\"\u003eWhat is Pi-hole?\u003c/h1\u003e\n\u003cp\u003ePi-hole is a Linux network-level advertisement and Internet tracker blocking application that acts as a DNS sinkhole and optionally a DHCP server, intended for use on a private network. It is designed for low-power embedded devices with network capability, such as the Raspberry Pi, but can be installed on any Linux machine. Pi-hole has the ability to block traditional website advertisements as well as advertisements in unconventional places, such as smart TVs and mobile operating system advertisements.\u003c/p\u003e","title":"Get ad free web with Pi-hole"},{"content":"SSH keys provide an extremely secure way of logging into your server.\nSSH Password Based VS Key Based Authentication Clients can be authenticated by an SSH server in a variety of ways. The most basic is password authentication, which is simple to use but not particularly secure. The more advanced and secure way is via ssh keys.Brute-forcing a password-protected account is quite possible thanks to modern computing power and automated scripts. The solution to that is ssh key based authentication.\nHow does Key Based Authentication work? SSH key pairs are two cryptographically secure keys that allow a client to connect to an SSH server. A public key and a private key make up each key pair.The client keeps the private key, which should be kept completely confidential.\nIf the attacker has access to the private key, they will be able to enter into servers using the corresponding public key without requiring further authentication. A passphrase can be used to encrypt the key on disc as an extra precaution.\nThe related public key can be freely shared without causing any harm. The public key can be used to encrypt communications that can only be decrypted with the private key. This attribute is used to verify the authenticity of the key pair. The public key is placed on a distant server that you wish to use SSH to access. The key is saved in a special file called /.ssh/authorized keys in the user account you’ll be login into.\nWhen a client uses SSH keys to authenticate, the server can check if the client has the private key. A shell session is started or the requested command is executed if the client can verify ownership of the private key.\nSetting up The first thing we will have to to do is generate an SSH key pair on your local computer.\nTo do that type\nssh-keygen\nYou should see something like this\nGenerating public/private rsa key pair. Enter file in which to save the key (/home/4rkal/.ssh/id_rsa): Enter passphrase (empty for no passphrase): If you want to you can enter a passphrase to encrypt the private key.\nAfter that your key should be generated.\nNow you will have to copy your public key to your server.\nTo do that type\nssh-copy-id username@host_ip\n(find your servers ip by typing ifconfig in your server)\neg.\n`ssh-copy-id server@192.168.1.13'\nTry to ssh into your server by typing\nssh username@host_ip\nYou should be able to login into your server without the password. However, brute force attacks continue to threaten your server. Now we have to disable password based authentication.\nFirst login to your ssh server by typing ssh username@host_ip\nNow we have edit the ssh config\nsudo nano /etc/ssh/sshd_config\nYou should see a large file that starts with\n# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ At this point press cntrl w and search for PasswordAuthentication\nUncomment the line that says\n#PasswordAuthentication yes\nAnd change it to\nPasswordAuthentication no\nNow press cntrl s to save and cntrl x to exit\nAfter that restart the ssh service with\nsudo service ssh restart\nNow try to ssh into your server from another machine or a vm and you should see something like this\nserver@192.168.1.13: Permission denied (publickey)\nGG you have now secured your server\n*If you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/sssh/","summary":"\u003cp\u003eSSH keys provide an extremely secure way of logging into your server.\u003c/p\u003e\n\u003ch1 id=\"ssh-password-based-vs-key-based-authentication\"\u003eSSH Password Based VS Key Based Authentication\u003c/h1\u003e\n\u003cp\u003eClients can be authenticated by an SSH server in a variety of ways. The most basic is password authentication, which is simple to use but not particularly secure. The more advanced and secure way is via ssh keys.Brute-forcing a password-protected account is quite possible thanks to modern computing power and automated scripts. The solution to that is ssh key based authentication.\u003c/p\u003e","title":"Securing ssh with Key-Based authentication"},{"content":"In this article i will be showing you how to host your “dark web” aka Tor website for free.\nWhat is Tor? Tor — short for the Onion Routing project — is an open-source privacy network that enables anonymous web browsing. The worldwide Tor computer network uses secure, encrypted protocols to ensure that users’ online privacy is protected. Tor users’ digital data and communications are shielded using a layered approach that resembles the nested layers of an onion.\nWhy use Tor? Tor is useful for anyone who wants to keep their internet activities out of the hands of advertisers, ISPs, and websites. That includes people getting around censorship restrictions in their country, people looking to hide their IP address, or anyone else who doesn’t want their browsing habits linked to them.\nThe Tor network may also host webpages that only other Tor users can view. In other words, you’ve entered the Dark Web, which consists of websites that aren’t indexed by the standard crawlers you use to look for products to purchase, and quiz answers etc . On the Dark Web, you can discover everything from free textbooks to drugs — and worse — as long as you know the secret URL that leads to these sites.\nTor Websites Just like any other website, you will need to know the address of an onion service in order to connect to it. An onion address is a string of 56 mostly random letters and numbers, followed by “.onion”.\nRequirements A linux machine (debian preferably) An internet connection (pretty hard without one,trust me) Installation The first thing we will have to do is install Tor\napt install tor\nNow we will have to enable tor hidden service(which is the website) for that type:\nsudo nano /etc/tor/torrc\nYou should see a large configuration file, search for HiddenService\nYou will have to uncoment:\n#HiddenServiceDir /var/lib/tor/hidden_service/ #HiddenServicePort 80 127.0.0.1:80 Now press cntrl s and then cntrl x to exit\nAfter that start the tor service by running\nsudo service tor start\nor\nsudo systemctl start tor\nNow we also have to install nginx to be able to run our website to do that type\nsudo apt install nginx\nStart the nginx service with the systemctl or service command\nNow we also have to install nginx to be able to run our website to do that type\nsudo cat /var/lib/tor/hidden_service/hostname\nYou should see a address that looks something like this\ntiur7p652svsaemdewbsxnnkrj3b35ny2rx454od5wk5ivfqhijm2qd.onion\nNow open your tor browser and paste your address and press enter.\nYou will most probably be greeted by the default nginx site.\nThis page is easily customized, you can check out my article: here\nGG you did it you are now running a pretty anonymous website on the tor network.\n*If you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/torhs/","summary":"\u003cp\u003eIn this article i will be showing you how to host your “dark web” aka Tor website for free.\u003c/p\u003e\n\u003ch1 id=\"what-is-tor\"\u003eWhat is Tor?\u003c/h1\u003e\n\u003cp\u003eTor — short for the Onion Routing project — is an open-source privacy network that enables anonymous web browsing. The worldwide Tor computer network uses secure, encrypted protocols to ensure that users’ online privacy is protected. Tor users’ digital data and communications are shielded using a layered approach that resembles the nested layers of an onion.\u003c/p\u003e","title":"Setup a tor website (hidden service)"},{"content":"As the linuxfoundation states about 95% of cloud providers run kubernetes which is an open sourced solution, the Apache Web server powers millions of websites including netflix.com, spotify.com and more. Most of the Internets core functions are based on open source technology. But what is it and why is it so important?\nWhat is open sourced software? Open-source software is computer software that is distributed under a license that allows users to use, study, modify and distribute the program and its source code to anyone and for any purpose. Open-source software may be created in a public, collaborative environment. Open-source software is a good example of open collaboration since it allows any skilled user to engage in development online.\n\u0026ldquo;Certainly there’s a phenomenon around open source. You know free software will be a vibrant area. There will be a lot of neat things that get done there.\u0026rdquo; -Bill Gates\nWhy open source? There are several advantages to using open-source software.\nTrust. One of the most important advantages is trust. As users can examine your code and make sure its not doing anything they don’t want it to. They are also able to change things they don’t like. Most cryptocurrency projects are open sourced to be able to develop trust with their community.\nCommunity A open source community allows more developers to build around the project . Bitcoin is the greatest example of such a community. As soon as bitcoin source code was published many utilities for bitcoin were made like wallets and more which would never have been made if bitcoin wasn’t open sourced.\nTransparency Anyone can read your source code and see if they want it to do what it is doing. That way your company gains a lot of trust.\n\u0026ldquo;Talk is cheap show me the code\u0026rdquo; Linus Torvalds\nContinuous evolution Your project will continue to be developed even if you give up on it. Again the greatest example for this kind of project is bitcoin. Even though the founder of bitcoin has vanished for more than 10 years, cryptocurrency technology is \u0026ldquo;changing\u0026rdquo; the world.\nLower Development costs (For companies) You can reduce your costs by using open source software. You can save money on licensing and maintenance. The only costs you’d have to deal with are those for documentation, media, support etc.\nControll With open source YOU are ultimately in controll. If you dont like something you can modify the source code to your liking.\nIf you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/opensource/","summary":"\u003cp\u003eAs the linuxfoundation states about 95% of cloud providers run kubernetes which is an open sourced solution, the Apache Web server powers millions of websites including netflix.com, spotify.com and more. Most of the Internets core functions are based on open source technology. But what is it and why is it so important?\u003c/p\u003e\n\u003ch2 id=\"what-is-open-sourced-software\"\u003eWhat is open sourced software?\u003c/h2\u003e\n\u003cp\u003eOpen-source software is computer software that is distributed under a license that allows users to use, study, modify and distribute the program and its source code to anyone and for any purpose. Open-source software may be created in a public, collaborative environment. Open-source software is a good example of open collaboration since it allows any skilled user to engage in development online.\u003c/p\u003e","title":"The importance of open source software"},{"content":"In this article i will show you how to self host your own website securely.\nRequirements A computer or microcomputer to host the website The computer needs to run linux An internet connection (Its pretty hard without one, trust me) Lets get started!\nInstallation The first thing that we will have to do is setup our nginx site.\nWe first have to be root\nsudo su\nIf you dont have sudo installed try:\nsu -\nNow we will have to install nginx\napt install nginx\nIf you are using any other package manager install it using the package name nginx\nNow we will have to start the nginx service\nsystemctl start nginx\nor\nservice nginx start\nLets find your ip with:\nip a\nor\nifconfig\nIf you open a web browser and go to your ip you should see the default welcome to nginx site.\nSince we want to make our website as secure as possible we can hide the nginx version\nTo do that type\n`sudo nano /etc/nginx/nginx.conf\nNow you should see the nginx configuration file.\nunder\nhttp { ## # Basic Settings ## sendfile on; tcp_nopush on; types_hash_max_size 2048; # server_tokens off; uncomment server_tokens off;\nNow restart your nginx service\nsystemctl restart nginx\nWe can now enter our html files inside of /var/www/html\nTo do that type:\ncd /usr/share/nginx/html\nand now we can create the index.html file\nnano index.html\nand paste/write your html code to index.html\nNow restart the nginx service again\nsystemctl restart nginx\nCertbot Now we will install cerbot in order to get https\nTo install certbot simply type\napt install certbot python-certbot-nginx\nNow we will have to run certbot\ncertbot --nginx\nEnter all the inf oand agree to the terms\nAfter that you will have to enter the name you would like to activate https for\nJust select the names\nAfter that select to redirect http to https\nPort forwarding There are a few ways to port forward. In this article we will use noip.com.\nHead over to noip.com to get started (Use my referal https://www.noip.com/?fpr=4rkal)\nCreate an account and register a hostname\nAfter that we will have to build the noip client on our computer for that paste these commands to your terminal\ncd /usr/local/src wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz tar xzf noip-duc-linux.tar.gz cd noip-2.1.9–1 make make install When you run make install you will be prompted to answer some questions like your login information and the update interval\nIn the update interval just set it to 30\nThen if you don’t want to run something at a successful update type n if you do then type y.\nYou will now also have to edit the nginx default settings\nto do that type\n`sudo nano /etc/nginx/sites-available/default\nNow you will have to change the server_name to the domain you registered at noip.com\nYou can check if your configuration was successful by running\nnginx -t\nYou can now restart the nginx service\nsystemctl restart nginx\nNow if you head to your domain it should be working and ssl should be installed\n*If you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/shwebsite/","summary":"\u003cp\u003eIn this article i will show you how to self host your own website securely.\u003c/p\u003e\n\u003ch1 id=\"requirements\"\u003eRequirements\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003eA computer or microcomputer to host the website\u003c/li\u003e\n\u003cli\u003eThe computer needs to run linux\u003c/li\u003e\n\u003cli\u003eAn internet connection (Its pretty hard without one, trust me)\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eLets get started!\u003c/p\u003e\n\u003ch1 id=\"installation\"\u003eInstallation\u003c/h1\u003e\n\u003cp\u003eThe first thing that we will have to do is setup our nginx site.\u003c/p\u003e\n\u003cp\u003eWe first have to be root\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003esudo su\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003eIf you dont have sudo installed try:\u003c/p\u003e","title":"Self host your own website"},{"content":"In this article i will show you how to setup a raspberry pi security camera using motion. In the end of this article you will have a fully functioning security camera with a live feed and motion detection.\nRequirements Raspberry pi or any other computer Web cam Any kind of debian based distro installed on the pi/computer Setup In this article we will be using the motion package (https://motion-project.github.io/)\nTo get started power on your raspberry pi and ssh into the machine or just connect it to a monitor and a keyboard. Also connect your web cam to the raspberry pi usb port.\nThe first thing we will have to do is install motion, for that type the following command:\napt install motion\nNow start motion with:\nsystemctl start motion\nor\nservice motion start\nNow we are going to change some of the default settings . To do that type:\nnano /etc/motion/motion.conf\nThe first thing that we are going to change is\nwebcontrol_localhost off\nThis will enable us to access the stream from other computers.\nTo view the stream run:\nmotion\nIf you get a permission denied error try running\nsudo motion\nIf you got to http://YOUR_IP:8080 you should see a live feed of the web cam\nYou can change the port under webcontrol_port in the config file eg. webcontrol_port 1234\nIf you only want the live stream port you can go to http://your_ip:8081\nAgain you can change that under stream_port.\nNow everything should be working fine. All motion detection files will be saved in /var/lib/motion\nYou can also change loads of other settings. Here are my settings:https://pastebin.com/WGn0NfcW\nRead the documentation here: https://motion-project.github.io/motion_guide.html\n*If you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/rpicamera/","summary":"\u003cp\u003eIn this article i will show you how to setup a raspberry pi security camera using motion. In the end of this article you will have a fully functioning security camera with a live feed and motion detection.\u003c/p\u003e\n\u003ch1 id=\"requirements\"\u003eRequirements\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003eRaspberry pi or any other computer\u003c/li\u003e\n\u003cli\u003eWeb cam\u003c/li\u003e\n\u003cli\u003eAny kind of debian based distro installed on the pi/computer\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"setup\"\u003eSetup\u003c/h1\u003e\n\u003cp\u003eIn this article we will be using the motion package (\u003ca href=\"https://motion-project.github.io/\"\u003ehttps://motion-project.github.io/\u003c/a\u003e)\u003c/p\u003e\n\u003cp\u003eTo get started power on your raspberry pi and ssh into the machine or just connect it to a monitor and a keyboard. Also connect your web cam to the raspberry pi usb port.\u003c/p\u003e","title":"Raspberry pi security camera"},{"content":"If you work in the IT industry, you’ve undoubtedly heard of ssh. But how does it work?\nSSH (secure shell) is a network protocol that allows two computers to connect securely over the internet. SSH uses encryption to prevent hackers from reading data sent between two connected devices.\nSSH is divided into three layers:\nThe transport layer The connection layer The authentication layer During and after authentication, the transport layer establishes safe and secure communication between a client and a server. It is in charge of data encryption, decryption, and integrity assurance. It also provides data compression and caching, which helps to speed up data communication.\nThe authentication layer informs the client about the available authentication methods. It’s also in charge of the whole user authentication procedure.\nAfter the authentication is successful, the connection layer oversees the communication between the machines. It manages communication channel opening and closure, as well as multiple channels for multiple sessions.\nSession Encryption The server sends the client a list of supported encryption protocols after receiving a connection request. The public key is used by the server as an authentication technique.\nThe client compares the protocols to the ones it already knows. If there are two protocols that are compatible, the machines agree to use one of them to establish the connection.\nOn the first connection attempt, the client compares the server’s public key to the private key saved in its system. If the keys are identical, the client and server agree to communicate using symmetric encryption during the SSH session. They communicate utilizing an asymmetrically encrypted mechanism based on the Diffie-Hellman (DH) key exchange algorithm for this purpose. There are different ciphers that can be used for SSH depending on the applications being used. Some of them include:\nCHACHA20 AES-GCM Blowfish-CBC AES128-CTR AES192-CTR AES256-CTR Arcfour Cast128-CBC Different Encryption Techniques SSH uses a variety of data manipulation techniques at various points in the transaction to ensure the security of information transmission. These include symmetrical and asymmetrical encryption, as well as hashing.\nSymmetrical Encryption Symmetric encryption creates a single key that is exchanged between two machines. The key is then used by the machines for both encryption and decryption. This approach is rapid and resource-light, and it is used by SSH for each session. When the client and server are deciding which algorithm to employ for an SSH session, the first algorithm on the client’s list that the server supports is always used.\nAsymmetrical Encryption Any party can have access to the public key. Although it is linked to its paired key, the private key cannot be deduced from the public key. The public key and private key have a mathematical relationship that allows the public key to encrypt messages that can only be decrypted by the private key. This is a one-way ability, which means that the public key cannot decode the communications it sends or decrypt anything the private key sends it.\nThe private key should be kept completely confidential and never shared with anybody else. This is a necessary condition for the public key paradigm to function.The only component that can decrypt communications encrypted with the accompanying public key is the private key. Any entity capable of decrypting these messages has demonstrated control over the private key as a result of this fact.\nHashing r key defining characteristics are that they are never supposed to be reversed, that they are nearly hard to predictably alter, and that they are practically unique.\nIf you use the same hashing function and message, you should get the same hash; if you change any part of the data, you should get a completely different hash. A user should not be able to deduce the actual message from a hash, but they should be able to determine whether a message produced a hash.\nSession Encryption Negotiation The server sends the client a list of supported encryption protocols after receiving a connection request. The public key is used by the server as an authentication technique.\nThe client evaluates the protocols in comparison to its own. The machines choose one to create the connection using if there are any compatible protocols.\nOn the initial connection attempt, the client checks the server\u0026rsquo;s public key to the saved copy of its own private key. The client and server consent to using symmetric encryption to communicate during an SSH session if the keys match. They converse utilizing an asymmetric encryption method that makes use of the Diffie-Hellman (DH) key exchange algorithm.\nUsing a public network, machines can safely collaborate to build a cryptographic key thanks to the DH algorithm. The machines go through the following processes to create a key:\nThe machines agree on two numbers: a modulus and a base number. To prevent brute force key decryption, the chosen modulus is a prime number of at least 600 digits. In order to solve the equation involving the two public numbers, the machines independently select one number. The calculated values are exchanged between the server and the client. Now, utilizing the information obtained from the other machine, each machine computes something. By carrying out the above processes, both machines determine the identical value, which is their secret key. The server then makes an attempt to verify the user\u0026rsquo;s identity who made the access request.\n***If you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/howsshworks/","summary":"\u003cp\u003eIf you work in the IT industry, you’ve undoubtedly heard of ssh. But how does it work?\u003cbr\u003e\nSSH (secure shell) is a network protocol that allows two computers to connect securely over the internet. SSH uses encryption to prevent hackers from reading data sent between two connected devices.\u003cbr\u003e\nSSH is divided into three layers:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eThe transport layer\u003c/li\u003e\n\u003cli\u003eThe connection layer\u003c/li\u003e\n\u003cli\u003eThe authentication layer\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eDuring and after authentication, the transport layer establishes safe and secure communication between a client and a server. It is in charge of data encryption, decryption, and integrity assurance. It also provides data compression and caching, which helps to speed up data communication.\u003c/p\u003e","title":"How SSH works"},{"content":"Selenium is a very good skill to have as you can automate almost everything that you can do with a web browser.\nIn this tutorial, we’ll learn how to use Python and Selenium to automate a web browser. This is an updated version of my previous article which unfortunately doesn\u0026rsquo;t work anymore. If you’re a complete beginner, read my python article to understand the basics. (https://4rkal.com/posts/python/)\nWhat is selenium? Selenium is an open source umbrella project for a range of tools and libraries aimed at supporting browser automation. You can use selenium in multiple programming languages including JavaScript (Node.js), C#, Groovy, Java, Perl, PHP, Python, Ruby and Scala and with multiple web browsers including firefox, internet explorer, safary, opera, chrome and edge. Selenium can be very useful for web scraping, automating boring and manual tasks and so much more.\nSetup To install selenium you first have to install a browser driver. Here is the list of supported web browsers :\nFirefox Internet Explorer? Safari Opera Chrome Edge In this article we will be using firefox geckodriver. But you can use any of the browser drivers above. Downloading geckodriver To get started go to github.com/mozilla/geckodriver/releases Scroll down and select the package for your computer. I’ll use geckodriver-v0.31.0-linux64.tar.gz because I’m using a linux 64-bit computer.\nInstalling geckodriver The setup varies depending on your operating system.\nIf you are using Arch Linux: You can install geckodriver from the aur. Using your favourite aur helper\nOn linux:\nUnzip the file Make the file executable chmod +x geckodriver Add the driver to your PATH so other tools can find it: export PATH=$PATH:/path-to-extracted-file/ On windows: Unzip the file Paste the file in the directory that your script will run Installing selenium To install selenium you have to have python and pip installed.Check out my article on python for more To install selenium open your cmd or terminal and type:\npip install selenium That should install it.\\\nBasics of selenium The first thing we have to do is to create a new file with the .py ending eg. main.py\nAfter you have created it open it in your ide or editor of choice.\\\nThe first thing that we have to do is to import the selenium webdriver : from selenium import webdriver\nAfter that we have to specify what webdriver we are using. In our case its firefox browser = webdriver.Firefox()\nNow we need to specify the url that we want it to go to eg python.org\nbrowser.get(\u0026#39;https://python.org\u0026#39;) The full code so far is:\\ import selenium from selenium import webdriver browser = webdriver.Firefox() browser.get(\u0026#39;https://python.org\u0026#39;) Now we might want it to click on the Downloads button\nThere are a few ways to do this\nMethod 1 of clicking a button The first is with XPATH\nTo find the xpath of a button / object on a website you have to open your web browser go to the desired website and hit F12 to get the development tools. Now you should click on the select tool (See below) Click on it and after that hover above the downloads button with your mouse and click it. After that you should see a bit of code getting highlighted. Right click on the bit of code and select Copy then select Xpath Now go back to the python file and type:\ndriver.find_element(By.XPATH, 'XPATH_HERE')\nThis will throw an error, to fix that error simply add this at the top of the file\nfrom selenium.webdriver.common.by import By\nYour code so far should look like this\nimport selenium from selenium import webdriver from selenium.webdriver.common.by import By browser = webdriver.Firefox() browser.get(\u0026#39;https://python.org\u0026#39;) browser.find_element(By.XPATH, \u0026#39;/html/body/div/header/div/nav/ul/li[2]/a\u0026#39;).click() Method 2 XPATH with text The second method is a bit simpler but not as reliable as the first as there might be many objects with the same name.\nTo use this method type: browser.find_element(By.XPATH, \u0026quot;//*[contains(text(), 'Downloads')]\u0026quot;).click() Your code should look something like this\nimport selenium from selenium import webdriver from selenium.webdriver.common.by import By browser = webdriver.Firefox() browser.get(\u0026#39;https://python.org\u0026#39;) browser.find_element(By.XPATH, \u0026#34;//*[contains(text(), \u0026#39;Downloads\u0026#39;)]\u0026#34;).click() . . . . .\nThere many methods on how to locate elements but the above i believe are the easiest. The methods are the following\nBy.ID By.NAME By.XPATH By.LINK-TEXT By.TAG_NAME By.CLASS_NAME By.CSS_SELECTOR\\ Read more here: https://selenium-python.readthedocs.io/locating-elements.html\nTyping text into input fields. Typing text into input fields is pretty straight forward.\nFor that we will use any of the above methods. I\u0026rsquo;m going to use xpath.\nFind the xpath of any input field, I\u0026rsquo;m going to use the google.com search field\nCopy the xpath and type:\na = browser.find_element(By.XPATH, \u0026quot;XPATH_HERE\u0026quot;) Paste the xpath in XPATH_HERE\nTo send keys we need to import the selenium.webdriver.common.keys library for that paste this line of code at the top of your file\nfrom selenium.webdriver.common.keys import Keys\nNow type:\na.send_keys(\u0026quot;python\u0026quot;)\nAfter that we want to press the enter key for that type:\na.send_keys(Keys.RETURN)\nThe full code should look something like this:\nimport selenium from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys browser = webdriver.Firefox() browser.get(\u0026#39;https://google.com\u0026#39;) a = browser.find_element(By.XPATH, \u0026#34;/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input\u0026#34;) a.send_keys(\u0026#34;python\u0026#34;) a.send_keys(Keys.RETURN) GG you just automated your first google search! You might first need to accept cookies for that just follow the steps on how to click a button from above.\nRead more about selenium here: https://selenium-python.readthedocs.io/\\\n*If you enjoyed this article consider supporting me\n","permalink":"https://4rkal.com/posts/selenium/","summary":"\u003cp\u003e\u003cstrong\u003eSelenium is a very good skill to have as you can automate almost everything that you can do with a web browser.\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eIn this tutorial, we’ll learn how to use Python and Selenium to automate a web browser. This is an updated version of my previous article which unfortunately doesn\u0026rsquo;t work anymore. If you’re a complete beginner, read my python article to understand the basics. (\u003ca href=\"https://4rkal.com/posts/python/\"\u003ehttps://4rkal.com/posts/python/\u003c/a\u003e)\u003c/p\u003e\n\u003ch2 id=\"what-is-selenium\"\u003eWhat is selenium?\u003c/h2\u003e\n\u003cp\u003eSelenium is an open source umbrella project for a range of tools and libraries aimed at supporting browser automation. You can use selenium in multiple programming languages including JavaScript (Node.js), C#, Groovy, Java, Perl, PHP, Python, Ruby and Scala and with multiple web browsers including firefox, internet explorer, safary, opera, chrome and edge. Selenium can be very useful for web scraping, automating boring and manual tasks and so much more.\u003c/p\u003e","title":"Automating your web browser with selenium"},{"content":"Most people know that adding up 0.1 + 0.2 equals 0.3. However computers represent it as 0.30000000000000004 .\nHere is a screenshot of it in python3 Your first thought might be that this is just some kind of error. Well its not\nWhy does this happen? Fractions can be represented precisely in the base 10 system (used by humans) if a prime factor of the base is used (10).\n2 and 5 are the prime factors of 10. 1/2, 1/4, 1/5 (0.2), 1/8, and 1/10 (0.1) can be expressed precisely as a result of denominators use prime factors of 10. Whereas, 1/3, 1/6, and 1/7 are repeating decimals as a result of denominators use a prime factor of 3 or 7. On the other hand, fractions can be represented precisely in the base 2 (binary) system (used by computers) if a prime factor of the base is used. 2 is the only prime factor of 2. So 1/2, 1/4, 1/8 can all be expressed precisely because the denominators use prime factors of 2. Whereas 1/5 (0.2) or 1/10 (0.1) are repeating decimals. When you perform math on these repeating decimals, you end up with leftovers which carry over when you convert the computer’s base-2 (binary) number into a more human-readable base-10 representation. Read more: 0.300.com Wikipedia:\nhttps://en.wikipedia.org/wiki/Floating-point_arithmetic\nIf you enjoyed this article consider donating\n","permalink":"https://4rkal.com/posts/zeropointthree/","summary":"\u003cp\u003e\u003cstrong\u003eMost people know that adding up 0.1 + 0.2 equals 0.3. However computers represent it as 0.30000000000000004 .\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eHere is a screenshot of it in python3\n\u003cimg loading=\"lazy\" src=\"/../assets/zeropointthree.png\" type=\"\" alt=\"0.1\u0026#43;0.2 in python\"  /\u003e\u003c/p\u003e\n\u003cp\u003eYour first thought might be that this is just some kind of error. Well its not\u003c/p\u003e\n\u003ch1 id=\"why-does-this-happen\"\u003eWhy does this happen?\u003c/h1\u003e\n\u003cp\u003eFractions can be represented precisely in the base 10 system (used by humans) if a prime factor of the base is used (10).\u003c/p\u003e","title":"Why computers can’t represent 0.3 accurately"}]