Friday, March 29, 2013

[Tutorial] CentOS 6 OpenVPN Client - Connecting to Existing Site to Site VPN (TomatoUSB)

In this tutorial, I'm going to show you how to add a CentOS 6 server as a OpenVPN client to your existing Site to Site VPN.

This is an extension of my [Tutorial - 30 Minutes or Less] Site to Site VPN with TomatoUSB and OpenVPN and assumes you already have your Site to Site VPN operational. However, you should be able to follow this tutorial and connect to any existing OpenVPN Server.

At the end of this tutorial, your CentOS server will be able to securely access your LAN resources (i.e, computers, printers) on both sites and vice versa (you will also be able to seamlessly access your CentOS server).

Overview of the Steps:

1) Generate Certs and Keys
2) Copy/Transfer over Certs and Keys to Client VPS
3) Install OpenVPN (client)
4) Configure OpenVPN Client
5) Connect


Generate cert/keys for VPS (CentOS 6 32-bit OpenVPN Client)

SSH into your TomatoUSB OpenVPN Server.

#Setup and initialize environment
cd /opt/openvpn-easy-rsa
source ./vars


#myvps_client is the Common Name
./build-key myvps_client


Copy/Transfer over Certs and Keys to Client VPS

Since my CentOS server is running SSH, I'm going to use SSH and SCP (secure copy) to transfer over the certificates and key. You can also transfer over the keys via SFTP or a USB drive.


#create the /etc/openvpn/keys folder on my centos server
ssh root@myvps.qnology.com mkdir -p /etc/openvpn/keys 

#copy over the certificates and keys
#all one line
cd /opt/openvpn-easy-rsa
scp keys/ca.crt keys/myvps_client.crt keys/myvps_client.key root@myvps.qnology.com:/etc/openvpn/keys

Install OpenVPN on CentOS 6

#Bring everything up to date
yum -y update

#Add EPEL (Extra Packages for Enterprise Linux) Repo
# RHEL/CentOS 6 32-Bit ##
cd /tmp 


wget http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm rpm -ivh epel-release-6-8.noarch.rpm

yum --enablerepo=epel install openvpn.i686

Configure OpenVPN Client

#copy sample client.conf to /etc/openvpn
cp /usr/share/doc/openvpn-2.2.2/sample-config-files/client.conf /etc/openvpn


#edit openvpn client.conf
nano /etc/openvpn/client.conf

Update the following lines
#remote OpenVPNServer.ADynamicDNSAddress.com 1194
#ca /etc/openvpn/keys/ca.crt
#cert /etc/openvpn/keys/myvps_client.crt
#key /etc/openvpn/keys/myvps_client.key

#start VPN manually to test
openvpn --config /etc/openvpn/client.conf


#test starting VPN as a service
service openvpn start

#autostart at OpenvPN client on reboot
chkconfig openvpn on



[Tutorial] - PogoPlug E02 with Arch Linux ARM - NAS (SAMBA4), AirPlay, AirPrint, Google CloudPrint

Pogoplugs sporting 1TB USB HDs, USB DACs and USB Wifi

In this tutorial I'm going to show you how to setup the following on a PogoPlug running Arch Linux ARM.

SAMBA
   - enable swapfile
Apple AirPlay
Apple AirPrint
Google CloudPrint
Re-install my.pogoplug.com service
Enable uPNP/DNLA (my.pogoplug.com)
Wireless Configuration
Motion Webcam
Transmission, Sabnzbd, SickBeard and CouchPotato
OpenVPN (client)
OwnCloud (nginx php-fpm sqlite)
Backup and Restore

A List of Compatible PogoPlug Devices:

Want to take a small gamble? Pick up the PogoPlug P21 (Black) or PogoPlug B01 (Pink). Eventhough the box is labeled as a P21/B01, chances are the PogoPlug itself will be a E02 model. I've bought at least 6 P21/B01 from various vendors - Adorama,  JR.com, and Ebay - and so far I have only received E02.


The E02 model is the ideal choice with 256MB RAM and a 1.2Ghz CPU versus other models which only has 128MB RAM and 800Mhz (dual-core) CPU. One last thing, don't get fooled by the USB 3.0 Ports in the Series 4 model; the CPU is a bottleneck and there is no performance difference with the USB 3.0 ports.

This will be a work in progress, so please excuse the typos and grammar.

Note:
- Watch out for run-on commands. I'm having issues with the blogger editor.
- 404 using pacman, just run the command again until it works.

Assumptions:
 - PogoPlug is installed behind a Router/Firewall on a secured LAN (home use only)

Last Updated: 5/18/2013

Arch Linux ARM Installation:

Official Instructions for installing Arch Linux on the PogoPlug E02 can be found here:
http://archlinuxarm.org/platforms/armv5/pogoplug-v2-pinkgray#qt-platform_tabs-ui-tabs2

My summarized version is below.

Turn on without usb drive attached first
SSH into PogoPlug
Login as root/ceadmin. 


#Stop the Pogoplug software
killall hbwd

#Install UBoot
cd /tmp
wget http://jeff.doozan.com/debian/uboot/install_uboot_mtd0.sh
chmod +x install_uboot_mtd0.sh
./install_uboot_mtd0.sh

#Would you like to disable the pogoplug services? [Y/n]
#y - don't look back

#Have uboot mount partition as ext3 
#safer in power outages
/usr/sbin/fw_setenv usb_rootfstype ext3

#Correct machid - make LED Green versus Orange
#Only for E02
/usr/sbin/fw_setenv machid dd6

#Plug in USB Flash Drive
#Use the back bottom USB port

#Partition your usb flash drive
/sbin/fdisk /dev/sda

# Type in the following commands to erase
# and re-partition usb flash drive 
#(WARNING - FLASH DRIVE WILL BE COMPLETELY WIPED): 

# p # list current partitions
# o # to delete all partitions
# n # new partition
# p # primary partition
# 1 (one) # first partition
# <enter> # default start block
# <enter> # default end block #use the whole flash drive
# w # write new partition to disk

#Format USB Flash Drive
cd /tmp

wget http://archlinuxarm.org/os/pogoplug/mke2fs
chmod 755 mke2fs

#format and label partition
./mke2fs -L ROOTFS -j /dev/sda1

#mount usb flash drive
mkdir -p /tmp/usb
mount /dev/sda1 /tmp/usb


#Download and install Arch Linux ARM:

cd /tmp/usb
wget http://archlinuxarm.org/os/ArchLinuxARM-armv5te-latest.tar.gz
tar -xzvf ArchLinuxARM-armv5te-*.tar.gz  

# This will take a long time
rm ArchLinuxARM-armv5te-*.tar.gz
sync  # Takes a while when using a flash drive
cd ..
umount /tmp/usb
reboot


SSH back into your PogoPlug and login with root/root. Success? Congratulations! At this point, Arch Linux is now running on your PogoPlug E02.

#Upgrade kernel and install some initial packages
pacman -Sy linux-kirkwood linux-headers-kirkwood 
ntp yaourt base-devel nano


#set hostname
hostnamectl set-hostname pogoplug

#list timezone
timedatectl timezone list

#set timezone
timedatectl set-timezone America/Los_Angeles



#autostart ntp 
#pogoplug has no hardware clock
systemctl enable ntpd

systemctl start ntpd

#Add ROOTFS to fstab so fsck will run when needed
echo "LABEL=ROOTFS / ext3 rw,noatime 0 1" >> /etc/fstab

#reboot


SAMBA Server - Setup your PogoPlug as a Network Attached Storage (NAS)

The PogoPlug makes an excellent NAS. Expect read/write performance between 23MB-28MB/s on a gigabit network using ext3/ext4.



Plug in your USB Hard Drive.

#Partition your USB Drive
/sbin/fdisk /dev/sdb

# Type in the following commands to erase
# and re-partition usb hard drive 
#(WARNING - HARD DRIVE WILL BE COMPLETELY WIPED): 
p       # list current partitions
# o       # to delete all partitions
# n       # new partition
# p       # primary partition
# 1 (one) # first partition
# <enter> # default start block
# <enter> # default end block #use the whole flash drive
# w       # write new partition to disk

#Format Disk, label as USB
#Assumes hd is /dev/sdb1
mkfs.ext3 -L USB /dev/sdb1

#mount disk
mkdir -p /media/usb
mount /dev/sdb1 /media/usb

#mount after reboot
echo "LABEL=USB /media/usb ext3 rw,noatime 0 0" >> /etc/fstab


#install samba
pacman -Sy samba

#backup existing smb.conf
cd /etc/samba
mv smb.conf smb.conf.original

#download example smb.conf for public share
#no authentication require, everyone has 
#read/write access to / (root$) and usb (/media/usb)

#Edit smb.conf (optional)
nano /etc/samba/smb.conf

#start samba
systemctl start smbd nmbd

#autostart samba on reboot
systemctl enable smbd nmbd

#test from computer: \\pogoplug\root$

#reboot and test

Enable Swapfile (Only if using hard drive)

#This will create a 512MB swap file
#Named "swapfile.img" in /media/usb (usb hd).
dd if=/dev/zero of=/media/usb/swapfile.img bs=1M count=512

mkswap /media/usb/swapfile.img

#You can now turn the swap file on using:
swapon /media/usb/swapfile.img

#You can also turn it off by using:
swapoff /media/usb/swapfile.img

#check if swap is enabled
free

#enable swapfile on reboot
echo "/media/usb/swapfile.img none swap sw 0 0" >> /etc/fstab

#reboot and test
free


Apple AirPlay (aka Shairport) - Play some music from your iOS Device or iTunes through your PogoPlug

Updated 5/14/2013 - I have plans to have a separate blog post regarding setting up the Ultimate Music System - AirPlay, Logitech Media Server/SqueezeBox Server and SqueezeLite, USB Audio configuration and various USB DACs I've tested.

I recommend the Behringer UCA202 Audio Interface. For around $30 this is a decent USB DAC with optical out, which allows you to connect your PogoPlug to your existing high end audio system.

#Install some required packages
pacman -S libao alsa-utils avahi libpulse

#audio fix
echo "use_mmap=no" >> /etc/libao.conf


#Configure alsa asound.conf file
#Try the following two files.

#direct HW playback
#will work for most usb audio cards/DACs#works for c-media chipset, PCM2704
cd /etc
wget https://dl.dropbox.com/u/42238/pogoplug/v2/default/asound.conf

#for the cheap $1-$2 on ebay/amazon which only supports 48Khz
#Bus 001 Device 006: ID 0c76:1607 JMTek, LLC. audio controller
#6911 Chipset (48000 Hz only)

cd /etc
wget https://dl.dropbox.com/u/42238/pogoplug/asound.conf
#download pre-compiled version of shairport
#compiled 4/22/2013
cd /usr/local/bin
wget http://dl.dropbox.com/u/42238/pogoplug/v2/shairport

#make shairport executable

chmod a+x shairport

#or compile shairport on your own
cd /tmp
wget --no-check-certificate https://github.com/abrasive/shairport/tarball/1.0-dev
tar xzf 1.0-dev
cd *shairport*
make
make install

#autostart avahi-daemon
systemctl start avahi-daemon.service
systemctl enable avahi-daemon.service

#start shairport and test
shairport -a Living_Room -v


#Test, Control C to stop

#autostart shairport on reboot
#edit shairport.service file to update AirPlay name
cd /etc/systemd/system

wget http://dl.dropbox.com/u/42238/pogoplug/v2/shairport.service

#start shairport and test
systemctl start shairport
systemctl status shairport

#autostart shairport on reboot
systemctl enable shairport

#reboot and test

#Schedule ShairPort to restart daily
#switch editor to nano
export EDITOR="/usr/bin/nano"

#edit/create crontab
crontab -e

#paste in the below
#restart shairport @ 5AM everyday
00 05 * * * /usr/bin/systemctl restart shairport


#list crontab
crontab -l



Adjusting the volume

#Find name of mixer control
amixer

#Simple mixer control 'Headphone',0
#  Capabilities: pvolume pswitch pswitch-joined
#  Playback channels: Front Left - Front Right
#  Limits: Playback 0 - 38
#  Mono:
#  Front Left: Playback 27 [71%] [-8.26dB] [on]
#  Front Right: Playback 27 [71%] [-8.26dB] [on]

#set volume to 90%
amixer set Headphone 90%


#Troubleshooting commands
lsusb
aplay -L
cat /proc/asound/card0/pcm0p/sub0/hw_params



AirPrint Server - Print to your non-AirPrint enabled printers

#Install CUPS and print drivers

pacman -Sy cups gutenprint pycups python2 avahi 

#link python to python2
ln -s /usr/bin/python2 /usr/bin/python


#For HP Printer Drivers
pacman -S hplip

#For Samsung Printer Drivers
pacman -S splix

#Backup original cupsd.conf

cd /etc/cups
mv cupsd.conf cupsd.conf.org


#download my cupsd.conf
wget http://dl.dropbox.com/u/42238/pogoplug/cupsd.conf

#Start CUPS

systemctl start cups.service


Configure CUPS Printer(s)

Now open up your web browser and go to http://<PogoPlugIPAddress>:631/admin.

This part is YMMV. Not all printers will work.


Click the "Add Printer" Button.

In my case, I am using a Brother HL-2270DW which has built in wireless and supports various printing options - socket, ipp, http, etc. I'm going to use socket (AppSocket/HP JetDirect) which is the same option you would select if you had your USB printer directly connected to your PogoPlug. 


Note that I will not cover USB attached printers at this time but will update the tutorial when I get a chance.

For my wireless printer, the Connection address I'm using is "socket://<PrinterIPAddress>:9100" ( for the record "ipp://<PrinterIPAddress>/pcl_p1" would also work).
Name your printer. Check the "Share This Printer" checkbox (not totally sure if this is required, but for now check it to be safe).Select the Make/Model of your Printer. Basically you are selecting the drivers to use. For my Brother HL-2270DW, I went with "Generic"->"Generic PCL 6/PCL XL Printer".

Click Add Printer.

Set your Default Options.

Print a test page. Maintenance->Print Test Page.

Printing a test page needs to work. If not, you can not continue. Not all printers will work. Try different drivers (or a different printer) if you're having a problem with printing a test page.


Back in the SSH Console

#download avahi airprint script
mkdir -p /opt/airprint
cd /opt/airprint

#this is all one line
wget -O airprint-generate.py --no-check-certificate https://raw.github.com/tjfontaine/airprint-generate/master/airprint-generate.py
#make script executable
chmod 755 airprint-generate.py

#add mime types needed for iOS6
echo "image/urf urf string(0,UNIRAST<00>)" > /usr/share/cups/mime/airprint.types
echo "image/urf application/pdf 100 pdftoraster" > /usr/share/cups/mime/airprint.convs

#autostart avahi-daemon
systemctl start avahi-daemon.service
systemctl enable avahi-daemon.service

#restart cups to pick up new mime types
systemctl restart cups.service

#Generate AirPrint service file
cd /etc/avahi/services
/opt/airprint/airprint-generate.py

#Check for AirPrint-<PrinterName>.service file
ls

#Test AirPrint from iOS Device

#autostart cupsd after reboot

systemctl enable cups.service


As a reference please check out this posting - [Tutorial] Apple AirPrint on TomatoUSB Router


Google CloudPrint - Print over the internet via Chrome Web Browser. Share your printer with friends/family.

pacman -Sy git

#download cloudprint
mkdir /opt
cd /opt
git clone git://github.com/armooo/cloudprint

#build and install cloudprint
cd /opt/cloudprint
python setup.py build
python setup.py install



#Run once to create auth files
cloudprint

#enter your google account email and password
#Google username:
#Password:

#Test print from your Chrome web browser
#Control+C to close cloudprint

#To run as daemon
pacman -S yaourt

#No need to edit anything
yaourt -ASy python2-daemon

#setup cloudprint to run on startup via systemd service
cd /etc/systemd/system
wget http://dl.dropbox.com/u/42238/pogoplug/v2/cloudprint.service
systemctl enable cloudprint.service

#Reboot and test CloudPrint

#Clear google credentials/auth files
#rm /root/.cloudprintauth
#rm /root/.cloudprintsaslauth

Cloudprint is very fragile. If you're having start-up or printing issues try the following steps.

- Clear your Google CloudPrint Print Queue - https://www.google.com/cloudprint/#jobs
- Delete your stored credential and reboot and start over.

One more thing regarding CloudPrint, my recommendation is to set up a new Google Account dedicated just for CloudPrint. Use this account for the above cloudprint login, and then share your printer(s) with your main account. I'm a little paranoid of having my email authentication stored on my router (even though its hashed or whatever).


Re-install my.pogoplug.com service (original software) 

Please go here for latest instructions
http://archlinuxarm.org/forum/viewtopic.php?f=18&t=3343 (Thanks moonman!)

pacman -U http://dl.dropbox.com/u/15043728/pogoplug-3.3.0-1-arm.pkg.tar.xz

#edit configuration file
#edit vfsdir0
#add svcid (ID) from the bottom of your PogoPlug (no dashes)
nano /etc/pogoplug.conf

##example below: vfsdir<number>=<name>,<path>
#vfsdir0=PogoPlug_USB,/media/usb
#installdir=/usr/local/cloudengines
##datadir=.
#datadir=.
#nohotplug=1
##use the ID from the bottom of your PogoPlug (no dashes)
#svcid=ASDFFGSASASADASDASDASDA


#note /etc/pogoplug.conf will be copied to
#/usr/local/cloudengines/hbplug.conf on service startup

systemctl enable pogoplug.service

#reboot and register @ my.pogoplug.com


Enable uPNP/DNLA (my.pogoplug.com)

The original my.pogoplug.com software has a (limited) built-in uPNP/DNLA server.

On my.pogoplug.com -> Settings -> Media












Wireless Configuration
Last Updated: 5/16/2013

The following USB Wireless Adapters are Plug and Play:
Alfa AWUS036H (RTL8187)
Etekcity High Power 802.11 B/N/G 300M USB Wireless 1000mw Wifi Network Adapter with Dual Antenna (RT3072)

This USB Adapter isn't Plug and Play:
Airlink101 AWLL5099


NETCFG has been replaced by NETCTL
https://wiki.archlinux.org/index.php/Netctl

#disable legacy netcfg auto start
systemctl disable net-auto-wired
systemctl disable net-auto-wireless

pacman -Sy wireless_tools netctl ifplugd wpa_actiond

#Copy Ethernet DHCP profile
cp /etc/netctl/examples/ethernet-dhcp /etc/netctl/eth0dhcp

#Connect to wireless network and create wireless profile
cd /etc/netctl
wifi-menu


#check if wireless profile got created
#you should see wlan0-SSIDName
ls /etc/netctl

#Auto Connect to Wireless Network
systemctl enable netctl-auto@wlan0.service

#Auto Connect to Wired Network
systemctl enable netctl-ifplugd@eth0.service

#reboot and test
ifconfig
iwconfig
Motion WebCam (work in progress)

pacman -S motion x264 fswebcam
mkdir -p /var/run/motion

#turn off localhost access only
sed -i 's:webcam_localhost on:webcam_localhost off:' /etc/motion/motion.conf

#adjust resolution to 640x480
sed -i 's:width 320:width 640:' /etc/motion/motion.conf
sed -i 's:height 240:height 480:' /etc/motion/motion.conf

#A little hack to get motion to detect webcam correctly

fswebcam -r 320x240 -d /dev/video0 -v /dev/null

#Start motion and access webcam @ http://IPAddress:8081
motion


Transmission, Sabnzbd, SickBeard and CouchPotato

Requires a swap partition or swapfile - 1GB recommended.

pacman -Sy sabnzbd sickbeard-git couchpotato-git transmission-cli


#start and stop all apps to create config files
systemctl start transmission sabnzbd couchpotato sickbeard

#give them some time to startup
sleep 10

#check status
systemctl status transmission sabnzbd couchpotato sickbeard

#shut them down
systemctl stop transmission sabnzbd couchpotato sickbeard

#transmission - allow login from any computer
cd /var/lib/transmission/.config/transmission-daemon/

sed -i 's^"rpc-whitelist-enabled": true^"rpc-whitelist-enabled": false^' ./settings.json

#sabnzbd - allow login from any computer
cd /opt/sabnzbd
sed -i 's^host = localhost^host = 0.0.0.0^' ./sabnzbd.ini

#start all
systemctl start transmission sabnzbd couchpotato sickbeard


# sabnzbd - http://PogoPlugIP:8080
# couchpotato - http://PogoPlugIP:5050/
# sickbeard - http://PogoPlugIP:8081/
# transmission - http://
PogoPlugIP:9091

TimeMachine Backup
Configure Netatalk in Arch Linux for Time Machine Goodness


OpenVPN (Client)

As a reference please check out my other two tutorials on OpenVPN:
[Tutorial - 30 Minutes or Less] Site to Site VPN with TomatoUSB and OpenVPN
[Tutorial] CentOS 6 OpenVPN Client - Connecting to Existing Site to Site VPN (TomatoUSB)



pacman -S openvpn


#generate keys on CA and copy them over
mkdir -p /etc/openvpn/keys

#copy sample client.conf to /etc/openvpn
cp /usr/share/openvpn/examples/client.conf /etc/openvpn

#edit openvpn client.conf
nano /etc/openvpn/client.conf

#Update the following lines
#remote vpnserverIPAddress 1194
#ca /etc/openvpn/keys/ca.crt
#cert /etc/openvpn/keys/pogoplug.crt
#key /etc/openvpn/keys/pogoplug.key



#start VPN manually to test
openvpn --config /etc/openvpn/client.conf



#autostart OpenVPN client on reboot
systemctl enable openvpn@client.service



OwnCloud (nginx php-fpm sqlite)

Note - I'm no longer actively working on owncloud. The default PogoPlug software works well enough for my needs. There is a bug with using a self sign certificate (expect a WebDav error). You'll need to mount a different disk for your owncloud data folder - /srv/http/owncloud/data (I was not able to get owncloud working if I used a different data folder path).

pacman -Sy owncloud nginx php-fpm sqlite3 php-sqlite

#copy owncloud files

cd /srv/http
cp -R /tmp/owncloud .

#update owner

chown http:http /srv/http/owncloud 
chown http:http /srv/http/owncloud/config
chown http:http /srv/http/owncloud/apps


#uncomment out required modules
sed -i 's^;extension=gd.so^extension=gd.so^' /etc/php/php.ini
sed -i 's^;extension=xmlrpc.so^extension=xmlrpc.so^' /etc/php/php.ini
sed -i 's^;extension=zip.so^extension=zip.so^' /etc/php/php.ini
sed -i 's^;extension=iconv.so^extension=iconv.so^' /etc/php/php.ini
sed -i 's^;extension=sqlite3.so^extension=sqlite3.so^' /etc/php/php.ini
sed -i 's^;extension=pdo_sqlite.so^extension=pdo_sqlite.so^' /etc/php/php.ini



#Maximum execution time of each script, in seconds
sed -i 's^max_execution_time = 30^max_execution_time = 300^' /etc/php/php.ini



#Maximum amount of time each script may spend parsing request data.
sed -i 's^max_input_time = 60^max_input_time = 600^' /etc/php/php.ini



#Maximum allowed size for uploaded files.
sed -i 's^upload_max_filesize = 2M^upload_max_filesize = 100M^' /etc/php/php.ini



#Maximum size of POST data that PHP will accept.
sed -i 's^post_max_size = 8M^post_max_size = 400M^' /etc/php/php.ini


#Maximum amount of memory a script may consume
sed -i 's^memory_limit = 128M^memory_limit = 512M^' /etc/php/php.ini



#http://doc.owncloud.org/server/5.0/admin_manual/installation/installation_others.html#nginx-configuration

#backup config and download working nginx.conf
cd /etc/nginx 

mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.original
wget http://dl.dropbox.com/u/42238/pogoplug/nginx.conf



#Configure SSL
#http://wiki.nginx.org/HttpSslModule


#create folder to store certs
mkdir -p /etc/nginx/certs
cd /etc/nginx/certs

#Now create the server private key

#you'll be asked for a passphrase
openssl genrsa -des3 -out pogoplug.key 1024

#Create the Certificate Signing Request (CSR):
openssl req -new -key pogoplug.key -out pogoplug.csr

#Remove the necessity of entering a 
passphrase 
#for starting up nginx with SSL using the above private key:
cp pogoplug.key pogoplug.key.org

openssl rsa -in pogoplug.key.org -out pogoplug.key

#sign the certificate using the above private key and CSR
openssl x509 -req -days 3650 -in pogoplug.csr -signkey pogoplug.key -out pogoplug.crt


#start nginx and php-fpm
systemctl start php-fpm
systemctl start nginx

#autostart nginx and php-fpm after reboot
systemctl enable php-fpm
systemctl enable nginx


#Finish configuration via https://PogoPlugIPAddress/owncloud/ or https://pogoplug/owncloud




Backup and Restore

Having a backup is always a good idea and is highly recommended. Its quick and simple and will save you the hassle of re-installation from scratch if anything ever happens to your flash drive (very common) or if you want to duplicate/clone your setup to another PogoPlug.

Offline Backup (Recommended) - These two methods, Disk Image and Tarball, requires unplugging the usb drive you want to backup and plugging it into another linux computer or VM, another pogoplug running alarm, or same pogoplug running alarm using a different usb flash drive.

Credit/Reference

1) Disk Image

#assumes /dev/sdb is the flash drive you want to backup
dd if=/dev/sdb of=/savetopath/pogoplug.e02.rootfs.backup.img bs=4M


#restore, swap if (in) and of (out)
dd if=/savetopath/pogoplug.e02.rootfs.backup.img of=/dev/sdb

2) Tarball

#assumes the flash drive you want to backup is /dev/sdb1

mkdir /tmp/usb
mount /dev/sdb1 /tmp/usb

#backup to root
tar -cvzf /pogoplug.e02.rootfs.backup.tar.gz ./

#restore
cd /tmp/usb
tar -xzvf /pogoplug.e02.rootfs.backup.tar.gz

Online Backup using rsync
http://mouhassan.wordpress.com/2012/06/30/backing-up-arch-linux-arm-alarm-on-pogoplug/

-------------------------------------------------------------------

That's it for now.

Please leave a comment if this is helpful or if you run into any issues. Thanks

Tuesday, March 5, 2013

[Tutorial] Apple AirPrint on TomatoUSB Router


In this tutorial, I'm going to show you how to setup Apple AirPrint Server on a router running TomatoUSB firmware. This will allow you to print from your iOS device (iPhone, iPod, iPad) to your non-AirPrint-enabled printer through your router. If you're familiar with AirPrint Activator or FingerPrint, this solution is similar, except you don't have to keep your power hungry MAC/PC running 24/7.

Before I start, I want to give special thanks to @davygravy on the TomatoUSB.org forum. He was the one that ultimately made this all possible by compiling, re-compiling and fixing all the required packages.

Another thing, if you're familiar with my Tutorial on Apple AirPlay on TomatoUSB Router, these two tutorials (currently) are not compatible with each other. Meaning, you either go with AirPrint or AirPlay on your TomatoUSB Router, NOT BOTH. This is because the AirPrint tutorial uses Entware and this tutorial uses Optware, which isn't compatible with each other. Hopefully we're get this issue resolved in the near future.

Note: this tutorial is a work in progress (but working). I'll be updating and flushing out the details as time permits. Please excuse the typos and bad grammar.

YMMV (Your Mileage May Vary) depending on your Printer model.

What you'll need:

  1. Router with TomatoUSB installed*
  2. USB Flash Drive >1GB (will be completely wiped)
  3. USB or Wireless/Network Printer
* If you're looking for a recommendation on a router for this project,  please check this post - [Tutorial] Apple AirPlay on TomatoUSB Router. You can pick up a router as low as $24.

Outline of Steps:

  1. Partition and Format USB Flash Drive*
  2. Install Optware
  3. Download and Install Required Packages
  4. Start CUPS and Configure Printer(s)
  5. Generate AirPrint Service File
  6. Startup DBus, Avahi and CUPS
  7. Test Print
  8. Configure the router so that everything works after a reboot
  9. CloudPrint (Bonus Content)

*Note that your USB Flash Drive will be completely wiped clean.


1) Partition and Format USB Drive:

Plug in your USB drive and connect to your router via SSH (Putty) and execute the following commands:

#Partition your usb flash drive 
umount /dev/sda1
fdisk /dev/sda

Type in the following commands to create a primary partition on your USB Flash drive
# p # list current partitions
# o # to delete all partitions
# n # new partition
# p # primary partition
# 1 (one) # first partition
# <enter> # default start block
# <enter> # default end block #use the whole flash drive
# w # write new partition to disk


#format newly created partition
#label disk as 'optware' case sensitive
umount /dev/sda1
mke2fs -j -L optware /dev/sda1

#mount partition as /opt

mount /dev/sda1 /opt

#Make sure /opt is properly mounted on a reboot.
echo "LABEL=optware /opt ext2 defaults 1 1" >> /etc/fstab
nvram setfile2nvram /etc/fstab
nvram commit


2) Install Optware

#Install Optware from scratch. 
#Assumes drive is formated and mounted as /opt already
cd /tmp
wget http://tomatousb.org/local--files/tut:optware-installation/optware-install.sh -O - | tr -d '\r' > /tmp/optware-install.sh
chmod +x /tmp/optware-install.sh
sh /tmp/optware-install.sh

3) Download and Install Required Packages

#create a folder to store packages

mkdir -p /opt/ipkgs
cd /opt/ipkgs

#download packages. 

#cut/paste this whole section
wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/dbus_1.2.16-2_mipsel.ipk
wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/cups_1.5.4-1_mipsel.ipk
wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/poppler_0.12.4-1_mipsel.ipk
wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/py26-cups_1.9.62-1_mipsel.ipk
wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/ghostscript_8.71-3_mipsel.ipk
wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/hplip_3.11.7-1_mipsel.ipk
wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/gutenprint_5.2.9-1_mipsel.ipk

wget http://dl.dropbox.com/u/42238/TomatoUSB/Optware/cups-driver-gutenprint_5.2.9-1_mipsel.ipk

#install packages. this may take awhile. 

#cut/paste this whole section
ipkg install /opt/ipkgs/dbus_1.2.16-2_mipsel.ipk
ipkg install /opt/ipkgs/cups_1.5.4-1_mipsel.ipk
ipkg install /opt/ipkgs/poppler_0.12.4-1_mipsel.ipk

ipkg install /opt/ipkgs/py26-cups_1.9.62-1_mipsel.ipk
ipkg install /opt/ipkgs/ghostscript_8.71-3_mipsel.ipk
ipkg install /opt/ipkgs/gutenprint_5.2.9-1_mipsel.ipk
ipkg install /opt/ipkgs/cups-driver-gutenprint_5.2.9-1_mipsel.ipk

#install hplip if you have a HP printer
#ipkg install /opt/ipkgs/hplip_3.11.7-1_mipsel.ipk


#install splix for Samsung printers
#ipkg install splix

#Color profiles for Samsung (untested)
#cd /opt/share/cups/model/samsung
#wget http://splix.ap2c.org/samsung_cms.tar.bz2
#tar xvjf samsung_cms.tar.bz2
#rm samsung_cms.tar.bz2



4) Start CUPS and Configure Printer(s)

#start cups
cupsd

Now open up your web browser and go to http://<RouterIPAddress>:631/admin (http://192.168.1.1:631/admin).

Click on "Manage Printers"->"hp990c"
Administration->Delete Printer (this printer was accidentally included)
If you're prompted for authentication, enter in root and your password.

Go back to Administration->Add Printer

In my case, I am using a Brother HL-2270DW which has built in wireless and supports various printing options - socket, ipp, http, etc. I'm going to use socket (AppSocket/HP JetDirect) which is the same option you would select if you had your USB printer directly connected to your router. Make sure you enable "USB Printer Support" in the Tomato GUI if you're using a USB attached printer.

For my wireless printer, the Connection address I'm using is "socket://<PrinterIPAddress>:9100" ( for the record "ipp://<PrinterIPAddress>/pcl_p1" would also work).

For a USB attached printer, the Connection address would be: "socket://<RouterIPAddress>:9100" (i.e., socket://192.168.1.1:9100)

Name your printer. Check the "Share This Printer" checkbox (not totally sure if this is required, but for now check it to be safe).

Select the Make/Model of your Printer. Basically you are selecting the drivers to use. For my Brother HL-2270DW, I went with "Generic"->"Generic PCL 6/PCL XL Printer".

Click Add Printer.

Set your Default Options.

Print a test page. Maintenance->Print Test Page.

Printing a test page needs to work. If not, you can not continue. Not all printers will work. Try different drivers (or a different printer).

5) Generate AirPrint Service File

Back in your SSH console session, execute the following:

#Stop CUPS
killall cupsd

#create some needed mime types for AirPrint and iOS6
echo "image/urf urf string(0,UNIRAST<00>)" > /opt/share/cups/mime/airprint.types


echo "image/urf application/pdf 100 pdftoraster" > /opt/share/cups/mime/airprint.convs

#Start CUPS
cupsd

#make airprint folder

mkdir -p /opt/airprint
cd /opt/airprint

#install wget-ssl (for https)
ipkg install wget-ssl

#Download airprint-generate.py
#this is all one line
/opt/bin/wget --no-check-certificate https://raw.github.com/tjfontaine/airprint-generate/master/airprint-generate.py

#set the script to be executable
chmod 755 ./airprint-generate.py

#Generate airprint service file
cd /opt/etc/avahi/services
python2.6 /opt/airprint/airprint-generate.py

#There should be a
#AirPrint-<PrinterName>.service file listed
ls

#Stop CUPS
killall cupsd


6) Startup DBus, Avahi (aka Bonjour) and CUPS

#Required for Avahi and dbus
#Ignore the warning
adduser avahi
addgroup netdev

#delete orphan pid files in case they exist
rm /opt/var/run/dbus/pid

rm /opt/var/run/avahi-daemon/pid

#start dbus before avahi
/opt/etc/init.d/S20dbus start

#start avahi (aka bonjour)
avahi-daemon -D

#Start CUPS
cupsd

#verify that your printer is being advertise
avahi-browse --terminate --resolve _ipp._tcp



7) Test Print

From your iPhone/iPad/iPod, do a test print.

8) Configure the router so that everything works after a reboot

Go to USB and NAS -> USB Support (http://192.168.1.1/nas-usb.asp).
In the "Run after mounting" section add the following:


#Required for avahi and dbus
adduser avahi
addgroup netdev

#delete orphan pid files in case they exist
rm /opt/var/run/dbus/pid

rm /opt/var/run/avahi-daemon/pid

#start dbus before avahi
/opt/etc/init.d/S20dbus start

#start avahi (aka bonjour)

avahi-daemon -D

#Start CUPS
cupsd


In the "Run before unmounting" section add the following:

#run before unmounting
killall cupsd
avahi-daemon -k
/opt/etc/init.d/S20dbus stop


You're done. Enjoy!

9) Google CloudPrint (Bonus Content - Work In Progress)

ipkg install git
cd /opt

git clone git://github.com/armooo/cloudprint

cd /opt/cloudprint
python2.6 setup.py build
python2.6 setup.py install

#Run once to create credential files
#give it about a minute to start up
/opt/local/bin/cloudprint

#enter your google account email and password
#Google username:
#Password:

#test print from your Chrome browser
#Control+C to close cloudprint

#copy your cloudprint authentication files to /opt
cp /tmp/home/root/.cloudprintauth /opt/cloudprint
cp /tmp/home/root/.cloudprintsaslauth /opt/cloudprint


To have cloudprint start automatically on reboot. Go to USB and NAS -> USB Support (http://192.168.1.1/nas-usb.asp). In the "Run after mounting" section add the following:

#copy back cloudprint authentication files to /tmp
cp /opt/cloudprint/.cloudprintauth /tmp/home/root/ 
cp /opt/cloudprint/.cloudprintsaslauth /tmp/home/root/
/opt/local/bin/cloudprint &

In the "Run before unmounting" section add the following:

killall cloudprint

Cloudprint is very fragile. If you're having start-up or printing issues try the following steps.

- Clear your Google CloudPrint Print Queue - https://www.google.com/cloudprint/#jobs
- Delete your stored credential and reboot and start over.

One more thing regarding CloudPrint, my recommendation is to set up a new Google Account dedicated just for CloudPrint. Use this account for the above cloudprint login, and then share your printer(s) with your main account. I'm a little paranoid of having my email authentication stored on my router (even though its hashed or whatever).

If you get AirPrint working with your printer, please leave a comment with your printer model and drivers used. This will help other users. Thanks

Please leave a comment with any questions or feedback. Thanks


[Update 4/9/2013] Please check out my PogoPlug Tutorial below. A PogoPlug running Arch Linux ARM is the perfect companion to your TomatoUSB Router. I highly recommend that you run AirPlay/AirPrint on the PogoPlug versus your TomatoUSB router.

[Tutorial] - PogoPlug E02 with Arch Linux ARM - NAS (Samba4), AirPlay, AirPrint, Google CloudPrint

Tuesday, February 19, 2013

[Tutorial - 30 Minutes or Less] Site to Site VPN with TomatoUSB and OpenVPN

The intent of the tutorial is to provide you with the quickest and least painful step-by-step process for setting up a secure, yet simple, Site to Site VPN between two locations using TomatoUSB and OpenVPN, allowing resources to be accessed and shared from both locations (resources behind the routers will be accessible to each other).

A Site to Site VPN can be setup between your home and business, two office locations, or between family members. Some common use cases would be to share files, printers, provide technical support (RDP/VNC),  view webcams (without opening webcam to the internet) and my favorite, as a mean for secure offsite backups.

By going through this tutorial you'll also learn:
    - How to setup a Certificate Authority on your router and generate Certificates and Keys
    - Setup (free) Dynamic DNS
    - A little bit on expanding the setup to include Client to Site VPN
    - How to enable SFTP on your router for secure access to certificates and keys

Here's a video walk-through of the whole process (24 minutes!):




What you'll need:
  1. Two routers with Tomato already installed.*
    1. The OpenVPN Server router should be running TomatoUSB (with a USB port)
    2. The OpenVPN Client router can run regular Tomato (no USB port required)
  2. USB Flash Drive >=1GB (will be completely wiped)
  3. Publicly accessible IP address for OpenVPN Server router.
If you're looking for a recommendation on which router to use for this project, please check out the Belkin routers I mention in this post, [Tutorial] Apple AirPlay on TomatoUSB Router.

Outline of Steps

1) Setup OpenVPN Server on Site A Router
        a) Setup Entware (package manager)
        b) Generate RSA Certificates and Keys
        c) Configure OpenVPN Server
        d) Setup Port Fowarding for OpenVPN Server
        e) Setup Free Dynamic DNS Service
        f) Start OpenVPN Server
2) Setup OpenVPN Client on Site B Router
     
        a) Configure OpenVPN Client
3) That's it! Enjoy.

Network Info

Site A
     OpenVPN Server
     Internal network/subnetmask - 192.168.1.0/255.255.255.0
     External Public IP Address

Site B
     OpenVPN Client
     Internal network/subnetmask - 192.168.2.0/255.255.255.0
     External Public IP Address

-------------------------------------------------------------------------------
LETS GET STARTED!

Setup OpenVPN Server on Site A Router

Plug in USB flash drive. Make sure the router has internet access.
Connect via SSH into router. For Windows, I recommend Putty.
Log in with username of root and password of admin.

Execute the following commands:

#Partition your usb flash drive
umount /dev/sda1
fdisk /dev/sda


Type in the following commands to create a primary partition on your USB Flash drive
# p       # list current partitions
# o       # to delete all partitions
# n       # new partition
# p       # primary partition
# 1 (one) # first partition
# <enter> # default start block
# <enter> # default end block #use the whole flash drive
# w       # write new partition to disk

#format newly created partition
#label disk as 'optware' case sensitive

umount /dev/sda1
mke2fs -j -L optware /dev/sda1


Install Entware (a package manager that allows you to install additional software on your router)

#mount the new disk partition
mount /dev/sda1 /opt
cd /opt
wget http://wl500g-repo.googlecode.com/svn/ipkg/entware_install.sh
sh ./entware_install.sh


#Make sure /opt is properly mounted on a reboot.
echo "LABEL=optware /opt ext2 defaults 1 1" >> /etc/fstab
nvram setfile2nvram /etc/fstab 
nvram commit


Install openvpn-easy-rsa

opkg install openvpn-easy-rsa nano

Setup working folder for openvpn-easy-rsa (It's recommended that you cut/paste everything up to Setup CA, into your console window to prevent any error/typos)


#Create a working folder for easy-rsa
rm -rf /opt/openvpn-easy-rsa
mkdir /opt/openvpn-easy-rsa


#copy files to working directory
cd /opt/openvpn-easy-rsa
cp /opt/sbin/sign-req .
cp /opt/sbin/build-req .
cp /opt/sbin/inherit-inter .
cp /opt/sbin/revoke-full .
cp /opt/sbin/clean-all .
cp /opt/sbin/build-ca .
cp /opt/sbin/pkitool .
cp /opt/sbin/build-dh .
cp /opt/sbin/build-key-pass .
cp /opt/sbin/build-key-pkcs12 .
cp /opt/sbin/list-crl .
cp /opt/sbin/whichopensslcnf .
cp /opt/sbin/build-key-server .
cp /opt/sbin/build-key .
cp /opt/etc/easy-rsa/openssl-1.0.0.cnf .
cp /opt/sbin/build-inter .
cp /opt/sbin/build-req-pass .

#copy vars files to working folder
cp /opt/etc/easy-rsa/vars /opt/openvpn-easy-rsa

#Set working directory and reduce key_size to 1024 in vars file

cd /opt/openvpn-easy-rsa
sed -i 's:`pwd`:/opt/openvpn-easy-rsa:' ./vars
sed -i 's:KEY_SIZE=2048:KEY_SIZE=1024:' ./vars

#update PATH to pick up correct openssl (save a reboot)

#correct = /opt/bin/openssl
PATH=/opt/bin:$PATH


Setup Certificate Authority (CA)

#Setup and initialize environment
cd /opt/openvpn-easy-rsa
source ./vars
./clean-all

#Select Default for All, Keep Hitting <Enter> (8 times)
./build-ca


Generate Diffie Hellman parameters (DH file)

./build-dh

Generate Certificate and Key for the OpenVPN Server router at Site A with Common Name [CN] of "OpenVPNServer".

#Generate Cert/Key for Site2SiteClient
#<Enter> 10 times to take default value
#Followed by two 'y' <Enter> when asked to sign and commit
./build-key-server OpenVPNServer

Generate Certificate and Key for the OpenVPN Client router Site B with Common Name [CN] of "Site2SiteClient". The "Common Name" isn't really "common". Make sure its unique for all your clients.

#Generate Cert/Key for Site2SiteClient
#<Enter> 10 times to take default value
#Followed by two 'y' <Enter> when asked to sign and commit
./build-key Site2SiteClient

Output Certificate and Key to console - cut/paste into text file for later use.


cd /opt/openvpn-easy-rsa/keys
cat ./ca.crt
cat ./Site2SiteClient.crt
cat ./
Site2SiteClient.key

Create a new text file on your computer and name it "ClientRouterKeys.txt" and cut and paste in the output of the three cat commands above. You'll need this file to setup the OpenVPN Client Router later in the tutorial.

That's it for the SSH Console. The rest of the configuration will be done via a web browser. If you run into any issues with the above commands, take a look at my console output. Hopefully it will help.

Configure OpenVPN Server

Open your favorite browser and connect to your router and go to VPN Tunneling -> OpenVPN Server (http://192.168.1.1/vpn-server.asp).

On "Server 1 -> Basic" Tab, check "Start with WAN". Leave everything else as default.

OpenVPN Server Configuration Server 1->Basic Screen should look like the following:



Change to the Advanced Tab

Check "Respond to DNS"
Check "Manage Client-Specific Options"
Check "Allow Client<->Client"
Check "Enable"
Type in "Site2SiteClient" under "Common Name"
Type in "192.168.2.0" under Subnet
Type in "255.255.255.0" under Netmask
Check Push
Click 'Add' button. (pushes routes to the client router and add route to server router. No need for router/iptable commands)
In the "Custom Configuration" box, paste in the following (saves us from pasting in the certs/key in the Keys Tab):

ca /opt/openvpn-easy-rsa/keys/ca.crt
cert /opt/openvpn-easy-rsa/keys/OpenVPNServer.crt
key /opt/openvpn-easy-rsa/keys/OpenVPNServer.key
dh /opt/openvpn-easy-rsa/keys/dh1024.pem

[Save]

OpenVPN Server Configuration Server 1->Advanced Screen should look like the following:



Setup Port Fowarding for OpenVPN Server

Forward UDP Port 1194 to your router internal IP @192.168.1.1

Go to Port Forwarding -> Basic (http://192.168.1.1/forward-basic.asp

Select UDP in the Proto dropdown box.
Type "1194" in the "Ext Ports" and "Int Port".
Type "192.168.1.1" for the "Int Address".
Type "OpenVPN Server" as the Description.
Click the "Add" button
[Save]



Setup Free Dynamic DNS Service (http://freedns.afraid.org/)

If you don't have a public static IP (most don't), you'll need to setup DDNS so your OpenVPN client(s) can find your OpenVPN server.

Go to http://freedns.afraid.org and setup an account and then setup a subdomain.

I'm using "OpenVPNServer.mooo.com" (use something else). We'll need this subdomain during the OpenVPN Client setup.




On the left hand side, select "Dynamic DNS" or go to http://freedns.afraid.org/dynamic

Find the subdomain you just created and right click on the "Direct URL" link and select "Copy link address"


On your router, go to Basic -> DDNS (http://192.168.1.1/basic-ddns.asp)

For Dynamic DNS 1, select "FreeDNS(afraid.org)" in the "Service" dropdown.
Paste in the URL you copied in the previous step (note that the URL will change to a token)
Check "Force next update"
Change the "Auto refresh every" to 7 or something lower than 30.
[Save]
Last Result should say Update Successfully.



Start OpenVPN Server

Go to VPN Tunneling -> OpenVPN Server (http://192.168.1.1/vpn-server.asp).

On "Server 1 -> Status" Tab, click the "Start Now" button. Give it a few seconds and click on the "Refresh Status" link.

If you see the following, then the OpenVPN Server has started successfully. Congratulations we're almost there. Note that the button will change to "Stop Now". If the button remains as "Start Now", we have a problem. Go back and review the instructions.



Configuration of Site A Router is complete. Go ahead and reboot the router and verify that OpenVPN Server started properly.

Let's move on to setting up your Site B Router.

Setup OpenVPN Client on Site B Router

Configure OpenVPN Client

At Site B, open up your browser and go to VPN Tunneling -> OpenVPN Client (http://192.168.2.1/vpn-client.asp). Go to Client 1 -> Basic.

Type in the Dynamic DNS address (subdomain) you setup for your Site A router in the "Server Address" field. In my example,  "OpenVPNServer.mooo.com"
Uncheck the "Connect NAT on tunnel"
Check "Start with WAN"
[Save]




Nothing has to be changed on the Client 1 -> Advanced Tab

Open up the Client 1 -> Keys Tab.

Open up "ClientRouterKeys.txt" file you created earlier in the tutorial and cut/paste the certificates and key into the appropriate field.

ca.crt in the Certificate Authority box
Site2SiteClient.crt in the Client Certificate box
Site2SiteClient.key in the Client Key box

Don't forget to [Save].






Your done with the configuration. The moment of truth, on the Client 1 -> Status Tab, Click "Start Now"

Wait a few seconds and click on the "Refresh Status" link. Hopefully you'll see some bytes in the Value column.



From Site B, you should now be able to access Site A network resources and vice-versa.

Lets give the VPN a quick test. Still connected to Site B, open up the OpenVPN Server Configuration page on your Site A router @ http://192.168.1.1/vpn-server.asp. Hopefully you can see a successfully status page like the one below:



That's it!! Enjoy.

Client to Site VPN

You should easily be able to add additional OpenVPN Clients (for Client to Site VPN) by generating additional RSA Certs/Key on your OpenVPN Server Router.

#Setup and initialize environment
cd /opt/openvpn-easy-rsa
source ./vars

./build-key Zoe-Laptop
./build-key Landon-Laptop

#Install SFTP so you can securely access your keys
#Location of keys = /opt/openvpn-easy-rsa/keys
#Connect as root
opkg install openssh-sftp-server

[Tutorial] CentOS 6 OpenVPN Client - Connecting to Existing Site to Site VPN

Troubleshooting and FAQ:

- Review my console output
- Watch my walk-through video
- Make sure the time is correct on both routers (NTP is setup, watch video)
- Check the logs
- Restore Default Configuration and start fresh (backup your current config, just in case).
        Erase all data in NVRAM memory (thorough) @ http://192.168.1.1/admin-config.asp
     


Special Thanks to Shibby for the excellent firmware, the Entware Team, and Wasaga Computer's for their excellent blog, which is the original tutorial I used to successfully setup my first Site to Site VPN using TomatoUSB.

If you have any issues, have any questions or notice any mistakes, please don't hesitate to leave a comment (anonymously if you want). Your feedback will help me improve the tutorial and keep it up to date. Thank you.