Although Ansible provides support for managing firewall rules via module, I still find initial setup is best done with a tested batch of firewall rules instead of adding them one-by-one. Since I’m migrating CentOS 7 servers to CentOS 8 now, I decided to convert iptables into nftables.
Will probably post a Unix Tutorial Project about this, but today I’m just capturing notes.
What is nftables?
nftables is the next (current) generation of NetFilter based firewall solutions, replacing iptables and providing backward compatible tools with iptables syntax.
If all you used before is iptables, you can continue using familiar commands – but in CentOS 8 this means that on the firewall level there’s no longer iptables running, all the functionality is provided by NFT.
IMPORTANT: make sure you put this into some nft-rules.txt file outside of the /etc/sysconfig location – if things go wrong, you’ll just reboot server via hosting console and regain access.
Try/Check NFT Ruleset
Now comes the moment to disable iptables and try NFT tables in their place.
I did the following: flushed IPtables (removed any rules) and then applied NFT rules.
Flush iptables
# iptables -F
Apply NFT rules from nft-rules.txt file
# nft -f nft-rules.txt
We can now have a look at the list of active NFT rules:
# nft list ruleset
Configure nftables Rules to Apply upon Reboot
Assuming everything works as expected, we can now move the nfs-rules.txt file into default location that will be used by NFT upon reboot:
# mv nft-rules.txt /etc/sysconfig/nftables.conf
Make sure it belongs to root and has correct permissions (it’s not a script so needs no execution bits):
root@s1:~ # ls -lad /etc/sysconfig/nftables.conf -rw-------. 1 root root 5227 Mar 12 01:48 /etc/sysconfig/nftables.conf
I was researching SSH daemon configuration on my macOS Catalina system and realised that lsof is still the best tool for meaningfully confirming network ports that are LISTENed to.
What does it mean for port to LISTEN?
All the network services in Linux (and Windows, actually) operating systems start with the same basic pattern: some process is managing incoming network connections.
Nowadays most of network services are directly managing their own network connections – meaning service like SSH daemon or Apache web server are made available via main process (sshd or httpd in my examples) constantly running and waiting for incoming network connections on specific port. For SSH server, default port is 22. For web servers, default ports are 80 and 443.
When we say a port is LISTENing, it means there’s a process running on your system that’s monitoring this specific port. SSH is therefore listening on/for port 22, Apache (httpd) is listening for port 80 and possibly 443.
Meaningful TCP ports reporting vs Default
You may remember that netstat command shows network ports as well, but its implementations are sometimes limited to just confirming that a certain port is listened to, without helping us understand what process is doing that port listening:
That’s why I prefer the lsof tool – it’s reporting processes information, which means any output you get is bound to contain processes numbers (PIDs) and most likely process names (binary names like sshd or httpd).
Use lsof to show listening TCP ports
lsof command has specific options for reporting processes with network activity: -iTCP will report TCP specific information, and -sTCP:LISTEN qualifier will filter just the processes that are listening for incoming connections on TCP ports (rather than client processes that only initiate outgoing network connections).
Don’t Forget to run lsof with sudo!
Normally lsof is super useful even with standard user privileges, but since I’m investigating a system service (SSH server), I have to run lsof as root. Otherwise lsof will report a list of network services, but hide the ones running above your standard user privilege level.
On modern Linux servers, lsof without sudo won’t show me anything:
greys@s2:~ $ lsof -iTCP -sTCP:LISTEN greys@s2:~ $
My complete command to list all the services listening for incoming TCP connections in will therefore look like this (this is the macOS example):
IMPORTANT: Note that because SSH is a standard service, lsof reports its name (ssh) rather than port number (22) in the last column of output. TCP *:ssh means process is listening for TCP port for SSH service.
I was expecting sshd, actually. But turns out remote access via SSH is managed by launchd process in recent macOS versions. Once someone logs in though, you’ll see sshd process spun up to manage the connection.
That’s it for today, hope you learned something new!
Standard command like hostname will still work in macOS, but perhaps it’s best to use the native way of updating system information on your Mac? scutil command is here to help.
Attach Interface to Specific Firewall Zone in RHEL 8
One of the first things I had to do on my recently built RHEL 8 PC was to move the primary network interface from public (default) zone to home zone – to make sure any firewall ports I open stay private enough.
How To List Which Zones and Interfaces are Active
Using the get-active-zones option of the firewall-cmd command, it’s possible to confirm where eno1 interface is at the moment. It’s already in the home zone cause I made the update earlier:
Don’t forget that after confirming a working firewall configuration, you need to re-run the same command with permanent option – this will update necessary files to make sure your firewall changes can survive a reboot:
root@redhat:~ # firewall-cmd --zone=home --change-interface=eno1 --permanent
The interface is under control of NetworkManager, setting zone to 'home'.
success
That’s it for today. Am really enjoying RHEL 8 configuration and still have this feeling I barely scratch the surface with all the new improvements this Red Hat Enterprise Linux brings.
I’m fascinated by the improvements and new features in RHEL 8, plus it’s a primary distro used in most corporate environments – so expect to quite a number of posts related to it in the nearest future.
The default interface for managing firewalls in RHEL 8 is firewalld and specifically firewall-cmd command.
Show Active Zones in RHEL 8
There’s a concept of zones – security domains – in RHEL 8 firewalls. You assign each of available network interfaces on your Red Hat Enterprise Linux system to one or more of these domains.
That’s why the first step is to confirm these zones, to see which ones are actively managing access for each network device:
root@rhel8:~ # firewall-cmd --get-active-zones home interfaces: enp2s0 libvirt interfaces: virbr0
List All Rules for Firewall Zone in RHEL 8
I’m interested in the primary physical network interface – enp2s0. It belongs to the home zone as per previous command, so that’s the zone we’ll list all the rules fore:
root@rhel8:~ # firewall-cmd --list-all --zone=home
home (active)
target: default
icmp-block-inversion: no
interfaces: enp2s0
sources:
services: cockpit dhcpv6-client mdns samba-client ssh
ports: 5901/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
From the output below, I have highlighted additionally enabled ports – 5901 is the one for VNC client that allows me to access graphics desktop session on my RHEL 8 PC remotely.
That’s it for today! Thanks for stopping by and talk soon!
I’ve actually written about ifconfig not found before, but noticed recently another possible scenario so will mention it today.
Make Sure Net-Tools Package is Installed
This is still the most common reason for your shell not finding the ifconfig command: it’s just not installed by default. So install it using apt command:
$ apt install net-tools
Call ifconfig Using Full Path
This is the thing I noticed on my Debian VM earlier today: your regular user may not have /sbin directory in its PATH. Which means ifconfig command will still not work if you just type the command name:
greys@debian9:~$ ifconfig -bash: ifconfig: command not found You have new mail in /var/mail/greys
But if you type the full path to the command, it will work:
Edit the .profile file in your home directory. For me it’s /home/greys/.profile.
Somewhere towards the end of it there should be a PATH variable updates section, on my VM it includes linuxbrew that I installed recently:
set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
PATH=$PATH:/home/greys/.linuxbrew/bin
eval $(/home/greys/.linuxbrew/bin/brew shellenv)
We need to update this section. And if there isn’t one, just create another one at the end of the file. Both changes should aim to add /sbin directory to the PATH variable.
Update the file:
PATH=$PATH:/home/greys/.linuxbrew/bin
… with this:
PATH=$PATH:/home/greys/.linuxbrew/bin:/sbin
… or create new one:
PATH=$PATH:/sbin
Save the file and read it again to test:
greys@debian9:~$ source .profile /home/greys/.linuxbrew/Homebrew/Library/Homebrew/brew.sh: line 4: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory
Even after a few years of blogging I still manage to find must-have and must-know commands that I barely mentioned here. nslookup is one such command – it’s an indispensable network troubleshooting tool when it comes to troubleshooting DNS issues.
Even after a few years of blogging I still manage to find must-have and must-know commands that I barely mentioned here. nslookup is one such command – it’s an indispensable network troubleshooting tool when it comes to troubleshooting DNS issues.
Get IP address for a Hostname
This is the most common nslookup command usage: you know a hostname or a domain name, and you want to get an IP address.
This is the opposite of the previous step, but it’s not always returning the opposite result. You see, if your domain name points to an IP address this IP address is not always pointing back to your domain:
When something about DNS resolution doesn’t make sense, I usually go back to basics: confirm the actual Name Servers that provide name resolution for the hostname or domain name.
For this, we need to make nslookup query specifically the NS records for a given hostname:
The output confirms that NS servers called alec and beth from Cloudflare are managing my unixtutorial.org domain.
Confirm Mail Servers for a Domain
Another really cool thing is that nslookup can get you MX recourds – they are pointing to the mail (SMTP) servers accepting emails on behalf of the domain:
This output confirms that my email is handled by Google, because I’m using the gSuite.
Query a Specific DNS Server Using nslookup
You may have noticed from examples that nslookup always reports my home office server (192.168.1.1) that it uses for making DNS queries.
Sometimes you want to know if other DNS servers resolve the name correctly, and so this example shows you how. Mind you, this must be either your local network (corporate) DNS server or a public NS server – otherwise your request may be rejected (because by default NS servers only resolve their own domains, not all the domains for the rest of the internet).
Here’s how I can resolve using Cloudflare’s public DNS service:
If you don’t have any other network services running on your Linux system, you probably don’t need portmapper running. Here are the steps to check and to disable portmap.
What portmapper does
Portm apper is a special Unix/Linux service that runs on networked systems that provide RPC (Remote Procedure Call) based services, like NFS.
Port mapper service is called portmapper and always runs on TCP and UDP ports 111.
IMPORTANT: back in 2015 portmapper was confirmed as vulnerable for Distributed Denial of Service attacks (DDoS) – so it’s considered a good practice to disable it or at least protect using firewall.
List RPC services
You can use rpcinfo command to list currently active RPC services on your system.
In my example below there’s nothing else running RPC, just the portmapper itself:
root@s5:~ # rpcinfo -p
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
Stop portmapper in CentOS 7
Somewhat confusing, the service providing portmapper functionality is always called rpcbind.
First, let’s stop the portmapper service:
root@s5:~ # systemctl stop rpcbind
Warning: Stopping rpcbind.service, but it can still be activated by:
rpcbind.socket
root@s5:~ # systemctl stop rpcbind.socket
Prevent portmapper from restarting upon reboot
Now, let’s make sure the service is also disabled:
I have a tiny server in home office, it used to be a Window 8 based entertainment box but I reinstalled it with Ubuntu 18.10 recently enough to run home automation. There has’t been any particular function assigned to this server but I have finally decided what role it will play: it will be an always-on Ubiquiti UniFi controller for my home office network!
My Ubuntu 18.10 server parameters
Like I said, it’s a fairly modest hardware and not a server grade at all. But thanks to 64-bit support (UEFI 32-bit boot though!) and low power consumtion, this is a perfect system for the always-on server:
Processor: Intel(R) Atom(TM) CPU Z3735F @ 1.33GHz – quad-core
RAM: 2GB 1333Mhz
Storage: internal 32GB flash storage
Operating System: custom Ubuntu 18.10 (64-bit OS but with 32-bit boot loader)
UniFi Network Management Controller
Ubiquiti have a few ranges of hardware, and I’m a big fan of the UniFi series of Software-Defined Networking (SDN) – very easy to setup and manager, plus you get quite a few updates via firmware, without having to change the hardware.
Network Management Controller is a piece of software or hardware that is running UniFi controller software that keeps track of all your UniFi devices and configurations. It has its own database for keeping track of settings and states and accepts network (browser or app) connections for remote management.
The mobile app for remote management is pretty cool.
UniFi Appliances I use in my Home Office
Ubiquiti Security Gateway (USG)
Wonderful little device for powerful traffic management, remote access (VPN) deployment and deep packet inspection (DPI) for visual understanding of how your network clients are consuming Internet traffic.
Ubiquiti UniFi Switch 8 60W (US-8-60W)
I have a number of switches like this, they’re great for building out a small office network and integrate with Network Management Console – meaning you see traffic and port status.
I also really like that this switch has 4 PoE (Power over Ethernet) ports, so you can plug in IP cameras and WiFi hotspots that support PoE – means you don’t need to run a separate power cable for them.
Installing UniFi Controller with installation scripts
Although there are official software repositories and RPM/DEB file downloads available from Ubiquiti, they’re kind of awkward to use: you still need to resolve software dependencies and preinstall a bunch of stuff.
So after a bit of researching online, I found that Glenn R from Ubiquiti’s community forums has prepared scripts for automatic installation of UniFi controller: UniFi Installation Scripts.
There’s a script available for the most recent Debian and Ubuntu builds, so if you want to install controller software on Ubuntu 16.04, Ubuntu 18.04, Ubuntu 18.10, Debian 8 or Debian 9 – there’s no better way that using one of these scripts.
Download the script for your controller version (5.9.x is the stable branch) and operating system
Make the downloaded script executable (chmod +x unifi-5.9.29.sh)
Execute the script as root
Enjoy! (browse to your server’s IP address and port 8443)
Here’s how my end result looks:
Do you use UniFi? Want to learn more about configuring or managing UniFi solutions? Let me know and I will wite a few follow-up posts.
Show Network Errors with netstat
netstat command is a mightly utility found in majority of Unix and Linux distributions.
Among other things like showing network routes and reporting network connections and ports, netstat can also report if your network interfaces have any trouble sending or receiving packets.
Report network errors with netstat
The basic format for this functionality is shown below:
greys@s5:~ $ netstat -ni
IMPORANT: always double-check the interface name you’re checking. I have highlighted the physical interface in my example, because it’s important: your virtual interfaces are unlikely to provide any useful network reliability info – so you always must be checking the primary, physical interfaces (or primary, virtual ones if you’re looking at a VM).
No errors in RX-ERR (receive errors) or TX-ERR (send errors), which is pretty impressive for a dedicated server that’s been online for a year: