それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

mydns 関連のドメインが 1.1.1.1 のpublic dns から引けない問題(DNSフィルタリング・規制か?)

twitter を見ていると、MyDNSが引けないというツイートを見かけた。

引いてみた。

takuya@untitled1$ dig aaaaaa.mydns.jp @1.1.1.1

; <<>> DiG 9.10.6 <<>> mydns.jp @1.1.1.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 25043
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1452
;; QUESTION SECTION:
;mydns.jp.          IN  A

;; Query time: 2209 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Mon Jul 01 16:00:36 JST 2019
;; MSG SIZE  rcvd: 37

ちゃんと引ける。ほかのところからも引ける。

takuya@untitled1$ dig +short xyz.mydns.jp   @dns-a.bbtec.net
163.44.151.xxx
takuya@untitled1$ dig +short xyz.mydns.jp   @8.8.8.8
168.235.75.xxx
takuya@untitled1$ dig +short xyz.mydns.jp   @1.0.0.1
takuya@untitled1$ dig +short xyz.mydns.jp   @1.1.1.1

Cloudflare から引けない問題。。。

これはDNSフィルタリングなんだろうか。public DNS がフィルタリングを始めたとなると本当に怖い世の中になったと思う。

追記:あとで確認したらTRACEはできる。

1.1.1.1 にたいして、何度かdig +trace を投げつけておくと、キャッシュされるみたい。+trace 後は通常通りDNSレコードを応答してくれる

takuya@untitled1$ dig +short a.mydns.jp   @1.1.1.1
takuya@untitled1$ for i in {1..10}; do echo $i; dig a.mydns.jp   @1.1.1.1 +trace > /dev/null  ;sleep 0.1  ; done
1
2
3
4
5
6
7
8
9
10
takuya@untitled1$ dig +short a.mydns.jp   @1.1.1.1
168.235.75.38
210.197.74.203
46.19.34.8
107.191.99.190
163.44.151.204
takuya@untitled1$

不思議で仕方ないので少し考えてみた。

ここから考えると、Cloudflare自体のDNSに問題はなく、mydns側の ns レコード(ns[0-2].mydns.jp)の設定に難があってCloudflareがうまくDNSをたどってないのではないか

そう考えると、ns レコードを引けていないので、たぶんmydns 側とcloudflareが使ってる再帰サーバーがうまく引けないのかもしれない。

takuya@untitled1$ dig mydns.jp    ns  @8.8.8.8 +short
ns1.mydns.jp.
ns2.mydns.jp.
ns0.mydns.jp.
takuya@untitled1$ dig mydns.jp    ns  @1.1.1.1 +short
takuya@untitled1$

いずれにせよ、特定のDNSサーバーを参照すると、DNSによる名前解決が止まってしまうのは困った問題だと思う(止められているならもっと怖い。)

openwrt で /etc/resolv.conf の dns サーバーを常に固定する

openwt で dns サーバーを指定する

OpenWRTでDNSサーバをあれこれいじってたので、メモ。

ルータのDNSサーバーを指定するには /etc/resolv.conf ( 実態は /tmp/resolv.conf ) にあります。

これは起動すると、自動的に生成されるresolv.confファイルで、PPPoEやDHCPv6などネットワーク接続後に更新されるファイルでもあります。

固定したい

openwrt がどのDNSサーバーから名前解決するかを固定したい

たとえば、nameserver をつねにlocalhost の unbound に固定したいとかある。

root@openwrt:~# nslookup  t.co
Server:     127.0.0.1
Address:    127.0.0.1#53

Name:      t.co
Address 1: 104.244.42.197
Address 2: 104.244.42.5
Address 3: 104.244.42.69
Address 4: 104.244.42.133

ネットワーク設定からやる

cloudflare の 1.1.1.1 をつねに自身の名前解決につかうには、LANネットワーク設定から行う

uci network.mylan.dns=' 1.1.1.1 8.8.8.8 8.8.4.4'

設定を書いて適用後

これを書いておくと、次のようにDNSの名前解決順序が適用される。

root@tplinkc7v5:~# cat /etc/resolv.conf
# Interface lan
nameserver 1.1.1.1
nameserver 8.8.8.8
nameserver 8.8.4.4
# Interface wan6
nameserver 2001:xxxx:8383:xxxxx:a5xx
search flets-xxxx.jp
search iptvf.jp
# Interface PPPoE-ISP
nameserver ISPのDNS1
nameserver ISPのDNS1

DNS の項目はいくつもあるので注意

OpenWRTルータ設定のDNS設定項目はいくつもあるので注意が必要

  • PPPoE / LAN ごとのDNS設定 ( uci show network.lan.dns )
  • ルータ自身のDNS設定( /etc/resolv.conf ← LAN設定に依存)
  • DNSMasq が問い合わせる先の設定 ( uci show dhcp.@dnsmasq[0].server
  • DNSMasq はDHCPと一体化している
  • DHCP サーバがIP配布時に通知するDNSサーバー設定 ( uci show dhcp.lan.dhcp_option//='6,192.168.11.1' )

今回使ったOpenWRT

root@openwrt:~# cat /etc/openwrt_release | grep RELEASE
DISTRIB_RELEASE='18.06.2'

参考資料

https://turedure-plog.blogspot.com/2014/10/openwrtgoogledns.html

unboundでrootから引くdnsサーバを作り、DNSフィルタリングに備える

この記事は試験的なものです。

ちゃんと動作するか現在、調査検討中です。

public DNSDNSブロッキングされる可能性がある。

public DNS 1.1.1.1/ 8.8.8.8 は多くの人が使っていて、とても公共性が高いのですが。多くの人が使うがゆえにフィルタリングされ自由を失う懸念が拭えない。

IIJの例

IIJ Public DNSサービス

DNSフィルタリング・ブロッキングについて 本サービスでは、インターネットコンテンツセーフティ協会(ICSA)が定める基準に則り、児童ポルノ対策のためのDNSブロッキングを実施しています。 なお、IIJが2019年7月より順次導入予定の「マルウェア対策のためのDNSフィルタリング」は実施いたしません。

DNS の名前解決がロギングされる。

どのドメインのIPを調べたのかの名前解決が残されます。DNSのフィルタリングとロギングはDNSサーバへの問い合せを記録し、その内容を保存調査分析します。ということはログ収集機構が組み込まれている。

DNSブロッキングは、オプトアウトしない限りログは収集される。またオプトアウトしても懸念は残る。 分析はしないと言ってるが、ロギング をしない とはどこにも書いていないので、ロギングされているのであろう。また「オプトアウトした」という情報が漏れる懸念がある。つまり私達がどのサイトをみたのかドメイン名で丸わかりになってしまう。そして、ISPはこれらの個人情報をいつもどおり任意で警察に提供する懸念がある。警察の任意取得が問題視されてから任意をやめるというTポイントのパターンを悪用される懸念がある。

IIJの例

IIJのセキュリティに関する取り組み | インターネットイニシアティブ(IIJ)

分析はしないとはいってるけど、蒐集しないとは言ってない。

自前でDNS をrootなserver から引いてくれるDNS問い合わせサーバを作りたい。

これらを踏まえると、ISPへのDNSサーバーへの問い合わせの記録は漏れるものです。プライバシーは保護されるか全く見通したが立たない。そこでDNSの問い合わせは、root サーバから自分で引いてくる必要がある。DNS用意しても、ISPや/1.1.1.1/8.8.8.8にフォワードしたらプライバシーが丸見えで意味がない。

DNSの問い合わせ用のサーバを作って運用してみようと思い立った。要は、オレオレpublicDNS です。

自分自身で、root からDNSを引っ張ってくるサーバを持っていれば、ISPgoogle(8.8.8.8)にどのサーバに問い合わせたかのプライバシー情報が漏れ無いと考えた。

今回のポイント forwardしない。

よくあるdnsサーバーのインストール記事だと 8.8.8.8へforward するだけです。

今回は、ISPやpublicDNSへ フォワードせず に自力で名前解決を試みます。

今回使ったもの - unbound

debian / unbound で構築してみました。

インストール

unbound のインストール。とにかくこいつがないと始まらない。

sudo apt install unbound 

あと、必要に応じて dns の問い合わせを確認するコマンドを入れておく

## drill コマンドのインストール
sudo apt install ldns-utils
## dig コマンドのインストール
sudo apt install dns-utils
## unbound-hosts コマンドのインストール
sudo apt install unbound-hosts

これらのコマンドは必要に応じてdnsの問い合わせを確認するのに使います。

私はDebianで実験しています。ubuntu の場合はdns-utilsではなくdnsutilsです。

基本設定

/etc/unbound にある設定を変えていきます。

debianの場合は次のようなディレクトリ構造になっていました。

takuya@:unbound$ tree .
.
├── unbound.conf
├── unbound.conf.d
│   ├── qname-minimisation.conf
│   └── root-auto-trust-anchor-file.conf
├── unbound_control.key
├── unbound_control.pem
├── unbound_server.key
└── unbound_server.pem

/etc/unbound/unbound.conf.d/qname-minimisation.conf

Serverの項目を変えていきます。

ここでは、指定したネットワークアドレス範囲からの問い合わせを許可。 また、unbound がListenするIPアドレスを指定した

server:

    #qname-minimisation: yes
    #
    access-control: 192.168.0.0/16 allow
    interface: 192.168.11.1
    root-hints: root.hints

root-hints は次で準備します。

root.hints を用意、root から問い合わせしてたどるようにする

root-hints ファイルを入れると、root の nameserver '.' からたどるようになります。

curl --output /etc/unbound/root.hints https://www.internic.net/domain/named.cache

root.hints ファイルの中身は、ROOT-SERVERSのIPアドレスです。 半年に一度くらいは更新するようにするといいらしいです。。

設定したら再起動とと動作確認

systemctl restart unbound で再起動

unbound-hosts で動作テスト。

unbound-host を使って動作テストをしてみます。

takuya@:unbound$ unbound-host -4 -d pbs.twimg.com

動作テスト dig

dig @192.168.11.1 twitter.com

これで、unbound のサーバーになります。

dig +trace できるようにする。

このままでは、IPの応答はできるけど、なにかしらトラブルのときに問い合わせを +trace できないので、 dig クライアントが trace コマンドを使えるようにします。

#    access-control: 192.168.0.0/16 allow 
access-control: 192.168.0.0/16 allow_snoop

traceするときは、クライアントが再起問い合わせをするので、サーバーが再起問い合わせをする必要がないですよね。 なので、クライアントが非再起問い合わせをしてくるので、それを許可するわけです。

+trace してみる

snoop をオンにすると dig +traceができるようになります。やったね。

dig +trace   pbs.twimg.com @192.168.11.1

; <<>> DiG 9.10.3-P4-Debian <<>> +trace pbs.twimg.com @192.168.11.1
;; global options: +cmd
.           448024  IN  NS  d.root-servers.net.
.           448
(中略
pbs.twimg.com.      300 IN  CNAME   cs196.wac.edgecastcdn.net.
;; Received 81 bytes from 204.13.251.34#53(ns4.p34.dynect.net) in 15 ms

unbound-anchor は自動的に更新される

systemctl restart unbound で再起動したら、 root.key のアンカーは自動的に更新されるようですね。

takuya@:unbound$ sudo systemctl restart unbound
takuya@:unbound$ cat "/var/lib/unbound/root.key"
; autotrust trust anchor file
;;id: . 1
;;last_queried: 1561371009 ;;Mon Jun 24 19:10:09 2019
;;last_success: 1561371009 ;;Mon Jun 24 19:10:09 2019
;;next_probe_time: 1561411721 ;;Tue Jun 25 06:28:41 2019
;;query_failed: 0

今回試したこと

unbound と root.hints を使って、カジュアルに呼ぶならオレオレpublic dns 的なものを作った。正しくは再起問い合わせのリゾルバ。

DNSブロッキングに備える。

DNSブロッキングDNSのロギングは、いつどこで誰に提供されるか全くわからない。そのため自分でDNS再起問い合わせをできるようにして自衛に努める必要がある。

追記 可能であれば、iptablesISPDNSやpublicDNSを止める

疎通確認をどうするか。可能であれば設定後にUnbound以外のDNSiptables でフィルタリングしてしまうのが良いと思う。

たとえば、yahoo bb のDNSサーバーとの通信を停止してDNS名前解決がソフトバンクに流れないようにする。

Chain zone_wan_output (1 references)
target     prot opt source               destination
output_wan_rule  all  --  anywhere             anywhere           
zone_wan_dest_REJECT  tcp  --  anywhere             dns-b.bbtec.net      tcp dpt:domain 
zone_wan_dest_REJECT  udp  --  anywhere             dns-b.bbtec.net      udp dpt:domain 
zone_wan_dest_REJECT  tcp  --  anywhere             dns-a.bbtec.net      tcp dpt:domain 
zone_wan_dest_REJECT  udp  --  anywhere             dns-a.bbtec.net      udp dpt:domain 
zone_wan_dest_ACCEPT  all  --  anywhere             anywhere             

追記: 簡単なパフォーマンス測定

cloudflare の 1.1.1.1 と google の 8.8.8.8 と、今回のunbound、そして dnsmasq で 1.1.1.1 にフォワードする ルーターで、簡単に応答時間を比べてみました。

takuya@:unbound$ for dns in 1.1.1.1 8.8.8.8 192.168.11.1 192.168.12,1; do  echo $dns ; time for i in {1..100}; do dig  +short @$dns t.co > /dev/null ; done ; done
1.1.1.1

real    0m2.012s
user    0m0.852s
sys 0m0.268s

8.8.8.8

real    0m1.851s
user    0m0.756s
sys 0m0.276s

192.168.11.1

real    0m0.845s
user    0m0.444s
sys 0m0.120s

192.168.12.1

real    0m0.587s
user    0m0.332s
sys 0m0.092s

なんか、public dns よりローカルのほうが速くね?

追記 DNSSEC の動作テスト

とくになにも設定してないけど、デフォルトで有効になってました。

takuya@:unbound$ dig +cd +short  @192.168.2.5 dnssec-failed.org
69.252.80.75
takuya@:unbound$ dig +short  @192.168.2.5 dnssec-failed.org
takuya@:unbound$ dig +dnssec +short  @192.168.2.5 dnssec-failed.org

参考資料

gitbookのビルドだけをgulpでフォルダ監視して自動実行したい

gitbook-cli でサーバーがいちいち上がるのがめんどくさい。

gitbook を使い込む気は、あまりないのだけど、マークダウンを記述して、gitbook serve で 変換が必要

gulp で監視してしまいたい。

HTMLに変換するだけなら、べつにserve は要らないし、そこまでリアルタイムな編集も要らないんだよね。

gitbook watch がほしいとおもったけど見つからないので、 しかし、gitbook-cli は開発終わってる。

仕方ないので、gitbook watch 代わりにgulp watch を作ってみた。

gitbook はWEBサービスになっちゃったんだけど、なんか残念だよね。

gitbook-cli のビルド部分だけを gulp 化したもの

var gulp = require("gulp");


gulp.task('watch', function(done){

  gulp.watch(['**/*.md'], gulp.task('book'));

});


gulp.task('book', function( done ){
  // ./node_modules/.bin/gitbook から抜粋
  var parsedArgv = require('optimist').argv;
  var color = require('bash-color');
  var manager = require('./node_modules/gitbook-cli/lib');
  var commands = require('./node_modules/gitbook-cli/lib/commands');
  var program = require('commander');
  var bookRoot = parsedArgv._[1] || process.cwd();

  function runPromise(p) {
    return p
      .then(function() {
        process.exit(0);
      }, function(err) {
        console.log('');
        console.log(color.red(err.toString()));
        if (program.debug || process.env.DEBUG) console.log(err.stack || '');
        process.exit(1);
      });
  }
  return manager.ensureAndLoad(bookRoot,program.gitbook)
    .then(function ( gitbook ) {
      return commands.exec(gitbook.commands, 'build', [], [])
    });
});

ハードウェアの情報を一覧する lshw コマンド

ハードウェアの情報を収集して出力する

lsusb や lspci などのコマンドがあるけど、まとめて実行して情報を取り出すには不便。調べたら lshw といういうコマンドを見つけた

インストール

takuya@:~$ sudo apt search lshw
ソート中... 完了
全文検索... 完了
lshw/stable 02.18-0.1 amd64
  ハードウェア設定に関する情報

lshw-gtk/stable 02.18-0.1 amd64
  ハードウェア構成に関する情報をグラフィカルに表示

python3-checkbox-support/stable 0.22-1 all
  collection of Python modules used by PlainBox providers

takuya@:~$ sudo apt instal  lshw

使い方

sudo をつけてコマンドを実行すると良い。 htmlやXMLで取得することも可能だ。

takuya@:~$ sudo lshw -h
Hardware Lister (lshw) - unknown
usage: lshw [-format] [-options ...]
       lshw -version

    -version        print program version (unknown)

format can be
    -html           output hardware tree as HTML
    -xml            output hardware tree as XML
    -short          output hardware paths
    -businfo        output bus information

options can be
    -class CLASS    only show a certain class of hardware
    -C CLASS        same as '-class CLASS'
    -c CLASS        same as '-class CLASS'
    -disable TEST   disable a test (like pci, isapnp, cpuid, etc. )
    -enable TEST    enable a test (like pci, isapnp, cpuid, etc. )
    -quiet          don't display status
    -sanitize       sanitize output (remove sensitive information like serial numbers, etc.)
    -numeric        output numeric IDs (for PCI, USB, etc.)
    -notime         exclude volatile attributes (timestamps) from output

実行例

そのまま実行すると出力が大きすぎなので、ターミナルで実行するときは -short オプションがおすすめ

takuya@:~$ sudo lshw  -short
H/W path         デバイス     クラス      詳細
=======================================================
                                  system         To Be Filled By O.E.M. (To Be Filled By O.E.M.)
/0                                bus            J5005-ITX
/0/0                              memory         64KiB BIOS
/0/b                              memory         8GiB システムメモリー
/0/b/0                            memory         8GiB SODIMM DDR4 同期 2400 MHz (0.4 ns)
/0/b/1                            memory         DIMM DDR2 同期 [空]
/0/15                             memory         224KiB L1 キャッシュ
/0/16                             memory         4MiB L2 キャッシュ
/0/17                             processor      Intel(R) Pentium(R) Silver J5005 CPU @ 1.50GHz
/0/100                            bridge         Intel Corporation
/0/100/0.1                        generic        Intel Corporation
/0/100/2                          display        Intel Corporation
/0/100/e                          multimedia     Intel Corporation
/0/100/f                          communication  Intel Corporation
/0/100/12                         storage        Intel Corporation
/0/100/13                         bridge         Intel Corporation
/0/100/13.1                       bridge         Intel Corporation
/0/100/13.2                       bridge         Intel Corporation
/0/100/13.2/0    enp3s0           network        RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
/0/100/13.3                       bridge         Intel Corporation
/0/100/13.3/0                     storage        ASM1062 Serial ATA Controller
/0/100/15                         bus            Intel Corporation
/0/100/15/0      usb1             bus            xHCI Host Controller
/0/100/15/0/3                     generic        802.11n WLAN Adapter
/0/100/15/0/5                     communication  BT2.0
/0/100/15/0/6                     bus            NEC USB HUB (ASC)
/0/100/15/0/6/1                   input          109 JPN USB KBD (ASC)
/0/100/15/0/6/3                   input          wireless dongle
/0/100/15/1      usb2             bus            xHCI Host Controller
/0/100/1f                         bridge         Intel Corporation
/0/100/1f.1                       bus            Intel Corporation
/0/1             scsi0            storage        
/0/1/0.0.0       /dev/sda         disk           240GB ADATA SP550
/0/1/0.0.0/1     /dev/sda1        volume         511MiB Windows FAT ボリューム
/0/1/0.0.0/2     /dev/sda2        volume         732MiB EXT4ボリューム
/0/1/0.0.0/3     /dev/sda3        volume         48GiB EFI partition
/0/1/0.0.0/4     /dev/sda4        volume         174GiB EXT4ボリューム
/1               vlan2            network        イーサネット interface
/2               vlan10           network        イーサネット interface
/3               vlan200          network        イーサネット interface
/4               vlan30           network        イーサネット interface
/5               wlx000b8181dc8e  network        無線インターフェース
takuya@:~$ 

if 文には必ずブロックをつけろと言われることが多いけど、使い方によってはむしろ邪魔

if にブロックがないと叱られたことが昔から多い。

if のブロックって上手に書けばいいと思うし、設定やLintで矯正されたりするんだけどさ。

この if の書き方を見ほしい

function setupAce(e, set){
  
  //デフォルト設定(カスタマイズしたい場合はの引数(set)に以下の様にセットして下さい。)
  if(!set) set = {
    theme:"chrome",  
    mode:"text",    
    options:{        //AceEditorOption設定類
      fontSize: "12px",
      maxLines: 30,
      minLines: 5,
      showInvisibles: true,
    },
    focus:false
  };

一見するとブロックがあるように見えるけど、ブロックは使ってなくて、初期化変数。

なかなかおもしろいよね。工夫次第でシンプルにわかりやすく記述はできるんだなと

laravel の api ルートを叩いてもloginページやHTMLが帰ってきてjson以外になってしまう場合

TL;DR

HTTPリクエストのヘッダに、 Accept: text/json が抜けている可能性が高い。

Laravelのレスポンスが login になる場合。

api で auth を入れているところへリクエスト投げつける。

HTMLのログインが帰ってくる。

実例

curl -H 'Content-Type: application/json' -F file='@/Users/takuya/Pictures/Dh6PcyQUYAEzhKp.jpg' http://127.0.0.1:8000/api/user/1/images/ 

* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> POST /api/user/1/images/ HTTP/1.1
> Host: 127.0.0.1:8000
> Accept: */*
> Accept-Encoding: gzip, deflate, sdch
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36
> X-Config-File: ~/.curlrc
> Content-Length: 37112
> Content-Type: application/json; boundary=------------------------f7fa3a50954906f3
> Expect: 100-continue
>
* Done waiting for 100-continue
  0 37112    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0} [37112 bytes data]
* We are completely uploaded and fine
< HTTP/1.1 302 Found
< Host: 127.0.0.1:8000
< Date: Tue, 28 May 2019 14:57:15 +0000
< Connection: close
< X-Powered-By: PHP/7.3.4
< Cache-Control: no-cache, private
< Date: Tue, 28 May 2019 14:57:15 GMT
< Location: http://127.0.0.1:8000/login
< X-RateLimit-Limit: 60
< X-RateLimit-Remaining: 59
< Content-Type: text/html; charset=UTF-8
<
{ [352 bytes data]
100 37464    0   352  100 37112    272  28724  0:00:01  0:00:01 --:--:-- 28996
* Closing connection 0
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url=http://127.0.0.1:8000/login" />

        <title>Redirecting to http://127.0.0.1:8000/login</title>
    </head>
    <body>
        Redirecting to <a href="http://127.0.0.1:8000/login">http://127.0.0.1:8000/login</a>.

同一ページに Accept-JSONを併せて送りつけた場合。

HTTPのヘッダにAcceptを入れると、401 がとJSONが返ってくる。

takuya@$ curl-json -H 'Content-Type: application/json' -F file='@/Users/takuya/Pictures/Dh6PcyQUYAEzhKp.jpg' http://127.0.0.1:8000/api/user/1/images/ 

> POST /api/user/1/images/ HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.65.0-DEV
> Accept: text/json
> X-Config-File: ~/.curlrc-json
> Content-Length: 37112
> Content-Type: text/json; boundary=------------------------4610ff915435cd7f
> Expect: 100-continue
>
* Done waiting for 100-continue
} [37112 bytes data]
* We are completely uploaded and fine
< HTTP/1.1 401 Unauthorized
< Host: 127.0.0.1:8000
< Date: Tue, 28 May 2019 14:54:59 +0000
< Connection: close
< X-Powered-By: PHP/7.3.4
< Cache-Control: no-cache, private
< Date: Tue, 28 May 2019 14:54:59 GMT
< Content-Type: application/json
< X-RateLimit-Limit: 60
< X-RateLimit-Remaining: 58
<
{ [30 bytes data]
* Closing connection 0
{"message":"Unauthenticated."}

laravel のAPIにリクエストを送付するときは

リクエストヘッダのAccept(クライアントが受け取りたいMIME形式の指定)でJSONを指定する必要がある。

Accept: text/json

これは、どこで定義されているのか

Accept をみてMIMEや認証は、どこのメソッドで定義されているのか。

vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithContentTypes.php#expectsJson
<?php
public function expectsJson()
    {
        return ($this->ajax() && ! $this->pjax() && $this->acceptsAnyContentType()) || $this->wantsJson();
    }

ここでリクエストのヘッダを見ている。HTTP/Requestで使える。

参考資料

https://github.com/laravel/framework/blob/5.8//src/Illuminate/Http/Concerns/InteractsWithContentTypes.php#L42

composer でgithub / gitlab などのgit レポジトリをコマンドから指定してインストール

php/composer でコマンドから git レポジトリをインストールしたい。

composer で git のレポジトリ(非公式 package / 自作pkg )を指定して追加して使いたい。

通常は composer.json を編集するのだろうけど、 jsonの手作業の編集は、苦痛。

なので、コマンドから指定して実行したら楽になる。

手順

  • composer.json に config を追加
  • composer install

composer.jsonに git(vcs)を追加する。

composer config コマンドを使って、git でアクセス可能なレポジトリを追加します。

composer  config repositories.my-helpers vcs ssh://git@example.com/takuya/my-helpers.git

これで、json ファイルができた。

composer install します。

vcs を参照するようになったら、require に登録してインストールします。

composer require --dev  takuya/my-helpers:master
composer install

レポジトリ名はURLから github.com/takuya/my-repos のような構造からパスを取り出して、ブランチを指定する。

これでミスなく手軽になる。composer で自作の非公開のパッケージを自動的に取り込む構成が作れるので、dockerイメージや docker-compose でインストールのスクリプトを作るときなどに本当に楽になる。

関連資料

http://takuya-1st.hatenablog.jp/entry/2014/07/09/114736

参考資料

https://stackoverflow.com/questions/31743139/how-to-add-non-public-repositories-from-command-line-with-composer

JS で String#replaceAll すべて置換をするには

JS のコードレビューをしていて、気になってしょうがない split.join

いっぱい次のような、関数をいっぱい見かけるのですが、これは replaceAll の代りにし使ってるんだろうか。一般的なんだろうか。 どっかのサイトで上位に出てくるんだろうか。○iita とか

## これはやめてほしい。
update_date.split('-').join('');

正規表現で意図が明確コードを

正規表現のグローバルマッチを使うと良い。

update_date.replace( /-/g , '' );

置換はコールバックが便利

置換するなら、コールバックをすることが便利。

update_date.replace( /-/g ,  function( e ){   return e+'--'   } );

sshfs でFUSEマウントしたフォルダへの転送速度を測定した

sshfs でFUSEマウントしてみました。

sshfs は gvfs などネットワークフォルダとしてSSHを扱えるものですね。

sudo apt install sshfs

マウント

mkdir mnt
sshfs takuya@192.168.11.125:/home/takuya mnt

転送してみました。

takuya@:Desktop$ dd if=test.img of=mnt/test.img 
2000000+0 レコード入力
2000000+0 レコード出力
1024000000 bytes (1.0 GB, 977 MiB) copied, 116.963 s, 8.8 MB/s

やっぱりFUSEは速度でないですね。CPU周りの問題なんでしょうか

それでも gvfs よりは速いです。

gvfs でssh FUSEマウントしたファイルシステムの書き込みが遅い

gvfs でマウントしつかってて、どうも遅い。

速度測定してみた

あまりに遅いので、1GBの転送は途中で諦めてしまった。

takuya@:Desktop$ dd if=test.img of=/run/user/1000/gvfs/sftp:host=192.168.11.125/home/takuya/test.img
^C97031+0 レコード入力
97031+0 レコード出力
49679872 bytes (50 MB, 47 MiB) copied, 126.678 s, 392 kB/s

10MBで試した結果がこちらです。

takuya@:takuya$ dd if=/dev/urandom  of=test.img bs=1k count=10000
10000+0 レコード入力
10000+0 レコード出力
10240000 bytes (10 MB, 9.8 MiB) copied, 12.7177 s, 805 kB/s

なんどか試してみましたが、sftp は 1MB/s で、afp/smb は 3MB/s が限界でした。FUSEなのでマウントしてるLinuxクライアント側のメモリ量やCPU速度にも影響を受けますが、めっっちゃ遅いですね。

ssh の転送速度を測定をしてみる

SSHの速度を測定しようと思い立った。

なんかネットワークが遅いので、SSHでの速度測定をしてみることに。

速度測定するコマンド

ファイルの準備

dd if=/dev/urandom  of=test.img bs=1k count=1000000

転送

cat test.img  | ssh host.tld 'dd of=/dev/null '

ssh でパイプする

ssh でパイプするとファイル転送ができる。

cat test.img | ssh host ' cat - > test.img'

dd は of だけ指定すると標準入力

dd は if / of で指定するけど、標準入力からもととれる。

実際にやってみた例

takuya@:Desktop$ dd if=/dev/urandom  of=test.img bs=1k count=1000000
1000000+0 レコード入力
1000000+0 レコード出力
1024000000 bytes (1.0 GB, 977 MiB) copied, 39.8002 s, 25.7 MB/s
takuya@:Desktop$ cat test.img  | ssh myhost 'dd of=/dev/null '
sign_and_send_pubkey: signing failed: agent refused operation
2000000+0 レコード入力
2000000+0 レコード出力
1024000000 bytes (1.0 GB, 977 MiB) copied, 9.16781 s, 112 MB/s

ファイル書き込みがボトルネックになっていないか

先程の例は、純粋にネットワーク速度に近いものが出ているはず。ファイルに書き込んでみたいと思う

この場合は、ファイルIOがメモリキャッシュされないように結構な量を書き込む必要がある。たぶん3GBくらい

SSD 相手に書き込んだとき

takuya@:Desktop$ cat test.img  test.img test.img | ssh host.tld ' dd of=test.img'
sign_and_send_pubkey: signing failed: agent refused operation
6000000+0 レコード入力
6000000+0 レコード出力
3072000000 bytes (3.1 GB, 2.9 GiB) copied, 30.6751 s, 100 MB/s

HDDを相手に書き込んだとき

takuya@:Desktop$ cat test.img test.img test.img  | ssh host.tld ' dd of=./mount/96.作業用/test.img'
sign_and_send_pubkey: signing failed: agent refused operation
6000000+0 レコード入力
6000000+0 レコード出力
3072000000 bytes (3.1 GB, 2.9 GiB) copied, 35.9622 s, 85.4 MB/s

メモリキャッシュがきいてる気もする。が、まぁ実際に使ってる速度に近い測定結果ナノではないでしょうか。

あくまで概算

ssh は圧縮されたりするので、本当のネットワークの速度よりも若干高くなる。 /dev/urandom を使うことで圧縮されないようにはしてるけど。

我が家の環境では 111 MB/s でているようである。

ところが、Samba経由したり WebDAV 経由すると 3MB/s くらいしかでない。こまった。

curl でもできる

curl を使ってもできる

これはSFTPで速度測定になる。

takuya@:~$ curl sftp://192.168.11.125/home/takuya/test.img > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 2929M  100 2929M    0     0  42.3M      0  0:01:09  0:01:09 --:--:-- 44.0M
100 2929M  100 2929M    0     0  42.3M      0  0:01:09  0:01:09 --:--:-- 42.3M

/dev/urandom の速度

ちなみに、/dev/uramdom でdd したときの速度が 25MB/s 程度のCPUで測定しました

gvfs あたらめ gio でログインしたときだけネットワークのドライブをマウントする

Ubuntu のGVSマウントをログイン時にしたい。

ubuntu デスクトップのログイン時のマウント機能と同等のマウントしたい

fstab や autofs でもできるが、そっちはシステム全体なのでわかりやす。gvfs は面倒かと思ったけど、使ってみたらgvfs が圧倒的に楽だったのでメモ。

管理の側面から考えると、ログイン時にマウントされる方が嬉しいし。そもそもmount でマウントポイントが見れないのでいいかな

これを使うメリット

ネットワークの越しのマウントに、root 権限も、マウントポイントも要らないので、mountコマンド初心者でも使いやすい。

gvfs とは

最近は gio という名前になっているようです。

いろいろな、ネットワークのドライブをFUSEでマウントしてくれたりする。Ubuntuだと次の「アカウントの追加」で追加設定したストレージに使われている。

f:id:takuya_1st:20190520162638p:plain:w200

実際にマウントされたら次のようになる。左の柱に出てくるネットワークの場所ですね。

f:id:takuya_1st:20190520162721p:plain:w200

gvfs はマウントポイントがわかりにくい

gvfs でマウントされている

gvfs-mount -l

これは、mountで出てくる。けど分かりにくいかもしれません。

takuya@:~$ mount | grep gvfs
gvfsd-fuse on /run/user/1000/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
takuya@:~$ 

ちなみに、gvs-mount はいまは gio を使う

gio moout -l 

gio/gvfs でネットワークをマウントしてみる。

gio mount "cifs://takuya@my-nas/takuya's%20home/"

他にも、SSHフォルダをSFTPでマウントするには。

gio mount "ssh://takuya@my-sftp-server/"

などと、URLでプロトコルを指定してマウントしFUSEとして使えるのでめっちゃ便利。あれ、もうローカルにストレージが要らなくね?

など手軽にマウントできるじゃん。

GUI ツールで管理できる。

gigoloという管理ツールがありました。

sudo apt install gigolo

f:id:takuya_1st:20190520163613p:plain

gigoloGUIで管理できる。いいじゃん gigolo

これ使えば、システム全体に関係なくマウントできるから、ルート権限もいらないしめっちゃ楽じゃん

f:id:takuya_1st:20190520163626p:plain

ログイン時に自動的に接続したい

touch ~/MountAtLogin.sh
chmod +x  ~/MountAtLogin.sh

ファイルの中身を書く

## ~/MountAtLogin.sh
gio mount ssh:takuya@my-server/

最後に

Ubuntu自動起動するアプリケーション に登録して終了

これで、ログイン時に再接続されるのでWindowsのネットワーク・ドライブのような運用ができる。便利。

2019-05-24 追記

手軽だけど、どうも速度が遅く、HDMIキャプチャの録画ファイルの保存に失敗しているようである。そこで速度測定してみました

どうも、gvfs でマウントしたドライブはFUSEの呼び出しループの中で、CPU処理に影響を多分に受けていると思われる。

あまり多量のファイルを扱うのは得策でないと思う。

参考資料

wordpress をniginx のリバースプロキシの背後に設置した場合の mixed contents 対策

nginx の背後に wordpress を設置したら mixed content

wordpress を設置したんだけど、 .htaccess も使いたいと言われて、nginx から apache+php-fpm にリバースプロキシをした。するとhttp/https混在コンテンツになってしまった。

対策。

nginx → apache で リバースプロキシするさい X-Forwarded-Proto を追加する。

nginx 側

     proxy_set_header X-Forwarded-Proto https;

nginx などリバースプロキシでhttpsだとメモを残してヘッダにつけて送る(今回は HTTP_X_FORWARDED_PROTO  を使う)

wordpress 側 wp-config.php

<php
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'){
  $_SERVER['HTTPS']='on';
  }

HTTP_X_FORWARDED_PROTOをphp 側で受け取って HTTPS 変数を上書きする。

その他の対策方法

  • nginx → apache2 のリバースプロキシをオレオレ証明書https でやるとか。
  • apache2→ php-fpm で構成して apache2 から https だよと宣言するとか

まぁいろいろと考えられるけど、一番手っ取り早いのは wp-config.php を弄ることだった。

これは、CloudflareやAWS ELB などでHTTPSをONにした場合にも同じことが言える。

chrome の開発ツールのConsoleの履歴を消す。

Chrome の devtool の履歴を消す方法。

ChromeのJSコンソールに、パスワードとか直書きで書いてしまったときに。

パソコン本体にロックが掛かるようにしておけば全く問題ないのだけれど、画面共有中にうっかり誰かに見られても困るだろうし。

履歴を消すには、右クリック

f:id:takuya_1st:20190516201309p:plain
me

昔は、もっとめんどくさかったのに。簡単になってるのでメモ