Skip to content

Computer Networking

概觀

提供服務給應用程式的基礎架構

基本元素

從邊際到核心

==終端系統==(end system)

另一個名稱為主機(host) 桌電, 筆電, 手上的智慧型手機

==通訊連結==(communication links)

終端系統通往網路核心的實體物理媒介 例如: 同軸電纜, 銅線, 光纖和無線電頻譜

==封包交換器==(packet switches)

引路者, 知道封包從何而來並指引封包該前往何處 封包(packet)是電腦網路中的資訊封裝單位 主要有路由器(router), 鏈結層交換器(link-layer switch)

元素要如何溝通?

==協定== 協定定義了兩個以上的通訊實體之間 1. 交換訊息的格式和順序 2. 傳送接收訊息或發生其他事件時所要採取的動作

類別?屬性和操作

類比

車輛運輸網路,由高速公路、一般道路和交流道組成。車輛類似封包,高速公路、一般道路類似通訊連結,交流道類似封包交換器,建築物類似終端系統。

連線網路

將終端系統連結到邊際路由器(edge router)的連線方式 邊際路由器: end-to-end路徑上的第一個路由器

連線類型

家用連線

==撥接數據機==(dial-up modem) 透過一般的類比電話線連線到家用ISP 類比電話線為雙絞同心線

==DSL數位用戶專線==(digital subscriber line) 通常由電話公司提供, 也是在既存的雙絞電話線上運作 透過頻率分割的多工處理技術, 可同時接聽撥打電話和使用網際網路

上傳和下載至ISP路由器的速率是不對稱的, 下載 > 上傳

==HFC混合光纖同軸電纜==(hybrid fiber coaxial cable) 脫胎自目前播送有線電視所使用的電纜網路 使用纜線數據機(cable modem), 是一種共用的播送媒介

撥接數據機 DSL HFC
實體線路 類比電話線 類比電話線 同軸電纜
同時接聽撥打電話和使用網際網路 X V V

公司連線

==區域網路(Local area network)== 有多種區域網路的技術, 常用的是乙太網路技術, 乙太網路可分為共用式和交換式

無線連線

==無線區域網路==(wireless LAN) 可從半徑數十公尺內的基地台(無線存取連接點)傳輸和接收封包

==廣域無線連線網路==(wide-area wireless access networks) 提供使用者在基地台方圓數十公里內的無線網路連線

國際化域名

  • https://xn--fiq228c.xn--kpry57d/domain_name01.html
  • https://xn--fiq228c.xn--kpry57d/technology/punycode.htm

BGP

NAT

方向性 使用port

DNAT vs PAT DNAT: pool of available public IP addresses PAT: a single public IP address and multiplexes incoming and outgoing network traffic using port numbers.

dynamic NAT

dynamic NAT is a good choice when you need to allow outgoing connections from a network that has a limited number of public IP addresses.

static NAT

with static NAT, the NAT device uses a fixed one-to-one mapping between private and public IP addresses.

Port Address Translation (PAT)

Port Address Translation (PAT) is a type of Network Address Translation (NAT) that is used to map multiple private IP addresses to a single public IP address. It is also known as Network Address Port Translation (NAPT) or IP masquerading.

  • PAT works by using a single public IP address and multiplexing incoming and outgoing network traffic using port numbers.
  • It allows multiple devices on the private network to share a single public IP address and access the internet simultaneously.

Port forwarding

Port forwarding is a networking technique that is used to allow incoming internet connections to reach a specific device on a private network.

  • This allows external devices to connect to the device on the private network using its public IP address and the forwarded port number.

Under the hood

就是要你懂网络--一个网络包的旅程 | plantegg os先根據目標IP本機的route規則計算使用哪個interface(nic) input: target ip, route rule output: interface

if same subnet, arp protocol(arp cache)

if different subnet, ask the gateway, and gateway use its route rule and arp cache

one interface can support multiple ip address

VLAN

Unmanaged Switch managed Switch

Access port: 只有一個VLAN的port Trunk port: 多個VLAN的port

Trunk link

Route

what meas about "ip route" result

default via 167.22.10.1 dev enp33s0f0 proto static metric 101
167.22.0.0/16 dev enp33s0f0 proto kernel scope link src 167.22.0.15 metric 101
167.122.0.0/16 dev ib0 proto kernel scope link src 167.122.0.15 metric 105

The output you provided is the result of running the "ip route" command, which displays the current routing table on a Linux system. Here is a breakdown of each line of the output:

default via 167.22.10.1 dev enp33s0f0 proto static metric 101: This line represents the default route, which is used when a packet needs to be sent to a destination that is not covered by any other more specific route. In this case, the default gateway is 167.22.10.1, and the outgoing interface is enp33s0f0. The "proto" field indicates that this is a static route, which is configured manually rather than learned dynamically, and the "metric" field represents the cost of this route relative to other routes in the table.

167.22.0.0/16 dev enp33s0f0 proto kernel scope link src 167.22.0.15 metric 101: This line represents a directly connected network, meaning that the system is directly connected to a subnet with the specified address range. In this case, the network address is 167.22.0.0/16, the outgoing interface is enp33s0f0, and the "proto" field indicates that this is a kernel route, which is automatically generated by the system. The "scope" field indicates the visibility of the route, with "link" meaning that it is only visible within the local network segment. The "src" field specifies the source IP address to use when sending packets to this subnet, and the "metric" field represents the cost of this route relative to other routes in the table.

167.122.0.0/16 dev ib0 proto kernel scope link src 167.122.0.15 metric 105: This line is similar to the previous one, but it represents a different network that is connected to a different interface. Specifically, the network address is 167.122.0.0/16, the outgoing interface is ib0, and the "proto", "scope", "src", and "metric" fields have the same meanings as in the previous line.

how to debug route if connection is break

If you are experiencing a network connectivity issue and suspect that there might be a problem with your routing configuration, there are a few steps you can take to troubleshoot the issue. Here are some tips on how to debug your routing configuration:

Check the routing table: Use the "ip route" command to check the current routing table on your system. Verify that the routes in the table are correct and that there are no conflicting routes. Make sure that the default gateway is set correctly and that the routing table is up-to-date.

Ping the default gateway: Use the "ping" command to verify that you can reach the default gateway. If the ping fails, it could indicate a problem with the default gateway or the routing configuration.

Trace the route to the destination: Use the "traceroute" or "tracepath" command to trace the route to the destination. This will help you identify where the connection is being lost and whether there are any routing issues along the way.

Check the network topology: If you have access to the network topology, check it to make sure that there are no misconfigured devices or routing loops that could be causing the connectivity issue.

Check the firewall: Make sure that any firewalls or security policies are not blocking the traffic. Check the firewall logs to see if any traffic is being dropped or rejected.

Check the network interface: Verify that the network interface is up and running, and that it is configured correctly with the correct IP address, subnet mask, and gateway.

ip r
ip route get 172.19.51.6
ip route del 172.19.51.0/24 via 172.19.41.1

ip route add 192.168.2.0/24 via 192.168.1.2 dev eth0
ip route del 192.168.2.0/24
# To make it permanent, add it to /etc/network/interfaces (Debian) or /etc/sysconfig/network-scripts/route-eth0 (RHEL).

sudo arp-scan -I eth15 172.19.51.0/24
  1. Learn about IP routing and how packets move through a Linux system.
  2. Understand routing table concepts, including: Default gateway Static routes Dynamic routes Routing policies Sure! Let’s break these topics down step by step.

Linux Routing Basic by chatgpt


1. Learn About IP Routing and How Packets Move Through a Linux System

What is IP Routing?

IP routing is the process of determining the path that packets take from a source to a destination across a network. In Linux, the kernel makes these decisions based on the system’s routing table.

How Packets Move Through a Linux System

When a packet is sent from a Linux system, the following steps occur:

  1. Packet Creation
  2. A user-space application (e.g., ping, curl, or a web browser) generates a packet.
  3. The packet is passed to the transport layer (TCP/UDP) and then to the network layer (IP).

  4. Route Lookup

  5. The kernel checks the routing table to determine the appropriate next hop.
  6. If a matching route is found, the packet is forwarded to the corresponding network interface.
  7. If no route is found, the packet is dropped, and an error (e.g., "Network unreachable") is generated.

  8. Packet Forwarding (if applicable)

  9. If the system is configured as a router (net.ipv4.ip_forward=1), it forwards packets between interfaces.
  10. The packet may be NAT-ed (if applicable) before being sent out.

  11. Packet Transmission

  12. The packet is encapsulated into an Ethernet frame and transmitted over the network.

  13. Reply Handling

  14. If a reply is received, it follows the same path in reverse.

Routing Decision Example

  • Suppose a Linux machine with the IP 192.168.1.10/24 wants to send a packet to 8.8.8.8:
  • The system checks the routing table.
  • If there is a default gateway (192.168.1.1), the packet is sent to it.
  • The gateway forwards it to the next router until it reaches 8.8.8.8.

You can inspect this process using:

ip route get 8.8.8.8


2. Understand Routing Table Concepts

a) Default Gateway

  • The default gateway is the router that the system uses when no specific route is found for a destination.
  • It is defined as:
    ip route add default via 192.168.1.1 dev eth0
    
  • To view the current default route:
    ip route show | grep default
    
  • This tells the system, “If you don’t know where to send the packet, send it to 192.168.1.1.”

b) Static Routes

  • Static routes are manually defined routes that do not change unless modified by the admin.
  • Used for networks that are not reachable via the default gateway.
  • Example: Add a route to 192.168.2.0/24 via 192.168.1.2:
    ip route add 192.168.2.0/24 via 192.168.1.2 dev eth0
    
  • To delete a static route:
    ip route del 192.168.2.0/24
    
  • To make it permanent, add it to /etc/network/interfaces (Debian) or /etc/sysconfig/network-scripts/route-eth0 (RHEL).

c) Dynamic Routes

  • Dynamic routing is managed by routing protocols like:
  • OSPF (Open Shortest Path First)
  • BGP (Border Gateway Protocol)
  • RIP (Routing Information Protocol)
  • Instead of static routes, dynamic routing updates routes automatically based on network conditions.
  • Dynamic routing is configured using software like:
  • Quagga
  • FRRouting (FRR)
  • BIRD
  • Example: Using FRRouting (for OSPF)
    vtysh -c 'show ip route'
    

d) Routing Policies (Policy-Based Routing)

  • Policy-Based Routing (PBR) allows packets to be routed based on criteria other than just the destination IP.
  • Example: If you want traffic from 192.168.1.100 to use a different gateway (192.168.1.2), you can do:
    ip rule add from 192.168.1.100 table 100
    ip route add default via 192.168.1.2 table 100
    
  • View existing rules:
    ip rule show
    
  • Example use cases:
  • Different ISPs for different traffic types.
  • Specific traffic (e.g., VoIP) using a dedicated gateway.

Conclusion

  • IP routing controls how packets move in a Linux system.
  • Default gateway is the fallback route for unknown destinations.
  • Static routes are manually set and do not change dynamically.
  • Dynamic routes are automatically updated using routing protocols.
  • Policy-based routing enables advanced traffic control.

Would you like me to provide practical exercises or a lab setup for hands-on learning? 🚀

VPN

ARP

DNS

DNSSEC

bind

bind for Ubuntu Domain Name Service (DNS) | Ubuntu

/etc/bind/named.conf
/var/lib/bind/db*
/etc/resolv.conf

bind for Redhat Chapter 3. Install and Configure Bind9 | Red Hat Product Documentation

/etc/named.conf
/var/named
/etc/resolv.conf

Verify

named-checkconf /etc/named.conf
systemctl status named
rndc status
netstat -tap | grep named
netstat -tulpn | grep 53

rndc

nsupdate

CoreDNS

docker run -d --name coredns \
--restart=always \
--volume=/root/coredns:/root/ \
-p 53:53/udp \
coredns/coredns -conf /root/Corefile
/root/coredns/Corefile
.:53 {
    forward . 8.8.8.8 9.9.9.9
    log
    errors
}

foo.bar:53 {
    file /root/db.foo.bar
    log
    errors
}

/root/coredns/db.foo.bar

$ORIGIN foo.bar.
@       3600 IN SOA dns.foo.bar. mail.foo.bar. (
                                2024123016 ; serial
                                7200       ; refresh (2 hours)
                                3600       ; retry (1 hour)
                                1209600    ; expire (2 weeks)
                                3600       ; minimum (1 hour)
                                )

dns    IN  A   172.19.57.10
test   IN  A   172.19.57.10
beta-test IN  CNAME   test

dig @192.168.1.10  test.foo.bar
dig @192.168.1.10  beta-test.foo.bar

DHCP

wget https://ftp.isc.org/isc/dhcp/4.4.3-P1/dhcp-4.4.3-P1.tar.gz
tar xvf dhcp-4.4.3-P1.tar.gz
sudo apt-get install build-essential
cd dhcp-4.4.3-P1
./configure --prefix=/usr --sysconfdir=/etc/dhcp --enable-binary-leases
make
sudo make install
vim /etc/init.d/isc-dhcp-server
systemctl daemon-reload

/etc/init.d/isc-dhcp-server

#!/bin/sh

### BEGIN INIT INFO
# Provides:          isc-dhcp-server
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Should-Start:      $local_fs slapd $named
# Should-Stop:       $local_fs slapd
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: DHCP server
# Description:       Dynamic Host Configuration Protocol Server
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin

test -f /usr/sbin/dhcpd || exit 0

DHCPD_DEFAULT="${DHCPD_DEFAULT:-/etc/default/isc-dhcp-server}"

# It is not safe to start if we don't have a default configuration...
if [ ! -f "$DHCPD_DEFAULT" ]; then
        echo "$DHCPD_DEFAULT does not exist! - Aborting..."
        if [ "$DHCPD_DEFAULT" = "/etc/default/isc-dhcp-server" ]; then
                echo "Run 'dpkg-reconfigure isc-dhcp-server' to fix the problem."
        fi
        exit 0
fi

. /lib/lsb/init-functions

# Read init script configuration
[ -f "$DHCPD_DEFAULT" ] && . "$DHCPD_DEFAULT"

NAME4=dhcpd
NAME6=dhcpd6

DESC4="ISC DHCPv4 server"
DESC6="ISC DHCPv6 server"

# use already specified config file or fallback to defaults
DHCPDv4_CONF=${DHCPDv4_CONF:-/etc/dhcp/dhcpd.conf}
DHCPDv6_CONF=${DHCPDv6_CONF:-/etc/dhcp/dhcpd6.conf}

# try to read pid file name from config file or fallback to defaults
if [ -z "$DHCPDv4_PID" ]; then
        DHCPDv4_PID=$(sed -n -e 's/^[ \t]*pid-file-name[ \t]*"\(.*\)"[ \t]*;.*$/\1/p' < "$DHCPDv4_CONF" 2>/dev/null | head -n 1)
fi
if [ -z "$DHCPDv6_PID" ]; then
        DHCPDv6_PID=$(sed -n -e 's/^[ \t]*dhcpv6-pid-file-name[ \t]*"\(.*\)"[ \t]*;.*$/\1/p' < "$DHCPDv6_CONF" 2>/dev/null | head -n 1)
fi
DHCPDv4_PID="${DHCPDv4_PID:-/var/run/dhcpd.pid}"
DHCPDv6_PID="${DHCPDv6_PID:-/var/run/dhcpd6.pid}"

test_config()
{
        VERSION="$1"
        CONF="$2"

        if ! /usr/sbin/dhcpd -t $VERSION -q -cf "$CONF" > /dev/null 2>&1; then
                echo "dhcpd self-test failed. Please fix $CONF."
                echo "The error was: "
                /usr/sbin/dhcpd -t $VERSION -cf "$CONF"
                exit 1
        fi
}

check_status()
{
        OPTION="$1"
        PIDFILE="$2"
        NAME="$3"

        if [ ! -r "$PIDFILE" ]; then
                test "$OPTION" != -v || echo "$NAME is not running."
                return 3
        fi

        if read pid < "$PIDFILE" && ps -p "$pid" > /dev/null 2>&1; then
                test "$OPTION" != -v || echo "$NAME is running."
                return 0
        else
                test "$OPTION" != -v || echo "$NAME is not running but $PIDFILE exists."
                return 1
        fi
}

start_daemon()
{
        VERSION="$1"
        CONF="$2"
        NAME="$3"
        PIDFILE="$4"
        DESC="$5"

        shift 5
        INTERFACES="$*"

        test_config "$VERSION" "$CONF"
        log_daemon_msg "Starting $DESC" "$NAME"

        if [ -e "$PIDFILE" ]; then
                log_failure_msg "dhcpd service already running (pid file $PIDFILE currenty exists)"
                exit 1
        fi

        touch /var/lib/dhcp/$NAME.leases

        start-stop-daemon --start --quiet --pidfile $PIDFILE \
                --exec /usr/sbin/dhcpd -- $VERSION -q -cf $CONF $INTERFACES
        sleep 2

        if check_status -q $PIDFILE $NAME; then
                log_end_msg 0
        else
                log_failure_msg "check syslog for diagnostics."
                log_end_msg 1
                exit 1
        fi
}

stop_daemon()
{
        if check_status -q $DHCPDv4_PID $NAME4; then
                log_daemon_msg "Stopping $DESC4" "$NAME4"
                start-stop-daemon --stop --quiet --pidfile $DHCPDv4_PID
                log_end_msg $?
                rm -f "$DHCPDv4_PID"
        fi

        if check_status -q $DHCPDv6_PID $NAME6; then
                log_daemon_msg "Stopping $DESC6" "$NAME6"
                start-stop-daemon --stop --quiet --pidfile $DHCPDv6_PID
                log_end_msg $?
                rm -f "$DHCPDv6_PID"
        fi
}

case "$1" in
        start)
                if test -n "$INTERFACES" -a -z "$INTERFACESv4"; then
                        echo "DHCPv4 interfaces are no longer set by the INTERFACES variable in" >&2
                        echo "/etc/default/isc-dhcp-server.  Please use INTERFACESv4 instead." >&2
                        echo "Migrating automatically for now, but this will go away in the future." >&2
                        INTERFACESv4="$INTERFACES"
                fi
                if test -n "$INTERFACESv4"; then
                        echo "Launching IPv4 server only."
                        start_daemon "-4" "$DHCPDv4_CONF" "$NAME4" \
                                "$DHCPDv4_PID" "$DESC4" "$INTERFACESv4"
                fi
                if test -n "$INTERFACESv6"; then
                        echo "Launching IPv6 server only."
                        start_daemon "-6" "$DHCPDv6_CONF" "$NAME6" \
                                "$DHCPDv6_PID" "$DESC6" "$INTERFACESv6"
                fi
                if test -z "$INTERFACESv4" -a -z "$INTERFACESv6"; then
                        echo "Launching both IPv4 and IPv6 servers (please configure INTERFACES in /etc/default/isc-dhcp-server if you only want one or the other)."
                        start_daemon "-4" "$DHCPDv4_CONF" "$NAME4" \
                                "$DHCPDv4_PID" "$DESC4" ""
                        start_daemon "-6" "$DHCPDv6_CONF" "$NAME6" \
                                "$DHCPDv6_PID" "$DESC6" ""
                fi
                ;;
        stop)
                stop_daemon
                ;;
        restart | force-reload)
                $0 stop
                sleep 2
                $0 start
                if [ "$?" != "0" ]; then
                        exit 1
                fi
                ;;
        status)
                if test -n "$INTERFACES" -a -z "$INTERFACESv4"; then
                        INTERFACESv4="$INTERFACES"
                fi
                if test -n "$INTERFACESv4"; then
                        echo -n "Status of $DESC4: "
                        check_status -v $DHCPDv4_PID $NAME4 || exit $?
                fi
                if test -n "$INTERFACESv6"; then
                        echo -n "Status of $DESC6: "
                        check_status -v $DHCPDv6_PID $NAME6 || exit $?
                fi
                ;;
        *)
                echo "Usage: $0 {start|stop|restart|force-reload|status}"
                exit 1
esac

exit 0

/etc/dhcp/dhcpd.conf

lease-file-name "/var/lib/dhcp/dhcpd.leases";
option client-architecture code 93 = unsigned integer 16;


shared-network ens160 {
    subnet 192.168.1.0 netmask 255.255.255.0 {
        max-lease-time 43200;
        min-lease-time 43200;
        default-lease-time 43200;
        range 192.168.1.100 192.168.1.200;
        option routers 192.168.1.1;
        option subnet-mask 255.255.255.0;
        option domain-name-servers 8.8.8.8;
        option domain-name "yourdomain.local";

        next-server 192.168.1.10;  # IP of your PXE server

        if option client-architecture = 00:07 {
           filename "mboot.efi";
        }
        else if option client-architecture = 00:09 {
           filename "mboot.efi";
        }
    }
}

/etc/default/isc-dhcp-server

# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server)

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
DHCPDv4_CONF=/etc/dhcp/dhcpd.conf
#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
DHCPDv4_PID=/var/run/dhcpd.pid
#DHCPDv6_PID=/var/run/dhcpd6.pid

# Additional options to start dhcpd with.
#       Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
#INTERFACESv4="ens160"
INTERFACESv4="ens160"

# Ubunut isc-dhcp-server service
dhcp-lease-list

ls -la /var/lib/dhcp/dhcpd.leases
wget https://sources.debian.org/data/main/i/isc-dhcp/4.4.3-P1-5/contrib/dhcp-lease-list.pl
chmod +x dhcp-lease-list.pl
./dhcp-lease-list.pl --parsable
/var/lib/dhcpd/dhcpd.leases
/etc/dhcp/dhcpd.conf

detect dhcp server in the subnet

sudo tcpdump -i <interface> port 67 or port 68 -n

14:04:36.123456 IP 192.168.1.1.67 > 192.168.1.100.68: BOOTP/DHCP, Reply, length 300
192.168.1.1 is the dhcp server

release and renew

# release and renew
ip link set <interface> down && ip link set <interface> up

OR

# release and renew
dhclient -r <interface> && dhclient <interface>

Configure Linux as a Router

(optional) If this parameter is disabled (0)

/etc/sysctl.conf

net.ipv4.ip_forward = 1

apply the changes

sysctl -p

  1. check the iptable eno1 is the interface to internet eno3 is the interface to intranet

if using the firewalld - Named and firewalld - Fedora Discussion

firewall-cmd --get-active-zones
firewall-cmd --change-interface=eno1 --zone=external
firewall-cmd --change-interface=eno3 --zone=internal
firewall-cmd --add-service=dns --zone=internal
firewall-cmd --list-all --zone=external
firewall-cmd --list-all --zone=internal

(optional: using iptables directly) => not complete for dns query

iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE
iptables -A FORWARD -i eno1 -o eno3 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eno3 -o eno1 -j ACCEPT

Add direct rules to firewalld. Add the --permanent option to keep these rules across restarts.

firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -o eno1 -j MASQUERADE
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i eno3 -o eno1 -j ACCEPT
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i eno1 -o eno3 -m state --state RELATED,ESTABLISHED -j ACCEPT

  1. DNS cache-only and forward /etc/named.conf
options {
        listen-on port 53 { any; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        secroots-file   "/var/named/data/named.secroots";
        recursing-file  "/var/named/data/named.recursing";
        allow-query     { 167.23.0.0/16; };

        /*
         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
         - If you are building a RECURSIVE (caching) DNS server, you need to enable
           recursion.
         - If your recursive DNS server has a public IP address, you MUST enable access
           control to limit queries to your legitimate users. Failing to do so will
           cause your server to become part of large scale DNS amplification
           attacks. Implementing BCP38 within your network would greatly
           reduce such attack surface
        */
        recursion yes;
        forward only ;
        forwarders {
         8.8.8.8;
        };

        dnssec-enable yes;
        dnssec-validation yes;

        managed-keys-directory "/var/named/dynamic";

        pid-file "/run/named/named.pid";
        session-keyfile "/run/named/session.key";

        /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */
        include "/etc/crypto-policies/back-ends/bind.config";
};

logging {
        channel default_debug {
                file "data/named.run";
                severity dynamic;
        };
};

zone "." IN {
        type hint;
        file "named.ca";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

Troubshooting for connection problems

ip link show
sudo mii-tool -v eno7

"LOWER_UP" means the cable is plugged in and has physical link

NO-CARRIER

Linux's network stack uses the NO CARRIER status for a network interface that is turned on ("up") but cannot be connected because the physical layer is not operating properly, e.g. because an ethernet cable is not plugged in.

linkdown from ip route

Cisco Nexus 9000 Series

Proxy

Squid + System Proxy config

export http_proxy="
http://10.199.19.1:3128"
export https_proxy="
http://10.199.19.1:3128"
/etc/squid/conf.d
/etc/squid/conf.d/debian.conf

apt

/etc/apt/apt.conf.d/99proxy

Acquire::http::Proxy "http://10.199.19.1:3128";

SSH Tunnel(SOCKS Proxy) + Broser Proxy config

ssh -N -D 9090 {user}@{bastion server}

run in the background

ssh -D 9090 -q -C -N -f {user}@{bastion server}

# in linux
ps aux | grep 'ssh -D'
kill {pid}

# in windows
tasklist | findstr ssh
taskkill /F /pid {pid}

windows chrome

命令提示字元

cd C:\Program Files\Google\Chrome\Application
chrome.exe --user-data-dir="%USERPROFILE%\proxy-profile" --proxy-server="socks4://localhost:9090"

windows edge

命令提示字元

cd "C:\Program Files (x86)\Microsoft\Edge\Application"
msedge.exe  --user-data-dir="%USERPROFILE%\edge-proxy-profile" --proxy-server="socks4://localhost:9090"

windows firefox

apt

in the machine which in the private subnet and without internet /etc/apt/apt.conf.d/99proxy

Acquire::http::Proxy "socks5h://127.0.0.1:9090";
Acquire::https::Proxy "socks5h://127.0.0.1:9090";
Acquire::socks::proxy "socks5h://127.0.0.1:9090";

MTU

After trial and error, I found the MTU config will impact the bandwidth

Case 1-1:
d23cn001 mtu: 9000
d23is168 mtu: 9000
d23en007-p38 mtu: 1500
d23en007-p39 mtu: 1500

r12 d23is168 => d23en007-p38 => d23en007-p39 => r12 d23cn001 Speed Weird 0 byte


Case 1-2:
d23cn001 mtu: 9000
d23is010 mtu: 1500
d23en007-p38 mtu: 1500
d23en007-p39 mtu: 1500

r1 d23is010 => d23en003-p10 => d23en007-p39 => r12 d23cn001 Speed OK


Case 1-3:
d23cn001 mtu: 1500
d23is010 mtu: 1500
d23en007-p35 mtu: 1500
d23en007-p37 mtu: 1500

r12 d23is165 => d23en007-p35 => d23en007-p37 => r12 d23is167 Speed OK


Case 2-1:
d23cn001 mtu: 9000
d23is168 mtu: 9000
d23en007-p38 mtu: 9000
d23en007-p39 mtu: 9000

r12 d23is168 => d23en007-p38 => d23en007-p39 => r12 d23cn001 Speed OK


Case 2-2:
d23cn001 mtu: 9000
d23is168 mtu: 1500
d23en007-p38 mtu: 9000
d23en007-p39 mtu: 9000

r12 d23is168 => d23en007-p38 => d23en007-p39 => r12 d23cn001 Speed OK


Case 2-3:
d23is165 mtu: 1500
d23is167 mtu: 1500
d23en007-p35 mtu: 9000
d23en007-p37 mtu: 9000

r12 d23is165 => d23en007-p35 => d23en007-p37 => r12 d23is167 Speed OK

localhost and 127.0.0.1

Can a single network card have 2 IP addresses

Firewall

PXE

達成這個 PXE 必須要有兩個環節 - (1)一個是用戶端的網路卡必須要支援 PXE 用戶端功能,並且開機時選擇網路卡開機,這樣系統才會以網路卡進入 PXE 用戶端的程序 - (2)一個是 PXE 伺服器必須要提供至少含有 DHCP 以及 TFTP 的服務才行 - DHCP 服務必須要能夠提供用戶端的網路參數之外,還得要告知用戶端 TFTP 所在的位置為何才行 - TFTP 則是提供用戶端 boot loader 及 kernel file 下載點的重要服務

Interface name

TFTP

sudo apt-get install tftpd-hpa

/etc/default/tftpd-hpa

# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp" 
TFTP_DIRECTORY="/tftpboot" 
TFTP_ADDRESS=":69" 
TFTP_OPTIONS="--secure" 

Test TFTP

[root@foo tmp]# tftp
tftp> connect 172.24.131.123
tftp> status
Connected to 172.24.131.123.
Mode: netascii Verbose: off Tracing: off Literal: off
Rexmt-interval: 5 seconds, Max-timeout: 25 seconds
tftp> get pxelinux.0
tftp> q
[root@foo tmp]# md5sum pxelinux.0

iPXE

sequenceDiagram
    participant TN as target node
    participant DHCP
    participant TFTP
    participant HTTP

    TN->>+DHCP: -
    DHCP-->>-TN: next server and get file "ipxe.efi"
    TN->>+TFTP: -
    TFTP-->>-TN: network boot firmware: ipxe.efi
    TN->>+DHCP: user-class = "iPXE"
    DHCP-->>-TN: next server and get file "ipxe.script"
    TN->>+TFTP: -
    TFTP-->>-TN: ipxe.script

    TN->>+HTTP: get kernel
    HTTP-->>-TN: vmlinuz
    TN->>+HTTP: get Initrd ramdisk
    HTTP-->>-TN: initrd
    TN->>+TN: boot with kernel and initrd

Ubuntu

nfs boot

sudo apt-get update
sudo apt-get install build-essential debootstrap isc-dhcp-server tftpd-hpa nfs-kernel-server

# tftp root path
sudo mkdir -p /tftpboot
sudo mkdir -p /tftpboot/boot

# nfs root path
sudo mkdir -p /srv/nfsroot
sudo echo "/srv/nfsroot *(rw,sync,no_root_squash,no_subtree_check)" > /etc/exports
sudo exportfs -a
sudo systemctl restart nfs-kernel-server

shared nfs for all nodes

# setup the nfs root filesystem
sudo debootstrap --arch amd64 jammy /srv/nfsroot http://archive.ubuntu.com/ubuntu/
# customize the nfs root filesystem
sudo chroot /srv/nfsroot
echo "root:$(openssl passwd -6 bar@123)" | chpasswd -e
useradd -m -d /home/foo -p $(openssl passwd -6 bar@123) foo
apt-get install -y openssh-server
exit

# ipxe
sudo cp /boot/vmlinuz-$(uname -r) /tftpboot/vmlinuz
sudo cp /boot/initrd.img-$(uname -r) /tftpboot/initrd.img
# sudo chmod 775 /tftpboot/vmlinuz
sudo wget -O /tftpboot/ipxe.efi http://boot.ipxe.org/ipxe.efi
# Define the content to append
content=$(cat <<EOF

#!ipxe

set http-server 192.168.1.10:8000
set nfs-server 192.168.1.10
set nfs-root /srv/nfsroot

kernel http://${http-server}/vmlinuz initrd=initrd.img root=/dev/nfs rw nfsroot=${nfs-server}:${nfs-root} ip=dhcp
initrd http://${http-server}/initrd.img
boot
EOF
)

# Append the content to the file
echo "$content" >> /tftpboot/ipxe.script

nfs by mac if mac is 00:0c:29:d5:8a:04

# setup the nfs root filesystem
sudo debootstrap --arch amd64 jammy /srv/nfsroot/000c29d58a04 http://archive.ubuntu.com/ubuntu/
# customize the nfs root filesystem
sudo chroot /srv/nfsroot/000c29d58a04
echo "root:$(openssl passwd -6 bar@123)" | chpasswd -e
useradd -m -d /home/foo -p $(openssl passwd -6 bar@123) foo
apt-get install -y openssh-server
exit

# ipxe
sudo cp /boot/vmlinuz-$(uname -r) /tftpboot/vmlinuz
sudo cp /boot/initrd.img-$(uname -r) /tftpboot/initrd.img
# sudo chmod 775 /tftpboot/vmlinuz
sudo wget -O /tftpboot/ipxe.efi http://boot.ipxe.org/ipxe.efi
# Define the content to append
content=$(cat <<EOF

#!ipxe
chain --replace --autofree mac-${mac:hexraw}.ipxe
EOF
)

# Append the content to the file
echo "$content" >> /tftpboot/ipxe.script

# Define the content to append
content=$(cat <<EOF

#!ipxe

set http-server 192.168.1.10:8000
set nfs-server 192.168.1.10
set nfs-root /srv/nfsroot

kernel http://${http-server}/vmlinuz initrd=initrd.img root=/dev/nfs rw nfsroot=${nfs-server}:${nfs-root}/${mac:hexraw} ip=dhcp
initrd http://${http-server}/initrd.img
boot
EOF
)

# Append the content to the file
echo "$content" >> /tftpboot/mac-000c29d58a04.ipxe

http autoinstall provision

Memory: at least 6GiB

/tftpboot/ipxe.script format 1

#!ipxe
set http-server 192.168.1.10:8000
set nfs-server 192.168.1.10
set nfs-root /srv/nfsroot

kernel http://${http-server}/ubuntu/jammy/casper/vmlinuz
initrd http://${http-server}/ubuntu/jammy/casper/initrd
imgargs vmlinuz initrd=initrd \
 autoinstall \
 ip=dhcp \
 url=http://192.168.1.10:8000/ubuntu/jammy/ubuntu-22.04.4-live-server-amd64.iso \
 ds=nocloud-net;s=http://192.168.1.10:8000/ubuntu/jammy/autoinstall/
boot

/tftpboot/ipxe.script format 2

#!ipxe
set http-server 192.168.1.10:8000
set nfs-server 192.168.1.10
set nfs-root /srv/nfsroot

kernel http://${http-server}/ubuntu/jammy/casper/vmlinuz autoinstall url=http://${http-server}/ubuntu/jammy/ubuntu-22.04.4-live-server-amd64.iso ds=nocloud-net;s=http://${http-server}/ubuntu/jammy/autoinstall/ ip=dhcp
initrd http://${http-server}/ubuntu/jammy/casper/initrd
boot

/etc/dhcp/dhcpd.conf

lease-file-name "/var/lib/dhcp/dhcpd.leases";
option client-architecture code 93 = unsigned integer 16;


shared-network ens192 {
    subnet 192.168.1.0 netmask 255.255.255.0 {
        max-lease-time 43200;
        min-lease-time 43200;
        default-lease-time 43200;
        range 192.168.1.100 192.168.1.200;
        option routers 192.168.1.1;
        option subnet-mask 255.255.255.0;
        #option domain-name-servers 8.8.8.8;
        option domain-name "yourdomain.local";

        next-server 192.168.1.10;  # IP of your TFTP server

        if exists user-class and option user-class = "iPXE" {
            filename "ipxe.script";
        } elsif option client-architecture = 00:00 {
            filename "undionly.kpxe";
        } else {
            filename "ipxe.efi";
        }
    }
}

wget -O /tmp/ubuntu-22.04.4-live-server-amd64.iso http://172.31.48.191/ISO/ubuntu-22.04.4-live-server-amd64.iso
mkdir -p /tmp/ubuntu-jammy
sudo mount -o loop /tmp/ubuntu-22.04.4-live-server-amd64.iso /tmp/ubuntu-jammy
sudo mkdir -p /tftpboot/boot/ubuntu/jammy/casper/
sudo cp /tmp/ubuntu-jammy/casper/initrd /tftpboot/boot/ubuntu/jammy/casper/
sudo cp /tmp/ubuntu-jammy/casper/vmlinuz /tftpboot/boot/ubuntu/jammy/casper/
umount /tmp/ubuntu-jammy
sudo cp /tmp/ubuntu-22.04.4-live-server-amd64.iso /tftpboot/boot/ubuntu/jammy/
sudo mkdir -p /tftpboot/boot/ubuntu/jammy/autoinstall
sudo touch /tftpboot/boot/ubuntu/jammy/autoinstall/meta-data
# disable_suites is for offline env
sudo cat > /tftpboot/boot/ubuntu/jammy/autoinstall/user-data << 'EOF'
#cloud-config
autoinstall:
  identity:
    hostname: ipxe-target-from-http
    password: $6$Br4k9eeV7CUn4yAh$XUSXOInFLjkgndlC.S9kdsS6LhOUoIhWprDSa.VKhvprmjSdMienG4b.4n5r3NrD.auc3SEjbseOn3td/FnYS/
    username: foo
  version: 1
  apt:
    disable_suites: [updates, backports, security, proposed, release, inversion, multiverse]
  user-data:
    users:
      - name: foo
        gecos: 'foo User'
        sudo: ALL=(ALL) NOPASSWD:ALL
EOF

sudo wget -O /tftpboot/ipxe.efi http://boot.ipxe.org/ipxe.efi

# Define the content to append
sudo cat > /tftpboot/ipxe.script << 'EOF'

#!ipxe

set http-server 192.168.1.10:8000
set nfs-server 192.168.1.10

kernel http://${http-server}/ubuntu/jammy/casper/vmlinuz autoinstall url=http://${http-server}/ubuntu/jammy/ubuntu-22.04.4-live-server-amd64.iso ds=nocloud-net;s=http://${http-server}/ubuntu/jammy/autoinstall/ ip=dhcp
initrd http://${http-server}/ubuntu/jammy/casper/initrd
boot
EOF

if need to enable root account ssh login by password, use this user-data

#cloud-config
autoinstall:
  identity:
    hostname: ipxe-target-from-http
    password: $6$Br4k9eeV7CUn4yAh$XUSXOInFLjkgndlC.S9kdsS6LhOUoIhWprDSa.VKhvprmjSdMienG4b.4n5r3NrD.auc3SEjbseOn3td/FnYS/
    username: foo
  version: 1
  apt:
    disable_suites: [updates, backports, security, proposed, release, inversion, multiverse]
  user-data:
    users:
      - name: foo
        gecos: 'foo User'
        sudo: ALL=(ALL) NOPASSWD:ALL
    chpasswd:
      list: |
        root:$6$Br4k9eeV7CUn4yAh$XUSXOInFLjkgndlC.S9kdsS6LhOUoIhWprDSa.VKhvprmjSdMienG4b.4n5r3NrD.auc3SEjbseOn3td/FnYS/
      expire: false
    ssh_pwauth: true
    write_files:
      - path: /etc/ssh/sshd_config.d/customized.conf
        content: |
          PermitRootLogin yes
          PasswordAuthentication yes
    runcmd:
      - systemctl restart sshd

Redhat

http autoinstall provision

/tftpboot/ipxe.script

#!ipxe

set http-server 192.168.1.10:8000

kernel http://${http-server}/boot/rhel/8.9/raw/images/pxeboot/vmlinuz initrd=initramfs inst.stage2=http://${http-server}/boot/rhel/8.9/raw inst.ks=http://${http-server}/boot/rhel/8.9/raw/ks.cfg
initrd --name initramfs http://${http-server}/boot/rhel/8.9/raw/images/pxeboot/initrd.img
boot

mount -t iso9660 /tmp/rhel-8.9-x86_64-dvd.iso /tmp/rhel-8.9 -o loop,ro
mkdir -p /home/foo/boot/rhel/8.9/raw
rsync -avzh --progress /tmp/rhel-8.9/ /home/foo/boot/rhel/8.9/raw/
touch /home/foo/boot/rhel/8.9/raw/ks.cfg
cat > /home/foo/boot/rhel/8.9/raw/ks.cfg << 'EOF'
#version=RHEL8
text

repo --name="AppStream" --baseurl=http://192.168.1.10:8000/boot/rhel/8.9/raw/AppStream

%packages
@^minimal-environment
kexec-tools

%end

# Keyboard layouts
keyboard --xlayouts='us'
# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp --device=ens160 --ipv6=auto --activate
network  --hostname=ipxe-target-from-http.localdomain

# Use network installation
url --url="http://192.168.1.10:8000/boot/rhel/8.9/raw"

# Run the Setup Agent on first boot
firstboot --enable

ignoredisk --only-use=sda
autopart
# Partition clearing information
clearpart --all --initlabel

# System timezone
timezone America/New_York --isUtc

# Root password
rootpw --iscrypted $6$nhMYeGx62dqF2l7O$pxNdZ6urW0mvCoMAh8.PhUFtbssl3LopiRCa7iMk.4n/qGcyKgDR2jMhhlcTHNPSJm73qEzeamQXfv.WyEEbb/
user --groups=wheel --name=foo --password=$6$M6xOA4EgUKJtHEUK$czJSOAjKfE1zbvZlB2CVOSRkmnRxCc52bPALWIJpk.aOaHAPT6ZvYWa4ZZaZTa0Q1o0ORf1Wf1yyR2OWkeCbY0 --iscrypted --gecos="foo"

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

reboot
EOF

ks.cfg for autopart

#version=RHEL8
text

repo --name="AppStream" --baseurl=http://192.168.1.10:8000/boot/rhel/8.9/raw/AppStream

%packages
@^minimal-environment
kexec-tools

%end

# Keyboard layouts
keyboard --xlayouts='us'
# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp --device=ens160 --ipv6=auto --activate
network  --hostname=ipxe-target-from-http.localdomain

# Use network installation
url --url="http://192.168.1.10:8000/boot/rhel/8.9/raw"

# Run the Setup Agent on first boot
firstboot --enable

ignoredisk --only-use=sda
autopart
# Partition clearing information
clearpart --all --initlabel

# System timezone
timezone America/New_York --isUtc

# Root password
rootpw --iscrypted $6$nhMYeGx62dqF2l7O$pxNdZ6urW0mvCoMAh8.PhUFtbssl3LopiRCa7iMk.4n/qGcyKgDR2jMhhlcTHNPSJm73qEzeamQXfv.WyEEbb/
user --groups=wheel --name=foo --password=$6$M6xOA4EgUKJtHEUK$czJSOAjKfE1zbvZlB2CVOSRkmnRxCc52bPALWIJpk.aOaHAPT6ZvYWa4ZZaZTa0Q1o0ORf1Wf1yyR2OWkeCbY0 --iscrypted --gecos="foo"

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

reboot

ks.cfg for customized partition(80G)

#version=RHEL9
text

repo --name="AppStream" --baseurl=http://192.168.1.10:8000/boot/rhel/9.3/raw/AppStream

%packages
@^minimal-environment
rsync
kexec-tools

%end

# Keyboard layouts
keyboard --xlayouts='us'
# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp --device=ens160 --ipv6=auto --activate
network  --hostname=ipxe-target-from-http.localdomain

# Use network installation
url --url="http://192.168.1.10:8000/boot/rhel/9.3/raw"

# Run the Setup Agent on first boot
firstboot --enable

ignoredisk --only-use=sda
# Disk partitioning information
part /boot/efi --fstype=efi --size=600
part /boot --fstype=xfs --size=1024
part pv.01 --size=1 --grow

volgroup vg_root pv.01
logvol / --vgname=vg_root --size=10240 --grow --name=lv_root --fstype=xfs
logvol /home --vgname=vg_root --size=10240 --name=lv_home --fstype=xfs
logvol /tmp --vgname=vg_root --size=30720 --name=lv_tmp --fstype=xfs
logvol swap --vgname=vg_root --size=2048 --name=lv_swap --fstype=swap

# Partition clearing information
clearpart --all --initlabel

# System timezone
timezone America/New_York --isUtc

# Root password
rootpw --iscrypted $6$nhMYeGx62dqF2l7O$pxNdZ6urW0mvCoMAh8.PhUFtbssl3LopiRCa7iMk.4n/qGcyKgDR2jMhhlcTHNPSJm73qEzeamQXfv.WyEEbb/
user --groups=wheel --name=foo --password=$6$M6xOA4EgUKJtHEUK$czJSOAjKfE1zbvZlB2CVOSRkmnRxCc52bPALWIJpk.aOaHAPT6ZvYWa4ZZaZTa0Q1o0ORf1Wf1yyR2OWkeCbY0 --iscrypted --gecos="foo"

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

reboot

ipxe menu

combine http autoinstall provision for ubuntu and redhat

/tftpboot/ipxe-menu.script

#!ipxe

# Set a timeout for the menu 20s
set menu-timeout 20000

# Set http server access point
set http-server 192.168.1.10:8000

# Define the menu
:start
menu iPXE Boot Menu
item --key u ubuntu22 Autoinstall provision for Ubuntu 22
item --key r rhel93 Autoinstall provision for Redhat 9.3
item --gap -- --------------------------
item --key x exit Exit iPXE

# Choose the default menu item
choose --default ubuntu22 --timeout ${menu-timeout} selected
goto ${selected}

:ubuntu22
echo Autoinstall provision for Ubuntu 22...
kernel http://${http-server}/boot/ubuntu/jammy/casper/vmlinuz autoinstall url=http://${http-server}/boot/ubuntu/jammy/ubuntu-22.04.4-live-server-amd64.iso ds=nocloud-net;s=http://${http-server}/boot/ubuntu/jammy/autoinstall/ ip=dhcp
initrd http://${http-server}/boot/ubuntu/jammy/casper/initrd
boot

:rhel93
echo Autoinstall provision for Redhat 9.3...
kernel http://${http-server}/boot/rhel/9.3/pxeboot/vmlinuz initrd=initramfs inst.stage2=http://${http-server}/boot/rhel/9.3/raw inst.ks=http://${http-server}/boot/rhel/9.3/raw/ks.cfg
initrd --name initramfs http://${http-server}/boot/rhel/9.3/pxeboot/initrd.img
boot

:exit
echo Exiting iPXE...

Cloudflare Tunnel