Saturday, April 25, 2020
Configuring Persistent Bans with Fail2Ban
Someone gave me a network to put a Virtual Machine on, and I thought that network was a NAT. It wasn't. I was extremely lucky the VM did not get hacked. I immediately shut down the public facing interface, and installed FirewallD, allowing only key authentication through ssh.
That is NOT enough. In examining logs, this VM was getting pounded on all day, every day.
So, I took an extra measure of installing Fail2Ban. Initially, I configured a 24 hour jail time. But after seeing the same IPs come after the VM time and time again, I decided to reconfigure for a permanent ban.
To configure a permanent ban, I used -1 on the ban time (which in old days was in seconds, but they now accept the "365d", "52w", "1y" formats.
Now from there, things get more interesting. Wanting to get this configured quickly, I took the measures explained in this blog post for configuring Persistent Bans on Fail2Ban.
Configuring Persistent Bans with Fail2Ban
First, let's discuss what he assumes. He assumes, that you are configuring your jail to use iptables-multiport actions. Indeed, I have read (in another blog) that using the iptables-multiport actions might be a bit safer than using firewalld-multiport rules, even though you might be running FirewallD!
So that is exactly what I did. My jail.local file has a default ban of 52w. My ssh-specific rules use a -1 value on ban time (permanent ban), and use the iptables-multiport action rules.
I backed up this iptables-multiport file, and added a line on "action start" to loop through all of the hosts (ip addresses) in the /etc/fail2ban/persistent.bans file, and block them (refer to blog link above for specific rule). Then, on action ban, a simple print statement will echo the action of a permanent ban to a log file, so that we can see incrementally, who is banned.
Now later, I did check out the firewallcmd-multiport file, which would essentially attempt the same things that iptables-multiport does, except with firewall-cmd statements instead.
To do that, I would do the same thing. I would back up the firewallcmd-multiport file, and make the following changes.
1. The action to ban an IP is: firewall-cmd --direct --add-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>
So I would take this, and add in the actionstart section, a loop rule that looks like this:
cat /etc/fail2ban/persistent.bans | awk '/^fail2ban-<name>/ {print $2}' | while read IP; do \
firewall-cmd --direct --add-rule <family> filter f2b-<name> 0 -s <ip> -j <blocktype>; done
2. Then, I would add in the actionban section, the same print statement that resides in the iptables-multiport.conf file so that as new bands are added, they get logged:
echo "fail2ban-<name> <ip>" >> /etc/fail2ban/persistent.bans
Of course, a restart of fail2ban needs to be made for these to kick in, and this needs to be verified before you walk away after the change!
The only thing that has me wondering now, is that as the list of banned ips grows, your rules will grow, and this could have performance impacts on packet processing. But protecting your box is imperative, and should be the first priority! You could, if your list grows too long, periodically release some prisoners from jail, I suppose. And see if they behave, or perhaps maybe move on to better things.
Friday, April 10, 2020
VMWare Forged Transmits - and how it blocks Nested Virtualization
Nested Virtualization is probably never a good idea in general, but there are certain cases where you need it. We happened to be in one of those certain cases.
After creating a VM on VMWare (CentOS7), we installed libVirtD.
The first issue we ran into, was that nobody had checked a checkbox called "Expose Hardware Virtualization to GuestOS". As a result, we were able to install libVirtD and launch a nested VM, but when creating the VM with virt-install, it was generated to run in qemu-mode rather than kvm-mode.
We also needed to change the LibVirtD default storage pool to point to a volume, so that it had enough space to run a large qcow2 vendor-provided image.
After running virt-install, we were able to get a virtual machine up and running, and get to the console (we had to toy with serial console settings in virt-install to get this to work).
The adaptor in the nested VM was a host-bridge, and what we found, was that we could - from the nested VM - ping the CentOS7 host VM (and vice-versa). But we couldn't ping anything further than that. The LibVirtD VM, that was hosting the nested VM had no problem pinging anything; it could ping the VM is was hosting, it could ping the default gateway on the subnet, ping other hosts on the subnet, and it could ping out to the internet.
So, the
In doing some arp checks, we actually saw that the CentOS7 LibVirtD host had a populated arp table. But the tenant nested VM, only had a partially full arp table.
After pulling in some additional network expertise to work alongside us in troubleshooting, this one fellow sent in a link to a blog article about a security policy feature on VMWare vSwitches called Forged Transmits.
I will drop a link to that article, but also post the picture from that article, because the diagram so simply and perfectly describes what is happening.
https://wahlnetwork.com/2013/04/29/how-the-vmware-forged-transmits-security-policy-works/
Not being a VMWare Administrator, I don't know how enabling this works; if it is at the entire vSwitch level, or if it is at a port or port group level, etc.
But - if you ever plan on running nested virtualization on a VMWare Type 1 Hypervisor, this setting will kill you. Your networking won't work for your nested virtual machine, unless you can find some clever way of tunneling or using a proxy.
Wednesday, April 1, 2020
Enabling Jumbo Frames on Tenant Virtual Machines - Should We?
I went looking for answers as to why the tenants were enabled with only 1500 MTU. Which led to me looking into who was responsible for setting the MTU.
- OpenStack?
- Neutron?
- LibVirt?
- Contrail?
- something else?
Now - the big question. If we can set the MTU on virtual machines, should we? Just because you can, doesn't necessarily mean you should, right?
I set about looking into that. And I ran into some really interesting discussions (and slide decks) on this very topic, and some outright debates on it.
This link below, was pretty informative, I thought.
Discussion: What advantage does enabling Jumbo Frames provide?
Make sure you expand the discussion out with "Read More Comments! That is where the good stuff lies!"
He brings up considerations:
- Everything in front of you, including WAN Accelerators and Optimizers, would need to support the larger MTUs.
- Your target VM on the other side of the world, would need to support the larger MTU.
Unless you use MTU Path Discovery, and I read a lot of bad things about MTU-PD. - Your MTU setting in a VM, would need to consider any encapsulation that would be done to the frames - and Contrail, being a L3 VPN, does indeed encapsulate the packets.
- On any OpenStack compute host running Contrail, the Contrail vRouter already places the payload into 9000 MTU frames, to send over the transport network. Maybe making it not necessary to use jumbo frames at the VM level?
Monday, March 30, 2020
How to run OpenStack on a single server - using veth pair
I decided I wanted to implement OpenStack using OpenVSwitch. On one server.
The way I decided to do this, was to spin up a KVM virtual machine (VM) as an OpenStack controller, and have it communicate to the bare metal CentOS7 Linux host (that runs the KVM hypervisor libvirt/qemu).
I did not realize how difficult this would be, until I realized that OpenVSwitch cannot leverage Linux bridges (bridges on the host).
OpenVSwitch allows you to create, delete and otherwise manipulate bridges - but ONLY bridges that are under the control of OpenVSswitch. So, if you happen to have a bridge on the Linux host (we will call it br0), you cannot snap that bridge into OpenVSwitch.
What you would normally do, is to create a new bridge on OpenVSwitch (i.e. br-ex), and migrate your connections from br0, to br-ex.
That's all well and good - and straightforward, most of the time. But, if you want to run a virtual machine (i.e. an OpenStack Controller VM), and have that virtual machine communicate to OpenStack Compute processes running on the bare metal host, abandoning the host bridges becomes a problem.
Virt-Manager, does NOT know anything about OpenVSwitches, nor OpenVSwitch bridges that OpenVSwitch controls. So when you create your VM, if everything is under an OpenVSwitch bridge (i.e. br-ex), Virt-Manager will only provide you a series of macvtap interfaces (macvtap, and for that matter macvlan, are topics in and of themselves that we won't get into here).
So. I did not want to try and use macvtap interfaces - and jump through hoops to get that to communicate to the underlying host (yes, there are some tricks with macvlan that can do this presumably, but the rabbit hole was getting deeper).
As it turns out, "you can have your cake, and eat it too". You can create a Linux bridge (br0), and plumb that into OpenVSwitch with a veth pair. A veth pair is used just for this very purpose. It is essentially a virtual patch cable between two bridges, since you cannot join bridges (joining bridges is called cascading bridges, and this is not allowed in Linux Networking).
So here is what we wound up doing.
Monday, March 9, 2020
CPU Isolation - and how dangerous it can be
I didn't think too much about it.
THEN - when I finally DID start to look into it - I realized that the feature was not turned on.
CPU Pinning, as they were configuring it, was comprised of 3 parameters:
- cpu_isol - a Linux Kernel setting, passed into grub boot loader on grub command line.
- vcpu_pin_set - defined in nova.conf - an OpenStack configuration file
- reserved_host_cpus - defined in nova.conf - an OpenStack configuration file
Thursday, March 5, 2020
Mounting a Linux Volume over a File System - the bind mount trick
Logged into a VM today trying to help troubleshoot issues. There was nothing in /var/log! No Syslog!
Turns out that this phenomenon had occurred, where Linux will indeed let you mount on top of pretty much any directory, because after all, a directory is just a mount point as far as Linux is concerned.
But what happens to the files in original directory? I used to think they were lost. They're not. They're there, but shielded. They can be recovered, with a neat trick called a bind mount!
All described here! Learn something new every day.
A snippet of dialog from the link below:
https://unix.stackexchange.com/questions/198542/what-happens-when-you-mount-over-an-existing-folder-with-contents
Q. Right now /tmp
has some temporary files in it. When I mount my hard drive (/dev/sdc1
) on top of /tmp
, I can see the files on the hard drive. What happens to the actual content of /tmp
when my hard drive is mounted?
A. Pretty much nothing. They're just hidden from view, not reachable via normal filesystem traversal.
Q. Is it possible to perform r/w operations on the actual content of /tmp
while the hard drive is mounted?
A. Yes. Processes that had open file handles inside your "original" /tmp
will continue to be able to use them. You can also make the "reappear" somewhere else by bind-mounting /
elsewhere.
# mount -o bind / /somewhere/else
# ls /somewhere/else/tmp
Wednesday, January 1, 2020
Cloudify
First, someone gave me access to an instance. Without spending up-front time reading up on Cloudify, I always try to see if I can intuitively figure it out without reading anything.
Not the case with Cloudify.
I had to take some steps to "get into" Cloudify, and I will recap some of those.
1. I went to YouTube, and watched a couple of Videos.
This was somewhat valuable, but I felt this was "hands-on" technology. I knew I would need to install this in my home lab to get proficient with it; that was clear from watching the videos.
2. I logged onto a Cloudify Instance, and looked through the UI
I saw the Blueprints, but couldn't read any of the meta information. Finally I figured out that if I switched browsers, I could scroll down and see the descriptors.
3. Reading up on TOSCA - and Cloudify TOSCA specifically
In examining the descriptors, I realized they were Greek to me, and had to take a step back and read and learn. So I first started reading up on some of the TOSCA standards, and standards like these are tedious and frankly, quite boring after a while. But - as a result of doing this, I started to realize that Cloudify has extended the TOSCA descriptors. So, there is a degree of proprietary with regards to Cloudify, and in reading a few blogs, Cloudify "sorta kinda" follows the ETSI MANO standards, but in extending (and probably changing) some of the TOSCA YAML descriptors, they are going to create some vendor lock-in. They tout this as "value add", and "innovation" of course. Hey - that is how people try to make money with standards.
4. Finally, I decided to stick my toe in the water
I logged onto Cloudify Manager, and decided I would try the openstack-example-network.
It wouldn't upload, so I had to look into why. We had the v3.x version of the OpenStack Plugin, which requires a compat.xml file that was not loaded. In figuring this out, I realized we probably shouldn't even be using that version of the plugin since the plugin is supported on version 5.x of Cloudify Manager, and we were running version 4.6.
So, I uninstalled version 3.x of the OpenStack plugin. And tried to upload the sample example blueprint, and voila', success. I stopped there, because I wanted to see if I could create my own blueprint.
5. Created my own Blueprint
Our initial interest in a use case was not to deploy services per se, but to onboard new customers onto an OpenStack platform. So, I saw the palette in OpenStack Composer for the OpenStack Plugin v2.14.7, and it allowed you to create all kinds of OpenStack objects. I decided to put a User and a Project on the palette. I used some web documentation to learn about secrets (which were already created by a Cloudify Consultant who set up the system), and used those to configure the openstack_config items on the project and user. I then configured up the user and project sections.
- I saved the blueprint,
- validated the blueprint (no complaints from Composer on that),
- and then uploaded the blueprint to Cloudify Manager.
It is worth noting that I don't see any examples on the web of people trying to "onboard" an OpenStack tenant. Just about all examples are people instantiating some kind of VM on an already-configured OpenStack platform (tenants, users, projects, et al already created).
...Meanwhile, I spun up a new thread, and did some additional things:
AI / ML - Feature Engineering - Interaction Features
I added some new macro features to my model - credit card debt, credit card delinquency, and unemployment data. Some of these were VERY infl...

-
After finishing up my last project, I was asked to reverse engineer a bunch of work a departing developer had done on Kubernetes. Immediat...
-
Initially, I started to follow some instructions on installing Kubernetes that someone sent to me in an email. I had trouble with those, s...
-
I did some more work on Kubernetes. So the way Kubernetes was set up in here, was that SD-WAN traffic would be "routed" through...