Home Blog

WooCommerce Stripe – Always remember Credit card


I am using the WooCommerce Stripe plugin.

When a user checks out, they are presented with the option to save their payment method.Stripe Because I sell subscriptions, I need to always save the payment information, so I don’t want to give the customer the choice.

To accomplish that, I created a custom plugin, which will ensure the change survives rounds of updates.

This plugin uses CSS to hide the checkbox while setting the value “checked” in the backend.

To use this plugin, create a directory name wp-content/plugins/always-save-credit-card, and inside it, a file always-save-credit-card.php

Like this:

├─ wp-admin/
├─ wp-content/
│   ├─ plugins/
│   │   ├─ always-save-credit-card/
│   │   │   ├─ always-save-credit-card.php

Then, inside the file php file, put this content.

 * Plugin Name: Custom Stripe Remember Me
 * Description: A custom plugin to force saving the payment information when a user checks out using the Stripe WooCommerce integration.
 * Version: 1.0.0
 * Author: koff
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt

function custom_wc_stripe_force_save_source($force_save_source, $source) {
    return true;
add_filter('wc_stripe_force_save_source', 'custom_wc_stripe_force_save_source', 10, 2);

function custom_hide_stripe_remember_me_css() {
    echo '<style>#wc-stripe-new-payment-method { display: none!important; }</style>';
    echo '<style>.woocommerce-SavedPaymentMethods-saveNew { display: none!important; }</style>';
add_action('wp_head', 'custom_hide_stripe_remember_me_css');

Finally, navigate to the admin panel of your site, and there, go to the plugins section, and activate your new plugin.

Coworking space in Madrid opened 24H


Making the post to hopefully save someone time. I am not affiliated, have been asked, or received money for this review.

I was in Madrid for one week and wanted to find a coworking space to work from. I also needed it to be open 24 hours, since I am working with a remote team, on the opposite side of the world.

I called many places: WeWork, Spaces, and others. They were either too expensive, opened only during the day, or required monthly plans. The solution is: https://goo.gl/maps/i8jQY2EFT4AztWYo7

The check all boxes: affordable, opened 24h and paid weekly.

Address: Glorieta de Cuatro Caminos, 6, 6ª, 28020 Madrid, Spain

Website: https://coworkinglafabrica.es/glorieta-de-cuatro-caminos/

A few photos about the place:



[Solved] Ethernet not working on RobotDyn Mega 2560 ETH R3 W5500


I bought a Mega 2560 from RobotDyn.com for a project and found the Ethernet port wasn’t working or was very unreliable. The shield (active PoE in my case), which comes soldered on the board wasn’t being recognized.

After hours of debugging, I found a solution in the Amazon reviews.

In the back, there are 4 solder jumpers, with the D7 one soldered. You need to desolder that jumper, and ta-da! Working like a charm.

Ethernet wasn’t working until I unsolder this jumper.

Root One Plus 5T on Android 10


With TWRP unavailable for Android 10, we can still root the One Plus 5T (and other models too) with these instructions.

This guide assumes your bootloader is unlocked. If not, here is a guide. Unlocking the bootloader will reset your device to factory settings, deleting all content, so make sure to backup anything important. After unlocking, or if your bootloader is already unlocked from a previous root, we can proceed.

1-. Using your phone, download the .zip of the Oxygen OS version that you are running on your device. Regularly, the images are found here: https://www.oneplus.com/support/softwareupgrade. But For Android 10, for both OP5 and OP5T, the images are directly in the forum.

Download links for OP 5 and OP5T for Android 10

2-. Install ZArchiver. It will allow us to copy the boot.img file inside the zip, without extracting other files. Copy that boot.img to your phone’s download directory.

3-. Install Magisk Manager from the official website: https://magiskmanager.com/ on your phone.

4-. Open Magisk Manager, click on Install -> Select and Patch a file. Now browse your downloads directory and tap on the boot.img file that we have just extracted.

Magisk App Opened

5-. Once flashing is done. Copy the flashed generated file magisk_patched.img to your computer. You can use Android File Transfer for this.

6-. Boot your phone into bootloader mode. To do this, enable advanced reboot in settings. Then press the button power for a few seconds, and you will see an option for bootloader mode.

7-. With your phone in bootloader mode, connect it to your computer, and run the following on a terminal:

fastboot flash boot magisk_patched.img

After rebooting, your phone should have root access.

Mac OS OpenVPN local traffic not routed via VPN


When using Tunnelblick, or Viscosity in Mac OS X (both use OpenVPN underneath), my local traffic was not routed via the VPN.

This happened despite enabling the options “route all traffic through VPN”, or adding push "redirect-gateway def1" to my VPN server options as suggested by https://askubuntu.com/questions/462533/route-all-traffic-through-openvpn

After some research, I found out what is happening, and I’ve come up with a temporary fix. I believe the root cause is a bug either on Mac OS X, or on OpenVPN, but this solution circumvents it.

First, disconnected from your VPN, your routing table should look like this:

netstat -nr

Routing tables

Destination        Gateway            Flags        Netif Expire
default          UGSc           en0
127                UCS            lo0          UH             lo0

After connecting to the VPN, running netstat -nr yields:

netstat -nr

Routing tables

Destination Gateway Flags Netif Expire
0/1 UGSc utun10
default UGSc en0
10.0.8/24 UGSc utun10 UH utun10

The problem is that the default route goes through, and not
This latter being our VPN gateway.

One solution to this is to explicitly add a route via the VPN gateway to individual local clients.
For instance, to access, a local client in the remote network, we run:

sudo route add

You can add as many clients as needed, and also add groups of them with IP/Masks. After this, you should be able to access local clients in the remote network.

Locked out of Instagram for not receiving 2FA SMS


If you have SMS 2FA activated in your Instagram account, and for some reason, you can’t receive SMS (changed phone numbers, traveling internationally, etc.) I have a potential solution for you.

To describe the problem a bit better. Last week, I accidentally logged out of my Instagram account. When I tried logging back in, they sent me an SMS that I couldn’t receive because I was traveling outside of the country. I read these posts: https://www.quora.com/How-do-I-verify-Instagram-if-it-wont-send-me-code, https://www.quora.com/How-do-I-login-to-Instagram-if-I-lost-my-phone-with-two-factor-authentication but I found another solution that might work for you too.

If this occurs to you, you can use the backup codes in lieu of the SMS. The backup codes are 8-digit codes that you download when activating 2FA in your account. But what if you, like me, don’t have those either?

Head down to your phone, and open the Instagram app, you should see something like this.

Android's Instagram logging in page
Android’s Instagram logging in page

Here, you are going to tap in “Log In with Facebook“. And you should see a page like this.

Logging in into Instagram through Facebook
Logging in into Facebook

Fill out your Facebook credentials, and then onto Facebook’s 2FA.

Facebook 2FA
Facebook 2FA

Since we don’t have an SMS to receive, login into your Facebook account, and head to settings. There click on Edit on the two-factor authentication.

Facebook security setting
Facebook security setting

We should be presented with the 2FA options. Since we can’t receive SMS, let’s download the recovery codes

Facebook's 2FA methods
Facebook’s 2FA methods

The codes should look like this.

Facebook's Back Up codes
Facebook back up codes

Copy one of these codes that haven’t been used yet, you can tell that from the icon on the right, and use it on your phone login screen instead of the SMS.

With that, I hope you regain access to your Instagram account. This time, make sure you enable a 2FA method that can be used if your SMSs are not working, such as an authenticator app, and download and keep your backup codes in a safe place.

Comment if this helped you, or if you are stilled locked out.

Build your own router, and homelab along the way



I am unhappy with the router options in the consumer segment. At home, I had a Netgear R7000, allegedly at the top of the consumer-grade routers pyramid.

Even after flashing it with DD-WRT, which multiplies the router’s capabilities, it couldn’t run a VPN client at a decent performance due to its unimpressive CPU (BCM4709A0). Furthermore, I never managed to get the VPN server to work on DD-WRT, and other aspects like DNS filtering felt very limited. Running anything else such as a torrent box on such tiny horsepower is a computational suicide.

I addressed the shortcomings of my setup with an RPi that I used to run a torrent seedbox, a local filesharing server, and a bitcoin node. The limitations of running these on the Pi were also obvious; the Pi didn’t have enough electrical power to drive the USB HDD attached to it. It also missed the mark on the CPU side – it couldn’t transcode video, so no Plex, and overall felt more like a toy and less like an actual production tool.

With all these problems, I started researching solutions, and I’ve developed a setup that I am delighted with and would like to share.

Costs and Materials

This table summarizes all I used, where did I find it, and its price.

[wptb id=766]

The brain

At the core of the system is the server, that is, a computer that will be on 24/7. Ideally, you want something that makes little to no noise, has a small form factor, and modest energy consumption, and at least 2 Gigabit ports.

Some go big and get an actual production server, e.g., a Dell PowerEdge R720. The problem is these are expensive, bulky, and use a lot of watts so that I wouldn’t suggest it.

Instead, I recommend going with a mini-PC. After some research, I ended up buying one from Protecli, in particular, the 6-port one with an Intel 7200U. These boxes are built like rocks and lack mechanical components such as fans or spinning disk hard drives. Mechanical parts are problematic in the long term because they end up breaking, require more power, and make noise.

Intel designed the 7200U for laptops, so it has a small energy footprint, yet it packs a decent punch. Since we will run it on DC as opposed to a battery, we can fully unleash its capabilities.

I ended up spending $660 with a 120 Gbytes of SDD.

Protectli 6 ports
Protectli 6 ports

Operative System

I wanted to run multiple services inside the box: router, bitcoin node, time machine backup, etc. and ideally, these services would be isolated.

There are a few ways to achieve this isolation in a single physical machine, such as virtual machines or docker images. I ended up going with bare metal Hypervisor, which means you run a small OS to manage Virtual Machines (VMs) that run directly on the hardware, as opposed to running VMs with instruction translation, the latter being much slower.

I tested ESXi from VMware in its free version, but I found bugs and shortcomings all along. I then tested Proxmox, which I found far superior and open source, and I have been happily running it ever since.

Installing Proxmox is quite simple; flash it on a USB thumb drive and boot your protectli with it. It will guide you through the installation process as a standard *nix distribution would. Make sure your box is connected via ethernet to a switch or router so that at the end of the installation process, Proxmox will get a local IP that you can then access from any local computer to manage our server.

Routing – PfSense

The first VM you want to install is the router one. Here the choice is simple: PfSense. Pfsense is a FreeBSD-based OS with 15 years in the making that specializes in networking. It has a fantastic web-UI to manage every single aspect of your network: DHCP, DNS, advertisement blocking, VPN (server and client), etc.

To install it, I followed this guide. In summary, download the latest .iso, and transfer it to a USB thumb drive, from there, upload it to the server via the web UI. Finally, add a CD drive to the VM, and point its content to the iso image.


CD-Rom drive Proxmox


Make sure you connect two extra ethernet ports while installing pfSense on our server. One should connect to your WAN (Wide Area Network), and that would usually be the ISP’s box that delivers internet to your house. The second one will be your LAN (Local Area Network) port, and you would connect this one directly to your computer, switch, or wireless access point.

PfBlockerNG is a remarkable feature that comes as an optional package for PfSense. In summary, PfBlockerNG blocks DNS requests to specified domains. It can also pull domain lists with a given frequency. These features combined, turn PfBlockerNG into an excellent advertisement blocker at the router level. The rest of my family is less technologically inclined than me, so blocking advertisement that harm sites’ user-friendliness and are sometimes malicious has saved them, and myself, a few headaches.

I don’t want to make a comprehensive list of features in this post. Instead, if you are curious, I suggest playing with it and exploring all it can do incrementally.

Once your Proxmox is up and running, this fantastic guide will help you get pfSense running on it: https://docs.netgate.com/pfsense/en/latest/virtualization/virtualizing-pfsense-with-proxmox.html.

Extra Storage

The internal SSD of 120 Gb is not going to take us too far. I suggest using this faster storage to store VM images and to purchase and connect a large USB HDD drive.

For ~ $100, you can find 5TB drives on popular e-commerce sites. Proxmox can connect to a USB drive and use it as internal storage. You can also mount the drive in different containers so you can effectively share data. A great example of this is downloading a video with the seedbox container that can then be read by the Plex media center container.

Ethernet, WiFi, and cameras

So Pfsense is acting as a router, and we should have two ethernet ports respectively mapped to WAN and LAN. Our Protectli machine has many more empty ethernet ports, so you might be tempted to use those for other LAN devices. That is a bad idea, as the protectli box will have to use the CPU on every data transfer across local devices.

A much better solution is to buy a switch, ideally a Power-over-Ethernet (PoE) one. I went with the Netgear GS108PP, for about ~$120. It has eight ports, and all of them are PoE. PoE means that each of the ethernet wires can deliver 15 watts, enough to power a camera, or WiFi access point.

Netgear 8 port switch

I have a set of 4 (Reolink) cameras installed around the house, so I ran four ethernet cables from the switch to their different locations. Because I made sure the cameras I bought were PoE, the ethernet cable was enough for the data and power transfer.

Camera Image Example
Reolink running on my Mac. I can access the four cameras I have installed around the house from anywhere. I’ve covered part of the images for privacy.

As for the WiFi, I found a Ubiquiti UAP-AC-Pro. A bit pricey, ~ $150, but performant, and also powered by PoE.

Wireless Access Point, or the wireless version of a switch

Other Services

You are set at this point, PfSense is acting as your router, WiFi served via the AP, and the cameras are connected to and powered by the switch.

While the basics are covered, your machine is capable of much more. To give you an idea, I run the following services: Plex to serve media around my house, Bitcoin node, filesharing, FTP server to store camera recordings, and a small python worker.

You should take this article as a starting point, and adjust this solution to your needs. Enjoy and comment if you like or have questions.

Network Diagram

This diagram represents my home network and lab.


Network Diagram for Building your own router
Network Diagram





[Tutorial] How to Run a Bitcoin Node on Ubuntu 19.10 – Updated 2020



In this guide, I show you how to run a headless (command line only) bitcoin node. I wrote it because most guides I found out there are incomplete, don’t work, run only on windowed mode, or are outdated.

I have tested these instructions 2 times on a clean Ubuntu 19.10, and it works. If it doesn’t for you please comment and I will try to help.

You can build bitcoin core with or without wallet support. I suggest against using your own node to store your coins unless you really know what you are doing. Instead, a dedicated hardware wallet such as a Trezor is a much better idea.

Building bitcoin core with wallet support requires to also build BerkeleyDB 4.8.30 which has a bug that prevents compiling. I show you how to fix that bug in this article.

TL;DR A just code version of this guide is available in github.


  • A computer running 24/7 or close to that. Your personal laptop is an awful place to run a bitcoin node as it will hog resources and most don’t keep their laptops on at all times. A RPi, a desktop that’s always on, or an Intel NUC, are best. I run it on a headless home server that I access via SSH.
  • Fresh install of Ubuntu 19.10. There are many online guides for this.
  • A fast, unmetered, and reliable internet connection. If you have vSDL or better you are good to go.
  • At least 400Gb of free HDD. Ideally more as the blockchain continues to grow. I had 500Gb.
  • Bitcoin is legal in most legislations, but you should check yours before doing any of this.

Getting our system ready

Assuming a fresh install of Ubuntu 19.10, and that you are logged in as root.

First things first, upgrade your local packages:

apt update
apt upgrade -y

For security, let’s create the user bitcoin_user to avoid running everything as root.

# add a regular user to our system
adduser --gecos "" bitcoin_user

Now add superuser permissions for bitcoin_user and login as such.

# add sudo permissions to this new user
usermod -aG sudo bitcoin_user

# and create a new shell logged in as her
su - bitcoin_user

Install these packages that we will need to compile Bitcoin core. Some of these are a bit heavy, be patient.

# build dependencies for Bitcoin core
sudo apt install -y git build-essential autoconf libtool pkg-config libdb++-dev libboost-all-dev libssl-dev libevent-dev

Optional, install BerkeleyDB for wallet support

# Download and untar the package
wget http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz
tar -xvf db-4.8.30.NC.tar.gz

# fix the bug on BerkeleyDB
sed -i 's/__atomic_compare_exchange/__atomic_compare_exchange_db/g' db-4.8.30.NC/dbinc/atomic.h

# Configure
cd db-4.8.30.NC/build_unix
mkdir -p build
BDB_PREFIX=$(pwd)/build  # we will use this shell variable later
../dist/configure --disable-shared --enable-cxx --with-pic --prefix=$BDB_PREFIX

# Compile and install
sudo make install

Install Bitcoin Core

Clone Bitcoin’s GitHub repo:

git clone https://github.com/bitcoin/bitcoin.git

Now check out the latest release from Github. You can see the latest release at https://github.com/bitcoin/bitcoin/releases. Today that is 0.19.1. Checkout the corresponding git tag:

cd bitcoin
git checkout v0.19.1

Compile and install bitcoin core!


# if you built BerkeleyDB
./configure CPPFLAGS="-I${BDB_PREFIX}/include/ -O2" LDFLAGS="-L${BDB_PREFIX}/lib/"

# else
./configure --disable-wallet

# in either case 
sudo make install

After installing you are ready to run bitcoin daemon and check the status with bitcoin-cli.

# start the bitcoin daemon in daemon mode :-)
bitcoind -daemon

Wait a minute after starting the daemon and running the next command.

# print the status of our local blockchain copy
bitcoin-cli getblockchaininfo

The Bitcoin daemon starts without errors, and we can see the initial block sync has started. It will take a few hours, or even days, depending on your hardware, for that initial block sync to complete. Once complete, the initialblockdownload will change to false, and verificationprogress will hover just below 1.

Forwarding port 8333

To have a fully functional Bitcoin node, you need to forward incoming connections on port 8333 to the device running Bitcoin core.

We first assign a static local IP to our bitcoin core host, e.g., then, we create a forwarding rule to that host for all incoming connections on port 8333.

I use pfSense and this is my config for a static IP:

pfSense Static IP
pfSense Static IP

As for forwarding port 8333:

Verifying everything is working

Once the bitcoin node has synced, and if your port forwarding is working properly, you can check your node on https://bitnodes.earn.com/ 

Insert your IP to check if your node is accepting incoming connections

Your public IP will be populated, and you can simply click on check node. In my case, I see this

Pat yourself in the back! You are supporting the Bitcoin network now.

Optional, auto start bitcoin core after shutdown/restart

The bitcoin daemon will not automatically start if the system shuts down or reboots. To auto start it, we can edit our crontab by running crontab -e, and add the following line to it.

@reboot /usr/local/bin/bitcoind --daemon


Speed of Sound


Visualization showing the speed of sound at different scales. Done in Adobe AfterEffects.

[OC] Speed of Sound from dataisbeautiful

Compiling Berkeley DB 4.8.30 in Ubuntu 19


I’ve been following guides like this one, to run a bitcoin node, but upon compiling Berkeley DB 4.8.30 on my Ubuntu virtual machine, I kept getting the error:

ln -s libdb-4.8.a libdb.a
./libtool --mode=compile g++ -c -I. -I../dist/..  -D_GNU_SOURCE -D_REENTRANT -O ../dist/../cxx/cxx_db.cpp
libtool: compile:  g++ -c -I. -I../dist/.. -D_GNU_SOURCE -D_REENTRANT -O ../dist/../cxx/cxx_db.cpp  -fPIC -DPIC -o cxx_db.o
In file included from ../dist/../dbinc/mutex_int.h:12,
                 from ../dist/../dbinc/mutex.h:15,
                 from ./db_int.h:884,
                 from ../dist/../cxx/cxx_db.cpp:11:
../dist/../dbinc/atomic.h:179:19: error: definition of 'int __atomic_compare_exchange(db_atomic_t*, atomic_value_t, atomic_value_t)' ambiguates built-in declaration 'bool __atomic_compare_exchange(long unsigned int, volatile void*, void*, void*, int, int)'
 static inline int __atomic_compare_exchange(
make: *** [Makefile:2018: cxx_db.o] Error 1

The solution is to edit the file  db-4.8.30.NC/dbinc/atomic.h.

Line 147, replace __atomic_compare_exchange((p), (o), (n)) with __atomic_compare_exchange_db((p), (o), (n))

Line 179, replace static inline int __atomic_compare_exchange( with static inline int __atomic_compare_exchange_db(

If you want a one-line solution

sed -i 's/__atomic_compare_exchange/__atomic_compare_exchange_db/g' db-4.8.30.NC/dbinc/atomic.h