地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Python】サブネット形式で値を渡すと国を判別するツールを書いた

github.com

サブネット形式で値を渡すと国を判別するツールを書いてみました。ちなみにGeoLite2をローカルに置いてそこを参照するので外部サイトへの確認なんかを行わない作りになっています。(問い合わせし放題)

使い方はこんな感じ。slackとかから呼べると便利そう。

# 引数で渡す
$ python3 iptokuni.py 1.1.1.1
build_date: 2021-08-31 10:29:40
1.1.1.1: AU

# サブネット形式で渡す
$ python3 iptokuni.py 1.1.1.1/29
build_date: 2021-08-31 10:29:40
1.1.1.1: AU
1.1.1.2: AU
1.1.1.3: AU
1.1.1.4: AU
1.1.1.5: AU
1.1.1.6: AU

# ファイルで渡す
$ cat test.txt
1.1.1.1
8.8.8.8
11.22.33.44

$ cat test.txt | python3 iptokuni.py
build_date: 2021-08-31 10:29:40
1.1.1.1: AU
8.8.8.8: US
11.22.33.44: US

GeoLite2のデータベースを落としてくる必要があります。

https://dev.maxmind.com/geoip/geolite2-free-geolocation-data?lang=en

【Ruby】ワンライナーで便利そうなものを書いていく

背景

Ruby門中だしでせっかくなのでRubyで便利だなぁと思ったワンライナーのTOP5を書いてみます。オプションとかは以下の記事がとてもわかりやすかったです。

maeharin.hatenablog.com

5位 webサーバ

定番のやつですね。nginxの検証とかするときにproxy先が何でも良い場合がそこそこあってワンライナーで済ませちゃう時とかに使えます。今まではpython使ってましたがせっかくなのでRubyでやってくようにしてみようかなと思います。

$ ruby -run -e httpd . --port 8080

他言語の情報などなどがこの記事で見れるのでとても面白かったです。言語ごとのwebサーバをabとかでベンチマーク取ってみるの面白そうとも思いましたwいつかやってみようかな。

qiita.com

4位 合計値を出す

BEGIN/ENDが使えるのでawkでできるようなことは大体できるのかなという印象を持ちました。$.awkでいうNRが取れます(perlと同じなのでわかりやすい)。この構文は汎用性がめちゃめちゃ高いので4位くらいに入れてみました。

ruby -ne 'BEGIN{$sum = 0}; $sum += $_.to_i; END{puts $sum}' number.txt

3位 四捨五入する

cat test.txt
test 1.2
aaa 2.23333
ccc 4.433
ddd 2.11

こんなファイルがあって第二フィールドをそれぞれ四捨五入したい場合にroundが使えて便利だった。awk使うとawk '{printf(“%d\n",$1 + .0.5)}’みたいに四捨五入したい桁が直感的にわからないけどroundなら直感的にわかって良い。

$ ruby -ne 'puts $_.split[1].to_f.round(1)' test.txt
1.2
2.2
4.4
2.1

2位 数字を括弧で括る

perlとかでやるようなchompが使えて便利でした。何かしらの文章を書くときにわかりやすいように表題とか書くときに使えたりします。

seq 10 | ruby -ne 'chomp;puts "{{ "+$_+" }}"'
{{ 1 }}
{{ 2 }}
{{ 3 }}
{{ 4 }}
{{ 5 }}
{{ 6 }}
{{ 7 }}
{{ 8 }}
{{ 9 }}
{{ 10 }}

1位 数字を渡すとエラーナンバーを表示してくれるワンライナー

エラー時にエラーナンバーしか出力されないみたいなケースで2とか111と頻出のものならさっと出てくるかもしれないですが12とか18とか数字からは何のエラーだろ?ってなります(少なくとも私は)。

#include <stdio.h>
#include <errno.h>

int main(int argc, char **argv)
{

  FILE *fp = fopen( "no_exist_filepath", "r" );
  if(fp == NULL)
    printf("%d\n", errno); // こんな感じの出力しかしないやつ

  return 0;
}

/usr/include/asm-generic/errno-base.hとかをさっとみにいけば良いですがパスを覚えている可能性も低いです。そうなったときに使えるのがこのワンライナー。数字を渡すことで人間がわかりやすいよう表示してくれます。便利!

$ echo 1 2 111 | ruby -ne '$_.split.map {|d| printf "%d: %s\n", d, SystemCallError.new(d.to_i)}'
1: Operation not permitted
2: No such file or directory
111: Connection refused

【Linux】fincoreコマンドを使ってファイルがページキャッシュに乗っているかを見るって記事を書こうとしたら自分で既に書いていた

「fincoreコマンドを使ってファイルがページキャッシュに乗っているかを見る」ってタイトルの記事を書いて色々ググっていたら自分で昔書いていた記事がヒットした。3年前くらいか。

qiita.com

mincore(2)に見覚えがあったがなるほどとなった。。アウトプットした記事がgoogleでヒットすることはたまにあるけど書き始めてから気づいたのは初めてかもしれない。。

はてブ/Qiita/note/Zenn/Gistへ雑多に書いてしまってるし整理もできてないのでよくなさそうだしどこかで時間見つけて見返してみるのも良いのですかね〜。

やりたかったことは「ある程度稼働したApache Solrは細切れのindexをどれくらい触ったのか」を雑にページキャッシュに乗ってるかの有無で見ようとしてましたが大体達成できたのでよかった。あとはなんか脆弱性があったらしいという新情報を得たので読んでみようと思います。

www.cvedetails.com

ファイルの権限確認とかケーパビリティ見る処理は記事を書いた当初はなかったみたいなのでこっちもみてみよう。

github.com

【Linux】tcpdumpを使って通信しているパケットのtlsバージョンを調べるメモ

背景

提供しているサービスに対してクライアントがどのTLSバージョンで来ているのかを調べるみたいな場合にサーバのログで出せれば一番手っ取り早いですが「そんな機能ないよ!」みたいな場合も往々にしてあると思い、「その場合はどうするのが良いんだろう?」と思って調べた記事です。そんなケースがあるのかは分からないですが勢いで調べてみました。(絶対のログの形式を変えてはいけないみたいなケースとかあるのかな。)

結論だけ書くとtcpdumpした結果をうまくawkなりでなんなりでパースすればいい感じにバージョンの統計データが取れそうでした。やりたくはないですがw

実験

TLS通信で使われているバージョンをtcpdumpを使って調べるための方法。打つコマンドは以下。

今回やりたいのクライアントが使用してくるTLSのバージョンを知りたいのでtcpdumpではTLSハンドシェイクに絞って実行していく。tcpヘッダー直後の1バイトが22(10)であるパケットのみを表示するコマンド。

$ tcpdump -ni ens192 "tcp port 443 and (tcp[((tcp[12] & 0xf0) >> 2)] = 0x16)" -x -s0

下記の記事にある通りContent Type:22はHandshakeとなっている。これでフィルタリングしていく。

milestone-of-se.nesuke.com

別コンソールを開いて適当にhttpsで通信を行う。すると以下のような出力が得られる。

 0x0000:  4500 00fd fce3 4000 4006 2806 c0a8 010a
    0x0010:  8efa c464 8afc 01bb 8dbf 8df8 df9e 5e04
    0x0020:  8018 00e5 1601 0000 0101 080a 0500 7166
    0x0030:  1f87 be9d 1603 0100 c401 0000 c003 0362
    0x0040:  fe05 ef7f e114 c927 d16f 84e4 d206 9f7c
    0x0050:  1583 4aaf 1f3a df90 bde1 0c3c 01ff 0c00
    0x0060:  0006 1301 1303 1302 0100 0091 0000 0013
    0x0070:  0011 0000 0e77 7777 2e67 6f6f 676c 652e
    0x0080:  636f 6d00 1700 00ff 0100 0100 000a 0014
    0x0090:  0012 001d 0017 0018 0019 0100 0101 0102
    0x00a0:  0103 0104 0033 0026 0024 001d 0020 1281
    0x00b0:  3328 2ad9 9727 eae0 cc82 cf03 84f8 dc70
    0x00c0:  32e0 f6c8 de60 4fde 2822 f09e de02 002b
    0x00d0:  0003 0203 0400 0d00 1800 1604 0305 0306
    0x00e0:  0302 0308 0408 0508 0604 0105 0106 0102
    0x00f0:  0100 2d00 0201 0100 1c00 0240 01

以下はIP/TCPヘッダーなので不要。

 0x0000:  4580 05ae 0646 0000 3806 e874 acd9 1f84
    0x0010:  c0a8 010a 01bb bb5c 228a 848c a6ec 74c9
    0x0020:  8010 0105 eab8 0000 0101 080a 9d78 e84c
    0x0030:  04ec 79b6

5バイト目が16(16)なのでhandshakeとなっている。先程のサイトを参考にすると6~7バイトの4bitがtlsのバージョンとなっている

 0x0030:  04ec 79b6 1603 0300 5a02 0000 5603 03b9
----------------------^^^^

今回は何も指定せずにcurlを実行しているので0x0303となっているようでtls1.2での通信を要求したようです。

tools.ietf.org

// 各バージョンでの実装はこのようになっているらしい
0x0300; / * SSL v1 * /
0x0301; / * TLS v1 * /
0x0302; / * TLS v1.1 * /
0x0303; / * TLS v1.2 * /

opensslなりcurlなりでバージョンを変えていくとここの数字が変わっていくのがみれます。

# ssl1
0x0030:  d089 475e 1603 0000 8f01 0000 8b03 0028

# tls1
0x0030:  050e c5f9 1603 0100 ba04 0000 b600 0001

# tls1.1
0x0030:  0511 91bc 1603 0200 ba04 0000 b600 0001

# tls1.2
0x0030:  050f 8c0f 1603 0300 ba04 0000 b600 0001

途中で気づいたのですがtcpdumpのフィルターでClientHelloメッセージ以外にしないとClientHelloメッセージのレコードレイヤーバージョンは、下位互換性のためにTLSv 1.0を使用するので要件次第では意図した結果にはならなそうです。

tls1.3だとどうなるのか

tls1.3だとどうなるのかの記述が見つけられなかったので試してみようとしました。そしたらmacだと以下のようになってそのままでは使えなそうでした。

curl https://cafe.classmethod.jp/ --tlsv1.3
curl: (4) LibreSSL was built without TLS 1.3 support

以下の記事を参考にTLSv 1.3 に対応している curlを導入してみます。

dev.classmethod.jp

実行。位置は若干ずれてますが"03 03"になっているのがわかります。tls1.3なら0x0304じゃないの?って思ったのですがどうやら違うようです。

0x0040:  3858 1603 0300 7a02 0000 7603 037a 7937

下位互換性を考慮した作りとなっているようなことが書かれていました。通信時にはTLS v1.2 を示す 0x0303 を格納して拡張領域にTLS v1.3であることを伝え認識できるサーバであれば移行をTLS v1.3で通信を行うような仕組みのようです(この辺全然勉強してないので自信ないので今度調べる。)

tools.ietf.org

wiresharkを見ると以下のようになっていました。

f:id:ryuichi1208:20210905234436p:plain

Extension: supported_versions は TLS v1.3 対応のサーバしか理解できなとのこと。なるほどね〜。

参考