Securing ISPConfig 3 Control Panel (Port 8080) With Let's Encrypt Free SSL

Discussion in 'Tips/Tricks/Mods' started by ahrasis, Feb 14, 2017.

  1. Tastiger

    Tastiger Member HowtoForge Supporter

    I think our posts crossed - I have since updated my post with more information.
     
  2. Tastiger

    Tastiger Member HowtoForge Supporter

    At the very least I think I will need some instruction on how to reverse the changes to pure-ftp
     
  3. ahrasis

    ahrasis Well-Known Member

    Sorry. I haven't received alert on your replies and didn't browse this board so frequent.

    This should be the full path of your server fqdn LE archive directory that you are using in this guide, as incron will run the created script if any changes are made to it.

    As for the ftp, if you set it correctly, you or other users can access it via your server fqdn and not others because this guide aimed to secure it access via your server fqdn only.
     
  4. Tuumke

    Tuumke Active Member

    Should i add an subdomain or a new site?
    -edit-
    Created a site.
    Set rewrite to https://web.domain.tld:8080
    Works like a charm!
    -edit2-
    New challenge:
    5 server setup. I now have my web.domain.tld secured via this tutorial, but how about my mail.domain.tld and ftp.domain.tld?
    Can i request a *.domain.tld (wildcard) certificate?
    LE doesnt support wildcard. Then how do i add mail.domain.tld to the certificate?
     
    Last edited: Jun 7, 2017
  5. Jesse Norell

    Jesse Norell ISPConfig Developer Staff Member ISPConfig Developer

  6. Tastiger

    Tastiger Member HowtoForge Supporter

    Should I be getting renewal notices?
    what is the command to manually renew certificates?
     
  7. ahrasis

    ahrasis Well-Known Member

    Relying on auto renewal by ISPConfig is preferred because people tend to forget Letsencrypt renewal most of the time.

    To ensure Letsencrypt auto renewal keeps working do check ISPC / Letsencrypt log file(s) for error(s) especially when renewal reminders are given any time after sixty days, before trying to renew Letsencrypt ssl certs manually.
     
  8. Tastiger

    Tastiger Member HowtoForge Supporter

    OK , thanks for that, will check the logs
    Just a quick question on the last part of the tutorial:-
    in incron.allow
    Code:
    /etc/letsencrypt/archive/yourserverdomain/ IN_MODIFY ./etc/init.d/le_ispc_pem.sh
    should the "yourserverdomain" be the full server name (ie: server1.XXX) or do I need an entry for each domain
     
  9. ahrasis

    ahrasis Well-Known Member

    It should be in full e.g. server1.example.com.
     
    Tastiger likes this.
  10. Tastiger

    Tastiger Member HowtoForge Supporter

    I actually think there may be an error in my setup - here is my /var/log/letsencrypt
    Code:
    2017-07-22 17:02:26,548:DEBUG:letsencrypt.cli:Root logging level set at 30
    2017-07-22 17:02:26,549:INFO:letsencrypt.cli:Saving debug log to /var/log/letsencrypt/letsencrypt.log
    2017-07-22 17:02:26,550:DEBUG:letsencrypt.cli:letsencrypt version: 0.4.1
    2017-07-22 17:02:26,550:DEBUG:letsencrypt.cli:Arguments: ['-n']
    2017-07-22 17:02:26,551:DEBUG:letsencrypt.cli:Discovered plugins: PluginsRegistry(PluginEntryPoint#webroot,PluginEntryPoint#null,PluginEntryPoint#manual,PluginEntryPoint#standalone)
    2017-07-22 17:02:26,606:DEBUG:letsencrypt.cli:Requested authenticator  and installer
    2017-07-22 17:02:26,606:DEBUG:letsencrypt.cli:Default Detector is Namespace(account='', agree_dev_preview=None, apache='', authenticator='', break_my_certs='', cert_path='/usr/local/ispconfig/server', chain_path=None, checkpoints=0, config_dir='', config_file=None, configurator='', csr='', debug='', domains=[], dry_run='', duplicate='', email='', expand='', fullchain_path=None, func=<function renew at 0x7f55afde9140>, hsts=False, http01_port=0, ifaces='', init='', installer='', key_path='/usr/local/ispconfig/server', logs_dir='', manual='', manual_public_ip_logging_ok=False, manual_test_mode=False, nginx='', no_self_upgrade='', no_verify_ssl=False, noninteractive_mode=True, os_packages_only='', prepare='', redirect=None, register_unsafely_without_email='', reinstall='', renew_by_default='', rsa_key_size=0, server='', staging='', standalone='', standalone_supported_challenges='tls-sni-01,http-01', store_false_vars={'--no-uir': True, <letsencrypt.cli.HelpfulArgumentParser object at 0x7f55af8f4910>: True, '--no-redirect': True, '--no-hsts': True}, strict_permissions='', text_mode='', tls_sni_01_port=0, tos='', uir=None, user_agent=None, verb='renew', verbose_count=0, version='', webroot='', webroot_map={}, webroot_path=[], work_dir='')
    2017-07-22 17:02:26,619:DEBUG:parsedatetime:parse (top of loop): [30 days][]
    2017-07-22 17:02:26,627:DEBUG:parsedatetime:CRE_UNITS matched
    2017-07-22 17:02:26,628:DEBUG:parsedatetime:parse (bottom) [][30 days][][]
    2017-07-22 17:02:26,628:DEBUG:parsedatetime:weekday False, dateStd False, dateStr False, time False, timeStr False, meridian False
    2017-07-22 17:02:26,628:DEBUG:parsedatetime:dayStr False, modifier False, modifier2 False, units True, qunits False
    2017-07-22 17:02:26,628:DEBUG:parsedatetime:_evalString(30 days, time.struct_time(tm_year=2017, tm_mon=7, tm_mday=22, tm_hour=17, tm_min=2, tm_sec=26, tm_wday=5, tm_yday=203, tm_isdst=0))
    2017-07-22 17:02:26,628:DEBUG:parsedatetime:_buildTime: [30 ][][days]
    2017-07-22 17:02:26,628:DEBUG:parsedatetime:units days --> realunit days
    2017-07-22 17:02:26,628:DEBUG:parsedatetime:return
    2017-07-22 17:02:26,629:INFO:letsencrypt.cli:Cert not yet due for renewal
    2017-07-22 17:02:26,629:WARNING:letsencrypt.cli:Renewal configuration file /etc/letsencrypt/renewal/jones.dhs.org.conf is broken. Skipping.
    2017-07-22 17:02:26,645:DEBUG:letsencrypt.cli:Traceback was:
    Traceback (most recent call last):
      File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 900, in _reconstitute
        full_path, configuration.RenewerConfiguration(config))
      File "/usr/lib/python2.7/dist-packages/letsencrypt/storage.py", line 200, in __init__
        "file reference".format(self.configfile))
    CertStorageError: renewal config file {} is missing a required file reference
    
    2017-07-22 17:02:26,683:DEBUG:parsedatetime:parse (top of loop): [30 days][]
    2017-07-22 17:02:26,683:DEBUG:parsedatetime:CRE_UNITS matched
    2017-07-22 17:02:26,683:DEBUG:parsedatetime:parse (bottom) [][30 days][][]
    2017-07-22 17:02:26,683:DEBUG:parsedatetime:weekday False, dateStd False, dateStr False, time False, timeStr False, meridian False
    2017-07-22 17:02:26,683:DEBUG:parsedatetime:dayStr False, modifier False, modifier2 False, units True, qunits False
    2017-07-22 17:02:26,684:DEBUG:parsedatetime:_evalString(30 days, time.struct_time(tm_year=2017, tm_mon=7, tm_mday=22, tm_hour=17, tm_min=2, tm_sec=26, tm_wday=5, tm_yday=203, tm_isdst=0))
    2017-07-22 17:02:26,684:DEBUG:parsedatetime:_buildTime: [30 ][][days]
    2017-07-22 17:02:26,684:DEBUG:parsedatetime:units days --> realunit days
    2017-07-22 17:02:26,684:DEBUG:parsedatetime:return
    2017-07-22 17:02:26,684:INFO:letsencrypt.cli:Cert not yet due for renewal
    2017-07-22 17:02:26,712:DEBUG:parsedatetime:parse (top of loop): [30 days][]
    2017-07-22 17:02:26,712:DEBUG:parsedatetime:CRE_UNITS matched
    2017-07-22 17:02:26,712:DEBUG:parsedatetime:parse (bottom) [][30 days][][]
    2017-07-22 17:02:26,712:DEBUG:parsedatetime:weekday False, dateStd False, dateStr False, time False, timeStr False, meridian False
    2017-07-22 17:02:26,712:DEBUG:parsedatetime:dayStr False, modifier False, modifier2 False, units True, qunits False
    2017-07-22 17:02:26,713:DEBUG:parsedatetime:_evalString(30 days, time.struct_time(tm_year=2017, tm_mon=7, tm_mday=22, tm_hour=17, tm_min=2, tm_sec=26, tm_wday=5, tm_yday=203, tm_isdst=0))
    2017-07-22 17:02:26,713:DEBUG:parsedatetime:_buildTime: [30 ][][days]
    2017-07-22 17:02:26,713:DEBUG:parsedatetime:units days --> realunit days
    2017-07-22 17:02:26,713:DEBUG:parsedatetime:return
    2017-07-22 17:02:26,713:INFO:letsencrypt.cli:Cert not yet due for renewal
    2017-07-22 17:02:26,747:DEBUG:parsedatetime:parse (top of loop): [30 days][]
    2017-07-22 17:02:26,747:DEBUG:parsedatetime:CRE_UNITS matched
    2017-07-22 17:02:26,747:DEBUG:parsedatetime:parse (bottom) [][30 days][][]
    2017-07-22 17:02:26,747:DEBUG:parsedatetime:weekday False, dateStd False, dateStr False, time False, timeStr False, meridian False
    2017-07-22 17:02:26,748:DEBUG:parsedatetime:dayStr False, modifier False, modifier2 False, units True, qunits False
    2017-07-22 17:02:26,748:DEBUG:parsedatetime:_evalString(30 days, time.struct_time(tm_year=2017, tm_mon=7, tm_mday=22, tm_hour=17, tm_min=2, tm_sec=26, tm_wday=5, tm_yday=203, tm_isdst=0))
    2017-07-22 17:02:26,748:DEBUG:parsedatetime:_buildTime: [30 ][][days]
    2017-07-22 17:02:26,748:DEBUG:parsedatetime:units days --> realunit days
    2017-07-22 17:02:26,748:DEBUG:parsedatetime:return
    2017-07-22 17:02:26,748:INFO:letsencrypt.cli:Cert not yet due for renewal
    2017-07-22 17:02:26,765:DEBUG:parsedatetime:parse (top of loop): [30 days][]
    2017-07-22 17:02:26,765:DEBUG:parsedatetime:CRE_UNITS matched
    2017-07-22 17:02:26,765:DEBUG:parsedatetime:parse (bottom) [][30 days][][]
    2017-07-22 17:02:26,765:DEBUG:parsedatetime:weekday False, dateStd False, dateStr False, time False, timeStr False, meridian False
    2017-07-22 17:02:26,765:DEBUG:parsedatetime:dayStr False, modifier False, modifier2 False, units True, qunits False
    2017-07-22 17:02:26,765:DEBUG:parsedatetime:_evalString(30 days, time.struct_time(tm_year=2017, tm_mon=7, tm_mday=22, tm_hour=17, tm_min=2, tm_sec=26, tm_wday=5, tm_yday=203, tm_isdst=0))
    2017-07-22 17:02:26,765:DEBUG:parsedatetime:_buildTime: [30 ][][days]
    2017-07-22 17:02:26,765:DEBUG:parsedatetime:units days --> realunit days
    2017-07-22 17:02:26,765:DEBUG:parsedatetime:return
    2017-07-22 17:02:26,765:INFO:letsencrypt.cli:Cert not yet due for renewal
    2017-07-22 17:02:26,798:DEBUG:parsedatetime:parse (top of loop): [30 days][]
    2017-07-22 17:02:26,798:DEBUG:parsedatetime:CRE_UNITS matched
    2017-07-22 17:02:26,798:DEBUG:parsedatetime:parse (bottom) [][30 days][][]
    2017-07-22 17:02:26,799:DEBUG:parsedatetime:weekday False, dateStd False, dateStr False, time False, timeStr False, meridian False
    2017-07-22 17:02:26,799:DEBUG:parsedatetime:dayStr False, modifier False, modifier2 False, units True, qunits False
    2017-07-22 17:02:26,799:DEBUG:parsedatetime:_evalString(30 days, time.struct_time(tm_year=2017, tm_mon=7, tm_mday=22, tm_hour=17, tm_min=2, tm_sec=26, tm_wday=5, tm_yday=203, tm_isdst=0))
    2017-07-22 17:02:26,799:DEBUG:parsedatetime:_buildTime: [30 ][][days]
    2017-07-22 17:02:26,799:DEBUG:parsedatetime:units days --> realunit days
    2017-07-22 17:02:26,799:DEBUG:parsedatetime:return
    2017-07-22 17:02:26,799:INFO:letsencrypt.cli:Cert not yet due for renewal
    2017-07-22 17:02:26,843:DEBUG:parsedatetime:parse (top of loop): [30 days][]
    2017-07-22 17:02:26,844:DEBUG:parsedatetime:CRE_UNITS matched
    2017-07-22 17:02:26,844:DEBUG:parsedatetime:parse (bottom) [][30 days][][]
    2017-07-22 17:02:26,844:DEBUG:parsedatetime:weekday False, dateStd False, dateStr False, time False, timeStr False, meridian False
    2017-07-22 17:02:26,844:DEBUG:parsedatetime:dayStr False, modifier False, modifier2 False, units True, qunits False
    2017-07-22 17:02:26,844:DEBUG:parsedatetime:_evalString(30 days, time.struct_time(tm_year=2017, tm_mon=7, tm_mday=22, tm_hour=17, tm_min=2, tm_sec=26, tm_wday=5, tm_yday=203, tm_isdst=0))
    2017-07-22 17:02:26,844:DEBUG:parsedatetime:_buildTime: [30 ][][days]
    2017-07-22 17:02:26,844:DEBUG:parsedatetime:units days --> realunit days
    2017-07-22 17:02:26,844:DEBUG:parsedatetime:return
    2017-07-22 17:02:26,844:INFO:letsencrypt.cli:Cert not yet due for renewal
    2017-07-22 17:02:26,845:DEBUG:letsencrypt.cli:Exiting abnormally:
    Traceback (most recent call last):
      File "/usr/bin/letsencrypt", line 9, in <module>
        load_entry_point('letsencrypt==0.4.1', 'console_scripts', 'letsencrypt')()
      File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 1986, in main
        return config.func(config, plugins)
      File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 1034, in renew
        len(renew_failures), len(parse_failures)))
    Error: 0 renew failure(s), 1 parse failure(s)
    
    
     
  11. Jesse Norell

    Jesse Norell ISPConfig Developer Staff Member ISPConfig Developer

    Is jones.dhs.org a site you created through ISPConfig? If so I'd just disable the letsencrypt checkbox on it, wait a minute, then clean up everything under /etc/letsencrypt pertaining to that name, and enable the checkbox again, so it requests a new certificate. (If you set that up manually, maybe just do the same cleanup, then attempt to issue a certificate manually again.)
     
  12. Tastiger

    Tastiger Member HowtoForge Supporter

    yes was created via ISPC, have done as you have suggested, however it has created the files as www.jones,dhs,org ?????
    No difference it site setup details from the other .dhs.org domains and they are not showing up as www but showing up as just the domain name (eg: tastiger.dhs.org)
     
  13. Tastiger

    Tastiger Member HowtoForge Supporter

    OK - it seems as if I had auto sub domain (www) selected when I saved the site after reactivating letsencrypt so I went through the process again and all looks good will see what happens with the log from here on in.

    Thanks
     
    ahrasis likes this.
  14. Tastiger

    Tastiger Member HowtoForge Supporter

    I'd also like to add that one thing I have noticed is that if you add a sub domain after initial setup, that sub domain does not appear on the certificate as can be seen from this excerpt from one of my /etc/letsencrypt/renewal *.conf files:
    Since that was generated I have added another sub domain "hunter-valley" which is not showing up as can be seen, is this normal behavior and should I switch off letsencrypt on the site and then reactivate to generate a new certificate?
    Or can I edit the renewal file to include the sub domain?
     
  15. ahrasis

    ahrasis Well-Known Member

    Basically this is not directly related to this thread which aims at a single domain website of the server.

    Nevertheless, with regards to your issues, normally the subdomain will be automatically inserted into the main website LE SSL certs.

    However, I think the subdomain must exist in the main website dns A record either like *.domain.tld or sub.domain.tld, or otherwise it won't work at all.

    Unless they are bugs which should be reported at the appropriate place, do check this as well as your log(s) to determine the problem(s) and find the right solution(s).

    As an option, for those who want simplicity in obtaining LE SSL certs without a need to create any website should really try to learn acme.sh as already prescribed by @sjau in other thread.
     
  16. Tastiger

    Tastiger Member HowtoForge Supporter

    That is what I was guessing - it was added to the "A" record after the certificate had been issued.
    Thanks anyway - will check out the other thread
     
  17. ahrasis

    ahrasis Well-Known Member

    Then simply uncheck, pause and recheck the LE button in the main website settings. I think it should be added automatically by ISPC thereafter without you have to rather manually do it outside ISPC.

    For acme.sh, almost like certbot, you need to run a proper command once, and it will take care of the creation and renewal/update automatically. This post and this post by @sjau should be the relevant references for that, while in the same thread, certbot solution as posted by @Jesse Norell should be a good option as well.
     
  18. ahrasis

    ahrasis Well-Known Member

    Updated the opening thread and modified all codes so that they can be scripted later on. While due care is given in updating the codes for future conversion to a script, do report if there is any error detected.
     
  19. chaosad

    chaosad New Member

    Hello,
    thank you for the great howto, it works really well so far but for FileZilla I still get a warning:

    Code:
    The error occured at a depth of 2 in the certificate chain. 
     
  20. ahrasis

    ahrasis Well-Known Member

    Sorry, I have not test this with filezilla for ftp but I think it should work fine. The following are just some checkup questions.

    1. Are you sure you are rightly connecting to your ftp to yourserver.domain.tld and not yourothersite.domain.tld?
    2. Can you check the output of "ls -l /etc/ssl/private/pure-ftpd.pem"?
    3. Does it show a link back to "/usr/local/ispconfig/interface/ssl/ispserver.pem"?
    4. Check also whether you have pure-ftpd.pem chmod to 600?
     

Share This Page