ぶろぐ

日記です

laravel-adminで独自ログイン認証を実装

github.com

基本は上記のとおりでいいが、Model(Authenticatable) に下記をmixinする必要がある。

対象trait

Encore\Admin\Auth\Database\HasPermissions;
Encore\Admin\Traits\AdminBuilder;

対象interface

Illuminate\Contracts\Auth\Authenticatable;

// admin_permissionsとかadmin_operation_logを本当は無効にしたいがめんどいのでやっていない

pythonとphpで相互に暗号化/復号化を行う

pythonで `Simple-AES-Cipher` を使って暗号化された文字列を復号化する。

`Simple-AES-Cipher` を使った場合デフォルトの暗号化方式はaes-256-cbcで、initialization vectorにランダムの文字列が使われる。
返り値はinitialization vector + 暗号化された文字列のbase64となる。

phpでは以下の手順をふみ、復号化する。

  • base64デコード
  • initialization vectorと暗号化を分ける。
  • openssl_decryptにそれぞれのパラメーターを渡す

以下テストコード。

'12345678901234567890123456789012' を共通で使用するkeyとする。

python で "php man" を暗号化

from simple_aes_cipher import AESCipher

cipher = AESCipher('12345678901234567890123456789012')
cipher.encrypt('php man')
# 0DbgJCpQDDvH8vNs1teJWaSk3U7mGsEdnA/mfg3r0bw=

php で "php man" に復号化

<?php
$key = "12345678901234567890123456789012";

$encrypted_by_python = '0DbgJCpQDDvH8vNs1teJWaSk3U7mGsEdnA/mfg3r0bw=';

$decoded = base64_decode($encrypted_by_python);
$iv = substr($decoded, 0, 16);
$encrypted = substr($decoded, 16);

$encrypted = openssl_decrypt($encrypted, 'aes-256-cbc', $key, true, $iv);
// php man

無事OK。

vi(initialization vector)ってなんだ

initialization vectorはECBモードの脆弱さをなくすために作られたらしい。

CBC暗号モードの初期値は、敵から見えてもかまわないことになっていますが、毎回違う値を利用することが推奨されています。

ふーむ。

ブロック暗号モード(block cipher mode)

CBCモードでは、前の平文ブロックを暗号化した結果を次の平文に XOR 演算によって重ね合わせ、その結果に対して暗号化処理を行います。

なるほど。ECBモードに存在した、

  • 同じ鍵で暗号化したデータは同じ暗号文になるため、元の平文データを推測しやすい。仮にphp manの暗号文がxxx だった場合、xxxという暗号文はphp manという事がわかってしまう。
  • 改ざん検知機能がない

っていうのを改善しているわけだ。改ざん検知機能は不産物感あるな。

オンラインでEBSのボリューム拡張した

昔できなかったのに、2017年ぐらいからできるようになったらしい。

デフォルトの8GBのEBSだけをマウントしているインスタンスで実行。

手順は以下。

1. aws web consoleでボリュームを拡張。50GBに。
2. /dev/xvda1 パーティションが切られていいたため、パーティションサイズを拡張
3. resize2fsでディスク領域を拡張

# ディスクを増やしてもパーティションサイズが8GBのまま
[ec2-user@xx ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  50G  0 disk
└─xvda1 202:1    0   8G  0 part /

# パーティションサイズを拡張
[ec2-user@xx ~]$ sudo growpart /dev/xvda 1
CHANGED: disk=/dev/xvda partition=1: start=4096 old: size=16773086,end=16777182 new: size=104853470,end=104857566

# 50Gになっていることを確認
[ec2-user@xx ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  50G  0 disk
└─xvda1 202:1    0  50G  0 part /

# マウントしているパーティションはまだ元の容量のまま
[ec2-user@xx ~]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1       7.8G  7.8G     0  100% /
devtmpfs         993M   56K  992M    1% /dev
tmpfs           1001M     0 1001M    0% /dev/shm

# 拡張
[ec2-user@xx ~]$ sudo resize2fs /dev/xvda1
resize2fs 1.42.12 (29-Aug-2014)
Filesystem at /dev/xvda1 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 4
The filesystem on /dev/xvda1 is now 13106683 (4k) blocks long.

# 無事50GBに増えた。
[ec2-user@xx ~]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1        50G  7.8G   42G   16% /
devtmpfs         993M   56K  992M    1% /dev
tmpfs           1001M     0 1001M    0% /dev/shm

go selenium memo

package main

import (
	"fmt"
	"net/http"
	"time"

	"github.com/pkg/errors"
	"github.com/sclevine/agouti"
)

// how to setup
// brew update
// brew install selenium-server-standalone
// brew cask install chromedriver
// go get "github.com/sclevine/agouti"
// go get "github.com/pkg/errors"

var adPage = "http://local.hoge/"

var driver = agouti.ChromeDriver()
var page *agouti.Page

func init() {
	driver.Debug = true

	if err := driver.Start(); err != nil {
		panic(errors.Wrap(err, "Failed to start driver"))
	}

	_page, err := driver.NewPage(agouti.Browser("chrome"))
	if err != nil {
		panic(err)
	}

	page = _page
}

func setCookie() {
	uuid := fmt.Sprintf("clickbot_%d", time.Now().Unix())
	err := page.Navigate("http://hoge.local/")
	if err != nil {
		panic(err)
	}
	time.Sleep(1000 * time.Millisecond)
	err = page.SetCookie(&http.Cookie{
		Name:   "uuid",
		Value:  uuid,
		Path:   "/",
		Domain: ".local",
	})
	if err != nil {
		panic(err)
	}
	fmt.Println("Refresh cookie uuid: " + uuid)
}

func main() {
	defer driver.Stop()
	setCookie()

	errcount := 0
	count := 0
	for {
		count++
		if count%5 == 0 {
			setCookie()
		}

		var err error
		err = page.Navigate(adPage)
		if err != nil {
			errcount++
		}

		time.Sleep(1000 * time.Millisecond)

		err = page.FindByXPath("/html/body/*/a[1]").Click()
		if err != nil {
			errcount++
		}

		time.Sleep(3000 * time.Millisecond)
	}
}