2011|08|
2013|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|05|06|07|08|09|10|11|12|
2016|01|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|

2020-01-01 GOによる簡単なWebサーバの作り方 [長年日記]

http://www.kobore.net/soft/wstest4/go_server.mm.html

GOによる簡単なWebサーバの作り方

GOによる簡単なWebサーバの作り方

  • 初版 2020/01/01

    /home/kobore/www/soft/wstest4に一式あり

    1.目的

    • WebSocketと連動させる方法を考えたが、難しいので単体で作ることにした

    2.サーバプログラム

    • "./main.go"
      • package main
      • import (
        • "log"
        • "net/http"
      • )
      • func main() {
        • http.Handle("/", http.FileServer(http.Dir("static")))
        • if err := http.ListenAndServe(":8686", nil); err != nil {
          • log.Fatal("ListenAndServe: ", err)
        • }
      • }
    • 起動方法
      • >go run main.go

    3.クライアントプログラム

    • "./index.html"
      • コード
        • <!DOCTYPE html>
          • <head>
            • <title>HTMLの練習1</title>
          • </head>
          • <body>
            • 初めてのWebページ1です。
          • </body>
        • </html>
      • 起動方法
        • http://192.168.0.88:8686/
    • "./user.html"
      • コード
        • <!DOCTYPE html>
          • <head>
            • <title>HTMLの練習2</title>
          • </head>
          • <body>
            • 初めてのWebページ2です。
          • </body>
        • </html>
      • 起動方法
        • http://192.168.0.88:8686/user.html

    4.その他

    • 画像を表示したい場合等
    • "./static/image1.jpg
      • 起動方法
        • http://192.168.0.88:8686/image1.jpg
    • "./static/image2.jpg
      • 起動方法
        • http://192.168.0.88:8686/image2.jpg

2020-01-02 GOによる簡単なWebSocketサーバの作り方 [長年日記]

GOによる簡単なWebSocketサーバの作り方

GOによる簡単なWebSocketサーバの作り方

  • 初版 2020/01/01 

     /home/kobore/www/soft/wstest32に一式あり

    1.目的

    • ラズパイを使って、クライアントで同じ画像の表示をさせたい
    • WebSocketを使ってクライアン間で共有させることを考えた

    2.課題

    • サンプルプログラムを見ても、(私には)仕組みが良く分からない
    • チャットアプリの例は沢山あるが、画像を共有する方法は分からなかった(多分あると思う)
    • が、まっとうな方法が分からなかったので、サンプルプログラムを流用させて貰うことにした

    3.前提

    • ラズパイにgoをインストールしておく
      • ネットに沢山が記載がある
    • "GOによる簡単なWebサーバの作り方"を作っておく
    • http://www.kobore.net/diary_techno/?date=20200101
    • go get github.com/gorilla/websocke
    • touch websocket-server.go
    • touch index.html

    4.サーバプログラム

    • https://qiita.com/__init__/items/08cbc3a870178fd6fc32 の内容と同じ
    • "./websocket-server.go"
      • package main
      • import (
        • "log"
        • "net/http"
        • "github.com/gorilla/websocket"
      • )
      • // WebSocket サーバーにつなぎにいくクライアント
      • var clients = make(map[*websocket.Conn]bool)
      • // クライアントから受け取るメッセージを格納
      • var broadcast = make(chan Message)
      • // WebSocket 更新用
      • var upgrader = websocket.Upgrader{}
      • // クライアントからは JSON 形式で受け取る
      • type Message struct {
        • Message string `json:message`
      • }
      • // クライアントのハンドラ
      • func HandleClients(w http.ResponseWriter, r *http.Request) {
        • // ゴルーチンで起動
        • go broadcastMessagesToClients()
        • // websocket の状態を更新
        • websocket, err := upgrader.Upgrade(w, r, nil)
        • if err != nil {
          • log.Fatal("error upgrading GET request to a websocket::", err)
        • }
        • // websocket を閉じる
        • defer websocket.Close()
        • clients[websocket] = true
        • for {
          • var message Message
          • // メッセージ読み込み
          • err := websocket.ReadJSON(&message)
          • if err != nil {
            • log.Printf("error occurred while reading message: %v", err)
            • delete(clients, websocket)
            • break
          • }
          • // メッセージを受け取る
            • broadcast <- message
        • }
      • }
      • func main() {
        • // localhost:8080 でアクセスした時に index.html を読み込む
        • http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
          • http.ServeFile(w, r, "index.html")
        • })
        • http.HandleFunc("/chat", HandleClients)
        • err := http.ListenAndServe(":8080", nil)
        • if err != nil {
          • log.Fatal("error starting http server::", err)
          • return
        • }
      • }
      • func broadcastMessagesToClients() {
        • for {
          • // メッセージ受け取り
          • message := <-broadcast
          • // クライアントの数だけループ
          • for client := range clients {
          • // 書き込む
            • err := client.WriteJSON(message)
            • if err != nil {
              • log.Printf("error occurred while writing message to client: %v",
        • err)
          • client.Close()
          • delete(clients, client)
          • }
          • }
          • }
      • }
    • 起動方法
      • go run websocket-server.go

    5.クライアントプログラム

    • こっちの方は、https://qiita.com/__init__/items/08cbc3a870178fd6fc32 の内容にちょっと追加をする
    • まったく美しくない方法だが(本来ならWebSocketを使うべき)、もうなにふり構わない
    • "./index.html"
      • コード
        • <!DOCTYPE html>
          • <head>
            • <meta charset="UTF-8">
            • <meta name="viewport" content="width=device-width, initial-scale=1.0">
            • <meta http-equiv="X-UA-Compatible" content="ie=edge">
            • <title>WebSocket Server</title>
          • </head>
          • <body>
            • <input id="input" type="text" />    <!-- 入力文字を表示  -->
            • <button onclick="send()">Send</button><!-- ボタンのメソッドをボタン本体を表
        • 示  -->
          • <pre id="output">outputのエリア</pre><!-- 出力結果を表示  -->
          • ~ <img id="image_place" src="http://192.168.0.88:8686/image3.jpg"/>
          • <script>
            • var input = document.getElementById('input');
            • var output = document.getElementById('output');
            • var socket = new WebSocket("ws://" + window.location.host + "/chat");
            • // 江端追記
            • // img要素を取得する
            • var img = document.getElementById("image_place");
            • // 表示する画像番号
            • var idx = 1;
            • // 江端追記ここまで
            • socket.onopen = function() {
            • // output.innerHTML += "Connection OK\n";
            • };
            • socket.onmessage = function(e) {
            • // output.innerHTML += "Get message from server: " + e.data + "\n";
            • // 江端追記
            • idx++;
            • if (idx > 3) {
            • idx = 1;
            • }
            • //output.innerHTML += idx + "\n";
            • //output.innerHTML += "before\n";
            • // img要素のsrcに画像ファイル名を設定する
            • //img.src = "image" + idx + ".jpg";
            • ~ img.src = "http://192.168.0.88:8686/image" + idx + ".jpg";
            • //output.innerHTML += "after\n";
            • // 江端追記ここまで
            • };
            • function send() {
              • socket.send(JSON.stringify(
              • {
                • message: input.value
              • }
              • ));
              • input.value = "";
            • };
          • </script>
          • </body>
        • </html>
      • 起動方法
        • http://192.168.0.88:8080/

    6.その他

    • 画像の場所
      • "./static/image1.jpg
        • 起動方法
          • http://192.168.0.88:8686/image1.jpg
      • "./static/image2.jpg
        • 起動方法
          • http://192.168.0.88:8686/image2.jpg

2020-01-03 オムロン社センサ 2jcie-bu01についてのコーディングについて [長年日記]


2020-01-15 ボタンを押すと全てのクライアントのコンテンツが同時に代わるように改造した [長年日記]

GOによる簡単なWebSocketサーバの作り方 の"index.html"だけを変更して、ボタンを押すと全てのクライアントのコンテンツが同時に代わるように改造した。(文字表示はコメントアウトして消すこと)

稼働確認直後の、もっとも汚い状態のコードをアップしている。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>WebSocket Server</title>
  </head>
  <body>
 
 
    <input id="Button1" type="button" value="スタンバイ中" onclick="onButtonClick1();" />
    <input id="Button2" type="button" value="待機中" onclick="onButtonClick2();" />
    <input id="Button3" type="button" value="移動中" onclick="onButtonClick3();" />
    
    
    <!--
    <input id="input" type="text" />    
    -->
 
    <p id="input"></p>
    <p id="input1"></p>
    <p id="input2"></p>
    <p id="input3"></p>
 
    <!--
    <button onclick="send()">Send</button>
    -->
    <!--
    <pre id="output">outputのエリア</pre>
    -->
 
    <pre id="output"></pre>    
 
    <!--
    <img id="image_place" src="http://192.168.0.88:8686/red.html"/>
 
    <img id="image_place" src="http://192.168.0.88:8686/image3.jpg"/>
    -->
 
    <iframe id="image_place" src="http://192.168.0.88:8686/red.html" width="100%" height="700"></iframe>
 
    
    <script>
      var input1 = document.getElementById('input1');
      var input2 = document.getElementById('input2');
      var input3 = document.getElementById('input3');      
 
      var output = document.getElementById('output');
      var socket = new WebSocket("ws://" + window.location.host + "/chat");
      
      // 江端追記
      // img要素を取得する
      var img = document.getElementById("image_place");
      // 表示する画像番号
      var idx = 1;
      
      // 江端追記ここまで
      
      socket.onopen = function() { 
      // output.innerHTML += "Connection OK\n";
      };
      
      socket.onmessage = function(e) {
      // output.innerHTML += "Get message from server:" + e.data + "\n";
 
      var obj = JSON.parse(e.data); // JSONオブジェクトに変換
 
      // output.innerHTML += "Get object :" + obj.Message + "\n";
      
          
      // 江端追記
      
      //idx++;
      //if (idx > 3) {
      //idx = 1;
      //}
      
      //output.innerHTML += idx + "\n";
      //output.innerHTML += "before\n";
 
      
      // switch(e.data){
      switch(obj.Message){      
      case '1':
      // console.log('1です');
      // document.write("1です<br/>");
      // document.getElementById("output").innerHTML += "1です";
 
      // img.src = "http://kobore.net/soft/wstest32/image1.jpg";
      // img.src = "http://192.168.0.88:8686/image1.jpg";
      img.src = "http://192.168.0.88:8686/red.html";
 
      break;
 
      case '2':
      // console.log('2です');
      // document.write("2です<br/>");
      // document.getElementById("output").innerHTML += "2です";
      // img.src = "http://192.168.0.88:8686/image2.jpg";
      img.src = "http://192.168.0.88:8686/yellow.html";
 
      break;
 
      case '3':
      // console.log('3です');
      // document.write("3です<br/>");
      // document.getElementById("output").innerHTML += "3です";
      // img.src = "http://192.168.0.88:8686/image3.jpg";
      img.src = "http://192.168.0.88:8686/blue.html";      
 
      break;
      }
 
      // img要素のsrcに画像ファイル名を設定する
      //img.src = "image" + idx + ".jpg";
      // img.src = "http://192.168.101.1:8686/image" + idx + ".jpg";
      //img.src = "http://192.168.0.88:8686/image" + idx + ".jpg";
 
      
      // output.innerHTML += "after\n";
      
      // 江端追記ここまで
      
      };
 
 
      //function send() {
      //  socket.send(JSON.stringify( 
      //  {
      //     message: input.value
      //  }
      //  ));
      //  input.value = "";
      //};
 
      function onButtonClick1(){
        input1.value = "1";
        socket.send(JSON.stringify( 
        {
           message: input1.value
        }
        ));
        input1.value = "";
      };
 
      function onButtonClick2(){
        input2.value = "2";
        socket.send(JSON.stringify( 
        {
           message: input2.value
        }
        ));
       input2.value = "";
      };
 
      function onButtonClick3(){
        input3.value = "3";      
        socket.send(JSON.stringify( 
        {
           message: input3.value
        }
        ));
       input3.value = "";
      };
    </script>
  </body>
</html>
 
 
 

"./static/red.html 等は、wstest4に入っている


2020-01-16 Web画面の中央で「移動中」が点滅するhtml [長年日記]

Web画面の中央で「移動中」が点滅するhtmlを作って欲しいといったら、私の上司が作ってくれました。

以下を"blue.html"という名前で保存

<!DOCTYPE html>
<html lang="ja">
  <head>
    <link rel="stylesheet" type="text/css" href="blue-style.css">
    <meta charset="utf-8">
  </head>
  <body>
    <div class="central">
      <div class="subtitle">
        移動中
      </div>
    </div>
  </body>
</html>
 

以下を"blue-style.css"という名前で保存

body {
  background: blue;
  color: white;
  overflow: hidden;
}
 
.central {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  width: 100%;
  font-size: 220px;
  font-weight: bold;
  -webkit-animation:blink 1.5s ease-in-out infinite alternate;
  -moz-animation:blink 1.5s ease-in-out infinite alternate;
  animation:blink 1.5s ease-in-out infinite alternate;
}
 
@-webkit-keyframes blink{
  0% {opacity:0;}
  100% {opacity:1;}
}
@-moz-keyframes blink{
  0% {opacity:0;}
  100% {opacity:1;}
}
@keyframes blink{
  0% {opacity:0;}
  100% {opacity:1;
}
 

2020-01-22 Googleフォームを自在にカスタマイズする [長年日記]

https://qiita.com/sota6412/items/fa077cbf820faca30598


2020-01-24 Go言語でWebサーバを作る時の注意点 [長年日記]

忘れない内に記載しておく

まず、以下のプログラムを、main.go とかいう名前でセーブして、go build main.go をすると、 main という実行フィイルができる。

ところが、問題は、これを、任意のディレクトリから実行させようとすると、絶対パスの記載が必要となり、これを見つけるのに結構な時間がかかった。

結果としては、以下のようにすれば良いらしい(動いている)。

package main
 
import (
    "log"
    "net/http"
)
 
func main() {
     http.Handle("/", http.FileServer(http.Dir("/home/pi/wstest4/static")))
 
    if err := http.ListenAndServe(":8686", nil); err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

上記のプログラムを、"http:/localhost:8686/xxxxx.html"とブラウザに打ちこむと

/home/pi/wstest4/static/xxxxx.htmlのファイルが表示される

もしプログラムの http.Handle("/" を、http.Handle("/hogehoge" とすると、"http:/localhost:8686/hogehoge/xxxxx.html"と入力することで

/home/pi/wstest4/static/xxxxx.htmlのファイルが表示される


2020-01-25 Go言語でWebSocketサーバを作る時の注意点 [長年日記]

忘れない内に記載しておく

まず、以下のプログラムを、web-server.go とかいう名前でセーブして、go build web-server.go をすると、 web-server という実行フィイルができる。

ところが、問題は、これを、任意のディレクトリから実行させようとすると、絶対パスの記載が必要となり、これを見つけるのに結構な時間がかかった。

結果としては、以下のようにすれば良いらしい(動いている)。

func main() {
 
    // localhost:8080 でアクセスした時に index.html を読み込む
    //http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    //    http.ServeFile(w, r, "index.html")
    //})
 
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        http.ServeFile(w, r, "/home/pi/wstest33/index.html")
    })
 
 
    http.HandleFunc("/chat", HandleClients)
 
   err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("error starting http server::", err)
        return
    }
 
}

上記のプログラムを、"http:/localhost:8080/xxxxx.html"とブラウザに打ちこむと

/home/pi/wstest33/index.htmlのファイルが表示される


2020-01-26 車載サイネージサービスを自動起動にした [長年日記]

2つのサービスを作るのは美しくないが、もう色々考えるのが面倒なので、このまま強行

[Unit]
Description = kanban daemon
 
[Service]
ExecStart = /home/pi/wstest4/main
Restart = always
Type = simple
 
[Install]
WantedBy = multi-user.target

を、/etc/systemd/system/kanban.serviceとして、保存し、

$ sudo systemctl enable kanban

でエントリして、

$ sudo systemctl start kanban

で、起動確認をする。

[Unit]
Description = kanban-cont daemon
 
[Service]
ExecStart = /home/pi/wstest33/websocket-server
Restart = always
Type = simple
 
[Install]
WantedBy = multi-user.target

を、/etc/systemd/system/kanban-cont.serviceとして、保存し、

$ sudo systemctl enable kanban-cont

でエントリして、

$ sudo systemctl start kanban-cont

で、起動確認をする。

起動確認できていれば、sudo rebootで再起動する。


2020-01-27 AWSを無料のSSLでなんとかしたい [長年日記]

AWSを無料のSSLでなんとかしたい

AWSを無料のSSLでなんとかしたい

  • 初版 2020/01/25

    (注)下記の情報は、適度に乱数化していますので、アタックは時間の無駄です

    謝辞: 私のために、わざわざ手順書を作成してくれたSさんに感謝します。

    • この情報はSさんの手順書に、私が疑問に思ったことと、私なりの解釈と、私の踏んだ地雷を全部記載したものです

    1.SSL証明書とは何か

    • ■知らん

      • しかし、AWS(Amazon Web Service)で、位置情報を取り扱うWebサイトを作るとき、この処理ができないと位置情報のやりとりができない(ブラウザの全部が、サービスを拒否する)ので、とにかく実装しなけれなならなくなった

      ■もう少し真面目に言うと

      • 電子証明書を発行する認証局自身の公開鍵が含まれた電子証明書
        • (私は、現時点でもこのフレーズを理解できるとは言えない)

      ■何が美味しいのか

      • 例えば、江端の運営している"kobore.net"が世界で唯一のホームページであることを、江端よりえらい人(機関、組織)に承認してもらうことで、"kobore.net"とあなたのPCやスマホのブラウザで暗号化通信がされることになる

        つまり、"kobore.net"とあなたのPCやスマホの間での通信を、盗聴しようとしても、訳の分からん文字(情報)しか見えなくなる

        • ちなみに、平文の盗聴なんぞ私(江端)でも簡単にできる
        • エンジニアの善意を、あんまり信じないほうがいいぞ

        この対応していないとどうなるか→ブラウザに「このサイト、信用できんぜ」と表示される

        • 「保護されていない通信」と表示される
        • 現在の、kobore.netもこう表示される(現在、対応中)

      ■で、分かると思うけど

      • あなたが、GoogleMAPや他のナビアプリを使っている時に、自分の位置情報が、他人や昔の恋人に盗聴されたら、ヤバいでしょ?

    2.やりたいこと

    • AWSで、無料SSL証明書のLet's Encryptを利用すること

    3. やってしまったこと

    • すでに、AWSのSSL証明書を使っていたので、これを外さなければならなくなった

    4.まず、AWSのSSL証明書を無効化する

    • (1)AWSのコンソールから、Certificate Managerにいって外そうとしたが、「証明書は *.sea-anemone.tech (a961fd79-546d-4915-bc6b-784decc76f3c)使用中で(他の AWS リソースに関連付けられていて)削除することはできません。リスト内の各リソースからその証明書との関連付けを解除し、もう一度お試しください。」と言われて失敗

      (2)今度はELBの方にいってみる→リスナーのところにあるhttpsのリストを消去→この後、Certificate Managerにいって外したら成功した

      (3)ところが、Webサービスが全滅してしまった

      (4)ELBの方にいってみる→リスナーのところにあるhttpsのリストをhttp(80)を追加することで、復活した

      • 実は、Webが使えない状態で、Let's Encryptを設定しようとして、何度もコケた
      • 酷く時間がかかった

    5.では始める

    • (1)前提とするシステム構成
      • EC2はapacheで動いていて、Webコンテンツは、/var/www/htmlに起いてあることとする
      • ドメイン名は"sea-anemone.tech"が取得してあり、Route53で、www.sea-anemone.techのレコードが作成しているものとする
    • (2)忘れてはならないこと
      • EC2の中にあるWebサーバのページの内容を保護することであって、自前のAWSシステム全体を守る訳ではないので、勘違いしないように(私は勘違いしていた)
      • 例えば、インターネットからEC2を直撃されたら、システム死ぬ
    • (3)EC2にSSHログインで入って、以下をやっておく
      • $ sudo apt-get install software-properties-common
      • $ sudo add-apt-repository ppa:certbot/certbot
      • $ sudo apt-get update
      • $ sudo apt-get install certbot
    • (4)EC2の中で各種証明書を作成する
      • $ sudo certbot certonly --webroot -w /var/www/html -d sea-anemone.tech -d www.sea-anemone.tech
        • 途中、メールアドレスの入力を要求される
        • 結構、エラーを繰り返した
          • Obtaining a new certificate Performing the following challenges: http-01 challenge for sea-anemone.tech http-01 challenge for www.sea-anemone.tech Using the webroot path /var/www/html for all unmatched domains. Waiting for verification... Cleaning up challenges Failed authorization procedure. sea-anemone.tech (http-01): urn:ietf:params:acme:error:dns :: No valid IP addresses found for sea-anemone.tech, www.sea-anemone.tech (http-01): urn:ietf:params:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://www.sea-anemone.tech/.well-known/acme-challenge/XKDZnnDIn-Y7BZYkx4Q6dPbUVeaSDrKAMgEW6Y2iLHU: Connection refused

        • この理由はELBの設定を転けていたから
      • 成功すると、こんな表示が出てくる
        • IMPORTANT NOTES:  - Congratulations! Your certificate and chain have been saved at:    /etc/letsencrypt/live/www.sea-anemone.tech/fullchain.pem    Your key file has been saved at:    /etc/letsencrypt/live/www.sea-anemone.tech/privkey.pem    Your cert will expire on 2020-04-24. To obtain a new or tweaked    version of this certificate in the future, simply run certbot    again. To non-interactively renew *all* of your certificates, run    "certbot renew"  - If you like Certbot, please consider supporting our work by:     Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate    Donating to EFF:                    https://eff.org/donate-le

      • ところが、この"/etc/letsencrypt/live/www.sea-anemone.tech/fullchain.pem"がlsとかでは見えないから、ちょっとビックリする
        • 例えば、$sudo ls -l /etc/letsencrypt/live/www.sea-anemone.tech

          -rw-r--r-- 1 root root 692 Jan 25 13:48 README lrwxrwxrwx 1 root root  42 Jan 25 13:53 cert.pem -> ../../archive/www.sea-anemone.tech/cert2.pem lrwxrwxrwx 1 root root  43 Jan 25 13:53 chain.pem -> ../../archive/www.sea-anemone.tech/chain2.pem lrwxrwxrwx 1 root root  47 Jan 25 13:53 fullchain.pem -> ../../archive/www.sea-anemone.tech/fullchain2.pem lrwxrwxrwx 1 root root  45 Jan 25 13:53 privkey.pem -> ../../archive/www.sea-anemone.tech/privkey2.pem

    • (5)awscliのインストール
      • 簡単に言うと、以下の処理はAWSのコンソールではできないので、コンソールで実施するためのコマンド
      • ところが、このインストールがsudo apt-getではできない。pip3でやる必要があるので、それをインストールする
        • $ sudo apt install python-pip python3-pip
      • んでもって、sudo pip3 install awscliでインストールする
    • (6)証明書のアップロード
      • 問題は、この"アップロード"って、どこからどこにアップロードするの?ということ
        • 認証局に問い合わせをするのは、Webにアクセスあった時だから、認証局に上げるのは"変"

          たぶん、EC2に証明書を閉じ込めておいても意味ないので、これをAWSの制御機能に渡す必要があるはず

      • アップロード用のコマンドを見てみると、sudo aws iam upload-server-certificate.... と記載されているから、どうやら"IAM"に上げるのだろうと思う
        • ところで、"IAM"って何?
          • AWSを使っているとき、こういう意味不明な用語で発狂しそうになること、多数
          • そして、AWS公式ページの内容が、(私には)恐しく訳が分からない
        • "IAM"とは、複数のユーザでAWSを使う時に、ユーザを"差別"するもの、という理解でいい
          • 江端のように一人で使う場合には、ユーザ管理なんぞは忘れていい
        • ここでは、「認証書類を保管する役所」くらいのイメージで良いだろう
      • では、EC2で作った認証書類を、"IAM"役所に預けるぞ
        • sudo aws iam upload-server-certificate --server-certificate-name sea-anemone-certificate-20200125 --certificate-body file:///etc/letsencrypt/live/www.sea-anemone.tech/cert.pem --private-key file:///etc/letsencrypt/live/www.sea-anemone.tech/privkey.pem

          • 文句を言わずに、この通りにやれ
      • で、当然に失敗する
        • Unable to locate credentials. You can configure credentials by running "aws configure"
        • なんだ、これ?
      • 言われた通り、$aws configure をやってみた
        • AWS Access Key ID [None]:とか聞かれた
          • 何これ?
          • どうもAWS コンソールの何かとは違う何かのよう
      • 調べてみたところ、AWS Concoleの中で何かをやるらしい
        • ~ https://console.aws.amazon.com/iam/home#/security_credentials
        • これで"Continue to Security Credentials"ボタンを押して、続ける
        • メニューの「アキスキー(アクセスキ-IDとシークレットアクセスキー)を選ぶ
          • AWSは、(MicorsoftのOfficeシリーズと同様に)ユーザの不便を全く考慮せずに、インターフェイスを気儘に変えるので、多分、これを見ている人は、同じメニューに出会えないと覚悟しておくこと
        • かまわんので「新しいアクセスキーの作成」ボタンを押す
          • アクセスキー ID: AKIAJODSYVZ5RPLQFQ
          • シークレットアクセスキー: Gu03B7yeb09BgmPZ7CM87d0P0NNhZm2N2C6NFV
          • てな表示が出てくるので、どこぞにコピペしておく( rootkey.csv で保存するか聞いてくるので、そっちでもいい)
      • で、ここまできて、さっきの続きになる。以下のように入力しておけばいい
        • AWS Access Key ID [None]: AKIAJODSYVE5RPLQFQ
        • AWS Secret Access Key [None]: Gu03B7yeb09BgmPZ7C7d0PCE0NNhZm2N2C6NFV
        • Default region name [None]: ap-northeast-1
          • → うち(江端の)はアジアパシフィック(東京)なので、こうなるらしい
        • Default output format [None]: text
          • → text, JSON, tableのいずれかを入れるらしい。よく分からないのでtextを入力
      • で、これが登録されたかは、このコマンドで確認できる
        • $aws ec2 describe-instances
        • これで、色々な情報がワラワラでてくれば成功しているはず
          • RESERVATIONS    924297495837    r-0886689180f576bd5 から、やく30行くらいの出力
      • さて、では、もう一度、EC2で作った認証書類を、"IAM"役所に預けるぞ
        • $ sudo aws iam upload-server-certificate --server-certificate-name sea-anemone-certificate-20200125 --certificate-body file:///etc/letsencrypt/live/www.sea-anemone.tech/cert.pem --private-key file:///etc/letsencrypt/live/www.sea-anemone.tech/privkey.pem --certificate-chain file:///etc/letsencrypt/live/www.sea-anemone.tech/chain.pem --path /www.sea-anemone.tech/

          • 成功すると、こんな感じ
            • SERVERCERTIFICATEMETADATA       arn:aws:iam::924297495837:server-certificate/www.sea-anemone.tech/sea-anemone-certificate-20200125     2020-04-24T03:53:05Z    /www.sea-anemone.tech/    ASCA5ONDMQUO2ZNB6MV7H   sea-anemone-certificate-20200125     2020-01-25T07:25:10Z

      • ちゃんと預けられたかを確認
        • $aws iam list-server-certificates
          • 上と同じ表示が出てこれは成功
      • 取り下げる(削除する)ときは、こうする
        • $aws iam delete-server-certificate --server-certificate-name sea-anemone-certificate-20200125
    • (7)ELBに証明書を関連付ける
      • 証明書はEC2のWebサーバ用だけど、WebアクセスはELBを窓口にしてやってくるので、ELBに証明書のことを知っておいて貰わないと困る ―― ということだろうと思う
      • AWSのコンソールをブラウザで開く
      • ロードバランサの画面で、sea-anemone.techで利用しているELBを選択。
      • アクションからリスナーの編集を選択し、ロードバランサのプロトルに、httpsを追加する。でもって、"SSL証明書"を叩くと、3つのメニューがでてくる
        • 証明書タイプ
          • ACMから証明書を選択する(推奨)
          • IAMから証明書を選択する           ←こいつを選ぶ
          • IAMに証明書をアップロードする
      • と、証明書の名前(sea-anemone-certificate-20200125)がかってに表示されるので、そのまま保存して良い

    6.確認方法

    • ブラウザから、"https://www.sea-anemone.tech"が見えれば成功

    以上


2020-01-28 ユーザのログイン履歴を確認する方法 [長年日記]

sshなどでリモートログインを可能にしている場合、ユーザのログイン履歴を調る方法

$ last [ユーザ名] ・・・ ログイン履歴を表示する。

$ lastlog [ユーザ名] ・・・ システムに登録された各ユーザの最終ログイン履歴を表示する。

$ lastb [ユーザ名] ・・・ ユーザのログイン失敗履歴を表示する。

出展 https://horus531.hatenadiary.org/entry/20110103/1294058791