Vấn đề về quyền root cần thiết cho script khởi động Nginx

Trong quá trình rà soát các vấn đề bảo mật trên hệ thống, tôi đã phát hiện ra rằng khi thêm tùy chọn user và group vào file cấu hình systemd của Nginx:

/etc/systemd/system/nginx.service

thì gặp phải lỗi khi khởi động:

the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /usr/local/nginx/nginx.conf:1
[Unit]
Description=nginx
After=network.target
 
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
<br></br>User=www
Group=www
[Install]
WantedBy=multi-user.target

Tuy nhiên, trong file cấu hình nginx.conf:

user  www;
worker_processes  1;

cài đặt thực sự là người dùng cho các tiến trình worker của Nginx, không phải tiến trình master

root     37796     1  0 09:50 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/nginx.conf
www      37797 37796  0 09:50 ?        00:00:00 nginx: worker process
root     38546 38413  0 10:09 pts/1    00:00:00 grep --color=auto nginx
Mặc định trong Linux, các cổng dưới 1024 chỉ có người dùng root mới có quyền sử dụng, đây là lý do Nginx thường sử dụng cổng 80 và 443

Ngay cả khi bạn chỉ định người dùng www trong file nginx.service, hệ thống vẫn sẽ báo lỗi vì không thể khởi động dịch vụ trên các cổng 80 và 443.

Giải pháp đơn giản là bạn chỉ cần comment lại các dòng User và Group:

#User=www
#Group=www

và các dịch vụ khác như Elasticsearch hay PHP-FPM có thể thêm tùy chọn này một cách trực tiếp.

Lưu ý: Sau khi sửa đổi file .service, bạn cần chạy lệnh systemctl daemon-reload để áp dụng thay đổi.

Ví dụ về script khởi động của Elasticsearch:

[Service]
Type=notify
RuntimeDirectory=elasticsearch
PrivateTmp=true
Environment=ES_HOME=/usr/share/elasticsearch
Environment=ES_PATH_CONF=/etc/elasticsearch
Environment=PID_DIR=/var/run/elasticsearch
Environment=ES_SD_NOTIFY=true
EnvironmentFile=-/etc/sysconfig/elasticsearch

WorkingDirectory=/usr/share/elasticsearch

User=elasticsearch
Group=elasticsearch

ExecStart=/usr/share/elasticsearch/bin/systemd-entrypoint -p ${PID_DIR}/elasticsearch.pid --quiet
# StandardOutput is configured to redirect to journalctl since
# some error messages may be logged in standard output before
# elasticsearch logging system is initialized. Elasticsearch
# stores its logs in /var/log/elasticsearch and does not use
# journalctl by default. If you also want to enable journalctl
# logging, you can simply remove the "quiet" option from ExecStart.
StandardOutput=journal
StandardError=inherit

# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65535

# Specifies the maximum number of processes
LimitNPROC=4096

# Specifies the maximum size of virtual memory
LimitAS=infinity

# Specifies the maximum file size
LimitFSIZE=infinity

# Disable timeout logic and wait until process is stopped
TimeoutStopSec=0

# SIGTERM signal is used to stop the Java process
KillSignal=SIGTERM

# Send the signal only to the JVM rather than its control group
KillMode=process

# Java process is never killed
SendSIGKILL=no

# When a JVM receives a SIGTERM signal it exits with code 143
SuccessExitStatus=143

# Allow a slow startup before the systemd notifier module kicks in to extend the timeout
TimeoutStartSec=75

[Install]
WantedBy=multi-user.target

View CodeScript khởi động của PHP-FPM:

[Unit]
Description=php8-fpm
After=syslog.target network.target

[Service]
Type=simple
PIDFile=/usr/local/php8/php-fpm.pid
ExecStart=/usr/local/php8/sbin/php-fpm -c /usr/local/php8/etc/php.ini -y /usr/local/php8/etc/php-fpm.conf
ExecReload=/bin/kill -USR2 $MAINPID
ExecStop=/bin/kill -SIGINT $MAINPID
User=www
Group=www

[Install]
WantedBy=multi-user.target

Các giải pháp thay thế khác:

Phương án 1:

Cho phép tất cả người dùng chạy (vì quyền 755, chủ sở hữu: root, nhóm sở hữu: root)

chown root.root ./nginx/
chmod 755 ./nginx/
chmod u+s ./nginx/

Phương án 2:

Chỉ cho phép người dùng root và wyq chạy (vì quyền 750, chủ sở hữu: root, nhóm sở hữu: www)

chown root.www ./nginx/
chmod 750 ./nginx/
chmod u+s ./nginx/

Thẻ: nginx systemd linux web-server permissions

Đăng vào ngày 20 tháng 6 lúc 17:04