Secure HTTPS Setup With nginx and Let’s Encrypt (Part 3) – Auto Renew Script

In this tutorial (which is an extension of part 2 and part 1 of a tutorial series for setting up letsencrypt on nginx) we’ll show you how to setup a BASH script that will automate the renewal of your certificates. This should enable you to sit back and have your Lets Encrypt SSL certificates automatically renew with a cron job that runs in the background on an interval.

  1. Add the following to /root/letsencrypt/cli.ini

     

  2. In the file above, change /home/yoursite.com/ to the document root of the site in question, and change the postmaster@yoursite.com to whatever email address you’d like to use for emailing when things fail.

     

  3. Add the following to /root/letsencrypt/letsrenew.sh

     

  4. In the file above, change yoursite.com and www.yoursite.com to your domain that you want to renew the SSL certificate(s) for, and change postmaster@yoursite.com to whatever email address you’d like to use for emailing when things fail.

     

  5. Add the following to crontab -e

     

  6. (optional) Add the following to your bash profile with:  vim ~/.bash_profile

    This just allows you to type letsrenew in your terminal to renew your certificates whenever you want. The cron job we added in step 5 should automate this part for you, so this is just an added convenience.

     

As always, if you have any issues or questions about this process, feel free to drop a comment below and I’ll try to help you troubleshoot whatever issues you’re having. Please remember to include as much detail as possible when you comment as it will help to better understand your issues.

How to Add a Custom WordPress TinyMCE Button to add Modal and Shortcode

Custom WordPress TinyMCE Button Modal Shortcode

This is a simple tutorial that will show you How to Add a Custom WordPress TinyMCE Button Modal Shortcode with a dashicon button into the WordPress Editor step by step with code snippets. In this example I’m going to be creating a “Buy Now” type of button in TinyMCE that initiates a modal window that will ask the user for fields and insert a shortcode at the current position in the editor with the shortcode attributes populated by the values from the inputs in the modal.

Place this code in functions.php

Note: As you can see in the example above, I’m adding a custom javascript file on line 18. The path to this file needs to be changed to reflect the path of a file you’re about to create.

Now we can create a buybutton.js file (or whatever you want to name it) and change the path and filename on line 18 in the code snippet above to reflect this new file path and filename. Once you’ve created that file, paste the following into that file…

Place this code in your custom buybutton.js script

If you want to modify the names of things, just make sure that you use find/replace where you can because many of these names in the filters, actions, and other areas will need to match in order for this to work. Also, if you want to change the icon of the button to another dashicon, feel free to look one up from a site like http://calebserna.com/dashicons-cheatsheet/ and replace the “content” CSS property with one of the unicodes from that page.

Update: (courtesy of Himanshu from the comments below)
If you would like to add other input types, here is a comprehensive list of all the different input types that TinyMCE will allow you to create in the windowManager.open() function:

The object above would go inside lines 13-25 of your buybutton.js script (replacing the object inside the body property’s array) and will give you a nice example of the various input types all in one modal:
TinyMCE Custom Modal - Input Types

Again, this is just a basic tutorial on How to Add a Custom WordPress TinyMCE Button Modal Shortcode into the WordPress Editor. If you are wanting to accomplish something else with TinyMCE, or have any issues, questions, or comments, please feel free to leave a comment in the comments section below.

How to Add a Posts Screen Users Filter in the WordPress Admin (edit.php)

Add Users Filter on Admin Posts Screen in WordPress Admin

This tutorial will teach you how to add a posts screen users filter in the WordPress Admin. This will allow you to add a dropdown list of users/authors/etc. (grouped by role) to the filter section at the top of the posts screen in the admin where all your posts are listed as seen in the image above.

How to Add a Posts Screen Users Filter in the WordPress Admin

Add this to functions.php:

That’s about it! Now if you wanted to get fancy you could also add an autocomplete as well. Perhaps if you comment in the comments below asking nicely for a revision to this post to show how to properly add something like Select2 or another autocomplete library I would be more inclined to do it 😉

As always, please let me know in the comments below if this worked for you, didn’t work for you, or anything else you want to let me know about this post!

How to Hide Political Posts from Facebook

How to Hide Political Posts from Facebook

Have you ever wanted to hide all the political posts from your Facebook feed without having to unfriend anyone or put your friends into groups? This post will show you how to hide political posts from Facebook while also giving you the option to temporarily toggle them on one post at a time.

I wrote this script after a receiving a few personal attacks on Facebook so I could quickly have a way to hide all the nonsense while maintaining my friendship with people from my past that have different political views. It currently is tailored to use a set of keywords that are geared towards blocking posts from the 2016 political season, but you can feel free to change these to your liking. Let’s dive into it!

This tutorial is for Chrome but this can also work in Firefox and any other browser that has the Tampermonkey browser extension…

How to Hide Political Posts from Facebook

  1. Download and install the Tampermonkey browser extension for your browser. A Google search for “tampermonkey chrome” or “tampermonkey firefox” etc. should do the trick.
  2. Once that’s installed, open up the Tampermonkey dashboard by clicking on the little Tampermonkey icon:
    Open Tampermonkey Dashboard
  3. Once you’re in the dashboard, click on the tab with the plus icon so you can create a new Tampermonkey script:
    Create New Tampermonkey Script
  4. Highlight all the code in the box below and delete it. Then replace it with the following code:

     
  5. Once you’re all done, click the little save/disk icon on the top left of the Tampermonkey window. Once you see a message at the top that says “Operation completed successfully” you can close the Tampermonkey tab.
  6. Now open up a Facebook tab (if you already have a Facebook tab open, go back to that tab and refresh it). You should now see political posts being hidden as you scroll through your news feed or any feed section on Facebook. It will tell you which buzz word it contained and who posted the post, and will allow you to click the hidden post to toggle it on in case you’re feeling temporarily political or you think it might have been hidden incorrectly.
    How to Hide Political Posts from Facebook
Note: If someone’s name contains these political buzz words and they commented on the post, it will hide the post.

Again, this is a simple tutorial on how to hide political posts from Facebook. This solution will not work perfectly for everyone because some people will not want to hide posts that contain the same words as I would like hidden, but it’s a good start for learning how to script for Facebook to improve your user experience. If you’re looking to tailor this to your specific needs, feel free to comment below with what you’re trying to accomplish. I’m always willing to help 🙂

Secure HTTPS Setup With nginx and Let’s Encrypt (Part 2)

In part 1 of this post, I covered getting nginx configured to securely handle HTTPS content.  Now, we’ll get Let’s Encrypt installed, get a certificate issued, and make nginx listen on the HTTPS port.

Let’s Encrypt!

Currently, the best way to get the most up-to-date version of the Let’s Encrypt client is via git, so if your server does not currently have the git client installed you’ll have to do that first (‘sudo yum install git’ on Fedora/CentOS-based systems, ‘sudo apt-get install git’ on Debian/Ubuntu/other apt-based systems).  Next, we’ll grab a copy of the repo with the following (feel free to replace ‘/opt/letsencrypt’ with another location if you’d prefer it be installed elsewhere):

sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

Assuming no errors, you now have the latest Let’s Encrypt client in /opt/letsencrypt — you can update it in the future by doing “sudo git pull” in /opt/letsencrypt or wherever else you cloned to.  The client includes several plugins to authenticate the fact that you actually control the domain you want a certificate for, but in this post we’re going to use the “webroot” plugin.  How this plugin works is that the client writes some files to a specific directory (‘.well-known’) in the document root of the website, then attempts to read them back over the internet.  Inherent in this is that you must first have DNS for the domain (or domains) pointed to your nginx server, and at least a basic HTTP vhost set up for it (check out http://robido.com/nginx/configure-an-nginx-virtual-host-with-phpmyadmin-and-php-fpm/ for some info on that if you have a fresh nginx install with no vhosts defined.)  If you have some form of access restriction (password, IP, etc.) on your website, you’ll have to allow access to the URLs Let’s Encrypt expects; you can do so by adding the following inside the ‘server’ block of your vhost configuration file (and then doing a ‘sudo nginx -t’ to test the configuration followed by ‘sudo nginx -s reload’ to pick up the changes):

On to making a certificate!  Enter the following:

cd /opt/letsencrypt (or wherever you cloned the git repo)
sudo ./letsencrypt-auto certonly -a webroot –webroot-path=/path/to/your/site/docroot -d sitedomain.com -d www.sitedomain.com -d alternatedomain.com …

The call to letsencrypt-auto supports multiple -d options for the same document root, creating a SAN certificate (that is, a certificate that is valid for all the domains listed).  You only need to provide one, but all of them will be checked so make sure DNS is pointed correctly or you’ll get an error.  You can also create multiple certificates at the same time like:

sudo ./letsencrypt-auto certonly -a webroot –webroot-path=/path/to/site/one -d site1.com –webroot-path=/path/to/site/two -d site2.com

The script will make sure the necessary packages are installed on your system, install them if any are missing, then execute.  On the very first time, you’ll be asked for some information:

Enter an email address that Let’s Encrypt can send lost key recovery and certification expiration notice emails to:
Let's Encrypt email

And then agree to their subscriber agreement (after reading it, of course! …) :
Let's Encrypt agreement

Once you’ve gotten through those screens, the script will verify the domains you entered actually point to the server and document root you entered, and if all is well you’ll receive a message with some “IMPORTANT NOTES”.  They actually are important, you may want to read them 😀

Put That Cert To Work

Assuming the steps above went well, you now have some files in /etc/letsencrypt/live/sitedomain.com/.  In case you’re wondering what those files are:

  • cert.pem:  The actual certificate for the domain.
  • chain.pem: The intermediate chain certificate for Let’s Encrypt (what gives them the authority to sign your cert).
  • fullchain.pem: cert.pem with chain.pem appended to the end of it.
  • privkey.pem: The private key for your cert.pem.

Sharp-eyed admins may notice that these files are actually just symlinks; this allows us to point nginx at them, and when we renew the certificate, Let’s Encrypt updates the symlinks for us.  On that note, let’s actually get nginx speaking HTTPS for your vhost; open up the nginx config file for your vhost in your favorite text editor (/etc/nginx/conf.d/domain.com.conf or whatever convention you chose to use).  Eventually, unless you have an exceptional reason not to, you’re going to want to force all HTTP traffic to HTTPS, but for now we’ll just duplicate your HTTP configuration as an HTTPS one with some added parameters.

A simple nginx vhost config might look like (WordPress or other PHP-based sites will have additional configuration parameters for PHP handling and so forth):

Simply duplicate that server block, change “listen 80” to “listen 443 ssl”, and add in the ssl_certificate and ssl_certificate_key parameters like (you may also wish to log SSL traffic to different log files):

Test your configuration afterwards with “sudo nginx -t”, and reload if all is well with “sudo nginx -s reload” to pick up the changes.  Accessing your site on HTTPS now may be a mess because of mixed content — resources linked via HTTP from an HTTPS page.  In the last part of this series of posts, we’ll force all HTTP links that the server has control over to go over HTTPS instead for security reasons, but it’s generally a good idea to fix these issues on your site instead of relying on the server to fix it for you (especially if you are loading some resources from other locations where we can’t re-write those!).  If you have any sort of default SSL vhost (often at /etc/nginx/conf.d/ssl.conf for example) with more SSL parameters than just the ‘ssl_certificate’ and ‘ssl_certificate_key’ defined, you’ll probably want to remove them to ensure they don’t overwrite our secure configuration.

One final wrinkle — you may find when attempting to connect to your site on HTTPS that the firewall is blocking you.  Opening port 443 on your firewall varies from Linux distro to distro, but for firewalld-based systems you’ll want to do:

sudo firewall-cmd –permanent –zone=public –add-service=https; sudo firewall-cmd –reload

The next step will be to clean up and finish tightening up your configuration, including forcing all connections to your site to be HTTPS once you’ve fixed up your site, enabling HSTS (HTTP Strict Transport Security) once you’re really sure the site works with HTTPS, and setting up a cron job to automatically renew your Let’s Encrypt certificates so they never expire.

If you’d like to setup an Auto Renew Script to automatically renew your certificates on a cron job, then continue to part 3 of this tutorial.

Secure HTTPS Setup With nginx and Let’s Encrypt (Part 1)

This is a tutorial for creating a secure HTTPS setup with nginx and Let’s Encrypt. So, with the introduction of Let’s Encrypt it has become possible to add a trusted SSL certificate for all of your sites for free, which is a fantastic development.  Not only can the encryption a certificate provides keep your e-commerce clients’ transaction data safe, with privacy becoming more and more of a concern these days, encrypting even mundane traffic helps ensure the privacy of visitors to your sites.

But like many things in life, you can set up HTTPS and you can set up HTTPS well.  Many encryption ciphers have been found to be vulnerable, and it is important to make sure that these ciphers cannot be requested by a potentially hostile client; with Let’s Encrypt, certificates are only valid for 90 days, so setting up automatic renewal is also handy to ensure those certs never lapse.  Fortunately, nginx (version 1.8.1 is used in these examples) has some simple configuration options to tighten up security!  I’ll discuss the nginx side of setup in this post, and go into getting Let’s Encrypt set up and your first cert in place in part 2.

nginx Setup

This assumes you already have nginx up and running on your server in some capacity; check out http://robido.com/nginx/how-to-install-web-server-centos-7-using-nginx-php-fpm-mariadb-firewalld/ if you’re not quite there yet.  First, we’ll need to create a Diffie-Hellman parameters file; this is used for Perfect Forward Secrecy, a pretty cool protocol that means that even if someone is listening to the entire initial SSL setup, they still can’t recover the key for decryption.  On a server with only 1 or 2 CPU cores, this might stress your system out (and it’ll take a while in any event), so if you’re on a low-end VPS, you may want to wait until later in the evening to run this!

Do the following as root:
cd /etc/ssl/certs (on Ubuntu, Debian, etc. this may differ; on RedHat/Fedora/CentOS-based systems this is where the base CA bundle is linked to.)
openssl dhparam -out dhparam.pem 4096

You should now have a new file at /etc/ssl/certs/dhparam.pem!  We’ll tell nginx to use it now, and tighten up some other SSL/TLS related settings.  Go ahead and create a new file as root in /etc/nginx with your favorite text editor — I like “secure-ssl.conf” but as long as it ends in “.conf” you’re good — and paste in the following:

I’ll break down each of these options in a little more detail, in case you’re the sort of person who doesn’t like blindly pasting configurations with no idea what’s going on 🙂

ssl_protocols
SSLv2 is insecure, and SSLv3 causes a vulnerability via TLS1.0 (TLS1.0 is vulnerable to a downgrade attack that can force the server to change to SSLv3), so we explicitly enable only TLSv1, TLSv1.1, and TLSv1.2.

ssl_prefer_server_ciphers
Under certain SSL/TLS protocol versions, the client’s preference of encryption cipher is used instead of the server’s.  This is a vulnerability if your client intentionally specifies a weak cipher, so this forces nginx to only use the ciphers we specify below.

ssl_dhparam
 This tells nginx to use the Diffie-Hellman parameters file we generated earlier for PFS.

ssl_ciphers
You’ll note a couple options here for this parameter — the commented-out, much smaller list can be used if you do not care about supporting older clients (in particular, Windows XP and IE6), as most of the long string you see in the other ssl_ciphers option deals with ordering ciphers in order of security (and explicitly discarding ciphers known to be totally broken at this point).  In essence, this list attempts to prioritize:

  • ECDHE+AESGCM ciphers are used whenever possible.  These are TLSv1.2 ciphers with no currently known weaknesses.
  • Perfect Forward Secrecy ciphers are preferred, with ECDHE over DHE.
  • AES128 is used over AES256.  This may seem backwards, but currently, AES128 has no serious known vulnerabilities, and is noticeably quicker than AES256.  This may change as CPU power continues to increase.
  • AES is preferred over 3DES, due to the weaknesses in 3DES in many situations.  In the shorter cipher list, 3DES is totally excluded.
  • RC4 is removed entirely due to the large number of vulnerabilities; RC4 should be considered entirely broken at this point.

ssl_session_timeout, ssl_session_cache
  These parameters enable nginx’s session cache.  Because of the fact that a majority of the overhead associated with an HTTPS connection is in the initial setup, caching these connection parameters can vastly improve response times for successive hits from the same client.  Here we create a 50MB cache (documentation claims 1MB can store an estimated 4K sessions, so this may be overkill) and time out SSL sessions after 30 minutes.

ssl_stapling, ssl_stapling_verify
These options implement OCSP stapling, a way to speed up the initial SSL handshake by letting the server announce to connecting clients that it is capable of sending a cached version of an OCSP record, normally something that the client has to connect separately to the CA to retrieve (and something that often times out or fails entirely!)

 

Once these are all in place, go ahead and test your nginx configuration with “sudo nginx -t”, and if all looks good, issue a “sudo nginx -s reload” to pick up the new configuration.  nginx is now configured to securely handle HTTPS traffic, but we still need to get it a certificate and key to use, and set up a secure vhost (your nginx package may have come with a default SSL vhost set up, but we’ll blow that out to make sure it doesn’t override our settings here).

Continue on to Part 2 of the tutorial to configure a secure HTTPS setup with nginx and Let’s Encrypt

Clear images from Facebook open graph image cache with a bookmarklet

Do you ever run into the problem where you pasted a link into Facebook, realized the featured images on that link were incorrect, and when you go to update the featured images on that link and paste it into Facebook again, the old images are still cached? Well this post will show you how to clear images from Facebook open graph image cache with a bookmarklet (literally in the click of a button).

Right Click on This Link and click “Copy” or copy the snippet below:

Now you just need to add the bookmarklet from above to your browser:

Chrome

  1. Go to Bookmarks > Bookmark Manager
  2. Click on the “Bookmarks Bar” folder on the left
  3. Right click in the white area on the right and click “Add Page”
  4. Type something like “Clear FB Images” in the first input, and paste in the code snippet from above into the second input.

Firefox

https://support.mozilla.org/en-US/kb/bookmarks-toolbar-display-favorite-websites

Safari

  1. Select/Tap the arrow button next to the URL bar and select “Bookmark.”
  2. Select/Tap the bookmark button, and then “Edit.”
  3. Paste in the code snippet from above.

Internet Explorer

Google it!


 

Once you’ve added the bookmarklet to your browser, we can clear images from Facebook open graph image cache with a bookmarklet by just browsing to the URL that you’re trying to clear cached Facebook images from and clicking the bookmarklet link. An alert will popup shortly informing you of any images that you just cleared from Facebook’s Open Graph cache server. Here’s what it looks like in action:

Clear images from Facebook open graph image cache with a bookmarklet

A Google Webmaster Tools API PHP Example – Using Search Analytics API to download search analytics data as CSV with the new OAuth 2.0 method

This is a Webmaster Tools API PHP Example to download your search analytics data as CSV with the new OAuth 2.0 method. As you probably have learned, Google announced that they will be discontinuing their old CSV download scripts for information on queries & rankings and replacing it with their new Search Analytics API. Since there’s a ton of Stack Overflow posts that seem to be unanswered on how to do this, I figured I’d post my approach to getting a CSV of my Search Analytics data like I’m accustomed to getting through the webmaster tools admin panel.

First thing we will do is create an application with these steps: https://developers.google.com/webmaster-tools/v3/how-tos/authorizing#APIKey

You’re going to add credentials for a Service account and select P12 as your key type. You’ll then receive the .p12 file that we’ll use to authenticate with OAuth 2.0 in the steps below. These are the screens you’ll see:

Google API Service AccountGoogle API P12 Key

 

 

 

 

 

 

At the end of this you’ll also get a service account email address. Copy that address down so you can put it into the example below. After you’ve got your app setup, follow all the instructions in these links to grant access to your app through the appropriate Google services (just going to link to Webmaster Tools and Google Analytics for this tutorial):

Webmaster Tools:  https://developers.google.com/webmaster-tools/v3/quickstart/quickstart-oacurl?hl=en

Google Analytics:  https://developers.google.com/analytics/devguides/reporting/core/v3/quickstart/service-php

Now we need to download the Google API PHP Client Library for PHP. Make a directory and place your .p12 file you downloaded from earlier inside. Open up a terminal, go to that directory, and clone the git repo they have to pull their latest Google API PHP Client Library:

That should download the google-api-php-client folder into your project’s directory. Now for the tricky part… writing the functions to retrieve the data. I took an object-oriented approach to this because I plan to turn this class into a library that pulls all the analytics and webmaster tools data I need – feel free to hack this up to be procedural if that’s all you need.

Here’s the beginning to my class that has a couple methods to grab the data from the API and create a CSV:

Now all you have to do is run it via the command line (or in a web browser if you want), and we have a beautiful CSV of the top 50 search queries (which can be changed with the second parameter in the get_searchanalytics() method) in a file called test.csv in my project’s directory. I know this is a relatively new subject so I’m going to post this prematurely without editing this a bunch so people can get the help they need on Stack Overflow and such.

A lot of this has been trial and error and digging into their Webmaster class for the methods, but if you have issues or questions feel free to comment and I’ll try to help you navigate this API as best I can.

Note: If you get a 403 Forbidden error, make sure you approve your app with this link: https://console.developers.google.com/flows/enableapi?apiid=webmasters&credential=client_key

Update: (courtesy of Jakob from the comments below)

Since the article was written Google has updated the main branch of their API, and a lot of code was removed from it because it has to be rewritten, so Webmasters class, which was in src/Google/Service/Webmasters.php is not there any longer.

However, if you browse their github page, they tell you that there is a separately maintained branch, marked as v1-master right here:
https://github.com/google/google-api-php-client/tree/v1-master

And that is the one you should use for this project. Don’t forget to update file references accordingly.

One more update. When you create a service account, it will ask if you want an App Engine default service account or Compute Engine default service account. The one you need to select in this case is the Compute Engine default service account.

Pure CSS select dropdown style – override the default select dropdown styles with CSS

Custom CSS Dropdown Style

I was recently tasked with coding a template that was made by a designer that doesn’t quite understand the headache involved in using custom styles on a select element. After explaining to my client what components I had control over styling, they decided to move forward with changing their select elements to use a custom style. Let’s dive into my approach on a Pure CSS select dropdown style that should allow you to override the default select dropdown styles with your own using only cross-browser CSS techniques.

In order to do this we’re going to need a containing element for the select element, so I’ve decided to use a label so that text can be put before the select to make the select labeled. This example will be applied to labels with the “dropdown” class.

Let’s start with the CSS:

And here’s the HTML:

Here’s a working example of this for you to play around with and test:

http://jsfiddle.net/jphase/quqnmoun/

I’ve tested the styling in Chrome 45.x, Firefox 41.x, and Internet Explorer 11.x. If you see any issues with styles looking funny, feel free to post which browser, browser version, and OS you’re using and I’ll update the CSS to fix the issue. That being said, your site will probably have some default styles that might conflict with the styles in this tutorial.

If you run into issues with the styles rendering on your site, feel free to paste a URL to that site along with your comment and I’ll try to figure out how to get the styles to render correctly for your site. Cheers 🙂

How to get shortcode attributes from WordPress content with regex

A few different people in the WordPress support channel on IRC have asked me for how to get shortcode attributes from WordPress content. This means that they are trying to take the raw content (before it’s WordPress natively processes the content for shortcodes) and pull attributes from those shortcodes.

This has proven to be a bit tricky for plain ol’ regex because some shortcodes are self-closing shortcodes and some have a closing shortcode tag. I’m not planning on reworking this code to work for everyone all the time, so please understand that the following snippet is just a specific use-case for processing the url attribute from soundcloud shortcodes.

This will use some regex to grab all shortcodes from the content (from the $content variable in this example) and filter out the results of the url attribute for those shortcodes. Since this is just an example, I’m not even checking to see if the matched shortcode is a soundcloud shortcode but that could be done pretty easily. Use the following as a starting point for your super-hacky less-than-clean shortcode regex attribute processing needs.

It’s also good to note that there’s a global you can use for listing all active shortcodes. Here is an example of that in case you need to print them out for debugging:

Let me know if you have any questions, comments, or concerns… but again… this is just an example so please don’t expect this to work for your specific needs without changing the code a bit.