Stuff I'm Up To

Technical Ramblings

WireGuard, OTP and ACL’s — September 29, 2022

WireGuard, OTP and ACL’s

Out of the box, WireGuard is a simple tool that solves a simple issue. Securely connect this system to that system. But what if that’s not quite enough? If a malicious actor obtains your WireGuard config then they are free to connect as you do!

In reality, your connection should still place restrictions on what you can access using whatever authentication mechanisms the remote network or system requires, place you into a mediation zone or take steps to ensure being connected isn’t your only trust mechanism.

This is where NHAS/Wag comes in.

WAG provides a means of using a One Time Password (for Multi-factor Authentication) that works with WireGuard and the Linux eBPF firewall. This means I now require a public/private key pair to authenticate with WireGuard, but then I must provide a one time password from an authenticator phone app like FreeOTP or Google Authenticator to enable the firewall to actually allow me on to something inside the network.

WAG manages your user registration process and sets up the WireGuard config ready for them. You can send them a link where they can obtain their configuration file, and when they first try to authenticate it even gives them the QR code to scan into the authenticator app.

The process is very simple.

  1. Register the user with WAG
  2. Send the user the registration link
  3. The user installs the WireGuard config they received
  4. The user connects with WireGuard
  5. The user visits the OTP page, eg. http://otp and enters the code from their phone
  6. If successful, WAG opens the firewall rules to allow the user access
Continue reading
Fail2ban – PostgreSQL — September 14, 2022

Fail2ban – PostgreSQL

We don’t often have the need to expose PostgreSQL to a network, let alone the internet. Mostly the instances are enclosed within a Docker container set and don’t need to be accessed by anything outside of that. So when we have a need to expose it we need to protect it as much as possible.

Make the change to enforce security within PostgreSQL, using TLS and certificates, lock down authentication to IP addresses using pg_hba.conf, but we should also monitor and block access at the firewall.

Continue reading
WireGuard and iptables, or Not — September 6, 2022

WireGuard and iptables, or Not

iptables isn’t essential for WireGuard. It really depends on your requirements. In my previous post, I used iptables for a point-to-multi-point set up. This is because the external user connecting to the office would need to get to all kinds of internal services. Without adding a route to all the internal services to reply to the incoming traffic, there is no way routing alone would handle this. It would become impossible to add routes for each users’ endpoint, without them clashing with each other. For this, I had to use NAT.

The PostUp rules handled that for me:

PostUp = iptables -t mangle -A PREROUTING -i %i -m comment --comment "wireguard"
PostUp = iptables -t nat -A POSTROUTING ! -o %i -j MASQUERADE -m comment --comment "wireguard"
  • %i represents the WireGuard interface name

The other rules in the FORWARD chain may not have been necessary, it depends on the existing rules. If you disable forwarding for all but necessary forwards, then you’d need to allow forwarding into and out of the wg0 interface.

With a point-to-point setup, say user to user. Then things get much easier. No need for iptables and both parties can talk across to each other using routing and ip_forward only. Of course, you may choose to add some rules to make things more secure, but a simple enough setup on both ends could be:

[interface]
Address = 10.0.0.1/32
ListenPort = 51820
PrivateKey = SuperSecretKey
PreUp = sysctl -w net.ipv4.ip_forward=1

[peer]
PublicKey = SecretKey
AllowedIPs = 10.0.0.2
EndPoint = 192.168.100.12:51820

Now, peers can talk to each other over the IP addresses 10.0.0.1 and 10.0.0.2. The 192.168.100.12:51820 represents the network, or internet, addresses used to connect to each other.

No need for the PreUp script if you already have forwarding enabled, but it’s a useful thing to do to ensure it is set up.

This simple config can work just as well for a multi-point-to-multi-point scenario. Where two offices might be connected. As long as they have different network addresses, no NAT is required. The only thing that changes is the AllowedIPs.

[interface]
Address = 10.0.0.1/32
ListenPort = 51820
PrivateKey = SuperSecretKey
PreUp = sysctl -w net.ipv4.ip_forward=1

[peer]
PublicKey = SecretKey
AllowedIPs = 10.0.1.0/24
EndPoint = 192.168.100.12:51820

The other end could use an AllowedIPs = 10.0.2.0/24 and the two networks can then talk to each other – with one important caveat. You either have the peers set as default routes, or add to the routes on the peer network for the other end, eg.

sudo ip route add 10.0.2.0/23 via 10.0.1.1 dev eno1

and vice versa.

  • 10.0.1.1 represents the IP address of the peer

Passing Over the Config

When sending the other party the WireGuard config, you can use a QR code. Very handy for mobile devices. Once you’ve saved the peers wg0.conf as a text file, convert it to an image using

qrencode -t png -r wg0.conf -o wg0.png

Then you can scan it with the mobile WireGuard client on Android, or fruit based device.

Python3 One Line Web Server —

Python3 One Line Web Server

Many times I find myself wanting to spin up a simple test service for a firewall rule. You can bring up a simple web server in Python3 from the command line.

python3 -m http.server

This will start it on port 8000 (http://0.0.0.0:8000). To start it on port 80 you will need root privileges, as per any port from 0-1023.

sudo python3 -m http.server 80

WireGuard — September 5, 2022

WireGuard

WireGuard is a very simple and efficient firewall. It has only one authentication mechanism and that is using public key cryptography, either public/private keys, or pre-shared key.

It’s very much an up-and-coming development that has been added into the Linux kernel, but still has some features to be added to network manager for peer support.

You need to use port forwarding on both ends of the tunnel. This is the part most user or client ends are likely to struggle with. With OpenVPN, we only need to have a system administrator open a firewall rule on the server end of the tunnel. The client doesn’t need to do anything other than connect.

Continue reading
OpenVPN Gnome Network Manager and OTP — September 3, 2022

OpenVPN Gnome Network Manager and OTP

If you’re looking for the answer to how to get Gnome to connect to your OpenVPN using OTP, then you’re going to come to a dead end.

There’s been an outstanding issue logged on Gitlab for over 3 years (to date) that wants this facility fixing.

https://gitlab.gnome.org/GNOME/NetworkManager-openvpn/-/issues/12

It’s frustrating because we have mostly Linux users. The few macs and Windows users are all right, they get the OTP prompt. Even Android works as it should, it’s only Linux that needs fixing.

I tried the workarounds from the comments and none of them worked for me.

For now, you’ll have to satisfy yourself with using the command line.

OpenVPN Client in the Background — September 2, 2022

OpenVPN Client in the Background

With 2FA/MFA and OpenVPN on Linux you need to use the terminal to start up the session.

sudo openvpn user.name.ovpn

You then get to see all the prompts for username, password, OTP and certificate key passphrase. The only trouble is you get to see it in a terminal all day and you can’t close it.

Run it inside a screen session instead!

screen -dmS vpn
screen -x vpn
sudo openvpn user.name.ovpn

Then CTRL+A+D to detach yourself. You can close the terminal and come back to it inside any new terminal using:

screen -x vpn

OpenVPN MFA and PAM — September 1, 2022

OpenVPN MFA and PAM

So far I’ve seen 2FA/MFA with OpenVPN using a 3rd Party plugin openvpn-otp.so from evgeny-gridasov/openvpn-otp, but after I got it working I didn’t like the way it implemented HOTP counter storage and the use of otp-secrets. There has to be another way.

I see that there is a native openvpn-plugin-auth-pam.so, and also know that on another system we’re using the OATH toolkit for providing OTP for sshd. The OATH toolkit includes pam_oath.so. This means there is a common link for me to make use of PAM to give me MFA for OpenVPN.

Continue reading
Restic and Backblaze B2 — August 24, 2022

Restic and Backblaze B2

Setting up restic as per the instructions on Backblaze didn’t work exactly as planned.

The environment variables needed to be changed from B2_ACCOUNT_ID and B2_ACCOUNT_KEY to B2_APPLICATION_KEY_ID and B2_APPLICATION_KEY. This may be down to the version of the b2 binary I’m using.

To get things going, download the binary from the Backblaze site, and put into your path somewhere, eg. /usr/local/bin/b2, make sure it’s executable with chmod ugo+x.

Continue reading
Exim4 Tainted and Permission Denied — August 22, 2022

Exim4 Tainted and Permission Denied

Talk about driving me crazy. We had error messages in our logs claiming that the vacation transport – or out of office auto replies didn’t work because of permission errors.

After changing folder and file permission to give full read, write, execute (0777) to everyone, it still generated errors.

dominic@domain.tld R=uservacation T=vacation_transport defer (13): Permission denied: Tainted '/home/dominic/.email-away.once.db' (once file for vacation_transport transport) not permitted
Continue reading
SonarQube — August 6, 2022
Components, props and emit events —

Components, props and emit events

One of the things that trips me up is writing Vue components and passing in parameters and returning results. It’s a one way process in the main. You can pass data into a component, but it doesn’t return anything unless you emit and event that returns something.

There are a few online tutorials that explain the use of props, and emit. This one I found useful:

https://learnvue.co/tutorials/vue-emit-guide

Passing data to a component is done using props. You specify the property to pass and the data it contains in the component tag, something like:

<MyComponent :myProp="this.myData" />

This creates the component and passed this.myData into the components props as myProp.

<script>
export default {
  props: {
    myProp: {
      type: Object,
      default: {},
  }
  ...
}
</script>

Now we have data in we can access myProp in any of the components function calls, etc.

Getting data back is done by way of an event. The component must emit an event and pass data to be consumed by the parent component that responds to the event.

Events are created on the component tag using an @ prefix, eg.

<MyComponent :myProp="this.myData" @myEvent="myFunction"

I must create myFunction in the parent component’s methods, and I can then call it from the child component. But, what I fail to realise each time, is that you aren’t calling a procedure as an emitted event. You are passing the function as an object parameter, or reference. Hence, there being no () in the @myEvent assignment. This is important to understand because it may look like things are working, but you will find you are not receiving the returning parameters.

In the child, call the event and pass parameters using:

this.$emit("myEvent", this.myReturn);

This will call the parent function myFunction and pass the child’s this.myReturn as the returning data. It can be consumed like this:

methods: {
  myFunction(args) {
    console.log("args: ", args);
  }
  ...
}

The main thing to take from this is DO NOT pass function calls to child components, pass a reference to the function, by not including the ().