Categories
Uncategorized

Electron with custom Chromium build

I was looking into a way to customise the Chromium code in an Electron app. As it turns out, it’s not as difficult as it might sound, though it requires some patience (mainly because building Chromium takes a lot of time, RAM and CPU).

To get started, make sure you have installed depot_tools from Google.
It’s a good idea to provision a git cache as well:

$ export GIT_CACHE_PATH="${HOME}/.git_cache"
$ mkdir -p "${GIT_CACHE_PATH}"

Now, you can fork electron and add your Chromium patches.
It’s important to make sure you deal with whitespace and newlines as well. Electron has a couple of scripts that will generate the patch file for you.


Next, let’s configure the build:

$ mkdir electron && cd electron
$ gclient config --name "src/electron" --unmanaged https://github.com/[your-fork-name]/electron
$ gclient sync --with_branch_heads --with_tags

Once that completes successfully, you can indicate the build config you want to use. In our case, let’s use the release config:

$ gn gen out/Release --args="import(\"//electron/build/args/release.gn\") $GN_EXTRA_ARGS"

$ ninja -C out/Release electron

This will take a while to build, depending on your CPU, RAM and disk.

When ninja finally completes, you might want to build a package of Electron:

$ ninja -C out/Release electron:electron_dist_zip

You now have a zip file, which you can use with for example @electron-forge. Make sure to specify the correct config in your package.json:

"config": { "forge": { "packagerConfig": { "electronZipDir": "../custom-electron" } }

The zip files should be named similar to these:

  • electron-v15.1.2-darwin-x64.zip
  • electron-v15.1.2-win32-x64.zip

Now you can build your Electron app with the custom Chromium build.

Categories
Uncategorized

VMWare Fusion – modify DHCP

If you are running VMWare Fusion, chances are you might have created your own custom network adapter.

In case you’re running an (authoritative) DHCP server in this subnet, you might see interference with VMWare Fusion’s own DHCP server.

You can easily disable the Fusion DHCP server by following these steps (no Fusion restart required):

  • set DHCP no for your adapter with sudo nano /Library/Preferences/VMware\ Fusion/networking
  • apply the new settings with:

sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --configure
sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --stop
sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --start

You might also need to disable the macOS bootp process:
sudo /bin/launchctl unload -w /System/Library/LaunchDaemons/bootps.plist

Categories
Uncategorized

Automated Browser Testing with Puppeteer

If you are interested in browser automation, you probably have heard of Puppeteer.

Puppeteer is a NodeJS library, which connects with Chromium browsers through the DevTools protocol.

Puppeteer will send the same messages back and forth just like the Chrome DevTools do. By doing that, it allows Puppeteer to control and interact with the Chrome browser.

There’s some advantages to using this method instead of using Selenium (WebDriver):

  • It is faster, because of the DevTools protocol which is natively supported. And because it’s using WebSockets instead of HTTP requests (which WebDriver uses).
  • The default mode is headless, which means no UI is visible. If you are automating your browser, chances are you don’t really need to see the browser. If you are doing UI tests, you might want to see the browser, in which case Puppeteer has a ‘headful‘ mode as well.
  • Regular updates. Puppeteer is maintained by Google. This means it will definitely keep up with Chrome and any new features.

Ready to get started? I can recommend reading the article Puppeteer Testing which will guide you through setting up and configuring Puppeteer and a test framework such as Jest, WebDriverIO or PyTest.

In case you’re looking for an alternative solution, I can recommend Playwright. It offers the same set of features, uses the same technology under the hood and has broader browser support.

Happy Testing!

Categories
Uncategorized

Removing ‘System Volume Information’ from a NTFS Volume

There’s a quick and easy way to remove the ‘System Volume Information’ folder from a NTFS disk. Run these commands in an elevated shell:

D: (or whichever volume letter you are using)
takeown /r /f "System Volume Information"
rd /s /q "System Volume Information"
Categories
Uncategorized

Streaming MySQL backup

This week I needed to backup a Percona MySQL server.
One solution for this, is to stop the MySQL server, create a mysqldump, and transfer it to your backup location.

However, depending on your tables and data size, this might not be the best solution. Especially if the database you want to backup is a live database with active users.

The solution for me was to use xtrabackup (innobackupex) from Percona to stream the database in tar format over SSH to another server:

innobackupex --stream=tar . | ssh user@x.x.x.x "cat - > /mnt/backup/backup.tar"

Once this is done, the other server needs to unpack the tar and prepare the backup:

xtrabackup --prepare --target-dir=/var/lib/mysql

At the end of this command, you should see an OK message.
If all went well, you can now do:

chown -R mysql:mysql /var/lib/mysql

and restart the MySQL server. The binlog position will be included in the output of the xtrabackup --prepare so you can easily set up master/slave syncing.

Finally, I created a cronjob on the MySQL Slave server which will take a daily backup with xtrabackup and upload to a 3rd party secure storage.

Categories
Uncategorized

image-orientation CSS property

The other day I was investigating an issue with Chrome 83 and a MJPEG stream embedded in an <img />

The MJPEG stream was streaming an iPhone screen to the end user. When the user decided to rotate the screen (switching between portrait and landscape), the MJPEG stream was updated accordingly when viewing the stream inside a separate tab, but it was not showing correctly when embedded in a HTML image tag.

Turns out that since Chrome 81, the browser will look at the EXIF data to decide the correct orientation. The issue I was experiencing was happening because the EXIF data did not update after each rotation.

The solution was to use image-orientation and apply this CSS rule to the image tag. Once that was in place, the MJPEG stream was showing correctly after each rotation.

More information is available in this Chromium ticket.

Categories
Linux

WireGuard: an alternative to OpenVPN

This week I’ve been experimenting with WireGuard, which is a relatively new alternative to OpenVPN. It claims to be faster and more secure than other VPN products, partly because its codebase is very small compared to other VPN products.

WireGuard is easy to configure. It is compatible with many Linux distro’s, including Ubuntu. For my testing purposes, I’ve set up a new Ubuntu 18.04 LTS VM with Hardware Enablement.

First, make sure you’ve installed WireGuard correctly:
apt-get install wireguard

You should now be able to use wg and wg-quick
Let’s create a public and private key, which we’ll be using to set up a secure connection:

wg genkey | tee privatekey | wg pubkey > publickey

On the server VM, create a new configuration file /etc/wireguard/wg0.conf
Add the private key you just generated in the PrivateKey section.

This should contain configuration like this:

[Interface]
PrivateKey = <private key>
Address = 192.168.160.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth1 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth1 -j MASQUERADE
SaveConfig = false

[Peer]
PublicKey = <public key>
AllowedIPs = 192.168.158.3/32

The next thing you’ll need to do is add the Peers that will be able to connect to this server. Simply create another VM (Windows, Linux or MacOS) and follow the same steps:

  • install WireGuard
  • generate private and public key
  • create a new /etc/wireguard/wg0.conf configuration file
[Interface]
PrivateKey = <private key>
Address = 192.168.158.3/32
DNS = 8.8.8.8

[Peer]
PublicKey = <public key of the server>
Endpoint = <ip4-of-server>:51820
AllowedIPs = 0.0.0.0/0, ::/0 # Forward all traffic to server

The AllowedIPs instructs WireGuard to forward all traffic through the tunnel.

Finally, you can start up WireGuard on both the server and client:

wg-quick up /etc/wireguard/wg0.conf

Now both VMs should be connected and able to ping each other.
You can check the status of the connection with:

wg show

I saw a notable increase in throughput compared to OpenVPN. Try it out yourself and let me know in the comments.

Categories
Linux

Speeding up your OpenVPN tunnel

Here are some settings to speed up the transmission rate through your OpenVPN tunnel:

  • proto udp
  • mssfix 0
  • fragment 0

mssfix: Even though MSS itself is a TCP feature, this OpenVPN option targets encapsulated UDP packets. It will change the MSS value of the TCP protocol inside the tunnel in such a way that after UDP encryption/encapsulation, the resulting UDP packet size (minus IP/UDP headers), will not exceed the mssfix value.
By setting the value to 0, we disable this feature.

fragment: This will disable OpenVPN’s internal fragmentation routines (OpenVPN 2.x actually does this by default).

Another improvement is raising the MTU (Maximum Transmission Units), which is the maximum datagram size in bytes that can be sent unfragmented over a network path.

First make sure your OpenVPN server has set the same MTU size:

ip link set eth0 mtu 9000

Next, add this to your OpenVPN configuration:

tun-mtu 9000

Categories
Linux

A gateway to forward all traffic to a remote VPN server

Suppose you’ve setup a VM and configured it as a site-to-site VPN with OpenVPN, using iroute and staticclients. You are using this VM as a default gateway for other VMs and now want to forward all traffic from the VMs not through the default gateway‘s adapter, but through the VPN tunnel.

Why would you want to do this? One use-case might be because you want your VMs to have the same originating IP address as the VPN server.

To get started, make sure you add these commands in a terminal on your default gateway:

  • ip route add ip-address-of-vpn-server/32 via default-gateway-ip dev enp0s5 (providing enp0s5 is your current adapter)
  • ip route del default
  • ip route add default via 192.168.159.14 dev tun0 (providing 192.168.159.14 is the private IP you got from your VPN)

The commands above will make sure your gateway can still reach the VPN server. Once the default route is deleted, we add a new default route that goes through the tunnel.

On the other side of the tunnel, on your VPN server, you will need to add these commands:

  • iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  • iptables -I FORWARD -i tun0 -o eth0 -s 192.168.159.0/24 -m conntrack --ctstate NEW -j ACCEPT
  • iptables -t nat -I POSTROUTING -s 192.168.159.0/24 -o eth0 -j MASQUERADE
  • iptables -t nat -I POSTROUTING -o tun0 -j MASQUERADE
  • iptables -I FORWARD -i eth0 -o tun0 -j ACCEPT
  • iptables -I FORWARD -i tun0 -o eth0 -j ACCEPT
  • iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

Now the VMs will be able to connect through the VPN tunnel and use the VPN server as default gateway.

Categories
OSX

VMsvga2

If you’re running macOS with QEMU, you’ll notice that the UI might be slow. This is because, by default, QEMU will use a basic display adapter with low display memory (VRAM).

There’s two ways to fix this problem:

  • Pass-through your GPU with vfio
  • Use another display adapter, such as VMsvga2

This post will focus on VMsvga2, which is a macOS kext that enables you to use the vmvga video model with libvirt.

Unfortunately VMsvga2 is an old project that is no longer maintained, same goes for the vmvga QEMU driver. Currently there’s no QXL driver available for macOS so this is the only choice we have.

Simply replace your existing video XML with this:

<video>
  <model type='vmvga' vram='16384' heads='1'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/> 
</video>

You can increase the vram to the amount you desire.
If you are using the Clover bootloader, you might have to add wmv_option_fb=0x06 to the arguments section in your config.plist

You will also need to make sure you have the VMsvga2 kext installed on your system.

Once you reboot, you’ll notice a more responsive UI.