<h1>
Operating System Overview - Linux
</h1>
<h2>
Tổng quan về Linux
</h2>
<h3>
File System
</h3>
**Linux File System** được cấu thành từ 3 lớp quan trọng. Lớp đầu tiên, `Logical File System` là giao diện cho người dùng có thể tương tác với File System, giúp cho người dùng có thể thực hiện các hành động như Mở, Viết và Xóa file. Lớp tiếp theo, `Virtual File System` đem lại tính ổn định cho nhiều lớp Physical File Systems. Cuối cùng là `Physical File System`, nó chịu trách nhiệm quản lý và lưu trữ các `khối bộ nhớ vật lý` (Physical memory blocks) trên disk, giúp đảm bảo việc `phân vùng dữ liệu` (data allocation) và `lấy dữ liệu` (Data retrieval).
=> Tổng quan 3 layers trên giúp cho Linux kết nối, ổn định và hiệu quả trong quá trình sử dụng.
<h4>
Cấu trúc
</h4>

*Logical File System*:
Là giao diện giúp người dùng tương tác với file system. Điều này giúp cho người dùng có thể thực hiện các hành động như mở, đóng hay xóa file. Nó cũng phục vụ giao diện thân thiện với người dùng, và đảm bảo rằng người dùng có thể tương tác với file đúng như cách mà họ mong muốn.
*Virtual File System* (VFS):
VFS được thiết kế để giúp cho nhiều instance của lớp Physical File System chạy đồng thời. Nó giúp đem lại một giao diện được chuẩn hóa, cho phép các file systems khác cùng tồn tại và cùng hoạt động. Đồng thời, VFS còn giúp trừu tượng hóa các tính năng phức tạp, tăng sự ổn định và nhất quán giữa các file systems được thêm vào.
*Physical File System*:
Chịu trách nhiệm trong việc quản lý và lưu trữ các `Physical Memory Blocks` trên đĩa. Nó lưu các dữ liệu tầng thấp và lấy dữ liệu đó, cũng như tương tác trực tiếp với hardware components. Physical File System cũng giúp đảm bảo việc `phân vùng dữ liệu` (data allocation) và `lấy dữ liệu` (Data retrieval).
<h4>
Đặc điểm
</h4>
`Quản lý không gian lưu trữ (Space Management)`:
Cách dữ liệu được lưu trữ trên thiết bị lưu trữ. Liên quan đến việc quản lý các khối nhớ (memory blocks) và các biện pháp chống phân mảnh được áp dụng trong hệ thống đó.
`Tên tập tin (Filename)`:
Một hệ thống tập tin có thể có những hạn chế nhất định về tên tập tin như độ dài tên, việc sử dụng ký tự đặc biệt, và việc phân biệt chữ hoa chữ thường.
`Thư mục (Directory)`:
Các thư mục/thư mục con có thể lưu trữ tập tin theo kiểu tuyến tính (linear) hoặc phân cấp (hierarchical), đồng thời duy trì một bảng chỉ mục (index table) chứa tất cả các tập tin trong thư mục hoặc thư mục con đó.
`Siêu dữ liệu (Metadata)`:
Đối với mỗi tập tin được lưu, hệ thống tập tin lưu trữ nhiều thông tin liên quan đến sự tồn tại của tập tin đó như độ dài dữ liệu, quyền truy cập, loại thiết bị, ngày giờ chỉnh sửa, và các thuộc tính khác. Những thông tin này được gọi là siêu dữ liệu (metadata).
`Tiện ích (Utilities)`:
Hệ thống tập tin cung cấp các chức năng như khởi tạo, xóa, đổi tên, di chuyển, sao chép, sao lưu, phục hồi, và kiểm soát quyền truy cập cho tập tin và thư mục.
`Thiết kế (Design)`:
Do cách triển khai, mỗi hệ thống tập tin sẽ có những giới hạn nhất định về dung lượng dữ liệu mà nó có thể lưu trữ.
<h4>
Các loại Linux File Systems
</h4>

`ext (Extended File System)`:
Được triển khai vào năm 1992, đây là hệ thống tập tin đầu tiên được thiết kế riêng cho Linux. Nó là thành viên đầu tiên của họ ext.
`ext2`:
Phiên bản ext thứ hai, phát triển năm 1993. Đây là hệ thống tập tin không có tính năng journaling nên thường được ưu tiên sử dụng cho USB hoặc SSD. ext2 giải quyết các vấn đề về lưu trữ riêng biệt thời gian truy cập, sửa đổi inode và sửa đổi dữ liệu. Vì không có journaling nên tốc độ tải lúc khởi động khá chậm.
`Xiafs`:
Cũng phát triển vào năm 1993, hệ thống tập tin này kém mạnh mẽ và chức năng hơn ext2 nên đã bị khai tử, không còn được sử dụng nữa.
`ext3`:
Ra đời năm 1999, là hệ thống tập tin có journaling. ext3 đáng tin cậy hơn, và không còn hiện tượng phải chờ lâu khi khởi động nếu hệ thống trước đó tắt không đúng cách. ext3 cũng hỗ trợ tăng trưởng file system trực tuyến (online), và có chỉ mục HTree giúp xử lý thư mục lớn tốt hơn.
`JFS (Journaled File System)`:
Được IBM phát triển đầu tiên năm 1990 và mã nguồn mở trên Linux năm 1999. JFS hoạt động hiệu quả với nhiều loại tải khác nhau, nhưng hiện ít dùng vì ext4 (ra mắt năm 2006) có hiệu năng tốt hơn.
`ReiserFS`:
Hệ thống tập tin journaling, phát triển năm 2001. Từng có nhiều vấn đề nhưng nổi bật với "tail packing" giúp giảm phân mảnh bên trong. Sử dụng cây B+ (B+ Tree) giúp tìm kiếm, cập nhật thư mục hiệu quả. Từng là mặc định trên SUSE Linux cho đến phiên bản 6.4, sau đó chuyển sang ext3 từ bản 10.2 (2006).
`XFS`:
XFS là hệ thống tập tin 64-bit có journaling, được port sang Linux năm 2001. Hiện là mặc định trên nhiều distro Linux. XFS hỗ trợ snapshot, chống phân mảnh online, file thưa (sparse file), block size thay đổi, dung lượng lớn, và hiệu năng tốt với I/O song song.
`SquashFS`:
Ra đời năm 2002, chỉ hỗ trợ đọc (read-only), thường dùng trong hệ nhúng (embedded) do overhead thấp.
`Reiser4`:
Là phiên bản nâng cấp của ReiserFS, phát triển năm 2004. Tuy nhiên, không được hỗ trợ rộng rãi trên các distro Linux.
`ext4`:
Ra mắt năm 2006, có journaling. Tương thích ngược với ext2, ext3, và bổ sung nhiều tính năng: phân bổ trước dữ liệu (persistent pre-allocation), không giới hạn số thư mục con, kiểm tra tổng (checksum) metadata, hỗ trợ file lớn, và tương thích với cả Windows, Mac.
`btrfs (Better/Butter/B-tree FS)`:
Phát triển năm 2007, nổi bật với các tính năng như snapshot, gộp ổ (drive pooling), kiểm tra và sửa lỗi tự động (data scrubbing, self-healing), chống phân mảnh online. Hiện là mặc định trên Fedora Workstation.
`bcachefs`:
Là hệ thống tập tin copy-on-write, công bố năm 2015, hướng tới hiệu năng vượt trội hơn btrfs và ext4. Có đầy đủ tính năng mã hóa (encryption), nén (compression), snapshot, và kiểm tra tổng 64-bit.
`Các hệ thống khác`:
Linux còn hỗ trợ các file system của hệ điều hành khác như NTFS (Windows) và exFAT, tuy nhiên không hỗ trợ quyền (permission) Unix chuẩn. Chủ yếu dùng để trao đổi dữ liệu giữa các hệ điều hành.
<h4>
Tree
</h4>

| Thư mục | Ý nghĩa, chức năng |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `/` | **Root**: Thư mục gốc, mọi thứ đều bắt đầu từ đây. |
| `/bin` | Chứa các lệnh hệ thống cơ bản, **bắt buộc phải có** (vd: `ls`, `cp`, `mv`, `cat`, `bash`). |
| `/sbin` | Lệnh hệ thống dành cho quản trị (superuser/root), như `ifconfig`, `shutdown`. |
| `/etc` | Chứa file **cấu hình hệ thống** và các dịch vụ (vd: `/etc/passwd`, `/etc/ssh/sshd_config`). |
| `/dev` | Chứa file đại diện **thiết bị vật lý** (vd: `/dev/sda`, `/dev/tty0`, `/dev/null`). |
| `/proc` | Chứa thông tin về **tiến trình (process)** và thông số kernel ở dạng file ảo (virtual file). Vd: `/proc/cpuinfo`, `/proc/1234/`. |
| `/sys` | Cấu trúc ảo, cung cấp thông tin và kiểm soát thiết bị, driver kernel (hotplug, quản lý power). |
| `/lib`, `/lib64` | Thư viện động hỗ trợ cho các lệnh trong `/bin` và `/sbin` (vd: `libc.so.6`). |
| `/usr` | Phần mềm người dùng cài thêm, các thư viện, mã nguồn, tài liệu; có nhiều nhánh con như `/usr/bin`, `/usr/lib`, `/usr/local`. |
| `/var` | Dữ liệu thay đổi thường xuyên như **log, mail, spool, cache**. Vd: `/var/log/syslog`, `/var/spool/cron/`. |
| `/tmp` | Lưu file tạm thời, sẽ bị xóa khi khởi động lại. |
| `/home` | Thư mục cá nhân của user thông thường. Vd: `/home/anhshidou/`. |
| `/root` | Thư mục cá nhân của user **root** (superuser). |
| `/boot` | Chứa file khởi động hệ thống như kernel (`vmlinuz`), initramfs, bootloader (`grub`). |
| `/media` | Điểm mount tạm thời cho thiết bị di động như USB, CD/DVD. |
| `/mnt` | Dùng để mount hệ thống tập tin tạm thời bởi admin. |
| `/opt` | Lưu trữ phần mềm bổ sung (optional packages), thường là ứng dụng bên thứ ba. |
| `/srv` | Dữ liệu cho các dịch vụ máy chủ (service), vd: `/srv/ftp/`, `/srv/www/`. |
Để kiểm tra xem trong directory có những file/directory con nào thì ta có thể sử dụng `tree`

<h3>
Process
</h3>
<h4>
Định nghĩa
</h4>
Khi một chương trình được thực thi, một process tương ứng với chương trình đó sẽ được tạo. Nó bao gồm tất cả các services/tài nguyên mà nó cần để thực thi.
<h4>
Đặc điểm
</h4>
Thông tin của Process được lưu ở trong thư mục `/proc`.
`/proc` là một thư mục có mặt trên tất cả các hệ thống Linux. Nó không phải là một real file system mà là một virtual file system được tạo bởi Linux cung cấp các thông tin của phần cứng và các process đang chạy.
Trong thư mục `/proc`, ta sẽ thấy rất nhiều thư mục, file và link. Các thư mục có số chứa thông tin của process có process ID là tên của thư mục. Các file có chứa thông tin phần cứng như: `cpuinfo`, `meminfo` hay các file system được hỗ trợ bởi Linux kernel (`filesystems`)

Một số file, thư mục quan trọng trong thư mục chứa thông tin process:
- `exe`: Dynamic link tới file thực thi của process
- `maps`: Chứa thông tin về các thư viện được load vào trong memory, địa chỉ tương ứng
- `cwd`: Dynamic link tới working directory của process
- `root`: Dynamic link tới work directory của process
- `cmdline`: chứa command start process
- `environ`: Chứa tên và giá trị của các biến môi trường của process
- `fd`: File descriptor của các object mà process đã mở
- `limits`: Chứa thông tin về giới hạn của process
- `mounts`: Liệt kê các file system được mount vào namespace của process. Mount namespace là tính năng cho phép process có các mount point khác biệt so với phần còn lại của hệ thống. Điều này có nghĩa là trong namespace, process có thể mount hoặc unmount mà không ảnh hưởng tới phần còn lại.
- `stack`: Xem call stack hiện tại của process.

<h4>
Memory Layout
</h4>
Bộ nhớ cấp phát cho mỗi một process được chia thành nhiều phần khác nhau, được gọi là các segment

##### Text Segment
- Chứa các chỉ lệnh ngôn ngữ máy của chương trình.
- Bởi vì một chương trình có thể chạy nhiều process nên phần text segment được thiết lập là sharable giúp các process có thể chia sẻ vùng bộ nhớ này giúp tiết kiệm tài nguyên.
- Segment này có quyền read-only.
##### Initialized data segment
- Bao gồm các biến toàn cục và biến tĩnh được khởi tạo một cách tường minh.
- Segment này có quyền read, write
##### Uninitialized data segment
- Bao gồm các biến toàn cục và biến static không được khởi tạo một cách tường minh.
- Segment này còn được gọi là BSS segment
- Lý do cần chia các biến toàn cục và biến static thành 2 phần vì ta không cần thiết phải cấp phát cho các biến uninitialized bởi vì điều này có thể làm size của chương trình tăng lên.
- Segment này có quyền read, write.
##### Heap segment
- Segment dành cho việc cấp phát bộ nhớ một cách tự động (sử dụng các hàm như `alloc()`, `malloc()`,…)
- Head có thể co dãn tương tự stack. Điểm kết thúc của Heap được gọi là `Program break`.
- Segment này có quyền read, write
##### Stack segment
- Có thể co dãn vùng nhớ bằng cách cấp phát hoặc giải phóng các stack frame. Khi có lời gọi tới một hàm, một stack frame sẽ được tạo cho hàm đó nhằm mục đích lưu trữ các thông tin về các biến cục bộ, các argument của hàm và giá trị return. Stack frame sẽ được giải phóng sau khi hàm kết thúc.
- Segment này có quyền read, write.
<h4>
Quản lý Process
</h4>
`ps`
Là một công cụ liệt kê tĩnh các process đang chạy

`top`
Cung cấp real-time view của các process chạy trên hệ thống

`kill`
Gửi signal tới process, có thể được sử dụng để terminate process.
`pstree`
Mô tả một view phân bậc của proces chạy trên hệ thống theo dạng tree.
#### Một số process quan trọng
##### Init hoặc Systemd
*Image Path:* `/usr/lib/systemd/systemd — switched-root — system — deserialize 21` (systemd) hoặc `/sbin/init`
*Parent Process:* Không có
*Number of Instance:* 1
*Process ID:* 1
*Parenct Process ID: 0*
*Session ID:* 1
*User account:* root
*Start time:* Trong vòng vài phút kể từ khi system boot.
*Mô tả:* Là process đầu tiên được chạy sau khi boot và tiếp tục chạy cho đến khi hệ thống tắt đi. Nó là process cha trực tiếp hoặc gián tiếp của tất cả các process.
##### [kthreadd] (Kernel thread process)
*Image Path:* N/A
*Parent Process:* Không có
*Number of Instance:* 1
*Process ID:* 2
*Parenct Process ID: 0*
*Session ID:* 0
*User account:* root
*Start time:* Trong vòng vài phút kể từ khi system boot.
*Mô tả:* Là một worker thread trong vùng nhớ của kernel, được chạy bởi kernel, chịu trách nhiệm lập lịch và quản lý tất cả các kernel thread. Nó không có image path và chỉ được chạy duy nhất dưới kernel mode. Một số child process:
- [migration/0]: Thread này có nhiệm vụ chuyển các process sang CPU khác để cân bằng tải.
- [crypto]: Cung cấp truy cập vào kernel cryto API để có thể mã hóa hoặc giả mã dữ liệu.
- [kworker/0:0]: Là một process giữ chỗ cho các kernel worker thread, thực hiện đa số các quá trình thực tế cho kernel, đặc biệt là trong các trường hợp interrupts, timers, I/O,…
##### systemd-journald
*Image Path:* `/usr/lib/systemd/systemd-journald`
*Parent Process:* Systemd
*Number of Instance:* 1
*Process ID:* Đa dạng
*Parenct Process ID: 1*
*User account:* root
*Start time:* Trong vòng vài phút kể từ khi system boot.
*Mô tả:* Là một system service thu thập và lưu lại các dữ liệu log.
##### systemd-udevd
*Image Path:* `/usr/lib/systemd/systemd-udevd`
*Parent Process:* Systemd
*Number of Instance:* 1
*Process ID:* Đa dạng
*Parenct Process ID: 1*
*User account:* root
*Start time:* Trong vòng vài phút kể từ khi system boot.
*Mô tả:* Là một system service nghe các kernel uevent và thực thi các chỉ dẫn được ghi trong udev rules (`udev.conf`) ví dụ như chạy một program, script,…
##### systemd-logind
*Image Path:* `/usr/lib/systemd/systemd-logind`
*Parent Process:* Systemd
*Number of Instance:* 1
*Process ID:* Đa dạng
*Parenct Process ID: 1*
*User account:* root
*Start time:* Trong vòng vài phút kể từ khi system boot.
*Mô tả:* Là một system service quản lý user session. Nó chịu trách nhiệm:
- Session Management: Theo dõi user và session, các process của nó cũng như trạng thái dỗi của nó.
- Seat Management: Seat là các thiết bị vật lý mà người dùng có thể tương tác với hệ thống như là bàn phím, chuột, màn hình. Hỗ trợ nhiều người dùng có thể có các session độc lập để truy cập vào hệ thống..
##### dbus
*Image Path:* `/usr/bin/dbus-daemon`
*Parent Process:* Systemd
*Number of Instance:* 1 systemwide process và 1 sessionwide process với môi trường cho phép nhiều session sử dụng cùng một `dbus-daemon` như GNOME
*Process ID:* Đa dạng
*Parenct Process ID: 1*
*User account:* `messsagebus` hoặc người dùng đăng nhập vào hệ thống
*Start time:* Trong vòng vài phút kể từ khi system boot với systemwide process và thời gian người dùng đăng nhập vào hệ thống với sessionwide process.
*Mô tả:* Sử dụng D-Bus library để làm trung gian cho các chương trình gửi message. Có 2 loại message bus instance: Systemwide message bus và session message bus.
##### cron
*Image Path:* `/usr/sbin/cron`
*Parent Process:* Systemd
*Number of Instance:* 1
*Process ID:* Đa dạng
*Parenct Process ID: 1*
*User account:* root
*Start time:* Trong vòng vài phút kể từ khi system boot
*Mô tả:* Chịu trách nhiệm thực thi các schedule task hoặc job tại một thời điểm được mô tả theo lịch được định nghĩa sẵn trong các file (`/etc/crontab`, `/etc/cron.d/*`)
##### agetty
*Image Path:* `/sbin/agetty`
*Parent Process:* Systemd
*Number of Instance:* 1
*Process ID:* Đa dạng
*Parenct Process ID: 1*
*User account:* root
*Start time:* Trong vòng vài phút kể từ khi system boot
*Mô tả:* Là “get tty” - một chương trình quản lý các terminal thật và ảo cho phép nhiều người dùng truy cập.
<h3>
Service
</h3>
<h4>
Định nghĩa
</h4>
`Service` là một process hoặc một ứng dụng được chạy ngầm. Nó thực hiện một task được định nghĩa từ trước hoặc chờ đợi một event nào đó.
`Daemon` là một long-running background process. Nó thực hiện một nhiệm vụ nào đó mà không cần sự tương tac với người dùng. Tên của daemon thường kết thúc bằng chữ `d` (sshd, httpd,…)
Một service có thể là một hoặc là kết hợp của nhiều daemon và các process, ứng dụng khác.
Ở hệ thống Linux, service được quản lý với hệ thống và service manager được gọi là `systemd`. `systemd` có vai trò khởi tạo và quản lý các service của hệ thống.
Mỗi service được định nghĩa ở trong một service file, chứa thông tin về service cũng như cách nó hoạt động và nhiệm vụ của nó.
`.service` file
`.service` file là một file config được sử dụng bởi systemd, để định nghĩa và quản lý service.
<strong>Vị trị của `.service` file</strong>
`.service` file có thể được chứa ở:
- `lib/systemd/system`: Chứa các service file cung cấp bởi các package (ví dụ như sshd được cung cấp bởi OpenSSH packet)
- `run/systemd/system`: Chứa các service file được tạo ở runtime, được tạo bởi quản trị viên hoặc system script. Sẽ bị xóa khi hệ thống reboot.
- `etc/systemd/system`: Chứa các service file ghi đè lên file có sẵn hoặc service file được tạo bởi quản trị viên.
<h4>
Cấu trúc
</h4>
- Cấu trúc file gồm 3 phần:
- `[Unit]`: Chứa các thông tin chung của service như là mô tả, tài liệu và điều kiện của nó được chạy
- `[Service]`: Định nghĩa cách mà service được chạy và quản lý. Nó bao gồm các thông tin như là địa chỉ file thực thi, các tham số command-line, các biến môi trường,…
- `[Install]`: Chứa các thông tin về các program, service cần nó.
- `[Unit]` section:
- **Description:** Mô tả về service. Cung cấp mô tả dễ hiểu cho người dùng
- **Documetation:** Chứa các tài liệu (file path hay URL liên quan đến service)
- **Requires**: Chứa các unit phải được bắt đầu trước nó. Nếu unit này fail thì service sẽ không thể chạy
- **After:** Chứa các unit cần được chạy trước service. Nếu unit này fail thì service vẫn chạy bình thường
- `[Service]` section:
- **Type:** Định nghĩa các mà process được thực thi. Ví dụ như: `simple` (service chạy ngay lập tức khi process trong directive `ExecStart` được chạy), `forking` (service chạy khi process trong directive `ExecStart` được chạy và parent process exit), `oneshot` (service chạy khi process trong directive `ExecStart`exit, dùng cho shorrt-task và chạy 1 lần)
- **ExecStart:** Command line để chạy service
- **Environment:** Các biến môi trường của service
- **WorkingDirectory:** Chỉ ra working directory của service
- **User:** Chỉ ra user chạy service
- **Group:** Chỉ ra group mà service sẽ chạy
- **Restart:** Định nghĩa tình huống mà service sẽ được restart khi
- **RestartSec:** Thiết lập khoảng thời gian chờ trước khi restart service
- **LimitNOFILE:** Thiết lập số lượng lớn nhất các file descriptor mà service cần có.
- **StandardOutput:** Chỉ ra địa điểm mà standard output sẽ được redirect
- **StandardError:** Chỉ ra địa điểm mà standard error sẽ được redirect
- `[Install]` Section:
- **WantedBy:** Chỉ ra các unit nếu nó được chạy thì service nên được chạy. Nếu service chạy fail thì unit cần nó vẫn sẽ được chạy.
- **RequiredBy:** Chỉ ra các unit nếu nó được chạy thì service phải chạy. Nếu service chạy fail, unit cần nó cũng sẽ fail.
<h4>
Quản lý service trên linux
</h4>
- Liệt kê service đang chạy

Start/restart/stop/enable/disable Service:
```systemctl start/restart/stop/enable/disable <service_name>```
Kiểm tra trạng tháu của service
```systemctl status <service_name>```
Reload lại các file configure của systemd:
```systemctl daemon-reload```
<h3>
User and Group user
</h3>
<h4>
User
</h4>
<h5>
Định nghĩa
</h5>
User trên HĐH Linux được gắn liền với 1 tài khoản người dùng có chứa các thuộc tính định nghĩa danh tính và quyền của tài khoản trong hệ thống. Các thuộc tính này là username, UserID, Group ID, home directory, default shell và mật khẩu.
<h5>
Các kiểu tài khoản của User
</h5>
- `Admin hoặc Non-admin account`: Tài khoản người dùng có thể là tài khoản admin hoặc không. Admin là tài khoản superuser (root user) với toàn bộ các quyền trên toàn bộ hệ thống. Tài khoản không phải admin thì sẽ chỉ có quyền truy cập vào một số file hệ thống, cấu hình giới hạn. Có `UID` = 0
- `Normal account`: Là tài khoản củ người dùng thật. Mỗi cá nhân sẽ có một tài khoản để đăng nhập và có quyền truy cập giới hạn vào các ứng dụng, file và tài nguyên trên hệ thống. Có `UID` từ 1 tới 999
- `System account`: Thường là tài khoản không đại diện cho con người và được tạo bởi máy tính. System account được tạo để chạy một chương trình, dịch vụ nào đó như là web server hoặc backup program. Loại tài khoản này có quyền truy cập hạn chế và chỉ có quyền truy cập đủ để quản lý các tiến trình chạy bởi người dùng đó. Có `UID` từ 1000 trở lên.
<h5>
Quản lý user trên linux
</h5>
File `/etc/passwd`: Được đọc bởi tất cả các user. Chứa thông tin về tất cả các tài khoản người dùng theo dạng:
```
username:password:UID:GID:comment:home:shell
```

Ngày xưa, `/etc/passwd` có lưu giá trị hash của password nhưng do để đảm bảo an toàn, tránh các người dùng xem được password hash của người khác thì giá trị của password này có giá trị là `x`
- File **`/etc/shadow`**: Được đọc bởi người dùng root và nhóm admin. Chứa các thông tin về mật khẩu của người dùng. Đây là các trường của một tài khoản trong `/etc/shadow`:
- `last password change`: Thời gian kể từ khi password thay đổi
- `min`: Thời gian tối thiểu mà người dùng có thể thay đổi mật khẩu lần nữa
- `max`: Thời gian tối đa mà password là vailid
- `warning`: Số ngày trước khi password hết hạn mà hệ thống sẽ gửi thông báo tới người dùng
- `inactive`: Thời gian mà tài khoản vẫn còn hoạt động khi password đã hết hạn.
- `expired`: Thời gian mà tài khoản bị vô hiệu hóa vĩnh viễn
```
username:password:last password change:min:max:warning:inactive:expired
```
*Kiểm tra thông tin user*:

*Chỉnh thông tin user*:

*Xóa user*:

<h4>
Group user
</h4>
<h5>
Định nghĩa
</h5>
Group là một nhóm các user, hỗ trợ việc quản lý một nhóm người dùng một cách đồng thời.
<h5>
Phân loại
</h5>
Có 3 cách phân loại:
- Phân loại theo nhóm chính/phụ:
- `Primary Group`: Là nhóm mặc định mà người dùng thuộc về. Mỗi người dùng trong hệ thống đều sẽ có một primary group và được ghi ở trong file `/etc/passwd`
- `Secondary Group`: Là nhóm mà người dùng được thêm vào (ví dụ như dùng lệnh `usermod -aG`). Một người dùng có tối đa 15 secondary group và có thể xem các nhóm này trong file `/etc/group`.
- Phân loại theo cách tạo ra:
- `System Group`: Thường có ID < 1000. Nhuwngxn hóm này được tạo ra và sử dụng bởi HĐH và các dịch vụ hệ thống (`root`, `daemon`, `bin`)
- `User Group`: Thường có ID > 1000. Nhóm này được tạo ra để đại diện cho các người dùng có trong hệ thống.
- Phân loại theo quyền sử dụng:
- `Administrative Groups`: Nhóm này có quyền đặc biệt để thực hiện các tác vụ của quản trị viên. Ví dụ: `sudo` (nhóm người dùng có quyền chạy lệnh với quyền root bằng lệnh sudo),
- `Functional Groups`: Nhóm được tạo ra để hỗ trợ một chức năng hoặc dịch vụ củ thể (`ftp`, `www-data`)
<h4>
Quản lý
</h4>
Xem thông tin group trong file etc/group: Password được set là x và password hash sẽ được lưu trong file etc/gshadow. Tuy nhiên có rất hiểm nhóm có password
```
name:password:GID:member_list
```
*Chỉnh sửa*


*Xóa group*

<h3>
Phân quyền trong Linux
</h3>
<h4>
Định nghĩa
</h4>
Mỗi file và directory trong linux có owner và group sở hữu nó. Người dùng và group này sẽ có nhiều quyền hơn những người, nhóm khác.
<h4>
Cấu trúc
</h4>
Sử dụng `ls -la` để liệt kê file cùng các quyền của nó

Lần lượt là quyền của owner, group và other.
- d ở đây là directory
- Thay đổi owner của tài nguyên: `chown <ten user> <file-path>`
- Thay đổi quyền truy cập vào tài nguyên: `chmod 777 <file-path>` hoặc `chmod u=rwx,g=rwx,o=rwx <file-path>`
Ngoài các quyền cơ bản đọc, viết, thực thi, có một số mode bổ sung trên linux:
- `+t mode` (sticky bit): Chỉ có chủ của tài nguyên (hoặc tài khoản root) có thể xóa hoặc đổi tên tài nguyên. Chú ý là `sticky mode` không ngăn người dùng có quyền write trong thư mục bao quanh tài nguyên xóa hoặc đổi tên file, nên ta cần set `sticky mode` cho cả thư mục đó
```
chmod +t <file-path>
chmod -t <file-path>
```
- `+s mode` (setuid bit): Cho phép người dùng có quyền thực thi file thì có thể chạy dưới quyền owner của tài nguyên. Ví dụ, một file tên work được sở hữu bởi root user và nhóm marketing có quyền thực thi nó. Nếu +s mode được bật, bất kỳ người dùng nào trong nhóm marketing có thể thực thi file work. Cần cẩn thận khi sử dụng
```
chmod g+s /usr/bin/work
```
#### Cấu hình login
- Cấu hình liên quan đến đăng nhập và tài khoản người dùng được chứa trong file `/etc/login.def`:
- `UID_MIN`: ID nhỏ nhất cho normal user
- `UID_MAX`: ID lớn nhất cho normal user
- `GID_MIN`: ID nhỏ nhất cho normal group
- `GID_MAX`: ID lớn nhất cho normail group
- `PASS_MAX_DAYS`: Thời gian tối đa password là valid trước khi người dùng cần thay đổi nó.
- `PASS_MIN_DAYS`: Thời gian tối thiểu trước khi người dùng có thể thay đổi mật khẩu.
- `CREATE_HOME`: Mặc định có tạo home directory cho user không.
- `ENCRYPT_METHOD`: Password có được hash không.
- `UMASK`: Thiết lập default mask cho file được tạo bởi người dùng.
- `LOGIN_TIMEOUT`: Thời gian mà phiên đăng nhập valid
#### Sudo Linux Group
`root` là một tại khoản super user và có quyền làm tất cả mọi thứ trên hệ thống. Để tạo thêm một tầng bảo mật `sudo` user được sử dụng để thay thế root. `sudo` thường được sử dụng để cho phép người dùng có quyền quản trị viên nhất định mà không cần đăng nhập vào tài khoản `root`.
Để có thể thực hiện sudo, ngươi dùng cần được thêm vào nhóm sudo hoặc username phải được thêm vào `sudoers` file với quyền nhất định.
Do `sudoers` file rất nhạy cảm và việc sửa nó trực tiếp có thể gây nên việc `sudo` không hoạt động đúng, ta nên sử dụng `visudo` để edit sudoers file.
Nội dung của file `sudoers`:

<h3>
Linux Log
</h3>
<h4>
Định nghĩa
</h4>
Linux Log là các file lưu lại các thông tin liên quan tới event, application và kernel. Khi gặp vấn đề nào đó, những file này sẽ là một tài nguyên quan trọng để xử lý.
Linux log được lưu dưới dạng plain text nằm ở thư mục `/var/log`. Linux log có thể chứa thông tin về tất cả các hoạt động của hệ thống, từ quá trình boot, quản lý package, kernel, Apache,…
<h4>
Phân loại
</h4>
Có thể chia làm bốn phần chính:
- `Application Logs`: Chứa các thông tin về hành vị của ứng dụng như là các message lỗi, cảnh báo,… Applicaion log được sử dụng để chuẩn đoán các vấn đề của ứng dụng và phân tích hiểu năng của ứng dụng.
- `System Logs`: Chứa các thông tin về các hoạt động của hệ thống, như là boot mesage, kernel mesage và các event của hardware. System log đóng vai trò quan trọng trong việc xử lý các system issue và quản lý hiệu năng hệ thống.
- `Service Logs`: Chứa các thông tin về service chạy trên hệ thống, bao gồm các network service và daemon. Service Log được sử dụng để quản lý các hoạt động của service và tối ưu hóa hiệu năng của service.
- `Event Logs`: Chứa các thông tin về các sự kiện có trên hệ thống như là user login, system shutdown và các sự kiện liên quan tới bảo mật. Event log được sử dụng để audit các hoạt động của hệ thống, lần theo các hoạt động của user và điều tra các sự cố liên quan tới bảo mật.
<h4>
Một số file logs quan trọng của Linux
</h4>
- `var/log/syslog` với debian và `var/log/messages` với Redhat:
- Chứa các thông tin chung liên quan hoạt động của hệ thống. Chủ yếu chứa các message thông tin và các message không nghiêm trọng của hệ thống.
- Log này giúp bạn có thể truy vết bất kỳ lỗi nào liên quan tới non-kernel, application service hoặc các message được log trong quá trình boot. Thường nó sẽ cung cấp các hiểu biết cơ bản về lỗi, nên nếu vấn đề được xác định trong quá trình khởi động, admin có thể xem qua các message để kiểm tra.
- `var/log/auth.log` với Debian và `var/log/secure` với Redhat:
- Chứa các event liên quan tới việc xác thực.
- Giúp truy vết các nỗ lực đăng nhập vào hệ thống và điều tra được brute-force attack và các lỗ hổng liên quan để cơ chế ủy quyền người dùng.
- `var/log/boot.log`:
- Chứa các message và thông tin liên quan tới quá trình boot. Trong quá trình boot, các script khởi tạo sẽ gửi các thông tin bootup tới log file.
- Giúp xử lý các vấn đề trong quá trình start up hệ thống hoặc đột ngột tắt.
- `/var/log/dmesg`:
- Cung cấp tất các các message có trong Kernel ring buffer, bao gồm thông tin liên quan tới hardware component và các driver. Kernel có khả năng phát hiện các thiết bị vật lý phần cứng kết nối với server và có thể log lại các lỗi liên quan tới quá trình kết nối đó.
- Tập trung vào quá trình boot và thời điểm ban đầu của việc khởi tạo phần cứng
- Giúp xử lý các vấn đề khi hardware kết nối với hệ thống.
- `var/log/kern.log`:
- Chứa các log liên quan tới kernel.
- Không chỉ tập trung vào quá trình boot.
- Giúp xử lý các vấn đề liên quan tới lỗi và cảnh báo trong kernel và debug hardware.
- `var/log/faillog`:
- Chứa các thông tin liện quan tới các nỗ lực login thất bại.
- Giúp nhận ra các cuộ tấn công xác thực.
- `var/log/cron`:
- Lưu lại các thông tin liên quan đến `cron` job. Khi `cron` job chạy, file này sẽ lưu lại các thông tin liên quan như là message thông báo thành công thực thi hoặc lỗi.
- Giúp quản lý các hoạt động của `cron` job.
- `/var/log/yum.log`:
- Cung cáp thông tin về các package được tải bởi `yum`.
- Giúp kiểm tra được package có được tải đúng cách hay không.
- Giúp phát hiện được các hành vi gây hại thông qua việc tải các package bằng `yum`
- `var/log/maillog`:
- Chứa các thông tin liên quan tới mail server.
- Giúp truy vết toàn bộ các email đến và đi trong một đoạn thời gian nào đó.
- Nếu việc chuyển phát mail bị lỗi, ta có thể sử dụng log này để xử lý.
- Ngoài ra, log này bao gồm các thông tin về mail đến, từ đó có thể phát hiện các nổ lực spam mail và chặn nó.
- `var/log/httpd`:
- Chứa các log được của Apache Server, bao gồm `error` log và `access` log.
- Giúp sửa lỗi khi có vấn đề xảy ra cho Apache Web server và quản lý truy cập vào web server.
- `var/log/mysqld` hoặc `/var/log/mysql.log`:
- Chứa các message debug, failure và success của MySQL server.
- Giúp xác định các vấn đề khi chạy và dừng MySQL server.
- Lấy thông tin về các kết nối từ client tới thư mục chứa dữ liệu của server.
Ở các phiên bản HĐH Linux mới, mặc định sẽ không có đa số file trong số các file trên. Thay vào đó, sử dụng `systemd-journal`. Nếu muốn có những file này, ta cần tải và chạy service `rsyslog`
### systemd-journal
#### Định nghĩa
`journal` là một thành phần của systemd. Nó là trung tâm của tất cả các message log của tất cả các thành phần trong hệ thống Linux systemd-enabled. Nó bao gồm các kernel và boot message, message tới từ syslog và các service khác nhau.
`systemd-journal` được lưu trữ tại thư mục `/var/log/journal` nếu config lưu trữ của nó là persistent còn nếu không sẽ được lưu tại `/run/log/journal`.
Các file lưu trữ log không có độ lớn quá lớn và được lưu dưới dạng binary. File này không sử dụng cơ chế `rotate` mà khi độ lớn của file đạt tới ngưỡng ở trong cấu hình thì sẽ xóa các log cũ nhất đi.
<h4>
Cấu hình
</h4>
File cấu hình của `systemd-journal` được lưu tại `/etc/systemd/journald.conf`

Ta thấy tất cả các tham số đều được comment, chỉ ra rằng đây chính là cấu hình default của `systemd-journal`.
Một số tham số cấu hình quan trọng:
- `Storage`: Log được lưu trữ persistent hay volatile hoặc không được lưu.
- `Compress`: Dữ liệu được lưu trữ khi vượt ngưỡng có được nén lại hay không
- `SystemKeepFree`: Chỉ ra độ lớn disk space mà `systemd-journal` sẽ để lại cho các ứng dụng khác ở file system và nó là chủ. Default: 15%.
- `RuntimeKeepFree`: Tương tự `SystemKeepFree` nhưng với volatile storage
- `ForwardToSyslog`: Có forward message nhận được tới syslog daemon không.
- `MaxLevelStore`: Tất cả message có level bằng hoặc nhỏ hơn mức độ này sẽ được lưu. Với `emerg` là level thấp nhất và `debug` là level cao nhất.
##### Tầm quan trọng của `systemd-journal`
Trước kia, mỗi loại log được lư ở file khác nhau với cách lưu khác nhau, điều này dẫn tới sự khó khăn trong việc đọc và tìm các log.
`systemd-journal` đóng vai trò thu thập các log một cách tập trung với format message cố định để giải quyết vấn đề này.
<h4>
Cấu trúc của log
</h4>

- TimeStamp
- Hostname
- Sender
- Message
- Level
**Thực hiện ghi log sẽ được listen bởi sysmd-journal**

- Ở đây, flag `-f` giúp jounalctl chỉ show entry mới nhất và sẽ tiếp tục print ra output mà nó được thêm vào systemd journal. `-n` sẽ chỉ hiện những entry mới
##### Sử dụng `systemd-journal`
- `journalctl`: Xem tất cả các log
- `journalctl -b`: Xem tất cả các boot message
- `journal -k -b -1`: Xem các kernel log từ previous boot
- `journalctl -u apache -u nginx`: Xem các log của systemd unit và service
- `journalctl -f`: Xem log theo thời gian thực
- `journalctl -n 10`: Xem 10 dòng cuối cùng của log
- `journalctl path/to/executable`: Xem tất cả các log được tạo bởi chương trình cụ thể
- `journalctl --since "time"`: Xem log trong 1 khoảng thời gian
- `journalctl _UID=300`: Xem log của một người dùng cụ thể
- `journalctl _PID=300`: Xem log của process cụ thể.
<h3>
Shell
</h3>
<h4>
Tổng quan
</h4>
Nếu như ở Windows, ta có 2 Shell language cơ bản la Batch (CMD) và Powershell, thì ở Linux, ta sẽ có C Shell và BASH
<h4>
C Shell
</h4>
C Shell (csh) là một trong các Unix shell được phát triển bởi Bill Joy vào cuối thập niên 1970, trên hệ thống BSD UNIX.
Lý do gọi là “C Shell” là vì cú pháp lệnh và scripting của nó rất giống ngôn ngữ C, tạo thuận lợi cho lập trình viên C sử dụng.
Một phiên bản mở rộng và cải tiến của csh là tcsh (TENEX C Shell).
<h5>
Tính năng đặc trưng
</h5>
- Cú pháp script giống ngôn ngữ C:
Ví dụ: if ( ... ) then ... else ... endif, foreach, switch,…
- History command:
Sử dụng phím ! để lặp lại các lệnh đã chạy trước đó (vd: !ls).
- Alias:
Đặt alias cho các lệnh dài, ví dụ: alias ll 'ls -l'.
- Biến môi trường và biến người dùng:
Thiết lập và sử dụng biến với set, ví dụ: set x = 10.
- Quản lý tiến trình (job control):
Dùng fg, bg, jobs để chuyển giữa các tiến trình chạy foreground/background.
- Scripting:
Có thể viết các shell script với kiểm soát điều kiện (if, switch), lặp (foreach, while), hàm đơn giản.
<h5>
Ưu/Nhược điểm
</h5>
- Ưu điểm:
- Dễ dùng cho người biết lập trình C.
- Hỗ trợ history, alias tiện lợi cho người dùng tương tác.
- Nhược điểm:
- Scripting hạn chế so với Bash, đặc biệt là về redirect và quản lý lỗi.
- Không được khuyến nghị cho scripting hiện đại do lỗi vặt, không có chuẩn POSIX.
- Bash và các shell khác (zsh, ksh) mạnh hơn, nhiều tính năng hơn.
=> Vì vậy nên bây giờ C Shell chỉ còn được ứng dụng trong việc duy trì các script hệ thống cũ trên BSD/UNIX hoặc các máy chủ legacy
<h4>
BASH
</h4>
<h5>
Định nghĩa
</h5>
BASH hay Bourne Again SHell, là loại shell script phổ biến và mặc định cho các distro linux hiện tại.
Bash vừa là command-line interpreter (giao tiếp người dùng với hệ thống), vừa là scripting language dùng để tự động hóa tác vụ trên Unix/Linux.
<h5>
Tính năng
</h5>
`Command-Line Interface (CLI)`
- Cho phép gõ lệnh trực tiếp, quản lý file, thư mục, tiến trình, package,...
- Hỗ trợ history (lịch sử lệnh, dùng phím ↑ ↓ để truy cập lại), tab completion (tự động hoàn thành tên lệnh/file).
`Scripting`
- Hỗ trợ đầy đủ biến, toán tử, kiểm tra điều kiện (if, case), vòng lặp (for, while, until), hàm (function).
- Scripting Bash dùng để tự động hóa từ đơn giản (backup, copy file) đến phức tạp (quản trị hệ thống, CTF, khai thác lỗi).
`Biến môi trường và biến người dùng`
- Biến môi trường (environment variable): dùng cho cả hệ thống.
- Ví dụ: $PATH, $HOME, $USER
- Biến người dùng (user-defined): do người dùng tạo ra trong script hoặc dòng lệnh.
`Quản lý tiến trình`
- Quản lý tiến trình foreground, background, dừng/tiếp tục tiến trình với fg, bg, jobs, kill.
`Redirect & Pipe`
- Chuyển hướng đầu vào/ra (input/output): >, >>, <
- Kết nối lệnh qua pipe: |
`Các tính năng khác`
- Command substitution: Lấy kết quả của lệnh khác làm tham số:
echo "Today is $(date)"
- Arithmetic operations: $((a + b))
- Điều khiển quyền truy cập, quản lý file chuyên sâu.
<h5>
Cấu trúc của BASH
</h5>
`Shell Core`
- Là chương trình chạy trên user space, thực hiện vai trò command-line interpreter.
- Khi bạn nhập lệnh vào terminal, Bash sẽ:
- Đọc lệnh (từ user/script).
- Phân tích cú pháp (parsing).
- Tìm lệnh (nội bộ hoặc tìm trong $PATH).
- Tạo tiến trình (nếu là lệnh ngoài).
- Giao tiếp với kernel (qua system call).
- Trả kết quả về cho user.
`Loại lệnh`
- Lệnh nội bộ (built-in): cd, echo, export, alias, history, jobs,...
- Lệnh bên ngoài: cat, grep, ls, ps,... (tìm theo $PATH).
<h5>
Cơ chế
</h5>
- Khi chạy lệnh, Bash sẽ:
- Kiểm tra xem là lệnh built-in hay không (ưu tiên nội bộ).
- Nếu không có, tìm file thực thi tương ứng trong các thư mục liệt kê bởi biến môi trường $PATH.
- Fork một tiến trình con, exec lệnh.
- Chờ tiến trình hoàn thành, lấy exit code.