{"id":2338,"date":"2016-06-27T00:00:54","date_gmt":"2016-06-27T07:00:54","guid":{"rendered":"http:\/\/192.168.3.4\/?p=2338"},"modified":"2018-01-09T06:50:24","modified_gmt":"2018-01-09T14:50:24","slug":"wordpress-disaster-recovery","status":"publish","type":"post","link":"https:\/\/www.cloudacm.com\/?p=2338","title":{"rendered":"WordPress Disaster Recovery"},"content":{"rendered":"<p><strong>Introduction<\/strong><\/p>\n<p>WordPress sites have been hacked and hijacked. Having the ability to recover from such an event can be critical. The recreation of content by other means may not be possible. This is why establishing a disaster recovery policy is important. More importantly, the policy must be put into practice.<br \/>\nIn this document, I\u2019ll cover the creation of a disaster recover policy and the steps involved in following through with the policy.<\/p>\n<p><strong>Creating a backup<\/strong><\/p>\n<p>This should be done as soon as possible. We\u2019ll use this backup to restore to a sandbox system to validate that our policy is sound.<\/p>\n<p>First is to make a backup of the file\/folder structure. I copied mine with FTP. This file\/folder data will be overwritten onto a sandbox instance of WordPress. Only one of the files in this backup will need to be modified in order for it to work in on our sandbox environment. That file is \u201cwp-config.php\u201d which contains pointers to the WordPress database. These are the specific lines in that file that must match the sandbox environment.<\/p>\n<p>define(&#8216;DB_NAME&#8217;, &#8216;NameOfDateBase&#8217;);<br \/>\ndefine(&#8216;DB_USER&#8217;, &#8216;DatabaseUser&#8217;);<br \/>\ndefine(&#8216;DB_PASSWORD&#8217;, &#8216;DatabasePassword&#8217;);<\/p>\n<p>Next, make a backup of the database. I used an integrated backup utility my provider makes available through its control panel. The database is then ready to download with FTP. Once copied, delete it from the host.<\/p>\n<p>Now that the database is copied locally, make another copy for modifications. These changes should not be made directly to the newly created backup database. Rather, you should create a copy of the database file for manipulation. This allows for additional recovery, in the event those changes cause the database to become corrupt.<\/p>\n<p><strong>Setup the Sandbox<\/strong><\/p>\n<p>Testing the process of recovery should never be done on a live system. For this purpose, a sandbox environment is used to validate the steps of data restoration.<\/p>\n<p>I\u2019m going with a VM that has the standard LAMP (Linux, Apache, MySQL, and PHP) setup. I won\u2019t go through how to create VMs or install LAMP. That is beyond the scope of this paper. There is plenty of documentation and demonstrations on how to do that online.<\/p>\n<p>Once the system is up and running, I\u2019ll install MyPHPAdmin. I\u2019ve found that this tool is much easier to use than fumbling through command line entry. Again, install steps are not covered here. Once it is up and running, you\u2019ll need to create a database and the user \/ password that WordPress will use.<\/p>\n<p>Login on the phpMyAdmin portal and click the \u201cDatabases\u201d link in the ribbon above the main page. Type in the name of the database we\u2019ll use for WordPress, in this example it will be \u201cwordpress\u201d, then click Create. You should see it listed in the left and below now.<\/p>\n<p>Now we\u2019ll create the user account that WordPress will use to connect with the database. Click the \u201cUsers\u201d link in the ribbon above. Midway down the page you should see a link named \u201cAdd user\u201d, click it. The Add user page should load. Fill in the fields for these items and set these options as follows:<\/p>\n<p>Login Informatoin<br \/>\nUser name: dbtest<br \/>\nHost: Local (localhost)<br \/>\nPassword: dbpass (use something stronger if online, but this is a sandbox)<br \/>\nRe-type: dbpass<\/p>\n<p>Database for user<br \/>\nGrant all priviledges on wildcard name \u2013 Check this box<\/p>\n<p>Global priviledges \u2013 Check all<\/p>\n<p>Resource limits \u2013 leave default<\/p>\n<p>Now the user account and database are ready for WordPress to utilize. We are ready to start the WordPress install and configure it on our sandbox. The steps to install will not be covered. I\u2019ll only cover the steps once it is installed.<\/p>\n<p>Now that WordPress is installed, you\u2019ll be prompted with a language preference when you first load the site. Choose your language and click Continue. Here you will see a notice about WordPress needing to connect to a database. This will be the database we create just a bit ago. Let\u2019s go!<\/p>\n<p>Enter in the information to connect to our WordPress database and click Submit. Then Run the install.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-2341\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage1.png\" alt=\"PostImage1\" width=\"427\" height=\"264\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage1.png 427w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage1-300x185.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage1-100x62.png 100w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage1-150x93.png 150w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage1-200x124.png 200w\" sizes=\"auto, (max-width: 427px) 100vw, 427px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Since this site will be overwritten later on, it isn\u2019t all that important what is entered in the Welcome page. Do make a note of it anyway, you may need it later. Use better login info if your sandbox is online, which is something highly discouraged.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-2346\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage2.png\" alt=\"PostImage2\" width=\"453\" height=\"466\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage2.png 453w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage2-292x300.png 292w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage2-100x103.png 100w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage2-150x154.png 150w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage2-200x206.png 200w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage2-300x309.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage2-450x463.png 450w\" sizes=\"auto, (max-width: 453px) 100vw, 453px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Now our sandbox WordPress site should be ready to use.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-2349\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage3.png\" alt=\"PostImage3\" width=\"157\" height=\"227\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage3.png 157w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage3-100x145.png 100w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage3-150x217.png 150w\" sizes=\"auto, (max-width: 157px) 100vw, 157px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>One thing to look at before we move on is the \u201cwp-config.php\u201d file in the root of the WordPress site. Go ahead and open it up in a text editor. You should see these entries:<\/p>\n<p>define(&#8216;DB_NAME&#8217;, &#8216;wordpress&#8217;);<br \/>\ndefine(&#8216;DB_USER&#8217;, &#8216;dbtest&#8217;);<br \/>\ndefine(&#8216;DB_PASSWORD&#8217;, &#8216;dbpass&#8217;);<\/p>\n<p>This is the config page we\u2019ll edit next when we restore our live database and file structure onto our sandbox system.<\/p>\n<p><strong>Modifying and Restoring the live WordPress site in the Sandbox<\/strong><\/p>\n<p>Now comes the moment of truth. Before we restore the data, it must be modified to work in our sandbox environment. Make a copy of the live database backup. This way, we can revert back if something doesn\u2019t go quite right.<\/p>\n<p><strong>Massage the data<\/strong><\/p>\n<p>Now, open the database copy in a text editor, I\u2019m using Notepad++. Since my live system is hosted with SSL and my sandbox is not, I\u2019ll need to do a search and replace for \u201chttps:\/\u201d and change it to \u201chttp:\/\u201d<\/p>\n<p>Next, I do search and replace for the URL that my live site uses and replace it with my sandbox URL. That\u2019s it, the database can be saved. Now we are ready to import it into our sandbox database on MySQL.<\/p>\n<p><strong>Import the data<\/strong><\/p>\n<p>From phpMyAdmin, go to the sandbox database then select Import from the ribbon bar. Select the database to import and uncheck the option to interrupt. Otherwise, the process could timeout.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-2351\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage4.png\" alt=\"PostImage4\" width=\"446\" height=\"330\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage4.png 446w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage4-300x222.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage4-100x74.png 100w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage4-150x111.png 150w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage4-200x148.png 200w\" sizes=\"auto, (max-width: 446px) 100vw, 446px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>It may take several minutes to complete. Keep the phpMyAdmin page open, it will tell you when it\u2019s done.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-2354\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2016\/06\/PostImage5.png\" alt=\"PostImage5\" width=\"502\" height=\"46\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage5.png 502w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage5-300x27.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage5-100x9.png 100w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage5-150x14.png 150w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage5-200x18.png 200w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2016\/06\/PostImage5-450x41.png 450w\" sizes=\"auto, (max-width: 502px) 100vw, 502px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Now the file and folder structure can be copied over the sandbox instance of WordPress. Before we begin, lets backup the sandbox \u201cwp-config.php\u201d file. We\u2019ll use this later.<\/p>\n<p>Once the sandbox WordPress directory has been overwritten with our live backup files and folder, we can modify the \u201cwp-config.php\u201d file to point to the sandbox database.<\/p>\n<p>define(&#8216;DB_NAME&#8217;, &#8216;wordpress&#8217;);<br \/>\ndefine(&#8216;DB_USER&#8217;, &#8216;dbtest&#8217;);<br \/>\ndefine(&#8216;DB_PASSWORD&#8217;, &#8216;dbpass&#8217;);<br \/>\ndefine(&#8216;DB_HOST&#8217;, &#8216;localhost&#8217;);<\/p>\n<p>That should do it, save the \u201cwp-config.php\u201d file and reload the sandbox WordPress site. You should see something similar to your live WordPress site.<\/p>\n<p>The theme, plugins, comments, posts, etc. should all be there. You may notice some formatting or main page content not quite in line with what\u2019s live. Look around, 99% of it should be available.<\/p>\n<p>Now, login on the wp-admin portal of the sandbox. You will need to use the login that is setup on your live system. This is because the database that was imported contains that information. This is why it\u2019s important to safeguard the database backup files. Even though the password is hashed, it can be broken to reveal it in plaintext.<\/p>\n<p>You have no excuses now! Do your backups and test your restore process before you need to!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction WordPress sites have been hacked and hijacked. Having the ability to recover from such an event can be critical. The recreation of content by other means may not be possible. This is why establishing a disaster recovery policy is important. More importantly, the policy must be put into practice. In this document, I\u2019ll cover the creation of a disaster recover policy and the steps involved in following through with the policy. Creating a backup This should be done as&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.cloudacm.com\/?p=2338\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2338","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/2338","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2338"}],"version-history":[{"count":12,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/2338\/revisions"}],"predecessor-version":[{"id":2353,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/2338\/revisions\/2353"}],"wp:attachment":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}