Networking
The Linux kernel supports several packet-filtering mechanisms.
- Netfilter using the venerable iptables utility
- nftables subsystem, introduced with kernel 3.13 (2014), had been commonly assumed to eventually take the place of iptables. Firewall rules are implemented in an in-kernel VM.
- bpfilter
Netfilter is a software firewall and packet filtering framework introduced with Linux 2.4.0 (2001) and controlled by the iptables command.
Netfilter rules are stored in tables and in chains, and tables are associated with various chains.
By convention, table names are specified in lowercase and chain names in uppercase. Every packet starts at the top of a chain and is matched rule by rule. When a match is found the specified action, called the target, is triggered: i.e. "DROP" or "ACCEPT".
Tables | INPUT | OUTPUT | FORWARD | PREROUTING | POSTROUTING |
---|---|---|---|---|---|
filter | ✔️ | ✔️ | ✔️ | ||
nat | ✔️ | ✔️ | ✔️ | ||
mangle | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
raw | ✔️ | ✔️ |
There are five builtin netfilter chains, though user-defined chains are also possible:
- INPUT used for filtering incoming packets where the host itself is the destination packet.
- OUTPUT for outgoing packets, where the host is the source of the packet.
- FORWARD for filtering routed packets, where the host is router.
- PREROUTING used for DNAT or port forwarding
- POSTROUTING used for SNAT
Netfilter tables:
- filter default
- nat for SNAT and DNAT
- mangle for packet alteration
- raw used only to mark packets that should not be handled by the connection tracking system using the NOTRACK target
NetworkManager
NetworkManager provides a high-level interface for the configuration of network interfaces. It was developed by Red Hat and released in late 2004.
The config file format native to NetworkManager is the ini-format keyfile stored in /etc/NetworkManager/system-connections. These files define network interfaces, or connection profiles in NetworkManager's terminology.
nmcli
-
Control NetworkManager and report network status
Display devices and statuses
nmcli device status
Display information on interfaces as well as status Including other network connections not managed by network manager ("unmanaged") or not connected ("unavailable")
nmcli dev status
Display what connections are enabled
nmcli general status
Display UUIDs associated with network connections
nmcli connection show --active
Display much more information on network devices
nmcli device show
Configure settings for network interface {ens01} via interactive shell
nmcli connection edit ens01
List all connections NetworkManager has
nmcli connection show
Show settings for network interface {ens01}
nmcli device show ens01
Show status for all devices
nmcli device status
Display currently configured hostname
nmcli general hostname
Set hostname to {hostname}
nmcli general hostname hostname
Show overall status of NetworkManager
nmcli general status
Migrate a connection profilenmcli connection migrate eth0
nmtui
- nmtui is a curses-based TUI for control of NetworkManager.
dnf install NetworkManager-tui
Netplan
netplan is a utility for network configuration using YAML files that is the default network management tool used by recent versions of Ubuntu (since Ubuntu 17.10). Netplan is used as the default network management tool (previously ifconfig and its config at /etc/network/interfaces was used).
Netplan supports two renderers or backends: NetworkManager and networkd.
Netplan configs are YAML format and placed in /etc/netplan. Ubuntu installations usually come with a single config in this location named 01-network-manage-all-yaml, but many configs can be created in subdirectories. These are processed in lexicographical order regardless of subdirectory (unless there are multiple files with the same name). If a boolean or scalar parameter is defined in more than one config, the last value is assumed. Values that are sequences are concatenated.
# Let NetworkManager manage all devices on this system
network:
version: 2
renderer: NetworkManager # (1)
- This may require the python3-networkmanager package to be installed first.
network:
version: 2
ethernets:
eth0:
addresses:
- 192.168.2.100/24
gateway4: 192.168.2.1
nameservers:
addresses:
- 192.168.1.1
search: []
netplan
-
The netplan utility can be used to load the on-disk configuration.
Reload configuration temporarilynetplan try
Tasks
Bridge
-
A bridge is used to unite two or more network segments, typically used to establish communication channels between VMs, containers, and the host.
Unlike the virtual bridge that Windows uses for WSL2 distributions, the bridge in Linux is strictly L2. That is, VMs connecting to the bridge are assigned IPs by the same DHCP server (i.e. the router) in the same subnet as that of the physical hosts. In Windows, the virtual bridge assigns an internal IP in a private range (usually 172.16.0.0/12), and connectivity to the host or the Internet has to be accomplished via NAT.
ip link add virbr0 type bridge # (1) ip link set virbr0 up
- The link can be deleted thus:
ip link delete virbr0
Adding an interface to the bridge is done by setting its master.
ip link set enp2s0f0 master virbr0 # (1)
- This can be undone as follows:
ip link set enp2s0f0 nomaster
The iproute2 bridge utility can be used to verify the command has taken effect:
bridge link
This may interrupt network connectivity. In this case, the IP address must be removed from the linked interface and assigned to the bridge
ip address delete 192.168.1.3 dev enp2s0f0 ip address add 192.168.1.3 dev virbr0
The default route in the routing table must also be amended. Note this is not the IP address of the interface but rather that of the gateway. Also note that this gateway must already have its own network segment defined. That is, in order for a default route to be defined at least one static route must also be defined, which is the gateway's own local subnet.
ip route delete default ip route add default via 192.168.1.1
- The link can be deleted thus:
Downloading files
-
Wget defaults to file operations in a way that is more natural for downloading.
wget $url
Curl depends on piping and defaults to STDOUT in a manner similar to cat.
curl -O $url
Wireguard tunnel
-
dnf install wireguard-tools
apt install wireguard
Successful installation can be confirmed by running the following, which should produce no output (and no error) on success.
sudo modprobe wireguard
The first step in creating a Wireguard tunnel is to create a private key on each endpoint of the tunnel. The genkey subcommand creates a 44-character base64 encoded key ending in
=
which can be redirected to a file. If the file will be world-readable, the utility will ask you to change the umask.wg genkey # ▓▓░░░▓░▒▓▒▓▒░▓░▒░▓░▒▒░▓░▓░▒░▒▓▒▒▒░░▒▒░░░▒▒▓▓=
The public key can be generated by piping the private key from STDIN or from the file.
wg pubkey private > public wg genkey | tee private | wg pubkey > public
Then a Wireguard interface is created, typically named wg0, using network management utilities.
ip link add wg0 type wireguard
An IP address is assigned to that interface, to be used within the tunnel:
ip addr add 10.0.0.1/24 dev wg0
Now the private key is associated with the interface:
wg set wg0 private-key ~/.config/wireguard/private
Finally, the interface is brought up:
ip link set wg0 up
The public key of the peer is now associated with the Wireguard interface and the public IP and port of the other endpoint are specified.
wg set wg0 peer $PUBKEY allowed-ips 10.0.0.2/32 endpoint $IP
The tunnel is dismantled by removing the interface.
ip link delete wg0
Alternatively, many of these steps can be consolidated into creating a config for the Wireguard interface at /etc/wireguard/wg0.conf with the following contents:
[Interface] PrivateKey = ▓▓░░░▓░▒▓▒▓▒░▓░▒░▓░▒▒░▓░▓░▒░▒▓▒▒▒░░▒▒░░░▒▒▓▓= Address = 10.0.0.1/24 PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE ListenPort = 51820 [Peer] PublicKey = ▓▒▓▒▓▓░▓▒▒░░▒▒▒▓▒░▒▓▒░▒▒▓▒░▒░░░░▒░▒▒▒░░▒▒▓░▒= AllowedIps = 10.0.0.2/32 Endpoint = 123.45.67.89:51820
Then to bring it up quickly:
wg-quick up wg0
The same utility can be used to teardown the tunnel
wg-quick down wg0
Static IP
-
Static IP configuration varies by the network management toolset and backend presenton a system. Ubuntu systems use Netplan whereas other distributions most commonly use Network Manager.
network: version: 2 ethernets: eth0: addresses: - 192.168.2.100/24 gateway4: 192.168.2.1 nameservers: addresses: - 192.168.1.1 search: []
[connection] id=Ethernet uuid=abcdef01-2345-6789-0abc-def012345678 type=ethernet interface-name=eth0 [ethernet] [ipv4] address1=192.168.2.100/24,192.168.2.1 dns=10.40.7.2 method=manual [ipv6] addr-gen-mode=stable-privacy method=auto
Setting a static IP address on Red Hat distributions could involve multiple methods:
- nmcli commands
- NetworkManager keyfiles
- ifcfg files (prior to distributions downstream to Fedora 36)
Commands
curl
-
Accept a self-signed certificate by skipping verification
curl -k https://192.168.1.10
Use the
dict
network protocol to retrieve the definition of a word. refSending a POST method to a FastAPI app (src)curl dict://dict.org/d:<word>
curl -X POST "http://127.0.0.1:8000/purchase/item/" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\":\"sample item\",\"info\":\"This is info for the item\",\"price\":40,\"qty\":2}"
firewall-cmd
-
Frontend to Netfilter in Red Hat distributions.
firewall-cmd --state # "running"
Firewalld has a runtime configuration and a saved, persistent configuration. Only the runtime configuration will be consulted for any command, unless the persistent configuration is specified with --permanent.
The runtime configuration can be saved with this command, which obviates the need to execute every change twice.
firewall-cmd --runtime-to-permanent
Alternatively, the persistent configuration can be loaded into memory:
firewall-cmd --reload
Display firewall rulesfirewall-cmd --list-all --permanent
Firewalld uses zones to define the level of trust for network connections. A connection can only be part of one zone, but a zone can be used for many network connections. Builtin zones have XML-format configs found in /usr/lib/firewalld/zones.
firewall-cmd --get-active-zones # Display active zones along with interfaces firewall-cmd --info-zone=public # Inspect zone firewall-cmd --new-zone=testlab # Create new zone
Firewalld rules are generally managed through builtin services. These bundle network settings together for well-known applications like SSH, etc. Builtin services are also XML-format configs found in /usr/lib/firewalld/services.
Servicesfirewall-cmd --list-services firewall-cmd --add-service=http firewall-cmd --remove-service=http
Firewalld's config file is at /etc/firewalld/firewalld.conf
/etc/firewalld/firewalld.confAllowZoneDrifting=no
Since RHEL 8, firewalld's backend has been changed to nftables.
/etc/firewalld/firewalld.confFirewallBackend=nftables
ip
-
ip address
ip address add 192.168.2.2 dev eth0
ip route# Add static route (this is sometimes done automatically by the system after adding an address) ip route add 192.168.2.0/24 dev eth0 # Add default route ip route add default via 192.168.2.1 dev eth0
ip link# Create new links ip link add virbr0 type bridge ip link add wg0 type wireguard # Listen for netlink messages ip monitor # Change the default gateway to 192.168.1.1 on eth0 ip route change default via 192.168.1.1 dev eth0 # Bring interface up" ip link set wlp2s0 up
ip neighbor# Display ARP cache ip neighbor show # Delete ARP entry ip neighbor delete $IP_ADDR dev eth0
ip netnsip netns # (1) # We can create a network namespace then add two virtual Ethernet interfaces. # These are **peers**, meaning they are linked together as if connected to the same switch. ip netns add netns0 ip link add veth0 type veth peer name veth1 netns netns0 # We can then run a command in the **context** of a namespace. Without providing a context, # the default namespace is used and we can display veth0 but not veth1. If there are no other # links in the namespace (which there shouldn't be) then the **number** of the interface's # peer appears in the link's name. By running a command in the context of the new namespace # we can display veth1. The interface number of the link it's paired with in the # default namespace also appears in this link's name. ip link show # "veth0@if2" ip netns exec netns0 ip link show # "veth1@if4" # Now we assign an address to the namespaced link and bring it up ip netns exec netns0 ip addr add 10.0.0.1/24 dev veth1 ip netns exec netns0 ip link set dev veth1 up # Pinging this IP from outside the namespace will not work because there is no route. # Adding an IP in the same subnet to veth0 creates the route. ip addr add 10.0.0.2/24 dev veth0 # The interface must be brought up, which automatically adds a route to the routing table. ip link set dev veth0 up
- Network namespaces are mounted to /var/run/netns
iptables
-
A frontend for the kernel-level netfilter service, similar to firewalld.
Rules are saved in a rulesfile which once may have been found at /etc/sysconfig/iptables, but this file does not exist on recent Fedora installations.
Display rules as written on disk
iptables --list-rules
Reload configuration file
iptables -F
Accept SSH traffic from a particular IP
iptables -A INPUT -p ssh -s 10.0.222.222 -j ACCEPT
Accept incoming TCP traffic to port 80
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
Change FORWARD chain policy
iptables -P FORWARD ACCEPT # (1)
- By default, the INPUT chain accepts incoming packets. However, this policy can be changed by specifying a DROP rule specification.
Allow incoming SSH connections only from a single IP address
iptables -A INPUT -p tcp --dport 22 -j DROP iptables -A INPUT -p tcp --dport 22 -s 1.2.3.4 -j ACCEPT
Do not respond to pings
iptables -t filter -A INPUT -p icmp -j DROP
netcat
-
The netcat utility allows testing of a host's ports, similar to ping, but more versatile because ping only uses the portless ICMP protocol. GNU and OpenBSD versions available
Connect to host on port 80
Scan portsnc example.com 80
nc -v -w 2 z 192.168.56.1 22
nc -v -w 2 z 192.168.56.1 22 80
nc -v -w 2 z 192.168.56.1 22-25
Transfer files between servers This example uses the
pv
utility to monitor progress.Create a command-line chat server# Run `nc` in listening mode (`-l` option) on port 3000 tar -zcf - debian-10.0.0-amd64-xfce-CD-1.iso | pv | nc -l -p 3000 -q 5 # On the receiving client, to obtain the file: nc 192.168.1.4 3000 | pv | tar -zxf -
Find a service running on port Obtain port banners (# Create chat server listening on port 5000 nc -l -vv -p 5000 # Launch a chat session on the other system nc 192.168.56.1 5000
-n
disables DNS lookup)Create stream sockets Create and listen on a UNIX-domain stream socketnc -v -n 192.168.56.110 80
Create a backdoor Netcat needs to listen on a chosen port (here 3001):nc -lU /var/tmp/mysocket & ss -lpn | grep "/var/tmp/"
-d
disables reading from stdin;-e
specifies the command to run on the target systemConnect to {port} at {host}nc -L -p 3001 -d -e cmd.exe
Netcat command that retrieves a webpagenc host port
nc host port get
nft
nft list ruleset nft list tables nft list table ip filter # display just the filter table nft flush ruleset
nmap
- Scan hosts from a text file
Identify a host's operating system
nmap -iL hosts.txt
Determine whether a host has a firewall enablednmap -A localhost.example.com
Scan a specified range of portsnmap -sA localhost.example.com
Perform a SYN TCP scan, stealthier than the TCP connect scannmap -p 10-300 localhost.example.com
Aggressive scannmap -sT localhost.example.com
Ping scan home network (not bothering with ports)nmap -A 192.168.1.0/24
Fast port scan using SYN packetsnmap -sn 192.168.1.0/24
Port scan using SYN ("synchronize") packet, first element of TCP handshakenmap -sS -F 192.168.1.0/24
Port scan using normal TCPnmap -sS 192.168.1.0/24
Port scan using UDPnmap -sT 192.168.1.0/24
Xmas scannmap -sU 192.168.1.0/24
Scan a range of IPs [ref][Sec+ Lab]nmap -sX
Identify operating system and scan ports using TCP SYN packets [ref][Sec+ Lab]nmap 192.168.27.0/24 > hosts.txt
nmap -O -sS 192.168.27.0/24 > hosts.txt
tcpdump
-
Inspect actual IP packets
Display all network data
Set snapshot length of capture (default: 65,535B)tcpdump -i eth0
tcpdump -s
ufw
-
Program for managing a Netfilter firewall.
Allow traffic associated with various services
ufw allow ssh ufw allow http ufw allow https
wg
-
This is the main CLI frontend for Wireguard, the UDP-based tunneling protocol and application that was introduced with kernel 5.6.
dnf install wireguard-tools
apt install wireguard
wget
- Accept a self-signed certificate by skipping verification
wget --no-check-certificate $URL
Glossary
eBPF
-
eBPF is an extended version of the Berkeley Packet Filter (BPF). It is a sandboxed environment that allows code to be inserted into the running kernel. Kernel functionality must normally be extended by building an entirely new kernel with custom modules or upstream patching of the Linux kernel.
eBPF's architecture includes a JIT compiler that compiles the program's generic bytecode, which means eBPF programs run as efficiently as natively compiled kernel code.
eBPF programs can be bound to kernel events, such as receipt of a packet from the NIC.
bpftool is a core eBPF CLI tool.
bpftool prog # Display running eBPF programs bpftool map show # Display maps
ifcfg
-
Historically, ifcfg (interface configuration) files were ini-format files found in /etc/sysconfig/network-scripts/ in Red Hat distributions. They were used to control network interfaces on the legacy "network" service, now part of the network-scripts package, which included the sysconfig.txt file which documents the ifcfg file format.
After the introduction of NetworkManager, this format survived and was expanded with new directives specific to NetworkManager.
By convention, the string value of the DEVICE directive was the suffix of the filename itself.
ifcfg-eth0DEVICE=eth0 BOOTPROTO=dhcp ONBOOT=yes TYPE=Ethernet
The nmcli utility exposes a command that can change the configuration backend from ifcfg to a NetworkManager keyfile.
Migrate a connection profilenmcli connection migrate eth0
Ifcfg file support was finally removed in RHEL 9 and Fedora 36. If no ifcfg files are present, the configuration backend that supports them can be removed.
dnf remove NetworkManager-initscripts-ifcfg-rh
Netfilter
- Netfilter is a software firewall and packet filtering framework introduced with Linux 2.4.0 (2001) and controlled by the iptables command.