VPN-only Internet Access on Linux Mint 19.3 via Private Internet Access

Setting up Private Internet Access VPN is usually not a problem these days as Linux version is readily available among the supported clients. However, such installation requires GUI. What if we don’t want or need one?

For setup to work independently of GUI, one approach is to use OpenVPN client usually installed by default. Also needed are PIA’s IP-based OpenVPN configuration files. While this might cause issues down the road if that IP changes, it does help a lot with security as we won’t need to poke an unencrypted hole (and thus leak information) for DNS.

From the PIA configuration archive extract your choice of .ovpn file (usually going with the one physically closest to you will give you the best results). There is no need to extract .crt and .pem files as configuration has certificates embedded.

Rest of the VPN configuration needs to be done from the Bash:

sudo cp ~/Downloads/openvpn-ip/^^US\ Seattle^^.ovpn /etc/openvpn/client/pia.conf

echo "auth-user-pass /etc/openvpn/client/pia.login" | sudo tee -a /etc/openvpn/client/pia.conf
echo "mssfix 1400" | sudo tee -a /etc/openvpn/client/pia.conf
echo "dhcp-option DNS 209.222.18.218" | sudo tee -a /etc/openvpn/client/pia.conf
echo "dhcp-option DNS 209.222.18.222" | sudo tee -a /etc/openvpn/client/pia.conf
echo "script-security 2" | sudo tee -a /etc/openvpn/client/pia.conf
echo "up /etc/openvpn/update-resolv-conf" | sudo tee -a /etc/openvpn/client/pia.conf
echo "down /etc/openvpn/update-resolv-conf" | sudo tee -a /etc/openvpn/client/pia.conf

The basic VPN setup is already completed but we still need to setup our login (replacing username and password with the actual values):

unset HISTFILE
echo '^^username^^' | sudo tee -a /etc/openvpn/client/pia.login
echo '^^password^^' | sudo tee -a /etc/openvpn/client/pia.login
sudo chmod 400 /etc/openvpn/client/pia.login

Firewall rules are to allow data flow only via VPN’s tun0 interface with only encrypted VPN traffic being allowed on port 1198.

sudo sed -i 's/IPV6=yes/IPV6=no/' /etc/default/ufw
yes | sudo ufw reset
sudo ufw default deny incoming
sudo ufw default deny outgoing
sudo ufw allow out on tun0
sudo ufw allow out on ^^eth0^^ proto udp to `cat /etc/openvpn/client/pia.conf \
    | grep "^remote " | grep -o ' [^ ]* '` port 1198
sudo ufw disable
sudo ufw enable

To test VPN connection execute:

sudo openvpn --config /etc/openvpn/client/pia.conf

Assuming test was successful (i.e. resulted in Initialization Sequence Completed message), we can further make sure data is actually traversing VPN. I’ve found whatismyipaddress.com quite helpful here. Just check if IP detected is different then IP you usually get without VPN.

Stop the test connection using Ctrl+C and proceed to configure OpenVPN’s auto-startup. Reboot is there just to test if auto-startup works.

sudo systemctl enable openvpn-client@pia
sudo reboot

This should give you quite secure setup without the need for GUI.

[2020-07-06: Works with Linux Mint 20 too.] [2020-08-07: Added step to disable IPv6.]

Gray Background for Read-Only QLineEdit

Setting a text box (aka QLineEdit) to read-only in QT doesn’t make its background gray as one would normally expect. Background remains as is with user confused as to why text cannot be changed. Classic Windows solution of graying out background seems much better to me and I decided to replicate the same.

My requirements for this were just two. It had to work correctly under both Windows and Linux. And it couldn’t use static color but follow the overall theme.

The first idea was to use background role.

ui->lineEdit->autoFillBackground(true);
ui->lineEdit->setBackgroundRole(QPalette::Window);

And, even with background auto-filling set, this doesn’t work.

As I was after the same color as window background, setting the whole text box transparent seemed at least plausible.

ui->lineEdit->setStyleSheet("background: transparent;");

This sort-of worked but with only top border-line visible instead of full rectangle. Passable but ugly.

After a few more false starts, I finally found code that fulfills both requirements.

QPalette readOnlyPalette = ui->lineEdit->palette();
readOnlyPalette.setColor(QPalette::Base, ui->lineEdit->palette().color(QPalette::Window));
ui->lineEdit->setPalette(readOnlyPalette);

Essentially, we modify palete and set it’s color to what Window would use. A bit more involved than just setting read-only property but I guess not too difficult either.

ResetBox

Illustration

It all started with an itch to scratch. My modem occasionally misbehaves and needs a reboot. Unfortunately, I have it mounted way back in the 19" rack and accessing it requires removing back panel. And no, I cannot easily unplug it’s connected to UPS and wires are all tucked in the back. What I needed was a button in one of rack spacers allowing for reboot of equipment in the back.

Since I couldn’t find something like this readily available, I decided to build it.

First I enumerated all the equipment I have. One modem (12 V), one NUC (19 V), and finally two wireless access points (48 V). I was at crossroads. As voltage range is quite wide I had to choose if I want to make device work of specific voltage (cheaper) or to have a single device covering all the bases (more expensive). While going cheaper was tempting, I decided to go with wide input after all. It meant I can design thing only once and use it later for some other project without having to check voltage rating each time.

This decision also made me select DC-DC converter module. Making my own wide range converter would be possible but getting it just right would take annoyingly long time and actual cost wouldn’t be much lower. Yes, at $5 R-78HE5.0-0.3 is not cheap but it’s simplicity is worth every penny. If I ever decided to produce this box in bigger quantities, this would probably be the first thing to go in order to lower expenses and simplify design.

While not necessarily mandatory, I also opted to include EMC filter for DC-DC converter. Considering low currents it’s probably an overkill but I really didn’t want to find out later that I’m spraying too much noise around my rack. Design improvement would be to either remove filter all together (probably possible due to low current requirements) or make it much simpler and hopefully omitting SMD inductor. I hate to solder that stuff.

It took me a while to find a button as I wanted momentary switch with LED (excellent for giving status) and it had to look nice in rack. I finally found Adafruit’s S 560. This button is awesome in person.

To connect button, I selected JST S3B-XH. I needed the minimum of three wires (GND, LED, and switch input) and I already had bunch of premade cables made in the course of another project. If I had only this project to worry about, I would probably select 4-wire connector as it would make soldering a bit easier. Not it’s too hard now - just wire GND to both LED and NC input and you’re golden.

Voltage connector choice was extremely easy as literally all devices I wanted to control already used barrel connector. Since 2.1 mm barrel had became a defacto standard for network cameras, this also meant I could count on connecting it all with factory cables making the whole setup a bit nicer.

Speaking of which, I mulled long time about whether I should support only barrel setup with positive voltage on tip and negative voltage on sleeve or the inverse one too. All network devices I ever owned have positive tip. However, I decided to allow negative tip setup to. I am 95% sure this was completely unnecessary precaution but at least I don’t need to worry about it.

As far as saving money goes, supporting only positive tip barrel connectors, would allow me to remove diode bridge on input and allow me to replace mechanical relay with MOSTFET. As I’m making only 3 devices, for now I value flexibility the most. But decision to include these still bothers me a bit.

Housing hardware fell to Hammond 1593KBK. This is a reasonably sized and more important reasonably priced case with side panels. While I usually replace such panels with custom PCB with cutouts in place of connectors, this time I opted for 3D printed version. It’s definitely cheaper than PCB but it does require you to have printer. And no, it’s not as nice as PCB panel but it looks good enough - especially since device will sit in the back of the rack.

Lastly, I had to select microprocessor that would handle all logic. As most of my devices, I simply went with selecting Microchip’s part. I needed two outputs (LED and relay) and a single input (switch). In order to avoid complications, I like to keep programming lines separate too (MCLR, PGD, and PGC). Yes, you can share these lines with logic if you’re careful but having them reserved is one way to make sure. Once you include power supply, there is variety of 8-pin microcontrollers to chose from.

Finally I went with PIC12F1501-I/SN. It has 8 pins which is what we needed. SOIC package makes it easy to solder and internal oscillator minimizes extra components needed.

Code running on chip is as easy as it gets. What follows is the main loop.

void main(void) {
    io_led_on();
    while(true) {
        if (io_switch()) {
            if (debounceCounter < DEBOUNCE_MAX) {
                debounceCounter++;
            } else {
                intensityCounter++;
                if ((intensityCounter % 8) == 0) { io_led_on(); } else { io_led_off(); }
            }
        } else {
            if (debounceCounter == DEBOUNCE_MAX) {
                io_relay_on();
                for (int i = 0; i < RESET_COUNTER; i++) {
                    io_led_on(); wait_short();
                    io_led_off(); wait_short();
                }
                io_relay_off();
            }
            io_led_on()
            debounceCounter = 0;
        }
    }
}

If button is pressed, counter (debounceCounter variable) gets increased while button is pressed and until it reaches maximum. Side effect of handling counter like this is automatic debouncing and making sure short, accidental, swipes don’t activate reboot functionality. Once at maximum, counter stops and we dim the LED so user knows reboot will follow once button is depressed. Dimming is actually done by poor man’s PWM - just turn LED manually on 1/8 of interval (when counter is divisible by 8).

Second path executes only when the button is not pressed. If debounce counter is at maximum, a simple reset sequence starts. Here we disconnect relay (ironically by turning it on as it’s normally-connected setup) and LED blinks for 4 seconds. Then we turn relay back off so that power returns to the device.

It’s probably the simplest code I’ve written in quite a while.

If you want to check it a bit more, feel free to look up both board and code at GitHub.

Multiple IPv6 Networks with Mikrotik

Illustration

Setting up IPv6 for home network is simple enough with Mikrotik. I actually already wrote about it and that IPv6 guide is still perfectly valid. However, what if you have multiple bridges and a single IPv6 address won’t do (e.g. home and guest network)?

Well, first you need to be lucky enough to have provider willing to give you multiple /64 prefixes as stateless address autoconfiguration (SLAAC) cannot work with prefix longer than that.

For this to work you need a prefix hint to let your provider know you want something bigger. Despite RIPE recommending at least /56 prefix length, my Comcast-provided connection gives /60 at most even if you request a shorter prefix.

/ipv6 dhcp-client
add interface=^^ether1^^ pool-name=general-pool6 request=prefix prefix-hint=::/48 add-default-route=yes

Once you receive IP allocation, check on Status tab you indeed got something shorter than /64. If you got only /64 allocation, you will not be able to have two independent networks. In my case, /60 enables me up to 16 networks.

Next we add additional router address to use for advertisement.

/ipv6 address
add address=::1 from-pool=general-pool6 interface=^^bridge2^^ advertise=yes

Lastly, we need to setup router announcements.

/ipv6 nd
add interface=^^bridge2^^ ra-interval=20s-60s

And that’s it. Now your guests can enjoy IPv6 too.

Colored CPU usage in TMUX

Illustration

Those spending a lot of time in Linux command line know the value of a good terminal multiplexer. Even in the age of GUI terminal windows, using tmux will speed your work while many customizations it offers will make for comfortable environment.

Knowing its flexibility, for my Minecraft server, I wanted tmux status line to include something I never tried before - CPU usage. Yes, one could use top, htop, glances, or any other of the many monitoring tools but I didn’t want the whole screen occupied by it. I wanted just a small unobtrusive note in the corner.

There are multitude of ways to retrieve CPU usage but I found vmstat works well for me and thus the first version just placed its parsed output in the bottom-right corner:

set-option -g status-interval 1
set-window-option -g status-right ' #( vmstat 1 2 | tail -1 | awk "{ printf 100-\$15; }" )% '

While this satisfied my original requirements, I started thinking about colors. Could I make it more colorful?

Search immediately found me a few tmux plugins and one of them looked really promising. While using it would be perfectly fine for my use case, I don’t like dependencies and thus I tried to find tmux-only solution for colors.

A bit of testing later and I noticed shell commands (enclosed in #()) are processed before formatting directives. So, if I manage to return the formatting from shell, tmux will do further processing and colors will be there. A bit of awk-ing later and this is what I came up with.

set-option -g status-interval 1
set-window-option -g status-right ' #( vmstat 1 2 | tail -1 | awk "{ USAGE=100-\$15; if (USAGE < 20) { printf \"#[fg=green,bright]\"; } else if (USAGE < 80) { printf \"#[fg=yellow,bright]\"; } else { printf \"#[bg=red,fg=white,bright]\"; }; print \" \" USAGE \"% \" }" )'

It’s still vmstat based output but now awk appends color formatting strings for different usage levels. If usage is lower than 20%, a bright green foreground is used; lower than 80% results in a bright yellow text; and anything higher results in a bright red background.

It’s a simple color-coded way of showing CPU usage at a glance.


PS: If you want extra status line text after CPU percentage, consider adding #[bg=default,fg=default] to stop color “bleeding” to remainder of the line.