-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
751 lines (702 loc) · 38.9 KB
/
Copy pathindex.html
File metadata and controls
751 lines (702 loc) · 38.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Operating Systems Weekly Reports</title>
<style>
body {
font-family: "Segoe UI", Arial, sans-serif;
background-color: #0d1117;
color: #e6edf3;
margin: 0;
padding: 0;
line-height: 1.6;
}
header {
background-color: #161b22;
padding: 1.5rem;
text-align: center;
border-bottom: 2px solid #30363d;
}
header h1 {
margin: 0;
color: #58a6ff;
font-size: 2.5rem;
}
main {
max-width: 800px;
margin: 2rem auto;
/*padding: 0 1rem;*/
}
section {
background-color: #1c2128;
border: 1px solid #30363d;
border-radius: 10px;
padding: 1rem 1.5rem;
margin-bottom: 1.5rem;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
width: 100%;
height: auto;
display: inline-block;
}
section h2 {
color: #58a6ff;
}
section h4 {
margin: 0;
color: #ffffff;
border-bottom: 1px solid #30363d;
padding-bottom: 0.3rem;
font-size: 1.0rem;
text-align: right;
}
footer {
text-align: center;
padding: 1rem;
font-size: 0.9rem;
color: #8b949e;
border-top: 1px solid #30363d;
}
a {
color: #58a6ff;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
background-color: #1c2128;
border: 1px solid #30363d;
border-radius: 10px;
overflow: hidden;
height: auto;
display: inline-block;
}
th, td {
padding: 0.75rem 1rem;
border-bottom: 1px solid #30363d;
text-align: left;
vertical-align: top;
}
th {
background-color: #161b22;
color: #58a6ff;
}
tr:last-child td {
border-bottom: none;
}
pre {
background-color: #000000;
padding: 1rem;
border-radius: 8px;
border: 1px solid #30363d;
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
margin: 1rem 0;
}
code {
font-family: "Fira Code", "Courier New", monospace;
background-color: #000000;
color: #e6edf3;
border-radius: 4px;
border: 1px solid #30363d;
font-size: 1rem;
}
.fixed-img {
width: 100%;
height: auto;
display: inline-block;
}
</style>
</head>
<body>
<header>
<h1>Operating Systems Weekly Reports</h1>
<p>By Jack Turner</p>
</header>
<main>
<section>
<h2>Week 1: System Planning and Distribution Selection</h2>
<h4>24/10/2025</h4>
<h3>System Architecture Diagram</h3>
<img src="OSArchitectureDiagram.png" alt="Systems Architecture Diagram" align="middle" class="fixed-img">
<h3>Distribution Selection Justification</h3>
<table>
<thead>
<tr>
<th>Distribution</th>
<th>Pros</th>
<th>Cons</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Ubuntu Server</strong></td>
<td>Widely supported, stable LTS, large community, compatible with VirtualBox</td>
<td>Slightly heavier base install</td>
</tr>
<tr>
<td><strong>Debian</strong></td>
<td>Extremely stable, secure, minimal setup</td>
<td>Older packages, smaller repositories for new tools</td>
</tr>
<tr>
<td><strong>CentOS</strong></td>
<td>Enterprise-level stability, SELinux enabled by default</td>
<td>Steeper learning curve, enterprise-focused tools</td>
</tr>
</tbody>
</table>
<p>After comparing several Linux server distributions, I decided to use <strong>Ubuntu Server</strong> for my project.
I chose Ubuntu because it is stable, easy to configure, and well-documented, which makes it suitable for developing my command-line and remote administration skills.
Although <strong>Debian</strong> is extremely reliable and secure, its slower updates and smaller repositories make it less flexible for experimenting.
On the other hand, <strong>CentOS</strong> is designed more for enterprise environments and has a steeper learning curve.
Overall, Ubuntu provides the best balance between usability, support, and performance for a headless SSH-based setup.</p>
<h3>Workstation Configuration Decision</h3>
<p>The workstation used is my host operating system running on macOS. MacOS provides built in terminal SSH access to the server virtual machine;
this method ensures that all administration is performed remotely, and aligning with professional practices. VirtualBox is used to host the server image and isolating it from the host environment.</p>
<h3>Network Configuration Documentation</h3>
<p>Due to university network restrictions preventing LAN connections over Wi-Fi, I configured my virtual machine
to use a <strong>NAT network</strong> in <strong>VirtualBox 7.2.4</strong> instead of a host-only adapter.
To enable secure remote administration, I created a <strong>port forwarding rule</strong> that maps
SSH traffic from the host (MacBook) to the guest virtual machine. This forwards connections from
<code>127.0.0.1:2222</code> on the host to port <code>22</code> on the virtual machine, allowing me to
connect locally using the command <code>ssh -p 2222 admin@127.0.0.1</code>. This approach avoids
university network restrictions while maintaining a realistic remote management workflow.</p>
<h3>System Specifications</h3>
<p>I used the <code>uname, free, df -h, ip addr, lsb_release</code> commands to provide the following specifications.</p>
<pre><code style="border: 0px">
# uname -a
Linux
# free -h
total used free shared buff/cache available
Mem: 2001372 246300 1165364 1024 678632 1755072
Swap: 0 0 0
# df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 196M 1.2M 195M 1% /run
/dev/sda2 24G 2.7G 20G 12% /
tmpfs 981M 0 981M 0% /dev/shm
/dev/sda1 1.1G 6.4M 1.0G 1% /boot/efi
tmpfs 196M 4.0K 196M 1% /run/user/1000
# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
inet 127.0.0.1/8 scope host lo
2: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 10.0.2.15/24 scope global dynamic enp0s8
# lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 22.04 LTS
</code></pre>
</section>
<section>
<h2>Week 2: Security Planning and Testing Methodology</h2>
<h4>31/10/2025</h4>
<h3>Performance Testing Plane</h3>
<p>For this phase, I plan to design a performance testing and monitoring approach that ensures my Linux server
remains stable and secure during remote administration. I will monitor resource usage using command-line tools such as
<code>top</code>, <code>free</code>, and <code>df -h</code> to assess CPU load, memory utilisation, and disk activity.
Network responsiveness will be tested using <code>ping</code> and <code>traceroute</code>, while service reliability will
be checked through <code>systemctl status ssh</code> and log analysis with <code>journalctl</code>. These results will form
the foundation for comparing performance before and after security hardening, helping to identify any negative impact caused
by configuration changes. By maintaining a clear testing methodology and consistent monitoring approach, I aim to ensure
the system remains efficient, responsive, and secure throughout the deployment.</p>
<h3>Security Configuration Checklist</h3>
<table>
<thead>
<tr>
<th>Area</th>
<th>Action</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>SSH Hardening</strong></td>
<td>Disabled root login, limited login attempts</td>
<td>Prevent brute-force and root access</td>
</tr>
<tr>
<td><strong>Firewall Configuration</strong></td>
<td>Installed & configured UFW</td>
<td>Restrict inbound traffic</td>
</tr>
<tr>
<td><strong>Mandatory Access Control</strong></td>
<td>Verified AppArmor/SELinux active</td>
<td>Enforce application-level security</td>
</tr>
<tr>
<td><strong>Automatic Updates</strong></td>
<td>Enabled unattended-upgrades</td>
<td>Maintain up-to-date security patches</td>
</tr>
<tr>
<td><strong>User Priviledge Management</strong></td>
<td>Created limited user, removed default admin</td>
<td>Principle of least privilege</td>
</tr>
<tr>
<td><strong>Network Security</strong></td>
<td>Checked open ports</td>
<td>Identify unnecessary exposed services</td>
</tr>
</tbody>
</table>
<h3>Threat Model</h3>
<p>The threat model outlines three seperate security concerns and suggests mitigation strategies for each of them.</p>
<ul>
<li>
<strong>Brute-force SSH attacks:</strong> This occurs when an attacker repeatedly attempts to guess login credentials to gain remote access.
To prevent this, I will disable root login, reduced the number of allowed authentication attempts, and configured the firewall to restrict
repeated SSH connections, significantly lowering the chance of unauthorised access.
</li>
<br>
<li>
<strong>Privilege escalation:</strong> This threat involves a regular user gaining administrative access, often through misconfigured permissions
or exploitation of vulnerabilities. I will mitigate this by enforcing the principle of least privilege, creating dedicated non-root user accounts,
and carefully controlling <code>sudo</code> access to minimise the risk of elevated privilege misuse.
</li>
<br>
<li>
<strong>Unpatched software vulnerabilities:</strong> Outdated packages can be exploited by attackers to compromise system security.
To address this, I will enable automatic updates using <code>unattended-upgrades</code> and scheduled periodic manual patch reviews to ensure
that the system remains fully updated with the latest security fixes.
</li>
</ul>
</section>
<section>
<h2>Week 3: Application Selection for Performance Testing</h2>
<h4>14/11/2025</h4>
<h3>Application Selection Matrix</h3>
<p>For performance evaluation, I selected a variety of applications that each represent a different
type of workload. These applications allow me to test CPU, memory, network load and disk I/O to understand how the system performs under different stress conditions.</p>
<table>
<thead>
<tr>
<th>Application</th>
<th>Workload Type</th>
<th>Justification</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>stress-ng --cpu 2</code></td>
<td>CPU-intensive</td>
<td>Generates sustained CPU load, good for analysing processor performance.</td>
</tr>
<tr>
<td><code>stress-ng --vm 1 --vm-bytes 512M</code></td>
<td>RAM-intensive</td>
<td>Allows controlled memory allocation to test RAM pressure and swapping.</td>
</tr>
<tr>
<td><code>iperf3</code></td>
<td>Network-intensive</td>
<td>Measures network throughput and latency under controlled conditions.</td>
</tr>
<tr>
<td><code>dd if=/dev/zero of=testfile bs=1M count=500</code></td>
<td>I/O-intensive</td>
<td>Creates a large file to simulate heavy disk write operations.</td>
</tr>
</tbody>
</table>
<h3>Installation Documentation</h3>
<p></p>All applications were installed remotely over SSH to maintain a headless, command-line focused
administration environment. The following commands were executed after connecting to the server via:
<code>ssh -p 2222 admin@127.0.0.1</code>.</p>
<pre>Update any repositories <code>sudo apt install</code></pre>
<pre>Install network testing tools <code>sudo apt install -y iperf3</code></pre>
<pre>Intsall stress testing tools <code>sudo apt install -y stress-ng</code></pre>
<pre>Install I/O performance analyser <code>sudo apt intall -y fio</code></pre>
<h3>Resource Profiles and Usage</h3>
<ul>
<li><strong>CPU-intensive:</strong> The <code>stress-ng --cpu 2</code> test is expected to cause
near 100% CPU utilisation on the selected cores, with minimal RAM, disk, or network usage.</li>
<li><strong>RAM-intensive:</strong> The <code>stress-ng --vm 1 --vm-bytes 512M</code> test should significantly
increase memory usage, potentially triggering swapping if RAM limits are reached, while CPU and
disk activity remain moderate.</li>
<li><strong>Network-intensive:</strong> Using <code>iperf3</code> should produce high network
throughput and increased socket activity, while CPU, RAM, and disk remain lightly used.</li>
<li><strong>I/O-intensive:</strong> The <code>dd if=/dev/zero of=testfile bs=1M count=500</code> file creation test is expected to generate
high disk write throughput and moderate CPU usage, with minimal RAM and no network activity.</li>
</ul>
<h3>Monitoring Strategy</h3>
<p>To measure system performance during each workload, I created a monitoring strategy using a range of
command-line tools that provide real-time system metrics. CPU and memory usage will be observed using
<code>top</code> and <code>vmstat</code>, which allow me to track load averages, process activity, and
overall memory utilisation. Disk performance will be monitored using <code>iostat</code> and <code>df -h</code>
to measure throughput and file system usage, while network-intensive workloads will be analysed using
<code>ss -tuln</code> and <code>ping</code> to monitor socket activity and latency. Logs will be collected using
<code>journalctl</code> to identify any unusual behaviour or performance issues. Each workload will be measured
before, during, and after execution to compare performance changes across different scenarios and identify
any potential bottlenecks.</p>
</section>
<section>
<h2>Week 4: Initial System Configuration & Security Implementation</h2>
<h4>21/11/25</h4>
<p>I focused on securing my Linux server while managing it entirely through SSH. I implemented key-based authentication,
configured a restrictive firewall, created a non-root administrative user, and documented all changes.
This phase strengthened the server’s security and ensured that all administration was performed remotely and securely.</p>
<h3>Configure SSH</h3>
<p>In this section, I configured the server to use key-based SSH authentication instead of passwords. I generated
a secure key pair, added my public key to the server, and disabled password authentication in the SSH configuration.
This significantly improved the security of remote access by preventing brute-force login attempts.</p>
<img src="PhaseFourSection1.png" alt="Configure SSH" align="middle" class="fixed-img">
<img src="PhaseFourSection1Config.png" alt="Configure SSH Config" align="middle" class="fixed-img">
<h3>Configure Firewall</h3>
<p>Here, I implemented a strict firewall policy to ensure that SSH access is only permitted from my workstation.
By allowing a single source IP, I reduced the server’s attack surface and ensured that no other device can attempt an SSH connection.
This follows the principle of least privilege.</p>
<img src="PhaseFourSection2.png" alt="Configure Firewall" align="middle" class="fixed-img">
<h3>Manage Users</h3>
<p>In this section, I created a dedicated non-root administrative user and granted them the necessary sudo privileges.
This allowed me to disable direct root login while still being able to perform administrative tasks when required.
This step improved accountability and aligned the system with Linux security best practices.</p>
<img src="PhaseFourSection3.png" alt="Manage Users" align="middle" class="fixed-img">
<h3>SSH Access Evidence</h3>
<p>Here, I collected screenshots showing that I could successfully connect to the server via SSH after applying the security changes.
These screenshots provide proof that key-based authentication works and that I can administer the system without relying on insecure methods.</p>
<img src="PhaseFourSection4.png" alt="SSH Access Evidence" align="middle" class="fixed-img">
<h3>Configuration Files</h3>
<p>In this section, I documented the changes I made to important configuration files, such as <code>sshd_config</code>. I included “before and after” comparisons
to clearly show how I modified system settings and explain why each change was necessary for security.</p>
<p>Before:</p>
<img src="PhaseFourSection5Before.png" alt="Configuration Files Before" align="middle" class="fixed-img">
<p>After:</p>
<img src="PhaseFourSection5After.png" alt="Configuration Files After" align="middle" class="fixed-img">
<h3>Firewall Documentation</h3>
<p>For this part, I captured the full firewall ruleset using commands such as ufw status numbered. I explained what each rule does and how it contributes to securing the server.
This documentation provides a clear overview of the system’s network-level protections.</p>
<img src="PhaseFourSection6.png" alt="Firewall Documentation" align="middle" class="fixed-img">
<h3>Remote Administration Evidence demonstrating commands executed via SSH</h3>
<p>In the final section, I demonstrated that all system changes were carried out remotely via SSH, in line with the module’s requirements.
I gathered evidence of administrative commands being executed from my workstation to show that I managed the server headlessly without relying on the VirtualBox console.</p>
<p>I had to update both UFW and my SSH key configuration because the VM was blocking legitimate SSH traffic and rejecting my authentication. VirtualBox NAT forwards connections
from the host as coming from <code>10.0.2.2</code>, not <code>127.0.0.1</code>, so UFW was silently dropping the packets until I added a rule allowing SSH from the NAT gateway. At the same time,
password authentication had been disabled for security, but the VM did not yet contain the correct public key from my Mac. This caused SSH to reject every login attempt until
I added my key to authorized_keys and configured my Mac to use the correct private key.</p>
<img src="PhaseFourSection7Config.png" alt="SSH Evidence Config File" align="middle" class="fixed-img">
<img src="PhaseFourSection7UFW.png" alt="SSH Evidence Firewall" align="middle" class="fixed-img">
<img src="PhaseFourSection7Update.png" alt="SSH Evidence Update" align="middle" class="fixed-img">
<img src="PhaseFourSection7Exit.png" alt="SSH Evidence Exit" align="middle" class="fixed-img">
</section>
<section>
<h2>Week 5: Advanced Security and Monitoring Infrastructure</h2>
<h4>28/11/2025</h4>
<h3>Implementing Access Control Using AppArmor</h3>
<p>To strengthen the server’s security posture, I enabled mandatory access control using AppArmor, which restricts program behaviour through profile-based rule enforcement.
This adds an additional layer of defence beyond standard UNIX permissions, ensuring that even if an application is compromised, its actions remain tightly controlled by its assigned security profile.
I installed the necessary AppArmor tools using <code>sudo apt update</code> and <code>sudo apt install -y apparmor apparmor-utils</code>, then ensured the service was active with <code>sudo systemctl enable --now apparmor</code>.
To generate evidence for my journal and confirm that AppArmor was correctly enforcing policies, I used <code>sudo aa-status</code> to list all active profiles and their modes.
This provides a clear demonstration of how access control is applied at the system level and how profile enforcement can be monitored and reported as part of continuous security management.</p>
<h3>Configuring Automatic Security Updates</h3>
<p>To ensure the server stays protected against newly discovered vulnerabilities, I configured automated security updates using the unattended-upgrades package.
Automated patching is essential for reducing the window of exposure caused by delayed manual updates, especially on headless or remotely administered systems.
I installed the update automation tools with <code>sudo apt install -y unattended-upgrades apt-listchanges</code> and enabled them using <code>sudo dpkg-reconfigure --priority=low unattended-upgrades</code>,
which configures the system to automatically apply security patches. I verified that the service was functioning properly with <code>sudo systemctl enable --now unattended-upgrades</code> and <code>sudo systemctl status unattended-upgrades</code>,
then collected evidence of recent patch activity using <code>sudo journalctl -u unattended-upgrades --no-pager | tail -n 50</code>. These commands demonstrate that the system is consistently receiving security patches without manual intervention,
strengthening long-term system resilience.</p>
<h3>Configure fail2ban</h3>
<p>To protect the server against brute-force attacks, I deployed and configured fail2ban, which automatically monitors authentication logs and bans IP addresses that repeatedly fail login attempts. This significantly reduces the attack surface for
SSH and protects against automated intrusion attempts, which are common across public networks. I began by installing fail2ban with <code>sudo apt install -y fail2ban</code>, then created a local jail configuration using
<pre><code style="border: 0px">
sudo bash -c 'cat > /etc/fail2ban/jail.d/ssh.local EOF
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
EOF'</code></pre>
to enable SSH protection, set a maximum of three failed attempts, and apply a one-hour ban time. I activated the service with <code>sudo systemctl restart fail2ban</code> and verified its operation using both <code>sudo fail2ban-client status</code>
and <code>sudo fail2ban-client status sshd</code>. These commands confirm that fail2ban is actively monitoring <code>/var/log/auth.log</code> and automatically enforcing bans, providing a strong intrusion detection and mitigation mechanism for the server.</p>
<h3>Security Baseline Verification Script</h3>
<p>The <code>security-baseline.sh</code> script runs on the server and automatically checks that all security controls from weeks 4 and 5 are correctly configured. It verifies AppArmor, automatic updates, fail2ban, SSH hardening, firewall rules, and authorised keys.
This script is needed because it provides a quick, repeatable way to confirm that the system’s security posture is stable and has not drifted from the intended configuration.</p>
<pre><code style="border: 0px">
#!/bin/bash
# security-baseline.sh
# Purpose: verify the server's security configuration (Phase 4 & 5). Run as root or with sudo.
# Usage: sudo ./security-baseline.sh
set -euo pipefail
# Helper: print section header
header() {
echo
echo "==================== $1 ===================="
}
header "Date / Host"
date
hostnamectl
header "1) AppArmor status"
if command -v aa-status >/dev/null 2>&1; then
aa-status || apparmor_status || true
else
echo "AppArmor tools not installed."
fi
header "2) Unattended upgrades"
if systemctl is-active --quiet unattended-upgrades 2>/dev/null; then
echo "unattended-upgrades: active"
sudo journalctl -u unattended-upgrades --no-pager | tail -n 10
else
echo "unattended-upgrades: NOT active"
fi
header "3) fail2ban"
if command -v fail2ban-client >/dev/null 2>&1; then
sudo fail2ban-client status || true
echo "SSH jail status:"
sudo fail2ban-client status sshd || echo "sshd jail not configured"
else
echo "fail2ban not installed."
fi
header "4) SSH hardening checks"
SSHD_CONFIG="/etc/ssh/sshd_config"
echo "Checking $SSHD_CONFIG for common hardening settings..."
sudo grep -E "^(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|PermitEmptyPasswords|ChallengeResponseAuthentication)" "$SSHD_CONFIG" || true
# Check that password authentication is disabled
if sudo grep -qE "^PasswordAuthentication\s+no" "$SSHD_CONFIG" ; then
echo "PasswordAuthentication disabled (OK)"
else
echo "Warning: PasswordAuthentication not set to 'no'"
fi
# Check root login disabled
if sudo grep -qE "^PermitRootLogin\s+no" "$SSHD_CONFIG" ; then
echo "PermitRootLogin disabled (OK)"
else
echo "Warning: PermitRootLogin not set to 'no'"
fi
header "5) UFW rules (firewall)"
if command -v ufw >/dev/null 2>&1; then
sudo ufw status verbose
else
echo "UFW not installed."
fi
header "6) Authorized keys for 'admin' user"
ADMIN_HOME=$(getent passwd admin | cut -d: -f6 2>/dev/null || echo "/home/admin")
if [ -f "$ADMIN_HOME/.ssh/authorized_keys" ]; then
echo "authorized_keys exists:"
sudo ls -l "$ADMIN_HOME/.ssh/authorized_keys"
sudo tail -n 5 "$ADMIN_HOME/.ssh/authorized_keys"
else
echo "No authorized_keys file for admin"
fi
header "7) Basic resource snapshot"
echo "Memory:"
free -h
echo "Disk:"
df -h /
echo "Uptime and load:"
uptime
echo
echo "Security baseline verification complete."
</code></pre>
<img src="VerificationScript1.png" alt="Verification Script 1" align="middle" class="fixed-img">
<img src="VerificationScript2.png" alt="Verification Script 2" align="middle" class="fixed-img">
<img src="VerificationScript3.png" alt="Verification Script 3" align="middle" class="fixed-img">
<img src="VerificationScript4.png" alt="Verification Script 4" align="middle" class="fixed-img">
<img src="VerificationScript5.png" alt="Verification Script 5" align="middle" class="fixed-img">
<h3>Remote Monitoring Script</h3>
<p>The <code>monitor-server.sh</code> script runs from my workstation and connects to the server via SSH to collect live performance and security metrics. It captures information such as memory usage,
disk space, active processes, and recent authentication logs, saving everything into a timestamped report. This script is important because it allows remote health monitoring without direct server access,
demonstrating automated administration and early issue detection.</p>
<pre><code style="border: 0px">
#!/bin/bash
# monitor-server.sh
# Connect to server via SSH and collect performance metrics for remote monitoring.
# ./monitor-server.sh admin@127.0.0.1 -p 2222
set -euo pipefail
# Parse args (simple)
REMOTE="${1:-admin@127.0.0.1}"
SSH_OPTS="-p 2222 -o BatchMode=yes -o StrictHostKeyChecking=accept-new"
OUTDIR="./monitor-output"
mkdir -p "$OUTDIR"
TIMESTAMP=$(date -u +"%Y%m%dT%H%M%SZ")
OUTFILE="$OUTDIR/metrics-$TIMESTAMP.txt"
echo "Collecting metrics from $REMOTE at $TIMESTAMP"
{
echo "==== Host info ===="
ssh $SSH_OPTS "$REMOTE" 'hostnamectl; uname -a'
echo
echo "==== Memory ===="
ssh $SSH_OPTS "$REMOTE" 'free -h'
echo
echo "==== Disk ===="
ssh $SSH_OPTS "$REMOTE" 'df -h'
echo
echo "==== Top processes (snapshot) ===="
ssh $SSH_OPTS "$REMOTE" 'ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head -n 15'
echo
echo "==== Network connections ===="
ssh $SSH_OPTS "$REMOTE" 'ss -tuln | head -n 20'
echo
echo "==== Recent auth logs (last 100 lines) ===="
ssh $SSH_OPTS "$REMOTE" 'sudo tail -n 100 /var/log/auth.log || sudo journalctl -u ssh -n 100 --no-pager'
echo
echo "==== Security baseline (quick) ===="
ssh $SSH_OPTS "$REMOTE" 'sudo /usr/local/bin/security-baseline.sh || echo "security-baseline.sh not present"'
} > "$OUTFILE"
echo "Saved metrics to $OUTFILE"
</code></pre>
</section>
<section>
<h2>Week 6: Performance Evaluation and Analysis</h1>
<h4>5/12/2025</h4>
<h3>Documentation of Approach</h3>
<p>I conducted performance tests using selected workloads to measure CPU, memory, disk I/O, network throughput, and latency.
Baseline measurements were collected with monitoring tools (vmstat, free, iostat, ping). Stress tests were executed using stress-ng,
iperf3, and dd, with outputs captured for comparison. After identifying bottlenecks, I applied two optimisations (noatime and reduced swappiness),
re-ran tests, and recorded improvements. Data was organised into structured tables and visualised with charts for clear analysis</p>
<h3>Performance Data Table</h3>
<table>
<thead>
<tr>
<th>Workload</th>
<th>Test Type</th>
<th>CPU Usage</th>
<th>Memory Usage</th>
<th>Disk I/O</th>
<th>Network</th>
<th>Latency</th>
</tr>
</thead>
<tbody>
<tr>
<td>Baseline</td>
<td>Idle System</td>
<td>9% (top)</td>
<td>284 MB used / 1065 MB free</td>
<td>–</td>
<td>–</td>
<td>–</td>
</tr>
<tr>
<td>CPU-Intensive</td>
<td><code>stress-ng --cpu 2</code></td>
<td>~198% across 2 vCPUs</td>
<td>290 MB used</td>
<td>–</td>
<td>–</td>
<td>–</td>
</tr>
<tr>
<td>RAM-Intensive</td>
<td><code>stress-ng --vm 1 --vm-bytes 512M</code></td>
<td>~15%</td>
<td>400 MB used / 950 MB free</td>
<td>–</td>
<td>–</td>
<td>–</td>
</tr>
<tr>
<td>Disk I/O</td>
<td><code>dd if=/dev/zero of=testfile</code></td>
<td>~35% (top)</td>
<td>300 MB used</td>
<td>2.3 GB/s write throughput</td>
<td>–</td>
<td>–</td>
</tr>
<tr>
<td>Network Throughput</td>
<td><code>iperf3 -c 10.0.2.2</code></td>
<td>18% (top)</td>
<td>–</td>
<td>–</td>
<td>620 Mbps (2 retransmits)</td>
<td>avg 0.355 ms</td>
</tr>
</tbody>
</table>
<h3>Performance Visualisations</h3>
<img src="cpu-usage.png" alt="CPU Usage" align="middle" class="fixed-img">
<img src="ram-usage.png" alt="Ram Usage" align="middle" class="fixed-img">
<img src="disk-io.png" alt="Disk I/O" align="middle" class="fixed-img">
<img src="network.png" alt="Network" align="middle" class="fixed-img">
<h3>Testing Evidence</h3>
<img src="Week6TestData1.png" alt="Test Data 1" align="middle" class="fixed-img">
<img src="Week6TestData2.png" alt="Test Data 2" align="middle" class="fixed-img">
<h3>Network Performance Analysis</h3>
<p>Network performance testing was carried out to measure both latency and throughput between the virtual machine and the host system.
Latency was assessed using the <code>ping -c 20 10.0.2.2</code> command, which sent 20 ICMP echo requests to the host gateway and recorded a low and stable
average round-trip time of approximately 0.327 ms with 0% packet loss, indicating reliable network connectivity. Network throughput was then evaluated using iperf3,
with the server started on the VM using <code>iperf3 -s</code> and the client connecting via the loopback interface using <code>iperf3 -c 127.0.0.1</code>. This approach was used due to VirtualBox NAT
networking limitations and allowed accurate testing of the operating system’s TCP/IP stack. The test achieved an average throughput of approximately 71.1 Gbit/s,
demonstrating high network stack performance within the virtualised environment.</p>
<img src="Week6NetworkAnalysis1.png" alt="Network Analysis 1" align="middle" class="fixed-img">
<img src="Week6NetworkAnalysis2.png" alt="Network Analysis 2" align="middle" class="fixed-img">
<img src="Week6NetworkAnalysis3.png" alt="Network Analysis 3" align="middle" class="fixed-img">
<h3>Optimisation Analysis</h3>
<p>System swappiness was reduced to minimise unnecessary use of swap memory and prioritise keeping active processes in physical RAM. By lowering the swappiness value using <code>sysctl</code>,
the system is less likely to move memory pages to swap under normal workloads, reducing disk I/O and improving overall responsiveness. This optimisation is particularly beneficial for
a virtualised server with sufficient available RAM, resulting in more predictable memory performance under load.</p>
<img src="Week6OptimisationSwappiness.png" alt="Optimisation Swappiness" align="middle" class="fixed-img">
<p>The <code>apport.service</code> was disabled to remove unnecessary background processes related to crash reporting, which are not required in a controlled server environment.
Disabling Apport reduces background resource usage and prevents the generation of diagnostic data during faults, improving system efficiency and stability.
This optimisation aligns with best practices for production servers where performance and reliability are prioritised over interactive debugging features.</p>
<img src="Week6OptimisationAutoService1.png" alt="Optimisation Auto Service 1" align="middle" class="fixed-img">
<img src="Week6OptimisationAutoService2.png" alt="Optimisation Auto Service 2" align="middle" class="fixed-img">
</section>
<section>
<h2>Week 7: Security Audit and System Evaluation</h2>
<h4>12/12/2025</h4>
<p>I completed a comprehensive security audit to evaluate the
overall system configuration and identify any remaining weaknesses. The audit
combined automated security scanning, network analysis, access control
verification, and service auditing to assess the effectiveness of security
controls implemented in previous phases.</p>
<h3>Infrastructure Security Assessment (Lynis)</h3>
<p>Lynis was used to perform a detailed security audit of the operating system,
assessing kernel configuration, authentication settings, logging, and system
hardening measures. The audit was run before and after remediation to
demonstrate measurable security improvements.</p>
<pre><code style="border: 0px">sudo apt install lynis -y sudo lynis audit system</code></pre>
<h3>Network Security Testing (nmap)</h3>
<p>Network exposure was assessed using nmap to identify open ports and confirm
that only essential services were accessible. This validated that firewall
rules and service hardening were correctly applied.</p>
<pre><code style="border: 0px">nmap -sS -p- 127.0.0.1 nmap -sS -p 22 127.0.0.1</code></pre>
<h3>SSH Security Verification</h3>
<p>SSH configuration was manually verified to ensure password authentication was
disabled, key-based authentication was enforced, and root login was restricted.
This confirms secure remote administration practices are in place.</p>
<pre><code style="border: 0px">sudo sshd -T | grep -E "passwordauthentication|pubkeyauthentication|permitrootlogin"</code></pre>
<h3>Access Control Verification (AppArmor)</h3>
<p>Mandatory Access Control was verified using AppArmor to ensure that active
security profiles were enforced, reducing the attack surface of system
services.</p>
<pre><code style="border: 0px">sudo aa-status</code></pre>
<h3>Service Inventory and Justification</h3>
<p>All enabled and running services were reviewed to ensure they were necessary
for the server’s role. Non-essential services were identified and removed,
while critical services such as SSH, UFW, and Fail2Ban were retained.</p>
<pre><code style="border: 0px">systemctl list-unit-files --type=service --state=enabled systemctl list-units --type=service --state=running</code></pre>
<h3>Risk Assessment</h3>
<p>The system demonstrates a strong security posture following hardening and
remediation. Remaining risks include potential zero-day vulnerabilities and
reliance on SSH for administration. These risks are mitigated through
restricted access, automated security updates, firewall controls, and
intrusion detection mechanisms.</p>
</section>
<section id="coursework-video">
<h2>Coursework Demonstration Video</h2>
<p>This video demonstrates the practical implementation of system configuration,
security hardening, monitoring, performance testing, and auditing as required
for the Operating Systems module coursework.</p>
<video controls width="100%" preload="metadata">
<source src="OSCoursework_Demonstration_Github.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</section>
</main>
<footer>
© 2025 Jack Turner | Operating Systems Module
</footer>
</body>
</html>