miércoles, 14 de diciembre de 2022

Eliminar miembros de un grupo de Active Directory



Cómo eliminar automáticamente mimebros de un grupo de Active Directory con PowerShell.



Tenemos un grupo de usuaros de Active Directory con cientos de miembros. Queremos eliminar varios miembros de golpe, por ejemplo 50 miembros, y no queremos hacerlo manualmente.

Para automatizar el eliminado de miembros de un grupo de Active Directory podemos usar un script de PowerShell con la función Remove-ADGroupMember:

$users = Get-Content "C:\Temp\mimebros.csv"

 foreach ($user in $users) {
    $obj = Get-ADUser $user
    Remove-ADGroupMember -ID Nombre_Grupo -Members $obj -Confirm:$false
}

Dentro de miembros.csv se debe escribir un nombre de usuario en cada línea.

Lo que hace el script es leer línea a línea el archivo csv y para cada línea, es decir, para cada usuario, eliminarlo del grupo "Nombre_Grupo" sin pedir confirmación.

Una vez ejecutado el script, los usuarios contenidos en el archivo csv ya no aparecerán en el grupo llamado "Nombre_Grupo".

miércoles, 2 de noviembre de 2022

Unable to open primary script (Permission denied)



Cómo configurar nginx para funcionar como webserver en SLES 15.



Instalé NGINX en un SLES 15 SP4 para hospedar una web, pero al ir a ver el index.php me encontré con el siguiente mensaje de error en el navegador:

An error occurred.

Sorry, the page you are looking for is currently unavailable.
Please try again later.


If you are the system administrator of this resource then you should check the error log for details.

Faithfully yours, nginx.

Al mirar los logs de error de nginx vi:

FastCGI sent in stderr: "Unable to open primary script: /srv/www/htdocs/index.php (Permission denied)" *3 FastCGI sent in stderr: "Unable to open primary script: /srv/www/htdocs/index.php (Permission denied)" while reading response header from upstream, client: 1.1.1.1, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "web.com"

Después de jugar con permisos durante algunas horas, di con que podría ser un problema de AppArmor, pero deshabilitarlo no surgió efecto.

Lo que sí funcionó fue poner AppArmor en modo "aa-complain" para php-fpm:

HOST # aa-complain php-fpm Setting /usr/sbin/php-fpm to complain mode. Warning: profile php-fpm represents multiple programs Warning: profile php-fpm represents multiple programs

Una vez hecho esto, reinicié el servicio nginx y la web empezó a funcionar :)


Fuentes:

https://documentation.suse.com/sles/15-SP4/html/SLES-all/cha-apparmor-intro.html
0

miércoles, 31 de agosto de 2022

Ver parches instalados en un SUSE Linux



Cómo ver el historial de todos los parches instalados en SLES (SUSE Linux Enterprise Server).



En una auditoría de seguridad me pidieron que presentara un listado que mostrara todos los parches instalados en un sistema SUSE Linux Enterprise Server durante el año en curso. Tras investigar un poco, di con las siguientes maneras de encontrar dicha información.


Histórico


SLES guarda un histórico de actualizaciones en /var/log/zypp/history:

HOST # cat /var/log/zypp/history 2022-08-31 12:08:56 | install | hwinfo | 21.82-150300.3.3.1 | x86_64 ||Basesystem_Module_15_SP3_x86_64:SLE-Module-Basesystem15-SP3-Updates|4cb0aad9e2148b3290877e3903a9792bfb31bfc7b9cb883a5088b6e04387d682| 2022-08-31 12:08:57 | install | glibc-locale-base | 2.31-150300.37.1 | x86_64 ||Basesystem_Module_15_SP3_x86_64:SLE-Module-Basesystem15-SP3-Updates|e13d47fd5e6a0cc73f5c469d16360b40c7c77ae560425c34c96e5fd67e8edae6| 2022-08-31 12:08:57 | install | glibc-lang | 2.31-150300.37.1 | noarch ||Basesystem_Module_15_SP3_x86_64:SLE-Module-Basesystem15-SP3-Updates|17185b24afb65caf58422923d28942ea7dc08efba88fde4608fca106f1b84879| 2022-08-31 12:08:57 | install | Mesa-libglapi0 | 20.2.4-150300.59.3.1 | x86_64 ||Basesystem_Module_15_SP3_x86_64:SLE-Module-Basesystem15-SP3-Updates|6170c01d46ec4b79feab1a1d5381e4328ca325f9134f73b4d80b01729c32446b| 2022-08-31 12:08:57 | install | libz1-32bit | 1.2.11-150000.3.33.1 | x86_64 ||Basesystem_Module_15_SP3_x86_64:SLE-Module-Basesystem15-SP3-Updates|fd6f29c14574b6daa8c8af6a17949ac9d9d68c71b7ac143a714eaa4815fee937| 2022-08-31 12:08:57 | install | libudev1-32bit |246.16-150300.7.51.1 | x86_64 ||Basesystem_Module_15_SP3_x86_64:SLE-Module-Basesystem15-SP3-Updates|39993ba30db3639e359662c4a70333b5f54718622309984e0c6e9a43bd08be00| 2022-08-31 12:08:57 | install | libsystemd0-32bit |246.16-150300.7.51.1 | x86_64 ||Basesystem_Module_15_SP3_x86_64:SLE-Module-Basesystem15-SP3-Updates|19aef524977d87bf6c4ba27e810c6e0ad849d68389cdbda5469a778895d01095| 2022-08-31 12:08:57 | install | libpcre1-32bit |8.45-150000.20.13.1 | x86_64 ||Basesystem_Module_15_SP3_x86_64:SLE-Module-Basesystem15-SP3-Updates|75a6cf6909f11a956935c6612cbac7509f33e7dca1dee6165c2698122a0be1ca| ...

Usando grep, podemos filtrar los resultados por año:

HOST # cat /var/log/zypp/history | grep 2022 | grep -E 'patch|install'


Listado


Por otro lado, podemos ver una lista con todos los parches instalados usando el siguiente comando:

HOST # zypper search --type patch --installed-only Loading repository data... Reading installed packages... S | Name | Summary | Type --+---------------------------------------------+-----------------------------+------ i | SUSE-SLE-Module-Basesystem-15-SP3-2021-1474 | Security update for ceph | patch i | SUSE-SLE-Module-Basesystem-15-SP3-2021-1481 | Recommended update for lvm2 | patch i | SUSE-SLE-Module-Basesystem-15-SP3-2021-1491 | Security update for p7zip | patch i | SUSE-SLE-Module-Basesystem-15-SP3-2021-1493 | Security update for avahi | patch i | SUSE-SLE-Module-Basesystem-15-SP3-2021-1523 | Security update for libxml2 | patch ...

Si queremos listar los parches por el CVE al que hacen referencia:

HOST # zypper list-patches --cve The following matches in issue numbers have been found: Issue | No. | Patch | Category | Severity | Status ------+---------------+-------------------+-------------+-----------+---------- cve | CVE-2015-0287 | SUSE-SLE-Module.. | recommended | moderate | needed cve | CVE-2014-3566 | SUSE-SLE-SERVER.. | recommended | moderate | not needed ...


Fuentes:

https://documentation.suse.com/sles/15-SP3/pdf/book-sle-admin_color_en.pdf
0

miércoles, 24 de agosto de 2022

Esconder la cabecera Server en nginx



Cómo esconder la versión de nginx o la cabecera server por completo.



Tras una auditoría de seguridad se me ha pedido esconder la versión de nginx corriendo en un servidor.

nginx, tanto en su versión plus como en su versión open source, permite esconder la versión que corre un servidor mediante la directiva server_tokens. Eso es útil para esconder la versión de nginx que se muestra en las páginas de error y en la cabecera Server de cada respuesta.

Las distintas posibilidades de sintaxis son las siguientes:

- server_tokens on: muestra la versión de nginx.
- server_tokens off: no muestra la versión de nginx.
- server_tokens build: muestra el nombre del build junto a la versión.
- server_tokens "string": muestra un string personalizado (plus).
- server_tokens "": no muestra la cabecera server (plus).

Por defecto nginx usa "server_tokens on", es decir, muestra la versión instalada de nginx.

Si quisieramos esconder la versión, como se me pedía a mi, podríamos usar:

server_tokens off;

Esta directiva se puede usar en distintos contextos:

- http: todos los dominios.
- server: un dominio concreto.
- location: una ruta dentro de un dominio concreto.

Asimismo, las dos últimas posibilidades (string personalizado y esconder el nombre del software) sólo están disponibles en nginx plus (la subscripción comercial) desde la versión 1.9.13.

Si queremos obtener los mismos resultados con la versión open source, siempre podemos compilar el código fuente de nginx eliminando todas las referencias a la versión o a nginx en sí mismo.


Fuentes:

http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens
0

miércoles, 3 de agosto de 2022

Compartir directorios entre servidores vía NFS



Cómo compartir directorios vía NFS entre servidores Linux.



A continuación un pequeño manual de cómo compartir directorios entre sistemas Linux vía NFS.


Servidor


En el lado servidor, instalamos el paquete nfs-server:

HOST # zypper in nfs-server*

Añadimos la entrada del host que se conectará a este servidor en la lista de entradas permitidas:

HOST # cat /etc/exports # See the exports(5) manpage for a description of the syntax of this file. # This file contains a list of all directories that are to be exported to # other computers via NFS (Network File System). # This file used by rpc.nfsd and rpc.mountd. See their manpages for details # on how make changes in this file effective. /carpetaexportada/ 10.100.200.2(rw,sync,no_root_squash)

Arrancamos el servicio nfs-server:

HOST # service nfs-server start

Lo hacemos permanente:

HOST # systemctl enable nfs-server Created symlink /etc/systemd/system/multi-user.target.wants/nfs-server.service → /usr/lib/systemd/system/nfs-server.service.

Exportamos el share:

HOST # exportsfs -a


Cliente


En el cliente, montamos el share en /etc/fstab:

10.120.200.1:/carpetaexportada /montajelocal nfs defaults 0 0

Remontamos todo:

HOST # mount -a

Mostramos las carpetas remotas compartidas:

HOST # showmount -e 10.100.200.1 Export list for 10.100.200.2: /carpetaexportada 10.100.200.1
0

miércoles, 6 de julio de 2022

Nginx socket() failed (24: Too many open files)



Cómo solucionar el error "too many open files" en NGINX.



Al acceder a una web que pasaba a través de NGINX en modo reverse proxy, he visto que esta no era accesible y me he encontrado el siguiente log en su archivo de log:

2021/07/06 12:21:23 [alert] 28720#0: *59757 socket() failed (24: Too many open files) while connecting to upstream,

Esto ha ocurrido porque NGINX tenía demasiados archivos abiertos. Recordemos que, por defecto, NGINX puede abrir un máximo de 4096 archivos simultáneos por worker.

Para saltarnos esta limitaxción, deberemos usar el parámetro "worker_rlimit_nofile", el cual deberemos añadir al archivo /etc/nginx/nginx.conf antes del bloque http:

# Increase open files worker_rlimit_nofile 30000;

En el ejemplo anterior le estamos diciendo a NGINX que puede abrir un máximo de 30.000 archivos, lo cual debería ser suficiente para proxys con una cantidad elevada de peticiones por segundo.

Para aplicar los cambios, reiniciamos NGINX:

service nginx restart

Luego comprobamos que la config. se ha aplicado correctamente:

HOST # ps -ef | grep nginx root 5092 1 0 09:33 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 5093 5092 13 09:33 ? 00:37:06 nginx: worker process

Nos fijamos en el worker process, servicio con PID 5093 y miramos sus límites:

HOST # cat /proc/5093/limits | grep "open files" Max open files 30000 30000 files


Fuentes:

https://www.claudiokuenzler.com/blog/850/nginx-socket-failed-24-too-many-open-files
0

miércoles, 1 de junio de 2022

NGINX: página de error 403 personalizada



Cómo personalizar la página de error 403 Forbidden en NGINX.



Por defecto, NGINX muestra una página de error 403 Forbidden muy básica. Lo bueno es que podemos personalizarla a nuestro gusto creando un documento HTML y enlazándolo desde la config. de NGINX.

Primero creamos un documento HTML:

<html> <head><title>Error 403 – Acceso denegado</title></head> <body> No tienes permisos suficientes para acceder a esta página. </body> </html>

Cuando hayamos creado el documento, lo guardamos en la ruta "root" de la web:

A continuación, editamos el fichero /etc/nginx/nginx.conf y añadimos:

... server { ... error_page 403 /error403.html; location /error403.html { allow all; } ... } ...

Destacar que la config. que nos permite personalizar el error 403 debe estar dentro del bloque "server" para un dominio o subdominio concreto.

En el código anterior se le dice a NGINX que muestre el archivo error403.html cada vez que ocurra un error 403 en el acceso a la web. Adicionalmente, se debe especificar explícitamente que todo el mundo pueda leer este archivo, de lo contrario, se mostrará la página de error 403 predeterminada de NGINX y nuestro trabajo no habrá servido para nada.
0

miércoles, 4 de mayo de 2022

Exportar lista de usuarios de un grupo de AD



Cómo exportar todos los usuarios de un grupo de Active Directory.



Imaginemos que queremos enviar un correo a todos los usuarios de un grupo concreto de Active Directory. Primero, deberemos saber qué usuarios hay en el grupo.

Para ver los usuarios y sus direcciones de correo, deberemos exportar los campos nombre y mail de los usuarios. Para ello, podemos usar la función Get-AdGroupMember:

$GroupName = 'Nombre del grupo'
Get-AdGroupMember -Identity $GroupName | Get-AdUser -Properties * | Select Name,Mail

El output del script será:

Name Mail -------------- ----------------- Marc Garcia marc.garcia@una.org Alberto Perez alberto.perez@una.org ...

De esta forma veremos el output en la terminal.

Si queremos exportar el resultado a un archivo csv podemos usar la función Export-csv:

$GroupName = 'Nombre del grupo'
$ExportPath = 'C:\Temp\export.csv'
Get-AdGroupMember -Identity $GroupName | Get-AdUser -Properties * | Select Name,Mail | Export-csv -NoTypeInformation $ExportPath

En este caso, el resultado será un archivo csv con los campos separados por comas:

"Marc García","marc.garcia@una.org" "Alberto Perez","alberto.perez@una.org" ...

Una vez obtenido el archivo csv, ya lo podremos manipular con Excel para extraer solo las direcciones de correo o eliminar ciertos usuarios, entre otros.


Fuentes:

https://shellgeek.com/powershell-export-active-directory-group-members/

miércoles, 6 de abril de 2022

Extraer .crt de un fichero .pfx



Comprobar si un certificado en formato PFX tiene un password asociado.



Si alguien nos envía un fichero .pfx que contiene un certificado generado para ser usado en un servidor Windows, necesitamos extraer la parte pública del certificado (el fichero .crt).


Exportar certificado (IIS)


Abrimos el Microsoft Management Console (mmc).

Ir a File > Add/Remove Snap-in.

Doble clic en Certificates.

Seleccionar Computer account.

Seleccionar Local computer y clic en Finish.

Ir a Console Root > Certificates > Certificate Enrollment Requests.

Clic derecho en el certificado y seleccionar All Tasks > Export.

Selecciona Yes, export the private key.

Selecciona Personal Information Exchange – PKCS #12.

Entra un password para proteger tu private key (obligatorio).

Seleccionar la ubicación dodne guardar la private key.

Clica Finish.

La clave privada se exporta como archivo .pfx.


Extraer .crt del .pfx


Ahora toca extraer el .crt del .pfx. Para ello, podemos usar la utilidad openssl en Windows/Linux:

HOST# openssl pkcs12 -in archivo.pfx -clcerts -nokeys -out archivo.crt

Donde archivo.pfx es el origen y archivo.crt el fichero que se generará.

Ya podemos usar el fichero .crt en nuestro servidor Linux.
0

miércoles, 16 de marzo de 2022

nginx: [emerg] getgrnam("deploy") failed



Cómo cambiar el usuario desde el que se ejecuta NGINX.



Hoy me han pedido que cambie el usuario desde el que se ejecuta nginx de "nginx" a "deploy", y me he encontrado algún problema durante el proceso.

Primero he comentado la línea:

user nginx;

y he añadido la línea:

user deploy;

dentro de /etc/nginx/nginx.conf.

A continuación, he comprobado la validez del fichero de confgiuración con:

HOST:/ # nginx -t nginx: [emerg] getgrnam("deploy") failed in /etc/nginx/nginx.conf:2 nginx: configuration file /etc/nginx/nginx.conf test failed

Tras buscar por internet he encontrado que se debe espcificar el nombre del grupo después del nombre de usuario (con un espacio en blanco entre ellos), es decir:

user usuario grupo;

Si no se especifica el grupo, NGINX toma como nombre de grupo el nombre de usuario.

Para aplicar este cambio de configuración, primero he comprobado su validez:

HOST:/ # nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

Acto seguido, he cargado la nueva configuración:

nginx -s reload

Tras este reload, nginx arrojaba un error 500 al navegar por la web, por lo que he optado por reiniciar el servicio nginx por completo:

systemctl restart nginx

Tras reiniciar el servicio, la web ha funcionado con normalidad.
0

miércoles, 26 de enero de 2022

AWS cli: recuperar versión de un fichero en S3



Cómo recuperar una versión concreta de un fichero alojado en un bucket S3 de AWS.



Veamos cómo recuperar una versión concreta de un fichero alojado en un bucket S3 de AWS.

En este ejemplo, el bucket se llama "blai-1".

Primero de todo, debemos tener habilitado o habilitar el versionado:

[ec2-user@ip-10-5-0-143 ~]$ aws s3api put-bucket-versioning --bucket s3-blai-1 --versioning-configuration Status=Enabled

Imaginemos que tenemos 3 ficheros en el bucket "blai-1":

[ec2-user@ip-10-5-0-143 ~]$ aws s3 ls s3://s3-blai-1/files/ 2021-11-24 11:56:31 30318 file1.txt 2021-11-24 11:56:32 43784 file2.txt 2021-11-24 11:56:32 96675 file3.txt

Borramos file1.txt en local:

[ec2-user@ip-10-5-0-143 ~]$ sudo rm files/file1.txt sudo rm files/file1.txt

Hacemos un sync de archivos con el flag delete (borra en el bucket aquello que no exista en local):

[ec2-user@ip-10-5-0-143 ~]$ aws s3 sync files s3://s3-blai-1/files/ --delete delete: s3://s3-blai-1/files/file1.txt

Tras la instrucción anterior, listamos los ficheros presentes en el bucket:

[ec2-user@ip-10-5-0-143 ~]$ aws s3 ls s3://s3-blai-1/files/ 2021-11-24 11:56:32 43784 file2.txt 2021-11-24 11:56:32 96675 file3.txt

Observamos que file1.txt ya no existe.

De repente necesitamos el file1.txt. Listamos sus versiones:

[ec2-user@ip-10-5-0-143 ~]$ aws s3api list-object-versions --bucket s3-blai-1 --prefix files/file1.txt { "DeleteMarkers": [ { "Owner": { "DisplayName": "aws038351", "ID": "2a6f0ac58291262d92b44b112cda554a8cf030cd5d4d742a7b60af5a5b89fd86" }, "IsLatest": true, "VersionId": "Nd1QvuJY56xi7nFHSC2ej_3nvm7xvw1u", "Key": "files/file1.txt", "LastModified": "2021-11-24T11:57:35.000Z" } ], "Versions": [ { "LastModified": "2021-11-24T11:56:31.000Z", "VersionId": "M3YMFwyIciILCfa.VX3pRdlLJkheUjy1", "ETag": "\"b76b2b775023e60be16bc332496f8409\"", "StorageClass": "STANDARD", "Key": "files/file1.txt", "Owner": { "DisplayName": "aws038351", "ID": "2a6f0ac58291262d92b44b112cda554a8cf030cd5d4d742a7b60af5a5b89fd86" }, "IsLatest": false, "Size": 30318 } ] }

Recuperamos la versión M3YMFwyIciILCfa.VX3pRdlLJkheUjy1 del fichero file1.txt, con fecha 2021-11-24T11:56:31.000Z:

[ec2-user@ip-10-5-0-143 ~]$ sudo aws s3api get-object --bucket s3-blai-1 --key files/file1.txt --version-id M3YMFwyIciILCfa.VX3pRdlLJkheUjy1 files/file1.txt { "AcceptRanges": "bytes", "ContentType": "text/plain", "LastModified": "Wed, 24 Nov 2021 11:56:31 GMT", "ContentLength": 30318, "VersionId": "M3YMFwyIciILCfa.VX3pRdlLJkheUjy1", "ETag": "\"b76b2b775023e60be16bc332496f8409\"", "Metadata": {} }

Listamos los ficheros en local:

[ec2-user@ip-10-5-0-143 ~]$ ls -la 2022-01-26 11:56:31 30318 file1.txt 2021-11-24 11:56:32 43784 file2.txt 2021-11-24 11:56:32 96675 file3.txt

Sincornizamos los ficheros hacia el bucket:

[ec2-user@ip-10-5-0-143 ~]$ aws s3 sync files s3://s3-blai-1/files/ upload: files/file1.txt to s3://s3-blai-1/files/file1.txt

Listamos los ficheros del bucket:

[ec2-user@ip-10-5-0-143 ~]$ aws s3 ls s3://s3-blai-1/files/ 2022-01-26 11:00:18 30318 file1.txt 2021-11-24 11:56:32 43784 file2.txt 2021-11-24 11:56:32 96675 file3.txt

Tras el sync, file1.txt vuelve a estar presente.
0