mkcert と golang の net/http を使い、ローカル環境に HTTPS サーバを立てる

Linux 環境で mkcert をインストール(ビルド)する

https://github.com/FiloSottile/mkcert#linux

$ sudo apt install libnss3-tools
$ git clone https://github.com/FiloSottile/mkcert && cd mkcert
$ go build -ldflags "-X main.Version=$(git describe --tags)"

mkcert で証明書とキーを作成する

$ mkcert -install
The local CA is already installed in the system trust store! 👍
The local CA is already installed in the Firefox and/or Chrome/Chromium trust store! 👍

$ mkcert -key-file key.pem -cert-file cert.pem 127.0.0.1 ::1

Created a new certificate valid for the following names 📜
 - "127.0.0.1"
 - "::1"

The certificate is at "cert.pem" and the key at "key.pem" ✅

It will expire on 18 October 2023 🗓

$ ls *.pem
cert.pem  key.pem

HTTPS サーバのサンプルコード

作成した cert.pemkey.pem のパスを http.ListenAndServeTLS に渡します。

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Protocol: %s\n", r.Proto)
    })
    if err := http.ListenAndServeTLS(":5000", "cert.pem", "key.pem", nil); err != nil {
        log.Fatal(err)
    }
}

動作確認

$ curl https://127.0.0.1:5000
Protocol: HTTP/2.0

参考にさせていただいたサイト

Linux のネットワーク関連コマンド

iptables と dnsmasq の使い方も後で追記したいです。

nc

TCPUDPのデータが送受信ができるコマンド。
TCP で Listen は nc -l 12345 、Connect は nc localhost 12345 にする。
UDP にする時は -u を付ける。

tcpdump

パケットをキャプチャできるコマンド。
-t で時刻を表示しない。
-nIPアドレスの名前解決をしない。
-i でキャプチャするインタフェースを指定する。-i any だと全てのインタフェースをキャプチャする。
-A でデータをASCIIで表示する。

別のターミナルから ping 8.8.8.8 -c 2 を実行し、ICMP パケットをキャプチャする例

$ sudo tcpdump -tn -i any icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
IP 192.168.0.10 > 8.8.8.8: ICMP echo request, id 5, seq 1, length 64
IP 8.8.8.8 > 192.168.0.10: ICMP echo reply, id 5, seq 1, length 64
IP 192.168.0.10 > 8.8.8.8: ICMP echo request, id 5, seq 2, length 64
IP 8.8.8.8 > 192.168.0.10: ICMP echo reply, id 5, seq 2, length 64
^C
4 packets captured
4 packets received by filter
0 packets dropped by kernel

UDP でポートを指定してキャプチャする例

$ sudo tcpdump -tnlA -i any "udp and port 12345"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
IP 127.0.0.1.37527 > 127.0.0.1.12345: UDP, length 4
E.. ..@.@.?A..........09....foo

IP 127.0.0.1.37527 > 127.0.0.1.12345: UDP, length 6
E..".z@.@.<O..........09...!hello

^C
2 packets captured
4 packets received by filter
0 packets dropped by kernel

lsof

プロセスが開いているファイルを表示できるコマンド。
-i でソケットだけを表示できる。-i:ポート番号 で絞り込みも可能。
-p でプロセスを指定できる。

$ lsof -i
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nc      1298 vagrant    3u  IPv4  28252      0t0  TCP *:12345 (LISTEN)
nc      1339 vagrant    3u  IPv4  29509      0t0  TCP *:9999 (LISTEN)
$ lsof -i:12345
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nc      1298 vagrant    3u  IPv4  28252      0t0  TCP *:12345 (LISTEN)
$ lsof -p 1339
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
nc      1339 vagrant  cwd    DIR    8,3     4096 5638785 /home/vagrant
nc      1339 vagrant  rtd    DIR    8,3     4096       2 /
nc      1339 vagrant  txt    REG    8,3    43664 4325590 /usr/bin/nc.openbsd
nc      1339 vagrant  mem    REG    8,3  2029224 4328519 /usr/lib/x86_64-linux-gnu/libc-2.31.so
nc      1339 vagrant  mem    REG    8,3   101320 4328538 /usr/lib/x86_64-linux-gnu/libresolv-2.31.so
nc      1339 vagrant  mem    REG    8,3    96728 4328287 /usr/lib/x86_64-linux-gnu/libbsd.so.0.10.0
nc      1339 vagrant  mem    REG    8,3   191472 4328477 /usr/lib/x86_64-linux-gnu/ld-2.31.so
nc      1339 vagrant    0u   CHR  136,0      0t0       3 /dev/pts/0
nc      1339 vagrant    1u   CHR  136,0      0t0       3 /dev/pts/0
nc      1339 vagrant    2u   CHR  136,0      0t0       3 /dev/pts/0
nc      1339 vagrant    3u  IPv4  29509      0t0     TCP *:9999 (LISTEN)

openssl s_client

openssl s_client -connectSSL/TLS 接続に関する情報を表示できる。

$ echo -e 'HEAD / HTTP/1.1\r\nHost: www.hatena.ne.jp\r\n\r\n' | openssl s_client -connect www.hatena.ne.jp:443 -quiet
depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
verify return:1
depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
verify return:1
depth=0 CN = www.hatena.ne.jp
verify return:1
HTTP/1.1 200 OK
Date: Tue, 13 Jul 2021 05:29:25 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 291348
Connection: keep-alive
Server: nginx
Vary: Accept-Encoding
Vary: Accept-Encoding
ETag: "47214-Bl7Cq7MeA3CEtqJhoXukBQe/L7k"
Vary: Accept-Encoding
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

^C

Linux で SMB 共有をマウントする

//192.168.1.100/test/tmp/smb-test にマウントする例です。
uid=$(id -u),gid=$(id -g) が無いと、スーパーユーザ権限でマウントされ色々と面倒なので付けています。

$ sudo mount -t cifs -o uid=$(id -u),gid=$(id -g),user=foo,password=bar //192.168.1.100/test /tmp/smb-test
$ sudo umount smb-test/

ip netns でブリッジを作成する

Linuxで動かしながら学ぶTCP/IPネットワーク入門 を読んでいます。 この本の中で登場した ip netns コマンドの使い方をメモしておきます。

ブリッジを作成する

「DNSがよくわかる教科書」を読んだメモ

TLD

  • TLD には ccTLD(Country code top-level domain) と gTLD(Generic top-level domain) がある
    • ccTLD: .jp や .uk などの国や地域に割り当てられる
    • gTLD: 国や地域の制限は無い。 .com や .net など。ただし .edu や .gov などには利用制限がある

スタブリゾル

  • DNSクライアントとも呼ばれる

フルリゾル

  • スタブリゾルバが指定した 問い合わせ情報(ドメイン名と種類) が自分のキャッシュにあれば、それを返す
  • 問い合わせ情報がキャッシュに無いと、権威サーバの階層構造をルートサーバから、たどり名前解決する。以下は example.jp を問い合わせする例
    1. ルートネームサーバに example.jp を聞いて、a.dns.jp に聞いてと返って来る
    2. a.dns.jp に example.jp を聞いて、ns1.example.jp に聞いてと返って来る
    3. ns1.example.jp に example.jp を聞いて、192.0.2.10 が返って来る
  • 委任情報や名前解決を一定時間キャッシュすることで以下を実現する
    • フルリゾルバ、権威サーバの負荷軽減
    • 問い合わせから応答までの時間短縮
    • ネットワークトラフィックの軽減
  • キャッシュには 問い合わせ情報(ドメイン名と種類) が存在しないことを表すネガティブキャッシュもある
  • 似ているものにフォワーダーがある

権威サーバ

  • 自分のゾーンの委任情報とドメインとアドレス間の対応関係を管理する。ネームサーバとも呼ばれる
  • 権威サーバでは階層化して委任することでドメインを管理する。委任された範囲を ゾーン と呼ぶ
  • ゾーンの設定内容を ゾーンデータ といい、 リソースレコード という単位で情報を保持する
  • 同じゾーンデータの権威サーバを複数台設置できる仕組みを ゾーン転送 という
  • プライマリサーバをリゾルバには応答しない形にして、ゾーン転送のみ利用する方法もある。プライマリサーバの負荷軽減とセキュリティ強化ができる
  • 委任した側を といい、委任された側を という。.jp なら、親がルートドメイン、子は jp ドメイン
  • 子はインターネット上にネームサーバ(ns1.example.jp など)を用意し、ゾーン内のドメイン名の対応付けと委任先(子)の情報を管理する
  • 親は子のネームサーバ情報(ns1.example.jp とその IP) を自分のネームサーバに登録する

リソースレコード

  • リソースレコードは次の要素から構成される
    • ドメイン名, TTL, クラス, タイプ, データ
    • 例: jprs.jp, 300, IN, A, 117.104.133.164

便利なコマンド

  • dig, drill, kdig

サンプルなど

  • 以下ではリソースレコードとコマンド実行例のサンプルを載せている arw.hatenablog.jp

iPad から Ubuntu の Vino に接続する

Vino を使うと、実際のデスクトップ画面に接続できます。

環境

Ubuntu の設定

設定 > 共有 > 画面共有 から Vino を有効にしてください。
Vino が起動していないときは /usr/lib/vino/vino-server で手動起動できます。

iPad の設定

VNC クライアントには VNC Viewer を使いました。
接続先ポートは 192.168.1.1::5900 のように :: で指定しないとダメでした。

参考にさせていただいたサイト

ip netns でネットワークセグメントを作成する

Linuxで動かしながら学ぶTCP/IPネットワーク入門 を読んでいます。 この本の中で登場した ip netns コマンドの使い方をメモしておきます。

ネットワークセグメントを 2 つ作成し、通信できるようにする

動作確認

$ sudo ./create_netns.sh
$ sudo ip netns exec node1 ping 192.0.2.1 -c 2
PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data.
64 bytes from 192.0.2.1: icmp_seq=1 ttl=62 time=0.022 ms
64 bytes from 192.0.2.1: icmp_seq=2 ttl=62 time=0.082 ms

--- 192.0.2.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1064ms
rtt min/avg/max/mdev = 0.022/0.052/0.082/0.030 ms