Final exam Q-and-A Summer 2026#

Date: 7/15/2026, time: 6 pm - 9 pm

Number of exercises: 4. Each exercise has a maximum score.

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.

In the file, first, put your name, then proceed with answering to the questions below. Please report all the commands and options used in each exercise.

All the exercises should be done on the VDI desktop solely.

1. Compilation and Makefiles (max score 4)#

  • On your desktop, in directory FINAL, create new file lu_d.c with content taken from the source code published at the following link: https://www.gnu.org/software/gsl/doc/html/linalg.html#examples

    Note: you should already have the gsl libraries installed on your VD from the exam review exercises.

  • A) Compile lu_d.c into executable file lu_d.x and run.

  • B) Develop makefile Makefile, that includes two targets lu_d.x, and clean. Run commands

    make clean
    make
    

Answers

A)

gcc -o lu_d.x lu_d.c  -lgsl
./lu_d.x

B) Makefile:

lu_d.x: lu_d.c
        gcc -o lu_d.x lu_d.c  -lgsl

clean:
        -rm *.x

2. Python scripting (max score 8)#

  • 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:

        { 0.2, 0.7, 0.3, 0.9,
         0.4, 0.4, 0.9, 0.8,
         0.1, 0.3, 0.7, 0.6,
         0.5, 0.3, 0.9, 0.5 }
    
         and  { 3.0, 2.0, 4.0, 7.0 }
    

    Note: Don’t import any python modules. Work with the lists.

    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[].

    Make sure you can compile lu_d_new.c and run the executable. Modify the Makefile in 1B to compile the new source file.

  • 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.

    Note: use module configparser only.

  • 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:

make clean
make
./lu_d.x

Note: use module subprocess

Answers

A)

#!/usr/bin/env python3

matrix_n = """
          { 0.2, 0.7, 0.3, 0.9,
           0.4, 0.4, 0.9, 0.8,
           0.1, 0.3, 0.7, 0.6,
           0.5, 0.3, 0.9, 0.5 }
           """

vector_n =  "{ 3.0, 2.0, 4.0, 7.0 }"

code = []
count = 0
counts_begin = []
counts_end = []

with open('lu_d.c', 'r') as f:
   for line in f:
     if 'double a_data[]' in line:
         counts_begin.append(count)

     if '};' in line:
         counts_end.append(count)

     count = count + 1
     code.append(line)


id_start = min(counts_begin)

id_end = min(counts_end)
while id_end <= id_start:
  counts_end.remove(id_end)
  id_end = min(counts_end)

print(id_start, id_end)

del code[id_start+1:id_end+1]

code[id_start] = f'double a_data[] = {matrix_n};'

code_new = []

for line in code:
  new_line = line
  if 'double b_data[]' in line:
     new_line = f'double b_data[] = {vector_n};'

  code_new.append(new_line)

print(code_new)

with open('lu_d_new.c', 'w') as f:
  for line in code_new:
    f.write(line)

B) File lu.ini:

[MATRIX_PARAMS]
matrix_n =
          { 0.2, 0.7, 0.3, 0.9,
           0.4, 0.4, 0.9, 0.8,
           0.1, 0.3, 0.7, 0.6,
           0.5, 0.3, 0.9, 0.5 }

vector_n =  { 3.0, 2.0, 4.0, 7.0 }

Script lu_b.py:

#!/usr/bin/env python3

import configparser

config = configparser.ConfigParser()
config.read('lu.ini')

matrix_n = config["MATRIX_PARAMS"]["matrix_n"]
vector_n = config["MATRIX_PARAMS"]["vector_n"]

code = []
count = 0
counts_begin = []
counts_end = []

with open('lu_d.c', 'r') as f:
   for line in f:
     if 'double a_data[]' in line:
         counts_begin.append(count)

     if '};' in line:
         counts_end.append(count)

     count = count + 1
     code.append(line)


id_start = min(counts_begin)

id_end = min(counts_end)
while id_end <= id_start:
  counts_end.remove(id_end)
  id_end = min(counts_end)

print(id_start, id_end)

del code[id_start+1:id_end+1]

code[id_start] = f'double a_data[] = {matrix_n};'

code_new = []

for line in code:
  new_line = line
  if 'double b_data[]' in line:
     new_line = f'double b_data[] = {vector_n};'

  code_new.append(new_line)

print(code_new)

with open('lu_d_new.c', 'w') as f:
  for line in code_new:
    f.write(line)

C) Script lu_c.py:

#!/usr/bin/env python3

import configparser, subprocess
config = configparser.ConfigParser()
config.read('lu.ini')

matrix_n = config["MATRIX_PARAMS"]["matrix_n"]
vector_n = config["MATRIX_PARAMS"]["vector_n"]

code = []
count = 0
counts_begin = []
counts_end = []

with open('lu_d.c', 'r') as f:
   for line in f:
     if 'double a_data[]' in line:
         counts_begin.append(count)

     if '};' in line:
         counts_end.append(count)

     count = count + 1
     code.append(line)


id_start = min(counts_begin)

id_end = min(counts_end)
while id_end <= id_start:
  counts_end.remove(id_end)
  id_end = min(counts_end)

print(id_start, id_end)

del code[id_start+1:id_end+1]

code[id_start] = f'double a_data[] = {matrix_n};'

code_new = []

for line in code:
  new_line = line
  if 'double b_data[]' in line:
     new_line = f'double b_data[] = {vector_n};'

  code_new.append(new_line)

print(code_new)

with open('lu_d_new.c', 'w') as f:
  for line in code_new:
    f.write(line)

DIR = "/home/hostadm/FINAL"
out = subprocess.run(f"cd {DIR}; make clean; make; ./lu_d.x", shell=True)

3. systemd and unit file (max score 4)#

  • Create systemd unit file lu_d.service to run executable lu_d.x from directory /home/hostadm/FINAL as a service.

  • Start the service:

    systemctl start lu_d
    
  • Verify that the service ran with

    systemctl status lu_d
    

Answers

lu_d.service file:

[Unit]
Description = start executable lu_d.x

[Service]
Type = simple
ExecStart = /home/hostadm/FINAL/lu_d.x

[Install]
WantedBy = default.target

Copy it into directory /lib/systemd/system and reload systemd:

sudo cp lu_d.service  /lib/systemd/system
sudo systemctl daemon-reload

Run the application through systemd, then veryfy that it ran:

systemctl start lu_d
systemctl status lu_d

4. Port scanning and firewalling (max score 4)#

  • A) Install lighttpd on cryptvm VM. Start the service.

  • B) Scan the TCP ports on cryptvm from your VD.

  • 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.

  • D) Scan cryptvm from your VD again to make sure only the SSH port shows up.

Answer

A) On cryptvm,

apt install lighttpd
systemctl start lighttpd

B) On the VD:

virsh domifaddr cryptvm
nmap -sT 192.168.122.42
Starting Nmap 7.93 ( https://nmap.org ) at 2026-07-15 20:07 EDT
Nmap scan report for 192.168.122.42
Host is up (0.0077s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

C) Script final_firewall.sh on cryptvm:

#!/bin/bash

IPT=/usr/sbin/iptables

$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD

$IPT -P INPUT DROP
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD DROP

$IPT -A INPUT -p icmp  -j ACCEPT
$IPT -A INPUT  -m state -p tcp --dport 22  !  --state INVALID  -j ACCEPT

D) Running scans on the VD after the firewall rules were applied:

nmap -sT 192.168.122.42  -Pn
Starting Nmap 7.93 ( https://nmap.org ) at 2026-07-15 20:10 EDT
Nmap scan report for 192.168.122.42
Host is up (0.00056s latency).
Not shown: 999 filtered tcp ports (no-response)
PORT   STATE SERVICE
22/tcp open  ssh

Fetching the firewall script from cryptvm into directory FINAL:

scp 192.168.122.42:final_firewall.sh .

Exam summary#

In your directory FINAL, I should be able to see the following files by the end of the exam:

  • answers.txt

  • lu_d.c

  • lu_d.x

  • Makefile

  • lu_a.py, lu_b.py, lu_c.py

  • lu_d_new.c

  • lu.ini

  • lu_d.service

  • final_firewall.sh