Get a delimited list in Oracle SQL

There are many times that I need to retrieve a delimited list in SQL and every time I have to track the solution down.

 

So here it is.

SELECT RTRIM (
 rtrim(XMLAGG (XMLELEMENT (e, column_name || ',')).EXTRACT ('//text()'), ',') name
 FROM table_name;

 

Just to break this down a little

rtrim(XMLELEMENT (e, column_name || 'This is the delimiter')).EXTRACT 
('//text()'), 'This is the delimiter')



Advertisements

Converting PDFs’ into text

PDFtoTXT

I am currently working on a project to extract the text from a PDF purchase order and create an xml file to feed into our ERP system, fully automated obviously.

I therefore needed a way to extract the text from a PDF at the command line, luckily there is a cool utility called poppler-utils. This works perfectly and is extremely fast.

I have installed this on both a CentOS server and more recently and Ubuntu server,

The caveat to this product is that you need the PDF to be real and not an image, this is why the Ubuntu server may be used.

mkdir ~/software
wget https://poppler.freedesktop.org/poppler-0.40.0.tar.xz
wget https://poppler.freedesktop.org/poppler-data-0.4.7.tar.gz
tar xvf poppler-0.40.0.tar.xz
tar xvf poppler-data-0.4.7.tar.gz

There are a few requirements

yum -y install fontconfig fontconfig-devel
yum -y install cairo cairo-devel libjpeg libjpeg-devel libcurl-devel gtk-doc 
yum -y install libtool gcc-c++ lcms2 openjpeg-libs xz openjpeg-devel
yum -y install libtiff-devel lcms2-devel

cd poppler-data-0.4.7
make install

tar (child): xz: Cannot exec: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now

Ensure that you install xz

cd poppler-0.40.0
./configure

ERROR

checking for a BSD-compatible install… /usr/bin/install -c
checking whether build environment is sane… yes
checking for a thread-safe mkdir -p… /bin/mkdir -p
checking for gawk… gawk
checking whether make sets $(MAKE)… yes
checking whether make supports nested variables… yes
checking whether make supports nested variables… (cached) yes
checking for style of include used by make… GNU
checking for gcc… no
checking for cc… no
checking for cl.exe… no
configure: error: in `/root/software/poppler-0.40.0′:
configure: error: no acceptable C compiler found in $PATH
See `config.log’ for more details

ERROR

No package ‘fontconfig’ found

Ensure that you installed  fontconfig fontconfig-devel

INFORMATION

Building poppler with support for:
font configuration: fontconfig
splash output: yes
cairo output: no (requires cairo >= 1.10.0)
qt4 wrapper: no
qt5 wrapper: no
glib wrapper: no (requires cairo output)
introspection: no
cpp wrapper: yes
use gtk-doc: no
use libjpeg: no
use libpng: no
use libtiff: no
use zlib: no
use libcurl: no
use libopenjpeg: no
use cms: no
command line utils: yes
test data dir: /root/software/poppler-0.40.0/./../test

Warning: Using libjpeg is recommended. The internal DCT decoder is unmaintained.
Warning: Using libopenjpeg is recommended. The internal JPX decoder is unmaintained.

Ensure that you installed  cairo cairo-devel libjpeg libjpeg-devel libcurl-devel gtk-doc

make
make all-recursive

make[1]: Entering directory `/root/software/poppler-0.40.0′
Making all in goo
make[2]: Entering directory `/root/software/poppler-0.40.0/goo’
CXX libgoo_la-gfile.lo
../libtool: line 1129: g++: command not found
make[2]: *** [libgoo_la-gfile.lo] Error 1
make[2]: Leaving directory `/root/software/poppler-0.40.0/goo’
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/root/software/poppler-0.40.0′
make: *** [all] Error 2

Ensure that you  installed libtool gcc-c++ lcms-libs openjpeg-libs

make install

You should now have a working copy of the software.

To convert a pdf you just simply issue

pdftotext -layout PDF_Name  Output_Filename

 

 

Ubuntu Install

mkdir ~/software

apt-get -y install libcurl4-gnutls-dev libcairo2-dev libcairo2 libjpeg libjpeg-dev \
libtiff5-dev libgtk-doc g++ fontconfig fontconfig-dev fontconfig*

wget https://launchpad.net/ubuntu/+archive/primary/+files/poppler-data_0.4.6.orig.tar.gz
wget https://launchpad.net/ubuntu/+archive/primary/+files/poppler_0.41.0.orig.tar.xz

tar -xvf poppler-data_0.4.6.orig.tar.gz

tar -xvf poppler_0.41.0.orig.tar.xz

cd 

cd poppler-data-0.4.6/

make install

cd poppler-0.41.0/

./configure –prefix=/usr

make

make install

 


Installing s3fs on Centos

centos-logos3_amazon

Many years ago I install s3fs on Centos servers and wrote about it, today I needed to install it on a new server.

I went straight to the instructions and of course as in everything Open Source they were out of date. So here for the next few months are the new install instructions. 🙂

cd ~
mkdir software
cd software
wget -O master.zip https://github.com/s3fs-fuse/s3fs-fuse/archive/master.zip 

Some prerequisites 

yum -y install automake libcurl gcc-c++ \
libcurl-devel libxml2 libxml2-devel libtool gettext gettext-devel \
openssl openssl-devel
 
unzip master.zip
cd s3fs-fuse-master
./autogen.sh 

 

ERROR

— Make commit hash file ——-
— Finished commit hash file —
— Start autotools ————-
./autogen.sh: 38: ./autogen.sh: aclocal: not found
— Finished autotools ———-

Ensure that you have installed automake

./configure --prefix=/usr

ERROR

checking whether the C++ compiler works… no
configure: error: in `/root/software/s3fs-fuse-master’:
configure: error: C++ compiler cannot create executables
See `config.log’ for more details

Ensure that you have installed  gcc-c++

No package ‘fuse’ found
No package ‘libcurl’ found
No package ‘libxml-2.0’ found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables common_lib_checking_CFLAGS
and common_lib_checking_LIBS to avoid the need to call pkg-config.

Ensure that you installed fuse-devel  libcurl-devel libxml2-devel

ERROR

configure: error: Package requirements (fuse >= 2.8.4 libcurl >= 7.0 libxml-2.0 >= 2.6) were not met:

Requested ‘fuse >= 2.8.4’ but version of fuse is 2.8.3

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables common_lib_checking_CFLAGS
and common_lib_checking_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

You need to uninstall fuse

You may get the following error

Error in PREUN scriptlet in rpm package realplay
XXXXXXX was supposed to be removed but is not!

rpm -e --noscripts --nodeps fuse
rpm --rebuilddb
yum erase fuse*

cd ~/software
wget -O fuse-2_9_bugfix.zip https://github.com/libfuse/\
libfuse/archive/fuse-2_9_bugfix.zip

unzip fuse-2_9_bugfix.zip
cd libfuse-fuse-2_9_bugfix

I tried the install with version 3, this was a disaster

wget -O libfuse.zip https://github.com/libfuse/libfuse/archive/master.zip
unzip libfuse.zip
cd libfuse-master/

./makeconf.sh

Running libtoolize...
./makeconf.sh: line 4: libtoolize: command not found
config.rpath not found! - is gettext installed?

Ensure that libtool gettext gettext-devel

./configure --prefix=/usr/local
make
make install

OK now to fix some path issue and a final dependency

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

To check if it is installed and the path statement is correct

pkg-config –modversion fuse

This is from version 3

pkg-config --modversion fuse3
ln -s /usr/local/lib/pkgconfig/fuse3.pc /usr/local/lib/pkgconfig/fuse.pc

cd ~/software/s3fs-fuse-master/
./configure --prefix=/usr

ERROR

checking for common_lib_checking… configure: error: Package requirements (fuse >= 2.8.4 libcurl >= 7.0 libxml-2.0 >= 2.6) were not met:

No package ‘fuse’ found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables common_lib_checking_CFLAGS
and common_lib_checking_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

ERROR

checking for DEPS… configure: error: Package requirements (fuse >= 2.8.4 libcurl >= 7.0 libxml-2.0 >= 2.6 libcrypto >= 0.9) were not met:

No package ‘libcrypto’ found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables DEPS_CFLAGS
and DEPS_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

Ensure that  openssl openssl-devel

make
make install

OK to test if you have this installed

s3f3 

should then prompt you for a bucket name and credentials

s3fs: missing BUCKET argument.
Usage: s3fs BUCKET:[PATH] MOUNTPOINT [OPTION]…

ERROR

s3fs: error while loading shared libraries: libfuse.so.2: cannot open shared object file: No such file or directory

yum install fuse-libs

You need to create a .passwd-s3fs file. This is best done as root as it should be stored in the home directory and should of course be secured done.

cd ~
echo accessKeyId:secretAccessKey > .passwd-s3fs
chmod 600 ~/.passwd-s3fs

Now create a mount point for the bucket

cd /mnt
mkdir bucketname - this is only a suggestion but it keeps it 
consistent and therefore easy to debug

then issue the s3fs commands (to text if the mount works)

s3fs mybucket /path/to/mountpoint -o passwd_file=~/.passwd-s3fs
 

NOTE the -o allow – makes the mounted directory accessible by other users of the server.

If you encounter any errors, enable debug output:

s3fs mybucket /path/to/mountpoint -o passwd_file=~/.passwd-s3fs -d -d -f -o 
f2 -o curldbg

Now to permanently mount the drive when the server boots up etc… the command for the fstab is as follows :

s3fs#bucketname /mnt/mount_folder fuse allow_other 0 0

e.g.

vi /ect/fstab

s3fs#domainname-website-export /mnt/website-export fuse _netdev,allow_other 0 0

To mount the bucket

mount -a 


Install s3fs Ubuntu 14.04 LTS

ubuntu-logo112s3_amazon

Many years ago I install s3fs on Centos servers and wrote about it, today I needed to install in an Ubuntu server.

I went straight to the instructions and of course as in everything Open Source they were out of date. So here for the next few months are the new install instructions. 🙂

cd ~
mkdir software
cd software
 wget https://github.com/s3fs-fuse/s3fs-fuse/archive/master.zip

Some prerequisites 

apt-get -y install automake build-essential libfuse-dev fuse libcurl3
libcurl3-dev libxml2 libxml2-dev
unzip master.zip
cd s3fs-fuse-master
 ./autogen.sh 

ERROR

— Make commit hash file ——-
— Finished commit hash file —
— Start autotools ————-
./autogen.sh: 38: ./autogen.sh: aclocal: not found
— Finished autotools ———-

Ensure that you have installed automake

./configure --prefix=/usr

ERROR

checking whether the C++ compiler works… no
configure: error: in `/root/software/s3fs-fuse-master’:
configure: error: C++ compiler cannot create executables
See `config.log’ for more details

Ensure that you have installed  build-essential

No package ‘fuse’ found
No package ‘libcurl’ found
No package ‘libxml-2.0’ found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables common_lib_checking_CFLAGS
and common_lib_checking_LIBS to avoid the need to call pkg-config.

Ensure that you installed libfuse-dev  libcurl3-dev libxml2-dev

A quick hint, if you are looking for a package e.g. libcurl you could use the following command :-

apt-cache search libcurl

make
make install

 

OK to test if you have this installed

s3f3 should then prompt you for a bucket name and credentials

s3fs: missing BUCKET argument.
Usage: s3fs BUCKET:[PATH] MOUNTPOINT [OPTION]…

You need to create a .passwd-s3fs file. This is best done as root as it should be stored in the home directory and should of course be secured done.

cd ~
echo accessKeyId:secretAccessKey > .passwd-s3fs
chmod 600 ~/.passwd-s3fs

Now create a mount point for the bucket

cd /mnt
mkdir bucketname - this is only a suggestion but it keeps it 
consistent and therefore easy to debug

then issue the s3fs commands (to text if the mount works)

s3fs mybucket /path/to/mountpoint -o passwd_file=~/.passwd-s3fs
 

NOTE the -o allow – makes the mounted directory accessible by other users of the server.

If you encounter any errors, enable debug output:

s3fs mybucket /path/to/mountpoint -o passwd_file=~/.passwd-s3fs -d -d -f -o 
f2 -o curldbg

 

Now to permanently mount the drive when the server boots up etc… the command for the fstab is as follows :

s3fs#bucketname /mnt/mount_folder fuse allow_other 0 0

e.g.

vi /ect/fstab

s3fs#domainname-website-export /mnt/website-export fuse _netdev,allow_other 0 0

Allowing access to a mounted drive from a non root user is a bit of a headache.

change the /etc/fuse.conf file and un-comment the user_allow_other

# Allow non-root users to specify the allow_other or allow_root mount options.
user_allow_other

Then add the mount line to /etc/fstab

s3fs#bucketname mount_point  fuse _netdev,allow_other,umask=700,use_rrs  0 0

The highlighted areas are the imported entries

To mount the bucket

mount -a 

 

 

 

 


Technical Bits n Pieces

This really is and aide memoire, a scrap pad, random commands etc ……. as I come across errors, workarounds, fixes.

This is all about making those notes so that I don’t have to trawl Google again to find the answers and at least I know these commands work 🙂

How to grep IP addresses in a file?

I needed to tail a file for IP addresses as some thing was using a large amount of web server resource. The log file is called httpd-access

 tail -f httpd-access_log | grep -E -o “([0-9]{1,3}[\.]){3}[0-9]{1,3}”

How to deny and ip address from accessing your server?

Yes you can use a firewall, but if you are behind a load balancer or proxy server then you can not.

In either the httpd.conf or the .htaccess file add the following lines :-

httpd.conf – add these to the directory element of the file

Order allow,deny
Allow from all
deny from Enter IP address

At the end of the file

<Files 403.shtml>
order allow,deny
allow from all

.htaccess – add this to the IfModule element, You can deny IP addresses or use a RewriteCond and Rule.

# Block Bad Bots
RewriteCond %{HTTP_USER_AGENT} ^.*(Vagabondo).*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(AhrefsBot).*$ [NC]
# ISSUE 403 / SERVE ERRORDOCUMENT
RewriteRule . - [F,L]
order allow,deny
allow from all

deny from Enter Ip address here

Add this at the end of the file

<Files 403.shtml>
order allow,deny
allow from all
</Files>

The server will redirect traffic to a 403 error.

 

How to log the source IP address when behind a load balancer or proxy?

You use a load balancer to spread the load of your web sites, but how can you find the ip address of who is using your site, this is specific to the Apache server but something similar will work on nginx I am sure.

In the httpd.conf file change the

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

to

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" combined

You now should create some custom logs files, again in httpd.conf add the following lines to the virtualhost element

ErrorLog logs/httpd-error_log
CustomLog logs/httpd-access_log combined

…..

Allowing SSH access to Ubuntu 14.0 LTS Desktop

We are running some software that needs a Linux desktop, I am not a big fan of Ubuntu but it is one of the listed supported platforms.

I obviously need vnc access, wow what a pain. Centos / Redhat easy to do Ubuntu !!!!

So I though ssh on and just configure, well there is no SSH access out of the box. Build for the GUI generation. To get ssh access

sudo apt-get update
sudo apt-get install openssh-server

 

You now have ssh access!!!

 

Create a patch file and then the application of the patch

If you need to create a differential file for redeployment on another system then creating a patch file is ideal.

You will need the patch utilities installed

yum install patch

Now to create your patch file. Copy the original file into the same directory

e.g. cp config.php config.php_chg

Now update the config.php_chg file with all of your amendments

Now to create the file

diff -Naur config.php config.php_chg > config.php.patch

If you want to now apply the patch

patch config.php < config.php.patch

You now should keep the file in a safe place or if it is not a sensitive change, i.e. containing passwords then you can add it to https://gist.github.com/

 

 

 

 

 

 


		

Creating self signed certificate

Again this is more an aide memoire.

Whilst waiting for my real SSL certificates to be create I wanted to continue my configuration of the server that I am building.

I therefore wanted a self signed certificate to try the config.

mkdir ~/sslselfsign
cd ~/sslselfsign
openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
openssl rsa -passin pass:x -in server.pass.key -out server.key
rm -f server.pass.key
openssl req -new -key server.key -out server.csr

 

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–

Country Name (2 letter code) [XX]:GB
State or Province Name (full name) []:County_Name
Locality Name (eg, city) [Default City]:City_Name
Organization Name (eg, company) [Default Company Ltd]:Comany_Name
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server’s hostname) []:xxxx.xxxxx.com
Email Address []:

Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

 openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

you should now have 3 files

ls -l

server.crt
server.csr
server.key


How to debug selinux

I am creating an externally facing server and need it to be as hardened as possible, normally for internal servers I just disable selinux as there the risk of hacking is virtually non existent.

To keep the security up on a external server though selinux should stay enabled.

To use the tools you will need to install the following :-

yum install policycoreutils-python
yum install setroubleshoot-server

Installing this you now have access to /var/log/audit/audit.log

tail -n 50 /var/log/audit/audit.log

Will give you something like this

type=AVC msg=audit(1452761897.495:221): avc: denied { unlink } for pid=2013 comm=”squid” name=”squid-cf__metadata.shm” dev=tmpfs ino=32533 scontext=unconfined_u:system_r:squid_t:s0 tcontext=unconfin
ed_u:object_r:tmpfs_t:s0 tclass=file

There are some tools that you can use to decipher this

mkdir ~/selinux_output
cd ~/selinux_output

You need to identify the application that you are trying to debug, in this instance it is squid as highlighted in the log above.

If you have a large audit log I would use the following commands

service auditd stop
rm -f /var/log/audit/audit.log
service auditd start

Now start the service that has failed or you are trying to debug

service squid start

Now to extract some details as create a policy file

cd ~/selinux_output
rm -f myaudit.txt
sealert -a /var/log/audit/audit.log > myaudit.txt

You can review what errors are being highlighted in the audit files. This is needed if you are constantly debugging the application

mv myapplication.te myapplication.bak

Now to create the policy file change squid for whichever application you are trying to debug

grep squid /var/log/audit/audit.log | audit2allow -m squid > myapplication.te

When the myapplication.te file has been created review it.

There will be a line at the top formatted something like this.

module squid 1.0;

Ensure that you prefix what ever the application is with my, this ensure that there will not be a conflict with pre-configured policies or future policies when they released.

module mysquid 1.0;

Now we need to create the policy and install it.

Again the first two lines are for when you are constantly updating the policy

rm -f *.mod
rm -f *.pp
checkmodule -M -m -o myapplication.mod myapplication.te
 semodule_package -o myapplication.pp -m myapplication.mod
 semodule -i myapplication.pp

You then need to test the application and keep repeating the exercise. Please note that you will need to merge the two policies together as you create them so in the example above merge the require and the policy from the .bak file with the newly created .te file. An example of a file that has been created from around three or four tries of the above process.


module mysquid 1.0;
require {
        type tmpfs_t;
        type squid_t;
        class dir { write read create add_name remove_name };
        class file { read write create add_name unlink };
}
#============= squid_t ==============
#!!!! The source type 'squid_t' can write to a 'dir' of the following types:
# var_log_t, var_run_t, pcscd_var_run_t, squid_var_run_t, squid_cache_t, squid_log_t, cluster_var_lib_t, cluster_var_run_t, root_t, krb5_host_rcache_t, cluster_conf_t, tmp_t
allow squid_t tmpfs_t:dir { write read create add_name remove_name };
allow squid_t tmpfs_t:file { write read create add_name unlink };

 

Some of the references used for this post

https://wiki.centos.org/HowTos/SELinux#head-faa96b3fdd922004cdb988c1989e56191c257c01

http://squid-web-proxy-cache.1019090.n4.nabble.com/squid-announce-Squid-3-5-9-is-available-td4673315.html