Repository: certbot/certbot

Issue:
NameError: free variable 'addrs' referenced before assignment in enclosing scope
When using `./letsencrypt-auto run` on Ubuntu 14.04 I run into this error:

`An unexpected error occurred:
NameError: free variable 'addrs' referenced before assignment in enclosing scope`.

From letsencrypt.log:

```
2016-02-13 10:13:29,799:DEBUG:letsencrypt.error_handler:Calling registered functions
2016-02-13 10:13:29,802:DEBUG:letsencrypt.cli:Exiting abnormally:
Traceback (most recent call last):
  File "/home/aaa/.local/share/letsencrypt/bin/letsencrypt", line 11, in <module>
    sys.exit(main())
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/cli.py", line 1987, in main
    return config.func(config, plugins)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/cli.py", line 667, in run
    lineage.chain, lineage.fullchain)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/client.py", line 355, in deploy_certificate
    fullchain_path=fullchain_path)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 214, in deploy_cert
    vhost = self.choose_vhost(domain)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 308, in choose_vhost
    vhost = self.make_vhost_ssl(vhost)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 733, in make_vhost_ssl
    self._add_name_vhost_if_necessary(ssl_vhost)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 905, in _add_name_vhost_if_necessary
    test_addr in test_vh.addrs) and
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 905, in <genexpr>
    test_addr in test_vh.addrs) and
NameError: free variable 'addrs' referenced before assignment in enclosing scope
```

I'm using version 45ee1eb889c86f582c53b1743fdfaf9187c4658b.

NameError: free variable 'addrs' referenced before assignment in enclosing scope
When using `./letsencrypt-auto run` on Ubuntu 14.04 I run into this error:

`An unexpected error occurred:
NameError: free variable 'addrs' referenced before assignment in enclosing scope`.

From letsencrypt.log:

```
2016-02-13 10:13:29,799:DEBUG:letsencrypt.error_handler:Calling registered functions
2016-02-13 10:13:29,802:DEBUG:letsencrypt.cli:Exiting abnormally:
Traceback (most recent call last):
  File "/home/aaa/.local/share/letsencrypt/bin/letsencrypt", line 11, in <module>
    sys.exit(main())
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/cli.py", line 1987, in main
    return config.func(config, plugins)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/cli.py", line 667, in run
    lineage.chain, lineage.fullchain)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/client.py", line 355, in deploy_certificate
    fullchain_path=fullchain_path)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 214, in deploy_cert
    vhost = self.choose_vhost(domain)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 308, in choose_vhost
    vhost = self.make_vhost_ssl(vhost)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 733, in make_vhost_ssl
    self._add_name_vhost_if_necessary(ssl_vhost)
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 905, in _add_name_vhost_if_necessary
    test_addr in test_vh.addrs) and
  File "/home/aaa/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt_apache/configurator.py", line 905, in <genexpr>
    test_addr in test_vh.addrs) and
NameError: free variable 'addrs' referenced before assignment in enclosing scope
```

I'm using version 45ee1eb889c86f582c53b1743fdfaf9187c4658b.



Discussion:
I'm getting the same error here. 
Edit: Running on Debian Jessie

+1, though trying it on CentOS 7.

A workaround for the people affected by this: 

As the stacktrace suggests, something goes wrong in creating a new virtualhost. If you set up an SSL enabled virtualhost for the domain yourself (without any certificates in it) and run letsencrypt-auto again, it will work. For ubuntu/Debian create the file  `/etc/apache2/sites-available/example.com.conf`. No need to enable, letsencrypt will do that for you.

Example vhost file (check your ciphers/protocols):

```
<VirtualHost *:443>
        ServerAdmin info@example.com
        ServerName example.com
        ServerAlias www.example.com

        DocumentRoot /var/www/example.com/public_html/

        ErrorLog /path/to/logs/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /path/to/logs/ssl_access.log combined

        #   SSL Engine Switch:
        #   Enable/Disable SSL for this virtual host.
        SSLEngine on
        SSLProtocol all -SSLv2 -SSLv3
        SSLHonorCipherOrder on
        SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4

        # Certificates
        SSLCertificateFile    /this/will/be/replaced/by/letsencrypt
        SSLCertificateKeyFile /this/will/be/replaced/by/letsencrypt/too

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>
        BrowserMatch "MSIE [2-6]" \
                nokeepalive ssl-unclean-shutdown \
                downgrade-1.0 force-response-1.0
        # MSIE 7 and newer should be able to use keepalive
        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

</VirtualHost>
```

I'm getting the same error here. 
Edit: Running on Debian Jessie

+1, though trying it on CentOS 7.

A workaround for the people affected by this: 

As the stacktrace suggests, something goes wrong in creating a new virtualhost. If you set up an SSL enabled virtualhost for the domain yourself (without any certificates in it) and run letsencrypt-auto again, it will work. For ubuntu/Debian create the file  `/etc/apache2/sites-available/example.com.conf`. No need to enable, letsencrypt will do that for you.

Example vhost file (check your ciphers/protocols):

```
<VirtualHost *:443>
        ServerAdmin info@example.com
        ServerName example.com
        ServerAlias www.example.com

        DocumentRoot /var/www/example.com/public_html/

        ErrorLog /path/to/logs/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /path/to/logs/ssl_access.log combined

        #   SSL Engine Switch:
        #   Enable/Disable SSL for this virtual host.
        SSLEngine on
        SSLProtocol all -SSLv2 -SSLv3
        SSLHonorCipherOrder on
        SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4

        # Certificates
        SSLCertificateFile    /this/will/be/replaced/by/letsencrypt
        SSLCertificateKeyFile /this/will/be/replaced/by/letsencrypt/too

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>
        BrowserMatch "MSIE [2-6]" \
                nokeepalive ssl-unclean-shutdown \
                downgrade-1.0 force-response-1.0
        # MSIE 7 and newer should be able to use keepalive
        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

</VirtualHost>
```


Resolving patch:
diff --git a/letsencrypt-apache/letsencrypt_apache/configurator.py b/letsencrypt-apache/letsencrypt_apache/configurator.py
--- a/letsencrypt-apache/letsencrypt_apache/configurator.py
+++ b/letsencrypt-apache/letsencrypt_apache/configurator.py
@@ -895,9 +895,10 @@ def _add_name_vhost_if_necessary(self, vhost):
         for addr in vhost.addrs:
             # In Apache 2.2, when a NameVirtualHost directive is not
             # set, "*" and "_default_" will conflict when sharing a port
+            addrs = set((addr,))
             if addr.get_addr() in ("*", "_default_"):
-                addrs = [obj.Addr((a, addr.get_port(),))
-                         for a in ("*", "_default_")]
+                addrs.update(obj.Addr((a, addr.get_port(),))
+                             for a in ("*", "_default_"))
 
             for test_vh in self.vhosts:
                 if (vhost.filep != test_vh.filep and
@@ -907,6 +908,7 @@ def _add_name_vhost_if_necessary(self, vhost):
                     self.add_name_vhost(addr)
                     logger.info("Enabling NameVirtualHosts on %s", addr)
                     need_to_save = True
+                    break
 
         if need_to_save:
             self.save()


Test patch: