Repository: certbot/certbot

Issue:
Validation of `--dns-rfc2136-credentials` prevents use of templating via process substitution
## My operating system is (include version):
Debian Stretch

## I installed Certbot with (certbot-auto, OS package manager, pip, etc):
Installed via pip from git@v0.35.1 

## I ran this command and it produced this output:
```
certbot certonly --agree-tos --register-unsafely-without-email --dns-rfc2136 --dns-rfc2136-propagation-seconds 10 --dns-rfc2136-credentials <(/usr/bin/envsubst < /usr/local/share/rfc2136.ini.template) -d ${ACME_DOMAIN} -d *.${ACME_DOMAIN}
```
Template allows dns-rfc2136 plugin to use a TSIG key stored in an environmental variable

## Certbot's behavior differed from what I expected because:
I somewhat expected `certbot` to [check](https://github.com/certbot/certbot/blob/master/certbot/plugins/dns_common.py#L307) if it was provided a real file, so this isn't unexpected.

I'm trying to dockerize certbot into an application that can be run as
```
export ACME_DOMAIN=example.com
export TSIG_ACME=dead...beef==
docker run -it -e ACME_DOMAIN -e TSIG_ACME -v /etc/letsencrypt:/etc/letsencrypt
 registry.example.com/certbot_rfc2136:0.1.0
```


## Here is a Certbot log showing the issue (if available):
###### Logs are stored in `/var/log/letsencrypt` by default. Feel free to redact domains, e-mail and IP addresses as you see fit.
```
2019-07-05 20:25:35,970:DEBUG:certbot.error_handler:Encountered exception:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/certbot/auth_handler.py", line 69, in handle_authorizations
    resps = self.auth.perform(achalls)
  File "/usr/local/lib/python2.7/dist-packages/certbot/plugins/dns_common.py", line 48, in perform
    self._setup_credentials()
  File "/usr/local/lib/python2.7/dist-packages/certbot_dns_rfc2136/dns_rfc2136.py", line 72, in _setup_credentia
ls
    self._validate_algorithm
  File "/usr/local/lib/python2.7/dist-packages/certbot/plugins/dns_common.py", line 171, in _configure_credentia
ls
    credentials_configuration = CredentialsConfiguration(self.conf(key), self.dest)
  File "/usr/local/lib/python2.7/dist-packages/certbot/plugins/dns_common.py", line 248, in __init__
    validate_file_permissions(filename)
  File "/usr/local/lib/python2.7/dist-packages/certbot/plugins/dns_common.py", line 313, in validate_file_permis
sions
    validate_file(filename)
  File "/usr/local/lib/python2.7/dist-packages/certbot/plugins/dns_common.py", line 307, in validate_file
    raise errors.PluginError('Path is not a file: {0}'.format(filename))
PluginError: Path is not a file: /dev/fd/63
```

```
$ ls -la <(/usr/bin/envsubst < /usr/local/share/rfc2136.ini.template)
lr-x------ 1 www-data www-data 64 Jul  5 20:27 /dev/fd/63 -> pipe:[683770]
```

I'll submit a pull request when I get a chance.


Discussion:

Resolving patch:
diff --git a/certbot/plugins/dns_common.py b/certbot/plugins/dns_common.py
--- a/certbot/plugins/dns_common.py
+++ b/certbot/plugins/dns_common.py
@@ -303,8 +303,8 @@ def validate_file(filename):
     if not os.path.exists(filename):
         raise errors.PluginError('File not found: {0}'.format(filename))
 
-    if not os.path.isfile(filename):
-        raise errors.PluginError('Path is not a file: {0}'.format(filename))
+    if os.path.isdir(filename):
+        raise errors.PluginError('Path is a directory: {0}'.format(filename))
 
 
 def validate_file_permissions(filename):


Test patch: