我想做的是:
允许web服务器用户(http)运行显式iptables命令或(优选地)脚本,在不需要密码的情况下将输入传递给iptables之前检查输入的语法。
问题:
尽管我对手头的问题进行了所有搜索,但对visudo、sudoers.d或php配置的任何更改似乎都会对我所做的工作产生影响。
我的服务器的相关条件:
[weasel@darwyn ~]$ uname -a
Linux darwyn 5.3.7-arch1-1-ARCH #1 SMP PREEMPT Fri Oct 18 00:17:03 UTC 2019 x86_64 GNU/Linux
nginx version: nginx/1.16.1
PHP 7.3.10 (cli) (built: Sep 26 2019 13:40:03) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.10, Copyright (c) 1998-2018 Zend Technologies
Username: http
UID: 33
Gecos field:
Home directory: /srv/http
Shell: /usr/bin/nologin
No login: yes
Primary group: http
GID: 33
Hushed: no
Running processes: 3
Last logs:
09:29 sudo[648]: pam_unix(sudo:auth): auth could not identify password for [http]
09:29 sudo[649]: pam_unix(sudo:account): account http has expired (account expired)
09:29 sudo[650]: pam_unix(sudo:account): account http has expired (account expired)
我已经采取步骤来解决这个问题:
/var/log/php-fpm.log告诉我正在启动调用,但需要密码:
"sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper"
从类似的问题中,我了解到sudoers文件对与用户相关的最后一个配置排序。所以我第一次
root ALL=(ALL) ALL
weasel ALL=(ALL) ALL
http ALL=(ALL) NOPASSWD: /usr/local/bin/blacklist_ip, /usr/bin/iptables
我把条目移到
root ALL=(ALL) ALL
weasel ALL=(ALL) ALL
## Uncomment to allow members of group wheel to execute any command
# %wheel ALL=(ALL) ALL
## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL
## Uncomment to allow members of group sudo to execute any command
# %sudo ALL=(ALL) ALL
## Uncomment to allow any user to run sudo if they know the password
## of the user they are running the command as (root by default).
# Defaults targetpw # Ask for the password of the target user
# ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw'
##
## Relocated user http permissions for testing
##
http ALL=(ALL) NOPASSWD: /usr/local/bin/blacklist_ip, /usr/bin/iptables
## Read drop-in files from /etc/sudoers.d
## (the '#' here does not indicate a comment)
#includedir /etc/sudoers.d
我删除了visudo中的http条目,并将其移到/etc/sudoers.d/90-MyOverders。
http ALL=(ALL) NOPASSWD: /usr/local/bin/blacklist_ip, /usr/bin/iptables
http ALL=NOPASSWD: /usr/local/bin/blacklist_ip, /usr/bin/iptables
http ALL=(http:http) NOPASSWD: /usr/local/bin/blacklist_ip, /usr/bin/iptables
http ALL=(ALL) NOPASSWD: /usr/local/bin/blacklist_ip *, /usr/bin/iptables *
http ALL=NOPASSWD: /usr/local/bin/blacklist_ip *, /usr/bin/iptables *
http ALL=(http:http) NOPASSWD: /usr/local/bin/blacklist_ip *, /usr/bin/iptables *
http ALL=(ALL) NOPASSWD: /usr/bin/iptables -L
http ALL=NOPASSWD: /usr/bin/iptables -L
http ALL=(http:http) NOPASSWD: /usr/bin/iptables -L
为了确保这有某种效果,我在我自己的用户上进行了测试。
weasel ALL=(ALL) NOPASSWD: /usr/bin/iptables
我可以在没有密码的情况下执行iptables命令,但php日志仍然需要用户http的密码。我还尝试使用'sudo -S‘命令,希望密码的null值能够工作,但是它也会出错。
"[sudo] password for http: "
"sudo: no password was provided"
我检查了/etc/php/php.ini和/etc/php/php-fpm.conf,以确保exec/shell_exec命令没有禁用,并且安全模式没有激活。在/var/log/php-fpm.log中得到的调试信息已经证明了这一点,但我想彻底了解。
这是有点多余,但只是为了排除它重要的可能性。
exec("sudo blacklist_ip 185.189.12.135");
shell_exec("sudo blacklist_ip 185.189.12.135");
return:
"sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper"
exec("blacklist_ip 185.189.12.135");
shell_exec("blacklist_ip 185.189.12.135");
exec("/usr/bin/iptables -A INPUT -s 185.189.12.135 -j DROP");
shell_exec("/usr/bin/iptables -A INPUT -s 185.189.12.135 -j DROP");
return:
"Fatal: can't open lock file /run/xtables.lock: Permission denied"
exec("sudo /usr/bin/iptables -A INPUT -s 185.189.12.135 -j DROP");
shell_exec("sudo /usr/bin/iptables -A INPUT -s 185.189.12.135 -j DROP");
return:
"sudo: Account expired or PAM config lacks an "account" section for sudo, contact your system administrator"
并通过一些搜索发现,根据https://www.sudo.ws/troubleshooting.html
( Q) sudo说,‘帐户过期或者PAM配置没有一个Sudo的“帐户”部分,联系您的系统管理员’并退出,但我知道我的帐户还没有过期。( A) PAM配置缺乏“帐户”规范。在Linux上,这通常意味着您遗漏了如下一行: account required pam_unix.so in /etc/amam.d/sudo。
在任何其他与这个话题相关的问答中,没有人提到这是一个原因。不过,为了彻底起见,我查了有关PAM和sudo的信息
#%PAM-1.0
auth include system-auth
account required pam_unix.so
#account include system-auth
session include system-auth
这没什么区别。
我没有主意了。我需要更多关于适当PAM模块的信息,使http用户可以通过PAM,或者我需要一些重定向来进行进一步的评估。
为了简洁起见,编辑更新以简化信息。
编辑添加了/etc/php/php-fpm.d/www.conf的内容
[www]
user = http
group = http
listen = /run/php-fpm/php-fpm.sock
listen.owner = http
listen.group = http
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
access.log = /var/log/php/$pool.access.log
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
catch_workers_output = yes
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/php/fpm-php.www.log
php_admin_flag[log_errors] = on
发布于 2019-10-22 19:43:22
根据注释中的戴安的建议,事实证明,在某个时候,http帐户的过期日期被设置为很久以前的时间,因此它在功能上永远不能用于sudo命令。也许这是一个未来的决定--防止通过在web服务器中使用PHP注入exec/shell_exec命令的可能性。
解决方案:
chage -E -1 http
这将用户的过期设置为“从不”,并使其再次可用。sudo设置现在按预期工作。
发布于 2020-11-13 11:17:05
很抱歉没有给出你的问题,但与这个问题有关,并认为值得一提的是这里。我遇到类似的问题时使用
GitHub actions to run sudo command in your-file-name.yaml file
所有脚本都成功运行,但在运行结束时
sudo supvervisor restart all
由于sudo命令所需的密码而失败,并返回一个错误sudo: no tty present and no askpass program specified
。
Bellow是解决这个问题的过程:
如果没有退出,可以使用以下命令将your-user-name
添加到sudoer组:
sudo adduser your-user-name sudo
现在,您可以告诉系统将其添加为不需要密码的用户。
sudo sh -c "echo 'your-user-name ALL=NOPASSWD: ALL' >> /etc/sudoers"
https://stackoverflow.com/questions/58509304
复制相似问题