Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows 10/WSL: Ansible cannot read ansible.cfg from NTFS mounts #42388

Closed
AngellusMortis opened this issue Jul 5, 2018 · 37 comments · Fixed by #43583
Closed

Windows 10/WSL: Ansible cannot read ansible.cfg from NTFS mounts #42388

AngellusMortis opened this issue Jul 5, 2018 · 37 comments · Fixed by #43583
Labels
affects_2.6 This issue/PR affects Ansible v2.6 bug This issue/PR relates to a bug. support:core This issue/PR relates to code supported by the Ansible Engineering Team. windows Windows community

Comments

@AngellusMortis
Copy link

AngellusMortis commented Jul 5, 2018

SUMMARY

Ansible 2.6.1 added #42070 which makes Ansible ignore ansible.cfg files in 777 directories. The problem is that all NTFS mounts (anything under /mnt/c) in WSL on Windows 10 are 777 because their permissions are managed by Windows.

Detecting a WSL install is pretty easy, I have been using ansible_kernel.find('Microsoft') != -1 to detect WSL. Tested on Arch, Ubuntu and Kali.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

lib/ansible/config/manager.py

ANSIBLE VERSION
ansible 2.6.1
  config file = None
  configured module search path = [u'/home/cbailey/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.15 (default, May  1 2018, 05:55:50) [GCC 7.3.0]
CONFIGURATION

N/A

OS / ENVIRONMENT

Windows 10 + any WSL distro

STEPS TO REPRODUCE
  1. Install a WSL distro
  2. sudo pip install ansible==2.6.1
  3. Put an ansible.cfg some where on your C:\ drive
  4. cd to Directory from WSL
  5. Run any Ansible command
EXPECTED RESULTS

ansible.cfg files on Windows mounts in WSL are not ignored

ACTUAL RESULTS

ansible.cfg file is ignored with the following warning:

[WARNING] Ansible is in a world writable directory (/mnt/c/**), ignoring it as an ansible.cfg source.
@ansibot
Copy link
Contributor

ansibot commented Jul 5, 2018

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added affects_2.6 This issue/PR affects Ansible v2.6 bug This issue/PR relates to a bug. needs_triage Needs a first human triage before being processed. support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Jul 5, 2018
@ansibot
Copy link
Contributor

ansibot commented Jul 5, 2018

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@abadger
Copy link
Contributor

abadger commented Jul 5, 2018

Detecting that the system is WSL would still leave a vulnerability. We'd have to detect that the file isn't world writable or in a world writable directory despite the permissions saying that it is.

We also don't support Ansible on Windows hosts so we can't guarantee a fix will be created for this.

@AngellusMortis
Copy link
Author

I absolutely understand the need for security, but there should at least be an option some how to disable that. Maybe something that has to be in the /etc/ansible/ansible.cfg specifically or something similar that makes it harder to flip on.

There are other use cases where it would not just be a Windows 10 NTFS mount to WSL that this would occur. If you have an NTFS mount or an Azure File Share mount on a locked down Linux build box, the mount would be 777, but it does not mean it is insecure to trust files from that location.

OpenSSH does not stop you from enabling root password login, but it does tell you it is a bad idea. Most security guidelines are relative to what the purpose is and the context around it.

@samdoran samdoran removed the needs_triage Needs a first human triage before being processed. label Jul 5, 2018
@zoredache
Copy link
Contributor

zoredache commented Jul 5, 2018

Maybe you could allow people to whitelist directories from this check via an environment variable? Something like ANSIBLE_TRUSTED_CONFIGPATHS or something? If the config is inside a path in that variable, then skip the permissions check?

I am not that good at python, but maybe something like this?

diff --git a/lib/ansible/config/manager.py b/lib/ansible/config/manager.py
index 48cf2cba3a..b356c84b9e 100644
--- a/lib/ansible/config/manager.py
+++ b/lib/ansible/config/manager.py
@@ -146,6 +146,10 @@ def find_ini_config_file(warnings=None):
    ''' Load INI Config File order(first found is used): ENV, CWD, HOME, /etc/ansible '''
    # FIXME: eventually deprecate ini configs

+    trusted_paths = os.getenv("ANSIBLE_TRUSTED_CONFIGPATHS",None)
+    if isinstance(trusted_paths, string_types):
+        trusted_paths=list(filter(None,trusted_paths.split(':')))
+
    path0 = os.getenv("ANSIBLE_CONFIG", None)
    if path0 is not None:
        path0 = unfrackpath(path0, follow=False)
@@ -154,7 +158,9 @@ def find_ini_config_file(warnings=None):
    try:
        path1 = os.getcwd()
        perms1 = os.stat(path1)
-        if perms1.st_mode & stat.S_IWOTH:
+        if trusted_paths and [i for i in trusted_paths if path1.startswith(i)]:
+            path1 += "/ansible.cfg"
+        elif perms1.st_mode & stat.S_IWOTH:
            if warnings is not None:
                warnings.add("Ansible is in a world writable directory (%s), ignoring it as an ansible.cfg source." % to_text(path1))
            path1 = None

Then I can just set export ANSIBLE_TRUSTED_CONFIGPATHS=/mnt/c/Users/ in my shell profile?

@rbaradari
Copy link

You can set the ANSIBLE_CONFIG variable to point to your world writable ansible.cfg and it currently works.

@abadger
Copy link
Contributor

abadger commented Jul 6, 2018 via email

@116davinder
Copy link

116davinder commented Jul 9, 2018

i am using vagrant on windows to run ansible playbooks.

Its still failing even after setting ansible_config value.

[root@controller ]# echo $ANSIBLE_CONFIG
/home/vagrant/projects/DevOps-Projects/

[root@controller mapr-ansible-paysafe]# ls -lh ansible.cfg
-rwxrwxrwx. 1 vagrant vagrant 73 Jul 9 07:43 ansible.cfg

[root@controller ]# ansible -m ping all -i environment/XXXX/cluster.ini -v
[WARNING] Ansible is in a world writable directory (/home/vagrant/projects/DevOps-Projects), ignoring it as an ansible.cfg source.
No config file found; using defaults

Temporary Solution
Install Only ansible 2.6.0

@agaffney
Copy link
Contributor

agaffney commented Jul 9, 2018

The ANSIBLE_CONFIG env var should point to a file, not a directory.

@sebastian-marinescu
Copy link

I've stumbled upon the same issue, and I don't want a global cfg for all my projects, I need a project-relative configuration. So how can I fix this for me?

@AngellusMortis
Copy link
Author

I've stumbled upon the same issue, and I don't want a global cfg for all my projects, I need a project-relative configuration. So how can I fix this for me?

pip install ansible==2.6.0 until the devs decide how they want to handle this.

@mrsombre
Copy link

Problems on Vagrant shared folder too, it is 0777 only mode for folders in this case and can't be changed.
Please, add check that CWD folder == folder containing playbook file, and then do not check for world writable. Or maybe try to find ansible.cfg in the same folder as playbook file? Would be helpful for vagrant on windows users.

@sgreiner
Copy link

I think I found a solution for 2.6.1 and so on...

Create this file in your wsl: /etc/wsl.conf

Content:

[automount]
enabled = true
mountFsTab = false
root = /mnt/
options = "metadata,umask=22,fmask=11"

[network]
generateHosts = true
generateResolvConf = true

After that all /mnt/c/foo will have different folder permissions (not 777 any more) and you will be able to use chmod.
It requires you to have the latest WSL as far as I know.
wsl.conf docs

@abadger
Copy link
Contributor

abadger commented Jul 11, 2018

Okay, the comment in #42388 (comment) is the equivalent of advice we'd tell people mounting an ntfs or vfat filesystem under Unix so I think that is the correct solution here.

For people using ANSIBLE_CONFIG (correctly... as agaffney notes, it needs to point to a file not a directory), please check whether the config file is actually being ignored or it's just spitting out an extra warning.

From looking at the code, I think that the config file is read when ANSIBLE_CONFIG is used correctly. If that happens to also be the current working directory, then the warning message is spit out in addition to the config being used because it is listed in ANSIBLE_CONFIG. If that is indeed the symptom being seen, it should be easy to fix it to only emit the warning if the only reason for the config to be used is because it's in the current working directory.

@bcoca
Copy link
Member

bcoca commented Jul 11, 2018

index c308c3810d..36641d9e01 100644
--- a/lib/ansible/config/manager.py
+++ b/lib/ansible/config/manager.py
@@ -150,6 +150,8 @@ def find_ini_config_file(warnings=None):
     ''' Load INI Config File order(first found is used): ENV, CWD, HOME, /etc/ansible '''
     # FIXME: eventually deprecate ini configs

+    warn_cwd_public = False
+
     path0 = os.getenv("ANSIBLE_CONFIG", None)
     if path0 is not None:
         path0 = unfrackpath(path0, follow=False)
@@ -159,8 +161,7 @@ def find_ini_config_file(warnings=None):
         path1 = os.getcwd()
         perms1 = os.stat(path1)
         if perms1.st_mode & stat.S_IWOTH:
-            if warnings is not None:
-                warnings.add("Ansible is in a world writable directory (%s), ignoring it as an ansible.cfg source." % to_text(path1))
+            warn_cwd_public = True
             path1 = None
         else:
             path1 += "/ansible.cfg"
@@ -175,6 +176,8 @@ def find_ini_config_file(warnings=None):
     else:
         path = None

+    if warn_cwd_public and warnings is not None and path != os.getcwd() + "/ansible.cfg":
+        warnings.add("Ansible is in a world writable directory (%s), skipped from possible ansible.cfg sources list." % to_text(path1))
     return path```
something like this should be more precise 

rezonanc-oxid added a commit to rezonanc-oxid/oxvm_base that referenced this issue Jul 12, 2018
This is needed as not all platforms support and/or accept the given
parameters and sometimes one could get the following message which
would prevent from the VM to start at all, e.g.:

```
Failed to mount folders in Linux guest. You've specified mount options
which are not supported by "prl_fs" file system.

Invalid mount options: ["dmode=775,fmode=664"]
```

Also the original issue only seems to affect Windows platform with
virtualbox as hypervisor, as this can be seen at:

ansible/ansible#42388
@goettl79
Copy link
Contributor

goettl79 commented Jul 17, 2018

For me the best solution is to change the permission on an wsl mounted nfs filesystem with Metadata option turned on. To do that follow this procedure here: https://blogs.msdn.microsoft.com/commandline/2018/01/12/chmod-chown-wsl-improvements.

Basically do the following for your ntfs mount to enable "chmod":

sudo umount /mnt/c
sudo mount -t drvfs C:/mnt/c -o metadata

And then do the chmod on the folder and everything is fine again. After the metadata was attached to the folder it stays there. should be wsl default for my humble opinion.

@NL9
Copy link

NL9 commented Jul 18, 2018

Solution for Vagrant, edit Vagrantfile and add mount_options:

config.vm.synced_folder "../my-folder", "/home/vagrant/my-folder",  mount_options: ["dmode=775"]

@Petrox
Copy link
Contributor

Petrox commented Jul 23, 2018

This is a nice example why ansible is a high upkeep module to build your project on.

I have prepared a vagrant+virtualbox+ansible project 3 years ago. Since then every 5 months ansible breaks. I have to implement workarounds to KEEP IT WORKING THE SAME WAY. So I can't tell the (few) users of the system that "this works", because every so often it just breaks. This was working 3 weeks ago, and it is not working now. And it's not a mayor version change, just a minor one, so breaking changes are not an option.

(see "touch" not implemented for years, apt module not having autoremove but has warnings implemented that I should not call "apt" as a command, stat.md5 removed without notice, vault_password.txt location was not allowed to set in ansible.cfg (feature request closed, then years later implemented) etc...)

You need to use workarounds every few weeks to get the same result as before.

I was hoping for a more mature project management from Redhat and ansible 2.0, but let this be a warning for the newcomers, that ansible needs upkeep.

@jefflill
Copy link

jefflill commented Jul 26, 2018

Could you please write this warning out to STDERR instead of STDOUT?

[WARNING] Ansible is in a world writable directory...

I'm seeing this message when I'm decrypting a variables file to STDOUT and I'm going to have to hack some special code node to watch for and strip this line out.

@kcd83
Copy link
Contributor

kcd83 commented Jul 30, 2018

Oh ha, this seems to work

export ANSIBLE_CONFIG=./ansible.cfg

Throw that in any vagrant/docker/wsl setups

@thegreatjerboa
Copy link

All these workarounds are great to know, but I think it is ridiculous assumption, and to have no possible workaround with inline ansible-playbook flags. I am now spending my day updating 40 build jobs with hacky workarounds, for breaking changes that were introduced in a patch version change! And all these builds run in short lived containers in which a single automated user has access to, so this dangerous world writable security hole you are protecting me from is completely invalid assumption.

@nitzmahone
Copy link
Member

nitzmahone commented Aug 1, 2018

Quick update: we're not ignoring this- we're looking at a few different ideas to preserve the security fix of not reading config from an unprotected cwd. Trust me, what shipped in response to the recent CVEs around this was a very measured approach compared to some of the draconian measures being floated.

That said, I'm sure we can come up with a refinement or workaround to support these "world-writable-but-not-really" cases.

@thegreatjerboa Can you be more specific about your setup? I'm curious why you're implicitly reading ansible.cfg from cwd rather than a fixed location (which should work fine with world-writable- if not, it's a bug).

@abadger
Copy link
Contributor

abadger commented Aug 1, 2018

@jefflill I'm working on a proposal to fix the more general problem there (that almost all warnings and errors, as well as verbose debugging type information) are going to stdout instead of stderr. unfortunately, I keep getting pulled onto other problems...

@thegreatjerboa
Copy link

@nitzmahone it is same-dir-as-playbook. We have a git repo per playbook that gets run on checkin. The ansible.cfg and playbook are the top level of the repo, which is also the CWD when it runs.

abadger added a commit to abadger/ansible that referenced this issue Aug 2, 2018
* Also add unittests for the find_ini_config_file function
* Add documentation on world writable current working directory
  config files can no longer be loaded from a world writable current
  working directory but the end user is allowed to specify that
  explicitly.  Give appropriate warnings and information on how.

Fixes ansible#42388
@soar
Copy link

soar commented Aug 3, 2018

export ANSIBLE_CONFIG=./ansible.cfg

is NOT working for me, still getting

 [WARNING] Ansible is in a world writable directory (/mnt/c/Users/soar/projectdir), ignoring it as an ansible.cfg source.

with ansible 2.6.2

@abadger
Copy link
Contributor

abadger commented Aug 3, 2018 via email

@abadger
Copy link
Contributor

abadger commented Aug 3, 2018

#43583 fixes the warning and should be merged later today to devel (backports to follow)

abadger added a commit to abadger/ansible that referenced this issue Aug 3, 2018
Only print warning when ansible.cfg is actually skipped

* Also add unittests for the find_ini_config_file function
* Add documentation on world writable current working directory
  config files can no longer be loaded from a world writable current
  working directory but the end user is allowed to specify that
  explicitly.  Give appropriate warnings and information on how.

Fixes ansible#42388
abadger added a commit to abadger/ansible that referenced this issue Aug 3, 2018
…nsible#43583)

Only print warning when ansible.cfg is actually skipped

* Also add unittests for the find_ini_config_file function
* Add documentation on world writable current working directory
  config files can no longer be loaded from a world writable current
  working directory but the end user is allowed to specify that
  explicitly.  Give appropriate warnings and information on how.

Fixes ansible#42388
(cherry picked from commit 30662be)

Co-authored-by: Toshio Kuratomi <a.badger@gmail.com>
abadger added a commit to abadger/ansible that referenced this issue Aug 3, 2018
…nsible#43583)

Only print warning when ansible.cfg is actually skipped

* Also add unittests for the find_ini_config_file function
* Add documentation on world writable current working directory
  config files can no longer be loaded from a world writable current
  working directory but the end user is allowed to specify that
  explicitly.  Give appropriate warnings and information on how.

Fixes ansible#42388
(cherry picked from commit 30662be)

Co-authored-by: Toshio Kuratomi <a.badger@gmail.com>
abadger added a commit that referenced this issue Aug 3, 2018
…43583)

Only print warning when ansible.cfg is actually skipped

* Also add unittests for the find_ini_config_file function
* Add documentation on world writable current working directory
  config files can no longer be loaded from a world writable current
  working directory but the end user is allowed to specify that
  explicitly.  Give appropriate warnings and information on how.

Fixes #42388.
(cherry picked from commit 30662be)

Co-authored-by: Toshio Kuratomi <a.badger@gmail.com>
@nicolaibaralmueller
Copy link

Having the same issue today after upgrade. We are using this in production so right now our customer reports don't work. Please provide a fix for this.

@abadger
Copy link
Contributor

abadger commented Aug 4, 2018

This has now been fixed in devel via #43583 Backports for 2.6 and 2.5 are in the two PRs #43648 and #43649 and the backport has also been merged to stable-2.4 should there be another 2.4.x release.

What is in the fix?

  • Documentation explaining the security risk and pointing to the right way of fixing it (mounting the filesystem so that the user and group that needs to access ansible.cfg can do so rather than mounting the directory world writable.
  • Pointers to blog posts explaining how to do this for both vagrant and WSL (Vagrant doesn't appear to have anything more official than blog posts to explain and the WSL feature has both official documentation and a blog post which explains in more detail how to mount the filesystems).
  • Documentation that explains that setting ANSIBLE_CONFIG to the config file you need can be used if you really must have it in a world writable directory as asked for by @AngellusMortis and @zoredache
  • A fix for the warning about skipping the directory so that it doesn't appear that the config file is being skipped when it is both in a world writable current working directory AND specified in ANSIBLE_CONFIG.

If you still experience this issue while testing the devel branch please open a new issue to let us know what the exact symptoms are so that we can try to reproduce.

@realtebo
Copy link

If it could be usefull as use case, we use ansible in a vmware workstation ubuntu machine, using a shared folder that point to a phisical location.

Initially this mount location was created for mistake with 777 permissions. We reduced it to 755.

@siran
Copy link
Contributor

siran commented Aug 12, 2018

I have set ANSIBLE_CONFIG environmental variable to teh absolute path to the ansible.cfg filename (/path/to/ansible.cfg), and I'm still getting the message: [WARNING] Ansible is in a world writable directory ...

$ ansible --version
 [WARNING] Ansible is in a world writable directory (/c/Users/my/path/to/ansible), ignoring it as an ansible.cfg source.
ansible 2.6.2
  config file = /path/to/ansible.cfg
  configured module search path = [u'/home/me/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]

@abadger
Copy link
Contributor

abadger commented Aug 12, 2018

If you can test that against the devel branch or one of the PRs with backports to 2.6 or 2.5, that would be great. Otherwise, you can wait for 2.6.3 to come out and try it there.

mattclay pushed a commit that referenced this issue Aug 13, 2018
…43583)

Only print warning when ansible.cfg is actually skipped

* Also add unittests for the find_ini_config_file function
* Add documentation on world writable current working directory
  config files can no longer be loaded from a world writable current
  working directory but the end user is allowed to specify that
  explicitly.  Give appropriate warnings and information on how.

Fixes #42388
(cherry picked from commit 30662be)

Co-authored-by: Toshio Kuratomi <a.badger@gmail.com>
nitzmahone pushed a commit that referenced this issue Aug 14, 2018
…43583) (#43649)

Only print warning when ansible.cfg is actually skipped

* Also add unittests for the find_ini_config_file function
* Add documentation on world writable current working directory
  config files can no longer be loaded from a world writable current
  working directory but the end user is allowed to specify that
  explicitly.  Give appropriate warnings and information on how.

Fixes #42388
(cherry picked from commit 30662be)

Co-authored-by: Toshio Kuratomi <a.badger@gmail.com>
@abadger
Copy link
Contributor

abadger commented Aug 17, 2018 via email

@automateyournetwork
Copy link

I have Ubuntu installed on Windows 10 along with the WSL

I have added the following to my /etc/environment

ANSIBLE_CONFIG="/etc/ansible/ansible.cfg"

I am still getting the error

How did those who added the ANSIBLE_CONFIG environment variable make it work?

@abadger
Copy link
Contributor

abadger commented Oct 16, 2018

Can you open a new ticket with details on your setup, output, and how to reproduce? The latest 2.6 and 2.7 releases should work without a warning message if ANSIBLE_CONFIG is set

@dagwieers dagwieers added the windows Windows community label Feb 8, 2019
@tamusjroyce
Copy link

tamusjroyce commented Feb 27, 2019

export ANSIBLE_CONFIG=./ansible.cfg

If it is an ansible.cfg in your current directory, not sure why you wouldn't allow it, since you navigate there. But having ANSIBLE_CONFIG is great! And considering security is way better than ignoring it. Thank you!!!

@ansible ansible locked and limited conversation to collaborators Jul 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.6 This issue/PR affects Ansible v2.6 bug This issue/PR relates to a bug. support:core This issue/PR relates to code supported by the Ansible Engineering Team. windows Windows community
Projects
None yet
Development

Successfully merging a pull request may close this issue.