First, add the table to /etc/iproute2/rt_tables
:
501 output
Set the default route of the table output
to go out through tap0
and make a rule such that all packets with mark 501
will use that route in the table output
:
ip route add default via 29.145.62.1 dev tap0 table output ip rule add fwmark 501 lookup output ip route flush cache
Mark all outgoing packets from port 9999
with mark 501
and NAT them to the local IP
:
iptables -t mangle -A PREROUTING -s 192.168.0.5 -p tcp --sport 9999 -j MARK --set-mark 501 iptables -t nat -A PREROUTING -i tap0 -p tcp --dport 9999 -j DNAT --to 192.168.0.5 # This is not needed if you masquerade: iptables -t nat -A POSTROUTING -o tap0 -j SNAT --to 29.145.62.1
TSO is meant for high-bandwidth networks and offloads the CPU workload by queueing up buffers and letting the network card split them into packets.
TSO can be enabled for a network card using:
ethtool -K eth0 tso on
and on Debian it can be enabled by editing /etc/network/interfaces
:
# The primary network interface allow-hotplug eth0 iface eth0 inet dhcp up sleep 5; ethtool -K eth0 tso on
My Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
.DWORD
named DisableLargeSendOffload
.
In simple terms, this reduces latency by allowing more packets to be sent during a TCP handshake. The initial congestion window size can be tuned when the interface goes up by creating a file in /etc/networking/if-up/
named iniconwin
containing the following:
#!/bin/sh -e ########################################################## ## (C) Wizardry and Steamworks 2014, license: GPLv3 ## ########################################################## # Do not bother to do anything if the interface does not # correspond to the interface for the default route. if [ "$IFACE" != eth0 ]; then exit 0 fi ip route change $(ip route show | grep '^default' | sed 's/initcwnd [0-9]+//' | sed 's/initrwnd [0-9]+//' ) initcwnd 12 initrwnd 12
The script assumes that the default interface is eth0
and the script will have to be adapted by changing eth0
to the default interface.
Assuming that you have wondershaper
installed and configured, the following TOS
rules using iptables
will help you prioritize traffic:
## ToS for table in OUTPUT PREROUTING; do # HTTP / HTTPS iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 80 -j TOS --set-tos Maximize-Throughput iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --sport 80 -j TOS --set-tos Maximize-Throughput iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 443 -j TOS --set-tos Maximize-Throughput iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --sport 443 -j TOS --set-tos Maximize-Throughput # DNS iptables -t mangle -A $table -p udp -m state --state NEW,ESTABLISHED,RELATED --dport 53 -j TOS --set-tos Minimize-Delay iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --sport 53 -j TOS --set-tos Minimize-Delay # SSH iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 22 -j TOS --set-tos Minimize-Delay iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --sport 22 -j TOS --set-tos Minimize-Delay # Samba iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 137 -j TOS --set-tos Maximize-Throughput iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --sport 138 -j TOS --set-tos Maximize-Throughput iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 139 -j TOS --set-tos Maximize-Throughput iptables -t mangle -A $table -p tcp -m state --state NEW,ESTABLISHED,RELATED --sport 445 -j TOS --set-tos Maximize-Throughput done
sysctl net.ipv4.tcp_available_congestion_control
The following formula can be used to calculate the txqueue
size using the BDP
rule:
where:
ping
).1500
MTU).The result can then be set under Linux with:
ifconfig <interface> txqueuelen <value>
Cnvert the IP
and the netmask
to a binary representation. For example, for the IP
address 192.168.1.101
we obtain 11000000 10101000 00000001 01100101
and for the netmask
255.255.255.224
we obtain 11111111 11111111 11111111 11100000
(the netmask
must be a sequential series of 1
s without any 0
gaps between the 1
s).
In order to obtain the first address, take the binary representation of the IP
and AND
it with the netmask
:
11000000 10101000 00000001 01100101 (IP) 11111111 11111111 11111111 11100000 (Netmask) ----------------------------------- AND 11000000 10101000 00000001 01100000 = 192.168.1.96 (first network address)
Then take the netmask
and invert the bits (NOT
) which will give you the size of the range:
11111111 11111111 11111111 11100000 (Netmask) ----------------------------------- NOT 00000000 00000000 00000000 00011111 = 31 addresses
Finally, the range for the IP
address 192.168.1.101
with subnet mask 255.255.255.224
is 31
addresses starting from 192.168.1.96
which gives the range: 192.168.1.96-192.168.1.127.127
.
CIDR | Range | Addresses | Description |
---|---|---|---|
10.0.0.0/8 | 10.0.0.0–10.255.255.255 | For private networks as described in RFC1918. | |
100.64.0.0/10 | 100.64.0.0–100.127.255.255 | ISP NAT RFC6598. | |
172.16.0.0/12 | 172.16.0.0–172.31.255.255 | For private networks as described in RFC1918. | |
192.0.0.0/29 | 192.0.0.0–192.0.0.7 | DS-Lite transition mechanism as specified by RFC6444. |
|
192.168.0.0/16 | 192.168.0.0–192.168.255.255 | For private networks as described in RFC1918. | |
198.18.0.0/15 | 198.18.0.0–198.19.255.255 | Inter-network communications between two separate subnets as specified in RFC2544. | |
fc00::/7 | fc00::–fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | Unique local address. |
or all in one line for a copy & paste:
10.0.0.0/8 100.64.0.0/10 172.16.0.0/12 192.0.0.0/29 192.168.0.0/16 198.18.0.0/15 fc00::/7
On Linux you can get the ring parameters with ethtool
. For example, for the eth0
interface:
ethtool -g eth0
which lists the pre-set maximums and the current settings:
Ring parameters for eth0: Pre-set maximums: RX: 1024 RX Mini: 255 RX Jumbo: 255 TX: 1024 Current hardware settings: RX: 512 RX Mini: 0 RX Jumbo: 128 TX: 512
You might observe that the pre-set maximums may not match the current settings, so they can be set using ethtool
:
ethtool -G eth0 rx 1024 rx-mini 255 rx-jumbo 255 tx 1024
This can be made permanent on distribution such as Debian by editing /etc/network/interfaces
:
allow-hotplug eth0 iface eth0 inet static up sleep 5; /sbin/ethtool -G eth0 rx 1024 rx-mini 255 rx-jumbo 255 tx 1024
and adding the up
directive which applies the setting on boot.
The following command can be used to connect to any host and port by using /dev/tcp
:
exec 7<>/dev/tcp/www.bing.com/80; cat <&7 & cat >&7; exec 7>&-
where:
www.bing.com
is the hostname to connect to80
is the destination port
The command uses exec
to set up a redirect to file descriptor 7
(can be any number), after which a redirect is launched from file descriptor 7
to STDOUT
and sent into the background (which causes the PID to be displayed) and then redirect STDIN
to the same descriptor with the second cat
. Finally, when cat
terminates (the connection is closed), the file descriptor is cleaned-up with exec
.
QUIC is a protocol that uses UDP instead of TCP to serve content, working on port 80 and 443 and used widely by Google, Youtube, etc… Unfortunately, UDP reveals the connecting address since it bypasses HTTP entirely. In order to disable QUIC you can add the following rules to your firewall:
iptables -A FORWARD -i br0 -p udp -m udp --dport 80 -j REJECT --reject-with icmp-port-unreachable iptables -A FORWARD -i br0 -p udp -m udp --dport 443 -j REJECT --reject-with icmp-port-unreachable iptables -A FORWARD -s 192.168.1.0/24 ! -d 192.168.1.1 -p tcp -m tcp --dport 80 -m state --state RELATED,ESTABLISHED -j DROP iptables -A FORWARD -s 192.168.1.0/24 ! -d 192.168.1.1 -p tcp -m tcp --dport 443 -m state --state RELATED,ESTABLISHED -j DROP
where:
192.168.1.0/24
is the network subnet.192.168.1.1
is the gateway.Additionally, you can have squid block alternate protocols by adding the following line:
# Disable alternate protocols request_header_access Alternate-Protocol deny all reply_header_access Alternate-Protocol deny all
to the squid configuration file.
squid will broadcast ICP requests and in order to disable them, edit the squid configuration file and add:
# disable ICP icp_port 0 icp_access deny all # plug ICP leaks reply_header_access X-Cache-Lookup deny !localnets reply_header_access X-Squid-Error deny !localnets reply_header_access X-Cache deny !localnets
where localness
is an ACL defined in your configuration file that should point to the local network.
Using portquiz a trick is to get nmap
to connect to portquiz.net on a port range:
nmap portquiz.net -p 1024-65535 -Pn --reason
where:
-p 1024-65535
is the port range between 1024
and 65535
-Pn
tells nmap
not to ping and just to connect–reason
will make nmap
explain why a port was considered closed
Either starting from a hostname, for instance tb1060.lon.100tb.com
by issuing:
nslookup tb1060.lon.100tb.com
to determine the IP address, or from the IP address itself (in this case, 146.185.28.59
), RADb can be used to determine an ISP's address block.
First, lookup the IP itself to determine which ISP it belongs to:
whois 146.185.28.59
Then, lookup the Autonomous System (AS) number (an ISP identifier code, if you will) of that ISP:
whois -h whois.radb.net 146.185.28.59 | grep ^origin
which should output:
origin: AS29302
There may be more AS numbers for small internet providers that are, in turn, customers of a larger network.
To make sure that the IP you are after is part of the AS, lookup the AS itself:
whois AS29302
and make sure that the ISP is listed.
The final step is to get all known routes for the AS:
whois -h whois.radb.net -- -i origin -T route AS29302 | grep ^route | awk '{ print $2 }'
which should output all IPv4 address blocks allocated to that ISP line-by-line (easy to automate):
146.185.16.0/20
IPv6 can also be queried in the same way:
whois -h whois.radb.net -- -i origin -T route6 AS29302 | grep ^route | awk '{ print $2 }'
and will yield similar results:
2a01:5a80::/32
A typical scenario of a non-working PXE server is a PXE server that has been set up on a Linux server running virtual machines that automatically join an STP-enabled network bridge once the virtual machine boots.
The phenomenon is due to STP itself that runs through various stages (Blocking
, Listening
, Learning
) before reaching the Forwarding
state. When the virtual machine adds its interface to the STP-enabled bridge, the bridge switches to the Learning
state, where, by default, the bridge spends at least 10 seconds (on Linux). For 10 seconds, the STP-enabled networking bridge will listen to packets and learn the new topology introduced by the addition of the interface. libvirt virtual machines run SeaBIOS as the default BIOS and, at version 1.12
, the PXE boot code does not wait sufficiently for the bridge to switch to the Forwarding
state and the network interface will not even be configured.
Cisco routers have a (nasty) hack named portfast
that can be set on a bridge that, when enabled, will skip over the Learning
stage of the bridge and commute directly into the Forwarding
state. Since the bridge will immediately forward packets, the issues with libvirt virtual machines should be resolved.
In order to resolve the issue, STP can be turned off for the entire bridge:
brctl stp br0 off
but that means losing the extra benefits of having the STP protocol.
Instead, and even better than Cisco portfast
, the forwarding delay can be lowered sufficiently for the SeaBIOS PXE boot code to obtain an IP address via DHCP:
brctl setfd br0 2
where:
2
is the number of seconds to spend in the Learning
state (default 10
seconds).
On Debian, in case the bridge is configured via /etc/network/interfaces
the following changes can be made to the bridge in order to make the forwarding delay permanent:
auto br0 iface br0 inet static ... # Enable STP bridge_stp on # Fix PXE with STP bridge_fd 2 ...
Zooko's triangle is a set of three properties where one rule is mutually exclusive with the other two that are generally considered desirable for names of participants on a network. The three properties are:
Examples:
nmap can be used to issue a DHCP request to a DHCP server in order to analyze what the DHCP server offers to clients. Issue:
nmap --script broadcast-dhcp-discover -e wlan1
in order to issue a DHCP DISCOVER message and request through the wlan1
network interface.
The expected output is similar to:
Starting Nmap 7.93 ( https://nmap.org ) at 2024-03-14 19:09 UTC Pre-scan script results: | broadcast-dhcp-discover: | Response 1 of 1: | Interface: wlan1 | IP Offered: 192.168.100.68 | DHCP Message Type: DHCPOFFER | Server Identifier: 192.168.100.1 | IP Address Lease Time: 1d00h00m00s | Renewal Time Value: 12h00m00s | Rebinding Time Value: 21h00m00s | Subnet Mask: 255.255.255.0 | Broadcast Address: 192.168.100.255 | Domain Name Server: 192.168.100.1 |_ Router: 192.168.100.1 WARNING: No targets were specified, so 0 hosts scanned. Nmap done: 0 IP addresses (0 hosts up) scanned in 11.31 seconds
The following script:
#!/usr/bin/env bash ########################################################################### ## Copyright (C) Wizardry and Steamworks 2020 - License: GNU GPLv3 ## ########################################################################### # Downloads Amazon AWS networks and adds all the ip blocks to an ipset. ## ########################################################################### `ipset list AMAZON-AWS 2>/dev/null >/dev/null` if [ $? = 1 ]; then ipset create AMAZON-AWS hash:net family inet fi ipset flush AMAZON-AWS for NETWORK in `curl -s https://ip-ranges.amazonaws.com/ip-ranges.json -o - | \ jq '.prefixes[] | .ip_prefix' | grep -P -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/[0-9]{0,2}'`; do ipset add AMAZON-AWS "$NETWORK" 2&>1 >/dev/null done
will process the AWS networks provided by Amazon and will generate an ipset to hold all the addresses using a network hash.
The TEE
extension from iptables
can be used to mirror a matching packet and sent it towards a different machine.
The following example will match TCP packets with the destination port set to 55435
and mirror the packets to 192.168.0.80
iptables -t mangle -A POSTROUTING -p tcp --dport 55435 -j TEE --gateway 192.168.0.80