Sudo reload-php8.1-fmp reload fails, requiring password

Using ansible v2.10, this error came up yesterday, when trying to deploy to a Ubuntu 20/php 7.4 DO droplet:

sudo: a terminal is required to read the password;...
 {"changed": true, "cmd": "sudo service php7.4-fpm reload", "delta": "0:00:00.012829", "end": 

Deployed a fresh droplet, having rebased to latest Trellis codebase for php 8.0/8.1.
Upgraded to latest Ansible (2.13.2).

Success with fresh Trellis instance, so I know it isn’t a bug, but I’m having trouble finding what’s different between my codebase and Trellis. Maybe it’s something different in Bedrock.

Input, of course, hoped for and will report back.

UPDATE: Doesn’t seem to be a Bedrock issue.

The problem is that your server is running 8.0 when your web user is granted permission to reload php7.4 only!

What does it say in /group_vars/all/users.yml for web_sudoers?

If you’re using a group_vars folder migrated from an earlier version of Trellis, then you’ll need to update some values so that provisioning assigns the correct permissions required to reload the proper version of PHP

Your users.yml file should have

web_sudoers:
  - "/usr/sbin/service php{{ php_version }}-fpm *"

You probably have it hard-coded to reload php7.4-fpm.

Make sure php_version in group_vars/all/main.yml is set to 8.0 and all php_extensions_custom (if you have any) are set to php8.0…

Then
vagrant reload --provision

2 Likes

Thanks, man. I should have mentioned that that was actually one of the first items I had checked and users.yml does, in fact have the variable version:

web_sudoers:
  - "/usr/sbin/service php{{ php_version }}-fpm *"

group_vars/all/main.yml has

php_version: "8.1"

This is on the remote server, so I don’t think vagrant would do anything, but I have re-provisioned the server. I even updated roles/users/tasks/main.yml so that admin can sudo without a password:

line: "%sudo ALL=(ALL:ALL) NOPASSWD:ALL"

I don’t quite understand how web has sudo capability and also how password is not required. Wouldn’t that be a security risk? Is it just for reloading php-fpm?

line: "%sudo ALL=(ALL:ALL) NOPASSWD:ALL"

Pretty sure you’re creating a massive security vulnerability with this but please correct me if I’m wrong.

That’s exactly what the /etc/sudoers file does; it grants root privileges as an exception, so that a specific user may execute a specific, benign command e.g. service php8.0-fpm start/stop/reload without requiring a password, otherwise the system is locked down to root.

What Ansible is doing with roles/users/tasks/main.yml between lines 42-50 is:

- name: Add web user sudoers items for services
  template:
    src: sudoers.d.j2
    dest: "/etc/sudoers.d/{{ web_user }}-services"
    mode: '0440'
    owner: root
    group: root
    validate: "/usr/sbin/visudo -cf %s"
  when: web_sudoers[0] is defined

If the web_sudoers variable has an item in the array, take that as a string and create a file on the server at /etc/sudoers.d/web-services with a single line of text that is determined by the variables interpreted by the Jinja2 templating engine at roles/users/templates/sudoers.d.j2. It uses visudo command to validate the input, so that you don’t accidentally bork your server. You can read more about this here.

# {{ ansible_managed }}

{% for service in web_sudoers %}
{{ web_user }} ALL=(root) NOPASSWD: {{ service }}
{% endfor %}

And since the web_sudoers array does have a value at key 0 at group_vars/all/users.yml as:
- "/usr/sbin/service php{{ php_version }}-fpm *"
We end up with the following at /etc/sudoers.d/web-services:

# Ansible managed

web ALL=(root) NOPASSWD: /usr/sbin/service php8.0-fpm *

You’ll need to log into your server as root to read the file but please do and let me know if you get the same output.

3 Likes

I had hit the cannot run wp core snag and got some tips from @strarsis.

On fresh Ubuntu 20 droplet, now using php8.0 (wp/php depr. warnings on 8.1):

/etc/sudoers.d/web-services content is:

# Ansible managed

web ALL=(root) NOPASSWD: /usr/sbin/service.php8.0-fmp.*

Running sudo service php8.0-fpm reload as web user, still get prompted for a password.
Tried putting the permission config directly in the /etc/sudoers file. Same result.

The sudo log:

/var/log/auth.log
Aug  5 15:55:48  su: (to web) admin on pts/0
Aug  5 15:55:48  su: pam_unix(su:session): session opened for user web by admin(uid=0)
Aug  5 15:55:59  sudo: pam_unix(sudo:auth): conversation failed
Aug  5 15:55:59  sudo: pam_unix(sudo:auth): auth could not identify password for [web]
Aug  5 15:55:59  sudo:      web : command not allowed ; TTY=pts/0 ; PWD=/home/admin ; USER=root ; COMMAND=/usr/sbin/service php8.0-fpm reload

As noted in the other thread, php permissions seem correct (or at least to match a working 7.4 server).

Not sure what my next move should be.

My understanding of password-less sudo:

I recently asked a friend/advisor the same thing and he said, “No, it’s not a massive security vuln.”, explaining to me that the sudo password is more to prevent the user from making a significant mistake in haste than for security. (Password-less sudo, being MORE secure than ssh connection that allows password access.) Since only ssh connections with keys on the computer can become the (in this case) admin user, it doesn’t make a significant difference in ability to access root. If someone can access my ssh private key, they can probably get the admin sudo password as well. That being said, there’s definitely something to the prevention of users from “making a significant mistake in haste”.

1 Like

If this is the actual contents of that file, there’s a typo. You have fmp and not fpm which would definitely cause this issue.

This was noticed by https://github.com/roots/trellis/pull/1388#issuecomment-1206687055

1 Like

FastCGI Process Manager. Thank you!

Also, check out the difference:

web ALL=(root) NOPASSWD: /usr/sbin/service.php8.0-fpm.*

vs the correct

web ALL=(root) NOPASSWD: /usr/sbin/service php8.0-fpm *

Somehow I managed to insert periods between service and php as well as between fpm and asterisk (which apparently isn’t “ast-rix”). I have VS Code configured to display little dots signifying whitespace, which makes such a difference even harder than it would be to identify than it would be if I was totally in my comfort zone.

Good times, little star. Good times. Thank you all for the eyes and wisdom.

1 Like

I’ve seen other programmers use that feature and always wondered if the benefits of knowing indentation outweighed the likelihood of mistyping a full stop. Now we know! Ha :smile: (please tell me you’ve disabled this feature)

1 Like

Ha ha. Actually it does end up being useful in some cases, particularly with Python where indentation is part of syntax, so four spaces doesn’t equal one tab. And no, I haven’t disabled it, but it’s on my list of things to address. :clown_face: