init iplocate repo
This commit is contained in:
commit
885d4bc3d6
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
__pycache__/
|
||||||
|
test/
|
||||||
|
*.db
|
||||||
|
config.cfg
|
167
README.md
Normal file
167
README.md
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
# iplocate
|
||||||
|
|
||||||
|
## Gestión de logs *nginx* archivados
|
||||||
|
|
||||||
|
Mueve archivos ***log.?.gz*** del servidor existentes en `/var/log/nginx` al directorio
|
||||||
|
de usuario "**ruta_base**" en el servidor especificado en `./config.cfg`. Utiliza el
|
||||||
|
script `muevelogz.sh` (script en servidor).
|
||||||
|
|
||||||
|
Mueve los archivos ***log.?.gz*** del directorio de usuario del servidor al directorio
|
||||||
|
local "**destino_log**" especificado en `./config.cfg`.
|
||||||
|
Descomprime archivos **`.gz`** y concatena los respectivos archivos de log.
|
||||||
|
Borra los archivos utilizados en concatenación. Script `./muevelog.sh`.
|
||||||
|
|
||||||
|
ej. archivo de configuración `./config.cfg`
|
||||||
|
```cfg
|
||||||
|
[bash_script]
|
||||||
|
ruta_base=mi_server://home/server_user/nginx_log.old/
|
||||||
|
destino_log=/home/server_logs/nginx_old
|
||||||
|
server_name=mi_server
|
||||||
|
server_script=//home/server_user/scripts/muevelogz.sh
|
||||||
|
|
||||||
|
[iplocate]
|
||||||
|
token = '?token=1234567890abc'
|
||||||
|
```
|
||||||
|
- ***mi_server***: parte de *ruta_base*, nombre del host según configuración
|
||||||
|
en `~/.ssh/config`.
|
||||||
|
- **ruta_base** : es la ruta en el servidor donde se mueven los logs
|
||||||
|
archivados (.gz) desde `/var/log/nginx/` (termina en `/`).
|
||||||
|
- **destino_log** : ruta donde se guardan local y temporalmente los
|
||||||
|
archivos *log.?.gz*.
|
||||||
|
- **server_name** : nombre del host según configuración en `~/.ssh/config`.
|
||||||
|
- **server_script** : ruta en el servidor, del script que mueve los *log.?.gz*.
|
||||||
|
|
||||||
|
|
||||||
|
Crea base de datos ***SQLite3*** **`./ipinfo.db`** con tablas de **registro** y de **visitas**.
|
||||||
|
|
||||||
|
## Uso
|
||||||
|
`./iplocate.py -h`
|
||||||
|
ej. alias `alias iploc='~/ruta/script/iplocate.py'`
|
||||||
|
```bash
|
||||||
|
ipLocate
|
||||||
|
Muestra información disponible en ipinfo.io sobre IPs consultadas.
|
||||||
|
|
||||||
|
Uso:
|
||||||
|
iploc <IP> - Muestra la información de <IP>.
|
||||||
|
iploc -f <archivo> - Muestra info. de las IPs en <archivo>
|
||||||
|
iploc -c - Carga logs en base de datos.
|
||||||
|
iploc -g - Guarda ipinfo de IPs sin registro en la BD.
|
||||||
|
iploc -h - Muestra esta ayuda.
|
||||||
|
iploc --sync - Sincroniza logs del servidor (bash script).
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**`iploc --sync`**
|
||||||
|
Realiza el proceso de copia de archivos del servidor, extracción y concatenado.
|
||||||
|
Explicado con detalle mas arriba.
|
||||||
|
|
||||||
|
**`iploc -c`**
|
||||||
|
Poblar la tabla **visita** de la BD. Carga los registros en archivos de log en la tabla.
|
||||||
|
|
||||||
|
**`iploc -g`**
|
||||||
|
Consulta a `ipinfo.io` por cada ip registrada en **visita** (una vez por ip).
|
||||||
|
Guarda los datos en tabla **registro**.
|
||||||
|
|
||||||
|
### Otras opciones
|
||||||
|
|
||||||
|
`iploc <IP>`:
|
||||||
|
- Muestra la información sobre \<IP\> disponible en ipinfo.io.
|
||||||
|
|
||||||
|
`iploc -t <IP>`: **PENDIENTE**
|
||||||
|
- Muestra la información sobre \<IP\> disponible en ipinfo.io
|
||||||
|
usando el **token** especificado en `./config.cfg`.
|
||||||
|
|
||||||
|
`iploc -d <IP>`: **PENDIENTE**
|
||||||
|
- Muestra toda la información disponible en BD acerca de \<IP\>
|
||||||
|
|
||||||
|
`iploc -f <archivo_IPs>`:
|
||||||
|
- Muestra la información disponible en ipinfo.io para cada \<IP\>
|
||||||
|
en archivo pasado como argumento.
|
||||||
|
|
||||||
|
`iploc -D <archivo_IPs>`: **PENDIENTE**
|
||||||
|
- Muestra toda la información disponible en BD para cada \<IP\>
|
||||||
|
en archivo pasado como argumento.
|
||||||
|
|
||||||
|
ej. formato \<archivo_IPs\>.
|
||||||
|
```
|
||||||
|
1.1.1.1
|
||||||
|
8.8.8.8
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sicronización manual
|
||||||
|
|
||||||
|
No es necesario el uso manual de este script, ya que es llamado por `iploc --sync`.
|
||||||
|
Pero ya que existe por que no tener la opción de llamar manualmente a las funciones.
|
||||||
|
|
||||||
|
`./muevelog.sh -h`
|
||||||
|
```
|
||||||
|
Ejecuta script del servidor que mueve los logs archivados, copia en ruta
|
||||||
|
de trabajo, concatena y elimina los archivos sobrantes.
|
||||||
|
|
||||||
|
Programa pensado para ser llamado por iplocate.py (muevelog.sh --start).
|
||||||
|
|
||||||
|
Operación manual: ./muevelog.sh [OPCION]
|
||||||
|
|
||||||
|
Ruta de trabajo: </ruta/segun/config.cfg>
|
||||||
|
|
||||||
|
Opciones:
|
||||||
|
-s, --start - Copia, extrae y concatena logs.
|
||||||
|
-S, --sync - Mueve logs.gz en el servidor (Pre-Copia).
|
||||||
|
-C, --copia - Copia logs del servidor en ruta de trabajo (Post-sync).
|
||||||
|
-x, --extraer - Descomprime logs en ruta de trabajo.
|
||||||
|
-c, --concat [error.log, all...] - Concatena logs de la ruta de trabajo.
|
||||||
|
-v, --version - Muestra la fecha de la versión.
|
||||||
|
-h, --help - Muestra información de ayuda.
|
||||||
|
```
|
||||||
|
|
||||||
|
`./muevelog.sh --start`:
|
||||||
|
Realiza todo el proceso **--sync**, **--copia**, **--extraer** y **--concat**.
|
||||||
|
|
||||||
|
|
||||||
|
### Implementación
|
||||||
|
Clonar proyecto en directorio ej. `~/nginx_data`.
|
||||||
|
|
||||||
|
Crear `alias iploc='~/nginx_data/iplocate.py'`.
|
||||||
|
|
||||||
|
Modificar ruta **logdest** en `muevelogz.sh` y copiar en el servidor.
|
||||||
|
```
|
||||||
|
# logdest debe ser la misma ruta especificada en config.cfg como *ruta_base*
|
||||||
|
logdest=</ruta/user/docs/logs/nginx_log.old>
|
||||||
|
```
|
||||||
|
Crear archivo de configuración según ejemplo mostrado en la primera sección
|
||||||
|
de este documento.
|
||||||
|
|
||||||
|
Correr `iploc -h` para crear base de datos.
|
||||||
|
|
||||||
|
```
|
||||||
|
📂️ nginx_data/
|
||||||
|
├── 📄️ config.cfg
|
||||||
|
├── 📄️ ipinfo.db
|
||||||
|
├── 📄️ iplocate.py
|
||||||
|
├── 📄️ muevelog.sh
|
||||||
|
├── 📄️ muevelogz.sh
|
||||||
|
├── 📄️ README.md
|
||||||
|
└── 📄️ sql_alch.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Seguir los pasos explicados en **Uso**.
|
||||||
|
|
||||||
|
### Requerimientos, dependencias
|
||||||
|
|
||||||
|
Servidor:
|
||||||
|
- Bash >= 5.0
|
||||||
|
- rsync
|
||||||
|
|
||||||
|
Local:
|
||||||
|
- Bash local >= 5.1.16
|
||||||
|
- SQLite3 3.38.5
|
||||||
|
- sqlitebrowser 3.35.5 (opc.)
|
||||||
|
- Python >= 3.10
|
||||||
|
- requests
|
||||||
|
- SQLAlchemy 1.4.32
|
||||||
|
- colorama
|
||||||
|
|
||||||
|
Token API [ipinfo.io](https://ipinfo.io/)
|
||||||
|
|
||||||
|
|
143
iplocate.py
Executable file
143
iplocate.py
Executable file
@ -0,0 +1,143 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import requests
|
||||||
|
import re
|
||||||
|
import configparser as cfg
|
||||||
|
from os.path import isfile
|
||||||
|
from json import loads
|
||||||
|
from colorama import Fore, Back, Style
|
||||||
|
import sql_alch
|
||||||
|
|
||||||
|
selfpath = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
ownip = requests.get('https://ifconfig.me/').text
|
||||||
|
parser = cfg.ConfigParser()
|
||||||
|
parser.read(f'{selfpath}/config.cfg')
|
||||||
|
token = parser.get('iplocate','token')
|
||||||
|
token = token.strip("'")
|
||||||
|
muevelog = f'{selfpath}/muevelog.sh '
|
||||||
|
|
||||||
|
# Colores
|
||||||
|
co_rst = Style.RESET_ALL
|
||||||
|
co_Blu = Fore.BLUE+Style.NORMAL
|
||||||
|
co_BluD = Fore.BLUE+Style.DIM
|
||||||
|
co_BluB = Fore.BLUE+Style.BRIGHT
|
||||||
|
co_Red = Fore.RED+Style.NORMAL
|
||||||
|
co_RedD = Fore.RED+Style.DIM
|
||||||
|
co_RedB = Fore.RED+Style.BRIGHT
|
||||||
|
co_Grn = Fore.GREEN+Style.NORMAL
|
||||||
|
co_GrnD = Fore.GREEN+Style.DIM
|
||||||
|
co_GrnB = Fore.GREEN+Style.BRIGHT
|
||||||
|
co_Yel = Fore.YELLOW+Style.NORMAL
|
||||||
|
co_YelD = Fore.YELLOW+Style.DIM
|
||||||
|
co_YelB = Fore.YELLOW+Style.BRIGHT
|
||||||
|
co_BluLWh = Fore.BLUE+Back.LIGHTWHITE_EX+Style.NORMAL
|
||||||
|
co_BluLWhB = Fore.BLUE+Back.LIGHTWHITE_EX+Style.BRIGHT
|
||||||
|
co_GrnMgnB = Fore.GREEN+Back.MAGENTA+Style.BRIGHT
|
||||||
|
co_RedBluD = Fore.RED+Back.BLUE+Style.DIM
|
||||||
|
co_LRedBleD = Fore.LIGHTRED_EX+Back.BLUE+Style.DIM
|
||||||
|
co_BlkMgnB = Fore.BLACK+Back.MAGENTA+Style.BRIGHT
|
||||||
|
co_BlkMgn = Fore.BLACK+Back.MAGENTA+Style.NORMAL
|
||||||
|
co_LGrLBlk = Fore.LIGHTGREEN_EX+Back.LIGHTBLACK_EX
|
||||||
|
co_RdYl = Fore.RED+Back.YELLOW+Style.NORMAL
|
||||||
|
co_RdYlB = Fore.RED+Back.YELLOW+Style.BRIGHT
|
||||||
|
co_BlkLBlkD = Fore.BLACK+Back.LIGHTBLACK_EX+Style.DIM
|
||||||
|
co_BluLBlkD = Fore.BLUE+Back.LIGHTBLACK_EX+Style.DIM
|
||||||
|
co_cuBlu = '\33[38;5;122m'
|
||||||
|
# IP validate https://stackoverflow.com/questions/319279/how-to-validate-ip-address-in-python
|
||||||
|
ip_regx = "^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$"
|
||||||
|
|
||||||
|
def filtro_ip_propia(ip):
|
||||||
|
return True if ip != ownip else False
|
||||||
|
|
||||||
|
|
||||||
|
def consulta_db(ip_consulta):
|
||||||
|
consulta = f'https://ipinfo.io/{ip_consulta}{token}'
|
||||||
|
info_ip = requests.get(consulta).text
|
||||||
|
return loads(info_ip)
|
||||||
|
|
||||||
|
|
||||||
|
def consulta(ip_consulta):
|
||||||
|
consulta = f'https://ipinfo.io/{ip_consulta}'
|
||||||
|
info_ip = requests.get(consulta).text
|
||||||
|
info_ip = loads(info_ip)
|
||||||
|
for llave, valor in info_ip.items():
|
||||||
|
print(f'{co_YelB}{llave}\b\t{co_Blu}->{co_rst} {co_Grn}{valor}{co_rst}')
|
||||||
|
|
||||||
|
|
||||||
|
def ipLocate(ip):
|
||||||
|
if (re.search(ip_regx, ip)):
|
||||||
|
consulta(ip)
|
||||||
|
print(f'{co_RedB}------------------------------', end='')
|
||||||
|
print(f'--------------------------------{co_rst}')
|
||||||
|
else:
|
||||||
|
ipr = ip.split('\n')[0]
|
||||||
|
print(f'{co_Red}[{co_BlkMgn}{ipr}{co_rst}{co_Red}] no es una IP válida!{co_rst}')
|
||||||
|
|
||||||
|
|
||||||
|
def archivo_ips(ips):
|
||||||
|
with open(ips, 'r') as lista:
|
||||||
|
for linea in lista:
|
||||||
|
ipLocate(linea)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
match sys.argv[1]:
|
||||||
|
case '--sync':
|
||||||
|
print(f'{co_YelB}Sincronizando logs del servidor(bash script){co_rst}')
|
||||||
|
subprocess.check_call(
|
||||||
|
muevelog+"%s" % "--start",
|
||||||
|
shell=True)
|
||||||
|
case '-c':
|
||||||
|
print(f'{co_YelB}Cargando logs en base de datos{co_rst}')
|
||||||
|
sql_alch.carga_logs()
|
||||||
|
case '-g':
|
||||||
|
print(f'{co_YelB}Registrando datos de ipinfo{co_rst}')
|
||||||
|
sql_alch.registro_ips()
|
||||||
|
case '-f':
|
||||||
|
if isfile(sys.argv[2]):
|
||||||
|
archivo_ips(sys.argv[2])
|
||||||
|
else:
|
||||||
|
print(f'{co_Red}Archivo [{co_BlkMgn}{sys.argv[2]}'+
|
||||||
|
f'{co_rst}{co_Red}] no es válido''')
|
||||||
|
sys.exit(0)
|
||||||
|
case '-h':
|
||||||
|
uso()
|
||||||
|
exit(0)
|
||||||
|
case _:
|
||||||
|
ip = sys.argv[1]
|
||||||
|
ipLocate(ip)
|
||||||
|
except IndexError:
|
||||||
|
print(f'\n{co_Blu}Ingresa una {co_BluB}IP o \'s\' ',end='')
|
||||||
|
print(f'{co_Blu}para salir:{co_rst}')
|
||||||
|
while True:
|
||||||
|
ip = input(f'{co_BluB} -> {co_rst}')
|
||||||
|
if ip in 'sq0SQnN':
|
||||||
|
exit(0)
|
||||||
|
ipLocate(ip)
|
||||||
|
finally:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
def uso():
|
||||||
|
ayuda = f"""
|
||||||
|
{co_BluB}ipLocate{co_rst}
|
||||||
|
{co_cuBlu}Muestra información disponible en ipinfo.io sobre IPs consultadas.{co_rst}
|
||||||
|
|
||||||
|
{co_BluB}Uso:{co_rst}
|
||||||
|
{co_YelB}iploc {co_Blu}<IP> {co_Grn}- Muestra la información de <IP>.{co_rst}
|
||||||
|
{co_YelB}iploc -f {co_Blu}<archivo> {co_Grn}- Muestra info. de las IPs en <archivo>
|
||||||
|
{co_YelB}iploc -c {co_Grn}- Carga logs en base de datos.{co_rst}
|
||||||
|
{co_YelB}iploc -g {co_Grn}- Guarda ipinfo de IPs sin registro en la BD.{co_rst}
|
||||||
|
{co_YelB}iploc -h {co_Grn}- Muestra esta ayuda.{co_rst}
|
||||||
|
{co_YelB}iploc --sync {co_Grn}- Sincroniza logs del servidor (bash script).{co_rst}
|
||||||
|
|
||||||
|
"""
|
||||||
|
print(ayuda)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
161
muevelog.sh
Executable file
161
muevelog.sh
Executable file
@ -0,0 +1,161 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
Progrm=$0
|
||||||
|
VersionStr='2022-05-14'
|
||||||
|
rutaprgrm=$(dirname $(realpath -s $0))
|
||||||
|
|
||||||
|
while read line; do
|
||||||
|
declare "$line" 2>/dev/null
|
||||||
|
done < $rutaprgrm/config.cfg
|
||||||
|
|
||||||
|
|
||||||
|
REd="\e[0;31m"; GRn="\e[0;32m"; BLu="\e[0;34m";
|
||||||
|
RED="\e[1;31m"; GRN="\e[1;32m"; BLU="\e[1;34m";
|
||||||
|
RST="\e[0m";
|
||||||
|
|
||||||
|
Err(){
|
||||||
|
printf '%bERROR: %s%b\n' "${RED}" "$2" "${RST}" 1>&2
|
||||||
|
[ $1 -gt 0 ] && exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
Info(){
|
||||||
|
printf '%bINFO: %s%b\n' "${REd}" "$2" "${RST}" 1>&2
|
||||||
|
[ $1 -gt 0 ] && exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
Uso(){
|
||||||
|
while read; do
|
||||||
|
printf '%s\n' "$REPLY"
|
||||||
|
done <<-EOF
|
||||||
|
Ejecuta script del servidor que mueve los logs archivados, copia en ruta
|
||||||
|
de trabajo, concatena y elimina los archivos sobrantes.
|
||||||
|
|
||||||
|
Programa pensado para ser llamado por iplocate.py (muevelog.sh --start).
|
||||||
|
|
||||||
|
Operación manual: ./muevelog.sh [OPCION]
|
||||||
|
|
||||||
|
Ruta de trabajo: $destino_log
|
||||||
|
|
||||||
|
Opciones:
|
||||||
|
-s, --start - Copia, extrae y concatena logs.
|
||||||
|
-S, --sync - Mueve logs.gz en el servidor (Pre-Copia).
|
||||||
|
-C, --copia - Copia logs del servidor en ruta de trabajo (Post-sync).
|
||||||
|
-x, --extraer - Descomprime logs en ruta de trabajo.
|
||||||
|
-c, --concat [error.log, all...] - Concatena logs de la ruta de trabajo.
|
||||||
|
-v, --version - Muestra la fecha de la versión.
|
||||||
|
-h, --help - Muestra información de ayuda.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_logs(){
|
||||||
|
printf '%b - Sincronizando con %s%b\n' "${GRn}" "${server_name}" "${RST}"
|
||||||
|
ssh -M -t $server_name $server_script || Info 1 'No hay logs.gz en este momento'
|
||||||
|
}
|
||||||
|
|
||||||
|
copia_logs(){
|
||||||
|
mkdir "$destino_log" 2>/dev/null
|
||||||
|
if [[ "$(ls $destino_log/*.* 2>/dev/null)" ]]; then
|
||||||
|
Info 0 'Hay logs pendientes de ser cargados a base de datos\n'
|
||||||
|
else
|
||||||
|
printf '%b - Moviendo logs.gz%b' "${GRn}" "${RST}"
|
||||||
|
rsync --remove-source-files -ha --info=progress2 "${ruta_base}" "${destino_log}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
extrae_logs(){
|
||||||
|
if [[ "$(ls $destino_log/*.gz 2>/dev/null)" ]]; then
|
||||||
|
for file in $(ls $destino_log/*.gz); do
|
||||||
|
gunzip ${file}
|
||||||
|
done
|
||||||
|
else
|
||||||
|
Info 0 'No existen logs.gz para extraer!'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
concat_log(){
|
||||||
|
log_tipo="${1}"
|
||||||
|
if [[ "$(ls $destino_log/$log_tipo.* 2>/dev/null)" ]]; then
|
||||||
|
printf '%b - Concatenando log %s %b\n' "${GRn}" "${1}" "${RST}"
|
||||||
|
for file in $(\ls -v $destino_log/$log_tipo.*); do
|
||||||
|
cat $file >> $destino_log/$log_tipo
|
||||||
|
rm -f $file
|
||||||
|
done
|
||||||
|
else
|
||||||
|
Info 0 "No existen logs [${log_tipo}] para concatenar"
|
||||||
|
fi #2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
concatena_logs(){
|
||||||
|
concat_log access.log &&
|
||||||
|
concat_log error.log &&
|
||||||
|
concat_log reverse-access.log &&
|
||||||
|
concat_log reverse-error.log
|
||||||
|
}
|
||||||
|
|
||||||
|
main(){
|
||||||
|
printf '%b - Preparación del servidor, pre-copia:%b\n' "${GRN}" "${RST}" &&
|
||||||
|
sync_logs || Err 0 'Error al syncronizar!'
|
||||||
|
wait
|
||||||
|
printf '%b - Copiando logs del servidor en\n - %s :%b\n' "${GRN}" "${destino_log}" "${RST}" &&
|
||||||
|
copia_logs && printf '%b Copia completada%b\n' "${BLu}" "${RST}" || Err 0 'Error al copiar!'
|
||||||
|
wait
|
||||||
|
printf '%b - Descomprimiendo archivos gunzip%b\n' "${GRN}" "${RST}" &&
|
||||||
|
extrae_logs && printf '%b Extración completada%b\n' "${BLu}" "${RST}" ||
|
||||||
|
Err 0 'Error al descomprimir!'
|
||||||
|
wait
|
||||||
|
printf '%b - Concatenando archivos:%b\n' "${GRN}" "${RST}" && concatena_logs &&
|
||||||
|
printf '%b Archivos concatenados%b\n\n' "${BLu}" "${RST}" || Err 0 'Error al concatenar logs!'
|
||||||
|
printf '%bProceso terminado %b\n' "${BLU}" "${RST}"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "${1}" ]; then
|
||||||
|
case $1 in
|
||||||
|
--sync|-S)
|
||||||
|
sync_logs
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--copia|-C)
|
||||||
|
copia_logs
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--extraer|-x)
|
||||||
|
extrae_logs
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--concat|-c)
|
||||||
|
case ${2} in
|
||||||
|
access.log)
|
||||||
|
concat_log ${2} ;;
|
||||||
|
error.log)
|
||||||
|
concat_log ${2} ;;
|
||||||
|
reverse-access.log)
|
||||||
|
concat_log ${2} ;;
|
||||||
|
reverse-error.log)
|
||||||
|
concat_log ${2} ;;
|
||||||
|
all)
|
||||||
|
concatena_logs ;;
|
||||||
|
*)
|
||||||
|
Err 1 'Ingresa el tipo de log a concatenar (access.log, all, etc)' ;;
|
||||||
|
esac
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--help|-h)
|
||||||
|
Uso; exit 0
|
||||||
|
;;
|
||||||
|
--version|-v)
|
||||||
|
printf '%s\n' "$VersionStr"; exit 0
|
||||||
|
;;
|
||||||
|
--help|-h)
|
||||||
|
Uso; exit 0
|
||||||
|
;;
|
||||||
|
--start|-s)
|
||||||
|
main; exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
Err 1 'Argumento(s) invalido(s).' ;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
Err 1 'Debes incluir una opción. ej: --help'
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$@"
|
26
muevelogz.sh
Executable file
26
muevelogz.sh
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# logdest debe ser la misma ruta especificada en config.cfg como *ruta_base*
|
||||||
|
logdest=</ruta/user/docs/logs/nginx_log.old>
|
||||||
|
serv_user="${USER}"
|
||||||
|
|
||||||
|
logdir=/var/log/nginx
|
||||||
|
|
||||||
|
mueve_loggz(){
|
||||||
|
if [[ "$(ls $logdir/*.log.*.gz 2>/dev/null)" ]]; then
|
||||||
|
printf 'Moviendo logs.gz de %s/\n' "${logdir}"
|
||||||
|
sudo mv $logdir/*.log.*.gz $logdest
|
||||||
|
sudo chown $serv_user:$serv_user $logdest/*
|
||||||
|
else
|
||||||
|
printf 'No hay logs archivados para mover\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "$(ls $logdest/*.gz 2>/dev/null)" ]]; then
|
||||||
|
printf 'Existen logs pendientes de respaldo\n'
|
||||||
|
else
|
||||||
|
mueve_loggz
|
||||||
|
fi
|
||||||
|
exit 0
|
224
sql_alch.py
Normal file
224
sql_alch.py
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy import Column, Integer, String, Sequence, update
|
||||||
|
from sqlalchemy.orm.session import Session
|
||||||
|
from sqlalchemy.sql.expression import select
|
||||||
|
import iplocate as ipl
|
||||||
|
|
||||||
|
logs_dir = ipl.parser.get('bash_script', 'destino_log')
|
||||||
|
logs_dir = logs_dir.strip("'")
|
||||||
|
base_de_datos = f'sqlite:////{ipl.selfpath}/ipinfo.db'
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
class Visita(Base):
|
||||||
|
__tablename__ = 'visita'
|
||||||
|
id = Column(Integer, Sequence('visita_id_seq'), primary_key=True)
|
||||||
|
ip = Column(String)
|
||||||
|
html = Column(Integer)
|
||||||
|
fecha = Column(Integer)
|
||||||
|
registro = Column(Integer, default=0)
|
||||||
|
|
||||||
|
def get_fecha(self):
|
||||||
|
return time.asctime(time.localtime(int(self.fecha.__repr__())))
|
||||||
|
|
||||||
|
def fecha_local(self):
|
||||||
|
fecha_l = self.get_fecha()
|
||||||
|
#fecha_l = time.asctime(self.fecha)
|
||||||
|
return fecha_l
|
||||||
|
#fecha_l = time.strftime(fecha_l)
|
||||||
|
|
||||||
|
def consulta_registro(self):
|
||||||
|
return True if self.registro == 1 else False
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return "ID: {}\nIP: {}\nHtmlCode: {}\n" \
|
||||||
|
"Fecha: {}\nRegistrado: {}\n".format(
|
||||||
|
self.id,
|
||||||
|
self.ip,
|
||||||
|
self.html,
|
||||||
|
self.get_fecha(),
|
||||||
|
self.consulta_registro())
|
||||||
|
|
||||||
|
|
||||||
|
# Tabla registro ip info
|
||||||
|
class Registro(Base):
|
||||||
|
__tablename__ = 'registro'
|
||||||
|
id = Column(Integer, Sequence('registro_id_seq'), primary_key=True)
|
||||||
|
ip = Column(String)
|
||||||
|
hostname = Column(String, nullable=True)
|
||||||
|
anycast = Column(String, nullable=True)
|
||||||
|
cuidad = Column(String, nullable=True)
|
||||||
|
region = Column(String, nullable=True)
|
||||||
|
pais = Column(String, nullable=True)
|
||||||
|
geoloc = Column(String, nullable=True)
|
||||||
|
organizacion = Column(String, nullable=True)
|
||||||
|
fecha_reg = Column(Integer, default=int(time.mktime(time.localtime())))
|
||||||
|
tzone = Column(String, nullable=True)
|
||||||
|
cod_post = Column(String, nullable=True)
|
||||||
|
link = Column(String, nullable=True)
|
||||||
|
|
||||||
|
|
||||||
|
engine = create_engine(base_de_datos)
|
||||||
|
Base.metadata.create_all(engine)
|
||||||
|
#Base.metadata.create_all(engine.execution_options(synchronize_session="fetch"))
|
||||||
|
Session = sessionmaker(bind=engine)
|
||||||
|
session = Session()
|
||||||
|
|
||||||
|
|
||||||
|
# Formatos fechas logs:
|
||||||
|
"""
|
||||||
|
# access.log == reverse_access.log
|
||||||
|
# error.log == reverse_error.log
|
||||||
|
fecha_error = "2022/05/10 07:11:46"
|
||||||
|
fecha_access = "10/May/2022:11:42:14 -0400".split(' ')[0]
|
||||||
|
"""
|
||||||
|
|
||||||
|
def fecha_access_to_epoch(fecha):
|
||||||
|
"""Convierte al fecha del formato entregado por access.log
|
||||||
|
y reverse_access.log(nginx) al formato unix epoch.
|
||||||
|
|
||||||
|
:fecha: str Fecha
|
||||||
|
:returns: int unix epoch fecha (secs)
|
||||||
|
"""
|
||||||
|
fecha = datetime.strptime(fecha, '%d/%b/%Y:%H:%M:%S')
|
||||||
|
fecha_unix = int(time.mktime(fecha.timetuple()))
|
||||||
|
return fecha_unix
|
||||||
|
|
||||||
|
def fecha_error_to_epoch(fecha):
|
||||||
|
"""Convierte al fecha del formato entregado por error.log
|
||||||
|
y reverse_error.log (nginx) al formato unix epoch.
|
||||||
|
|
||||||
|
:fecha_local: str Fecha
|
||||||
|
:returns: int unix epoch fecha (secs)
|
||||||
|
"""
|
||||||
|
fecha = datetime.strptime(fecha, '%Y/%m/%d %H:%M:%S')
|
||||||
|
fecha_unix = int(time.mktime(fecha.timetuple()))
|
||||||
|
return fecha_unix
|
||||||
|
|
||||||
|
def epoch_to_local(fecha):
|
||||||
|
"""Convierte fecha unix epoch a localtime
|
||||||
|
|
||||||
|
:fecha: int Fecha (secs)
|
||||||
|
:returns: str Fecha
|
||||||
|
"""
|
||||||
|
return time.asctime(time.localtime(int(fecha)))
|
||||||
|
|
||||||
|
|
||||||
|
def ip_registrada(ip):
|
||||||
|
ip_reg = session.query(Visita).filter(Visita.ip==ip).filter(Visita.registro==1).first()
|
||||||
|
return 0 if ip_reg is None else ip_reg.registro
|
||||||
|
|
||||||
|
|
||||||
|
def carga_access_log(log):
|
||||||
|
if os.path.exists(log):
|
||||||
|
print(f'{ipl.co_Yel}Registrando [{log}]{ipl.co_rst}')
|
||||||
|
try:
|
||||||
|
with open(log, 'r') as lista:
|
||||||
|
for linea in lista:
|
||||||
|
ip = linea.split(' ')[0]
|
||||||
|
if ipl.filtro_ip_propia(ip):
|
||||||
|
fecha = fecha_access_to_epoch(linea.split(' ')[3][1:])
|
||||||
|
codigo= int(linea.split('"')[2].split(' ')[1])
|
||||||
|
if ip_registrada(ip):
|
||||||
|
session.add(Visita(ip=ip, html=codigo, fecha=fecha, registro=1))
|
||||||
|
else:
|
||||||
|
session.add(Visita(ip=ip, html=codigo, fecha=fecha))
|
||||||
|
session.commit()
|
||||||
|
print(f'{ipl.co_Grn}Carga completa.. borrando log{ipl.co_rst}\n')
|
||||||
|
os.remove(log)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
print(f'{ipl.co_Red}Ocurrio un error al intentar abrir/cargar: [{log}]{ipl.co_rst}\n')
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print(f'{ipl.co_Red}log: [{log}] inexistente.{ipl.co_rst}\n')
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def carga_error_logs(log):
|
||||||
|
if os.path.exists(log):
|
||||||
|
print(f'{ipl.co_Yel}Registrando [{log}]{ipl.co_rst}')
|
||||||
|
try:
|
||||||
|
with open(log, 'r') as lista:
|
||||||
|
for linea in lista:
|
||||||
|
ip = linea.split('client: ')[1].split(',')[0]
|
||||||
|
if ipl.filtro_ip_propia(ip):
|
||||||
|
fecha = fecha_error_to_epoch(' '.join(linea.split()[0:2]))
|
||||||
|
codigo = 300
|
||||||
|
if ip_registrada(ip):
|
||||||
|
session.add(Visita(ip=ip, html=codigo, fecha=fecha, registro=1))
|
||||||
|
else:
|
||||||
|
session.add(Visita(ip=ip, html=codigo, fecha=fecha))
|
||||||
|
session.commit()
|
||||||
|
print(f'{ipl.co_Grn}Carga completa.. borrando log{ipl.co_rst}\n')
|
||||||
|
os.remove(log)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
print(f'{ipl.co_Red}Ocurrio un error'+
|
||||||
|
f'al intentar abrir/cargar: [{log}]{ipl.co_rst}\n')
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print(f'{ipl.co_Red}log: [{log}] inexistente.{ipl.co_rst}\n')
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def carga_logs():
|
||||||
|
print(f'{ipl.co_Grn}Carga de logs en base de datos:{ipl.co_rst}\n')
|
||||||
|
carga_access_log(logs_dir+'/access.log')
|
||||||
|
carga_access_log(logs_dir+'/reverse-access.log')
|
||||||
|
carga_error_logs(logs_dir+'/error.log')
|
||||||
|
carga_error_logs(logs_dir+'/reverse-error.log')
|
||||||
|
|
||||||
|
|
||||||
|
def carga_registro_ip(ip_info):
|
||||||
|
if not ip_registrada(ip_info['ip']):
|
||||||
|
info_dic = {}
|
||||||
|
info_dic['ip'] = ip_info['ip']
|
||||||
|
info_dic['hostname'] = ip_info['hostname'] if 'hostname' in ip_info else None
|
||||||
|
info_dic['anycast'] = ip_info['anycast'] if 'anycast' in ip_info else None
|
||||||
|
info_dic['ciudad'] = ip_info['city'] if 'city' in ip_info else None
|
||||||
|
info_dic['region'] = ip_info['region'] if 'region' in ip_info else None
|
||||||
|
info_dic['pais'] = ip_info['country'] if 'country' in ip_info else None
|
||||||
|
info_dic['geoloc'] = ip_info['loc'] if 'loc' in ip_info else None
|
||||||
|
info_dic['organizacion'] = ip_info['org'] if 'org' in ip_info else None
|
||||||
|
info_dic['tzone'] = ip_info['timezone'] if 'timezone' in ip_info else None
|
||||||
|
info_dic['cod_post'] = ip_info['postal'] if 'postal' in ip_info else None
|
||||||
|
info_dic['link'] = ip_info['readme'] if 'readme' in ip_info else None
|
||||||
|
session.add(Registro( ip = info_dic['ip'],
|
||||||
|
hostname = info_dic['hostname'],
|
||||||
|
anycast = info_dic['anycast'],
|
||||||
|
cuidad = info_dic['ciudad'],
|
||||||
|
region = info_dic['region'],
|
||||||
|
pais = info_dic['pais'],
|
||||||
|
geoloc = info_dic['geoloc'],
|
||||||
|
organizacion = info_dic['organizacion'],
|
||||||
|
fecha_reg = int(time.mktime(time.localtime())),
|
||||||
|
tzone = info_dic['tzone'],
|
||||||
|
cod_post = info_dic['cod_post'],
|
||||||
|
link = info_dic['link'],
|
||||||
|
))
|
||||||
|
session.commit()
|
||||||
|
stmt = update(Visita).where(Visita.ip == ip_info['ip']).values(registro=1).\
|
||||||
|
execution_options(synchronize_session="fetch")
|
||||||
|
#result = session.execute(stmt)
|
||||||
|
session.execute(stmt)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def registro_ips():
|
||||||
|
registrar = True
|
||||||
|
while registrar:
|
||||||
|
statement = select(Visita).filter_by(registro=0)
|
||||||
|
res = session.execute(statement).scalars().first()
|
||||||
|
if res is None:
|
||||||
|
print(f'{ipl.co_Grn}Registro ipinfo en DB finzalizado.{ipl.co_rst}')
|
||||||
|
registrar = False
|
||||||
|
#ip_actual= res.ip.split('\n')[0]
|
||||||
|
ip_actual= res.ip
|
||||||
|
ip_info = ipl.consulta_db(ip_actual)
|
||||||
|
carga_registro_ip(ip_info)
|
Loading…
Reference in New Issue
Block a user