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

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

httpdでhttpとhttpsを両方同時にListenするVirtualHost作成手順

【必要なパッケージのインストール】

suod yum update -y
sudo yum install httpd -y
sudo yum install mod_ssl -y
sudo yum install openssl -y

 

 

SSL証明書の発行】

※手順はネットに山ほどあるので割愛

 

httpd.confの設定】

※重要な箇所だけ記載

・Listen 80はそのまま

・NameVirtualHost *:80をコメントアウト(有効にする)

 443ポートは追加する必要ない(後述するVirtualHostだけでOK)

・DocumentRoot は443で公開するディレクトリを設定

 

<VirtualHost *:80>
    DocumentRoot /var/www/html
    ServerName hogehoge.com
    ErrorLog logs/error_log
    CustomLog logs/log
</VirtualHost>

 

<VirtualHost *:443>
    ServerName hogehoge.com
    SSLEngine on
    SSLProtocol all -SSLv2 -SSLv3
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
    SSLCertificateFile /usr/local/httpd/ssl_certificate.crt
    SSLCertificateKeyFile /usr/local/httpd/server.key
    SSLCertificateChainFile /usr/local/httpd/IntermediateCA.crt
</VirtualHost>

 

上記では80と443とで同じDocumentRootにしていますがもちろん分けてもOKです。

AWSのS3にてファイルが作成/削除されたときに自動でCloudFrontのキャッシュを消す(応用)

 

 

AWSのS3にてファイルが作成/削除されたときに自動でCloudFrontのキャッシュを消すってやり方自体はほかのブログなどでも紹介されていますが、私がやりたかったの単純にファイルのオブジェクトを消すだけじゃなくて「https://hogehoge.com/index.htmlが更新されたらhttps://hogehoge.com/も消す」ってことでした。

 

詳しくはこちら↓

rn4ru.com

 

あとS3へのアクセスをCloudfrontだけに制限したかったのでこちらなども参考にしました。

christina04.hatenablog.com

 

で、つまりはこういうことです。

・index.htmlが更新・削除されたら/のキャッシュも消す

・それ以外(画像とかCSSとか)だったらそのファイルだけのキャッシュを消す

 

で、まずはこちらのサイトからコードを拝借。

cluex-developers.hateblo.jp

 

拝借したコードに手を加えたのがこちら。

 

 

from __future__ import print_function

import boto3
import time
import re

def lambda_handler(event, context):
    for items in event["Records"]:
        FILE = "/" + items["s3"]["object"]["key"]
    LIST=[FILE]
    if "index.html" in FILE:
        pattern = "(.*)index.html(.*)"
        PATH = re.search(pattern, FILE)
        LIST.append(PATH.group(1))
    for path in LIST:
        print(path)
        client = boto3.client('cloudfront')
        invalidation = client.create_invalidation(DistributionId='CloudFrontのID',
            InvalidationBatch={
                'Paths': {
                    'Quantity': 1,
                    'Items': [path]
                },
                'CallerReference': str(time.time())
            })

 

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がほしい方にはおすすめです(少しの辛抱強さも必要ですが)