Archive for the ‘Linux’ Category

Installing Chrome WebDriver (Linux Script)

Wednesday, August 28th, 2019

Installing Chrome WebDriver (Linux Script)

Find out which version of Chrome is installed on your system before running the below commands.  You can find out your chrome version by running the following command:

google-chrome --version

Adjust the version number (replace {VERSION_NUMBER})  in the below commands to match the version installed on your system!!!

sudo -i
cd ~/Downloads
rm chromedriver_linux64.zip
wget -N https://chromedriver.storage.googleapis.com/{VERSION_NUMBER}/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
mv chromedriver /usr/bin/chromedriver
chown root:root /usr/bin/chromedriver
chmod +x /usr/bin/chromedriver

Selenium and other libraries that rely on the Chrome WebDriver should now work properly.

CentOS – Using NAT with KVM Guests

Wednesday, July 17th, 2019

CentOS – Using NAT with KVM Guests

Please note that all commands in this guide must be run on the main HOST machine (the physical machine).  They should not be run on KVM guests (virtual machines).

If your server has a limited number of IPv4 addresses, it might be best to setup and run some virtual machines that are configured to use the default NAT network interface that KVM provides.  This will allow you to run multiple virtual machines that share the same IP address.  Think of it as setting up a home network with multiple devices with certain ports forwarded to specific devices for incoming connections.

First, create the virtual machines that are going to use NAT using virt-manager as you normally would.  In the virtual machine configuration wizard, assign the default NAT network interface named "virbr0".  After the virtual machines have been created, shut down the virtual machines.  Now, we'll assign these virtual machines static LAN IP addresses so that we can port forward certain ports and always have them reach the proper virtual machines. 

The first thing we need to do is get the MAC address of each virtual machine.  Write down the name of the virtual machine and its MAC address, as we'll need this information later on when we edit the NAT interface and assign static LAN IP addresses to our virtual machines.  Run this command to retrieve the MAC address for a specific virtual machine.

virsh dumpxml VM_NAME | grep -i '<mac'

Using the MAC address information from the VMs we want to use NAT with, edit the default NAT interface by running the below command. 

virsh net-edit default

If for some reason the NAT interface is not named default, you can find it by running the below command:

virsh net-list

After the <range /> entry, assign the static LAN IP addresses similar to the following:

<dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
      <host mac='52:54:00:ff:4a:2a' name='vm1' ip='192.168.122.13'/>
      <host mac='52:54:00:bb:35:67' name='vm2' ip='192.168.122.14'/>
      <host mac='52:54:00:aa:d9:f2' name='vm3' ip='192.168.122.15'/>
</dhcp>

Save the file with your desired values and quit the editor.  Restart the NAT interface by running the below commands:

virsh net-destroy default
virsh net-start default

Now, you'll need to setup your iptables port forwarding rules.  Adjust the below rules as necessary (changing the port numbers to the ones you want to use) and then save them so that they persist:

iptables -I FORWARD -o virbr0 -d 192.168.122.13 -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport 39989 -j DNAT --to 192.168.122.13:39989
iptables -I FORWARD -o virbr0 -d 192.168.122.14 -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport 39990 -j DNAT --to 192.168.122.14:39990
iptables -I FORWARD -o virbr0 -d 192.168.122.15 -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport 39991 -j DNAT --to 192.168.122.15:39991
iptables -t nat -A POSTROUTING -s 192.168.122.0/24 -j MASQUERADE
iptables -A FORWARD -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i virbr0 -o br0 -j ACCEPT
iptables -A FORWARD -i virbr0 -o lo -j ACCEPT
iptables-save
service iptables save

Congrats, your virtual machines are now using NAT, have been assigned static LAN IP addresses, and iptables rules on the host server have been configured to port forward specific ports to each NAT VM.


Persistently Saving NAT Port Forward Rules

The only solution I found that would persistently save my NAT forwarding rules is to create a libvirt hook bash script as mentioned here

service iptables stop
iptables -F
service iptables save
service iptables start
mkdir -p  /etc/libvirt/hooks
nano  /etc/libvirt/hooks/qemu

The contents of the "/etc/libvirt/hooks/qemu" file should look similar to the following:

#!/bin/bash
# IMPORTANT: Change the "VM NAME" string to match your actual VM Name.
# In order to create rules to other VMs, just duplicate the below block and configure
# it accordingly.
if [ "${1}" = "vm1" ]; then   # Update the following variables to fit your setup
   GUEST_IP=192.168.122.13
   GUEST_PORT=39989
   HOST_PORT=39989   if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
    /sbin/iptables -D FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
    /sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
   if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
    /sbin/iptables -I FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
    /sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
fi
if [ "${1}" = "vm2" ]; then   # Update the following variables to fit your setup
   GUEST_IP=192.168.122.14
   GUEST_PORT=39990
   HOST_PORT=39990   
   if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
        /sbin/iptables -D FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
        /sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
   if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
        /sbin/iptables -I FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
        /sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
fi
if [ "${1}" = "vm3" ]; then   # Update the following variables to fit your setup
   GUEST_IP=192.168.122.15
   GUEST_PORT=39991
   HOST_PORT=39991
   if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
        /sbin/iptables -D FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
        /sbin/iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
   if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
        /sbin/iptables -I FORWARD -o virbr0 -d  $GUEST_IP -j ACCEPT
        /sbin/iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
   fi
fi

Save and exit.  Make the script executable.

chmod +x /etc/libvirt/hooks/qemu

Reboot the host server.


Old Instructions for Persistent Saving (Non-Working)

If your iptables forwarding rules are not persisted after the host machine is rebooted or shutdown, run the following commands:

sudo -i
yum install -y iptables-services
systemctl stop firewalld
systemctl disable firewalld
systemctl enable iptables
nano /etc/sysconfig/iptables-config 

Change the below values to "yes":

IPTABLES_SAVE_ON_RESTART="yes"
IPTABLES_SAVE_ON_STOP="yes"

Save and exit.  Reboot the server.

If you're still having issues, try this (will clear your existing iptables rules):

iptables-save > iptables_bk
service iptables stop
iptables -F
<run iptables NAT rules here>
<run any other iptables rules you want>
service iptables save
service iptables start

More Detailed Guide

Installing the Newest Version of Python 2.7.x on Older Versions of Ubuntu (like 14.04)

Thursday, May 9th, 2019

Installing the Newest Version of Python 2.7.x on Older Ubuntu Systems

If you need to upgrade to the newest version of Python 2.7.x, and you're running an older distribution (like Ubuntu 14.04), use the following commands to get the latest version (works on Ubuntu 17.04 and older – tested on Ubuntu 14.04):

sudo add-apt-repository ppa:jonathonf/python-2.7
sudo apt-get update
sudo apt-get install python2.7

Then, you'll need to cleanup a few leftover system packages manually before installing the newest version of python-pip.  If you don't do this, you'll run into problems installing some new packages using pip.

sudo rm /usr/lib/python2.7/dist-packages/chardet*.egg-info
sudo rm -r /usr/lib/python2.7/dist-packages/chardet
sudo rm /usr/lib/python2.7/lib-dynload/_hashlib.x86_64-linux-gnu.so
sudo rm /usr/lib/python2.7/lib-dynload/_hashlib.i386-linux-gnu.so

Now, you can download and install the newest version of python-pip:

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
sudo python get-pip.py

Getting Let's Encrypt Certbot to Work:

First, you'll need to install a few packages that Certbot (the Let's Encrypt client) uses:

sudo pip install requests
sudo pip install hmac

Now, you'll need to delete the EFF directory from the /opt directory to avoid old configuration issues that were used for your older version of python.  Once you cleanup this directory, you'll run certbot again so it can reconfigure itself. 

sudo rm -r /opt/eff.org/
sudo certbot

You're done.

Full list of commands (for quickly doing all of the above):

sudo -i
add-apt-repository ppa:jonathonf/python-2.7
apt-get update
apt-get install python2.7
rm /usr/lib/python2.7/dist-packages/chardet*.egg-info
rm -r /usr/lib/python2.7/dist-packages/chardet
rm /usr/lib/python2.7/lib-dynload/_hashlib.x86_64-linux-gnu.so
rm /usr/lib/python2.7/lib-dynload/_hashlib.i386-linux-gnu.so
mkdir -p /root/Downloads
cd /root/Downloads
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
pip install requests
pip install hmac
rm -r /opt/eff.org/
certbot

Change the Default Editor to nano in Linux

Saturday, April 27th, 2019

Use nano as the Default Editor

If you hate vi like I do, you can configure Linux to always default to using the nano editor.

Simply add the following to the bottom of the /etc/bashrc file:

export EDITOR="nano"

Save the file.  nano is now the default editor.  When you use

sudo crontab -e

The nano editor will now be used by default.

Configuring Let’s Encrypt Certbot on CentOS 7 with lighttpd

Saturday, April 27th, 2019

Configuring Let's Encrypt Certbot on CentOS 7 with lighttpd

Installing Certbot

First, install certbot by using the below commands:

sudo yum -y install epel-release
sudo yum install certbot

certbot is python based program that allows you to request SSL certificates for your domains. 

Request a Certificate

Use the below command to request a certificate (adjust paths and replace the test.com domain as necessary):

sudo certbot certonly --webroot -w /var/www/vhosts/test/httpdocs -d test.com

A certificate has now been stored in /etc/letsencrypt/live.  Create a combined certificate format by using the below command (replacing test.com with your real domain):

/bin/cat /etc/letsencrypt/live/test.com/cert.pem /etc/letsencrypt/live/test.com/privkey.pem > /etc/letsencrypt/live/test.com/custom.pem && /bin/chmod 777 /etc/letsencrypt/live/test.com/custom.pem && /sbin/service lighttpd restart

Certificate Renewal Cronjobs

You may want to create a cronjob to renew the certificate and a cronjob for regenerating the combined format certificate since the underlying certificate file can change (such as when it's renewed):

sudo crontab -e

Insert the below cronjobs:

0 1 * * 1 /usr/bin/certbot renew --quiet
5 1 * * 1 /bin/cat /etc/letsencrypt/live/test.com/cert.pem /etc/letsencrypt/live/test.com/privkey.pem > /etc/letsencrypt/live/test.com/custom.pem && /bin/chmod 777 /etc/letsencrypt/live/test.com/custom.pem && /sbin/service lighttpd restart

Save your crontab configuration. 

Setting Up Lighttpd to Use SSL Certificate

Edit your default-enabled lighttpd configuration file in /etc/lighttpd/vhosts.d to look similar to the following (replacing test.com with your real domain and adjusting various file paths)

$HTTP["host"] == "test.com" {
  var.server_name = "test.com"
  server.name = server_name  server.document-root = vhosts_dir + "/test/httpdocs"
  #accesslog.filename          = vhosts_dir + "/test/log" + "/access.log"
}
$SERVER["socket"] == ":80" {
  server.document-root = vhosts_dir + "/test/httpdocs"
}
$SERVER["socket"] == ":443" {
    ssl.engine           = "enable"
    ssl.pemfile          = "/etc/letsencrypt/live/test.com/custom.pem"
    server.document-root = vhosts_dir + "/test/httpdocs"
    ssl.ca-file = "/etc/letsencrypt/live/test.com/chain.pem" # Root CA
    server.name = "test.com" # Domain Name OR Virtual Host Name
}

Here's how you can set a different document root for specific https (port 443) virtual hosts:

$SERVER["socket"] == ":443" {
    ssl.engine           = "enable"
    ssl.pemfile          = "/etc/letsencrypt/live/test.com/custom.pem"
    server.document-root = vhosts_dir + "/test/httpdocs/"
    ssl.ca-file = "/etc/letsencrypt/live/test.com/chain.pem" # Root CA
    server.name = "test.com" # Domain Name OR Virtual Host Name
    
    $HTTP["host"] =~ "(^|www\.)somethingelse.test.com" {
        server.document-root = vhosts_dir + "/test/httpdocs/subdir"
    }
}

Save and restart the lighttpd service.

sudo service lighttpd restart

Congrats, SSL is now available on your domain, and your Let's Encrypt certificate has been configured and will be renewed automatically by your cronjob.

Copying LVM Containers from One Remote Server to Another

Saturday, April 27th, 2019

Transferring LVM Containers

Before you transfer a KVM container to another machine, create a KVM virtual machine on the target server with the same or larger disk size than the container being transferred. 

You can see a full list of LVM containers by using the below command:

sudo lvdisplay

Copying an LVM Container from the Local Machine to a Remote Server

sudo -i
dd if=/dev/vms/phpdev bs=4096 | pv | ssh root@IPADDRESS_HERE -p SSH_PORT 'dd of=/dev/pool/phpdev bs=4096'

Adjust the above pool paths as necessary since this may vary from server to server. 

Copying an LVM Container from a Remote Machine to the Local Machine

sudo -i
ssh root@IPADDRESS_HERE -p SSH_PORT "dd if=/dev/vms/phpdev bs=4096" | dd of="/dev/vms/phpdev" bs="4096"

Adjust the above pool paths as necessary since this may vary from server to server. 

With SSH Passphrase Key

If you're using an SSH key that is protected with a passphrase, use the below commands to open the key, provide the passphrase for that key, and copy the containers without being prompted for the passphrase when the container transfer begins:

sudo -i
eval $(ssh-agent)
ssh-add /root/keys/{PATH_TO_KEY}
dd if=/dev/pool/test bs=4096 | pv | ssh root@host.com -p {PORT} -i /root/keys/{PATH_TO_KEY} 'dd of=/dev/haha/test bs=4096'

CentOS 7 – Easiest Way to Configure LVM KVM Pool for Virtual Machines

Saturday, April 27th, 2019

Configuring LVM in CentOS

When installing CentOS 7, be sure to only partition the hard drive with about 100GB of space for the OS file system itself.  Leave the rest of the drive unpartitioned.  After CentOS has been successfully installed, run gparted via a terminal using the below command:

sudo gparted

Create a new "LVM2 PV" file system based partition on the drive's remaining space like so:

Now, create the LVM volume group by using the below command and replacing /dev/md126p3 with the new partition's path label:

sudo vgcreate vms /dev/md126p3

Now, launch virt-manager by running the below command:

sudo virt-manager

Go to "Edit" –> "Connection Details" –> click on the "Storage" tab.  Click on the "+" icon on the bottom left.  You're now creating a storage pool.  Give it a name like "vms" which is short for virtual machines.  Select "logical: LVM Volume Group" for the type.  Here's a screenshot:

In "Target Path" select the volume group that you created named vms (which you did earlier using the "vgcreate" command).  Do NOT check the "Build Pool" checkbox, and leave the "Source Path" field blank.  Here's a screenshot of what it should look like:

Click on "Finish".  You're done, and you can now create LVM storage containers for your KVM configured pool named vms.

Here's a good LVM KVM Pool guide from RedHat that includes more information (though it's not as simple as following this guide).

Running PolicyKit (pkexec) Commands without Prompting for Authentication

Saturday, December 8th, 2018

PolicyKit pkexec – Running without Prompting for Authentication

The following guide explains how to configure a pkexec command to run without prompting for authentication.  This is helpful when you want to grant root access to key piece of the system (such as allowing virsh commands from another user when running KVM virtual machines) or just want to run a GUI command as root without having to login or use authentication. 

https://askubuntu.com/questions/383747/how-to-configure-pkexec-to-not-ask-for-password#answer-388660

Or in our own archive in case the above link disappears.