Posted on

Windspeed Setup

The server needs to have run at minimum 24 hours before the mysql tuning can be performed. Other steps can be performed prior.

MySQL tuning

Direct SSH steps:wget perl

Make a note to the side about the recommended settings provided and adjust values from the tuner in /etc/my.cnf

service mysql restart

Upgrade MySQL to MariaDB 10.0 or newer.

Apache configuration

From WHM, go to Service Configuration > Apache Configuration > Global Configuration. Adjust the following values accordingly:

Start Servers - 15
Minimum Spare Servers - 15
Maximum Spare Servers - 30
Server Limit - 1024
Max Request Workers - 300
Max Connections per Child - 15000

PHP handler “fcgi” will also help.

.htaccess modification

Add the following to the end of the .htaccess files for domains on the server:

# Use Mod_deflate to compress static files
<ifmodule mod_deflate.c>
<filesmatch "\.(js|css|ico|txt|htm|html|php)$">
SetOutputFilter DEFLATE
# Speed up caching
FileETag MTime Size
# Expires
ExpiresActive On
ExpiresDefault "access plus 366 days"
# Future Expires Headers
<filesmatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Expires "Sat, 27 Dec 2014 23:59:59 GMT"
<IfModule mod_headers.c>
  <FilesMatch "\.(js|css|xml|gz)$">
    Header append Vary: Accept-Encoding
AddDefaultCharset UTF-8
DefaultLanguage en-US
SetEnv TZ America/Chicago
ServerSignature Off
<ifmodule mod_php4.c>
 php_value zlib.output_compression 16386
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 2 days"
## Compression ##
# compress text, html, javascript, css, xml:
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
<FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf)$">
Header set Cache-Control max-age=2592000?
<ifModule mod_gzip.c>
  mod_gzip_on Yes
  mod_gzip_dechunk Yes
  mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
  mod_gzip_item_include handler ^cgi-script$
  mod_gzip_item_include mime ^text/.*
  mod_gzip_item_include mime ^application/x-javascript.*
  mod_gzip_item_exclude mime ^image/.*
  mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
## Compression ##
Posted on

Updating Intel Gigabit Ethernet drivers

(Redirected from How to: Update IGB / Eth drivers)
Older ethernet drivers may cause packet loss, connection issues, especially on high usage systems, updating the driver will generally correct this. You should always update the eth drivers when you see or receive the following errors:

igb 000:01:00.1: eth1: Reset adapter
igb 000:01:00.1: eth0: Reset adapter
To view the current eth driver, run ethtool -i interface. For example:

# ethtool -i eth1
driver: igb
firmware-version: 1.52, 0x800007ae
bus-info: 0000:01:00.1
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no
To update the driver, the following should be installed first

/usr/bin/yum -y install gcc* kernel-* man && reboot

After reboot, you can run the below, which will update the eth driver.

/usr/bin/wget -O /root/igb.tar.gz
tar -xzvf /root/igb.tar.gz
cd /root/igb- && /usr/bin/make install
rmmod igb; modprobe igb
Rerun ethtool as in the example above to check that you are now running a new version.

Posted on

Wildcard Subdomains and DNS

How to Create a WildCard Subdomain

    1. Log into cPanel.
    2. Click the Subdomains link in the Domains section.
    3. In the Subdomain field, place an asterisk * symbol there signifying that you are creating a wildcard subdomain.
    4. Choose the domain you want to create a wildcard subdomain for in the Domain section.
    5. The Document Root field will automatically generate a path for your wildcard subdomain. You can change the path as needed.
    6. Click the Create button.

      You will then see a success message to confirm the subdomain was setup.

Congratulations! You have now successfully set up your account for wildcard domains. You still may need to modify your .htaccess file. If you have set up wildcard subdomains for WordPress Multisite, it will automatically configure the .htaccess file for you.

Posted on

How to avoid WordPress shared hosting high CPU problems

WordPress is the most popular CMS on the web and very easy to use with a great ecosystem of plugins. CPU related errors are quite common for those using WordPress on a shared host. Most webmasters complain that their web host account has been suspended due to excessive CPU usage. This can happen even if your site isn’t receiving unusually high traffic, which most people find very confusing.

CPU usage usually depends on the amount of request that your server receives. Besides, it may also depend on the number of people accessing your site/blog at the same time. Whatever the reason may be; your objective is to reduce CPU usage.

CPU Time on Single CPU Multi Tasking System (Photo credit: Wikipedia)


Following are the top 10 tips to keep your CPU usage minimal:

#1. Remove unwanted Plugins

When it comes to WordPress, plugins consume maximum resource. Moreover, with time, plugins can become unresponsive. Often, they may not tally with your present WordPress version also. Hence, it is recommended to install reliable plugins and remove the ones that are no more in use. Using too many plugins overloads the server. Avoid using poorly coded plugins and deactivate the unnecessary ones.

#2. Update to the Latest version plug-ins

Updating plugins is not a cakewalk. The update process may bring along a number of bugs, particularly if you have up have upgraded to the advanced WordPress version but have forgot to keep pace with new developments. However, ensure to check the plug-in discussion groups as well as forums to ensure that it’s fine to update. Updates often pop-up on your screen however, read the pop-up message carefully before clicking the update version.

#3. Routine Database Tables Optimization

To keep things running smoothly, you need to log onto PhpMyAdmin on a routine bases and optimize the database tables. Unoptimized data tables can overload the server. More over, the CPU usage is also more for reading unoptimized data tables. Besides data table optimization, you can also delete spam/unapproved data.

#4. Concentrate on the themes

Themes may also add to high CPU usage. Hence, the moment you realize that too many themes have piled up, try updating or changing them. The more stylish themes you choose, the more loaded the CPU is. Simpler or optimized themes work better and don’t consume much resource. Some themes may come with plugins; in that case you should update the plugins as well. Prefer using a light them that has fewer queries.

#5. WordPress Upgradating and Caching

Are you still laid behind with the older WordPress version? Well, if that is so then it is high time you upgrade to an advanced and latest version. Most of us ignore the idea of upgrading WordPress just because it works perfectly. An upgradation helps because the newer versions are better in terms of security and optimization.

You may also install WordPress caching program. Caching archives each web page on your site. This lowers server load as it doesn’t require sending multiple queries to the database for generating multiple pages.

#6. Reduce widgets

There may be certain widgets that aren’t essential. Check them thoroughly and remove the ones that may not be beneficial for the readers. The more widgets you use the more strain you are enforcing on the server. Hence, to lower server load and CPU usage, get rid of unwanted widgets.

#7. Lower PHP or Database calls

PHP scripts and database calls also consume a lot of CPU resource. Caching your sites helps but certain database/PHP calls cannot be avoided. Hence, you should go through the plugins documentation carefully and disable the unnecessary options.

#8. Lower load on index.php file

At peak hours, your homepage may create a load on your server during the peak hours. To lower this load, ensure keeping your homepage simple. Try to lower the number of posts on your homepage and remove unwanted files, links and high resolution images. It would be even better if you choose a CDN service like Cloudfront

#9 Disable WP-Cron

Disable WP-Cron or change to a scheduled task to run every hour. This will greatly reduce your CPU usage. WP-Cron manages all your scheduled events so it is continually active on many sites when it isn’t necessary.

#10 Avoid plugins that use excessive CPU load.

These are often backup and security pluggins. These functions are best being offered by a quality host provider that has integrated solutions.

There are a number of server monitoring tools available to assist with this. Whilst we can’t vouch for the product we thank Monitoringscout for the contribution to this article.

Posted on

Excessive Disk usage by MySQL Bin-logs

Please do not just delete them in the OS!!!

You need to let mysqld do that for you. Here is how mysqld manages it:

The file mysql-bin.[index] keeps a list of all binary logs mysqld has generated and auto-rotated. The mechanisms for cleaning out the binlogs in conjunction with mysql-bin.[index] are:

PURGE BINARY LOGS TO 'binlogname';

These will clear all binary logs before the binlog or timestamp you just specified.

For example, if you run

PURGE BINARY LOGS TO `mysql-bin.000223`;

this will erase all binary logs before mysql-bin.000223.

If you run


this will erase all binary logs before midnight 3 days ago.

If you want to have binlog rotated away automatically and keep 3 days woth, simply set this:

mysql> SET GLOBAL expire_logs_days = 3;

then add this to /etc/my.cnf


and mysqld will delete them logs for you


This is critical. When you run SHOW SLAVE STATUS\G, you will see two binary logs from the Master:

  • Master_Log_File
  • Relay_Master_Log_File

When replication has little or no lag these are usually the same value. When there is a lot of replication lag, these values are different. Just to make it simple, choose whatever Relay_Master_Log_File is, and go back to the Master and run

PURGE BINARY LOGS TO 'Whatever Relay_Master_Log_File Is';

That way, replication is not interrupted.

Give it a try!!!

Posted on

Setting, Changing And Resetting MySQL Root Passwords

This tutorial explains how you can set, change and reset (if you’ve forgotten the password) MySQL root passwords. Time and again I see problems like mysqladmin:  connect to server at ‘localhost’ failed error: ‘Access denied for user ‘root’@’localhost’ (using password: YES)’. So I thought it’s time to remind you how to solve MySQL related password problems. If you are just looking for a quick fix how to reset a MySQL root password you can find that at the bottom of this tutorial.


mysqladmin Command To Change Root Password

Method 1 – Set up root password for the first time

If you have never set a root password for MySQL, the server does not require a password at all for connecting as root. To set up a root password for the first time, use the mysqladmin command at the shell prompt as follows:

$ mysqladmin -u root password newpass

If you want to change (or update) a root password, then you need to use the following command:

$ mysqladmin -u root -p oldpassword newpass

Enter password:

If you get…

mysqladmin: connect to server at ‘localhost’ failed
error: ‘Access denied for user ‘root’@’localhost’ (using password: YES)’

then follow the instructions below on how to recover your MySQL password.


Change MySQL password for other users

To change a normal user password you need to type:

$ mysqladmin -u user-name -p oldpassword newpass


Method 2 – Update or change password

MySQL stores usernames and passwords in the user table inside the MySQL database. You can directly update a password using the following method to update or change passwords:

1) Login to the MySQL server, type the following command at the shell prompt:

$ mysql -u root -p

2) Use the mysql database (type commands at the mysql> prompt):

mysql> use mysql;

3) Change password for a user:

mysql> update user set password=PASSWORD(“newpass”) where User=’ENTER-USER-NAME-HERE’;

4) Reload privileges:

mysql> flush privileges;
mysql> quit

This method you need to use while using PHP or Perl scripting.


Recover MySQL root password

You can recover a MySQL database server password with the following five easy steps:

Step # 1: Stop the MySQL server process.

Step # 2: Start the MySQL (mysqld) server/daemon process with the –skip-grant-tables option so that it will not prompt for a password.

Step # 3: Connect to the MySQL server as the root user.

Step # 4: Set a new root password.

Step # 5: Exit and restart the MySQL server.

Here are the commands you need to type for each step (log in as the root user):

Step # 1 : Stop the MySQL service:

# /etc/init.d/mysql stop


Stopping MySQL database server: mysqld.

Step # 2: Start the MySQL server w/o password:

# mysqld_safe –skip-grant-tables &


[1] 5988
Starting mysqld daemon with databases from /var/lib/mysql
mysqld_safe[6025]: started

Step # 3: Connect to the MySQL server using the MySQL client:

# mysql -u root


Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 4.1.15-Debian_1-log

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.


Step # 4: Set a new MySQL root user password:

mysql> use mysql;
mysql> update user set password=PASSWORD(“NEW-ROOT-PASSWORD”) where User=’root’;
mysql> flush privileges;
mysql> quit

Step # 5: Stop the MySQL server:

# /etc/init.d/mysql stop


Stopping MySQL database server: mysqld
STOPPING server from pid file /var/run/mysqld/
mysqld_safe[6186]: ended

[1]+  Done                    mysqld_safe –skip-grant-tables

Start the MySQL server and test it:

# /etc/init.d/mysql start
# mysql -u root -p

Posted on

Despite revoked CA’s, StartCom and WoSign continue to sell certificates

As it stands, the HTTPs “encrypted web” is built on trust. We use browsers that trust that Certificate Authorities secure their infrastructure and deliver TLS certificates (1) after validating and verifying the request correctly.

It’s all about trust. Browsers trust those CA root certificates and in turn, they accept the certificates that the CA issues.

(1) Let’s all agree to never call it SSL certificates ever again.

Revoking trust

Once in a while, Certificate Authorities misbehave. They might have bugs in their validation procedures that have lead to TLS certificates being issued where the requester had no access to. It’s happened for, Gmail, … you can probably guess the likely targets.

When that happens, an investigation is performed — in the open — to ensure the CA has taken adequate measures to prevent it from happening again. But sometimes, those CA’s don’t cooperate. As is the case with StartCom (StartSSL) and WoSign, which in the next Chrome update will start to show as invalid certificates.

Google has determined that two CAs, WoSign and StartCom, have not maintained the high standards expected of CAs and will no longer be trusted by Google Chrome, in accordance with our Root Certificate Policy.

This view is similar to the recent announcements by the root certificate programs of both Apple and Mozilla.

Distrusting WoSign and StartCom Certificates

So Apple (Safari), Mozilla (Firefox) and Google (Chrome) are about to stop trusting the StartCom & WoSign TLS certificates.

From that point forward, those sites will look like this.

With Mozilla, Chrome & Safari, that’s 80% of the browser market share blocking those Certificate Authorities.

Staged removal of CA trust

Chrome is handling the update sensibly, it’ll start distrusting the most recent certificates first, and gradually block the entire CA.

Beginning with Chrome 56, certificates issued by WoSign and StartCom after October 21, 2016 00:00:00 UTC will not be trusted. [..]

In subsequent Chrome releases, these exceptions will be reduced and ultimately removed, culminating in the full distrust of these CAs.

Distrusting WoSign and StartCom Certificates

If you purchased a TLS certificate from either of those 2 CAs in the last 2 months, it won’t work in Chrome, Firefox or Safari.

Customer Transparency

Those 3 browsers have essentially just bankrupted those 2 CA’s. Surely, if your certificates are not going to be accepted by 80% of the browsers, you’re out of business — right?

Those companies don’t see it that way, apparently, as they still sell new certificates online.

This is pure fraud: they’re willingly selling certificates that are known to stop working in all major browsers.

Things like that piss me of, because only a handful of IT experts know that those Certificate Authorities are essentially worthless. But they’re still willing to accept money from unsuspecting individuals wishing to secure their sites.

I guess they proved once again why they should be distrusted in the first place.

Guilt by Association

Part of the irony is that StartCom, which runs StartSSL, didn’t actually do anything wrong. But a few years ago, they were bought by WoSign. In that process, StartCom replaced its own process and staff with those of WoSign, essentially copying the bad practices that WoSign had.

If StartCom hadn’t been bought by WoSign, they’d still be in business.

I’m looking forward to the days when we have an easy-to-use, secure, decentralized alternative to Certificate Authorities.

Posted on

How to Change Your Password on a Remote Desktop Server

Changing your password on your local PC is easy. Pressing the <CTRL> + <ALT> + <DEL> key combination brings up a task menu which allows you to change your password (as well as other common administrative tasks). When you’re connected to a Remote Desktop server and press the <CTRL> + <ALT> + <DEL> key combination, you will still see this task menu for your local PC, not the remote server.So how can you change your password when connected to a Remote Desktop server? Well the smart folks at Microsoft thought about that very question and have come up with a couple of solutions.


Method #1

While logged into a Remote Desktop session, press the <CTRL> + <ALT> + <END> key combination. This will launch the same task menu, but on the remote server instead of on your local PC. Now you can click on the Change a Password menu option to change your password on the remote server


Method #2

From the Start Menu type the word: password. This will query the Start Menu for anything related to passwords. From the query results select the item called Change your Windows password. You will now have an option to change your password to the remote desktop server.

Posted on

Transferring Emails from your old host to your new host

In this article we’ll go over how to move emails from a previous host to your new host. If your previous hosting provider uses cPanel, this article will not apply as your emails will be moved over with your full cPanel backup.

How to move your emails from one server to another

The steps involved will depend on whether or not you use POP3 or IMAP to check emails at your previous host. If you’re not sure which connection you use, you can check your email settings in your email client to determine which type of connection you use.


If you use a POP3 connection when checking emails on your previous host, your emails are downloaded to your local computer. You will not have to follow any steps to move emails as they are already on your computer. You will want to take a look at the section below on how not to lose emails when you point your domain to our Nameservers.


There are more steps involved when you use IMAP because emails are stored on the server and aren’t actually downloaded to your local computer; so the emails will actually need to be moved over from that server to your new server. If you have a lot of email addresses, this will be a tedious process you will need to go through for each email account.

How not to lose emails during propagation time after a Nameserver change

When you have completed your website migration, the last step is to update your domain’s Nameservers. After propagation, emails will be routed to the new server, but during the 4-24 hours it can take for DNS propagation some emails will go to the new servers and some email will go to your old server. Fortunately, we have two recommendations to keep you from missing emails during that time:

  1. Before you point your domain to our Nameservers, create a forwarder at your previous host that forwards emails to an email that’s not on the same domain you are moving to your new Hosting (e.g. gmail, yahoo, hotmail or another domain at which you receive emails).
  2. Check email at your old host using their webmail interface. You will want to make sure you use a temp url or similar url that specifies the server name in the url instead of or

Modifying your MX Records

Some people use third party companies for their email and thus will not be pointing to our nameservers for email services. If this is your case, you will want to make sure that your

Posted on

How Shitty Start-Com SSL, Go With Let-encrypt, Less Shady COMPLETELY FREE AND AUTOMATED!!

Hey guys, I may not have a large audience, but I need to correct previous recommendations for this shitty ass company known as Start-Com.

First, they are sanction for what some would consider to be shady activity, I am glad they are working to rectify the issue, however I have not seen a backup scheme they should have implement to prevent an issue as this. My Certificate that I generated when I had paid them for Verification (Which is a Whole shitty process unto itself if you move around because of Education or work), doesn’t work, here is a link to their faux pa:

Google to Distrust WoSign, StartCom Certs in 2017

I was an avid  fan, yea the Verification was a bit tedious, however it wasn’t as flexible as I would assume it should be, with many different forms of verfify myself, who I am, where I am currently established, with documents such as my SSN, Drivers Licenses old and new, electric bills, Email verification, They stated that in the interim due to the issue that they would provide SSLs free of charge.

So now I am out of  site protection, try to fix the issue for a few smaller things, and yet they still insist on further verification of making a payment of 0.50 USD to verify who I am via PayPal.

Besides the fact I don’t have .50 in my Paypal accout, and I am overdrafted till later is none of your financial concern. Asking to provide money up front isn’t free, to have it refunded later is to defeat the purpose of something being free.

So, here is a guide to Install LetsEncrypt on CentOS 7 :

Step 1 — Install the Certbot Let’s Encrypt Client

The first step to using Let’s Encrypt to obtain an SSL certificate is to install the certbot software on your server. Currently, the best way to install this is through the EPEL repository.

Enable access to the EPEL repository on your server by typing:

  • sudo yum install epel-release

Once the repository has been enabled, you can obtain the certbot package by typing:

  • sudo yum install certbot

The certbot Let’s Encrypt client should now be installed and ready to use.

Step 2 — Obtain a Certificate

Let’s Encrypt provides a variety of ways to obtain SSL certificates, through various plugins. Unlike the Apache plugin, which is covered in a different tutorial, most of the plugins will only help you with obtaining a certificate which you must manually configure your web server to use. Plugins that only obtain certificates, and don’t install them, are referred to as “authenticators” because they are used to authenticate whether a server should be issued a certificate.

We’ll show you how to use the Webroot plugin to obtain an SSL certificate.

How To Use the Webroot Plugin

The Webroot plugin works by placing a special file in the /.well-known directory within your document root, which can be opened (through your web server) by the Let’s Encrypt service for validation. Depending on your configuration, you may need to explicitly allow access to the /.well-known directory.

If you haven’t installed Nginx yet, you can do so now. The EPEL repository should already be enabled from the previous section, so you can install Nginx by typing:

  • sudo yum install nginx

To ensure that the directory is accessible to Let’s Encrypt for validation, let’s make a quick change to our default Nginx server block. The default Nginx configuration file allows us to easily add directives to the port 80 server block by adding files in the /etc/nginx/default.d directory.

If you’re using the default configuration, create a new file called le-well-known.conf and open it for editing with this command:

  • sudo vi /etc/nginx/default.d/le-well-known.conf

Then paste in these lines:

location ~ /.well-known {
        allow all;

Save and exit.

Check the configuration for syntax errors by typing:

  • sudo nginx -t

If no errors were reported, start or restart Nginx with this command:

  • sudo systemctl restart nginx

If you aren’t using the default server block, you will need to look up what your document root is set to by looking for the root directive in your default Nginx server block. This is the value that Let’s Encrypt requires, as webroot-path, when using the Webroot plugin. The default root is /usr/share/nginx/html.

Next, make sure port 80 and 443 are open in your firewall. If you are not running a firewall, you can skip ahead.

If you have a firewalld firewall running, you can open these ports by typing:

  • sudo firewall-cmd –add-service=http
  • sudo firewall-cmd –add-service=https
  • sudo firewall-cmd –runtime-to-permanent

If have an iptables firewall running, the commands you need to run are highly dependent on your current rule set. For a basic rule set, you can add HTTP and HTTPS access by typing:

  • sudo iptables -I INPUT -p tcp -m tcp –dport 80 -j ACCEPT
  • sudo iptables -I INPUT -p tcp -m tcp –dport 443 -j ACCEPT

Now that we know our webroot-path, we can use the Webroot plugin to request an SSL certificate with these commands. Here, we are also specifying our domain names with the -d option. If you want a single cert to work with multiple domain names (e.g. and, be sure to include all of them. Also, make sure that you replace the highlighted parts with the appropriate webroot path and domain name(s):

  • sudo certbot certonly -a webroot –webroot-path=/usr/share/nginx/html -d -d

After certbot initializes, you will be prompted for some information. The exact prompts may vary depending on if you’ve used certbot before, but we’ll step you through the first time.

At the prompt, enter an email address that will be used for notices and lost key recovery:

Email prompt

Then you must agree to the Let’s Encrypt Subscribe Agreement. Select Agree:

Let's Encrypt Subscriber's Agreement

If everything was successful, you should see an output message that looks something like this:

 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/ Your
   cert will expire on 2016-03-15. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - If you lose your account credentials, you can recover through
   e-mails sent to
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - If like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:
   Donating to EFF:          

You will want to note the path and expiration date of your certificate, which was highlighted in the example output.

Note: If you receive an error like Failed to connect to host for DVSNI challenge, recheck your server’s firewall to make sure it is configured to allow TCP traffic on port 80 and 443.

Note: If your domain is routing through a DNS service like CloudFlare, you will need to temporarily disable it until you have obtained the certificate.

Certificate Files

After obtaining the cert, you will have the following PEM-encoded files:

  • cert.pem: Your domain’s certificate
  • chain.pem: The Let’s Encrypt chain certificate
  • fullchain.pem: cert.pem and chain.pem combined
  • privkey.pem: Your certificate’s private key

It’s important that you are aware of the location of the certificate files that were just created, so you can use them in your web server configuration. The files themselves are placed in a subdirectory in /etc/letsencrypt/archive. However, the certbot Let’s Encrypt client creates symbolic links to the most recent certificate files in the /etc/letsencrypt/live/your_domain_name directory. Because the links will always point to the most recent certificate files, this is the path that you should use to refer to your certificate files.

You can check that the files exist by running this command (substituting in your domain name):

  • sudo ls -l /etc/letsencrypt/live/your_domain_name

The output should be the four previously mentioned certificate files. In a moment, you will configure your web server to use fullchain.pem as the certificate file, and privkey.pem as the certificate key file.

Generate Strong Diffie-Hellman Group

To further increase security, you should also generate a strong Diffie-Hellman group. To generate a 2048-bit group, use this command:

  • sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

This may take a few minutes but when it’s done you will have a strong DH group at /etc/ssl/certs/dhparam.pem.

Step 3 — Configure TLS/SSL on Web Server (Nginx)

Now you must edit the Nginx configuration to use the Let’s Encrypt certificate files. The default Nginx configuration on CentOS is pretty open-ended but we will create a new server block that uses SSL/TLS and listens on port 443. Then we’ll configure the default (HTTP on port 80) server block to redirect to the HTTPS-enabled server block.

By default, additional server block configuration can be placed in /etc/nginx/conf.d. Create a new file called ssl.conf and open it for editing with this command:

  • sudo vi /etc/nginx/conf.d/ssl.conf

Then paste this configuration in. Be sure to change every instance of, all four, with your own domain name:

server {
        listen 443 http2 ssl;


        ssl_certificate /etc/letsencrypt/live/;
        ssl_certificate_key /etc/letsencrypt/live/;

        # from                                            #
        # and #

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
        ssl_ecdh_curve secp384r1;
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off;
        ssl_stapling on;
        ssl_stapling_verify on;
        resolver valid=300s;
        resolver_timeout 5s;
        # Disable preloading HSTS for now.  You can use the commented out header line that includes
        # the "preload" directive if you understand the implications.
        #add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;

        # END BLOCK #

        ssl_dhparam /etc/ssl/certs/dhparam.pem;

        location ~ /.well-known {
                allow all;

        # The rest of your server block
        root /usr/share/nginx/html;
        index index.html index.htm;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;

To set up Nginx SSL securely, in the configuration above we used the recommendations by Remy van Elston the site. This site is designed to provide easy-to-consume encryption settings for popular software. You can read more about his decisions regarding the Nginx choices here.

Note: The default suggested settings on offer strong security. Sometimes, this comes at the cost of greater client compatibility. If you need to support older clients, there is an alternative list that can be accessed by clicking the link on the link labeled “Yes, give me a ciphersuite that works with legacy / old software.”

The compatibility list can be used instead of the default suggestions in the configuration above between the two comment blocks. The choice of which config you use will depend largely on what you need to support.

There are a few pieces of the configuration that you may wish to modify. First, we added our preferred DNS resolver for upstream requests. We used Google’s for this guide, but you can change this if you have other preferences.

Finally, you should take take a moment to read up on HTTP Strict Transport Security, or HSTS, and specifically about the “preload” functionality. Preloading HSTS provides increased security, but can have far reaching consequences if accidentally enabled or enabled incorrectly. In this guide, we did not preload the settings, but you can modify that if you are sure you understand the implications.

Modify the rest of the server block to suit your needs.

Save and exit. This configures Nginx to use SSL, and tells it to use the Let’s Encrypt SSL certificate that we obtained earlier. Also, the SSL options specified here ensure that only the most secure protocols and ciphers will be used. Note that this example configuration simply serves the default Nginx page, so you may want to modify it to meet your needs.

Next, we’ll configure Nginx to redirect HTTP requests on port 80 to HTTPS on port 443.

The default Nginx configuration file allows us to easily add directives to the port 80 server block by adding files in the /etc/nginx/default.d directory. Create a new file called ssl-redirect.conf and open it for editing with this command:

  • sudo vi /etc/nginx/default.d/ssl-redirect.conf

Then paste in this line:

    return 301 https://$host$request_uri;

Save and exit. This configures the HTTP on port 80 (default) server block to redirect incoming requests to HTTPS.

Now, check the configuration for syntax errors:

  • sudo nginx -t

If no errors are found, restart Nginx:

  • sudo systemctl restart nginx

You will also want to enable Nginx, so it starts when your server boots:

  • sudo systemctl enable nginx

The Let’s Encrypt TLS/SSL certificate is now in place. At this point, you should test that the TLS/SSL certificate works by visiting your domain via HTTPS in a web browser.

You can use the Qualys SSL Labs Report to see how your server configuration scores:

In a web browser:

This SSL setup should report an A rating.

Step 4 — Set Up Auto Renewal

Let’s Encrypt certificates are valid for 90 days, but it’s recommended that you renew the certificates every 60 days to allow a margin of error. At the time of this writing, automatic renewal is still not available as a feature of the client itself, but you can manually renew your certificates by running the certbot Let’s Encrypt client with the renew option.

To trigger the renewal process for all installed domains, run this command:

  • sudo certbot renew

Because we recently installed the certificate, the command will only check for the expiration date and print a message informing that the certificate is not due to renewal yet. The output should look similar to this:

Saving debug log to /var/log/letsencrypt/

Processing /etc/letsencrypt/renewal/
Cert not yet due for renewal

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/ (skipped)
No renewals were attempted.

Notice that if you created a bundled certificate with multiple domains, only the base domain name will be shown in the output, but the renewal should be valid for all domains included in this certificate.

A practical way to ensure your certificates won’t get outdated is to create a cron job that will periodically execute the automatic renewal command for you. Since the renewal first checks for the expiration date and only executes the renewal if the certificate is less than 30 days away from expiration, it is safe to create a cron job that runs every week or even every day, for instance.

Let’s edit the crontab to create a new job that will run the renewal command every week. To edit the crontab for the root user, run:

  • sudo crontab -e

Add the following lines:

crontab entry
30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log
35 2 * * 1 /usr/bin/systemctl reload nginx

Save and exit. This will create a new cron job that will execute the certbot renew command every Monday at 2:30 am, and reload Nginx at 2:35am (so the renewed certificate will be used). The output produced by the command will be piped to a log file located at /var/log/le-renewal.log.

For more information on how to create and schedule cron jobs, you can check our How to Use Cron to Automate Tasks in a VPS guide.


That’s it! Your web server is now using a free Let’s Encrypt TLS/SSL certificate to securely serve HTTPS content.