Skip to main content

openssl

自己認証局の作成・運用を手作業で実施する手順を記載する。

自己認証局の作成

(事前にindex.txtファイル、serialファイル等もろもろ準備した、作業ディレクトリで作業。)

擬似乱数ファイルの作成(ほどよく更新されるファイルのダイジェストを得る。パーミッション、更新日時に留意。)

openssl dgst -sha1 /var/log/{lastlog,wtmp*} > rand.dat

秘密鍵を作成(当面はRSAで問題ない) aes256で秘密鍵を保護。

openssl genrsa -aes256 -rand rand.dat -out cakey.pem 4096
openssl rsa -in cakey.pem -text -noout
(nooutを指定しないと保護されない秘密鍵が画面に出る。)

CSRを作成(署名アルゴリズムをsha256にしている)

openssl req -config openssl.cnf -new -sha256 -key cakey.pem -out cacsr.csr \
-subj '/C=country/ST=state/L=local/O=object name/OU=organizational unit/CN=common name'
openssl req -in cacsr.csr -text -noout

CSRより自己署名のCA証明書を作成(署名アルゴリズムをsha256にする)

openssl req -x509 -sha256 -days ddd -key cakey.pem -in cacsr.csr -out cacert.cer
openssl x509 -in cacert.cer -text -noout

CAでの、CSRに対する署名

サーバ証明書、クライアント証明書でも同様

openssl ca -md sha256 -config openssl.cnf -cert cacert.cer -keyfile cakey.pem -in servercsr.csr -out servercert.cer

Revoke、CRL作成

以前と同じDNの証明書を作りたい場合、その証明書の期限が切れていても、事前に以前のものを取り消す必要がある場合がある。

openssl ca -config openssl.cnf -cert cacert.cer -keyfile cakey.pem -revoke usercert.cer
openssl ca -config openssl.cnf -md sha256 -cert cacert.cer -keyfile cakey.pem -gencrl -out crl.pem
openssl crl -in crl.pem -text -noout

CA証明書とCRLを結合して利用する場合がある。 結合してできたファイルをCA証明書として指定することで、CRLの情報も読み取られる。(dovecot等)

cat cacert.cer crl.pem > cacert2.cer
openssl crl -in cacert2.cer -text -noout
openssl x509 -in cacert2.cer -text -noout

結合したファイルで、サーバ証明書を検証する。

openssl verify -crl_check -CAfile cacert2.cer usercert.cer

サーバ証明書の申請

クライアント証明書でも同様

擬似乱数ファイル作成。秘密鍵作成

openssl dgst -sha1 /var/log/{lastlog,wtmp*} > rand.dat
openssl genrsa -out serverkey.pem 2048
openssl rsa -in serverkey.pem -text -noout

証明書署名要求を作成 プライベートCAで自分で署名する分には、CSRの署名アルゴリズムにこだわる必要はない。 認証機関に承認を依頼する場合は影響があるとかないとか。

openssl req -config openssl.cnf -new -sha256 -key serverkey.pem -out servercsr.csr \
-subj '/C=country/ST=state/L=local/O=object name/OU=organizational unit/CN=my server'
openssl req -in servercsr.csr -text -noout

CSRをCAに申請して署名してもらう。 署名された証明書を確認する。

openssl x509 -in servercert.cer -text -noout
openssl verify -purpose sslserver -CAfile cacert.cer servercert.cer
openssl verify -purpose sslclient -CAfile cacert.cer usercert.cer

必要に応じて秘密鍵のパスフレーズ解除

openssl rsa -in serverkey.pem -out serverkey-nopass.pem
chmod 600 serverkey-nopass.pem

証明書、ssl通信のテスト

クライアントからの接続テスト

openssl s_server
-CAfile cacert.cer
-cert servercert.cer
-key serverkey.pem
-Verify num クライアント証明書を要求し、検証する
-crl_check CRLによる検証を実施
-state

サーバへの接続テスト

openssl s_client
-connect address:port 省略時はlocalhost:4433
-CAfile cacert.cer
-cert usercert.cer
-key userkey.pem
-crl_check
-state

pkcs12の作成

(スマホ、PC等にインストールできるように)クライアントの秘密鍵、証明書を1ファイルにまとめる。(拡張子はpfxやp12が一般的)

openssl pkcs12 -export -in cert.cer -inkey key.pem -out file.p12

iphoneで、CA証明書(.cer)と、p12ファイル(.p12)をメール等で送って、それぞれ「信頼」する。

[おまけ]秘密鍵と証明書の対応の確認

秘密鍵と証明書のmodulusが同一であることを確認(md5ダイジェストが一致することをもってよしとする)

openssl rsa -in 秘密鍵 -modulus -noout | openssl md5
openssl x509 -in 証明書 -modulus -noout | openssl md5

[おまけ]楕円曲線暗号を使った鍵の作成

google先生によると、prime256v1、secp384r1 あたりが良く使われるらしい。(ecdsaの使用の判断は熟慮の上で。)

openssl ecparam -list_curves
openssl ecparam -name secp384r1 -genkey -out secp384r1.key
openssl ec -in secp384r1.key -text -noout
openssl ec -in secp384r1.key -out secp384r1_aes256.key -aes256

認証局による証明書は、暗号化とサーバ運営者の身元確認という目的がある。 個人で作成する自己認証局では、暗号化はできるが身元確認ができないと言われる。 実社会で互いに信頼できる相手なら、CA証明書を配布して事前にインストールしてもらうようにすれば、身元確認の問題はおきないのではないか。 限定された範囲での利用なら、この運用で問題ないのではないか。

openldap tools

ldapエントリの検索

ldapsearch -x [-H ldap:///] -D "<basedn>" -W -b <searchbase> [filter]

ldapmodifyによるエントリの更新

ldapmodify -x [-H ldap:///] -D "<basedn>" -W -f <file.ldif> [-n -v]
-n: dry-run
-v: verbose

ldapmodifyで使用するldifファイルの例

(例) 既存のdn に、新しい属性を追加する。
dn: uid=user1,ou=user,dc=example
changetype: modify
add: gecos
gecos: user1@example
<複数のエントリを続ける時は、空行で区切る>
dn: uid=user2,ou=user,dc=example
changetype: modify
add: gecos
gecos: user2@example

serversman vps

ServersMan@VPSは、コンテナ型仮想化の virtuozzo を採用した、ホスティングサービス。

Debianで使っていたのだが、間もなくWheezyのLTSサポート期限を迎えるのに、新しいバージョンの対応が公表されないので、名残惜しいけど退会することにした。

よかったこと

  • 東京でサーバを借りられる。固定アドレス。IPv6あり。料金が安い。コスト/パフォーマンス比は悪くないのではないか。
  • 個人用途で、Apache, PosgreSQL, PHPのアプリを動かしていたが、速度等の不満は特になかった。
  • 環境について技術的な内容の問い合わせ(メール)をしたことがあったが、レスポンスの早さ・内容とも悪印象はなかった。

残念なこと

  • DebianでサポートされているバージョンはWheezyが最新。Ubuntuでは(14.04)が最新。(私用ではDebian系を使いたい)
  • 環境に起因する制限がいくつかある。loopデバイスが使えない。コンテナ、仮想環境が使えない等。

各種アプリケーションがプリインストールされたコースもあるが、自分は試したことは無い。 ネットワーク/セキュリティについての理解がある人が、自分で構築できるサーバを個人用途で東京に安く借りたい、性能を求める場合にはそれだけの対価を支払うつもりがある、という場合にはおすすめできる。

(最近は新しいニュースリリースもなく、勝手な見解だが、現在は維持・運用するだけにとどまり、積極的な増設・投資はだいぶ前からやめているのではないかと感じている)

windows script host by jscript

スクリプトの呼び出し。 アイコンのダブルクリックや、アイコンへのドラッグ&ドロップでも起動できる。

cscript script.js //Nologo
wscript script.js //Nologo

メッセージの表示。cscript ... で実行するとターミナルに表示される。

WScript.Echo( "メッセージ" + foo);

バッチファイルを呼び出す

var openssl     = "C:\\Users\\public\\Documents\\bin\\openssl.exe";
var shell   = WScript.CreateObject("WScript.Shell");

try {
  oExec = shell.Exec( openssl + " version" );
  //oExec = shell.Exec( openssl + " --help" );
  while ( ! oExec.StdOut.AtEndOfStream ) {
    WScript.Echo(oExec.StdOut.readline());
  }
  while ( ! oExec.StdErr.AtEndOfStream ) {
    WScript.Echo(oExec.StdErr.readline());
  }
}
catch (e){ 
  WScript.Echo(e)
}

引数のぶんだけ繰り返して実行する

var objArgs = WScript.Arguments;
var fso     = new ActiveXObject("Scripting.FileSystemObject");
var file;

for (i = 0; i < objArgs.length; i++) {
  try {
    file = fso.GetFile( objArgs(i) );
    fin = fso.OpenTextFile(file, 1, false);
    while ( ! fin.AtEndOfStream ) {
      line = fin.readline();
      WScript.Echo(line);
    }
    fin.Close();
  }
  catch (e) {
    WScript.Echo(e);
  }
}

ファイルを開き一行ずつ読み込んで処理。

var objArgs = WScript.Arguments;
var fso     = new ActiveXObject("Scripting.FileSystemObject");
var file;
var fin;

for (i = 0; i < objArgs.length; i++) {
  try {
    file = fso.GetFile( objArgs(i) );
  }
  catch(e) {
    WScript.Echo(e);
    continue;
  }
  fin = fso.OpenTextFile(file, 1, false);
  while ( ! fin.AtEndOfStream ) {
      line = fin.readline();
      WScript.Echo(line);
  }
  fin.Close();
}

アクセスファイルを開き、マクロを呼び出す。

var dbfile='C:\\Users\\public\\Documents\\Database1.accdb';
var timeout = 500; // milliseconds
try {
  var AccessApp = new ActiveXObject( "Access.Application" );
  // AccessApp.Visible = true;
  WScript.Sleep( timeout );

  try {
    AccessApp.OpenCurrentDatabase( dbfile );
    WScript.Sleep( timeout );
    // マクロを実行する例
    // AccessApp.DoCmd.RunMacro( "マクロ名" );
  }
  catch(e) {
    WScript.Echo(e);
  }
  finally {
    AccessApp.CloseCurrentDatabase();
  }
}
catch(e) {
    WScript.Echo(e);
}
finally {
  AccessApp.Quit();
  AccessApp = null;
}

excel

var excelfile = "c:\\users\\public\\documents\\test.xlsm"
var updatelinks = true;
var readonly = true;

try {
  var ExcelApp = new ActiveXObject("Excel.Application");
  // ExcelApp.Visible = true;
  // ExcelApp.DisplayAlerts = true;

  try {
    // var book = ExcelApp.Workbooks.Open(excelfile);
    var book = ExcelApp.Workbooks.Open(excelfile, updatelinks, readonly);
    // マクロを実行する例
    ExcelApp.Run("マクロ名")

    // シートに記入して保存する例
    // var sheet = book.sheets(1);
    // sheet.Cells(2, 1).value = "message...";
    // book.Save();
  }
  catch(e) {
    WScript.Echo(e)
  }
  finally {
    book.Close();
  }
}
catch(e) {
  WScript.Echo(e)
}
finally {
  ExcelApp.Quit();
}

backup and restore openldap

backup

# systemctl stop slapd
slapcat > ldap.ldif
slapcat -b cn=config > ldap-config.ldif

restore

systemctl stop slapd
mv /etc/ldap/slapd.d{,.bak}
mv /var/lib/ldap{,.bak}
mkdir /etc/ldap/slapd.d
mkdir /var/lib/ldap
slapadd -n0 -F /etc/ldap/slapd.d -l ldap-config.ldif
slapadd -l ldap.ldif
chown openldap:openldap -R /etc/ldap/slapd.d
chown openldap:openldap -R /var/lib/ldap
systemctl start slapd

sample of simple bash scripts

ファイルバックアップスクリプト

引数に与えられたファイルを3ケタの連番をつけてコピーする。 まだいま一ついけてない。

gistの引用のテストをかねて。

git

オープンソースの分散型VCS。同種のアプリケーションと比較してgitが優れているところは、ユーザが多く情報が多いという点。

gitリポジトリの作成

cd myproject
git init
git add .
git status
git diff
git rm [-r] target # -rで、ディレクトリを削除
git commit -m "commit message"
git log

作業ディレクトリを持たない公開用リポジトリの作成

git init --bare
or
git clone --bare myproject myproject.git

git log
git branch

単純なリモート作業

git clone git://example.com/.../myproject.git # リポジトリのclone
cd myproject
:
git push [origin] [master] # 変更内容をpush

git pull # fetchしてmerge

ブランチを作成し作業対象とする

git branch master
git pull
git checkout -b mybranch
git branch

masterブランチにマージ。不要なブランチの削除

git checkout master
git merge mybranch
git branch -d mybranch

ブランチをリモートにpush

git push origin mybranch

ブランチをリモートからfetchして作業

git fetch origin
git branch -a
git checkout -b mybranch origin/mybranch # ブランチを作成してチェックアウト

リモートブランチの削除

git push origin :mybranch

change last commit

git add file
git commit --amend -m "commit message"
git push -f origin master

Stash the changes in a dirty working directory away

git stash
git stash list
git stash show -p stash@{0}

apply stash on top of the current working directory. and remove a stash from the list

git stash apply stash@{0}
git stash drop stash@{0}

reset indext to cancel add operation and leave the file as it is

git reset HEAD xxxx.txt

ignore file permission change (chmod)

git config --local core.filemode false
git config --local --list

example of URIs

ssh://username@serverhostname/var/lib/git/myrepository.git
file:///var/lib/git/myrepository.git

ansible

エージェントレスの構成管理ツール。

対象ホストでは、エージェント等をインストールする必要がなく、基本的に下記を満たせばよい。

  • Pythonが動くこと
  • 相手がリモートホストならsshでログインできること

(ただし、使うモジュールによっては追加パッケージが必要。例:aptモジュールを使うためにはpython-aptが必要)

「あるべき姿」をYAMLで記載する。(記載したファイル(群)をplaybookと呼ぶ)

ansible
  -i hosts インベントリファイルを指定
  -m ping 疎通確認
  -m setup ファクト収集
  -a 'command -h' 指定したコマンドを実行
  --ask-pass ログインで必要となるパスワードを要求
  targethost 対象ホストを指定

リポジトリファイル(hosts)の内容の例

[myserver]
192.168.1.1 ansible_ssh_user=myusername
[desktop]
myhostname  ansible_connection=local

疎通確認の例

$ ansible -i hosts -m ping 192.168.1.1 --ask-pass
$ ansible -i hosts -m ping myhostname
    $ ansible -i hosts -m ping 192.168.1.1 --ask-pass --ssh-common-args '-o PubkeyAuthentication=no'

ansible-playbook
  -i hosts
  --syntax-check  プレイブックの文法チェックのみ
  --list-tasks   プレイブックのタスクをリスト表示
  --check ドライラン
  --ask-sudo-pass sudoで必要となるパスワードを要求
  --ask-su-pass suで必要となるパスワードを要求
  --ask-pass ログインで必要となるパスワードを要求
  --diff show differences
  --tags "tag1,tag2,..."
  --skip-tags "tag1,tag2,..."
  playbook.yml プレイブックを指定

プレイリストの内容確認、実行前確認、設定反映の例

$ ansible-playbook -i hosts --syntax-check myserver.yml
$ ansible-playbook -i hosts --list-tasks myserver.yml 
$ ansible-playbook -i hosts --check myserver.yml --ask-pass
$ ansible-playbook -i hosts myserver.yml --ask-pass

Sample ansible playbook in a single yaml file

resource monitoring

top

topコマンドを一回だけ実行して終了する(バッチモード)。

top -b -n 1

sar

sarで蓄積したデータの閲覧

LANG=C sar # LANGが日本語だと時分秒が日本語表記になるので、LANG=Cで実行
-q # loadaverage
-u # CPU
-b # I/O
-r # メモリ
-S # スワップ
:
:
-n DEV  # 送受信パケットの情報
   EDEV # エラーパケットの情報
   :
   :
-f /var/log/sa/saxx # 履歴ファイルを指定
-s hh:mm # 以降のデータを表示
-e hh:mm # 以前のデータを表示
(-fではなく、[interval] [count]の指定で、リアルタイム表示できるらしい)

network commands on linux

Recently, the iproute2 package's commands are recommended instead of net-tools to show or control network settings.

確認コマンド

show mac address table

ip [-6] neigh
arp -an

show interface mac address

ip link
ifconfig

show host ip address

ip [-6] addr
ifconfig

show routing table

ip [-6] route
netstat -rn
route -n

show tcp and udp port status

ss -an
netstat -an

query domain name server

dig <@nameserver> domainname [a|any|mx|ns|...]

cat << END > list.dig
@xxx.xxx.xxx.xxx example.com
@xxx.xxx.xxx.yyy example.com
END

dig -f list.dig


nslookup domainname <nameserver>

nslookup << exit
server xxx.xxx.xxx.xxx
example.org
example.com
exit

設定コマンド

down and up the link

ip link set br0 down
ip link set br0 up

delete and add from/to interface

ifconfig eth0 0.0.0.0
ifconfig eth0 192.168.0.1 netmask 255.255.255.0
ip address delete 192.168.0.1/24 dev enp0s25    
ip address add 192.168.0.1/24 brd + dev enp0s25

delete and add default gateway

ip route delete default
ip route add default via 192.168.0.254

add static route

ip route add 10.0.0.0/24 via 192.168.0.252

operate virtual bridge

show information of virtual bridge

brctl show
ip link show master br0
bridge link show

add and delete virtual bridge

ip link add br0 type bridge
ip link del br0
brctl addbr br0
brctl delbr br0

create tap0 and set pormiscuous mode

ip tuntap add dev tap0 mode tap
ip link set tap0 up promisc on
ip link set tap0 down promisc off
ip tuntap del dev tap0 mode tap

add and delete interface to virtual bridge

ip link set dev enp0s25 master br0
ip link set dev tap0 master br0
ip link set dev enp0s25 nomaster
brctl addif br0 eth0
brctl addif br0 tap0
brctl delif br0 eth0

write below to network config file and execute service networking restart

auto eth0
iface eth0 inet static
  address 0.0.0.0
auto br0
iface br0 inet static
  address 192.168.0.1
  netmask 255.255.255.0
  bridge_ports eth0

Alternatively you can use systemd-networkd for handling virtual bridge. At first put these 3 files in /etc/systemd/network

eth0.network

[Match]
Name=eth0

[Network]
Bridge=br0
## if you want to use this interface, comment out above line
## and specify dhcp or static address
#DHCP=ipv4
#Address=192.168.0.1
#Gateway=192.168.0.254
#DNS=192.168.0.254

br0.netdev

[NetDev]
Name=br0
Kind=bridge

br0.network

[Match]
Name=br0

[Network]
# DHCP=ipv4
Address=192.168.0.1
Gateway=192.168.0.254
DNS=192.168.0.254

then enable and start systemd-networkd

systemctl enable  systemd-networkd
systemctl restart systemd-networkd

openvswitch

show information of virtual bridge

ovs-vsctl show

add and delete virtual bridge

ovs-vsctl add-br br0
ovs-vsctl del-br br0

add and dlete interface to virtual bridge

ovs-vsctl add-port br0 eth0
ovs-vsctl add-port br0 tap0
ip link set br0 up
ovs-vsctl del-port br0 tap0
ovs-vsctl del-port br0 eth0