{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3f8da06d",
   "metadata": {},
   "source": [
    "## Final exam Q-and-A Summer 2026\n",
    "\n",
    "<b> Date: 7/15/2026,  time: 6 pm - 9 pm </b>\n",
    "\n",
    "Number of exercises: 4. Each exercise has a maximum score. \n",
    "\n",
    "In home directory of user hostadm, you need to create a new subdirectory, FINAL and a file within it, `answers.txt`, where you will be writing answers to the exam exercises.\n",
    "\n",
    "In the file, first, put your name, then proceed with answering to the questions below.\n",
    " Please report all the commands and options used in each exercise.\n",
    "\n",
    "All the exercises should be done on the VDI desktop solely."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a4c20aa",
   "metadata": {},
   "source": [
    "### 1. Compilation and Makefiles (max score 4)\n",
    "\n",
    "- On your desktop, in directory FINAL, create new file ```lu_d.c``` with content taken from the source code published at the following link:\n",
    " https://www.gnu.org/software/gsl/doc/html/linalg.html#examples\n",
    "\n",
    "    Note: you should already have the ```gsl``` libraries installed on your VD from the exam review exercises.\n",
    "\n",
    "- A) Compile ```lu_d.c``` into executable file ```lu_d.x``` and run. \n",
    "\n",
    "- B) Develop makefile ```Makefile```, that includes two targets ```lu_d.x```, and ```clean```. Run commands\n",
    "\n",
    "  ```bash\n",
    "  make clean\n",
    "  make\n",
    "  ```\n",
    "\n",
    "***Answers***\n",
    "\n",
    "A)\n",
    "```bash\n",
    "gcc -o lu_d.x lu_d.c  -lgsl\n",
    "./lu_d.x\n",
    "```\n",
    "\n",
    "B) Makefile:\n",
    "```c\n",
    "lu_d.x: lu_d.c\n",
    "        gcc -o lu_d.x lu_d.c  -lgsl\n",
    "\n",
    "clean:\n",
    "        -rm *.x\n",
    "```\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb78ca69",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "### 2. Python scripting (max score 8)\n",
    "\n",
    "- A) In directory FINAL, develop python script ```lu_a.py``` that reads the source code ```lu_d.c```, then creates new file ```lu_d_new.c``` with  replaced matrix elements in ```a_data[]``` and vector elements in ```b_data[]```. The new matrix and vector elements are shown below:\n",
    "\n",
    "\n",
    "          { 0.2, 0.7, 0.3, 0.9,\n",
    "           0.4, 0.4, 0.9, 0.8,\n",
    "           0.1, 0.3, 0.7, 0.6,\n",
    "           0.5, 0.3, 0.9, 0.5 }\n",
    "\n",
    "           and  { 3.0, 2.0, 4.0, 7.0 }\n",
    "\n",
    "  \n",
    "  Note: Don't import any python modules. Work with the lists.\n",
    "\n",
    "  Hint: you  can read ```lu_d.c``` into a list, remove the slice with the old matrix elements for ```a_data[]```, then replace the line  containing ```a_data[]``` with a string that contains the new elements. Similarly, update the line with ```b_data[]```.\n",
    "\n",
    "  Make sure you can compile ```lu_d_new.c``` and run the executable. Modify the Makefile in 1B to compile the new source file.\n",
    "\n",
    "- B) By modifying script ```lu_a.py```, create python script ```lu_b.py``` that reads the new matrix and vector elements from file ```lu.ini``` and replaces them in the source file.\n",
    "\n",
    "  Note: use module ```configparser``` only. \n",
    "    \n",
    "  \n",
    "- C) By modifying ```lu_b.py```, create python script ```lu_c.py``` that completes the tasks of the script above and also runs three commands below:\n",
    "```bash\n",
    "make clean\n",
    "make\n",
    "./lu_d.x\n",
    "```\n",
    "\n",
    "   Note: use module ```subprocess```\n",
    "\n",
    "***Answers***\n",
    "\n",
    "A) \n",
    "```python\n",
    "#!/usr/bin/env python3\n",
    "\n",
    "matrix_n = \"\"\"\n",
    "          { 0.2, 0.7, 0.3, 0.9,\n",
    "           0.4, 0.4, 0.9, 0.8,\n",
    "           0.1, 0.3, 0.7, 0.6,\n",
    "           0.5, 0.3, 0.9, 0.5 }\n",
    "           \"\"\"\n",
    "\n",
    "vector_n =  \"{ 3.0, 2.0, 4.0, 7.0 }\"\n",
    "\n",
    "code = []\n",
    "count = 0\n",
    "counts_begin = []\n",
    "counts_end = []\n",
    "\n",
    "with open('lu_d.c', 'r') as f:\n",
    "   for line in f:\n",
    "     if 'double a_data[]' in line:\n",
    "         counts_begin.append(count)\n",
    "\n",
    "     if '};' in line:\n",
    "         counts_end.append(count)\n",
    "\n",
    "     count = count + 1\n",
    "     code.append(line)\n",
    "\n",
    "\n",
    "id_start = min(counts_begin)\n",
    "\n",
    "id_end = min(counts_end)\n",
    "while id_end <= id_start:\n",
    "  counts_end.remove(id_end)\n",
    "  id_end = min(counts_end)\n",
    "\n",
    "print(id_start, id_end)\n",
    "\n",
    "del code[id_start+1:id_end+1]\n",
    "\n",
    "code[id_start] = f'double a_data[] = {matrix_n};'\n",
    "\n",
    "code_new = []\n",
    "\n",
    "for line in code:\n",
    "  new_line = line\n",
    "  if 'double b_data[]' in line:\n",
    "     new_line = f'double b_data[] = {vector_n};'\n",
    "\n",
    "  code_new.append(new_line)\n",
    "\n",
    "print(code_new)\n",
    "\n",
    "with open('lu_d_new.c', 'w') as f:\n",
    "  for line in code_new:\n",
    "    f.write(line)\n",
    "```\n",
    "\n",
    "B) File lu.ini:\n",
    "```\n",
    "[MATRIX_PARAMS]\n",
    "matrix_n =\n",
    "          { 0.2, 0.7, 0.3, 0.9,\n",
    "           0.4, 0.4, 0.9, 0.8,\n",
    "           0.1, 0.3, 0.7, 0.6,\n",
    "           0.5, 0.3, 0.9, 0.5 }\n",
    "\n",
    "vector_n =  { 3.0, 2.0, 4.0, 7.0 }\n",
    "```\n",
    "\n",
    "Script lu_b.py:\n",
    "```python\n",
    "#!/usr/bin/env python3\n",
    "\n",
    "import configparser\n",
    "\n",
    "config = configparser.ConfigParser()\n",
    "config.read('lu.ini')\n",
    "\n",
    "matrix_n = config[\"MATRIX_PARAMS\"][\"matrix_n\"]\n",
    "vector_n = config[\"MATRIX_PARAMS\"][\"vector_n\"]\n",
    "\n",
    "code = []\n",
    "count = 0\n",
    "counts_begin = []\n",
    "counts_end = []\n",
    "\n",
    "with open('lu_d.c', 'r') as f:\n",
    "   for line in f:\n",
    "     if 'double a_data[]' in line:\n",
    "         counts_begin.append(count)\n",
    "\n",
    "     if '};' in line:\n",
    "         counts_end.append(count)\n",
    "\n",
    "     count = count + 1\n",
    "     code.append(line)\n",
    "\n",
    "\n",
    "id_start = min(counts_begin)\n",
    "\n",
    "id_end = min(counts_end)\n",
    "while id_end <= id_start:\n",
    "  counts_end.remove(id_end)\n",
    "  id_end = min(counts_end)\n",
    "\n",
    "print(id_start, id_end)\n",
    "\n",
    "del code[id_start+1:id_end+1]\n",
    "\n",
    "code[id_start] = f'double a_data[] = {matrix_n};'\n",
    "\n",
    "code_new = []\n",
    "\n",
    "for line in code:\n",
    "  new_line = line\n",
    "  if 'double b_data[]' in line:\n",
    "     new_line = f'double b_data[] = {vector_n};'\n",
    "\n",
    "  code_new.append(new_line)\n",
    "\n",
    "print(code_new)\n",
    "\n",
    "with open('lu_d_new.c', 'w') as f:\n",
    "  for line in code_new:\n",
    "    f.write(line)\n",
    "```\n",
    "C) Script lu_c.py:\n",
    "```python\n",
    "#!/usr/bin/env python3\n",
    "\n",
    "import configparser, subprocess\n",
    "config = configparser.ConfigParser()\n",
    "config.read('lu.ini')\n",
    "\n",
    "matrix_n = config[\"MATRIX_PARAMS\"][\"matrix_n\"]\n",
    "vector_n = config[\"MATRIX_PARAMS\"][\"vector_n\"]\n",
    "\n",
    "code = []\n",
    "count = 0\n",
    "counts_begin = []\n",
    "counts_end = []\n",
    "\n",
    "with open('lu_d.c', 'r') as f:\n",
    "   for line in f:\n",
    "     if 'double a_data[]' in line:\n",
    "         counts_begin.append(count)\n",
    "\n",
    "     if '};' in line:\n",
    "         counts_end.append(count)\n",
    "\n",
    "     count = count + 1\n",
    "     code.append(line)\n",
    "\n",
    "\n",
    "id_start = min(counts_begin)\n",
    "\n",
    "id_end = min(counts_end)\n",
    "while id_end <= id_start:\n",
    "  counts_end.remove(id_end)\n",
    "  id_end = min(counts_end)\n",
    "\n",
    "print(id_start, id_end)\n",
    "\n",
    "del code[id_start+1:id_end+1]\n",
    "\n",
    "code[id_start] = f'double a_data[] = {matrix_n};'\n",
    "\n",
    "code_new = []\n",
    "\n",
    "for line in code:\n",
    "  new_line = line\n",
    "  if 'double b_data[]' in line:\n",
    "     new_line = f'double b_data[] = {vector_n};'\n",
    "\n",
    "  code_new.append(new_line)\n",
    "\n",
    "print(code_new)\n",
    "\n",
    "with open('lu_d_new.c', 'w') as f:\n",
    "  for line in code_new:\n",
    "    f.write(line)\n",
    "\n",
    "DIR = \"/home/hostadm/FINAL\"\n",
    "out = subprocess.run(f\"cd {DIR}; make clean; make; ./lu_d.x\", shell=True)\n",
    "```\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e86f47ba",
   "metadata": {},
   "source": [
    "### 3. systemd and unit file (max score 4)\n",
    "\n",
    "- Create systemd unit file ```lu_d.service``` to run executable ```lu_d.x``` from directory ```/home/hostadm/FINAL``` as a service.\n",
    "- Start the service:\n",
    "  ```bash\n",
    "  systemctl start lu_d\n",
    "  ```\n",
    "- Verify that the service ran with\n",
    "  ```bash\n",
    "  systemctl status lu_d\n",
    "  ```\n",
    "***Answers***\n",
    "\n",
    "lu_d.service file:\n",
    "\n",
    "```\n",
    "[Unit]\n",
    "Description = start executable lu_d.x\n",
    "\n",
    "[Service]\n",
    "Type = simple\n",
    "ExecStart = /home/hostadm/FINAL/lu_d.x\n",
    "\n",
    "[Install]\n",
    "WantedBy = default.target\n",
    "```\n",
    "\n",
    "Copy it into directory ```/lib/systemd/system``` and reload systemd:\n",
    "```bash\n",
    "sudo cp lu_d.service  /lib/systemd/system\n",
    "sudo systemctl daemon-reload\n",
    "```\n",
    "\n",
    "Run the application through systemd, then veryfy that it ran:\n",
    "```bash\n",
    "systemctl start lu_d\n",
    "systemctl status lu_d\n",
    "```\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "186c8c1b",
   "metadata": {},
   "source": [
    "### 4. Port scanning and firewalling (max score 4)</b>\n",
    "\n",
    "\n",
    "- A) Install ```lighttpd``` on ```cryptvm``` VM. Start the service.\n",
    "\n",
    "- B) Scan the TCP ports on ```cryptvm``` from your VD.\n",
    "\n",
    "- C) Create script ```final_firewall.sh``` on cryptvm to firewall all input connections except SSH. Run the script. Copy the script into your directory FINAL on the VD.\n",
    "\n",
    "- D) Scan ```cryptvm``` from your VD again to make sure only the SSH port shows up.\n",
    "\n",
    "***Answer***\n",
    "\n",
    "A) On cryptvm,\n",
    "```bash\n",
    "apt install lighttpd\n",
    "systemctl start lighttpd\n",
    "```\n",
    "\n",
    "B) On the VD:\n",
    "```bash\n",
    "virsh domifaddr cryptvm\n",
    "nmap -sT 192.168.122.42\n",
    "```\n",
    "```\n",
    "Starting Nmap 7.93 ( https://nmap.org ) at 2026-07-15 20:07 EDT\n",
    "Nmap scan report for 192.168.122.42\n",
    "Host is up (0.0077s latency).\n",
    "Not shown: 998 closed tcp ports (conn-refused)\n",
    "PORT   STATE SERVICE\n",
    "22/tcp open  ssh\n",
    "80/tcp open  http\n",
    "```\n",
    "\n",
    "C) Script  ```final_firewall.sh``` on cryptvm:\n",
    "```c\n",
    "#!/bin/bash\n",
    "\n",
    "IPT=/usr/sbin/iptables\n",
    "\n",
    "$IPT -F INPUT\n",
    "$IPT -F OUTPUT\n",
    "$IPT -F FORWARD\n",
    "\n",
    "$IPT -P INPUT DROP\n",
    "$IPT -P OUTPUT ACCEPT\n",
    "$IPT -P FORWARD DROP\n",
    "\n",
    "$IPT -A INPUT -p icmp  -j ACCEPT\n",
    "$IPT -A INPUT  -m state -p tcp --dport 22  !  --state INVALID  -j ACCEPT\n",
    "```\n",
    "\n",
    "D) Running scans on the VD after the firewall rules were applied:\n",
    "```bash\n",
    "nmap -sT 192.168.122.42  -Pn\n",
    "```\n",
    "```\n",
    "Starting Nmap 7.93 ( https://nmap.org ) at 2026-07-15 20:10 EDT\n",
    "Nmap scan report for 192.168.122.42\n",
    "Host is up (0.00056s latency).\n",
    "Not shown: 999 filtered tcp ports (no-response)\n",
    "PORT   STATE SERVICE\n",
    "22/tcp open  ssh\n",
    "```\n",
    "\n",
    "Fetching the firewall script from cryptvm into directory FINAL:\n",
    "```bash\n",
    "scp 192.168.122.42:final_firewall.sh .\n",
    "```\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5f250f9-2fe0-4610-83bb-cd0541187d27",
   "metadata": {},
   "source": [
    "### Exam summary\n",
    "\n",
    "In your directory FINAL, I should be able to see the following files by the end of the exam:\n",
    "- answers.txt\n",
    "- lu_d.c\n",
    "- lu_d.x\n",
    "- Makefile\n",
    "- lu_a.py, lu_b.py, lu_c.py\n",
    "- lu_d_new.c\n",
    "- lu.ini\n",
    "- lu_d.service\n",
    "- final_firewall.sh"
   ]
  }
 ],
 "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.13.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
