
Kết nối SSH bằng key và cấu hình truy cập an toàn
Tạo SSH key từ Windows, Linux hoặc macOS, xác minh host key và kiểm tra phiên đăng nhập mới trước khi hạn chế đăng nhập mật khẩu trên Ubuntu Server.

Thực hành tạo systemd service trên Ubuntu, kiểm tra trạng thái, restart, reload và tự khởi động; tìm lỗi từ user, đường dẫn, quyền và log của dịch vụ.
Một chương trình chạy được trong terminal chưa chắc chạy được sau khi bạn thoát SSH hoặc reboot. Nó có thể đang dựa vào thư mục hiện tại, biến môi trường của shell hoặc quyền của tài khoản quản trị. systemd giúp mô tả rõ những điều kiện đó và quản lý vòng đời dịch vụ. Bài này thực hành trên Ubuntu Server 24.04 LTS với một HTTP server chỉ phục vụ dữ liệu lab.
Unit là đối tượng systemd quản lý; service unit mô tả một dịch vụ. Ngoài service còn có socket, timer, mount và các loại unit khác. Một socket có thể tiếp nhận yêu cầu để kích hoạt service, nên trạng thái service riêng lẻ không phải lúc nào cũng mô tả toàn bộ cơ chế truy cập.
systemctl điều khiển và truy vấn unit. Nó không thay thế kiểm tra ứng dụng: service active nhưng ứng dụng có thể trả lỗi hoặc chưa sẵn sàng. Theo systemd.service, loại service và cách xác định tiến trình chính ảnh hưởng thời điểm systemd coi dịch vụ đã bắt đầu.
Ví dụ dùng Type=simple, phù hợp cho tiến trình chạy foreground trong lab. Không thêm cơ chế daemonize hoặc ký tự & vào ExecStart. Nếu phần mềm có unit chính thức do package cung cấp, ưu tiên unit đó và dùng override đúng cách, thay vì thay bằng mẫu đơn giản bên dưới.
systemctl status ssh --no-pager
systemctl is-active ssh
systemctl is-enabled ssh
systemctl list-units --type=service --state=running
systemctl --failed --no-pager
active mô tả trạng thái hoạt động; enabled liên quan liên kết kích hoạt khi boot hoặc target phù hợp. Enabled không bảo đảm dịch vụ đang chạy, còn một dịch vụ disabled vẫn có thể đang chạy do khởi động thủ công hoặc dependency.
Đọc exit code của các lệnh kiểm tra trong script thay vì mặc định mọi câu lệnh trả mã 0. Một unit static cũng không đồng nghĩa bị hỏng: nó có thể được kéo vào bởi unit khác mà không có phần enable độc lập.
Chỉ thực hiện trên lab. Nếu đã tạo labapp ở bài quản lý user thì giữ tài khoản đó; nếu chưa, tạo system user trước. Không chạy lại lệnh tạo user mà bỏ qua lỗi trùng tên.
getent passwd labapp
sudo apt install python3 curl
sudo install -d -o root -g root -m 755 /srv/lab-web
printf 'Linux lab OK\n' | sudo tee /srv/lab-web/index.html
sudo chmod 644 /srv/lab-web/index.html
Nội dung web do root sở hữu nhưng service chỉ cần đọc. Với một ứng dụng thực, thư mục dữ liệu ghi được nên tách riêng khỏi mã và cấu hình. Ví dụ Python HTTP server dùng để học vòng đời dịch vụ, không phải khuyến nghị triển khai ứng dụng Internet bằng công cụ này.
Kiểm tra cổng 8080 chưa bị chiếm bằng sudo ss -lntp. Nếu đã có listener, xác định dịch vụ đó thay vì kill tiến trình để giành cổng. Chọn cổng khác cho lab và cập nhật đồng bộ trong unit lẫn lệnh kiểm tra.

Tạo file bằng sudoedit /etc/systemd/system/lab-web.service:
[Unit]
Description=HTTP server for Linux editorial lab
After=network.target
[Service]
Type=simple
User=labapp
Group=labapp
WorkingDirectory=/srv/lab-web
ExecStart=/usr/bin/python3 -u -m http.server 8080 --bind 127.0.0.1
Restart=on-failure
RestartSec=3
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
After=network.target thiết lập thứ tự, không chứng minh Internet hay DNS đã sẵn sàng. Ứng dụng phụ thuộc dịch vụ ngoài cần có cơ chế retry và timeout phù hợp; chỉ thêm dependency không xử lý hết lỗi mạng sau khởi động.
Bind 127.0.0.1 giới hạn listener ở loopback để lab không tự mở dịch vụ ra mạng. Restart=on-failure giúp khởi động lại khi tiến trình thất bại theo điều kiện systemd, nhưng không sửa nguyên nhân. Nếu cấu hình sai, service có thể lặp lỗi và chạm giới hạn restart.
ExecStart không mặc định chạy qua shell tương tác. Đường dẫn ~, các phép pipe và biến từ profile của người dùng không hoạt động như lúc bạn gõ trong Bash. Dùng đường dẫn tuyệt đối và cấu hình môi trường rõ ràng. Nếu thực sự cần script, tạo script đã kiểm tra thay vì nhét chuỗi shell khó kiểm soát vào unit.
sudo systemd-analyze verify /etc/systemd/system/lab-web.service
sudo systemctl daemon-reload
sudo systemctl enable --now lab-web.service
systemctl status lab-web.service --no-pager
curl --fail http://127.0.0.1:8080/
verify giúp phát hiện nhiều lỗi unit nhưng không chứng minh ứng dụng sẽ chạy đúng. daemon-reload yêu cầu systemd đọc lại định nghĩa unit; nó không restart tiến trình ứng dụng. enable --now kết hợp enable và start, nên có tác động ngay tới dịch vụ.
Kết quả mong đợi của HTTP là nội dung Linux lab OK, không chỉ một mã thoát từ systemctl. Kiểm tra listener bằng ss để xác nhận đúng địa chỉ loopback. Sau đó xem log sudo journalctl -u lab-web.service -n 30 --no-pager để nhận diện các yêu cầu vừa thực hiện.
Trong cửa sổ bảo trì của lab, reboot máy ảo rồi đăng nhập lại và lặp kiểm tra HTTP. Reboot ngắt mọi phiên và dừng dịch vụ tạm thời. Việc enabled có hiệu lực sau boot phải được xác nhận bằng hành vi thực tế, không suy luận chỉ từ tên file unit.
restart dừng rồi khởi động lại service, có thể làm gián đoạn kết nối đang xử lý. Đánh giá tác động và chọn thời điểm phù hợp trước khi dùng trên máy phục vụ người dùng.
reload yêu cầu ứng dụng đọc lại cấu hình nếu unit và chương trình hỗ trợ cơ chế này. Không phải service nào cũng có reload. HTTP server mẫu không có ExecReload, nên không dùng nó để minh họa khả năng reload cấu hình ứng dụng.
daemon-reload áp dụng khi định nghĩa unit hoặc drop-in thay đổi. Nếu chỉ sửa nội dung trang tĩnh trong lab, không cần daemon-reload. Nếu sửa ExecStart, phải daemon-reload rồi restart để tiến trình mới nhận tham số.
Để xem cấu hình kết hợp từ package và override:
systemctl cat lab-web.service
systemctl show lab-web.service -p FragmentPath -p User -p Group -p ExecStart
Với unit do package cung cấp, dùng systemctl edit tạo override khi phù hợp. Không chỉnh trực tiếp file dưới /usr/lib/systemd/system rồi kỳ vọng nó được giữ nguyên qua mọi lần cập nhật package.

Trên lab, ghi lại cấu hình đang chạy và thay tạm đường dẫn binary trong ExecStart thành một đường dẫn không tồn tại. Thực hiện verify, daemon-reload và restart, rồi đọc status cùng journal. Thao tác này cố ý làm service mẫu không phục vụ được; không áp dụng cho dịch vụ thật.
Tìm dòng đầu tiên nói về việc không thực thi được chương trình, thay vì chỉ nhìn thông báo restart thất bại xuất hiện sau đó. Khôi phục đường dẫn đúng, daemon-reload và start lại. Nếu đã chạm start limit, sau khi sửa nguyên nhân mới dùng sudo systemctl reset-failed lab-web.service rồi start.
Một lỗi khác là user không đi qua được WorkingDirectory. Khi đó, đọc quyền từng thư mục cha và thử bằng đúng user dịch vụ. Không chuyển User=root để che lỗi. Với phần mềm cần file cấu hình hoặc biến môi trường, kiểm tra chúng có sẵn trong bối cảnh systemd hay chỉ tồn tại trong shell của bạn.
Hoàn thành khi service trả nội dung đúng, chạy bằng labapp, chỉ listen loopback, tự hoạt động sau reboot và phục hồi được sau lỗi có chủ đích. Lưu unit, phiên bản OS, kết quả status và yêu cầu HTTP trước/sau sửa. Không đưa token hoặc dữ liệu thật vào log mẫu.
Nếu không tiếp tục bài lab, sudo systemctl disable --now lab-web.service sẽ dừng service và bỏ enable. Sau khi xác nhận đúng tên unit tự tạo, có thể xóa file đó và daemon-reload. Giữ các service do package hoặc người khác quản lý nguyên trạng.
Một chương trình tìm thấy khi gõ tên trong SSH có thể được cài qua công cụ quản lý phiên bản trong home người dùng. systemd không tự đọc cùng profile để tìm binary đó. Kiểm tra đường dẫn thực tế bằng công cụ của ứng dụng và dùng cấu hình triển khai được hỗ trợ. Không giải quyết bằng cách cho service source mọi file shell của người quản trị.
Nếu cần biến môi trường, khai báo rõ phạm vi và bảo vệ nơi chứa giá trị nhạy cảm. Không đưa secret vào file unit công khai hoặc tham số có thể hiển thị trong danh sách tiến trình. Một file environment cũng không tự có tính bí mật nếu quyền đọc quá rộng hoặc được đưa vào backup không kiểm soát.
Dependency giữa unit chỉ giải quyết một phần thứ tự khởi động. Dịch vụ từ xa có thể mất kết nối sau khi unit đã active; ứng dụng vẫn cần xử lý lỗi, retry có giới hạn và khả năng quan sát. Khi kiểm tra boot, thử chức năng thật rồi đọc log để phân biệt thiếu dependency với một ứng dụng đang retry đúng thiết kế.

Tạo SSH key từ Windows, Linux hoặc macOS, xác minh host key và kiểm tra phiên đăng nhập mới trước khi hạn chế đăng nhập mật khẩu trên Ubuntu Server.

Tạo tài khoản quản trị, user dịch vụ và thư mục dùng chung trên Ubuntu; chẩn đoán Permission denied theo user, đường dẫn, mode và chính sách truy cập.

Hiểu repository, cài và cập nhật gói trên Ubuntu Server, kiểm tra sau thay đổi và xử lý lỗi lock, DNS hoặc chữ ký mà không bỏ qua cơ chế xác minh.

Lọc log Linux theo service, thời gian và boot; phân biệt lỗi gốc với thông báo hệ quả, kiểm tra quyền đọc và xác nhận phục hồi sau khi sửa nguyên nhân.