Archive for the ‘Guides’ Category

Save iptables on Shutdown and Restart, and Restore on Boot

Tuesday, October 6th, 2015

Save iptables Rules on Shutdown, Restore on Boot

When your server shutsdown (halts), reboots, or enters runlevel 1, your iptables configuration is automatically wiped and reset.  Packages such as iptables-persistent supposedly help with this problem, but unless you save your rules manually, the rules are never saved automatically when the system reboots. 

I've wanted to truly persist my iptables, so I decided to change their package to always save the iptables rules when the system reboots, halts, or enters runlevel 1 automatically.  The rules are then restored when the system boots to runlevels 2-5.  This means that your iptables configuration will persist forever.  This may not be desired, but if I ban an IP address permanently, I always want it to be banned.

If you'd like to use this modified version of iptables-persistent so that your rules are automatically saved on shutdown, you can install it by running the below commands:

sudo apt-get remove iptables-persistent
sudo dpkg -r iptables-persistent
wget http://dinofly.com/files/linux/iptables-persistent_0.5.8_all.deb
sudo dpkg --install iptables-persistent_0.5.8_all.deb

Use at your own risk.  If you do something stupid, it will persist until you can clear it!

The above package was tested in Ubuntu 12.04 x86, Ubuntu 12.04 x64, Ubuntu 14.04 x86, Ubuntu 14.04 x64, and Ubuntu 15.04 x64.  Should work on other debian operating systems as well.

Get the Source Code and Modify an Ubuntu Package

Tuesday, October 6th, 2015

Modifiying the Source of a Package and Creating a New Deb Binary

In order to download the source code of an existing package, first install the prerequisites:

sudo apt-get install build-essential debhelper

To get the source code of a package, run the following command:

apt-get source {name_of_package_interested_in}

Make changes to the source using an editor like geany or via terminal through nano.  Edit the changelog file and add a record of your changes to build a new revision number.  After you have made the changes, run the following commands to build the package which should include your changes.

dpkg-source --commit
dpkg-buildpackage -b

The updated package has been built.  To install the package, simply use the below commands:

sudo dpkg --install {name_of_new_deb_file}

To remove the software:

sudo dpkg -r {name_of_package [NOT NAME OF DEB FILE]}

Now you can release it!

Ubuntu Grub Fails to Install on RAID Array

Friday, February 6th, 2015

Ubuntu Grub RAID Issues

Grub Fails To Install on RAID Array

If grub fails to install on your RAID array in any version of Ubuntu, do NOT disable your BIOS RAID! The correct solution is at this blog entry. I'll summarize it below.

At the stage of the install where it is attempting to install GRUB it will detect as

/dev/mapper

This is incomplete! That's why the GRUB install fails.

You need the actual name of the RAID array to install to. So during that step, press ctrl+alt+F2 to drop to a busybox terminal, then enter

ls -l /dev/mapper

Pick out the name of your array from the list shown, then press ctrl+alt+F1 to switch back to the install (you can switch back and forth as much as you like with no problems) and enter it in the field as

/dev/mapper/{your array name}  

Then GRUB installs perfectly and you're ready to go, with a proper BIOS RAID array intact.

System Won't Boot After Grub Failed to Install

If your system will no longer boot because you skipped installing or updating grub, you need to download an Ubuntu version that does support RAID, boot from the LIVE CD, drop to a terminal, and then run:

ls -l /dev/mapper
sudo grub-install /dev/mapper/{ARRAY_NAME_HERE}

Setting Up RAID Array During Ubuntu Install

If you are configuring a BIOS RAID array for the first time on Ubuntu, you should create a 1MB boot partition.  Its partition type is "boot".  If you do this, grub will always try to install there and will succeed every time without failing when upgrading or reinstalling grub.

Install VSFTPD 3.0.2 on the ARM Platform for Raspbian or Debian

Saturday, January 3rd, 2015

Install VSFTPD 3.0.2 on the ARM Platform for Raspbian or Debian

Download and install the arm compiled VSFTPD 3.0.2 deb package file and init script:

wget -N http://dinofly.com/files/linux/vsftpd_3.0.2_arm.tar.gz
tar -zxvf vsftpd_3.0.2_arm.tar.gz
if [ ! -e "/etc/init.d/vsftpd" ]; then
    sudo cp vsftpd /etc/init.d/
fi
sudo dpkg -i vsftpd_3.0.2-1_armhf.deb

Now, run these commands:

sudo useradd -d /var/ftp ftp
sudo mkdir -p /var/ftp
sudo chown root.root /var/ftp

Finally, start the VSFTPD service and set it to run on boot:

sudo service vsftpd restart
sudo update-rc.d vsftpd defaults

VSFTPD 3.0.2 should now be installed on your ARM device.

Allow Anonymous Read Only FTP via VSFTPD

Saturday, January 3rd, 2015

Anonymous VSFTPD Setup (Read Only)

Configuration:

In order to enable anonymous FTP connections to a particular directory while still supporting authentication for virtual users for their files via PAM isn't that difficult.  Install VSFTPD if you haven't done so already by running the following command:

sudo apt-get install vsftpd

Create a backup of your existing VSFTPD confiugration file (this guide assumes you have already installed vsftpd):

sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak

Next, let's edit the file:

sudo nano /etc/vsftpd.conf

Add the following lines to your configuration file:

anonymous_enable=YES
anon_root={INSERT_PATH_TO_ANONYMOUS_DIRECTORY}
anon_mkdir_write_enable=NO
anon_upload_enable=NO

Adding these lines enables anonymous FTP to the specified directory where files can be read and downloaded only.  Anonymous users cannot write, delete, change, or modify files because of the anon_mkdir_write_enable=NO and the anon_upload_enable=NO configuration lines.  For your changes to take effect, restart vsftpd.

sudo service vsftpd restart

You're done!

Multiple Comment Forms on WordPress Page – Using WYSIWYG Editor NicEdit

Tuesday, January 28th, 2014

WYSIWYG WordPress Comments

I tried and tried to get the CKEditor plugin for WordPress to initalize multiple comment textareas for a custom post type I had created using the pods WordPress plugin.  No matter how hard I tried, I failed.  Only the first instance would get initialized.  I dug through the code and found where the instance was created, but even with the code in front of my eyes, I could not figure out how to adapt the messy PHP / Javascript mesh to do what I wanted.

Eventually, I came accross a great guide explaining how to use NicEdit, a simple WYSIWYG editor that can be used easily to replace the boring WordPress comment box with something more friendly for end users leaving comments.

Following this guide, I downloaded and uploaded the NicEdit files to a folder named "scripts" in my theme's directory (please adjust the path in the functions below if you want to use another directory or place the files elsewhere).  I would recommend downloading the non-compressed version, as the code is easier to read and making changes is a lot easier.  I inserted the following function into my WordPress theme's functions.php file:

function add_nicEdit() {
    if ( !is_admin() ) {
        // register scripts
        wp_register_script('nicEdit', get_stylesheet_directory_uri() . '/scripts/nicEdit.js', array(), false, true);
 
        // enqueue scripts
        wp_enqueue_script('nicEdit');
    }
}
 
add_action('wp_enqueue_scripts', 'add_nicEdit');

Then, I created a new function that I added to NicEdit.js file.  After this code:

allTextAreas : function(nicOptions) {
        var textareas = document.getElementsByTagName("textarea");
        for(var i=0;i<textareas.length;i++) {
            nicEditors.editors.push(new nicEditor(nicOptions).panelInstance(textareas[i]));
        }
        return nicEditors.editors;
    },

I added a function called allCommentTextAreas:

allCommentTextAreas : function(nicOptions) {
        var textareas = document.getElementsByTagName("textarea");
        for(var i=0;i<textareas.length;i++) {
      if(textareas[i].className == "comment_editor"){
               nicEditors.editors.push(new nicEditor(nicOptions).panelInstance(textareas[i]));
      }
        }
        return nicEditors.editors;
    },

The way this function works is that it will replace all textareas that have a class of "comment_editor" only.

Next, in my theme's footer.php file after the <?php wp_footer(); ?> line, I added the following:

<script type="text/javascript">
           // We need to initialize the WYSIWIG editor for the comments field                   bkLib.onDomLoaded(function() { nicEditors.allCommentTextAreas({
                   iconsPath : '<?php bloginfo( 'stylesheet_directory' ) ?>/scripts/nicEditorIcons.gif', buttonList : ['bold','italic','strikethrough','link','unlink','removeformat']})
                   });
        </script>

In your pods page template, load comments like this:

$args["comment_notes_after"] = "";
$args["comment_field"] = '<p class="comment-form-comment"><label for="comment">' . _x( 'Comment', 'noun' ) .          
'</label><textarea id="comment" class="comment_editor" name="comment" cols="45" rows="8" aria-required="true">' .          
'</textarea></p>';
comment_form( $args, $post_id ); 

Your comments form will now look a lot better, specifically, they will look like this:

nic edit

Disable BIND9 Recursive DNS Queries to Prevent UDP DDOS Flood Attacks

Sunday, January 12th, 2014

Turn Off BIND9 Recursion

By default, BIND9 is configured to allow recursive DNS queries.  This allows others to use your DNS server to query other domains on your server's behalf.  Unfortunately, recursive DNS queries can be used to amplify a UDP flood DDOS attack.  As such, for a shared web hosting environment, it is best to disable recursive DNS queries.  You can disable BIND9 recursion easily by running the following script:

cd ~/Downloads
wget -N "http://dinofly.com/files/linux/disable_bind9_recursion.tar.gz"
tar -zxvf disable_bind9_recursion.tar.gz
sudo bash disable_bind9_recursion.sh

It should work on all versions of Linux but has been tested and works perfectly on Ubuntu.  You may need to change the path used for the BIND config file. 

MySQL Dump Insert Statements Only

Saturday, September 14th, 2013

Using mysqldump to Create SQL Backups with Only Insert Statements and Ignore Existing Records

mysqldump -u USER -p PASSWORD --skip-triggers --compact --no-create-info --insert-ignore DBNAME

 

Debian & Ubuntu :: Suppress Installation Package Prompts Completely or Preconfigure Prompt Answers

Saturday, September 14th, 2013

Suppress Installation Package Prompts Completely or Preconfigure Installation Question Answers

Automating the installation of software via bash scripting on Linux can be difficult.  However, in debian and its related distributions such as Ubuntu, you can simplify the installation of packages by using a few tools.  One of these tools is called debconf-utils.  If installation packages such as MySQL or PHPMyAdmin ask configuration questions, you can provide a default set of answers without being prompted.  This is excellent for testing scripts or automating installation for users who may not know how to appropriately answer these questions.

Basically, with debconf-utils you can pre-answer these questions so that no prompts show up!

To install, run this command:

sudo apt-get install debconf-utils

To get a list of questions an installer might ask, first install the package on a test machine where you're writing the script normally.  For example, let's install phpmyadmin:

sudo apt-get install phpmyadmin

Now, to retrieve a set of questions phpmyadmin may ask, you can run this command:

sudo debconf-get-selections | grep phpmyadmin

In your bash script, you can now pre-answer certain questions by including your preconfigured answer commands before installing the package.  For example, when phpmyadmin installs, it asks for the MySQL root user password.  You can skip this prompt and define what the MySQL root password should be by using this command in your script:

echo 'phpmyadmin phpmyadmin/mysql/admin-pass password 1234' | debconf-set-selections

password defines the type and 1234 sets the password to 1234.
You can also suppress questions entirely by using the following command in front of your install command:

DEBIAN_FRONTEND=noninteractive sudo apt-get install phpmyadmin

Default configuration will be used during the installation of the phpmyadmin package, which means it may not work after being installed because some configuration options should be answered.  So, use both combinations for various packages to fit your needs!

Using JQuery Color Picker and Cookie Plugins to Change Element Background Colors Dynamically Based on User Preference

Sunday, April 21st, 2013

Changing Website Element Colors Dynamically Based on User Preferences

Wouldn't it be cool to dynamically style a website or webpage based on a user's favorite color?  Thanks to several JQuery plugins, it is now possible to do so!  The JQuery Color Picker plugin allows users to select a color based on a color pallete / color wheel similar to those found within photo editing software such as Adobe Photoshop or Corel PaintShop Pro.  The JQuery Color Plugin can darken, lighten, add, multiply, subtract, find color hues, change rgb values, and manipulate colors in all sorts of ways you probably never imagined possible.  The final piece to dynamically styling a page based on a user selected color is to save the picked color's value in a cookie using the JQuery-Cookie Plugin.  When any page loads, you will need to use the document.ready JQuery function to read the cookie and restyle elements as necessary.  If a cookie is not set, the default color can also be specified here. 

Here's a screenshot of the JQuery Color Picker in action:

To load / use the color picker, place this function within the document.ready function:

// Color Picker Loader
    $('#colorpicker').ColorPicker({
    
       color: defaultColor,
         onShow: function (colpkr) {
              $(colpkr).fadeIn(500);
              return false;
         },
         onHide: function (colpkr) {
              $(colpkr).fadeOut(500);
              return false;
         },
         onChange: function (hsb, hex, rgb) {
          var origColor = '#' + hex;
       
          // Set the main div background colors to what was selected in the color picker
              $('#colorpicker').css('backgroundColor', origColor);
          $('#origColor').css('backgroundColor', origColor);
          
          // Set the cookie
          $.cookie("color", '#' + hex, { path: '/' });
          
          // Set the dark and light colors (multi-iterations)
          darkColor = $.xcolor.darken('#' + hex).getHex();
          for (var i = 0; i < iterations; i++) {
            darkColor = $.xcolor.darken(darkColor).getHex();
          }
            
          lightColor = $.xcolor.lighten('#' + hex).getHex();
          for (var i = 0; i < iterations; i++) {
            lightColor = $.xcolor.lighten(lightColor).getHex();
          }
          
          
          // Set the light and dark divs
          $('#darkColor').css('backgroundColor', darkColor);
          $('#lightColor').css('backgroundColor', lightColor);
          
          // Change class attributes
          $('.light').css('backgroundColor', lightColor);
          $('.dark').css('backgroundColor', darkColor);
          $('.pad').css('backgroundColor', origColor);
          
          // Set the border
          $('#colorpicker').css('border-color', darkColor);
          
          
         }
    }); 

Assign a DIV element the ID of "colorpicker" in your HTML file to activate the color picker.    Don't change the "onShow" or "onHide" JQuery sub-functions of the ColorPicker.  When a user chooses a color from the color picker, the color picker "onChange" function is called.  This is where you need to define what should be done with the color the user has picked.  In my example, I call the $.xcolor.lighten and $.xcolor.darken Color Plugin functions to generate a lighter and darker color.  I use then use the color selected, a lighter variant of that color, and a darker variant of that color to style elements appropriately to keep text readable while offering a new color scheme.  As you can see from the code above, I mainly change the css attributes of certain classes, which the elements have been assigned.  What is changed is the backgroundColor and border-color of certain classes based on the three colors that were generated.

To see what other cool things you can do with all of these plugins, check out the links in the first paragraph.  Click here to see a live demonstration of all three plugins in action and download the source for how it all works based on the example discussed above.  The only Javascript file that needs to be changed to experiment with this sample is the "main.js" file within the "js" folder.

I hope this guide helps.  The plugin websites did not provide all of the code needed for a working sample, but luckily, I did the combination work for you.  Go ahead and use my source for anything!  Please comment if you have questions.