人とはちょっと違うことをやるのがすごく好き。

仕事(主にインフラ系のエンジニア)と家族(主にトイプードル)と趣味(主にバドミントン)について感じたことや、勉強したことなどを自分のメモ&誰かの参考になるかもしれないと思って書きます。

LINEに送信済みメッセージ取り消し機能実装の予定

japanese.engadget.com

「コーディング不要で簡単にウェブアプリが作れるビジュアルプログラミングツール「Bubble」」がすごい!!

gigazine.net

 

Ideaはあるけどスキルが不足している人にとってはいいんじゃないでしょうか。

ITエンジニア的なステッカー

中国のXiaomi社が販売しているMacbook Likeな「Mi Notebook Air」の12.5インチ版を買いました。

外見は「りんごマークのないMacbook」です。

このままでもSimple and coolではあるのですが、せっかくなのでよくいる「WEBサービスやアプリケーションのステッカーをベタベタ貼ってる奴」をやってみようと思い、ステッカーの入手方法を調べました。

国内ではあまりなくて、企業が開催するイベントなどの配布ぐらいしか入手するチャンスがなさそうです。

で、国外のWEB通販だといろいろ手に入るみたいなので買ってみました。

 

まずは「unixstickers」。

まんまの名前ですね。

www.unixstickers.com

 10日ぐらいで届きます。

追跡番号もあります。

 

次は「redbubble」

www.redbubble.com

10日~14日で届きます。

追跡番号もあります。

種類はここが一番豊富だと思います。

 

あとは「GitHub Shop」。

Tシャツとかフーディー(パーカー)なんかもあります。

github.myshopify.com

10日ぐらいで届きました。

追跡番号もあります。

 

「ステッカー・ミュール」

www.stickermule.com

10日ぐらいで届きました。

追跡番号もあります。

 

最後は「Elasticsearch Shop」

自社サービスのElasticsearchやkibanaなどのステッカーを販売しています。

elastic.shop

ここが一番遅くて4~6週間かかるといわれました。

(10/19に発送した!って連絡もらってますが11/13現在まだ届いていません。遅すぎ。)

追跡番号らしきものをメールでもらえますが実はダミーで荷物は追えません。

 

 

 

Elastic shop以外はおおむね10日程度で届きます。

(ポストに勝手に入ってます)

 

同じようにIT系のステッカーを探している方のご参考になればと思います。

ちなみにステッカーを貼る基準は自分のスキルセットに合ったものに限定しています。

f:id:carlos-yossy:20171114225118j:plain

AWSのS3で特定の複数SourceIPからのみアクセスを許容するバケットポリシーの書き方

・ことの発端

CloudFrontを使った静的コンテンツの配信システムを設計しました。

よくある構成なので検証環境を作ることは悩むことなくできたのですが、ある問題に直面しました。

それは「https://~/Dir名/」でアクセスした際に、自動的にindex.htmlを取得してくれない問題です。

CloudFrontのRoot Objectに「index.html」を記載してもだめ。

S3のインデックスドキュメントに記載してもだめ。

どうやらRootディレクトリ(https://~/」でしか自動的に取得してくれない”仕様”だそうで。

それの解決策を探したところ、CloudFrontの「Origin Domein Name」を入力欄に自動で現れるものを選ばすに「http://バケット名.s3-website-ap-northeast-1.amazonaws.com」を手動で設定すれば解決するとのこと→確かに解決しました。

しかしながら、新たな問題としてこのままだとS3へのアクセスをCloudFrontだけに制限することができません。(パブリック公開になってしまう)

で、アクセス制限の問題に対しての対策として「CloudFrontが使用する可能性のあるIPアドレスだけを全て許容する」ことにしました。

CloudFront(というかAWSが)使用するIPアドレスは以下で確認できます。

https://ip-ranges.amazonaws.com/ip-ranges.json

 

これを元にバケットポリシーに対して43あるアドレスレンジをAllowするポリシーを書いて設定!・・・したところエラーにしかならない。

ほかにも同じようなことをやろうとしている人はいるはず、とGoogleで調べてたどり着いたこちらのサイトを参考にしました。

 S3 でIPアドレスアクセス制限をかける際のバケットポリシー | ハックノート

 

ほかのブログなどでは以下のようにSourceIPの部分をカンマで区切って複数行記載できるようなものがありますが、上記リンクの形式でないとエラーになります。(時期によって違うのかも)

 

【誤った記載例】

{
    "Version": "2012-10-17",
    "Id": "S3Policy#{unique_id}",
    "Statement": [
        {
    "Sid": "Stmt#{unique_id}",
    "Effect": "Deny",
    "Principal": {
    "AWS": "*"
        },
    "Action": "s3:*",
    "Resource": "arn:aws:s3:::バケット名/*",
    "Condition": {
        "NotIpAddress": {
            "aws:SourceIP": [
                "xxx.xxx.xxx.xxx/xx",
                "xxx.xxx.xxx.xxx" ★ここがだめでした。
                    ]
                }
            }
        }
    ]
}

 

 

で、同じようにS3への制限をCloudFrontのIPだけに絞りたくてここにたどり着いた方のためにポリシーを公開します。

バケット名など、固有情報だけ一括置き換えなどで流用できると思いますのでどうぞ。

 

 

【S3へのアクセスをCloudFrontだけに制限するポリシー】

{
"Version": "2012-10-17",
"Id": "*****************,
"Statement": [
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "13.32.0.0/15"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.46.0.0/18"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.84.0.0/15"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.222.128.0/17"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.182.0.0/16"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.192.0.0/16"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.230.0.0/16"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.239.128.0/18"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.239.192.0/19"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.240.128.0/18"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "204.246.164.0/22"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "204.246.168.0/22"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "204.246.174.0/23"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "204.246.176.0/20"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "205.251.192.0/19"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "205.251.249.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "205.251.250.0/23"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "205.251.252.0/23"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "205.251.254.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "216.137.32.0/19"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "13.54.63.128/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "13.59.250.0/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "13.113.203.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "13.124.199.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "13.228.69.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "34.195.252.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "34.226.14.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "34.232.163.208/29"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "35.158.136.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "35.162.63.192/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "35.167.191.128/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.15.127.128/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.47.139.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.52.191.128/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.56.127.0/25"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.57.254.0/24"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.66.194.128/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.78.247.128/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.199.127.192/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.212.248.0/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "52.220.191.0/26"
}
}
},
{
"Sid": "*****************",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "54.233.255.128/26"
}
}
}
]
}

Xiaomi mi notebook air 12.5を買いました

新しいPCほしいなーと思ってしまったので探してみました。

条件は

・軽い(できれば1kg以下)

・安い(数万程度)

・かっこいい(Macbook的な)

・そんなにスペックいらない(PythonでのプログラミングやDockerと使ったシステム構築ができればOK)

 

で、たどり着いたのが件名の機種。

Xiaomiは日本未進出の中国企業なので日本の量販店や通販では買えません。

なので中国企業のスマフォなんかのデバイスを買いたい場合によく使われている通販サイトのGearbestで注文しました。

8/30に購入。

翌日の8/31にはトラッキング番号をメールで送ってくれたけどいつまでたってもまったく更新されない。

で、なぜか9/12にまたトラッキング番号が届く(当然、違う番号)

結局、届くまで約三週間。

何度かGearbestにクレームめいた質問投げたけど大体の回答は「辛抱強く待て」だけ。

 

まぁ、届いたからいいけど。

で、届いてから中国版(中国語版ではない)のWindowsでアクティベートしてすぐにUSBメモリに用意しておいた日本語版のWindows10に再インストール。

それからVirtualBOXをいれてLinux環境作ろうかな、と思っていたらまさかの事態に。

 

そう、まさかのメモリ不足。

4GBしかないのでWindowsが起動しただけで3GB強を消費してしまい、その上でLinuxなんぞ使いようがない。。。

 

というわけでWindowsじゃないといけない理由もないので一旦はLinux Mintデュアルブートにしたのだが、64GBずつしかない状態になり、これじゃさすがに少ないと思って128GBのSSDを増設したのですが、なぜか認識してくれないのでもうあきらめてLinuxだけにしてしまいました。(特に不具合なく使えています)

 

軽量(物理的にも能力的にも)で安価でスタイリッシュなPCがほしい方にはおすすめです(少しの辛抱強さも必要ですが)

Le Eco MAX2 X829にカスタムROMをいれてみた。

Le Eco MAX2 X829にカスタムROMをいれてみた。

その結果。

 

・cocuo92

度々Google Play開発者サービスのエラー→フォードバック画面のコンボが発生し、ストレスフル。

 

・revolution

 

cocuo92に似たような症状で、かなり頻繁にDomainなんちゃらでエラーが発生してストレスフル。

 

・AOKP

起動後、ホーム画面に遷移しようとするたびにエラー。

まったく使えない。

 

というわけで結局元に戻すことにしました。

LeViewとかはいらないからドロアーにしたいんだけど。

今から元のEUIに戻して、ホームアプリでカスタマイズしてみます。

 

 

→追記

エラーの原因がわかりました。

既にはいっているROMを消さずに上書きする形で新しいROMをいれると古いROMの残りファイルが悪さするみたいで、挙動がおかしくなります。

なので、ROM焼きする場合は古いROMを消すことが原則必要です。

というわけで今は「AospExtended-v4.5-x2-20170813-0832-OFFICIAL」を入れてほぼ問題なく使えています(たまに充電中、勝手に再起動することがある程度。ROMの問題かどうかは不明)

ROMはここからDLできます。

Le Max 2 (x2) | Downloads - AospExtended

新しいAndroid端末を決めたよ

Apollo liteをぶっ壊して数日。

とりあえず次の機種を検討する。

同じVernee社のApolloにするか、elephoneのS7にするか、デュアルカメラのある機種にしようか、など色々考えたあげく、これにしました。

 

LeTV LeEco Le Max 2

スナップドラゴン829、4GB RAM、64GB ROM、5.7インチ、WQHD(2560x1440)

このスペックで23000円ぐらい。。。

おサイフケータイだとか、ワンセグ・フルセグだとか、赤外線だとかはないけど、基本スペックだけ見ると日本のAndoroid買えなくなってしまう内容。

 

このブログのタイトルにもあるとおり、他人とはちょっと違うものを持ったりすることに満足感を感じたりする私なのでそもそも日本にない機種っていうだけで血が騒ぐ。

gearbestでDHL便を使って注文したので早ければ今週中には届くはず。