miércoles, 28 de octubre de 2020

Setup HSQLDB on MAC

A few days ago, I was involved in developing a practice for a University project where a Java application had to be built that communicated with an SQL instance. There is not much problem using standard SQL such as mySQL, MariaDB or PostgreSQL, but the export is a bit cumbersome. Doing some research on the Internet I found this wonderful HyperSQL solution, it is a functional Java based SQL database solution that you can easily save to your git repository like the rest of your application.

Let me detail step by step how we proceed with the installation and later I will publish some tricks.

Hsqldb Server

This is the preferred way of running a database server and the fastest one. A proprietary communications protocol is used for this mode. A command similar to those used for running tools and described above is used for running the server. The following example of the command for starting the server starts the server with one (default) database with files named "mydb.*".

java -cp ../lib/hsqldb.jar org.hsqldb.Server -database.0 file:xdb -dbname.0 xdb

The command line argument -? can be used to get a list of available arguments.

Note that both "xdb" is used for both File and database name.


   Running Tools

All tools can be run in the standard way for archived Java classes. In the following example the AWT version of the Database Manager, the hsqldb.jar is located in the directory ../lib relative to the current directory.

 java -cp ../lib/hsqldb.jar org.hsqldb.util.DatabaseManager

If hsqldb.jar is in the current directory, the command would change to:

java -cp hsqldb.jar org.hsqldb.util.DatabaseManager

Main classes for the Hsqldb tools
  • org.hsqldb.util.DatabaseManager
  • org.hsqldb.util.DatabaseManagerSwing
  • org.hsqldb.util.Transfer
  • org.hsqldb.util.QueryTool
  • org.hsqldb.util.SqlTool
Use these setting in the connection to setting to run the server.



Start the DB Manager Swing application

HSQL needs to be setup in JPA persistence.xml to perform connections.
screenshot hyperSQL




<persistence-unit name="Stocks" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>nJTA</non-jta-data-source>
        <class>com.larebelion.db.stock</class>
        <properties>
        <!-- jdbc:hsqldb:mdb -->
        <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:hsql://localhost/mdb" />
        <property name="javax.persistence.jdbc.user" value="SA"/>
        <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
        <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(SchemaAction='add', ForeignKeys=true)"/>
<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>        
     <property name="openjpa.jdbc.DBDictionary" value="hsql" />
<property name="openjpa.jdbc.Schema" value="PUBLIC" />
        </properties>   
    </persistence-unit> 
</persistence>

domingo, 18 de octubre de 2020

Code Stars


"Everybody in this country should learn how to program computer...

because it teaches you how to think" Steve Jobs




"I like programming more and more every day, I think it's the best job in the world. Dream, enjoy. build, program..." Jose Luis Santamaria

martes, 14 de julio de 2020

Installing, hardening, mod-security and fail2ban for Apache server

The following post is related to computer security, one of my passions as a hobby and what has fed me for several years being my profession a few years ago. The aim of the article is none other than to install and secure a web server, I have chosen Apache.

  1. Installing

If you need something help in order to compiling and installing you apache web server, please find more information in the official documentation.

    2. Hardening


Relatively recently, I found this public project called "Apache Hardening" and was completely delighted. It's not even worth transcribing, the best thing you can do is go to the original link and marvel at it by following the instructions.

    3. Mod-Security

Another important topic related you webserver Apache, is apply the mod-security. Mod-Security is one of the most popular security module for Apache and due MS more than the 85% of the automatics vulnerabilities and exploits are stopped.


On Intenet, normally you can find a lot of valid websites where explain how you need to install the tool but in my opinion one of the best is this.

    4. Fail2ban

Ok, we are very close to conclude this mini tutorial, imagine that all the above fails, what we have left, well, many things, we should be sure that we have secured our operating system, that we do not have unnecessary services published on the Internet and a long etcetera, but ... what if we apply firewall rules dynamically before events recorded in the log? Welcome to Fail2ban.

Let’s assume that you already installed fail2ban, you can check here how to do that: – https://www.ionos.com/community/server-cloud-infrastructure/linux-server/use-fail2ban-on-a-cloud-server-with-linux/

We need to copy this to a file called jail.local for Fail2Ban to find it.

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Configure defaults in jail.local
Open up the new Fail2Ban configuration file:
You can see the default section below:
[DEFAULT]

# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
# ban a host which matches an address in this list. Several addresses can be
# defined using space separator.
ignoreip = 127.0.0.1

# Override /etc/fail2ban/jail.d/00-firewalld.conf:
banaction = iptables-multiport

# "bantime" is the number of seconds that a host is banned.
bantime  = 600

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 600

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

Configure Fail2ban For ssh

Although you can add this parameters in the global jail.local file, it is a good practice to create seperate jail files for each of the services we want to protect with Fail2Ban.
So lets create a new jail for SSH with the vi editor.
vi /etc/fail2ban/jail.d/sshd.local
In the above file, add the following lines of code:
[sshd]
enabled = true
port = ssh
action = iptables-multiport
logpath = /var/log/secure
maxretry = 5
bantime = 600
Restart Fail2Ban
After making any changes to the Fail2Ban config, always be sure to restart Fail2Ban.
systemctl restart fail2ban
You can see the rules that fail2ban puts in effect within the IP table:
iptables -L -n
Check Fail2Ban Status
Use fail2ban-client command to query the overall status of the Fail2Ban jails.
fail2ban-client status
You can also query a specific jail status using the following command:
fail2ban-client status sshd

Configure Fail2ban For Apache

Edit this file:
sudo nano /etc/fail2ban/jail.local
Add the following content. Note: Substitute your own static IP address for the sample address (127.0.0.1) in this example:
# detect password authentication failures
[apache]
enabled  = true
filter   = apache-auth
action   = iptables-multiport[name=auth, port="http,https"]
logpath  = /var/log/httpd/fail2ban_log
bantime  = 3600
maxretry = 3
ignoreip = 127.0.0.1

# detect spammer robots crawling email addresses
[apache-badbots]
enabled  = true
filter   = apache-badbots
action   = iptables-multiport[name=badbots, port="http,https"]
logpath  = /var/log/httpd/fail2ban_log
bantime  = 3600
maxretry = 1
ignoreip = 127.0.0.1

# detect potential search for exploits
[apache-noscript]
enabled  = true
filter   = apache-noscript
action   = iptables-multiport[name=noscript, port="http,https"]
logpath  = /var/log/httpd/fail2ban_log
bantime  = 3600
maxretry = 6
ignoreip = 127.0.0.1

# detect Apache overflow attempts
[apache-overflows]
enabled  = true
filter   = apache-overflows
action   = iptables-multiport[name=overflows, port="http,https"]
logpath  = /var/log/httpd/fail2ban_log
bantime  = 3600
maxretry = 2
ignoreip = 127.0.0.1
Save and close the file, then restart Fail2ban for the changes to take effect:
sudo systemctl restart fail2ban
Now, configure the Fail2ban service to start on boot with the command:
sudo systemctl enable fail2ban
To verify the rules that were added to iptables by Fail2ban, use the following command:
sudo iptables -L



miércoles, 15 de abril de 2020

Graphviz. Simple solution for recreating graphics

This is the first article that I publish in English, the main reason to do it is because all the documentation related to context maps that I have found so far, are related in English and obviously my way to contribute to the extensive Internet community, is to do it in a universal language, at least for this article.

Well, today I want to talk about two utilities that have helped me a lot, one of them is graphviz.org. Graphviz, which has versions for Windows, Mac or Linux (in my case I have tried in Linux and Mac OS), is a powerful Open Source tool that allows to easily generate almost any graphic, cool stuff like this:



Or simpler things than recreating a binary tree that I explained in the previous section, https://www.larebelion.com/2020/04/arboles-binarios.html

Imagine that in code C, you want to represent the resulting binary tree, with few lines of code you could get something like this:


Let me a simple C function to add to the previous tree and generate this:

static void _generating_graphviz_details(const tree_t node, const void *extra)
{
 FILE *f = (FILE *) extra;

 fprintf(f, " node_%p [label=\"{%p | content: %d | { <izqda> %p | <dcha> %p}\"];\n",
  node, node, node->content, node->left, node->right
 );
 if (node->left != NULL) {
  fprintf(f, " node_%p:left -> node_%p;\n", node, node->left);
 }
 if (node->right != NULL) {
  fprintf(f, " node_%p:dcha -> node_%p;\n", node, node->dcha);
 }
 fprintf(f, "f");
}

Okay, hopefully this tiny contribution will help you in the dynamic generation of your graphics.

martes, 14 de abril de 2020

Backup de seguridad de tu máquina Linux

En estos días de confinamiento, me he decidido a ordenar un poco mis máquinas, en mi caso, cuento con tres raspberry en casa con diferentes distribuciones de Linux que utilizo para montar labs de sistemas, de programación, bases de datos como MariaDB o PostgreSQL e incluso cosas de seguridad o hardening.

Las raspberry, por la experiencia que tengo ya con ellas de varios años pueden sufrir problemas con la tarjeta SD y dejarte tirado. Como me ha pasado ya varias veces, me he decidido por escribir un script en shell para salvaguardar la información. Hasta aquí, todo más o menos sencillo, el problema es... ¿donde lo almaceno?.

Gracias a mi hermano, he descubierto http://mega.nz, se trata de una nueva startup del reputado empresario Kim_Dotcom, el creador de Megaupload. Lo primero que recomiendo hacer es crearte una cuenta gratuita de Meganz (50GB gratis).



Una vez la crees, descargate el componente para utilizar via json la integración con el API de meganz, el componente se llama Megacmd


Una vez que ya tengas todo esto instalado en tu máquina, ya puedes personalizar este pequeño shell script y almacenar tus backups en la nube.



#!/bin/bash

NAME=`hostname`
LIMITSIZE=5485760 # 5G = 10*1024*1024k   # limit size in GB   (FLOOR QUOTA)
MAILCMD=mail
R=/home/xxxx/src
LOG=$R/log/log-$(basename ${0}).log
EMAILIDS="user@domain.net"
MAILMESSAGE=$R/log/tmp-$(basename ${0})

if [ -d /media/4TB ]
then
        ROOTPATH=/media/4TB/servers/$NAME  # in case we've mount volume
        MOUNTP=/media/4TB
else
        ROOTPATH=/opt/$NAME  # in case no
        MOUNTP=/
fi

BKDIR=$ROOTPATH/bkdir # simple text file for to list your directories for backup, normally /etc /home/user /root /var/www/html ...
BKPATH=$ROOTPATH/backup
FREE=$(df -k --output=avail "$MOUNTP" | tail -n1) # df -k not df -h because is more exact

if [ ! -d $BKPATH ]
then
        mkdir -p $BKPATH
fi

if [ ! -d $R/log ]
then
        mkdir -p $R/log
fi

email_on_failure () # functions for launch email alert
{

          sMess="$1"
          echo "" >$MAILMESSAGE
          echo "Hostname: $(hostname)" >>$MAILMESSAGE
          echo "Date & Time: $(date)" >>$MAILMESSAGE

          # Email letter formation here:
          echo -e "\n[ $(date +%Y%m%d_%H%M%S%Z) ] Current Status:\n\n" >>$MAILMESSAGE
          cat $sMess >>$MAILMESSAGE

          echo "" >>$MAILMESSAGE
          echo "*** This email generated by $(basename $0) shell script ***" >>$MAILMESSAGE
          echo "*** Please don't reply this email, this is just notification email ***" >>$MAILMESSAGE

          # sending email (need to have an email client set up or sendmail)
          $MAILCMD -s "Urgent MAIL Alert For $(hostname) Server" "$EMAILIDS" < $MAILMESSAGE

          [ -f $MAILMESSAGE ] && rm -f $MAILMESSAGE
}

if [ "$FREE" -lt "$LIMITSIZE" ]
then
          echo "Writing to $LOG"
          echo "MAIL ERROR: Less than $((($FREE/1000))) MB free (QUOTA) on $MOUNTP!" | tee ${LOG}
          echo -e "\nPotential Files To Delete:" | tee -a ${LOG}
          find $MOUNTP -xdev -type f -size +500M -exec du -sh {} ';' | sort -rh | head -n20 | tee -a ${LOG}
          email_on_failure ${LOG}
else
   echo "Currently $((($FREE-$LIMITSIZE)/1000))) MB of QUOTA available of on $MOUNTP. " 
fi

if [ ! -f $BKDIR ]
then
        echo "Doesn't exist bkdir file. Aborting!" 
        exit 1
else
        filename=$NAME"_daily_backup_""$(date +'%Y_%m_%d')".tar.gz
        logfile="$R/"log/backup_log_"$(date +'%Y_%m')".log

        # Packages installed on Linux

        dpkg-query -W -f='${Installed-Size} ${Package}\n' | sort -n > $BKPATH/packages_installed.txt

        # Compressing my directories

        tar czf $BKPATH/$filename -T $BKDIR
        echo "dumping source code finished at $(date +'%d-%m-%Y %H:%M:%S')" >> "$logfile"

        # Changing permission

        chown root -R "$BKPATH"
        chown root "$logfile"
        chmod 644 $BKDIR
        chmod 600 $ROOTPATH

        echo "file permission changed" >> "$logfile"

        # removing old files and temporary files

        find "$BKPATH" -name "*daily_backup*" -mtime +3 -exec rm {} \;
        echo "old files deleted" >> "$logfile"
        echo "operation finished at $(date +'%d-%m-%Y %H:%M:%S')" >> "$logfile"

        # pushing mega.nz

        mega-login user@domain.net password
        mega-sync $BKPATH $NAME
        echo "pushing backup to mega.nz $(date +'%d-%m-%Y %H:%M:%S')" >> "$logfile"
        echo "*****************" >> "$logfile"
        exit 0
fi

domingo, 12 de abril de 2020

Árboles binarios

Ejercicio sencillo para representar un Arbol Binario, funciones básicas:

  • Crear nuevo árbol
  • Insertar hojas
  • Destruir Árbol
  • Imprimir en (Preorden, Postorden e Inorden)
  • Localizar nodos menores a un número, mostrarlos y contarlos.






#include <stdio.h>
#include <stdlib.h>

typedef struct nodo
{
    struct nodo *hizqdo;
    struct nodo *hdrcho;
    int contenido;
} nodo;

typedef struct nodo *arbol;

arbol nuevo_arbol (int contenido);
void destruir_arbol (arbol a);
void insertar_arbol (arbol nuevo, arbol *a);
void encontrar_menores (arbol a, int comparador, int *contador);
void imprimir (arbol a, int modo);

int main (void)
{
    int contenidos[] = {1, 20, 43, 12, 45, 21, 75, 26, 16, 74, 74, 36, 24, 2, 29, 97, -1};
    int *c = contenidos;
    arbol a = NULL;
    int contador = 0;
    while (*c >= 0) {
        arbol nuevo = nuevo_arbol(*c);
        insertar_arbol (nuevo, &a);
        c++;
    }

    printf ("\nPreorden:\n");
    imprimir(a, 1);
    printf ("\nPostorden:\n");
    imprimir(a, 2);
    printf ("\nInorden:\n");
    imprimir(a, 3);

    printf ("\nEncontrar menores de 50:\n");
    encontrar_menores(a, 50, &contador);
    printf ("\nContador: %d", contador);

    destruir_arbol(a);
    return EXIT_SUCCESS;
}

arbol nuevo_arbol (int contenido)
{
    arbol ret;
    if ((ret = calloc(1,sizeof(nodo))) == NULL) {
        return NULL;
    }

    ret->contenido = contenido;

    return ret;
}

void destruir_arbol (arbol a)
{
    if (a == NULL) {
        return;
    }
    destruir_arbol(a->hizqdo);
    destruir_arbol(a->hdrcho);
    free(a);
}

void insertar_arbol (arbol nuevo, arbol *a)
{
    if (*a == NULL) {
        *a = nuevo;
        return;
    }

    if (nuevo->contenido < (*a)->contenido) {
        insertar_arbol(nuevo, &((*a)->hizqdo));
    } else if (nuevo->contenido > (*a)->contenido) {
        insertar_arbol(nuevo, &((*a)->hdrcho));
    }
}

void encontrar_menores (arbol a, int comparador, int *contador)
{
    if (a == NULL) {
        return;
    }

    if (a->contenido < comparador) {
        printf ("%d | ", a->contenido);  
        ++(*contador);
    } 
    encontrar_menores (a->hizqdo, comparador, contador);
    encontrar_menores (a->hdrcho, comparador, contador);
}

void imprimir (arbol a, int modo) 
{
    if (a == NULL) {
        return;
    }

    if (modo == 1) { // Preorden
    printf ("%d | ", a->contenido);
    imprimir(a->hizqdo, 1);
    imprimir(a->hdrcho, 1);
    } else if (modo == 2){ // Postorden
        imprimir(a->hizqdo, 2);
        imprimir(a->hdrcho, 2);
        printf ("%d | ", a->contenido);
        } else if (modo == 3) {// Inorden
            imprimir(a->hizqdo, 3);
            printf ("%d | ", a->contenido);
            imprimir(a->hdrcho, 3);
            }
}

miércoles, 8 de abril de 2020

Matrices dinámicas en C

A continuación un ejercicio, similar a otros que he publicado, pero ésta vez con Matrices de dimensiones dinámicas.




#include <stdio.h>
#include <stdlib.h>


int ** IntroduceMatriz (int *, int *);
void SumaFilas (int **, int, int);
void MultiplicaColumnas (int **, int, int);
void RotaMatrizDerecha (int **, int, int);
void MostrarMatriz (int **, int, int);

int main () 
{
    int **matriz, f ,c;
    int i;

    matriz = IntroduceMatriz(&f, &c);
    MostrarMatriz(matriz,f,c);
    SumaFilas(matriz,f,c);
    MultiplicaColumnas(matriz,f,c);
    RotaMatrizDerecha(matriz,f,c);
    MostrarMatriz(matriz,f,c);
    for (i=0; i<f ; i++) {
        free(matriz[i]);
    }
    free(matriz);
    return EXIT_SUCCESS;
}

int ** IntroduceMatriz (int *f, int *c)
{
    int **matriz;
    int i, j;

    printf ("Indique numero de filas: \n");
    scanf ("%d",f);
    fflush (stdin);  // Limpiar el buffer de entrada
    printf ("Indique numero de columnas: \n");
    scanf ("%d",c);
    fflush (stdin);

    matriz = (int **) calloc (*f,sizeof(int*));

    for (i=0 ; i<*f ; i++) {
            matriz[i] = (int*) calloc (*c,sizeof(int));
    }

    for (i=0 ; i<*f ; i++) {
        for (j=0 ; j<*c ; j++) {
            printf ("\nIntroduzca posición %d - %d: ",i,j);
            scanf("%d",&matriz[i][j]);
            fflush(stdin);
        }
    }
    return matriz;
}

void MostrarMatriz (int **matriz, int f, int c)
{
    int i,j;
    for (i=0 ; i<f ; i++) {
        for (j=0 ; j<c ; j++) {
            printf ("%d ",matriz[i][j]);
        } printf ("\n");
    }
}

void SumaFilas (int **matriz, int f, int c)
{
    int i,j,suma;
    for (i=0 ; i<f ; i++) {
        suma = 0;
        for (j=0 ; j<c ; j++) {
            suma += matriz[i][j];
        } printf ("La fila %d suma: %d \n",f,suma);
    }
}

void MultiplicaColumnas (int **matriz, int f, int c)
{
    int i,j, multiplica;
    for (j=0 ; j<c ; j++) {
        multiplica = 1;
        for (i=0 ; i<f ; i++) {
            multiplica *= matriz[i][j];
        } printf ("La columna %d da: %d \n",j,multiplica);
    }
}

void RotaMatrizDerecha (int **matriz, int f, int c)
{
    int i,j;
    int **matrizt;

 
    matrizt = (int**) calloc (f,sizeof(int*));
    for (i=0; i<f ; i++) {
        matrizt[i] = (int*) calloc (c,sizeof(int));
    }

    for (i=0 ; i<f ; i++) {
        for (j=0 ; j<c ; j++) {
            if (j == c-1) {
                matrizt[i][0] = matriz[i][j]; 
            } else {
                matrizt[i][j+1] = matriz[i][j];
            }     
        } 
    }

    for (i=0 ; i<f ; i++) {
        for (j=0 ; j<c ; j++) {
            matriz[i][j] = matrizt[i][j];
        } 
    }

}

lunes, 6 de enero de 2020

Programa en C que genere 6 hilos y estos se identifiquen

Generemos un programa en lenguaje C que lance o genere 6 hilos y estos se identifiquen con un identificador.





#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define NUMERO 6

int contador;
static void *saluda (void *);

int main (void)
{
 int i;
 pthread_t hilo[NUMERO];

 for (i = 0; i < NUMERO ; i++) {
  sleep(1);
  pthread_create (&hilo[i],NULL,saluda,NULL);
 }

 for (i = 0; i < NUMERO ; i++) {

  pthread_join (hilo[i],NULL);
 }

 return 0;
}

static void *saluda (void *args) 
{
 contador += 1;
 printf ("Soy el thread %d y tengo el id %d\n",contador,(int) pthread_self());
 return NULL;
}