このブログを検索

2022/02/26

c言語のchar

c言語のcharについて。

# cat cha.c
#include 

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

        char *c1;
        c1="a";
        printf("c1: %d %s\n", c1, c1);

        c1++;
        printf("c1: %d %s\n", c1, c1);

        c1="hello";
        printf("c1: %d %s\n", c1, c1);


        char c2;
        c2 = 'a';
        printf("c2: %d %c\n", c2, c2);

        c2++;
        printf("c2: %d %c\n", c2, c2);

        c2 = 'c';
        printf("c2: %d %c\n", c2, c2);

        return 0;
}


# ./a.out x
c1: 4196104 a
c1: 4196105
c1: 4196116 hello
c2: 97 a
c2: 98 b
c2: 99 c


charというのは「1文字」である。
1文字なので、"hello"とかを代入できない。

上記の例では、c1は char *c1
c2は char c2
と定義(宣言?)している。

注目すべきはc1, c2に代入するときの引用符で、c1は"", c2は''にしている。

ポインタ宣言(という言い方でいいのか)した場合は"", そうでない場合は'' である。

c1に'a'を、c2に"hello"を入れようとするとコンパイルでエラーになる。

char *c1;
としたときはc1はポインタなので、%dで表示するとその内容はアドレスになる。
char c2;
としたときはc2は文字なので、%dで表示するとその内容は文字コードになる。

c1はポインタなので、インクリメントしても未定義の値が表示される。
c2は文字なので、aをインクリメントするとaの次の文字コードであるbが表示される。

2022/02/18

2022年のmotion@raspberry pi

しばらく放置していたraspberry piを起動して、最近変えた構成に合わせようとして

/etc/dhcpcd.conf のgatewayのアドレスを変更しようとしたら、なんど変更しても再起動すると元に戻ってしまう。

networkingがresolve.confを書き換えるとかいうことはあるようだがdhcpd.confが何かによって上書きされるという話は聞いたことがない。

どこかのフォーラムで同じようなケースがありsdカードの不良じゃないかみたいな結論になっていた。

私もそれしかないと思い新しいSDカードにインストールしなおした。

まあ、私のraspberry piには大した設定は入っていないので再インストールすることはそんなにオオゴトではない。


ただ、久しぶり、といっても1年とか2年とかだが、にインストールしたらちょこちょこと変化があった。

osを書き込むソフトが新しいものになりフォーマットもせずにいきなり書き込めた。

初期状態ではコンソールもsshもアクセスできない。(まあこれは少し前に気づいていたこと)。

それから、カメラモジュールがlegacy扱いされていた。

raspistillコマンドがなくなりlibcamera-still とかいうコマンドになった。

(OSによるのか)

が、libcamera-stillは、先ほどのlegacy cameraが有効になっていると使えない。

そしてlegacy cameraを無効にするとmotionでcameraがdetectされない。

なので、legacyカメラを有効にし、コマンドでのカメラ動作確認はせずにmotionを動かして確認する。


前から使っているmotionをインストールした。

motion.confは

norm 1 を追加

stream_localhost off

正常動作を確認したら、daemon on にする


自分の以前書いたメモに以下の記述があったのでそれもやったが必要かどうかは微妙

> /etc/modulesに以下の記述を追加

>bcm2835-v4l2


とりあえず動いている。


pi@raspberrypi:~ $ cat /etc/debian_version
11.2

pi@raspberrypi:~ $ cat /etc/issue
Debian GNU/Linux 11 \n \l


pi@raspberrypi:~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:        11
Codename:       bullseye

pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.10.92-v8+ #1514 SMP PREEMPT Mon Jan 17 17:39:38 GMT 2022 aarch64 GNU/Linux

2022/02/16

SSLインスペクションした時にVPN通信はどのように扱われるのか

最近会社から自宅にVPNをつないで家のPCを使っていろいろやっているのだが、 
ふと、『SSLインスペクションしている時のVPN通信の内容ってどこまで把握されているのだろう』
と思った。

確認してみた。

自宅のパソコンを家の無線LANにつないでinternetに出るときはpaloaltoを通るようにしている。

こないだVPSに設定したopenvpn通信がある。

まず、VPNなしでeicarをダウンロードして、paloaltoがブロックするのを確認する。

次に、openvpn全通信をVPN経由になるようにして、VPSに接続し、
同じようにeicarをダウンロードしてみたらブロックされない。

フーン....

2022/02/15

RSA暗号を実際に計算してみる

下記にRSA暗号の計算例が載っていたので、perlで実際に計算してみた。
https://milestone-of-se.nesuke.com/nw-basic/tls/rsa-summary/
# cat rsa.pl
use Math::BigInt;

#data
my $data = Math::BigInt->new("508");

print "data: ".$data."\n";

# encrypt
# koukaikagi 223, 1357

my $pubkey1 = 223;
my $pubkey2 = 1357;

my $crypt = ($data ** $pubkey1) % $pubkey2;

print "crypted data: ".$crypt."\n";


#decrypt

#himitukagi 103

my $privkey = 103;


$decrypt = ($crypt ** $privkey) % $pubkey2;

print "decrypted data: ".$decrypt."\n";

実行結果
# perl rsa.pl
data: 508
crypted data: 1319
decrypted data: 508
元のデータは 508
公開鍵となる数字は2つのペアで 223と1357である。
暗号化されたデータは、元のデータを223乗して、それを1357で割った余りとして作成し
この例ではその値は 1319である。
秘密鍵の値は103である。
復号は、1319を103乗して1357で割った余りとして求め、
その値は508であり、元のデータと一致する。

結果だけ見ると3~4桁の数字であるが、
計算途中で「508の223乗」というとんでもない計算があり、
280桁くらいになるので BigIntを使っている。

しかし実際の暗号化においては、508などという数値どころではない
文字列や画像、音声などを暗号化しているのだから
とてつもない量の計算がされている。
そのために暗号化専用のチップなどが使われたりしているのだ。

注目すべきは下記の記述である。
「メッセージ m を e 乗 (公開鍵で暗号化) したものに対しては d 乗 (秘密鍵で復号) することで元の m に戻りますし、
メッセージ m を d 乗 (秘密鍵で暗号化) したものに対しては e 乗 (公開鍵で復号) することで元の m に戻るのです。」

これがよく話題になる、「電子署名のことを秘密鍵で暗号化するというのは間違い」
のことである。
この人は、「別に署名を秘密鍵で暗号化するといってもいいじゃないか。」
という旨のことを言っている。
私もそう思う。

では、署名と検証もやってみよう。
# cat sign.pl
use Math::BigInt;

#data
my $data = Math::BigInt->new("508");

print "data: ".$data."\n";

# encrypt
# koukaikagi 223, 1357
#himitukagi 103

my $pubkey1 = 223;
my $pubkey2 = 1357;

my $privkey = 103;

my $sign = ($data ** $privkey) % $pubkey2;

print "signed data: ".$sign."\n";


#verify

$verified = ($sign ** $pubkey1) % $pubkey2;

print "verified data: ".$verified."\n";
さっきの暗号化の計算と同じことを、
暗号化時(署名時)に103乗し、復号時(検証時)に223乗、つまり逆にしている。
逆にしても、元の値に戻る。

# perl sign.pl
data: 508
signed data: 315
verified data: 508
当然、公開鍵と秘密鍵というのはどんな数字でもいいわけではなく、
上記のような計算が成り立つような数字を選ぶわけであるが、
「署名を秘密鍵で暗号化すると言ってはいけない」と怒ることはないんだなと、
ようやく安心できた。

python版
# cat rsa.py
data=508
pub1=223
pub2=1357
priv=103

print("data:"+str(data))

crypted=(data ** pub1) % pub2
print("crypted:"+str(crypted))

decrypted=(crypted ** priv) % pub2
print("decrypted:"+str(decrypted))

signed=(data ** priv) % pub2
print("signed:"+str(signed))

verified=(signed ** pub1) % pub2
print("verified:"+str(verified))

# python rsa.py
data:508
crypted:1319
decrypted:508
signed:315
verified:508
BigIntとかいらない。

2022/02/12

openvpn@centos8 第3回 証明書, iPhone, Mac

サーバがcentos8, クライアントがWindows10で、static keyで接続できた。

その時のクライアント側configをiPhoneにメールで転送してopenvpnアプリに追加して接続しようとすると、 CA not defined というエラーになって接続できない。

このあたりはOSの種類やバージョンによって変わってくることは、違うvpnを設定した時にもあったことだ。 apple製品はこの辺がwindowsより厳しくなっている。

まあ最初から証明書は作るつもりだったので。

証明書はopensslでやる。

サーバの秘密鍵を作る→csr作成→caで署名

ここは何度もやったので省略

opensslの設定はほぼデフォルト

configはサンプルをコピーして作る。configの置き場は /etc/openvpn/server/

# cp /usr/share/doc/openvpn/sample/sample-config-files/server.conf /etc/openvpn/server/

なるべくデフォルト設定を使う。

以下のファイルが必要

ca ca.crt #VPNサーバの証明書を発行(署名)するCAの証明書
cert server.crt #VPNサーバの証明書
key server.key #VPNサーバの秘密鍵

#   openssl dhparam -out dh2048.pem 2048
dh dh2048.pem # DHパラメータ

#   openvpn --genkey --secret ta.key
#
# The server and each client must have
# a copy of this key.
# The second parameter should be '0'
# on the server and '1' on the clients.
tls-auth ta.key 0 # This file is secret # tlsキー、後ろの数字は0がサーバー、1がクライアント

dhパラメータをeasyrsaで作るように説明している情報が多いがsampleコンフィグにopensslのコマンドが書いてあるのでそれを使う。

ごちゃごちゃやったが結局つながったので、configを載せておく。 サーバ証明書とクライアント証明書での接続

サーバ(コメント部分削除)
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 192.168.55.0 255.255.255.0"
keepalive 10 120
tls-auth ta.key 0
persist-key
persist-tun
status openvpn-status.log
log-append  openvpn.log
verb 4
explicit-exit-notify 1

外部ファイル(server.confと同じフォルダ /etc/openvpn/server に置く) ca.crt
server.crt
server.key
dh2048.pem

pushは接続先のプライベートネットワークセグメント(アクセス先)
加えてサーバ側のfirewalld設定やip forwardingの設定が必要(前回の記事を参照)
ログ出力設定はデフォルトで無効だが有効にした

クライアント(windows) ※タグが表示されるように<>の前後にスペースを入れてある
client
remote vpn.example.com
port 1194
proto udp
dev tun
tls-auth ta.key 1
persist-tun
persist-key
verb 4
mute 10

< ca >
-----BEGIN CERTIFICATE-----
(省略、サーバ証明書にサインしたCAの証明書)
-----END CERTIFICATE-----
< /ca >
< cert >
-----BEGIN CERTIFICATE-----
(省略、クライアント証明書)
-----END CERTIFICATE-----
< /cert >
< key >
-----BEGIN RSA PRIVATE KEY-----
(省略、クライアントの秘密鍵)
-----END RSA PRIVATE KEY-----
< /key >

外部ファイル
ta.key

client が必要

クライアント(iPhone 15.2.1, Mac Monterey Version12.2)
client
remote www.monqy.net
port 1194
proto udp
dev tun
persist-tun
persist-key
verb 4
mute 10
key-direction 1
< ca >
-----BEGIN CERTIFICATE-----
(省略、サーバ証明書にサインしたCAの証明書)
-----END CERTIFICATE-----
< /ca >
< cert >
-----BEGIN CERTIFICATE-----
(省略、クライアント証明書)
-----END CERTIFICATE-----
< /cert >
< key >
-----BEGIN RSA PRIVATE KEY-----
(省略、クライアントの秘密鍵)
-----END RSA PRIVATE KEY-----
< /key >
< tls-auth >
-----BEGIN OpenVPN Static key V1-----
(省略、ta.keyの中身)
-----END OpenVPN Static key V1-----
< /tls-auth >
ポイントは、 tls-auth ta.key 1 と書くところは ta.keyの内容を< tls-auth >に貼り付けて、
key-direction 1 (client側を意味する) を書く。

2022/02/11

openvpn@centos8 第2回 スプリットトンネリング

やること 
  •  firewalldは止めずにちゃんとopenvpnを指定して許可する 
  •  接続先サーバのlan側のみをトンネリングする 
  •  接続先サーバはconohaのプライベートネットワーク(192.168.55.0/24)経由で接続されたもう一台のVPS

# cat server.conf
port 1194
proto udp
dev tun
ifconfig 10.8.0.1 10.8.0.2
secret static.key
cipher AES-128-CBC
#comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key

status openvpn-status.log
log-append openvpn.log
verb 3

#クライアント側の設定ファイル (client.ovpn)
remote vpn.example.com
proto udp
dev tun
port 1194
ifconfig 10.8.0.2 10.8.0.1
secret static.key
cipher AES-128-CBC
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
route 192.168.55.0 255.255.255.0
サーバ側のconfigに下記を入れたがうまくいかない。 
クライアント側のルーティングが書き換わらない。 
openvpnを管理者として実行にしてもダメ。 

push "route 192.168.55.0 255.255.255.0"

 クライアント側の設定ファイルに下記を追加したら追加された。 (route printで確認)
route 192.168.55.0 255.255.255.0

あとは、接続先のサーバ側でip forwardingとnat設定をする。
フォワーディングは
sysctl -w net.ipv4.ip_forward=1

firewall-cmdで"Internal"ゾーンを作成し(internalというのが既存であるが)
eth1を追加

そしてNAT
あるサイトを参考に下記の設定を入れてみたら、
pingはプライベートネットワーク越しに通るようになったのだが、http/httpsが通らない。
firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth1 -j MASQUERADE
悩んで調べた結果、
firewall-cmdでプライベートネットワーク側にmasquerade設定を入れることで解決
firewall-cmd --zone=Internal --add-masquerade
最初に入れた --direct --passthrough .... の設定も必要なのかはわからない。 本当は消したいのだが、消し方がわからない....

openvpn@centos8 第1回 とりあえずつなげる

最近会社のネットワークやパソコン自体も非常に制限が多くなってきて、 ほとんど仕事にならない状態。
それで、vpnをいろいろ試している。
会社から自宅にVPN接続してRDPで家のパソコンにログインしていろいろやる。

中古のVPN装置を買っていろいろ試したのだが、 まともにVPNをやろうとすると中古の機器を買ってもまあまあの出費になる。
本体は安くてもライセンスが有効なものになるとグンと値段があがる。
そこでこんどはフリーのOpenVPNを試すことにした。
以前やったことはあるが、つながったことを確認して なるほどな、くらいで終わったのだが、
今回は実用に耐えられるかまでちゃんと試す。

openvpnについてはたくさん情報があるが、ほとんどの人がeasyrsaを使っているのだが、 今まで苦労してようやくプライベートCAが安定稼働したので、 
easyrsaは使わずopensslでやる。

CentOS Linux release 8.3.2011

参考にした情報で
dnf update

していたのでやっとくかと、やると
# dnf update

CentOS Linux 8 - AppStream                   80  B/s |  38  B     00:00

エラー: repo 'appstream' のメタデータのダウンロードに失敗しました : 
Cannot prepare internal mirrorlist: No URLs in mirrorlist
調べるとなんか変わったらしいので以下を実施
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Linux-*; 
もう一回updateすると今度は
エラー:
 問題: cannot install both device-mapper-8:1.02.177-10.el8.x86_64 and device-mapper-8:1.02.171-5.el8.x86_64
  - package device-mapper-devel-8:1.02.171-5.el8.x86_64 
  requires device-mapper = 8:1.02.171-5.el8, but none of the providers cae installed
  - cannot install the best update candidate for package device-mapper-8:1.02.171-5.el8.x86_64
  - problem with installed package device-mapper-devel-8:1.02.171-5.el8.x86_64

(競合するパッケージを置き換えるには、コマンドラインに '--allowerasing' を追加してみてください 
または、'--skip-broken' を追加し インストール不可のパッケージをスキップしてください 
または、'--nobest' を追加して、最適候補のパッケージのみを使用しないでください
調べてもよくわからないが、言われた通り
install device-mapper-8:1.02.177-10.el8.x86_64 --allowerasing
をやる。 で、もう一度
dnf update
今度はok 結構長い。久しぶりだからな。
dnf install openvpn
すでにinstallしてあった。 

ちゃんと公式ドキュメントを見ておくか、とみると、 
証明書を使わず静的キーでやる方法が紹介されていたので まずそれでやってみる。
https://www.openvpn.jp/document/quickstart-statickey/
サーバを起動する
systemctl start openvpn-server@server.service
statusを見ると activatingで止まっている
● openvpn-server@server.service - OpenVPN service for server
   Loaded: loaded (/usr/lib/systemd/system/openvpn-server@.service; enabled; vendor preset: disabled)
   Active: activating (auto-restart) (Result: exit-code) since Fri 2022-02-11 17:56:52 JST; 3s ago
/var/log/messagesを見ると

Feb 11 17:56:57 xxx openvpn[363482]: Cipher 'AES-256-GCM' mode not supported

cipherは何も指定していない。
ついこないだ別のサーバでやったときはこんなことなかったけどな...
cipher AES-128-CBC
にしたら起動した。 client側の設定にも入れるとつながった。
centosは一時的にfirewalldを止めた
#server.conf
proto udp
dev tun
port 1194
ifconfig 10.8.0.1 10.8.0.2
secret static.key
cipher AES-128-CBC
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key
クライアントはとりあえずwindows10で クライアントのconfigは 
 C:\Users\(username)\OpenVPN\config 
か 
C:\Program Files\OpenVPN\config\ 
に 拡張子 .ovpn のファイルを置けばいいみたい
#client.ovpn
remote vpn.example.com
proto udp
dev tun
port 1194
ifconfig 10.8.0.2 10.8.0.1
secret static.key
cipher AES-128-CBC
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key

2022/02/10

なぜIT業界のプロジェクトはうまくいかないのか

私はIT業界で30年以上仕事をしてきた。

30年前に「IT」という呼ばれ方はされていず、「情報処理」とか「OA(Office Automation)」などと言われ、もっと柔らかい言い方だと「コンピューター関係」とか「ソフト開発」とかいう風に言ったり言われたりしていた。

「IT」という呼称が一般化したのは2000年ごろだろうか。森総理大臣がそれを「イット」と読んだことがニュースになったのが2000年である。

わたしのキャリアの1/3くらいはまだITとは呼ばれなかった時期ということになるが、ここではその時期を含めて「IT業界」という言葉を使う。

30年ほどこの業界にかかわってきてずっと、この業界のプロジェクトは成功した例があるのだろうか?と感じていた。

あらゆるプロジェクトが計画通りに進まず、仕様が途中で変更あるいは追加され、無謀なスケジュールと不均等な業務分担が当たり前だった。

わたしはこの業界以外を知らないが、たとえば自動車を製造する、ビルを建築する、お菓子の製品を開発して販売するといったプロジェクトでは絶対にこんなひどくはないはずだという確信がある。

IT業界が特殊な理由として私が考えていたのは、まずそれが成熟していない新しい産業であるということだ。コンピューターというもの自体が実用化され始めたのは1950年代ごろだろうか。

私は1990年代初めにこの業界で仕事を始めた。最初に入った会社は「XXシステム開発」という名前で、ソフトウェア開発を主業務としていた。その会社はある企業のシステム部門が独立した会社だった。

私が入社した時(最初は契約社員だった)、机の上にパソコンはなかった。
灰皿があった(と思う)。

私が入社して2年くらいして喫煙室ができたので、それまでは室内で吸っていたはずだ。

プログラミングするときは、コーディング用紙に鉛筆(シャーペン)で書いて、完成してから端末で入力した。

コードを入力できる端末はそのオフィスには確か3台くらいしかないので、交代で使用するのである。

その端末は本当に「端末」だった。

今の人は「タンマツ」といっても通じないか。

タンマツというのは、ホストコンピュータに接続されてディスプレイとキーボードをそなえたものであり、一見現在使用されているデスクトップコンピュータのようだが、実際に処理が行われているのはホストコンピュータであり、「端末」は入出力装置にすぎない。だから「端末(Terminal)」なのである。

私の所属していた部署は「オフコン」を使用するシステム開発をする部署であった。
「オフコン」とはオフィスコンピュータの略であるが、いわゆるメインフレームと言われる大型のコンピュータと同様の機能を持っているが小型でオフィス等におけるくらいの人の腰の高さくらいの大きさのコンピュータである。

ドキュメント類も鉛筆と定規を使って手書きで書いていた。
フローチャートとか、ファイル定義とか。

1992年くらいからか、職場に自分のノートパソコンを持ち込む人が現れ始めた。
そしてオフコンを使ったシステムの需要は急速に減少していき、仕事が暇になった。
そして1995年に私はその会社を辞めた。

Windows95が発売された年である。

5年ほどいたその会社でかかわったプロジェクトでうまくいったと言えるものはほとんどなかった。比較的うまくいったプロジェクトは、要件があいまいなままなんとなくだらだら続けたものか、ガチガチに要件を固めて客に有無を言わせず作ったものかのどちらかだった。

それからはソフトウェア開発からインフラ構築とか検証とか運用のような業務をするようになっていったが常にキーボードをたたいて何かしらのコマンドを実行したりコードを入力することをしていて、自分は「SE(システムエンジニア)」であると自覚していた。

1995年のWindows95の登場をきっかけに家庭や企業でのインターネット利用が本格的に普及しはじめ、職場では一人1台パソコンを使用するようになっていった。

そして私はネットワークを主に担当するネットワークエンジニアとなっていった。

ネットワークはソフトウェア開発とは多少異なるが、やはり要件定義、設計、構築(実装)、試験(検証)、運用というフェーズを経るのは同じだった。

そしてネットワークのプロジェクトもだいたい計画通りにいかず仕様変更(要件変更)や追加は当たり前でやっとの思いでプロジェクトを完遂させるのだった。

なぜ、IT業界のプロジェクトはうまくいかないのだろうか。
今、改めてそれを考えている。

私は最初の会社でシステムエンジニアをしていた時に「人月の神話」という本を読んだ。
これは今では当たり前に言われる「プロジェクトマネジメント」について書かれた本であるが、私がこれを読んだ当時プロジェクトマネジメントなどという言葉はほとんど聞いたことがなく、会社にもそのようなポジションはなかった。

SE(システムエンジニア)とPG(プログラマ)があるだけだった。

今年、人月の神話のことを思い出して改めてざっと読んでみたのだが、
結局30年間、この本に書かれているプロジェクト管理についての問題とそれを解決する特効薬のような手段(銀の弾丸)はないというある意味悲観的な結論が正しいというのは変わらなかったのだと再認識した。

IT業界というのはソフトウェアが非常に重要であり、わたしにとってITとはほとんどソフトウェアとイコールである。

コンピュータや通信機器はソフトウェアを入れる箱のようなものであり、ITエンジニア(システムエンジニア)というのは、その箱を作る人ではなく箱の中に入れるものを作る人であると考えている。

30年前から、ソフトウェアなどというものはコンピュータを動かすためのちょっとしたおまじないのようなものだと考えている人がいたが、それは現在も同様である。

ITのプロジェクトが失敗する根本的な原因はソフトウェア軽視なのではないか?

そしてもう一つ、ソフトウェアやプログラミングというものが数学だと思っている人が多い気がするが、一般の企業で社員が使用するようなシステムにおいては、ソフトウェア開発でもネットワークシステム設計においても数学を使用することはほとんどない。

(四則演算とか不等号とか2進数16進数などは必要だがそれは数学というほどのことではない)


「私は文系だからプログラミングができない」
「私は理系だからプログラミング(コンピュータ)のことがわかる」

これは実際に私が職場で聞いた発言であるがどちらを聞いた時も釈然とせず少し憤りをおぼえさえした。

わたしがコンピュータプログラミングに興味を持ったのはテレビでBASIC言語を知り、

if a>0 then goto 10

という構文を見た時だった。

「もし...なら、...しろ」
コンピュータが人間の言葉で動かせるんだ、という驚きである。

つまり、プログラミングは数学ではなくむしろ英語なのである。

(アセンブラとかはもちろん例外)

「理系だから英語が苦手」
「文系だから数学わからない」

それはいいが、だからといって理系だから「if ... then」がわからないとは言えないだろうし
文系だからって「 a > b  」は理解できるだろう。

そしてIT業界(先ほど言ったように一般企業で社員が使うようなシステム)で必要な英語も数学もその程度でしかない。

出身が理系文系かなど関係ないのである。

あと、「数学とプログラミングは論理的思考が必要な点で似ている」とかいうのもよく聞くのだが、数学でなければ論理的思考は必要ないのだろうか?

文章を読んだり書いたりするときに論理的に考えないのだろうか?

そういうことを言う人は「英語や歴史は考えないで丸暗記するから」程度のことしか考えていないのではないか?


ここまで書いてきて、ITプロジェクトがうまくいかない、炎上する、破綻する、頓挫する、終わらない、理由が分かった気がする。

まず、コンピュータやソフトウェアが魔法のツールであるという過信。
それらも人間がプログラミングしデバッグし検証を繰り返すという地道な作業なしに成立しないことへの不理解。

先ほどの文系理系数学英語というものと結び付けて話すことからわかるように、学問や技術についても学校などで教えてもらえば使えるハサミやトンカチのような便利な道具であるとしかとらえていないこと。

つまり、ほかの業界では当然考えたり確認したりするようなことを、IT業界ではしなくていいという先入観、これが根本原因ではないだろうか。

2022/02/06

CA作り直し

何度やっても忘れる...
#opensslの設定ファイル場所

/etc/pki/tls/openssl.cnf


#抜粋

####################################################################
[ ca ]
default_ca      = CA_default            # The default ca section

####################################################################
[ CA_default ]

dir             = /etc/pki/CA           # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several certs with same subject.
new_certs_dir   = $dir/newcerts         # default place for new certs.

certificate     = $dir/cacert.pem       # The CA certificate
serial          = $dir/serial           # The current serial number
crlnumber       = $dir/crlnumber        # the current crl number
                                        # must be commented out to leave a V1 CRL
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/cakey.pem# The private key


なるべくデフォルト値を使う
ファイル名は、キーは xxxkey.pem 証明書は xxxcert.pem とする。

コマンドは /etc/pki/CA で実行する。

CAの秘密鍵の場所は /etc/pki/CA/private.cakey.pem
CA証明書は /etc/pki/CA/cacert.pem



#CAの秘密鍵生成

[root@god tls]# openssl genrsa -aes256 -out ./private/cakey.pem
Generating RSA private key, 2048 bit long modulus (2 primes)
..............+++++
..............+++++
e is 65537 (0x010001)
Enter pass phrase for ./private/cakey.pem:
Verifying - Enter pass phrase for ./private/cakey.pem:



#CA秘密鍵の場所

/etc/pki/CA/private/cakey.pem



#CAのcsr作成(openssl.cnfにデフォルト値を設定)

root@god tls]# openssl req -new 
-key ./private/cakey.pem 
-out ./cacert.csr

Enter pass phrase for ./private/cakey.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [Tokyo]:
Locality Name (eg, city) [Shinjuku]:
Organization Name (eg, company) [example]:
Organizational Unit Name (eg, section) [tech]:
Common Name (eg, your name or your server's hostname) []:myca.example.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:



#CAのcsrに自己署名してCAの証明書を生成(1行で入れる)

openssl x509 -days 365 -in ./cacert.csr 
-req -signkey ./private/cakey.pem 
-out ./cacert.pem

/etc/pki/CA/cacert.pem



#以下、サーバ証明書作成
#今回作成する証明書はpaloaltoのglobal protectで使う

#サーバの秘密鍵作成

[root@god tls]# openssl genrsa -aes256 -out ./gpkey.pem 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.................................................................+++++
...................+++++
e is 65537 (0x010001)
Enter pass phrase for ./gpkey.pem:
Verifying - Enter pass phrase for ./gpkey.pem:


/etc/pki/CA/gpkey.pem



#サーバのCSR発行(1行で)

[root@god tls]# openssl req 
-new -key ./gpkey.pem 
-out ./gp.csr


Enter pass phrase for ./gpkey.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [Tokyo]:
Locality Name (eg, city) [Shinjuku]:
Organization Name (eg, company) [example]:
Organizational Unit Name (eg, section) [tech]:
Common Name (eg, your name or your server's hostname) []:hoge.example.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:


/etc/pki/CA/gp.csr


#拡張属性指定

[root@god CA]# cat myext.txt
extendedKeyUsage = 1.3.6.1.5.5.7.3.1
subjectAltName=DNS:hoge.example.com



global protectは下記の情報を参考に設定した。
paloaltoではCA証明書とサーバ証明書を発行できる。(自己署名)
しかし、その証明書を使うとiphone接続時に証明書のエラーになってしまう。
https://hirotanoblog.com/paloalto-globalprotect-local-db/4784/#toc1

iOSやmacosでは、拡張属性が設定されている必要があるらしい。
https://support.apple.com/en-in/HT210176

そのためにわざわざcentosのopensslで証明書を発行した。



CAサイン=証明書発行
#実際は1行で入力
[root@god CA]# openssl ca -in ./gp.csr 
-keyfile ./private/cakey.pem 
-cert ./cacert.pem 
-out ./gp.pem 
-extfile ./myext.txt


Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for ./private/cakey.pem:
Check that the request matches the signature
Signature ok
ERROR:There is already a certificate for /C=JP/ST=Tokyo/O=example/OU=tech/CN=hoge.example.com
The matching entry has the following details
Type          :Valid
Expires on    :320203233742Z
Serial Number :06
File name     :unknown
Subject Name  :/C=JP/ST=Tokyo/O=example/OU=tech/CN=hoge.example.com
[root@god CA]#


#前回発行した証明書が有効なためerrorが出た。
#よくあるケースなのであえて残す
#この場合はrevokeする

[root@god CA]# ls ./newcerts/ -l
合計 32
-rw-r--r--. 1 root root 4002  6月  5  2021 01.pem
-rw-r--r--. 1 root root 4002  6月  6  2021 02.pem
-rw-r--r--. 1 root root 4002  6月  6  2021 03.pem
-rw-r--r--. 1 root root 4002  6月  6  2021 04.pem
-rw-r--r--. 1 root root 4161  2月  6 08:31 05.pem
-rw-r--r--. 1 root root 5631  2月  6 08:37 06.pem
[root@god CA]# openssl ca -revoke ./newcerts/06.pem
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /etc/pki/CA/private/cakey.pem:
Revoking Certificate 06.
Data Base Update


#再署名

[root@god CA]# openssl ca -in ./gp.csr 
-keyfile ./private/cakey.pem -cert ./cacert.pem 
-out ./gp.pem 
-extfile ./myext.txt

Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for ./private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 7 (0x7)
        Validity
            Not Before: Feb  6 01:15:35 2022 GMT
            Not After : Feb  6 01:15:35 2023 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            organizationName          = example
            organizationalUnitName    = tech
            commonName                = hoge.example.com
        X509v3 extensions:
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:hoge.example.com
Certificate is to be certified until Feb  6 01:15:35 2023 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated



#作った証明書の中身を確認


[root@god CA]# openssl x509 -in ./gp.pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 7 (0x7)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JP, ST = Tokyo, L = Shinjuku, O = example, OU = tech, CN = myca.example.com
        Validity
            Not Before: Feb  6 01:15:35 2022 GMT
            Not After : Feb  6 01:15:35 2023 GMT
        Subject: C = JP, ST = Tokyo, O = example, OU = tech, CN = hoge.example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:b2:de:1f:bb:12:39:56:0f:4b:77:9c:5f:96:d2:
(略)
                    87:27:1a:0f:42:d8:f8:bd:b3:3c:25:dd:be:fa:92:
                    1f:bb
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:hoge.example.com
    Signature Algorithm: sha256WithRSAEncryption
         66:76:ea:36:f8:9d:19:16:6f:3a:6c:1d:c1:b0:a8:f1:89:88:
(略)
         0b:74:e9:7e:f5:a1:ae:e1:a5:aa:b6:6b:62:7a:a8:14:7c:6a:
         b6:53:a5:d8
-----BEGIN CERTIFICATE-----
MIIDczCCAlugAwIBAgIBBzANBgkqhkiG9w0BAQsFADBrMQswCQYDVQQGEwJKUDEO
(略)
dxQmAodMgTX6seEhz5DKzhUMG3Aie3pLVFnzuW27FPwTIxa2wt5lAvoBDGb5pWrb
tAt06X71oa7hpaq2a2J6qBR8arZTpdg=
-----END CERTIFICATE-----
[root@god CA]#


#証明書と秘密鍵を pfx形式にする

[root@god CA]# openssl pkcs12 -export 
-out ./gp.pfx 
-inkey ./gpkey.pem 
-in ./gp.pem

Enter pass phrase for ./gpkey.pem:
Enter Export Password:
Verifying - Enter Export Password:



pfxファイルをダウンロードする

tera termのSSH SCPが簡単

ファイルの属性を 666にしてから(最低必要な権限は何だろう?)

chmod 666 gp.pfx



#2023/11 追記
証明書をインポートするとき、CA証明書とサーバ証明書をインポートする。
CA証明書とサーバ証明書の組織は同じであること。
サーバ証明書は秘密鍵もインポートする。(インポート時に指定する)
CA証明書は「信頼されたルートCA」にする。