{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Networking"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Linux networking\n",
    "\n",
    "- Overview of network protocols and TCP/IP in Linux.\n",
    "- Network configuration in Linux.\n",
    "- Netplan on Ubuntu servers.\n",
    "- Network settings in Red Hat for NetworkManager.\n",
    "- Network troubleshooting tools: ping, traceroute, tcpdump.\n",
    "- Network calculation with <TT>ipcalc</TT>\n",
    "- Network applications and services.\n",
    "- Network traffic sniffing with tcpdump.\n",
    "- lighttpd server installation.\n",
    "- Port tunneling with SSH.\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Computers on the intertnet\n",
    "\n",
    "- Network communication allows sending information, transfering files, and managing applications remotely between computers.\n",
    "- Networks are organized in a series of layers implemented on each machine.\n",
    "- The layers are independent and each layer offers a specific task to the neighboring layers above and below.\n",
    "- The communication between the layers is based on defined rules and procedures, called protocols.\n",
    "- Data is processed and passed through the layers from above to below, until the bottom layer is reached.\n",
    "- At the bottom layer, computers communicate with each other via sending and receiving network datagrams through - cables, switches and routers.\n",
    "\n",
    "![](img/computers_on_network.png)\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## TCP/IP 5 layer protocol suit\n",
    "\n",
    "\n",
    "![](img/tcp-ip.jpg)\n",
    "\n",
    "Each layer has its own task:\n",
    "\n",
    "\n",
    "|TCP/IP Protocol Layer | Tasks\n",
    "| :-- | :--\n",
    "|5. Application Layer: ssh, ftp, http ... | Data segmentation by the application into Message Transfer Unit (MTU) segments. Typical MTU is 1.5 Kbyte, which includes the data payload plus 40 bytes for TCP and IP headers.\n",
    "|4. Transport Layer: TCP, UDP, ports  | Connection management, quality, and ports to the applications\n",
    "|3. Internet Layer: IP addresses, subnets, routing | Addressing: each computer has a unique address on its network or subnet. Routing between networks.\n",
    "|2. Link Layer: Ethernet | Communication on the local network (subnet) through a switch. Media Access Card (MAC) address unique on the subnet. For example, 48:d2:4f:f4:d:fb, should be unique within a subnet. Address Resolution Protocol (ARP) matches the IP address to MAC on the subnet.\n",
    "|1. Physical Layer: NIC, hubs, switches, routers, cabling, wifi APs and cards | Electronic devices to send and receive signals between computers.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## OSI 7 layer Network Stack Model\n",
    "\n",
    "![](img/osi.jpg)\n",
    "\n",
    "|TCP/IP Protocol Layer | Task\n",
    "| :-- | :--\n",
    "|7. Application Layer: ssh, ftp, http ... | Data segmentation by the application into Message Transfer Unit (MTU) segments. Typical MTU is 1.5 Kbyte\n",
    "|6. Presentation Layer: SSL, libz, XDR  | Data encryption, compression, and encoding/decoding\n",
    "|5. Session Layer: Remote Procedure Call (RPC) | Responsible for opening, using and closing sessions. Remote procedures.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## TCP/IP and Kernel\n",
    "\n",
    "![](img/tcpip-kernel.jpg)\n",
    "\n",
    "The Link, Internet and Transport layers are implemented through kernel.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Packet Encapsulation\n",
    "\n",
    "Data is processed in form of packet encapsulation and transmitted/received in form of Ethernet frames.\n",
    "\n",
    "![](img/ip_packet.jpg)\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hosts communication via TCP/IP\n",
    "\n",
    "![](img/host-host.jpg)\n",
    "\n",
    "![](img/host-tcpip.jpg)\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Wired connection checkup (Exercise)\n",
    "\n",
    "- To see whether your desktop is connected to a network switch and at what speed, use command  ```ethtool```.\n",
    "\n",
    "- On your desktop, install package <TT>ethtool</TT>:\n",
    "```bash\n",
    "apt install ethtool\n",
    "```\n",
    "- See your network interfaces with command ```ifconfig``` or ```ip a```:\n",
    "```bash\n",
    "/sbin/ifconfig -a\n",
    "```\n",
    "or \n",
    "```bash\n",
    "ip a\n",
    "```\n",
    "\n",
    "The main network interface, connected to the Ethernet, is <TT>enp0s3</TT>. Run command below:\n",
    "```bash\n",
    "/sbin/ethtool enp0s3\n",
    "```\n",
    "\n",
    "In the output, among various parameters, it doesn't show Speed and Duplex because the desktop is a VM in VDI.\n",
    "\n",
    "  - Speed: Unknown!\n",
    "  - Duplex: Unknown!\n",
    "  - Link detected: yes\n",
    "  \n",
    "If the desktop was installed on a bare metal hardware, we would see something like below:\n",
    "\n",
    "  - Speed: 1000Mb/s, \n",
    "  - Duplex: Full, \n",
    "  - Link detected: yes\n",
    "  \n",
    "Which means the cable is connected and the link speed is 1Gb/s speed, full duplex mode. \n",
    "  <hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network IP configuration\n",
    "\n",
    "- Static configuration\n",
    "    - IP address, gateway, hostname, and Domain Name System (DNS) are configured on the host.\n",
    "    \n",
    "    \n",
    "    \n",
    "- Dynamic Host Configuration Protocol (DHCP)\n",
    "    - The settings are obtained from a DHCP server.\n",
    "    \n",
    "![](img/dhcp.gif)\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Environment for IP configuration on Ubuntu and RedHat\n",
    "\n",
    "|ifupdown scripts\t| ```NetworkManager``` service \t| Netplan ```networkd``` service Meaning\n",
    "|:---    | ---      | ---:        |  \n",
    "|Old Debian/Ubuntu: | Ubuntu desktop, Debian, Redhat: | Ubuntu server: |\n",
    "|File: ```/etc/network/interfaces``` |  Commands: ```nmtui, nmcli```     | File:```/etc/netplan/00-installer-config.yaml``` |\n",
    "|RedHat:                 | Redhat                 | Command: ```netplan apply``` |\n",
    "|File: ```/etc/sysconfig/network-scripts/ifcfg-ens3```|  File: ```/etc/NetworkManager/system-connections/<conn name>.nmconnection``` |\n",
    "|Command:```ifup ens3``` |  ```systemctl restart NetworkManager; nmcli con up <conn name>```\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "<HR>\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Deploy a new VM for exercises\n",
    "\n",
    "Shutdown <TT>kvm1</TT> VM, and clone it into <TT>netplan</TT> VM:\n",
    "```bash\n",
    "virsh shutdown kvm1\n",
    "virt-clone  -o kvm1 -n netplan -f /home/hostadm/KVM/netplan.qcow2\n",
    "```\n",
    "Start netplan. Login to console of netplan:\n",
    "```bash\n",
    "virsh console netplan\n",
    "```\n",
    "Fix the hostname in file <TT>/etc/hostname</TT>.\n",
    "\n",
    "Reset the machine ID by running the following script on netplan:\n",
    "```bash\n",
    "./vm_id_reset.sh\n",
    "```\n",
    "\n",
    "Execute command reboot on netplan:\n",
    "```bash\n",
    "reboot\n",
    "```\n",
    "\n",
    "<hr>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Configuring network settings on Ubuntu server with Netplan (Exercises)\n",
    "\n",
    "On <TT>netplan</TT> VM check the IP address settings by running command below:\n",
    "```bash\n",
    "ip addr\n",
    "```\n",
    "All the commands below in this section need to be run as root. Elevate the user privileges to root:\n",
    "```bash\n",
    "sudo -s\n",
    "```\n",
    "\n",
    "Assign IP address <TT>192.168.122.222</TT> by modifying the content of ```/etc/netplan/00-installer-config.yaml``` as follows:\n",
    "\n",
    "```yaml\n",
    "---\n",
    "network:\n",
    "  version: 2\n",
    "  renderer: networkd\n",
    "  ethernets:\n",
    "    enp1s0:\n",
    "      dhcp4: false\n",
    "      addresses:\n",
    "        - 192.168.122.222/24\n",
    "      routes:\n",
    "        - to: default\n",
    "          via: 192.168.122.1\n",
    "      nameservers:\n",
    "        addresses: [192.168.122.1]\n",
    "```\n",
    "\n",
    "Install the Yaml syntax check tool:\n",
    "```bash\n",
    "apt install yamllint\n",
    "```\n",
    "\n",
    "Check the network configuration file for syntax correctness:\n",
    "```bash\n",
    "yamllint /etc/netplan/00-installer-config.yaml\n",
    "```\n",
    "If no errors found, have the new network settings applied:\n",
    "```bash\n",
    "netplan apply\n",
    "```\n",
    "Check the IP address again:\n",
    "```bash\n",
    "ip addr\n",
    "```\n",
    "It should show <TT>192.168.122.222</TT> for <TT>ens3</TT> interface now.\n",
    "\n",
    "See the gateway settings by running command \n",
    "```bash\n",
    "ip route show\n",
    "```\n",
    "It should show the \"default via 192.168.122.1\"\n",
    "\n",
    "Logout and disconnect from the console.\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Clone rocky9 VM (Exercises)\n",
    "\n",
    "In case you already have ```rocky91``` VM from the package management class, skip the cloning steps below and proceed to the \n",
    " network configuration on ```rocky91```.\n",
    " \n",
    "Make sure rocky9 is down:\n",
    "```bash\n",
    "virsh list\n",
    "virsh stop rocky9\n",
    "```\n",
    "Clone rocky9 into new VM rocky91:\n",
    "```bash\n",
    "virt-clone -o rocky9 -n rocky91 -f /home/hostadm/KVM/rocky91.qcow2\n",
    "```\n",
    "Start the VM:\n",
    "```bash\n",
    "virsh start rocky91\n",
    "```\n",
    "Connect to the cnsole:\n",
    "```bash\n",
    "virsh console rocky91\n",
    "```\n",
    "Login to the system.\n",
    "\n",
    "You need to install editor `dbus-tools`:\n",
    "```bash\n",
    "sudo dnf install dbus-tools\n",
    "```\n",
    "\n",
    "Change the hostname to `rocky91` by editing file `/etc/hostname` with `nano`.\n",
    "\n",
    "Reset the machine ID:\n",
    "```bash\n",
    "sudo dnf install dbus-tools\n",
    "sudo rm -f /etc/machine-id\n",
    "sudo dbus-uuidgen --ensure=/etc/machine-id\n",
    "sudo dbus-uuidgen --ensure\n",
    "sudo dhclient -r eth0\n",
    "```\n",
    "\n",
    "Reboot the VM.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network configurations on a Red Hat server (Exercises)\n",
    "\n",
    "On RedHat based systems, we can use ```nmcli``` to control the network settings in the NetworkManager service.\n",
    "\n",
    "Start rocky91 VMs:\n",
    "```bash\n",
    "virsh start rocky91\n",
    "```\n",
    "Login to console of rocky91:\n",
    "```bash\n",
    "virsh console rocky91\n",
    "```\n",
    "Execute command ip address show to read the IP address:\n",
    "```bash\n",
    "ip addr show eth0\n",
    "```\n",
    "Try pinging ```netplan``` by its IP address, for example:\n",
    "```bash\n",
    "ping -c 3 192.168.122.222\n",
    "```\n",
    "Become root on rocky91 VM\n",
    "```bash\n",
    "sudo -s\n",
    "```\n",
    "\n",
    "By using command ```nmcli``` check available and active connactions:\n",
    "```bash\n",
    "nmcli conn show\n",
    "```\n",
    "There is connection named \"System eth0\" for interface eth0.\n",
    "\n",
    "See the settings for device eth0:\n",
    "```bash\n",
    "nmcli dev show eth0\n",
    "```\n",
    "\n",
    "With command ```nmcli```, we can create various connections with different settings for eth0 interface, then we can activate the needed connection, and de-activate non-needed.\n",
    "\n",
    "Let's create new connection named \"eth_static\" and assign it static IP address 192.168.122.126 and netmask /24:\n",
    "```bash\n",
    "nmcli con add type ethernet con-name eth_static ip4 192.168.122.126/24 gw4 192.168.122.1 ipv4.dns 192.168.122.1\n",
    "```\n",
    "Activate the connection:\n",
    "```bash\n",
    "nmcli con up eth_static\n",
    "```\n",
    "Check the connection status:\n",
    "```bash\n",
    "nmcli conn show\n",
    "```\n",
    "Check the new IP address:\n",
    "```bash\n",
    "ip addr show eth0\n",
    "```\n",
    "\n",
    "Change the IP address to 192.168.122.25 via ```nmcli``` command:\n",
    "```bash\n",
    "nmcli con modify eth_static ipv4.addresses 192.168.122.125/24\n",
    "```\n",
    "Activate eth_static connection:\n",
    "Activate the connection:\n",
    "```bash\n",
    "nmcli con up eth_static\n",
    "```\n",
    "Check the connection status:\n",
    "```bash\n",
    "nmcli conn show\n",
    "```\n",
    "Check the new IP address:\n",
    "```bash\n",
    "ip addr show eth0\n",
    "```\n",
    "\n",
    "**Alternative way of modifying the IP address settings for a connection.**\n",
    "\n",
    "When creating a new connection with ```nmcli``` command, a new file is created in directory \n",
    " /etc/NetworkManager/system-connections/.\n",
    "\n",
    "We can modify the settings in the file with an editor, then restart the NetworkManager and activate the connection, for example:\n",
    "```bash\n",
    "systemctl restart NetworkManager\n",
    "nmcli con up eth_static\n",
    "```\n",
    "\n",
    "**Revert back to the DHCP based connection**\n",
    "\n",
    "```bash\n",
    "nmcli conn show\n",
    "```\n",
    "\n",
    "We need to activate connection \"System eth0\":\n",
    "```bash\n",
    "nmcli conn up \"System eth0\"\n",
    "```\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Internet Control Message Protocol (ICMP) protocol (Exercises)\n",
    "\n",
    "Implemented on hosts and gateways (routers) for:\n",
    "\n",
    "Reporting the status of datagram processing.\n",
    "Diagnostics of connection and routing.\n",
    "Reporting errors in the processing of a datagram.\n",
    "\n",
    "Example: ```ping```\n",
    "\n",
    "![](img/ping.jpg)\n",
    "\n",
    "Exercise: command ```ping```.\n",
    "```bash\n",
    "ping -c 5 capone.rutgers.edu\n",
    "ping -c 5 engsoft.rutgers.edu\n",
    "ping -c 5 google.com\n",
    "```\n",
    "If the systems respond, it means they are reachable on the network. Notice how varies the round-trip time and Time to Live (ttl) for packets between the hosts.\n",
    "\n",
    "Example: ```traceroute```\n",
    "\n",
    "\n",
    "![](img/traceroute.jpg)\n",
    "\n",
    "Time to leave (TTL) decrement. The TTL value of an IP packet represents the maximum number of IP routers that the packet can go through before being thrown away. You can expect each router in the Internet to decrement the TTL field by exactly one. The default TTL for traceroute on Linux is 30. It can be increased up to 255 maximum by using the -m command option.\n",
    "\n",
    "Exercise: command traceroute.\n",
    "\n",
    "```bash\n",
    "sudo apt install traceroute\n",
    "sudo /usr/sbin/traceroute -I capone.rutgers.edu\n",
    "sudo /usr/sbin/traceroute -I engsoft.rutgers.edu\n",
    "sudo /usr/sbin/traceroute -I google.com\n",
    "```\n",
    "This shows you all the gateways between the subnets your packet travels towards the destination. Notice the difference in the number of gateways between your desktop and the three remote hosts as well as the round trip times.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Subnets and routing\n",
    "\n",
    "Example: Host A can communicate with both the hosts - B and C. Hosts B and C can't communicate with each other.\n",
    "What is the problem?\n",
    "<br>\n",
    "Answer: the routing (gateway) is not defined on Host B.\n",
    "\n",
    "![](img/hosts-router.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network calculation, gateway and routing\n",
    "\n",
    "- Computers connected to the same switch are on the same network/subnet and communicate with each other directly through the switch.\n",
    "- For computers located on the different networks/subnets, gateway/router is needed.\n",
    "- To define the local subnet, netmask is used.\n",
    "\n",
    "- Subnet mask defines the network and the host parts of the IP address\n",
    "\n",
    "Network address = Host address (logical AND) Netmask:\n",
    "\n",
    "\n",
    "\n",
    "| Address         | Decimal/Hexadecimal  | Binary | \n",
    "|:- | :-: | :- |                                  \n",
    "| IP address      | 192.168.5.10  |  ```11000000 10010100 00000101 00001010``` |  \n",
    "| Netmask         | 255.255.255.0 |  ```11111111 11111111 11111111 00000000``` |\n",
    "| Network address | 192.168.5.0   |  ```11000000 10010100 00000101 00000000``` |\n",
    "\n",
    "\n",
    "\n",
    "- The network address is the smallest address on the network:\n",
    "\n",
    "```11000000 10010100 00000101 00000000 = 192.168.5.0```\n",
    "\n",
    "- The broadcast address is the largest address on the network:\n",
    "\n",
    "```11000000 10010100 00000101 11111111 = 192.168.5.255```\n",
    "\n",
    "- Max number of hosts on the subnet: 254 = 256 - 2\n",
    "The gateway address should be on the same subnet with the host\n",
    "\n",
    "- Subnet mask consists of contiguous 1. The bytes filled with 1 become 255 in decimal notation.  The bytes ending with 0 can be converted from binary to decimal by the following technique:\n",
    "  \n",
    "  $a_7 \\cdot 128 + a_6 \\cdot 64 + a_5 \\cdot 32 + a_4 \\cdot 16 + a_3 \\cdot 8 + a_2 \\cdot 4 + a_1 \\cdot 2 + a_0$\n",
    "\n",
    "  where the coefficients, $a_7, a_6, a_5, a_4, a_3, a_2, a_1, a_0$, are the bits with values of 0 or 1.\n",
    "\n",
    "- It is easier to use ipcalculator for computing subnets.\n",
    "<hr>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## IP calculator exercises\n",
    "\n",
    "Network IP calculations with ipcalc\n",
    "On the desktop, install ipcalc by using APT:\n",
    "```bash\n",
    "apt install ipcalc\n",
    "```\n",
    "Run ipcalc for network address 192.168.5.0 with subnet mask 255.255.255.0.\n",
    "```bash\n",
    "ipcalc 192.168.5.0/255.255.255.0\n",
    "```\n",
    "See the output for Address, Netmask, Network, HostMin, HostMax, Broadcast, Hosts/Net.\n",
    "Notice the same results for the same network and the different representation of the netmask:\n",
    "```bash\n",
    "ipcalc 192.168.5.0/24\n",
    "```\n",
    "Notice the same results for Netmask, Network, HostMin, HostMax, Broadcast, Hosts/Net if using the different IP addresses within the same network in ipcalc, for example:\n",
    "```bash\n",
    "ipcalc 192.168.5.15/24\n",
    "ipcalc 192.168.5.34/24\n",
    "```\n",
    "Run ipcalc for subnets (networks) 192.168.5.0/25 and 192.168.5.128/25:\n",
    "```bash\n",
    "ipcalc 192.168.5.0/25\n",
    "ipcalc 192.168.5.128/25\n",
    "```\n",
    "Notice the values for HostMin and HostMax in both the cases. By looking at the ranges [HostMin, HostMax], you can see, for example, that IP address 192.168.5.5 belongs to the first subnet and 192.168.5.250 to the second.\n",
    "You can verify that by running ipcalc on the IP addresses above and then comparing the Network values:\n",
    "```bash\n",
    "ipcalc 192.168.5.5/25\n",
    "ipcalc 192.168.5.250/25\n",
    "```\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network applications: ssh, sftp, scp, rsync (Exercises)\n",
    "\n",
    "Make sure virtual machine netplan is running\n",
    "```bash\n",
    "virsh list\n",
    "```\n",
    "Figure out the IP address of netplan:\n",
    "```bash\n",
    "virsh domifaddr netplan\n",
    "```\n",
    "\n",
    "Place the IP address and netplan host name into file ```/etc/hosts``` on your desktop. \n",
    "netplan  IP is 192.168.122.222\n",
    "```bash\n",
    "nano /etc/hosts\n",
    "```\n",
    "Make entry in the file:  ```192.168.122.222   netplan```\n",
    "\n",
    "ssh to netplan as user hostadm:\n",
    "```bash\n",
    "ssh hostadm@netplan\n",
    "```\n",
    "\n",
    "Configure SSH for private/public key authentication.\n",
    "For SSH authentication, you can use either RSA or DSA public/private keys besides password. We'll be using RSA in the exercises below.\n",
    "To generate an RSA key pair, type the following command at a shell prompt on your desktop:\n",
    "```bash\n",
    "ssh-keygen -t rsa\n",
    "```\n",
    "Accept the default file location of ```~/.ssh/id_rsa```. Enter a passphrase different from your account password and confirm it by entering it again.\n",
    "The public key is written to ```~/.ssh/id_rsa.pub```. The private key is written to ```~/.ssh/id_rsa```.\n",
    "Never distribute your private key to anyone.\n",
    "The contents of ```~/.ssh/id_rsa.pub``` needs to be delivered onto the remote machine to which you want to connect, specifically netplan, into file ```~/.ssh/authorized_keys```\n",
    "To accomplish the transfer task, here you can use one of the commands for file transfer.\n",
    "Commands ```scp``` and ```sftp``` come with ssh. We use interactive ```sftp``` command here:\n",
    "```bash\n",
    "sftp  netplan\n",
    "Name (netplan:hostadm): hostadm\n",
    "sftp> cd .ssh\n",
    "sftp> lcd .ssh\n",
    "sftp> put id_rsa.pub authorized_keys\n",
    "sftp>  quit\n",
    "```\n",
    "Command ```cd``` in the sftp> shell above is for stepping into the directory, .ssh, on the remote host, netplan.\n",
    "Command ```lcd``` is for stepping into the directory, .ssh, on the local desktop.\n",
    "\n",
    "Now try to ssh to netplan. You should be prompted to enter your passphrase.\n",
    "\n",
    "The ```ssh-agent``` can be used to store your passphrase so that you do not have to enter it each time you make a ssh or scp connection.\n",
    "At a shell prompt on the desktop, type the following command:\n",
    "```bash\n",
    "exec ssh-agent $SHELL\n",
    "```\n",
    "Then type the command:\n",
    "```bash\n",
    "ssh-add\n",
    "```\n",
    "and enter your passphrase(s). If you have more than one key pair configured, you will be prompted for each one. When you log out, your passphrase(s) will be forgotten. You must execute these two commands each time you log in to a virtual console or open a terminal window.\n",
    "\n",
    "Run a remote command over ssh, for example:\n",
    "```bash\n",
    "ssh netplan \"uname -a\"\n",
    "```\n",
    "Beside ```sftp```, command ```scp``` can be used for copying files from host to host.\n",
    "In `scp`, the first argument is the <i>source_host:source_file</i>, the second is <i>destination_host:destination_dir</i>. If the source_host or the destination_host is local, it is absent in the argumernt. The local directory is signified by ```.```\n",
    "\n",
    "Copy file /etc/hosts from netplan VM to the current directory on the desktop by using scp command:\n",
    "```bash\n",
    "scp netplan:/etc/hosts .\n",
    "```\n",
    "\n",
    "Copy new file, somef.txt, from the local directory to the home directory on netplan VM.\n",
    "```bash\n",
    "touch somef.txt\n",
    "scp somef.txt netplan:/home/$USER\n",
    "```\n",
    "\n",
    "You can also copy a group of files, for example, somef.txt and /etc/hosts, by placing them in block {}:\n",
    "```bash\n",
    "scp {somef.txt,/etc/hosts} netplan:/home/$USER\n",
    "```\n",
    "\n",
    "Directories can be copied recursively with ```scp```. For example, to copy /etc directory recursively from the desktop to  the user home directory on netplan:\n",
    "```bash\n",
    "scp -r /etc netplan:\n",
    "```\n",
    "\n",
    "Syncronizing directories between remote hosts by using ```rsync```.\n",
    "This tool lets you copy files and directories between a local host and a remote host.\n",
    "Install ```rsync``` on both your desktop and netplan:\n",
    "```bash\n",
    "apt install rsync\n",
    "```\n",
    "Creat a directory tree and copy it over to netplan with rsync command.\n",
    "```bash\n",
    "mkdir -p dir1/dir2/dir3\n",
    "rsync  -avz dir1 netplan:/home/$USER\n",
    "```\n",
    "Option a stands for archive (preserve links and timestamps); <TT>v</TT> is for verbose and <TT>z</TT> is for data compression when sending-receiving.\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Send/receive data with netcat (Exercises)\n",
    "\n",
    "Netcat is a very useful tool to connect to any TCP and UDP port on a remote host, and send/receive data.\n",
    "\n",
    "\n",
    "Start both, netplan and rocky91 VMs:\n",
    "```bash\n",
    "virsh start netplan\n",
    "virsh start rocky91\n",
    "```\n",
    "Start ```tmux``` on your desktop, and split the terminal into two panes.\n",
    "\n",
    "In one pane, login to console of netplan:\n",
    "```bash\n",
    "virsh console netplan\n",
    "```\n",
    "In the other pane of tmux, login to rocky91:\n",
    "```bash\n",
    "virsh console rocky91\n",
    "```\n",
    "\n",
    "Become root on both the VMs\n",
    "```bash\n",
    "sudo -s\n",
    "```\n",
    "\n",
    "| Step | On Ubuntu (server) | On rocky91 |\n",
    "|:- | :-: | -: |     \n",
    "|1.  |Install netcat: ```apt install netcat``` | ```dnf install nmap-ncat``` | \n",
    "|2.    | Start netcat as a server, listening on port UDP/8080: |  Connect to UDP/8080 port on netplan, 192.168.122.222: |  \n",
    "|      | ```netcat -l -u 8080``` | ```ncat 192.168.122.222 -u 8080``` | \n",
    "|3.    | When the session is over, type Ctrl-C to stop the netcat server.  |     Start typing text. Hit ENTER key. The text should appear on the both terminals. Press Ctrl+D to close the UDP connection. | \n",
    "|4.    | Start the server on TCP/8080 to write into a file, outputfile.txt |   Send file /etc/hosts to TCP/8080 on netplan VM via netcat |\n",
    "|   | ```netcat -l 8080 > outputfile.txt```  |  ```ncat 192.168.122.222  8080 < /etc/hosts``` | \n",
    "|5.  |  After the file is received, the connection closes itself. Check the content of the file: |  |\n",
    "|    | ```less outputfile.txt```  |  \n",
    "|6.  | Start ```netcat``` to receive a directory via ```tar``` command:   | Send ```/etc``` directory via ```tar``` and netcat: | \n",
    "|    | ```netcat -l 8080 \\| tar xf -```   |  ```tar cf - /etc \\| nc -w 20  192.168.122.222  8080``` |\n",
    "|7.  | Check if the directory tree has been transferred:  | |\n",
    "|    |  ```tree etc``` | |\n",
    " \n",
    "\n",
    "`netcat` provides away faster transfer of files and directories than `scp`, but it can be used only on a private network.\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## tcpdump command to see the traffic on NIC (Exercises)\n",
    "\n",
    "When you need to see all the network traffic on a network card, you can run the command for the network interface.\n",
    "It helps to identify the subnet your system is connected to, and see all the active traffic.\n",
    "\n",
    "On netplan VM, install tcpdump:\n",
    "```bash\n",
    "apt install tcpdump\n",
    "```\n",
    "Run command `tcpdump` on the ethernet interface:\n",
    "```bash\n",
    "tcpdump -v -n -i enp1s0\n",
    "```\n",
    "\n",
    "On rocky91 VM, start pingin the IP address of netplan VM:\n",
    "```bash\n",
    "ping 192.168.122.222\n",
    "```\n",
    "\n",
    "See the output in tcpdump on netplan VM.\n",
    "It should show some traffic related to echo request and reply from rocky VM:\n",
    "\n",
    "```\n",
    "    192.168.122.126 > 192.168.122.222: ICMP echo request ...\n",
    "    192.168.122.222 > 192.168.122.126: ICMP echo reply ...\n",
    "```\n",
    "\n",
    "```tcpdum``` is very noisy because it picks up all the packets going through interface enp1s0.\n",
    "We can filter the output by the IP, protocol, and port, for example:\n",
    "```bash\n",
    "tcpdump -v -n -i enp1s0 host 192.168.122.126 and proto \\\\icmp\n",
    "```\n",
    "The IP address of rocky91 is 192.168.122.126 here. In your case it maybe different.\n",
    "\n",
    "To see only the incoming packets, use the `src` IP address:\n",
    "```bash\n",
    "tcpdump -v -n -i enp1s0 src host 192.168.122.126 and proto \\\\icmp\n",
    "```\n",
    "\n",
    "Move to the pane with rocky91 in ```tmux```.\n",
    "\n",
    "SSH to netplan and start ```tcpdump``` with reading the traffic, coming from rocky91, on local port udp/8080:\n",
    "```bash\n",
    "sudo tcpdump -i enp1s0 src host 192.168.122.126 and dst port 8080 -A\n",
    "```\n",
    "\n",
    "<hr>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Light web server, lighttpd, for file download (Exercises)\n",
    "\n",
    "- On netplan VM, install lighttpd:\n",
    "```bash\n",
    "apt install lighttpd\n",
    "```\n",
    "\n",
    "Add the following line to the server configuration file, ```/etc/lighttpd/lighttpd.conf```, right after the line with \n",
    "```server.port = 80```:\n",
    "```{admonition} add to lighttpd.conf \n",
    "    dir-listing.activate   = \"enable\"\n",
    "```\n",
    "Restart the service:\n",
    "```bash\n",
    "systemctl restart lighttpd\n",
    "```\n",
    "Populate files and directories in the server document-root directory, ```/var/www/html```:\n",
    "```bash\n",
    "cd /var/www/html\n",
    "apt download lua5.4\n",
    "dpkg -X lua5.4_5.4.4-1_amd64.deb LUA\n",
    "```\n",
    "Remove the index file from the directory:\n",
    "```bash\n",
    "rm index.lighttpd.html\n",
    "```\n",
    "\n",
    "- On the desktop, create new directory DOWNLOADS, then download file lua5.4_5.4.4-1_amd64.deb from the web server into the directory:\n",
    "```bash\n",
    "mkdir DOWNLOADS\n",
    "cd DOWNLOADS\n",
    "wget http://192.168.122.222/lua5.4_5.4.4-1_amd64.deb\n",
    "```\n",
    "\n",
    "Download the whole directory recursively:\n",
    "```bash\n",
    "wget --recursive -nH http://192.168.122.222/\n",
    "```\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## SSH local port tunneling (Exercise).\n",
    "\n",
    "With SSH you can make a tcp port available from a private network to your local system.\n",
    "For example, we can map port tcp/80 from 192.168.122.222 to your localhost:8080 via SSH to the desktop.\n",
    "\n",
    "Add the port mapping option to the SSH command you usually use:\n",
    "```{admonition} add this to your ssh command you run to the desktop\n",
    "    -L 8080:192.168.122.222:80\n",
    "```\n",
    "\n",
    "In the browser on your laptop, navigate to port 8080 at localhost:\n",
    "```{admonition} in the browser\n",
    "http://localhost:8080/\n",
    "```\n",
    "\n",
    "***"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
