Weekend Project: Part 2 – Configuring a VPN on a Raspberry Pi

Following on from my previous post I will be setting up a VPN on my Raspberry Pi with an aim to better protect my online privacy with a VPN and Pi-hole. Having this setup will allow me to connect various household devices to the Raspberry Pi which will then pass traffic though the VPN. To allow connections we must make sure the Pi has a static IP address.

To set a static IP address we must add the address we want to the /etc/network/interfaces file on the Pi.

Add the address you wish your Pi to have in my case I chose for gateway specify your gateway normally this is the address you us to access your router.

auto eth0
iface eth0 inet static

Lets start getting the packages we will need to configure our VPN by running the below;

paz@raspberrypi:~ $ sudo apt install openvpn curl iptables-persistent python-requests -y

Next we will begin configuring the VPN. For my VPN provider I use PrivateVPN. They are well respeceted, reasnably priced and keep no logs what so ever.

Download PrivateVPN’s openvpn files to your Raspberry Pi with the below commands;

paz@raspberrypi:/etc/openvpn $ sudo wget https://privatevpn.com/client/install.sh
paz@raspberrypi:/etc/openvpn $ sudo su -
root@raspberrypi:~# cd /etc/openvpn
root@raspberrypi:/etc/openvpn# ./install.sh

Running install.sh prompts you for username/password and creates the a VPN connection on your Pi that can be used on your Pi.

Edit the file /etc/openvpn/privatvpn.conf with the details of the PrivateVPN exist point you wish to connect to PrivateVPN provides a script to allow you to start the VPN called privatvpn. After install this file is located at /usr/bin/privatvpn. Add this file location to /etc/rc.local which will ensure that the VPN starts on startup should your Pi reboot or require a restart.

Weekend Project: Part 1 – Securing a Raspberry Pi

Recently I dug out the old Raspberry Pi with the aim of using it as a VPN and a DNS backhole. I have always hand a handle on my privacy online but since looking up a new office chair online last week Facebook has provided me with an onslaught of ads for various office chairs, normally I brush this off tracking cookies never really bother me to much but, for some reason this got me triggered. So this weekend I will be turning my Raspberry Pi into a VPN and DNS black hole. The Raspberry Pi will sit on my home network, any devices phone’s, laptops, PC’s etc can be configured to send traffic through the Pi and then out to the internet fully encrpted.

First things first is down download the latest version of Raspbian, you can find it here : https://www.raspberrypi.org/downloads/raspbian/

I am pretty well versed in a Linux/Unix command line and am comfertable in my Linux knowlage to know the various tools, where they are and if they are not present where to get them so, I went for the Raspian Lite image just to keep things as lean as possible.

Tip: If you plan to run your Pi as a headless server, after writing the Raspbian image to an SD Card create a file called ‘ssh’ (file can be empty) on the card to enable ssh on first boot. This used to be enabled by default but a recent change due to worries of attackers high jacking un-secure Raspberry Pi’s prompted the folks over an Pi HQ to turn SSH as default. This tip saves you having to connect a monitor, keyboard & mouse to your Pi just to turn on SSH.

First Things First

At this point I assume you have your Raspberry Pi powered on, to find you Pi’s IP address you can look up your router to see whats connected or try to ping raspberrypi.local. Once you have the IP you can ssh using Putty or Terminal with the following command;

ssh -l pi

Defualt password for pi user is raspberry

Change pi users password

At the end of this guide we will delete the pi user from the system but first things first lets change that default password. Just type the below;

pi@raspberrypi:~ $ passwd
Changing password for pi.
Current password:
New password:
Retype new password:
passwd: password updated successfully

Now that the password has been changed we will update the Pi so we are running the latest and greatest. The example below shows the command to run, although my Pi is already updated so it shows as no updates, expect this to take 10-15min download and install updates on your Pi.

pi@raspberrypi:~ $ sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get dist-upgrade
Hit:1 http://raspbian.raspberrypi.org/raspbian buster InRelease
Hit:2 http://archive.raspberrypi.org/debian buster InRelease
Reading package lists… Done
Reading package lists… Done
Building dependency tree
Reading state information… Done
Calculating upgrade… Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Reading package lists… Done
Building dependency tree
Reading state information… Done
Calculating upgrade… Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Now we have an up-to-date system lets create a new user and remove the default pi user. A new user can be created with the useradd comand. We will set a password for the new user.

pi@raspberrypi:~ $ sudo useradd paz
pi@raspberrypi:~ $ sudo usermod -a -G adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,gpio,i2c,spi paz

pi@raspberrypi:~ $ sudo passwd paz
New password:
Retype new password:
passwd: password updated successfully
pi@raspberrypi:~ $
pi@raspberrypi:~ $ exit
Connection to closed.

Lets disconnect as the pi user and connect as our new user, in my case ‘paz’.
pazy@Andrews-Air Downloads % ssh -l paz
paz@'s password:
Linux raspberrypi 4.19.75-v7+ #1270 SMP Tue Sep 24 18:45:11 BST 2019 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
paz@raspberrypi:~ $

Finally we can delete the pi user from our Raspberry Pi;

paz@raspberrypi:~ $ sudo deluser pi
Removing user pi' ... Warning: grouppi' has no more members.

paz@raspberrypi:~ $ sudo rm -rf /home/pi

We now have an up-to-date Pi and new user different to the default to connect with. To many this is enough but if your intent to connect your Pi to face the internet then you should be performing further steps to prevent attacks. On th next section we will guide you though this.

The Next Level

To secure your Raspberry Pi further we will insall fail2ban and change the defauly SSH port from 22 to something of your choosing.

Changing SSH port is simple just edit the file /etc/ssh/ssd_config, where you see the entry #Port remove the # and change the port number from the default 22 to something of your choosing. In my case I use 2222.

Once you update /etc/ssh/ssd_config you will need to restart the ssh service using the below command;

paz@raspberrypi:~ $ sudo service ssh restart

If we exit our session on our Pi and try and re-connect you will see our connection fails as we no longer have ssh running on port 22, we must use -p option to specify port at 2222.

pazy@Andrews-Air Downloads % ssh -l paz -p 22
ssh: connect to host port 22: Connection refused
pazy@Andrews-Air Downloads %
pazy@Andrews-Air Downloads %
pazy@Andrews-Air Downloads % ssh -l paz -p 2222

Next we will install fail2ban. fail2ban analyses system logs for failed attempts to login to you Pi, should X number of attempts result in a fail that IP address is then banned from accessing the host. This provided pretty good protection from anyone trying to brute force thier way onto your Pi.

To install fail2ban do the following;

paz@raspberrypi:~ $ sudo apt-get install fail2ban

With fail2ban you much copy the .config file to .local as per below;

paz@raspberrypi:~ $ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

If you wish to edit configuration for example the number of bad attempts allowed before a ban edit the jail.local file.

While the article does seem pretty long it will only take 15min or so to run through the commands. Next I will write about setting up a VPN and Pi-hole on your Pi.

Weekly script #3 unix_usr.sql

I use this one all the time. You have a high usage unix PID that is an Oracle Process. The script will take your defined pid and lookup the relating SQL and database user details to help you figure out the root cause.

set serveroutput on size 50000
set echo off feed off veri off
accept 1 prompt 'Enter Unix process id: '

v_sid number;
s sys.v_$session%ROWTYPE;
p sys.v_$process%ROWTYPE;
select sid into v_sid
from sys.v_$process p, sys.v_$session s
where p.addr = s.paddr
and (p.spid = &&1
or s.process = '&&1');
when no_data_found then
dbms_output.put_line('Unable to find process id &&1!!!');
when others then

select * into s from sys.v_$session where sid = v_sid;
select * into p from sys.v_$process where addr = s.paddr;

dbms_output.put_line('SID/Serial : '|| s.sid||','||s.serial#);
dbms_output.put_line('Foreground : '|| 'PID: '||s.process||' - '||s.program);
dbms_output.put_line('Shadow : '|| 'PID: '||p.spid||' - '||p.program);
dbms_output.put_line('Terminal : '|| s.terminal || '/ ' || p.terminal);
dbms_output.put_line('OS User : '|| s.osuser||' on '||s.machine);
dbms_output.put_line('Ora User : '|| s.username);
dbms_output.put_line('Status Flags: '|| s.status||' '||s.server||' '||s.type);
dbms_output.put_line('Tran Active : '|| nvl(s.taddr, 'NONE'));
dbms_output.put_line('Login Time : '|| to_char(s.logon_time, 'Dy HH24:MI:SS'));
dbms_output.put_line('Last Call : '|| to_char(sysdate-(s.last_call_et/60/60/24), 'Dy HH24:MI:SS') || ' - ' || to_char(s.last_call_et/60, '990.0') || ' min');
dbms_output.put_line('Lock/ Latch : '|| nvl(s.lockwait, 'NONE')||'/ '||nvl(p.latchwait, 'NONE'));
dbms_output.put_line('Latch Spin : '|| nvl(p.latchspin, 'NONE'));

dbms_output.put_line('Current SQL statement:');
for c1 in ( select * from sys.v_$sqltext
where HASH_VALUE = s.sql_hash_value order by piece) loop
end loop;

dbms_output.put_line('Previous SQL statement:');
for c1 in ( select * from sys.v_$sqltext
where HASH_VALUE = s.prev_hash_value order by piece) loop
end loop;

dbms_output.put_line('Session Waits:');
for c1 in ( select * from sys.v_$session_wait where sid = s.sid) loop
dbms_output.put_line(chr(9)||c1.state||': '||c1.event);
end loop;

-- dbms_output.put_line('Connect Info:');
-- for c1 in ( select * from sys.v_$session_connect_info where sid = s.sid) loop
-- dbms_output.put_line(chr(9)||': '||c1.network_service_banner);
-- end loop;

for c1 in ( select /*+ ordered */
-- Long locks
-- Short locks
'RW', 'ROW WAIT ',
'TD', 'DLL ENQ ', 'TE', 'EXTEND SEG ',
'TYPE='||l.type) type,
decode(l.lmode, 0, 'NONE', 1, 'NULL', 2, 'RS', 3, 'RX',
4, 'S', 5, 'RSX', 6, 'X',
to_char(l.lmode) ) lmode,
decode(l.request, 0, 'NONE', 1, 'NULL', 2, 'RS', 3, 'RX',
4, 'S', 5, 'RSX', 6, 'X',
to_char(l.request) ) lrequest,
decode(l.type, 'MR', o.name,
'TD', o.name,
'TM', o.name,
'RW', 'FILE#='||substr(l.id1,1,3)||
' BLOCK#='||substr(l.id1,4,5)||' ROW='||l.id2,
'TX', 'RS+SLOT#'||l.id1||' WRP#'||l.id2,
'WL', 'REDO LOG FILE#='||l.id1,
'RT', 'THREAD='||l.id1,
'TS', decode(l.id2, 0, 'ENQUEUE', 'NEW BLOCK ALLOCATION'),
'ID1='||l.id1||' ID2='||l.id2) objname
from sys.v_$lock l, sys.obj$ o
where sid = s.sid
and l.id1 = o.obj#(+) ) loop
dbms_output.put_line(chr(9)||c1.type||' H: '||c1.lmode||' R: '||c1.lrequest||' - '||c1.objname);
end loop;



undef 1

Weekly script #2 pid_from_sid.sql

A fairly easy script today that isn’t really hard to work out for yourself but I find it useful to have this script kicking around for when you find high resource using Oracle server process and you want to identify the offending SQL.

set pages 1000;
set lines 200;
col username for a10;

select b.status,a.inst_id,a.PID "Ora PID",a.SPID "Server PID",
a.LATCHWAIT,b.Program, b.Username,b.Osuser,b.machine,
b.terminal,a.terminal,b.Process "Client Process"
from gv$process a,gv$session b where a.addr=b.paddr and b.sid=&SID

See you next week!

Le Paz


Weekly Script #1 – ssh_key_scp.sh

Since I dont post on here to often I will try and post a weekly script that I find useful day-to-day.

First up is a short simple script to scp your private key to a defined server. Usage is pretty simple call the script with the username@hostname

e.g ./ssh_key_scp.sh username@hostname

If no ssh key already exists the script gives you the option to generate one.

# Andrew Paz
# 06/01/15


if [ ! -f ~/.ssh/id_rsa.pub ];then
echo "Private key not found at $KEY"
while true; do
read -p "Do you wish to generate a private key?" yn
case $yn in
[Yy]* ) ssh-keygen -t rsa; break;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no!";;


if [ -z $1 ];then
echo "Please specify user@host as the first parameter of this script"

echo "Putting your key on $1... "

ssh -q $1 "mkdir ~/.ssh 2>/dev/null; chmod 700 ~/.ssh; echo "$KEYCODE" >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys"

echo "done :D Key Uploaded!"


Thats it for this week, will post another next week.


A better Oracle DAC startserver.sh

Just want to share my Oracle DAC 10g startserver.sh.

startserver.sh is already provides as part of the DAC 10g install. I have added a couple of extra java parameters to allow a larger heap size and garbage collection method

. ./config.sh

$JAVA -server -Xms2048m -Xmx2048m -XX:+UseParNewGC -XX:ErrorFile='./hs_err_pid.log' -cp $DACCLASSPATH com.siebel.etl.net.QServer

-Xms and -Xmx give the dac server application 2GB of heap size to play with.

-XX:+UseParNewGC forces JVM to use parallel young generation GC with the concurrent GC.

-XX:ErrorFile should your dac server crash with a JVM error the stacktrace/dump will be stored in the specified file.

Until I feel like posting again 😉

DAC automationUtils.sh Script

Hi Again,

Today I noticed that DAC doesn’t have a method to export DAC repository meta data using the Linux/Unix Shell.

DAC is a windows tool that can also run on Linux. Unfortunately for us Linux users this means that not all of the command line options are available as they come in the form of a .bat file wont work in out native shell.

I was looking for a way to export DAC meta data using the command line, I was fully aware that this task could be achieved using the DAC Client GUI but I wanted something that could be run on a schedule to take backups. After some reading it was revealed that this was possible in Windows but now Linux. I have now converted the automationUtils.bat to automationUtils.sh that can run in Linux and Solaris giving you all the functionality. See the completed script below

#set -x
# Author - Andrew Pazikas
# Date - 10-07-13
# Desc - Originaly a Windows tool automationUtils.bat converted to run as a shell script Linux

. ./dac_env.sh

JAVA_HOME=/usr/jdk/instances/jdk1.6.0;export JAVA_HOME;
JAVA=${JAVA_HOME}/bin/sparcv9/java;export JAVA

export SQLSERVERLIB=./lib/msbase.jar:./lib/mssqlserver.jar:./lib/msutil.jar:./lib/sqljdbc.jar
export ORACLELIB=./lib/ojdbc6.jar:./lib/ojdbc5.jar:./lib/ojdbc14.jar
export DB2LIB=./lib/db2java.zip
export TERADATALIB=./lib/teradata.jar:./lib/terajdbc4.jar:./lib/log4j.jar:./lib/tdgssjava.jar:./lib/tdgssconfig.jar:./lib
#export SQLSERVERLIB ; export ORACLELIB ; export DB2LIB ; export TERADATALIB

export DACLIB=./DAWSystem.jar:.:
#export DBLIBS ; export DACLIB ; export DACCLASSPATH;
$JAVA -Xmx1024m -cp $DACCLASSPATH com.siebel.etl.functional.AutomationUtils "$1" "$2" "$3"