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. ahrasis

    ahrasis Active Member

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

    Earlier, I have posted on how to create Let's Encrypt for your server. However, there is a minor issue with ispserver.pem, where it will need to be rebuilt manually upon Let's Encrypt renewal of its SSL files. This is because it is not merely symlinked but rather created by combining several Let's Encrypt files.

    It is pertinent to note that I am using Ubuntu 16.04 with Nginx while Let's Encrypt (creation and renewal) from ISPConfig 3 is fully working, so I do not guarantee this to work for all of you on other builds or distros or you got problems with your Let's Encrypt. Certain modifications may be necessary to make it work for you. So let us start the guide once more time for the benefits of all.

    [Creating ISPConfig Server Website Using Its Hostname FQDN]
    1. Create a site for your server in ISPConfig panel via Sites > Website > Add new website. Remember! This creates your server website, thus it must contain your server fully qualified domain name (FQDN). I will refer to it as `hostname -f` in this guide, hopefully in can work without any changes for your server as well.

    [Accessing ISPConfig Website Online]
    2. Check if your server site is ready and accessible online as Let's Encrypt needs to verify your website is accessible before issuing SSL files for your server website. You have to create its DNS Zone and allow it to properly propagate as Let's Encrypt needs to verify it too.

    [Enabling SSL For ISPConfig 3 Control Panel (Port 8080)]
    3. If you haven't enabled SSL during ISPConfig setup (default is port 8080), enable it by running in the terminal and select yes for SSL. We don't need this to be a proper key nor do we want to keep it but we do want to work faster, thus we can simply enter for all of its fields. When you finished this, the self-signed SSL should already be enabled for this port.

    [Checking SSL For ISPConfig 3 Control Panel]
    4. Check your browser to confirm by opening the ISPConfig control panel at port 8080. Note that you might get some warning at this stage since the created SSL files are self-signed but the browser will confirm that your ISPConfig has SSL enabled or otherwise.

    [Securing ISPConfig Website With Let's Encrypt SSL]
    5. To create Let's Encrypt SSL files and enable them for your server site, go back to ISPConfig panel > Sites > Website > Website Name, click SSL and Let's Encrypt check buttons and save. If successful, your server website shall now be using this Let's Encrypt SSL files but not yet for your ISPConfig 8080 port. If unsuccessful, DO NOT proceed further but check its log file for a clue.

    [Assigning Let's Encrypt SSL For ISPConfig 3 Control Panel]
    6. If LE SSL is already working, via your server terminal, root via sudo su and use the following command to backup and replace the created self-signed SSL files with Let's Encrypt SSL files.
    cd /usr/local/ispconfig/interface/ssl/
    mv ispserver.crt ispserver.crt-$(date +"%y%m%d%H%M%S").bak
    mv ispserver.key ispserver.key-$(date +"%y%m%d%H%M%S").bak
    if [ -f "ispserver.pem" ]; then
        mv ispserver.pem ispserver.pem-$(date +"%y%m%d%H%M%S").bak
    ln -s /etc/letsencrypt/live/$(hostname -f)/fullchain.pem ispserver.crt
    ln -s /etc/letsencrypt/live/$(hostname -f)/privkey.pem ispserver.key
    cat ispserver.{key,crt} > ispserver.pem
    chmod 600 ispserver.pem
    * If you haven't created ispserver.pem before, the code will ignore it.
    * Note that we are using Let's Encrypt live folder instead of archive folder.
    * Also note the last line where ispserver.pem is created by combining LE SSL files, thus, it won't be automatically renewed by Let's Encrypt unlike other files which we merely symlinked them, so, we will deal with this in the last part of this guide.
    * Note also that you either use `hostname -f` or as the result normally is the same, but use the later if you face problem with the first.

    [Using The Same Let's Encrypt SSL Certs For Other Major Services]
    7. As additional tips, based on Securing Your ISPConfig 3 Installation you may want to use symlink to ispserver.key or .crt or .pem instead of directly pointing your postfix, dovecot, courier, pure-FTPd and monit to the same SSL files. In details you only need to do the followings:
    a. For postfix:
    cd /etc/postfix/
    mv smtpd.cert smtpd.cert-$(date +"%y%m%d%H%M%S").bak
    mv smtpd.key smtpd.key-$(date +"%y%m%d%H%M%S").bak
    ln -s /usr/local/ispconfig/interface/ssl/ispserver.crt smtpd.cert
    ln -s /usr/local/ispconfig/interface/ssl/ispserver.key smtpd.key
    service postfix restart
    service dovecot restart
    b. For dovecot: (* Note this shouldn't exist together with courier)
    Check if it is set to use the postfix SSL files (see below) via "nano /etc/dovecot/dovecot.conf".
    ssl_cert = </etc/postfix/smtpd.cert
    ssl_key = </etc/postfix/smtpd.key
    Leave it, if it is rightly set. Otherwise, fix it. In any event, running "service dovecot restart" is already covered earlier.
    c. For courier: (* Note this shouldn't exist together with dovecot)
    cd /etc/courier/
    mv imapd.pem imapd.pem-$(date +"%y%m%d%H%M%S").bak
    mv pop3d.pem pop3d.pem-$(date +"%y%m%d%H%M%S").bak
    ln -s /usr/local/ispconfig/interface/ssl/ispserver.pem imapd.pem
    ln -s /usr/local/ispconfig/interface/ssl/ispserver.pem pop3d.pem
    service courier-imap-ssl stop
    service courier-imap-ssl start
    service courier-pop-ssl stop
    service courier-pop-ssl start
    d. For pure-FTPd:
    cd /etc/ssl/private/
    if [ -f "pure-ftpd.pem" ]; then
        mv pure-ftpd.pem pure-ftpd.pem-$(date +"%y%m%d%H%M%S").bak
    ln -s /usr/local/ispconfig/interface/ssl/ispserver.pem pure-ftpd.pem
    chmod 600 pure-ftpd.pem
    service pure-ftpd-mysql restart
    e. For monit: (If it is installed in your server)
    nano /etc/monit/monitrc
    Add the above symlink to ispserver.pem we created for pure-ftpd in here as well:
      set httpd port 2812 and
        SSL ENABLE
        PEMFILE /etc/ssl/private/pure-ftpd.pem
        allow admin:'secretpassword'
    And restart monit:
    service monit restart

    [Creating Auto Renewal Script For Your ISPConfig Pem File (ispserver.pem)]
    8. In this last step, which I haven't found in any guide so far, is the automatic update of ispserver.pem as earlier hinted. Currently, it has to be manually changed right after Let's Encrypt automatically renewed your server SSL files. To avoid overlooking this, you may want to install incron as suggested in the respective incron tutorial and create a script to automatically update your ispserver.pem file, as follows:
    a. Via terminal command, install incron, then create the script file and edit it using nano:
    apt install -y incron
    nano /etc/init.d/
    b. Add this in the
    # Required-Start:  $local_fs $network
    # Required-Stop:  $local_fs
    # Default-Start:  2 3 4 5
    # Default-Stop:  0 1 6
    # Short-Description:  LE ISPSERVER.PEM AUTO UPDATER
    # Description:  Update ispserver.pem automatically after ISPC LE SSL certs are renewed.
    cd /usr/local/ispconfig/interface/ssl/
    mv ispserver.pem ispserver.pem-$(date +"%y%m%d%H%M%S").bak
    cat ispserver.{key,crt} > ispserver.pem
    chmod 600 ispserver.pem
    chmod 600 /etc/ssl/private/pure-ftpd.pem
    service pure-ftpd-mysql restart
    service monit restart
    service postfix restart
    service dovecot restart
    service nginx restart
    * Note some people do not install monit, so they can safely remove it. Do adjust the above script accordingly.
    * For multi server setup, do refer to post #203 where you need to create aliasdomain to this server and add scp code to this script to automate future update.
    c. We then make it executable, add root as allowed user for incrontab and then edit incrontab file:
    chmod +x /etc/init.d/
    echo "root" >> /etc/incron.allow
    echo "/etc/letsencrypt/archive/$(hostname -f)/ IN_MODIFY /bin/bash /etc/init.d/" >> /var/spool/incron/root

    [Restarting Your System]
    I think that is all about it for Securing Your Server With Let's Encrypt. You may want to restart your system afterwards
    service nginx restart
    Remember if you are using apache, change nginx to apache2 accordingly.

    As an alternative, you may want to use LE4ISPC script created for this purpose which supports both nginx and apache2 from ISPConfig up to pure-ftpd above except for monit. Before using it, you should already completed the above steps (1-5) and have :
    1. Created the website for your server via ISPConfig;
    2. The website accessible online;
    3. ISPConfig SSL enabled (via installation or update);
    4. LE SSL successfully enabled for the website.

    [Special note]
    Thank you @till, @florian030, @Thaddeus, @Turbanator, @Jesse Norell and others for their observations, feedbacks and suggestions that lead to the improvement of this guide.
    Last edited: May 21, 2018
    borekon, sagem, Taleman and 10 others like this.
  2. Turbanator

    Turbanator Member HowtoForge Supporter

    This is great, thank you. I think your cron line has a typo. should be
  3. ahrasis

    ahrasis Active Member

    Yes. You are right. Thank you for the fix. I already updated the guide with your fix. Thank you again.
  4. Jesse Norell

    Jesse Norell Well-Known Member

    Clever, I like it.

    Doesn't this end up with multiple inotifywait processes watching the privkey1.pem file, with a new one starting every day? (Maybe it prints a notice that it's running and exits, I've not tried it yet.) Might need to use a lock file or something?

    You also need to restart nginx, pure-ftpd and monit whenever the certificate changes, maybe make it run as part of the loop in
  5. ahrasis

    ahrasis Active Member

    Though I have also said the above, there is always room for improvement. Any suggestion for that?

    By the way, I am not so sure why we need to restart nginx, pure-ftpd and monit whenever the certificate changes. To me they are just using symlink to ISPC ispserver.pem and that symlink will remains after any changes. Care to explain why since the symlink name remains the same even after the renewal?
  6. till

    till Super Moderator Staff Member ISPConfig Developer

    The services won't recognize and pick up a changed SSL cert without restart. An real world example: we use LE as cert authority on the server, the server runs nginx and gitlab without a controlpanel, during initial installation we missed to add a restart of nginx after cert renewal which caused an expired SSL cert warning in the browser while the actual cert was up to date. Adding a nginx restart fixed that.
    ahrasis likes this.
  7. ahrasis

    ahrasis Active Member

    Thank you till and Jesse Norell for their observations, feedbacks and suggestions that lead to the improvement of this guide.

    I changed the script to be an init.d script, add new header to it as well as -m to inotifywait and and service nginx restart as thing to be done upon such changes. The reason for its change to an init.d script is due to the fact that inotifywait may stop on system reboot unless it is made a part of update-rc.d. With this change there will be no need of the tedious cron job.

    I am still not sure if we should restart pure-ftpd and monit services as well. Please do explain why it is needed, if you want it to be added as well.

    Thank you again.
  8. florian030

    florian030 ISPConfig Developer ISPConfig Developer

    Maybe we can add pre and post-hooks to the certbot-call. A post-hook could restart several services like mail and ftp. Just LE decided, if there is a need for restarting a services.
  9. ahrasis

    ahrasis Active Member

    Interesting idea florian. I'd prefer a hook to LE as well but that would require a proper knowledge and experience with its code of which I do not have. I will leave that to the expert hands to build one.
  10. florian030

    florian030 ISPConfig Developer ISPConfig Developer

    If you want to try post-hooks:
    Download and unzip the file to /usr/local/ispconfig/server/lib/classes/cron.d
    Create a post-hook-file /usr/local/ispconfig/server/scripts/ I.e.
    service postfix restart
    service dovecot restart
    and set the permissions:
    chown root.root /usr/local/ispconfig/server/scripts/
    chmod 700 /usr/local/ispconfig/server/scripts/
    The post-hook will be called every time a cert is renewed. Maybe it's possible to limit the restarts to several domains.
  11. ahrasis

    ahrasis Active Member

    Great code. So, basically, we need to modify the default or replace it with the one you provide. This is creating one question - will it be replaced by an ISPConfig update?

    And if the postfix and dovecot restart is necessary, (because for now I still do not think they are yet, similar to pure-ftpd and monit), it would rather be easier if they are included in the suggested script in the above guide.
    while inotifywait -m -q -e modify,attrib /etc/letsencrypt/archive/yourserverdomain/privkey1.pem >/dev/null; do
      rm /usr/local/ispconfig/interface/ssl/ispserver.pem
      cat /usr/local/ispconfig/interface/ssl/ispserver.{key,crt} > /usr/local/ispconfig/interface/ssl/ispserver.pem
      service nginx restart
  12. florian030

    florian030 ISPConfig Developer ISPConfig Developer

    An ispconfig-update will overwrite this. It's more like a quick hack but if this is working, i will add this to the main-code.
    With a post-hook you can trigger an action if you you get new cert. Your script checks only a specified cert. I think, it's easier to just define some hooks in a script. Especially, when you run a multiserer-setup with just one master and one interface. It should possible to copy new cerst over ssh with a hook-script to another server.
    You have to reload postfix and dovecot after you changed the cert. You may want to add the bundle to postfix and dovecot, too. I saw some problems with outlook when the bundle was not defined.
  13. ahrasis

    ahrasis Active Member

    Great. It would be nicer if by default, ISPConfig could create its own Let's Encrypt SSL, renew it and then restart all necessary services upon its Let's Encrypt SSL files renewal.

    Note that I did not include restart the system earlier because I was under the impression that ISPConfig should restart it after any Let's Encrypt SSL renewal. Then, after reading the replies, I realized that ispserver.pem may not be deleted and rebuilt at that time yet, so I added it in, just to make sure.

    However, I am still in doubt to add restart for other services though adding them will be more prudent. So in the above guide, I added restarting them as an option instead.

    By the way, what do you mean by bundle? If you mean the certificate and the chain, that are already included, because from what I understand, they are already bundled in the fullchain.pem. So in the above guide, I used:
    ln -s /etc/letsencrypt/live/yourserverdomain/fullchain.pem /usr/local/ispconfig/interface/ssl/ispserver.crt
    Last edited: Feb 16, 2017
  14. till

    till Super Moderator Staff Member ISPConfig Developer

    I doubt that any service will recognize a changed SSL cert without restart as these certs were normally read only once when the service starts and it is kept in memory then, so it is very likely that you have to restart each service that uses this SSL cert on renewal.
    ahrasis likes this.
  15. till

    till Super Moderator Staff Member ISPConfig Developer

    Bundle is another term for chain certificate.
    ahrasis likes this.
  16. ahrasis

    ahrasis Active Member

    Thank you for the feedback. I edited the guide to for all them to be included and restarted upon Let's Encrypt SSL renewal (not as option anymore).

    So, I get that bundle as already included and correct. Thank you till.
    Last edited: Feb 16, 2017
  17. Jesse Norell

    Jesse Norell Well-Known Member

    As @till has indicated, anything that holds the certificate in memory probably needs restarted; pure-ftpd does for sure, I have no experience with monit.

    On the design of implementation from ispconfig triggers, I would probably not use inotifywait myself. Normally letsencrypt will renew the certificate with there is still a fair bit of time (I think 1 month?) until the old certificate expires - you definitely don't need up to the second service reloads after the certificate changes. As a standalone monitoring script I think it is clever and would have very quick response to certificate changes. For an ispconfig hook like @florian030 is suggesting I would compare the pure-ftpd pid file timestamp with the certificate timestamp, and only restart pure-ftpd if the certificate is newer.
  18. ahrasis

    ahrasis Active Member

    For me, I will not use the suggested replacement of until it is implemented by ISPConfig, just in case I need to update ISPConfig as it might wipe out the replacement.

    And on the contrary, I do believe inotifywait will check and only acted upon a change of the specified file and this includes the attributes. So it is basically safer and more practical for the time being.
  19. Tuumke

    Tuumke Member

    I use ISPConfig for personal websites only at the moment.
    How would use my mail setup so that it sees the letsencrypt certs?
    Currently each domain has its own A 3600 mail.domain.tld pointing to the server ip.
    The MX record points to the A 3600 mail.domain.tld

    Do i have to setup the auto-subdomain to * or something so that the ssl cert is valid for domain.tld and *.domain.tld?
  20. Jesse Norell

    Jesse Norell Well-Known Member

    ISPConfig currently only requests letsencrypt certificates for websites, so use with email must be setup manually for now. The instructions in this thread only request a certificate for the server's full hostname (output of `hostname -f`); you can request a certificate which includes multiple names (server hostname,,, etc.) from the command prompt, which would work if you have a single server installation (not multi-server). You would need to request a new certificate from the command line every time you add or remove a name from it; as long as the first name in the certificate is `hostname -f`, then the instructions above to configure postfix and dovecot should work (ie. point to the certificate/key files in /etc/letsencrypt/live/`hostname -f`/).

    Note you can only have I believe 100 names included in a letsencrypt certificate, so doing this is only practical for small sites/config. Note also that if any of the domains you have move away from your server, so that no longer resolves to your server's ip address, then you must request another certificate without that name included; if you do not, the certificate cannot be renewed as it is, and will expire in < 90 days.

    Another option is to use a different letsencrypt client,, and this would work in a multi-server installation. It's a little more complicated to setup, but not too bad; @sjau has posted a howto and various other info on it on the forums here. It sounds like IPSConfig may switch to using in the future (or maybe support both clients).

    If interested, our current solution to this is to tell customer they can use as the server name for convenience, but they will get certificate errors; or they can use the actual server hostname without errors, but will probably have to change that every now and then (eg. every few years) whenever their domain moves to a new server. Some pick/prefer one, some the other, and I think most don't care.

Share This Page