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.cwith content taken from the source code published at the following link: https://www.gnu.org/software/gsl/doc/html/linalg.html#examplesNote: you should already have the
gsllibraries installed on your VD from the exam review exercises.A) Compile
lu_d.cinto executable filelu_d.xand run.B) Develop makefile
Makefile, that includes two targetslu_d.x, andclean. Run commandsmake 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.pythat reads the source codelu_d.c, then creates new filelu_d_new.cwith replaced matrix elements ina_data[]and vector elements inb_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.cinto a list, remove the slice with the old matrix elements fora_data[], then replace the line containinga_data[]with a string that contains the new elements. Similarly, update the line withb_data[].Make sure you can compile
lu_d_new.cand run the executable. Modify the Makefile in 1B to compile the new source file.B) By modifying script
lu_a.py, create python scriptlu_b.pythat reads the new matrix and vector elements from filelu.iniand replaces them in the source file.Note: use module
configparseronly.C) By modifying
lu_b.py, create python scriptlu_c.pythat 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.serviceto run executablelu_d.xfrom directory/home/hostadm/FINALas 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
lighttpdoncryptvmVM. Start the service.B) Scan the TCP ports on
cryptvmfrom your VD.C) Create script
final_firewall.shon cryptvm to firewall all input connections except SSH. Run the script. Copy the script into your directory FINAL on the VD.D) Scan
cryptvmfrom 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