
Sections
- Introduction
- Where to practice
- IO Redirection
- LVM
- Advanced Permissions
- Special Bits
- Security Limit / Resource Limit
- Fallocate and Swap
- Manage Virtual Machines (libvirt)
- Others
- Conclusion
Introduction
Holy fuck, I lost basic, very, very much!
Where to practice
IO Redirection
I think this is the most command I often used but never understand correctly, LOL. Yes, it is 2>&1. But no more, today I swear I will remember and understand it! So let's take an example:
./script.sh > output.txt 2>&1
./script.sh will give to output
bob@ubuntu-host ~ ✖ ./script.sh
/home/bob
./script.sh: line 2: lss: command not found
This part > output.txt: can be understood as redirect stdout (file descriptor 1) into file output.txt
This part 2>&1: can be understood as redirect stderr (file descriptor 2) into file descriptor 1 pointed to. At this time file descriptor 1 already getting redirected into output.txt, so file descriptor 2 will go together xD
And order is important
- It must be
> output.txt 2>&1. Example:
bob@ubuntu-host ~ ➜ ./script.sh > output.txt 2>&1
bob@ubuntu-host ~ ✖ cat output.txt
/home/bob
./script.sh: line 2: lss: command not found
- If
2>&1 > asd.txt: only stdout getting into file. Example:
bob@ubuntu-host ~ ➜ ./script.sh 2>&1 > asd.txt
./script.sh: line 2: lss: command not found
bob@ubuntu-host ~ ✖ cat asd.txt
/home/bob
Shell Redirection Cheat sheet:
> file 2>&1Redirects both stdout and stderr to a file (the most standard/compatible method).&> fileShorthand for the above (supported in bash and zsh).>> file 2>&1Appends both stdout and stderr to a file.2>/dev/nullDiscards error messages (stderr); keeps only the standard output.
Redirection Use Cases:
./script.sh > output.txt 2>&1Captures everything (logs + errors) into a single file../script.sh > /dev/null 2>&1Total silence; suppresses all output and error messages completely../script.sh 2> error.txtRedirects only the errors to a file; the normal logs will still show up on your terminal.
And the last, we had fd2/fd1 so what is fd0? It is standard input (stdin). Example: mysql database_name < backup.sql
LVM (Logical Volume Manager)
To be honest, I rarely use LVM in OpenStack environments because my managed platforms are Elasticsearch, Kafka, which all support multiple disks. You know in the OpenStack environment, 1 volume 10 GB has 200 IOPS, but 2 volumes 5 GB have 400 IOPS. Same size but double IOPS, that is why I used multi disk.
But when it comes to MongoDB, it needs to use LVM since MongoDB doesn't support multi-disk. But It was a lab setup without document write back, so it is like fire and forget mode -.-
So that is a story for simple knowledge everyone remembers and understands, but not me xD. So this is "day one" instead of "one day"!
Physical Volume (PV)
They are physical volumes (P) like /dev/sdb or disk partition /dev/sda1 you want to put it in LVM system.
- Init PV:
pvcreate /dev/sdb(turn/dev/sdbinto material for LVM) - Check PV:
pvdisplayorpvs
Example:
### PV Create
root@caleston-lp10 ~ ➜ pvcreate /dev/vdb /dev/vdc
Physical volume "/dev/vdb" successfully created.
Physical volume "/dev/vdc" successfully created.
### PV Display
root@caleston-lp10 ~ ➜ pvdisplay
"/dev/vdb" is a new physical volume of "1.00 GiB"
--- NEW Physical volume ---
PV Name /dev/vdb
VG Name
PV Size 1.00 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID aaPJMu-vtoq-yU0a-xsg4-LwPV-IYE4-TRb1sF
"/dev/vdc" is a new physical volume of "1.00 GiB"
--- NEW Physical volume ---
PV Name /dev/vdc
VG Name
PV Size 1.00 GiB
Allocatable NO
PE Size 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID y1Mod8-Li2M-i7NR-Yqg4-mjZt-gEos-M4EwSe
root@caleston-lp10 ~ ➜ pvs
PV VG Fmt Attr PSize PFree
/dev/vdb lvm2 --- 1.00g 1.00g
/dev/vdc lvm2 --- 1.00g 1.00g
- Remove PV from LVM:
pvremove /dev/vdc
root@caleston-lp10 ~ ➜ pvremove /dev/vdc
Labels on physical volume "/dev/vdc" successfully wiped.
root@caleston-lp10 ~ ➜ pvs
PV VG Fmt Attr PSize PFree
/dev/vdb lvm2 --- 1.00g 1.00g
Volume Group (VG)
Group of physical volumes (V). You group all the PVs together into one large group called VGs.
VG named by you, ex: VG named "my-vg"
Command to create VG: vgcreate volume-name pv-here
root@caleston-lp10 ~ ➜ vgcreate volume1 /dev/vdb
Volume group "volume1" successfully created
Command to check VG: vgdisplay or vgs
Extend VG by adding PV: vgextend volume-name pv-here
root@caleston-lp10 ~ ➜ vgextend volume1 /dev/vdc
Physical volume "/dev/vdc" successfully created.
Volume group "volume1" successfully extended
# Before add pv /dev/vdc to vg volume1, it was 1 PV and Vsize 1.00g
root@caleston-lp10 ~ ➜ vgs
VG #PV #LV #SN Attr VSize VFree
volume1 2 0 0 wz--n- 1.99g 1.99g
Remove PV from VG: vgreduce volume-name pv-here
root@caleston-lp10 ~ ➜ vgreduce volume1 /dev/vdc
Removed "/dev/vdc" from volume group "volume1"
root@caleston-lp10 ~ ➜ vgs
VG #PV #LV #SN Attr VSize VFree
volume1 1 0 0 wz--n- 1020.00m 1020.00m
Logical Volume (LV)
from big VG, you divide it into smaller or all to use called LV (L).
Relationship: 1 VG can divide into 1 or more LV
Init command: Create LV named smalldata, size 0.5 G from VG volume1.
root@caleston-lp10 ~ ✖ lvcreate -L 0.5G -n smalldata volume1
Logical volume "smalldata" created.
root@caleston-lp10 ~ ➜ lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
smalldata volume1 -wi-a----- 512.00m
Display LV command: lvs or lvdisplay
Resize LV to 752 MB: param can be -L or --size xD
root@caleston-lp10 ~ ✖ lvresize -L 752M volume1/smalldata
Size of logical volume volume1/smalldata changed from 512.00 MiB (128 extents) to 752.00 MiB (188 extents).
Logical volume volume1/smalldata successfully resized.
root@caleston-lp10 ~ ➜ lvresize --size 753M volume1/smalldata
Rounding size to boundary between physical extents: 756.00 MiB.
Size of logical volume volume1/smalldata changed from 752.00 MiB (188 extents) to 756.00 MiB (189 extents).
Logical volume volume1/smalldata successfully resized.
While lvresize can reduce size of LV, lvextend can not
lvextend -l +100%FREE /dev/VG1/LV1 # Add 100% free of VG1 to LV1
lvextend -L 5G /dev/VG1/LV1 # Add LV1 Size to 5Gb, error if current size > 5G
lvextend -l +100%FREE -r /dev/VG1/LV1 # -r auto resize fs
Destroy/Remove LV from VG
root@caleston-lp10 ~ ➜ lvremove volume1/smalldata
Do you really want to remove and DISCARD active logical volume volume1/smalldata? [y/n]: y
Logical volume "smalldata" successfully removed
root@caleston-lp10 ~ ➜ vgs
VG #PV #LV #SN Attr VSize VFree
volume1 1 0 0 wz--n- 1020.00m 1020.00m
root@caleston-lp10 ~ ➜ lvs
Create filesystem from LV
XFS or EXT4, your choice
Command: mkfs.xfs /dev/volume1/smalldata
mkfs.xfs /dev/volume1/smalldata
Advanced Permissions
Get ACL
Question: Check permission for user john in file archive
root@caleston-lp10 ~ ➜ ls -lia
total 44
1572865 drwx------. 7 root root 4096 Dec 29 05:16 .
2 drwxr-xr-x. 19 root root 4096 Sep 19 2024 ..
1572885 -rw-r--r--+ 1 root root 0 Dec 29 05:16 archive
We already know others only has read permission, and john is in others. There is another way give same output
root@caleston-lp10 ~ ➜ getfacl archive
# file: archive
# owner: root
# group: root
user::rw-
user:john:r--
group::r--
mask::r--
other::r--
Set ACL
We have this file specialfile, we want to add john can read and write it
root@caleston-lp10 ~ ✖ getfacl specialfile
# file: specialfile
# owner: root
# group: root
user::rw-
group::r--
other::r--
###
root@caleston-lp10 ~ ➜ setfacl --modify user:john:rw specialfile # Alternative: setfacl -m u:john:rw specialfile
root@caleston-lp10 ~ ➜ getfacl specialfile |grep john
user:john:rw-
### For group mail and permission read and execute
root@caleston-lp10 ~ ➜ setfacl --modify group:mail:rx specialfile
### For recursive within folder
setfacl --recursive --modify user:john:rwx collection/
Remove ACL
root@caleston-lp10 ~ ✖ setfacl --remove user:john specialfile
root@caleston-lp10 ~ ➜ getfacl specialfile |grep john
Create Raid 1
Question: Create Raid 1 named /dev/md0 with 2 disk /dev/vdb /dev/vdc
root@caleston-lp10 ~ ➜ mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/vdb /dev/vdc
mdadm: Note: this array has metadata at the start and
may not be suitable as a boot device. If you plan to
store '/boot' on this device please ensure that
your boot-loader understands md/v1.x metadata, or use
--metadata=0.90
Continue creating array?
Continue creating array? (y/n) y
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
Special Bits
Haha, I still don't remember this enough like common permission. I guess I rarely use it. So this is a chance for me, to write a document, whenever I forget, I read this document again!
SetUID (Set User ID): 4
So when execute a binary that have this bit, anyone executes that file will has permission like owner of file (permission borrow?)
Example: passwd
Symbol: rwsr-xr-x ==> 4755
ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 59976 Feb 6 2024 /usr/bin/passwd*
If owner doesn't have executes:
# ll
-rw-rw-r--. 1 bob bob 0 Dec 29 07:47 test.txt
# chmod 4644 test.txt && ll
-rwSr--r--. 1 bob bob 0 Dec 29 07:47 test.txt
SetGID (Set Group ID): 2
This is more interesting, especially when applied to directories.
-
On a file: When you run the file, it runs with the group permissions of the file’s group owner (you "borrow" the group’s rights).
-
On a directory (this is the most common and useful case):
Any file or subdirectory created inside this folder will automatically inherit the group owner of the parent directory — instead of taking the group of the user who created it.
Real benefit: In team shared folders, this ensures everyone in the same group can read, write, and manage each other’s files without needing to manually change ownership every time.
Sticky Bit: 1
This commonly used by directory to protect file getting deleted.
Mechanic: If folder has stick bit set, only owner or root has permission to delete/rename/... that file.
Example: /tmp folder, Everyone can create file in that, but you can not delete file of other user
Symbol: t in the last (rwxrwxrwt)
drwxrwxrwt. 11 root root 4096 Dec 29 07:48 tmp/
Security Limit / Resource Limit
Haha, I often used for increase max open file of mysql server instance. Read /etc/security/limits.conf
Scenario: Set limit for user john that he can open no more than 30 process. Set limit for user jane that she can not create file more than 1024kb, soft limit
john hard nproc 30
jane soft fsize 1024
Fallocate and Swap
For the exam....
fallocate -l 1024M /swfile # Locate file
chmod 600 /swfile # Change permission
mkswap /swfile # Create swap
swapon /swfile # Enable swap
/swfile none swap sw 0 0 # mount on boot in /etc/fstab
Manage Virtual Machines (libvirt)
Shiet, I have no fucking idea about this!!!!
Question:
For the operating system information parameter use the ubuntu22.04.
Name the virtual machine mockexam2.
Assign 1024 MB of RAM to this machine.
Assign it one virtual CPU.
Import the disk image /var/lib/libvirt/images/ubuntu.img to this virtual machine.
At the end of your command, you can add the parameter --noautoconsole to avoid waiting for this virtual machine to boot up, and not get stuck in the virtual console after it initializes.
Answer copied:
# Install
sudo virt-install \
--name mockexam2 \
--memory 1024 \
--vcpus 1 \
--os-variant ubuntu22.04 \
--disk path=/var/lib/libvirt/images/ubuntu.img \
--import \
--noautoconsole
# Auto start
sudo virsh autostart mockexam2
Check:
root@caleston-lp10 ~ ➜ virsh list --all
Id Name State
---------------------------
1 mockexam2 running
Create new VM with New Disk:
sudo virt-install \
--name myvm \
--memory 2048 \
--vcpus 2 \
--os-variant ubuntu22.04 \
--disk size=20 \
--cdrom /path/to/ubuntu.iso \
--network network=default \
--graphics vnc \
--noautoconsole
Others
Find process eating high IO
First find process first: iotop or pidstat -d 1
SELinux
Get current SELinux mode: getenforce or more detail with sestatus
sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: default
Current mode: permissive
Mode from config file: permissive
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: requested (insecure)
Max kernel policy version: 33
Check if file that has the wrong SELinux type label:
ls -Z /usr/bin/less
system_u:object_r:user_tmp_t:s0 /usr/bin/less
Fix:
root@node01 ~ ➜ restorecon -v /usr/bin/less
root@node01 ~ ➜ ls -Z /usr/bin/less
system_u:object_r:bin_t:s0 /usr/bin/less
Create bridge network
Question: have 2 interfaces eth1 and eth2,turn DHCP off
Answer: edit file /etc/netplan/60-bridge.yaml
network:
version: 2
ethernets:
eth1:
dhcp4: no
eth2:
dhcp4: no
bridges:
bridge1:
interfaces: [eth1, eth2]
dhcp4: yes
Run command: netplan apply
Check:
root@node01 ~ ➜ ip addr show bridge1
6: bridge1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 22:17:8b:bb:af:16 brd ff:ff:ff:ff:ff:ff
inet 172.28.128.239/24 metric 100 brd 172.28.128.255 scope global dynamic bridge1
valid_lft 3585sec preferred_lft 3585sec
inet6 fe80::2017:8bff:febb:af16/64 scope link
valid_lft forever preferred_lft forever
root@node01 ~ ➜ bridge link show
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master bridge1 state forwarding priority 32 cost 100
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master bridge1 state forwarding priority 32 cost 100
For Exam: man netplan
Iptables
- Redirect rule: redirects any IPv4 packet from the 10.5.5.0/24 CIDR range incoming on port 81 to another machine with the IP address 192.168.5.2 on port 80.
sudo iptables -t nat -A PREROUTING -p tcp -s 10.5.5.0/24 --dport 81 -j DNAT --to-destination 192.168.5.2:80
- masquerading rule so that packets redirected from 10.5.5.0/24 have a way of getting back to that sender
sudo iptables -t nat -A POSTROUTING -s 10.5.5.0/24 -j MASQUERADE
- Make it persistent:
sudo apt install iptables-persistent
OpenSSL Cheat Sheet for LFCS
- Generate Private Key
openssl genrsa -out server.key 2048
- Generate CSR (Certificate Signing Request)
openssl req -new -key server.key -out server.csr
- Generate Self-signed Cert (single command)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt
- View Information
# View cert
openssl x509 -in server.crt -noout -text
openssl x509 -in server.crt -noout -subject
openssl x509 -in server.crt -noout -dates
# View CSR
openssl req -in server.csr -noout -text
# View private key
openssl rsa -in server.key -check
- Verify cert and key match
openssl x509 -in server.crt -noout -modulus | md5sum
openssl rsa -in server.key -noout -modulus | md5sum
# Both must be identical
- Quick Reference
| Task | Keyword |
|---|---|
| Generate key | genrsa |
| Generate CSR | req -new |
| Generate self-signed | req -x509 |
| View cert | x509 -in |
| View CSR | req -in |
- Basic Flow
genrsa → req -new → CA sign → .crt
- Or shortcut:
req -x509 -newkey(generate key + cert at once)
Conclusion
This exam is considered easy to pass because it requires only 67 to pass! In fact, I only spent 2 days preparing.
Passing this exam doesn't make me satisfied, I am satisfied with the progress, what I learned and remembered while preparing for this exam!
Scored 86/100, not too bad! Hats off to people who scored 100/100, since there are some questions that are really advanced and require deep knowledge to score!
Thanks to KodeKloud for providing good mock exams!