{"action":"created","issue":{"url":"https://api.github.com/repos/ansible/ansible/issues/10698","labels_url":"https://api.github.com/repos/ansible/ansible/issues/10698/labels{/name}","comments_url":"https://api.github.com/repos/ansible/ansible/issues/10698/comments","events_url":"https://api.github.com/repos/ansible/ansible/issues/10698/events","html_url":"https://github.com/ansible/ansible/issues/10698","id":68297632,"number":10698,"title":"Ansible permits ssh to send local LANG and LC_ALL env vars (file misencoding, filename corruption)","user":{"login":"ringerc","id":274337,"avatar_url":"https://avatars.githubusercontent.com/u/274337?v=3","gravatar_id":"","url":"https://api.github.com/users/ringerc","html_url":"https://github.com/ringerc","followers_url":"https://api.github.com/users/ringerc/followers","following_url":"https://api.github.com/users/ringerc/following{/other_user}","gists_url":"https://api.github.com/users/ringerc/gists{/gist_id}","starred_url":"https://api.github.com/users/ringerc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ringerc/subscriptions","organizations_url":"https://api.github.com/users/ringerc/orgs","repos_url":"https://api.github.com/users/ringerc/repos","events_url":"https://api.github.com/users/ringerc/events{/privacy}","received_events_url":"https://api.github.com/users/ringerc/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-04-14T08:06:26Z","updated_at":"2015-04-14T21:09:07Z","closed_at":null,"body":"Newer ssh versions like to send `LANG` and `LC_ALL` to the remote sshd, so that the remote ssh session has the same locale as the local user's session.\r\n\r\nThis makes Ansible playbook execution, including things like files created on the remote end, dependent on the environment of the user running the playbook. Files may have different language text and/or be in a different text encoding. File *names* may have different encodings too, so that the file named `Álvaro` in `en_US.utf-8` will be listed as `??lvaro` in `en_US`, even though it'll actually match the glob `?lvaro`.\r\n\r\nE.g.\r\n\r\n```\r\n$ LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 touch \"Álvaro\"\r\n$ LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 ls\r\nÁlvaro\r\n$ LANG=en_US LC_ALL=en_US ls\r\n??lvaro\r\n```\r\n\r\nAs far as I can tell Ansible doesn't support overriding environment variables for all tasks that run on a given host / hostgroup, nor does it support the `environment` keyword at the playbook level under the `hosts` dictionary. So it's not currently easy to say \"Always use the xx_XX locale for this host\".\r\n\r\nThese errors are often treated as minor and ignore-able, but they're anything but, especially when they result in mixing utf-8 and 1-byte encodings.\r\n\r\n**This does not (just) affect people who use non-English languages**. I noticed the problem because I use the `en_AU.utf-8` locale on my workstation, but most of the hosts I manage only have the `C`, `C.UTF-8` and `en_US.UTF-8` locales configured. The system falls back to `C`.\r\n\r\n[`perl` is particularly noisy about this](http://stackoverflow.com/q/2499794/398670):\r\n\r\n```\r\n$ perl\r\nperl: warning: Setting locale failed.\r\nperl: warning: Please check that your locale settings:\r\n\tLANGUAGE = (unset),\r\n\tLC_ALL = (unset),\r\n\tLC_PAPER = \"en_AU.utf8\",\r\n\tLC_MONETARY = \"en_AU.utf8\",\r\n\tLC_NUMERIC = \"en_AU.utf8\",\r\n\tLC_MEASUREMENT = \"en_AU.utf8\",\r\n\tLC_TIME = \"en_AU.utf8\",\r\n\tLANG = \"en_US.UTF-8\"\r\n    are supported and installed on your system.\r\nperl: warning: Falling back to the standard locale (\"C\").\r\n```\r\n\r\nThe `locale` command will also complain:\r\n\r\n```\r\n$ locale\r\nlocale: Cannot set LC_ALL to default locale: No such file or directory\r\n```\r\n\r\n\r\nThe best solution, IMO, is for Ansible to use the *remote end*'s default locale, by suppressing sending of `LANG` and `LC_ALL` over `ssh` by default.\r\n\r\nThis is most visible on Debian and Ubuntu systems, which default to\r\n\r\n```\r\nAcceptEnv LANG LC_*\r\n```\r\n\r\nin `/etc/ssh/sshd_config`.\r\n\r\nAs a workaround for this issue, users may wish to remove the above `AcceptEnv` directive from the `sshd_config` on the server, thus disallowing locales from being set by the `ssh` client. Alternately, on the *client* side, users may remove:\r\n\r\n```\r\nSendEnv LANG LC_*\r\n```\r\n\r\nfrom their `/etc/ssh/ssh_config`. It does *not* appear to be possible to disable this on a per-host basis, unfortunately; see:\r\n\r\n* http://superuser.com/q/485569/167160\r\n* https://bugzilla.mindrot.org/show_bug.cgi?id=1285\r\n* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=573316\r\n\r\nSo the ideal would be for Ansible to override the `LC_` variables and `LANG` before invoking `ssh`, or for Ansible to use its own global configuration file for `ssh`.\r\n\r\n---\r\n\r\nThe simplest workaround is to create a minimal `ansible_ssh_config` in your Ansible project trees, like:\r\n\r\n```\r\nHost *\r\n        ForwardAgent no\r\n        ControlMaster=auto\r\n        ControlPersist=60s\r\n```\r\n\r\nand then override `ansible`'s default ssh command in an `ansible.cfg` in your project tree, like:\r\n\r\n```\r\n[ssh_connection]\r\nssh_args=-F ansible_ssh_config\r\n```\r\n\r\nThe downside is that if Ansible's default ssh command changes, you won't see the change."},"comment":{"url":"https://api.github.com/repos/ansible/ansible/issues/comments/93062191","html_url":"https://github.com/ansible/ansible/issues/10698#issuecomment-93062191","issue_url":"https://api.github.com/repos/ansible/ansible/issues/10698","id":93062191,"user":{"login":"mscherer","id":230335,"avatar_url":"https://avatars.githubusercontent.com/u/230335?v=3","gravatar_id":"","url":"https://api.github.com/users/mscherer","html_url":"https://github.com/mscherer","followers_url":"https://api.github.com/users/mscherer/followers","following_url":"https://api.github.com/users/mscherer/following{/other_user}","gists_url":"https://api.github.com/users/mscherer/gists{/gist_id}","starred_url":"https://api.github.com/users/mscherer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mscherer/subscriptions","organizations_url":"https://api.github.com/users/mscherer/orgs","repos_url":"https://api.github.com/users/mscherer/repos","events_url":"https://api.github.com/users/mscherer/events{/privacy}","received_events_url":"https://api.github.com/users/mscherer/received_events","type":"User","site_admin":false},"created_at":"2015-04-14T21:09:06Z","updated_at":"2015-04-14T21:09:06Z","body":"Yeah, this can have some annoying effect, especially if you parse the output of tools  ( personal example with salt and chkconfig  https://github.com/saltstack/salt-bootstrap/pull/558 ). \r\n\r\nI think it would just be easier to force LC_ALL=C in the ssh plugin."}}