なんかてきとうに

わりと個人的な忘備録的ですよ。

無断転載 #とは

vaaaaaanquish.hatenadiary.jp

無断転載についていろいろと書いてありますね! 私のアイコンも無断転載です!すみません! 好きなアイコンなんですけどオワコンなんです!もう更新されないんですよ!!!

それはさておき。

無断転載とかをRTしたり言及するのはできるだけ避けるようにしてますけど、現実は厳しいのですよね。

Youtubeとかアプリを開いたとたん、真っ先に無断転載動画とかでるじゃないですか?

目的のものを探そうとしても無断転載動画がひっかかるじゃないですか?しかも場合によってはオフィシャルより上位に。

もうね、つらいんです。ほんとに。

アーティストがYoutubeにチャンネル作って、動画上げてるのに、 それより画質が残念な無断転載動画が上位にくるんですよね。

私が見たいのはそれじゃない! 声を大にして言いたい。

こんな感じで読者になってくれるんでしょうか。

Firewallの設定は難しい。

大体題意の通りなのですが。

Firewallなら大抵NAT機能なんかも普通についていて、結構頭が良い。

それだけに、設定値をどうすればいいのかみたいなところが、癖みたいなのを知ってないと苦労するような気がする。という話。

とあるFirewallがEOSになるからと、ルータに乗せ換える設計をしていましたが、

FirewallでNATしていると、NAT変換後のIPアドレスをベースにルールを書くのか、NAT変換前のIPアドレスをベースにルールを書くのか

みたいなところにズレが生じたり、ルールを設定できる箇所が違ったり。

なんだかいろいろ面倒だなぁという感じです。

Linuxiptables触っていると、

  1. パケットがインターフェースに着信する。
  2. 着信インターフェースにてPREROUTINGプロセスが走る
  3. 着信インターフェースにてINPUTフィルターが動作する
  4. FORWARDされる
  5. 発信インターフェースにてOUTPUTフィルターが動作する
  6. 発信インターフェースにてPOSTROUGINGプロセスが走る

みたいな動作をして NATアドレス変換はPREROUTINGとPOSTROUTINGで行われるので、 イメージ的にはルーティングプロセス内IPアドレスと、実世界IPアドレスみたいなのがあって、 フィルターはルーティングプロセス内IPアドレスに対して行う。 というのが正解なんだけれど、

NATアドレス変換後というか、実世界IPアドレスにてルールを設定するFirewallというのに出会って苦労しました。

dockerでansibleのテストをする。

docker でansibleのテストができれば、
きっと、vagrantよりも速いはず!

ということでやってみる。

まずは適当にDockerfile作ってbuild
この時、authorized_keyを設定するようにDockerfileを作ると幸せです。

FROM ...
...
RUN mkdir -p /home/username/.ssh;chown username /home/username/.ssh; chmod 700 /home/username/.ssh
ADD authorized_key /home/username/.ssh/authorized_keys
RUN chown username /home/username/.ssh/authorized_keys;chmod 600 /home/username/.ssh/authorized_keys
...

こんな風に。

あとは普通に

docker build /path/to/Dockerfiledir/ base

出来上がったら、テストしたいansibleのplaybookに登録してある台数分作る。

mkdir -p /tmp/for/docker
chcon -Rt svirt_sandbox_file_t /tmp/for/docker

for i in `seq 1 5`; do mkdir -p /tmp/for/docker/$i; done
chcon -Rt svirt_sandbox_file_t /tmp/for/docker

で、キャッシュ用ディレクトリを作っておくと、2回目以降、ファイルのダウンロードとか楽になるかも。

ただし、キャッシュ読み書きでconflict起こす可能性があるので、コンテナごとに作るか
.ansible.cfg を作って

[defaults]
forks=1

にしておきましょう。

キャッシュを個別に作った場合は

for i in `seq 1 5';do docker run -v /tmp/for/docker/$i/:/var/cache/ -d --name ansible-test$i base;done

キャッシュを共用させる場合は

for i in `seq 1 5';do docker run -v /tmp/for/docker/:/var/cache/ -d --name ansible-test$i base;done

こんな感じでさくっと5台作る。
で、IPアドレスを確認

for i in `seq 1 5`;do docker inspect -f "{{ .NetworkSettings.IPAddress }}" ansible-test$i

これをansibleのインベントリファイルに書く。この辺はplaybook次第ですが
たとえば test-inventoryという名前で

[webservers]
172.17.0.2
172.17.0.3
172.17.0.4
[dbservers]
172.17.0.5
172.17.0.6

こんな感じのファイルを作る。IPアドレスは先のコマンドで確認したやつです。

あとは

ansible-playbook -i test-inventory --private-key=/path/to/docker/container/private-key /path/to/playbook

こんな感じでテストできます。

ダメだったら

docker ps -aq | xargs docker rm -f

でさくっとコンテナを削除してplaybook修正して docker runからやりなおし。

Expect的な処理は平行実行させると速いですね

&入れてwaitするだけでこの違い

平行実行するコード

#!/bin/bash
. ${0%/*}/.password
TMP=$(mktemp -d)
trap "rm -rf $TMP" 0
for i in $(cat list.txt);do
    expect -c "
    spawn ssh $user@$i -o UserKnownHostsFile=/dev/null
    expect {
        yes/no { send yes\r ; exp_continue }
        -nocase password { send $passwd\r ; }
    }
    expect >
    send \"term len 0\r\"
    expect >
    send \"sh arp\r\"
    expect >
    " > $TMP/$i.log &
done
wait
cat $TMP/* > $(date +"%Y%m%d").log

実行速度

real    0m6.605s
user    0m0.107s
sys     0m0.071s

順次実行するコード

#!/bin/bash
. ${0%/*}/.password
TMP=$(mktemp -d)
trap "rm -rf $TMP" 0
for i in $(cat list.txt);do
    expect -c "
    spawn ssh $user@$i -o UserKnownHostsFile=/dev/null
    expect {
        yes/no { send yes\r ; exp_continue }
        -nocase password { send $passwd\r ; }
    }
    expect >
    send \"term len 0\r\"
    expect >
    send \"sh arp\r\"
    expect >
    " > $TMP/$i.log
done
cat $TMP/* > $(date +"%Y%m%d").log

実行速度

real    0m59.881s
user    0m0.134s
sys     0m0.070s

paramikoで対話型処理をしたい

python使ってNW機器のコンフィグバックアップとか、
いろんなデータ拾ったりとかを自動化できると便利ですよねぇ。

そんなわけで、やってみる。

環境 * Python 3.5.1 * paramiko 1.16.0

import paramiko

host='somehost'
username='someuser'
password='password'
password_e='password_e'

client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host,username=username,password=password,look_for_keys=False,allow_agent=False)

stdin,stdout,stderr = client.exec_command('show arp\n')
for line in stdout:
    print(line)

こういうのは問題なくできますね。
最後3行の部分を

stdin,stdout,stderr = client.exec_command('enable\n')
for line in stdout:
    print(line)

みたいな。enable送ってpasswordが来たら……みたいなexpectでやるようなことをしようとしたら、 できない。
exec_commandが、コネクション開いて、メッセージ送信して、その結果をもらって、コネクションを閉じる。
という一連の作業をやってコネクション閉じちゃうからなんですよねぇ

コネクション開いてそのコネクション自体をもらう
invoke_shell()
というのが用意されていますが、これを使うと……

shell = client.invoke_shell()
shell.recv(1000)
shell.send('enable\n')
output=''
while True:
    output = output + shell.recv(1000).decode('utf-8')
    if(re.search('[Pp]assword',output)):
        output=''
        break
shell.send(passwd_e+'\n')
while True:
    output = output + shell.recv(1000).decode('utf-8')
    if(re.search('#',output)):
        output=''
        break
shell.send('term len 0\n')
while True:
    output = output + shell.recv(1000).decode('utf-8')
    if(re.search('#',output)):
        output=''
        break
shell.send('show start\n')
while True:
    output = output + shell.recv(1000).decode('utf-8')
    if(re.search('\nend',output)):
        print(output)
        output=''
        break

こういう、データ自分で待ち受けたりとかする作業が必要に。

これならParamikoあきらめてPexpectとかPexpectのpxssh使いたくなりますね。

もともとopensshクライアントではないものを使ってみたくて(速度とかどうなんだろう?と思って) Paramiko使ってるのになぁ

何かいい感じの方法ないんですかねえ

GNS3 VM を proxy環境でupgrade

/etc/apt/apt.conf に proxy設定をする

Acquire::http::proxy "http://proxy.example.com:8080";
Acquire::https::proxy "http://user:password@proxy.example.com:8080";
Acquire::ftp::proxy "http://proxy.example.com:8080";

普通に環境変数

export http_proxy="http://proxy.example.com:8080"

等とやっても利用されない。

またこれだけだと失敗するので 上記状態でUbuntuのアップデートが終わったら Ctrl+Cなどでいったんshellに戻って

sudo pip3 install --proxy=http://proxy.example.com:8080 --pre --ignore-installed gns3-server

とやってインストールする必要がある。 その後、再起動すればバージョンアップされているのが確認できる。

Let's Encrypt を Windows Apacheで使ってみる。

無償で利用できるSSL証明書発行サービス Let's Encryptがpublic betaになったので試してみます。

なお、作業はWebサーバ上で行いましょう。

Windows用クライアントはletsencrypt-win-simple というのをgithubで公開されてる方がいますのでこれを利用しましょう。

IISなら何も考えずにいけるっぽいですが(IIS使ってないので知りません)。

何はともあれ、ダウンロードして解凍します。 別途.NetFramework4.0以上が必要なのでまだインストールしてなければインストールしておきましょう。

解凍して出てきたletsencrypt.exeを実行します。

Enter an email address (not public, used for renewal fail notices):

最初にこんな感じでE-mailを聞かれるのでちゃんと受け取れるメールアドレスを入力しましょう。

その後、

Do you agree to https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf? (Y/N)

利用規約に同意しますか?と聞かれますので、読んで問題なければYと入力し、同意しましょう。

Scanning IIS 7 Site Bindings for Hosts
 IIS Version not found in windows registry. Skipping scan.
No targets found.

 M: Generate a certificate manually.
 A: Get certificates for all hosts
 Q: Quit
Which host do you want to get a certificate for:

あとはIISがないとこんな感じで、 手動で生成しますか?みたいなことを聞かれますので Mを入力して手動で証明書の生成を行うようにしましょう。

Enter a host name:

ドメイン名を入力して。

Enter a site path (the web root of the host for http authentication):

apacheの設定ファイルに記載されている DocumentRootを記載します。

すると、認証用のファイルがDocumentRoot以下に設置されて、向こうからそこにアクセスが来て、アクセスができれば 認証されて秘密鍵、公開鍵証明書、中間CA証明書が
c:\Users\user名\AppData\Roaming\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org\
以下に現れます。
ドメイン名-key.pem
ドメイン名-crt.pem
ca-XXXXXXX.pem
あとはこれをapacheSSL設定に

SSLCertificateFile "path-to ドメイン名-crt.pem"
SSLCertificateKeyFile "path-to ドメイン名-key.pem"
SSLCertificateChainFile "path-to ca-XXXXXXX.pem"

とやってあげれば大丈夫です。 apacheを再起動してアクセスしてみましょう。