emacsとzshで共有できるクリップボード(キルリング)もどきの自作
sshでサーバにつないでscreen上でzshとかemacs使っていると emacs<->zshとかscreen上のシェル間でkill, yank出来なくてもどかしい。
ホスト側でマウス操作するなりすればいいんだけど、 最近ipadからsshしてるからそれも面倒くさい。 x windowも動かしていないからxselも使えない。
screenにコピーペーストもあるんだけど、 コマンドでやりたいので自作することにする。
実装方針
kill ring用のファイルを用意し、そのファイルで共有することにする。
関数名はshared-yankとshared-killとする。 ショートカットはshared-yankをESC-uとshared-killをESC-jにする。 emacsにしてもzshにしても大したキーバインドが割り当てられていないのでちょうどいい。
kill ring用のファイルは~/.tmp/shared_kill_ringとする。 個人用なので~以下でパーミッションは400推奨。
emacs
(defun shared-yank () "yank from shared kill ring file" (interactive) (with-temp-buffer (insert-file-contents "~/.tmp/shared_kill_ring") (setq shared_kill_ring (read (buffer-string)))) (insert-before-markers (format "%s" shared_kill_ring))) (global-set-key "\M-u" 'shared-yank) (defun shared-kill (beg end) "kill to shared kill ring file" (interactive "r") (if (and mark-active transient-mark-mode) (progn (setq temp (buffer-substring beg end)) (with-temp-buffer (insert (format "%s" temp)) (write-file "~/.tmp/shared_kill_ring"))))) (global-set-key "\M-j" 'shared-kill)
zsh
function shared-kill(){ echo $RBUFFER > ~/.tmp/shared_kill_ring; RBUFFER="" } function shared-yank(){ LBUFFER=$LBUFFER"`cat ~/.tmp/shared_kill_ring`"; } zle -N shared-kill zle -N shared-yank bindkey '^[j' shared-kill bindkey '^[u' shared-yank
最後に
ringと書いているが、あれは嘘だ。 あと、killの方はzshとemacsで挙動が違います。 (emacsの方はcopy-regionの挙動)
実践パケット解析第3版 レビュー
Interop TokyoでO’reillyが10%割引で販売してて、かつ実践パケット解析の第3版が先行販売してた。前々から読みたい本だったので、つい買ってしまった。というわけでせっかくだからレビューする。
TL; DR
- サンプルのpcapファイルを用いて、Wiresharkの使い方を手を動かしながら身につけることが出来る
- Tsharkとtcpdumの使い方もわかる←new
- TCP/IPの仕組みをパケットを解析しながら理解できる
- ネットワークのトラブルシューティングやセキュリティの解説もある
- TCP/IPがよくわかっていない人、wiresharkなどパケットキャプチャを使いこなしたい人は買って損はないと思う。
メモ書き
- Wiresharkにて一連のTCPをストリーム表示できる
- IOグラフなどの統計の取得も基本機能として備えている
- ARPスプーフィングのやり取りを見るだけでも、自作自演感が結構面白い
- tcpのRSTフラグがセットされたパケットをフィルタ出来る(ビット単位でのフィルタ)
- 著者のChris Sandersはケンタッキー州でビーチに面した土地を売りに出している。
落ち穂拾い
Conoha × Let’s encryptにてワイルドカード証明書を自動取得する
Let’s encryptではワイルドカード証明書を取得できるようになっているが、ワイルドカード証明書の場合にはDNSでの認証が必須となっている。
3ヶ月ごとに手動で更新+DNSに認証用のレコード追加は手間になるのでこれを今回自動化する。
DNSのレコード追加は使用しているDNSサーバ次第であるが、ConohaではDNS用のAPIがあるためこちらを利用してスクリプトを作成する。作成スクリプトは認証レコード追加用と削除用の2種類。
それぞれのスクリプトはcertbot実行時に—manual-auth-hook及び—manual-cleanup-hookのオプションで指定することで実行できる。なお、スクリプト内では認証用のトークンは$CERTBOT_VALIDATIONにて取得できる。
作成したスクリプト github.com
なお、スクリプトを指定せずにcertbot renewすると The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping. といったエラーが出る。
FW設定とL2TP/IPsec 接続エラー
概要
- conohaのVPS(CentOS)にてL2TP/IPsecを構築してAndroid/iOS/windowsから接続していたが、FW(openstackのnetwork apiによるFW)の設定を変更したらwindowsからのみ接続できなくなった。
- FWの設定変更(任意のプロトコル接続の許可設定追加)により事象は解決した。
背景
CentOSにL2TP/IPsecを構築し、Android/iOS/windowsからVPN接続出来るようにしていた。どの環境においても標準機能で接続できるため、結構便利。
CentOSではfirewalldの設定をしていたが、特定のポート宛に頻繁にアクセスが来ていたため、dropログの容量が1日1G近くなっており、運用上の懸案であった。とはいうものの、ログを取らないようにするのは気持ちが悪い。
このため、openstack側のFWを設定し、これらを遮断することにした。運用が面倒になるだでスマートな感じはしないのだけれど、firewalldのdropログが増えなくなるのは何となく安心感がある。
もろもろサービスが動くのを確認してFWの設定(稼働サービス用のポートのホワイトリスト登録)を完了したのだが、ある日windowsのVPNが切れて、再接続出来なくなった。
(FW設定時にwindowsのVPNはつなぎっぱなしだったため、すぐには問題が発生せず、FWの設定から数日経ってから発覚した)
原因
windows端末はVPSを使用していたため、グローバルIPを持っており、ESP(プロトコル番号50)にて通信を行っていたが、これがFWにて弾かれていた。windowsのVPNエラー番号としては800や809などが発生(windowsのVPN設定により若干変動)
エラー809は「リモートサーバが応答しないため、使用するコンピューターとVPNサーバー側のネットワーク接続を確立できませんでした。」等の表示。
こちらのエラー番号で検索すると、大体がNAT超えのための設定にたどり着くのだが、今回はNATをそもそも使用していないので非該当。
なお、AndroidやiOSはnatを使用していたため、ESPを使用せずUDPにカプセル化して通信するので事象が発生しなかった。これにより、当初はwindows側の設定を疑ったので、パケットキャプチャで双方のパケットを確認しESPパケットがCentOS側に届いていないのを発見するまで原因にたどり着けなかった。
対策
FWの設定にて任意のプロトコルを許可するよう設定することで解消。なお、conohaではプロトコル指定が出来るのはTCP、UDP、ICMPのみであるため、それ以外のプロトコルを許可するためにはすべて許可の設定になる。
感想
windows側がグローバルIPで、conoha(openstack)のFW使用なので珍しいケースにハマった感があるが、IPsecのプロトコルを理解してなかったことを痛感した。もうちょっとちゃんと勉強したい。
追記
任意のプロトコルを許可すると、拒否したい通信も通ってしまう(ホワイトリストだから当然の動作!!)
よって、今回はグローバルIPを用いているwindows側でもNAT使用時と同様にUDPカプセル化を用いるように設定する。
設定項目は
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgentにAssumeUDPEncapsulationContextOnSendRuleを作成し、値を2にする
forceencapsとかnat_traversalとかの項目を指定している記事も見つかるがlibreswanでは廃止されている模様。
(/var/log/messagesにobsolete keyword 'forceencaps' ignoredが記録される)
mod_securityとAuditConsoleを使ってみる
OSSなWAFがどんなものか気になったのでmod_securityとAuditConsoleを使ってみた。
また、両者の連携のためにmlogcが必要なため、併せて入れる。
おおむねこちらの記事を参考にした。
AuditConsoleを設定 - あるシステム管理者の日常
差分としては、AuditConsoleをyumにてインストールしたことくらい。
ちなみに、Javaのバージョンは特に意識しなくても問題なかった。
(1.8系のJavaが依存パッケージとしてインストールされていた)
mod_security
AuditConsole
AuditConsoleはtomcatで動くmod_securityのログの監視用Webインターフェースである。
mod_securityのコンソールはAuditConsoleとWAF-FLEの2種類あるようであるが、
今回はAuditConsoleを動かしてみる。WAF-FLEもそのうち試してみたい。
install / setup
こちらもyumで入れる。
標準のリポジトリには入っていないため、jwallのリポジトリを追加する。
手順はjwallのUser Guideに記載してある。
サービス開始前に
/etc/default/auditconsoleに
JAVA_HOMEを追記する。
JAVA_HOMEの確認は
readlink $(which java)
で出来る。
(設定時はbin/javaを除く。例えば、/usr/lib/jvm/java-1.6.0-openjdk)
ポート番号を変えたい場合にはここの設定で変えておく(デフォルトでは8080と8443)。
# systemctl start auditconsole
http://localhost:8080にアクセスして初期設定をする。
設定内容を変更する必要は特になかった。
mlogc
ソースからコンパイルする。
mod_securityのソースに含まれているのでダウンロードして、
./configure
make
する。
mlogcだけ欲しいのでmake installはしない。
mlogc.con及びmod_security.confを設定する。
なお、iusのリポジトリであればyumでインストールできるが、httpdもiusのものを入れる必要があるため、今回は却下。
エラー対応
mlogc-error.logに
Invalid entry (failed to match regex)
が出て、ログが正常にAuditConsoleに連携しない事象が発生。
mod_security.conにて
SecAuditLogType Serial
になっているのが原因であった。
SerialをConcurrentに変更して解消。
各端末へのクライアント証明書のインストール
android、ios、ubuntuへクライアント証明書をインストールした際のメモ
インストール方法が端末によって癖があるので少しハマった。
ちなみに証明書はCAを構築して作成したが、作成方法は他のサイトで見つかるので割愛。
ios
ios バージョン:9.3.5(ipad miniの結構古いやつ)
webサーバから証明書をダウンロードしてインストールしようと試みるが、chromeではダウンロードしたあとのインストールが出来ない。
Safariでダウンロードすると、設定に切り替わり、インストール出来る。 (メール経由でも出来るようである)
android
android バージョン:6.0.1
同じくwebサーバからダウンロードする。
ダウンロードするものの、「インストール出来ませんでした。証明書ファイルが読み取れませんでした」と表示が出る。
設定→セキュリティ→情報セキュリティ→証明書のインストールからインストールすると正常にインストール出来る。
(webから安易にインストール出来ないようにということなのだろうか)
なお、インストールした証明書の一覧を出したり、個別にクライアント証明書を削除する機能もなさそうである。
ubuntu
ダウンロードしてダブルクリックするとGnome2 key strageにインストール出来るがブラウザとの連携が不明のため、chromeで個別に設定(インストール)した。
多分連携が出来ると思うが、よくわかっていない。
追記
CRLを作成してApacheの設定をしたが、うまく動作せずハマったのでメモ。 /var/log/httpd/ssl_error_logに以下のエラーが出ており、Apacheのコンフィグを変更した。
X.509 CRL storage locations configured, but CRL checking (SSLCARevocationCheck) is not enabled
Apacheに以下を追記して解消
SSLCARevocationCheck chain
参考: https://stackoverflow.com/questions/23939112/apache-not-checking-crl-for-revoked-certificates
conohaのvpsにcentos7の作業環境作ったのでまとめ(ログイン環境編)
これまでdtiのvpsを作業環境として使っていたのだが、centos6からcentos7に環境を変えるのを契機にconohaに乗り換え。ということでログイン環境の設定をしたのでメモ。 今回は主にpostfixとopenvpnの設定。 postfixはroot宛メールをgmailに転送する用で、外向けに送信が出来ればいいので、真面目なメールサーバは作っていない。
パッケージのインストール
postfixはデフォルトでインストール済みなのでopenvpnだけインストール。 zshとか色々入れているけれど、ここでは割愛。 net-toolsは元々入っていたかもしれない。bridge-utilsはいらないかも。。。
sudo yum --enablerepo=epel install openvpn easy-rsa net-tools bridge-utils
設定
まずはホストネームとドメインネームの設定。
1.hostname
/etc/hostnameに以下を入れる。
<hostname>.<domain name>
2.domain name
centos7からはコマンドで設定。
sudo nmcli c modify eth0 ipv4.dns-search <donamin name>
設定入れたらリブート。
3.aliasとログイン時のslack通知の設定
今回は別ユーザにroot宛メールを転送し、それからgmailへ転送する。
まずはユーザの追加
useradd <new user> passwd <new user>
/etc/aliasesに以下を追加
root: <new user> <new user>: <mail address>
忘れずにnewaliases
sudo newaliases
- slackへの通知設定
事前にslackにてapi urlを取得しておき、/etc/ssh/sshrcに以下を追記
curl -X POST --data-urlencode \ "payload={\"channel\": \"#<channel name>\", \ \"username\": \"$USER\", \ \"text\": \"$USER has logged in from $SSH_CLIENT at `date +"%Y/%m/%d %p %I:%M:%S"`\", \ \"icon_emoji\": \":ghost:\" \ }" \ <slack api url> > /dev/null 2>&1 &
- sshのポート番号を変える
/etc/ssh/sshdのポート番号設定箇所(port=22
)を変更。デフォルトは22だが、好きな番号にする。
変えたらsshdをリスタート
- firewalld
/usr/lib/firewalld/services/ssh.xmlを/etc/firewalld/servicesにコピーして、ポート番号を変えておく。
firewall-cmd --add-service=ssh --permanent firewall-cmd --reload
smtp
1.postfix
基本はデフォルトの通りだが、以下修正箇所
myorigin = $mydomain
inet_interfaces = all
inet_protocols = ipv4
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
2.dns
conohaのコンソールにて以下レコードを追加する。 今回はサブドメインを使用するのでAレコードも必要になる SPFとしてTXTレコードも入れるとgmailがメールに重要マーク付けてくれる。
MX record: mx.<donamin name> value=mail.<donamin name> A record: mail.<domanin name> value=<ip address> TXT record: value="v=spf1 ip4: <ipaddress> -all"
3.firewalld
忘れずにポート開放。
firewall-cmd --add-service=smtp --permanent firewall-cmd --reload
4.動作確認
- オープンリレーの確認
不正利用されないようにオープンリレーになっていないかの確認。 ブラウザで以下サイトにアクセスして自分のメールサーバを入力
check.jippg.org
メールサーバから以下アドレスにメール送るとspfの設定状況を返送してくれる。
check-auth@verifier.port25.com
openvpn
1.鍵の生成
easy-rsaをつかって鍵、証明書を作成。詳細は割愛。廃止リストも作っておく。今回は/etc/openvpn/keysに諸々の鍵を配置した。必要なのは ca.crt, server.crt, server.key, client.crt, client.key, ta.key, crl.pem dh2048.pem。
いつも忘れるのだが、crlは証明書(certificate)、keyは鍵(key)、crlは廃止リスト(certificate revocattion list)、pemはファイル形式を示しているだけ。ta.keyはtls-auth用の鍵でこれによりHMAC署名が付く。
2./etc/openvpn/server.confの修正
<port number>
は好きなポート番号に変える。デフォルトポートは使いたくない。
以下有効設定の抜粋
port <port number> proto udp dev tun ca keys/ca.crt cert keys/server.crt key keys/server.key dh keys/dh2048.pem server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt keepalive 10 120 tls-auth keys/ta.key 0 # This file is secret cipher AES-256-CBC persist-key persist-tun status /var/log/openvpn-status.log log-append /var/log/openvpn.log verb 3 explicit-exit-notify 1 crl-verify keys/crl.pem script-security 2 --client-connect /etc/openvpn/up.sh --client-disconnect /etc/openvpn/down.sh
3.デーモンの設定
systemctlで設定する。 /usr/lib/systemd/system/openvpn@.serviceをopenvpn.serviceに書き換えて設定してもいいのだけれど、とりあえずopenvpn@serverにて対応。どっちのやり方が良いのかはよくわかっていない。
sudo sytemctl enable openvpn@server sudo sytemctl start openvpn@server
- up, down script
vpn接続時にslackに通知出す。 以下を/etc/openvpnに配置
up.sh
#!/bin/bash time=$(echo $(date +"%c")) USER=root TEXT=`cat <<EOF openvpn up virtual ip address = $ifconfig_pool_remote_ip ip address = $untrusted_ip $time name = $common_name EOF` curl -X POST --data-urlencode \ "payload={\"channel\": \"#<channel name>\", \ \"username\": \"$USER\", \ \"text\": \"$TEXT\", \ \"icon_emoji\": \":ghost:\" \ }" \ <slack api url> > /dev/null 2>&1 &
down.sh
#!/bin/bash time=$(echo $(date +"%c")) USER=root TEXT=`cat <<EOF openvpn down virtual ip address = $ifconfig_pool_remote_ip ip address = $untrusted_ip $time name = $common_name EOF` curl -X POST --data-urlencode \ "payload={\"channel\": \"#<channel name>\", \ \"username\": \"$USER\", \ \"text\": \"$TEXT\", \ \"icon_emoji\": \":ghost:\" \ }" \ <slack api url> > /dev/null 2>&1 &
4.ログの設定
ログのローテーションの設定/etc/logrotate.d/openvpnを作成し、以下を入力。
/var/log/openvpn.log { missingok notifempty sharedscripts postrotate systemctl restart openvpn@server 2>&1 > /dev/null || true endscript }
logrotate -dv /etc/logrotate.d/openvpn
にてdry-runが出来る。-fvにすると強制実行。
5.firewalld テンプレートをコピーして編集、ポート開放する。
cp /usr/lib/firewalld/services/openvpn.xml /etc/firewalld/services/ vi /etc/firewalld/services/openvpn.xml firewall-cmd --add-service=openvpn firewall-cmd --reload
openvpnで出来たtun0インターフェースにはinternalゾーンを適用
firewall-cmd --change-interface=tun0 --zone=internal nmcli conn show tun0
nmcliでないと、どのzoneが適用されているかが確認できないのだが理由がよくわからない。
※追記:この設定を入れてもゾーンはデフォルトのpublicが適用されている。仕方がないので、デフォルトゾーンをinternalに変更して対応。どうやらknown issueのようであるが、解消されてないのかな。 Bug 1065948 – firewalld zone not applied for vpn connections
firewalld
firewalld自体のログの設定
1.ログ取得の有効化
firewall-cmd --set-log-denied=all
にてdropしたログが/var/log/messagesに吐き出される。
2.modify /etc/rsyslog.conf
:msg, contains, "FINAL_REJECT" -/var/log/firewalld-drop.log
にてログを別ファイルに吐き出すように変える。 "FINAL_REJECT"はデフォルトのプレフィクス。 (本当はプレフィクスも変えたいが、デフォルトの設定がどうなっているのかよくわからないので、今回はそのまま)
3.logrotate
ローテーションの設定、ログのたまり具合が速かったのでdailyにしてみた。 /etc/logrotate.d/firewalldに以下を入力。
/var/log/firewalld-drop.log /var/log/firewalld { daily rotate 4 create postrotate /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true endscript }