Fail-To-Ban (Lite) – EdgeRouter

Here’s how to create a fail-to-ban type of functionality on an EdgeRouter completely using BASH, without installing any 3rd party packages. We are going to create a single script and add a scheduled job to run it. That’s all there is to it.

Step 1
Run the following

vi /config/scripts/fail-to-ban

Now we need to turn off auto indent before copying and pasting the script below. Type the following:

:set noai
i

Now paste the following script into the file:

#!/bin/bash

PATH=$PATH:/usr/bin:/bin:/sbin:/usr/sbin

ATTEMPTS=10;    # NUMBER OF ATTEMPTS IN A GIVEN INTERVAL
INTERVAL=600;   # INTERVAL (IN SECONDS) TO WATCH FOR FAILED ATTEMPTS - HISTORICALLY FROM CURRENT TIME
PERMBAN=100;    # AFTER THIS NUM OF FAILED ATTEMPTS, BAN UNTIL LOG ROTATES
BLOCKSECS=3600; # AFTER THIS TIME (IN SECONDS), UNBLOCK A BLOCKED IP
BLOCKED_ALREADY=""
BLOCKED_NOW=""
SKIPPED=""
EXPIRED_BLOCK=""
NOW=`date '+%s'`

isip() {
  ISIP=$1
  if [ $(echo $IP | sed 's/[^.]//g' | awk '{print length; }' 2> /dev/null) -eq 3 ]; then
    ISIP=1
  fi
}

fail2ban() {
        # echo failing $IP with count $COUNT and lastcount $LASTCOUNT
        IP=$IP
        EXISTS=`nice -19 iptables -n -L | grep $IP | wc -l`
        IS_LOCAL=`echo $IP | grep -E '^10\.|192\.168|127\.' | wc -l`
        if [ $EXISTS -gt 0 ]; then
    BLOCKED_ALREADY+=",$IP:$COUNT"
                # echo "IP $IP is already blocked"
        elif [ $IS_LOCAL -eq 1 ]; then
    SKIPPED+=",$IP:$COUNT"
                # echo "IP is local IP.  Not blocking"
        else
    if [ ! "$IP" == "" ]; then
                  # echo "Blocking IP $IP after $COUNT abuses."
                  BLOCKED_NOW+=",$IP:$COUNT"
                  iptables -I INPUT 1 -j DROP -s $IP
                  echo "`date`:$IP:$NEWCOUNT:$COUNT:BLOCKED" >> /tmp/banned.log
    fi
        fi
}

updateList() {
        NOW=`date '+%s'`
        sed -i /tmp/ip-list.log -e "s/:"$IP":"$LASTCOUNT".*$/:"$IP":"$COUNT":"$NOW"/"
}

updateTime() {
  NOW=`date '+%s'`
  sed -i /tmp/ip-list.log -e "s/:"$IP":"$LASTCOUNT".*$/:"$IP":"$LASTCOUNT":"$NOW"/"
}


showList() {
  LIST="$2"
  DESCRIPTION="$1"
  if [ ! "$LIST" == "" ]; then  
        	echo "$DESCRIPTION"
        	for i in `echo "$LIST"`                                                                       
        	do                                                                                                   
        	        BIP=$(echo $i | sed -e 's/:.*$//')                                                           
        	        BCOUNT=$(echo $i | sed -e 's/^.*://')                                                        
      if [ ! "$BIP" == "" ]; then
                    echo $BIP $BCOUNT                                                                            
      fi
        	done
  fi	
}

checkExpired() {
  BLOCKED=$(nice -19 iptables -L INPUT -n | grep "^DROP" | sed -e 's/^.*--  //' | sed -e 's/ .*$//')
  for i in `grep -e "$BLOCKED" /tmp/ip-list.log`                                                                                                                                              
  do                                                                                                                                                                           
          IP=`echo $i | cut -d':' -f2`                                                                                                                                         
          isip $IP                                                                                                                                                             
          COUNT=`echo $i | cut -d':' -f3`                                                                                                                                      
          LASTACTION=`echo $i | cut -d':' -f4`                                                                                                                                 
                                                                                                                                                                               
          if [ $((NOW-LASTACTION)) -gt $BLOCKSECS ] && [ ! "$IP" == "" ] && [ $ISIP -eq 1 ] && [ $COUNT -lt $PERMBAN ]; then                                                   
                  LINE=`nice -19 iptables -L -n --line-numbers | grep "$IP" | cut -d' ' -f1`                                                                                            
                  if [ ! "$LINE" == "" ]; then                                                                                                                                 
                          echo "Removing block on $IP"                                                                                                                         
        echo "$(date):$IP:UNBLOCKED" >> /tmp/banned.log
                          # EXPIRED_BLOCK+=",$IP"                                                                                                                              
                          echo iptables -D INPUT $LINE                                                                                                                         
                          iptables -D INPUT $LINE                                                                                                                              
                  fi                                                                                                                                                           
          fi                                                                                                                                                                   
  done                                   
}


if [ ! -f /tmp/ip-list.log ]; then
        touch /tmp/ip-list.log
fi

# CLEANUP - KEEP ONLY HACKERS FROM TODAY
echo -n "" > /tmp/ip-list.new
IFS="
"
for i in `grep "^$(date +%Y%m%d):" /tmp/ip-list.log`
do
  if [ ! "$i" == "" ]; then
    echo $i >> /tmp/ip-list.new
  fi
done
mv /tmp/ip-list.new /tmp/ip-list.log

# Do some checking to see if the logs actually changed
if [ -f /tmp/this-run ]; then
  mv /tmp/this-run /tmp/last-run
else
  touch /tmp/last-run
fi
ls -1 --full-time /var/log/auth.log > /tmp/this-run
CHANGE=$(diff /tmp/last-run /tmp/this-run | wc -l)
if [ $CHANGE -eq 0 ]; then
  echo "No change since last run"
  checkExpired
  exit
fi

IPLIST=`nice -19 grep failure /var/log/auth.log | grep rhost | sed -e 's/^.*rhost=//' | sed -e 's/ .*$//' | sort | uniq -c | sed -e 's/^ *//' | sed -e 's/ /:/' | grep -E ":[0-9.]*$" | sed -e "s/^\(.*\)$/$(date +%Y%m%d):\1/"`

for i in `echo "$IPLIST"`
do
  #echo $i
        COUNT=`echo $i | cut -d':' -f2`
        IP=`echo $i | cut -d':' -f3`
  DATE=`echo $i | cut -d':' -f1`
  isip $IP
        LASTCOUNT=`cat /tmp/ip-list.log | grep ":$IP:" | cut -d':' -f3`
        ELAPSED=`cat /tmp/ip-list.log | grep ":$IP:" | cut -d':' -f4 | sed -e 's/\n//g'`
  ELAPSED=$((NOW-ELAPSED))
        if [ "$COUNT" == "" ]; then
                COUNT=0
        fi
        if [ "$LASTCOUNT" == "" ]; then
                LASTCOUNT=0
        fi
        NEWCOUNT=$((COUNT-LASTCOUNT))
        if [ ! "$LASTCOUNT" == "" ] && [ $LASTCOUNT -eq 0 ] && [ $ISIP -eq 1 ]; then
                echo "$DATE:$IP:$COUNT:$NOW" >> /tmp/ip-list.log
               # echo "Adding $IP to the IP tracking log with count $COUNT"
        fi
  # echo "IP:$IP NEWCOUNT:$NEWCOUNT LASTCOUNT:$LASTCOUNT COUNT:$COUNT ELAPSED:$ELAPSED ISIP:$ISIP ATTEMPTS:$ATTEMPTS INTERVAL:$INTERVAL"
  
        if [ $NEWCOUNT -ge $ATTEMPTS ] && [ $ISIP -eq 1 ] && ( [ $ELAPSED -le $INTERVAL ]  ||  [ $COUNT -gt $PERMBAN ] ); then
                if [ $LASTCOUNT -ne 0 ]; then
      echo "Updating IP:$IP with NEWCOUNT:$NEWCOUNT ATTEMPTS:$ATTEMPTS ELAPSED:$ELAPSED INTERVAL:$INTERVAL ISIP:$ISIP"
                        updateList

                fi
                fail2ban
  elif [ $NEWCOUNT -ge $ATTEMPTS ] && [ $ISIP -eq 1 ]; then
    echo "Updating the timestamp for IP $IP; +$NEWCOUNT since last update"
    updateTime
        fi
done

checkExpired

IFS=","

showList "Blocked | Attempts" "$BLOCKED_ALREADY"
showList "Newly Blocked | Attempts" "$BLOCKED_NOW"
showList "Skipped | Attempts" "$SKIPPED"
showList "Expired" "$EXPIRED_BLOCK"

Now you need to exit and save your changes.
esc
:wq

Now let’s make the script executable:

chmod a+x /config/scripts/fail-to-ban

And lastly, we need to add a job to run this periodically and also disable hostname lookups in SSH to make the script’s IP validation work properly and remove a possible DoS vector.

configure
set system task-scheduler task failtoban executable path /config/scripts/fail-to-ban
set system task-scheduler task failtoban interval 1m
set service ssh disable-host-validation
commit
save

Done! Now your EdgeRouter should be protected against brute force login attacks.

How to replace a brick in GlusterFS

Scenario 1: Your data drive fails in your machine and you really don’t want to go through the process of reconfiguring a new system just to create and join a new brick.

Scenario 2: You proactively replace your hard drive and you keep the OS in tact and just want to use the new drive.

The solution to either scenario is quite simple.

Let’s stop cron just in case we have any watchdog processes running.

service cron stop

First thing we need to do is tell GlusterFS that we want to take the brick offline. We do that with this command.

gluster volume reset-brick your-volume your-hostname-or-ip:/path-to-failed-brick

Then we can unmount the old volume and swap out a new disk. As long as our config remains the same, we will later use the reset-brick command to get all of the data back from the redundant copy.

Now, you need to create a partition and then format the new drive with the following. Let’s assume that your new drive/partition is /dev/sdb1 and that it’s an SSD so that you want to use f2fs.

mkfs.f2fs /dev/sdb1

Now, you need to update /etc/fstab so that it automatically mounts. Let’s say your mount point is /mnt/gluster. You will want to use something like this:

echo "UUID=`blkid | grep /dev/sdb1 | cut -d'\"' -f2` /mnt/gluster        f2fs     defaults,noatime,nofail    0 1" >> /etc/fstab

Note: You should comment out the old entry in your fstab file.

Next, you will want to mount your new partition.

mount -a

Now let’s create the new brick. This must be a different name than the old one!! Assuming that your old brick is /mnt/gluster/brick, we could simply do.

mkdir -p /mnt/gluster/brick

Now let’s use the gluster volume reset-brick command to do the heavy lifting for us.

gluster volume reset-brick your-volume your-hostname-or-ip:/path-to-failed-brick your-hostname-or-ip:/path-to-failed-brick commit force

If you stopped cron, start it back up now.

service cron start

That’s it.

Now you can check on the progress of the re-population of data by using the heal info command.

Hope this helps!

Simple Fail2Ban Alternative for FreePBX + SSH

I created a script to help secure Asterisk servers: fail-to-ban. It runs once per minute and will block an IP that tries, unsuccessfully, to authenticate more than a certain number of tries within a certain interval. It keeps track of each block and will automatically unblock an IP after a given amount of time elapses. All of these variables are easily set/tuned at the beginning of the script. It’s basic, easy to install, and effective. The installation is just two extremely easy steps.

  • Create the file /scripts/fail-to-ban.
  • Add a cron job entry to run it.
  • /scripts/fail-to-ban

    #!/bin/bash
    
    PATH=$PATH:/usr/bin:/bin:/sbin:/usr/sbin
    
    ATTEMPTS=10;    # NUMBER OF ATTEMPTS IN A GIVEN INTERVAL
    INTERVAL=300;   # INTERVAL (IN SECONDS) TO WATCH FOR FAILED ATTEMPTS - HISTORICALLY FROM CURRENT TIME
    PERMBAN=100;    # AFTER THIS NUM OF FAILED ATTEMPTS, BAN UNTIL LOG ROTATES
    BLOCKSECS=3600;   # AFTER THIS TIME (IN SECONDS), UNBLOCK A BLOCKED IP
    BLOCKED_ALREADY=""
    BLOCKED_NOW=""
    SKIPPED=""
    EXPIRED_BLOCK=""
    NOW=`date '+%s'`
    
    isip() {
            ISIP=$1
            if [ $(echo $IP | sed 's/[^.]//g' | awk '{print length; }' 2> /dev/null) -eq 3 ]; then
                    ISIP=1
            fi
    }
    
    fail2ban() {
            # echo failing $IP with count $COUNT and lastcount $LASTCOUNT
            IP=$IP
            EXISTS=`iptables -n -L | grep $IP | wc -l`
            IS_LOCAL=`echo $IP | grep -E '^10\.|192\.168|127\.' | wc -l`
            if [ $EXISTS -gt 0 ]; then
                    BLOCKED_ALREADY+=",$IP:$COUNT"
                    # echo "IP $IP is already blocked"
            elif [ $IS_LOCAL -eq 1 ]; then
                    SKIPPED+=",$IP:$COUNT"
                    # echo "IP is local IP.  Not blocking"
            else
                    if [ ! "$IP" == "" ]; then
                            # echo "Blocking IP $IP after $COUNT abuses."
                            BLOCKED_NOW+=",$IP:$COUNT"
                            iptables -I INPUT 1 -j DROP -s $IP
                            echo "`date`:$IP:$NEWCOUNT:$COUNT" >> /tmp/banned.log
                    fi
            fi
    }
    
    updateList() {
            NOW=`date '+%s'`
            sed -i /tmp/ip-list.log -e "s/"$IP":"$LASTCOUNT".*$/"$IP":"$COUNT":"$NOW"/"
    }
    
    
    showList() {
            LIST="$2"
            DESCRIPTION="$1"
            if [ ! "$LIST" == "" ]; then  
                    echo "$DESCRIPTION"
                    for i in `echo "$LIST"`                                                                       
                    do                                                                                                   
                            BIP=$(echo $i | sed -e 's/:.*$//')                                                           
                            BCOUNT=$(echo $i | sed -e 's/^.*://')                                                        
                            if [ ! "$BIP" == "" ]; then
                                    echo $BIP $BCOUNT                                                                            
                            fi
                    done
            fi
    }
    
    checkExpired() {
            BLOCKED=$(iptables -L INPUT -n | grep "^DROP" | sed -e 's/^.*--  //' | sed -e 's/ .*$//')
            for i in `grep -e "$BLOCKED" /tmp/ip-list.log`                                                                                                                                              
            do                                                                                                                                                                           
                    IP=`echo $i | cut -d':' -f1`                                                                                                                                         
                    isip $IP                                                                                                                                                             
                    COUNT=`echo $i | cut -d':' -f2`                                                                                                                                      
                    LASTACTION=`echo $i | cut -d':' -f3`                                                                                                                                 
                                                                                                                                                                                         
                    if [ $((NOW-LASTACTION)) -gt $BLOCKSECS ] && [ ! "$IP" == "" ] && [ $ISIP -eq 1 ] && [ $COUNT -lt $PERMBAN ]; then                                                   
                            LINE=`iptables -L -n --line-numbers | grep "$IP" | cut -d' ' -f1`                                                                                            
                            if [ ! "$LINE" == "" ]; then                                                                                                                                 
                                    echo "Removing block on $IP"                                                                                                                         
                                    # EXPIRED_BLOCK+=",$IP"                                                                                                                              
                                    echo iptables -D INPUT $LINE                                                                                                                         
                                    iptables -D INPUT $LINE                                                                                                                              
                            fi                                                                                                                                                           
                    fi                                                                                                                                                                   
            done                                   
    }
    
    
    if [ ! -f /tmp/ip-list.log ]; then
            touch /tmp/ip-list.log
    fi
    
    # Do some checking to see if the logs actually changed
    if [ -f /tmp/this-run ]; then
            mv /tmp/this-run /tmp/last-run
    else
            touch /tmp/last-run
    fi
    ls -al /var/log/asterisk/security > /tmp/this-run
    CHANGE=$(diff /tmp/last-run /tmp/this-run | wc -l)
    if [ $CHANGE -eq 0 ]; then
            echo "No change since last run"
            checkExpired
            exit
    fi
    
    IPLIST=$(/bin/grep -E "InvalidAccount|ChallengeResponseFailed" /var/log/asterisk/security | sed -e 's/^.*RemoteAddress="IPV4\/UDP\/\([0-9.]*\)\/.*$/\1/' | sort | uniq -c | sed -e 's/^ *//' | sed -e 's/ /:/')
    
    for i in `echo "$IPLIST"`
    do
            #echo $i
            COUNT=`echo $i | cut -d':' -f1`
            IP=`echo $i | cut -d':' -f2`
            isip $IP
            LASTCOUNT=`cat /tmp/ip-list.log | grep "^$IP:" | cut -d':' -f2`
            ELAPSED=`cat /tmp/ip-list.log | grep "^$IP:" | cut -d':' -f3 | sed -e 's/\n//g'`
            ELAPSED=$((NOW-ELAPSED))
            if [ "$COUNT" == "" ]; then
                    COUNT=0
            fi
            if [ "$LASTCOUNT" == "" ]; then
                    LASTCOUNT=0
            fi
            NEWCOUNT=$((COUNT-LASTCOUNT))
            if [ ! "$LASTCOUNT" == "" ] && [ $LASTCOUNT -eq 0 ] && [ $ISIP -eq 1 ]; then
                    echo "$IP:$COUNT:$NOW" >> /tmp/ip-list.log
                   # echo "Adding $IP to the IP tracking log with count $COUNT"
            fi
            if [ $NEWCOUNT -ge $ATTEMPTS ] && [ $ISIP -eq 1 ] && ( [ $ELAPSED -le $INTERVAL ]  ||  [ $COUNT -gt $PERMBAN ] ); then
                    if [ $LASTCOUNT -ne 0 ]; then
                            # echo "Updating IP:$IP with NEWCOUNT:$NEWCOUNT ATTEMPTS:$ATTEMPTS ELAPSED:$ELAPSED INTERVAL:$INTERVAL ISIP:$ISIP"
                            updateList
    
                    fi
                    fail2ban
            fi
    done
    
    checkExpired
    
    IFS=","
    
    showList "Blocked | Attempts" "$BLOCKED_ALREADY"
    showList "Newly Blocked | Attempts" "$BLOCKED_NOW"
    showList "Skipped | Attempts" "$SKIPPED"
    showList "Expired" "$EXPIRED_BLOCK"
    

    /scripts/crontab

    * * * * * /scripts/fail-to-ban > /dev/null 2>&1 &
    

    After creating these files, simply run the following commands:

    chmod a+x /scripts/fail-to-ban
    crontab /scripts/crontab
    

    That’s really all you need to do!

    Blank Page when signing into Office 365 using Chromium (Fixed)

    Symptom: A blank page when accessing https://outlook.office365.com, https://login.microsoftonline.com, or most other Microsoft sites.

    Cause: An untrusted root certificate.

    Solution: Add the proper Symantec root CA.

    1. Paste in the following into a new file called symantec-ca.cer
    2. -----BEGIN CERTIFICATE-----
      MIIFODCCBCCgAwIBAgIQUT+5dDhwtzRAQY0wkwaZ/zANBgkqhkiG9w0BAQsFADCB
      yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
      ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
      U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
      ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
      aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB+MQsw
      CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV
      BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVjIENs
      YXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOC
      AQ8AMIIBCgKCAQEAstgFyhx0LbUXVjnFSlIJluhL2AzxaJ+aQihiw6UwU35VEYJb
      A3oNL+F5BMm0lncZgQGUWfm893qZJ4Itt4PdWid/sgN6nFMl6UgfRk/InSn4vnlW
      9vf92Tpo2otLgjNBEsPIPMzWlnqEIRoiBAMnF4scaGGTDw5RgDMdtLXO637QYqzu
      s3sBdO9pNevK1T2p7peYyo2qRA4lmUoVlqTObQJUHypqJuIGOmNIrLRM0XWTUP8T
      L9ba4cYY9Z/JJV3zADreJk20KQnNDz0jbxZKgRb78oMQw7jW2FUyPfG9D72MUpVK
      Fpd6UiFjdS8W+cRmvvW1Cdj/JwDNRHxvSz+w9wIDAQABo4IBYzCCAV8wEgYDVR0T
      AQH/BAgwBgEB/wIBADAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vczEuc3ltY2Iu
      Y29tL3BjYTMtZzUuY3JsMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQjMCEw
      HwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wawYDVR0gBGQwYjBgBgpg
      hkgBhvhFAQc2MFIwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20v
      Y3BzMCgGCCsGAQUFBwICMBwaGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vcnBhMCkG
      A1UdEQQiMCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTUzNDAdBgNVHQ4E
      FgQUX2DPYZBV34RDFIpgKrL1evRDGO8wHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnz
      Qzn6Aq8zMTMwDQYJKoZIhvcNAQELBQADggEBAF6UVkndji1l9cE2UbYD49qecxny
      H1mrWH5sJgUs+oHXXCMXIiw3k/eG7IXmsKP9H+IyqEVv4dn7ua/ScKAyQmW/hP4W
      Ko8/xabWo5N9Q+l0IZE1KPRj6S7t9/Vcf0uatSDpCr3gRRAMFJSaXaXjS5HoJJtG
      QGX0InLNmfiIEfXzf+YzguaoxX7+0AjiJVgIcWjmzaLmFN5OUiQt/eV5E1PnXi8t
      TRttQBVSK/eHiXgSgW7ZTaoteNTCLD0IX4eRnh8OsN4wUmSGiaqdZpwOdgyA8nTY
      Kvi4Os7X1g8RvmurFPW9QaAiY4nxug9vKWNmLT+sjHLF+8fk1A/yO0+MKcc=
      -----END CERTIFICATE-----

    3. Open Settings->Manage Certificates
    4. Browse to Authorities->Import
    5. Open the symantec-ca.cer file that you saved earlier
    6. That’s it! Now you should be able to access Office 365.

    iOS 10 OpenVPN with Active Directory Authentication

    With iOS 10, PPTP is out and IPSEC and L2TP are the main options now. PPTP uses a protocol that is neither TCP or UDP – it is GRE. And IPSEC uses yet another protocol called ESP. The problem with most VPNs is that they do not work when you need them to because many hotel and guest networks allow access to only specific protocols, such as TCP/UDP. This tutorial will show you how you can configure a simple OpenVPN server to authenticate your Active Directory users even through environments that are prone to blocking PPTP, IPSEC, and L2TP.

    First, let’s download a copy of the very cool open source router, VyOS.
    http://packages.vyos.net/iso/release/1.1.7/vyos-1.1.7-amd64.iso

    Now, we create a VM with a 2GB partition and we install VyOS. At the prompt, login with vyos/vyos and type:

    install image
    

    When asked, set your password of choice for the vyos username. Eject the CD, reboot, and you should get to the login prompt. Login, and let’s get started.

    Type the following:

    configure
    set system package repository squeeze components 'main contrib non-free'
    set system package repository squeeze distribution 'squeeze'
    set system package repository squeeze url 'http://archive.debian.org/debian'
    set system package repository squeeze-lts components 'main contrib non-free'
    set system package repository squeeze-lts distribution 'squeeze-lts'
    set system package repository squeeze-lts url 'http://archive.debian.org/debian'
    sudo apt-get -o Acquire::Check-Valid-Until=false update
    sudo apt-get install krb5-config krb5-user libpam-krb5
    commit
    

    Now you should have all of the packages that you need, so its time to start configuring kerberos. Type the following:

    sudo nano /etc/krb5.conf
    

    Here is a template for a simple krb5.conf file that you will need to modify to match your domain. The IP of your domain controller will be the IP for the kdc. Take note of the case changes for the domain name. Match the example for the case for your domain.

    [libdefaults]
            default_realm = MYDOMAIN.LOCAL
    
    [realms]
            MYDOMAIN.LOCAL = {
            kdc = 10.0.0.2
            }
    
    [domain_realms]
            .mydomain.local = MYDOMAIN.LOCAL
            mydomain.local = MYDOMAIN.LOCAL
    
    [appdefaults]
            forwardable = true
            pam = {
                minimum_uid = 1000
                MYDOMAIN.LOCAL = {
                    ignore_k5login = true
                }
            }
    
    

    Now that /etc/krb5.conf is configured, we should be able to do the first test. Let’s run kinit and see if we can login. Here is an example:

    kinit myuser
    

    After you type in the password, you should be able to check if you are logged in with the klist command.

    klist
    

    If all worked, type the following.

    save
    exit
    reboot now
    

    Now it’s time to configure OpenVPN.
    First, let’s copy over the template easy-rsa folder to the config folder so that it persists upon upgrades.

    cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /config/easy-rsa2
    cd /config/easy-rsa2
    source ./vars
    ./clean-all 
    ./build-ca
    ./build-dh
    ./build-key-server 
    ./build-key-server  server
    cp keys/ca.crt /config/auth/
    cp keys/dh1024.pem ../auth/
    cp keys/server.key ../auth/
    cp keys/server.crt ../auth/
    ./build-key company
    

    Phew! Ok, now we’re done with the prerequisites to configure OpenVPN. Let’s start configuring VyOS so that it uses all of these new settings.

    configure
    set interfaces openvpn vtun0 mode server
    set interfaces openvpn vtun0 openvpn-option --username-as-common-name
    set interfaces openvpn vtun0  openvpn-option "plugin /usr/lib/openvpn/openvpn-auth-pam.so login"
    set interfaces openvpn vtun0 persistent-tunnel
    set interfaces openvpn vtun0 protocol udp
    set interfaces openvpn vtun0 server domain-name mydomain.local
    set interfaces openvpn vtun0 server subnet 10.0.1.0/24
    set interfaces openvpn vtun0 server name-server 10.0.0.2
    set interfaces openvpn vtun0 push-route 10.0.0.0/16
    set interfaces openvpn vtun0 tls ca-cert-file /config/auth/ca.crt
    set interfaces openvpn vtun0 tls cert-file /config/auth/server.crt
    set interfaces openvpn vtun0 tls dh-file /config/auth/dh1024.pem
    set interfaces openvpn vtun0 tls key-file /config/auth/server.key
    commit
    exit
    

    We are almost there. Now we just need to create the .ovpn file. Replace the sections between , , and with the contents of the files /config/auth/ca.crt, /config/auth/company.crt, and /config/auth/company.key. Hint: You can get the contents by typing something like: cat /config/auth/ca.crt.

    client
    remote VPN.mydomain.com 1194
    proto udp
    dev tun
    resolv-retry infinite
    nobind
    persist-key
    persist-tun
    
    -----BEGIN CERTIFICATE-----
    ........................................
    ........................................
    ........................................
    ........................................
    .........................==
    -----END CERTIFICATE-----
    
    
    -----BEGIN CERTIFICATE-----
    ........................................
    ........................................
    ........................................
    ........................................
    .........................==
    -----END CERTIFICATE-----
    
    
    -----BEGIN RSA PRIVATE KEY-----
    ........................................
    ........................................
    ........................................
    ........................................
    .........................==
    -----END RSA PRIVATE KEY-----
    
    auth-user-pass
    

    Install OpenVPN Connect on your iOS 10 device.
    Copy your .ovpn file onto your device and open it.
    Enter your username/pass and you’re ready to go.

    Note: It is not imperative that each person has a unique certificate because they need to authenticate their user/pass in order to connect (and we use their username to register instead of their certificate name). If you are not happy with the security risk of re-using certificates, you can generate a new certificate for each person by using the ./build-key script in the /config/easy-rsa2 folder.

    The Fastest and Easiest Way to Clone a PC on a Network

    This is a guide for using the automated clone assistant on RestartOS to clone a PC over a network. We have a source PC and a target PC. The source PC has the content that we want, and the target PC’s disk will be overwritten with the data from the source PC’s disk. In this guide both PCs have a single disk drive to keep the instructions simple. If you have more than one disk, you can repeat the steps for each disk.

    Target PC

    First, we launch the software on the target PC.
    clone-target-launch

    Then we choose the disk that we want to overwrite and confirm our selection.
    clone-target-step1

    Source PC

    Next, we launch the software on the source PC.
    clone-source-launch

    We choose the disk that we want to clone and then we wait for the system to find the target PC automatically.
    clone-source-step1

    We confirm the IP address of the target PC (as is seen in step #2 above) and just press enter (or type “y”) to proceed.
    clone-source-step2

    That’s it! The cloning starts. No IPs to type in. No hassle of copying over MBRs. And it’s very fast.. like 15 minutes for a Windows 10 install fast.
    success

    How To Change a Xenserver VM Type

    Here is a quick and dirty script to change the VM type of an existing Xenserver VM. This can be useful if you are, let’s say, using Linux-based cloning software to clone a Windows VM and you want it to run as fast as possible. You may realize that the system runs very slow. That’s because the Windows VM handles paravirtualization differently than the Linux environment will. You have to change the device type, and this script will help. I added a layer of abstraction to simplify the whole process of switching VM types.

    Here are examples of how to run the script:
    ./change-type myvm This will print out the current VM type as either “windows” or “linux”. A numerical ID is printed in [] that designates the current device_id, for your information.
    change-type myvm linux This will change the device type from whatever it is now, to linux.
    change-type myvm windows This will change the device type from whatever it is now, to windows.
    change-type 00000000-0000-0000-0000-000000000000 linux This will change the device type for the machine with the UUID specified.

    #!/bin/bash
    # /usr/bin/change-type
    #
    # Written by Pete Lombardo
    #
    # This script can change the type of hardware for a VM in a Xen Pool(for example, from Linux to Windows or visa versa).
    # It can also be used to resolve a blue screen issue after upgrading the tools inside a Windows VM.
    #
    
    if [ ! "$1" == "" ]; then
            uuidtest=`echo $1 | sed -e 's/\-//g' | egrep "[0-9a-f]{32}" | wc -l`
            if [ $uuidtest -eq 0 ]; then
                    uuid=`xe vm-list | grep -i ": $1" -B1 | grep uuid | cut -d':' -f2 | cut -d' ' -f2`
                    name="$1"
            else
                    uuid=$1
                    name=`xe vm-list | grep "$uuid" -A1 | grep name | cut -d':' -f2 | cut -d' ' -f2-`
            fi
    fi
    
    if [ "$1" == "" ]; then
            echo
            echo "Usage: change-type [machine-name] [type]"
            echo "Available Types: linux,windows"
            echo
            exit
    elif [ "$2" == "" ]; then
            echo
            echo "Checking the device type for $name"
            if [ "$uuid" == "" ]; then
                    echo
                    echo "ERROR: System $1 not found."
                    echo
                    exit
            fi
            type=`xe vm-param-get uuid=$uuid param-name=platform param-key=device_id 2>/dev/null`
            case $type in
                    0001)
                            echo "linux [$type]"
                            ;;
                    0002)
                            echo "windows [$type]"
                            ;;
                    *)
                            echo "linux [$type]"
                            ;;
            esac
            echo
            exit
    fi
    
    case $2 in
    linux)
            device="0001"
            ;;
    windows)
            device="0002"
            ;;
    esac
    
    if [ "$uuid" == "" ]; then
            echo
            echo "ERROR: System $1 not found."
            echo
            exit
    fi
    
    xe vm-param-set uuid=$uuid platform:device_id=$device
    
    echo
    type=`xe vm-param-get uuid=$uuid param-name=platform param-key=device_id`
            case $type in
                    0001)
                            echo "linux [$type]"
                            ;;
                    0002)
                            echo "windows [$type]"
                            ;;
                    *)
                            echo "linux [$type]"
                            ;;
            esac
    echo
    
    

    Prepping VyOS + OpenVPN for use with a Chromebook

    First, you need to create the certificates. Use EasyRSA for this. Follow the instructions at the OpenVPN site for that.
    https://openvpn.net/index.php/open-source/documentation/miscellaneous/77-rsa-key-management.html

    To build the CA certificate, use the command:
    ./easyrsa build-ca

    To build the server certificate, use the command:
    ./easyrsa build-server-full server

    To build a client, use the command:
    ./easyrsa build-client-full client

    You may want to remove the password for the private keys for the server and client certificates. To do that, use these commands.

    cd private
    openssl rsa -in server.key -out server-nopass.key
    openssl rsa -in client.key -out client-nopass.key
    cd ..

    Now copy the ./issued/server.crt, the ./ca.crt, and the ./private/client-nopass.key to the VyOS server. Create a new folder called /config/auth/openvpn and store them there.

    The OpenVPN connection for VyOS should look like this:

     openvpn vtun0 {
         local-port 1194
         mode server
         openvpn-option --persist-tun
         protocol udp
         replace-default-route {
             local
         }
         server {
             domain-name mydomain.com
             max-connections 10
             name-server 10.0.0.1
             push-route 10.0.0.0/23
             subnet 10.0.1.0/24
             topology subnet
         }
         tls {
             ca-cert-file /config/auth/openvpn/ca.crt
             cert-file /config/auth/openvpn/server.crt
             dh-file /config/auth/openvpn/dh.pem
             key-file /config/auth/openvpn/server-nopass.key
         }
     }
    

    Now we have to prep the Chromebook certificate.

    openssl pkcs12 -export -out client.pfx -inkey private/client-nopass.key -in issued/client.crt -certfile ca.crt

    Now upload the ca.crt and the client.pfx files to the Chromebook (You can use the SCP addon for the file manager to transfer them there.)

    Navigate to chrome://certificate-manager.
    Click on Authorities and then click Import.
    Navigate to the ca.crt and import it.
    Now click back to “Your certificates” and click “Import and Bind to Device”.
    Navigate to the client.pfx and import it. When it asks for a password, hit enter without one if you did not set one.
    Now navigate to chrome://settings and click “Add Connection”. Choose OpenVPN.
    Set the “Provider Type” to be OpenVPN.
    Set the CA certificate to be the one that we uploaded.
    Set the client certificate to be the client.pfx. Note: It will show up with the common name of the certificate, not the file name.
    Now type in any username and password. It doesn’t matter since we are using certificate based authentication. Save the user/pass so that you do not have to type it every time. Again, it does not matter what you type here.

    Now you should be able to connect!

    XenCenter Storage Repository Rescan Issue – Solved

    When clicking rescan on a storage respository in XenCenter, you may encounter an error like the one below.

    rescan-failure

    The problem is usually due to a foreign file in the storage repository. To find out what the offending file is, turn to the power of the command-line. Login to the master server and run the following command.
    tail -n 100 /var/log/SMlog

    Review the log and find the offending entry. It might look something like this.
    ***** VHD scan error: vhd=/var/run/sr-mount/3219ad4f-242e-1744-6d38-78e17efdce69/9411b73c-7a3a-4812-b64b-edfe8f04ee70.vhd scan-error=-32 error-message='opening file'

    In this case, the file /var/run/sr-mount/3219ad4f-242e-1744-6d38-78e17efdce69/9411b73c-7a3a-4812-b64b-edfe8f04ee70.vhd could not be opened. After taking a quick look at that file, I quickly recognized that it was a 0 byte file. It did not create properly. I moved it out to the /tmp folder and tried to rescan. This resolved my issue.

    FreePBX 13 – MySQL Performance – RESOLVED

    I resolved the performance issue by running the following commands in MySQL:

    use asterisk;
    alter table kvstore engine=MyISAM;

    My new FreePBX 13 server was causing disk IO contention with my other VMs, so I had a look at the disk writes to the MySQL database. The MySQL databases are the ONLY thing on the VDB disk. Notice anything strange? So did I. The disk usage ramps up over time, so it looks like that periodic Cron job of theirs to refresh the Dashboard has some build up of data that makes the system more and more sluggish as time goes on.

    graph_image.php

    No known fix yet. Fixed by using the MyISAM engine for the kvstore table instead of InnoDB. Disabling cron is a temporary workaround. Restarting FreePBX (fwconsole restart) may be another workaround.