Grow up

生活とプログラミング

EC2に配置したWebサイトをELBと無料のSSL証明書を使ってHTTPSで公開する


はじめに

EC2でHTTPS通信を行う手順をいつも調べてしまうため簡単にまとめます。
今回の前提条件として無料のSSL証明書ドメインは取得済みとなります。

1. VPC

VPCを作成します。

2. サブネット

後のALBを利用してHTTPS通信を行う設定でサブネットが2つ必要となるため事前に作成します。

2. インターネットゲートウェイ

インターネットゲートウェイを作成します。
作成したインターネットゲートウェイを先ほど作成したVPCにアタッチします。

3. ルートテーブル

ルートのターゲットは先ほど作成したインターネットゲートウェイを指定します。

4. サブネットの関連付け

サブネットの関連付けを行います。
先ほど作成した2つのサブネットを登録します。

5. EC2

EC2のインスタンスを作成します。

注意:インターネットゲートウェイやルートテーブルが設定できていないとSSHやRDPを使ったEC2への接続ができず、EC2にElastic IPの関連付けもできません。

6. ロードバランサ―

ACMから取得したSSL証明書とALBを利用してEC2へHTTPS通信ができるように設定します。
ターゲットの種類はインスタンスを指定します。

サブネットは先ほど作成した2つの候補が出てくるので両方とも選択します。

セキュリティグループのインバンドルールはHTTPSとHTTPを指定します。

ターゲットグループには先ほど作成したEC2インスタンスを登録します。

リスナーとルーティングにはHTTPSとHTTPを指定します。

7. EC2のセキュリティグループ

EC2のセキュリティグループのインバウンドルールを編集します。
HTTPにロードバランサ―のセキュリティグループを指定するように変更します。

8. Route 53

ホストゾーンのAレコードにロードバランサ―を指定します。
エイリアスを有効にして先ほど作成したロードバランサ―を選択します。

9. 確認

EC2に配置したWebサイトがHTTPSで公開されていることを確認します。

その他

ロードバランサ―のリスナーからHTTPのルールを変更することでHTTPSにリダイレクトすることが出来ます。

WSL2 から Hyper-V にアクセスする


はじめに

WSL2で起動しているDockerコンテナからHyper-VUbuntuSSH接続をしたのですが、タイムアウトしてしまいました。

以下の記事を参考にしてWSL2からHyper-VSSH接続することができました。
zenn.dev

変更前の確認
PS C:\Users\User> Get-NetIPInterface | `
>>     Select-Object ifIndex,InterfaceAlias,AddressFamily,ConnectionState,Forwarding | `
>>     Sort-Object -Property IfIndex | `
>>     Format-Table

ifIndex InterfaceAlias               AddressFamily ConnectionState Forwarding
------- --------------               ------------- --------------- ----------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     17 vEthernet (Default Switch)            IPv6       Connected   Disabled
     17 vEthernet (Default Switch)            IPv4       Connected   Disabled
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    108 vEthernet (WSL)                       IPv6       Connected   Disabled
    108 vEthernet (WSL)                       IPv4       Connected   Disabled
設定の変更

PowerShell を管理者権限で起動して設定の変更を行う必要がありました。

PS C:\Users\User> Get-NetIPInterface | `
>> Where-Object {$_.InterfaceAlias -eq 'vEthernet (WSL)' -or $_.InterfaceAlias -eq 'vEthernet (Default Switch)'} | `
>> Set-NetIPInterface -Forwarding Enabled
変更後の確認
PS C:\Users\User> Get-NetIPInterface | `
>>     Select-Object ifIndex,InterfaceAlias,AddressFamily,ConnectionState,Forwarding | `
>>     Sort-Object -Property IfIndex | `
>>     Format-Table

ifIndex InterfaceAlias               AddressFamily ConnectionState Forwarding
------- --------------               ------------- --------------- ----------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     17 vEthernet (Default Switch)            IPv6       Connected    Enabled
     17 vEthernet (Default Switch)            IPv4       Connected    Enabled
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    108 vEthernet (WSL)                       IPv6       Connected    Enabled
    108 vEthernet (WSL)                       IPv4       Connected    Enabled

Ansible を使って Ubuntu 22.04 に Docker をインストールして PostgresSQL を起動する


はじめに

今回はAnsibleを使ってDocker のインストールとイメージを作成して
コンテナの起動はサーバーにSSH接続してコマンドを実行する方法となります。

環境

Ubuntu 22.04

鍵認証によるSSH

ssh-leygenコマンドを使ってSSHに使用する秘密鍵と公開鍵を作成します。
今回キーペアの作成場所は初期値 /root/.ssh/ のままで、パスフレーズは設定していません。

root@d4988cd12c43:/# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:OHEWEvbb895QIx+oomZn7zAa8Mxn0FvjTucRxyDjXGk root@d4988cd12c43
The key's randomart image is:
+---[RSA 3072]----+
|      +..        |
|     . o .   .   |
|      . + o E    |
|       * = = +   |
|    . + S B + *  |
|     = o + = * o |
|      = B + = .  |
|      o*o* + +   |
|     ooo o+ o .  |
+----[SHA256]-----+

ssh-copy-idコマンドを使って、先ほど作成した公開鍵をSSH接続するサーバーに保存します。

root@d4988cd12c43:/# ssh-copy-id ubuntu@192.168.11.57
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
ubuntu@192.168.11.57's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'ubuntu@192.168.11.57'"
and check to make sure that only the key(s) you wanted were added.
ansible-playbook の実行

init フォルダ内にテーブルを作成するための init.sql を保存しています。

C:.
│  inventry.ini
│  playbook.yml
│
└─postgresql
    │  Dockerfile
    │
    └─init
            init.sql

今回なぜか inventry.ini にSSHの接続情報を保存しないと play-book が使えない状況でした。
inventry.ini

target ansible_host=192.168.11.57 ansible_ssh_user=ubuntu aniansible_ssh_pass=ubuntu

[target:var]
ansible_python_interpreter=/usr/bin/python3

また ansible-playbook コマンドに --ask-pass と --ask-become-pass のオプションが必要でした。

root@d4988cd12c43:/ansible# ansible-playbook -i inventry.ini playbook.yml --ask-pass --ask-become-pass
SSH password:
BECOME password[defaults to SSH password]:
PostgreSQL のコンテナを起動

Ansible からコンテナを起動できなかったため手動でコンテナを実行しました。
ansible-playbook コマンドによって2種類のイメージが作成されています。

ubuntu@ubuntu:~$ sudo docker image ls
REPOSITORY   TAG           IMAGE ID       CREATED         SIZE
postgres     14.0-alpine   87440f4e7f9e   10 months ago   195MB
psql14       v1.0          87440f4e7f9e   10 months ago   195MB

ポートやパスワードを指定してコンテナを起動します。

 sudo docker run -p 5432:5432 --name psql14 -e POSTGRES_PASSWORD=postgres psql14:v1.0
PostgreSQL への接続を確認

psql コマンドを使用して接続を確認します。

www.postgresql.jp

Server [localhost]: 192.168.11.57
Database [postgres]:
Port [5432]:
Username [postgres]:
Client Encoding [SJIS]:
Password for user postgres:
psql (12.10, server 14.0)
WARNING: psql major version 12, server major version 14.
         Some psql features might not work.
Type "help" for help.

Dockerfile で指定したバージョン PostgreSQL 14.0 に接続できていることが確認できました。

postgres=# SELECT version();
                                                   version
--------------------------------------------------------------------------------------------------------------
 PostgreSQL 14.0 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424, 64-bit
(1 row)

AWS CLI を使って S3 のファイルを操作する


はじめに

AWS CLI の使い方を説明する機会があったので導入からS3のファイルを操作するまでの手順をまとめました。なお AWS CLI にて利用する Access Key ID と Secret access key についてはIAMより作成済みとします。

環境

Windows 10

AWS CLI インストール

以下の公式ページよりAWS CLIをダウンロードします。
aws.amazon.com

ダウンロードしたインストーラを実行します。

チェックボックスにチェックを入れて Next ボタンを押下します。

Next ボタンを押下します。

Install ボタンを押下します。

Finish ボタンを押下します。

AWS CLI 設定

Windows PowerShell を起動します。

以下のコマンドを実行してクイック設定を開始します。

aws configure

以下のような Access Key ID と Secret access key である場合の入力例です。


$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: ap-northeast-1
Default output format [None]: json
S3 ファイル操作

S3 バケットとオブジェクトの一覧を表示します

aws s3 ls


S3 バケット(例: 20220513-example)を作成します

aws s3 mb s3://20220513-example


S3 バケット(例: 20220513-example)にローカルのファイル(例: index.html)をアップロードします

aws s3 cp C:\file\index.html s3://20220513-example/index.html


S3 バケット内(例: 20220513-example)のファイルを表示します

aws s3 ls s3://20220513-example/


S3 バケット内(例: 20220513-example)のファイルをダウンロードします

aws s3 cp s3://20220513-example/index.html C:\file\index.html


S3 バケット内(例: 20220513-example)のファイル(例: index.html)を削除します

aws s3 rm s3://20220513-example/index.html



トラブルシューティング

AWS Access Key Id の入力を間違えていて以下のようなエラーメッセージが表示されました。

An error occurred (InvalidAccessKeyId) when calling the ListBuckets operation: The AWS Access Key Id you provided does not exist in our records.

aws configure からクイック設定を行って正しい AWS Access Key Id を入力することで解決できました。

参考資料

docs.aws.amazon.com

What are operating systems?

Functions of Operating System

An operating system is oversee hardware use.

1. Directs operational resource

control use of CPU, memory, peripheral devices.
hardware resource be allocate applications.

2. Enforces working policies

fair resource access, limits to resource usage.

3. Mitigates difficulty of complex tasks

abstract hardware details. (system calls)

Operating System Definition
  • Directly has privileged access to the underlying hardware
  • Hides the hardware complexity
  • Manages hardware on behalf of more applications according
  • It Ensures that applications are isolated and protected from one another
Operating System Examples

Desktop Environment

Embedded Environment

OS Elements
  • Abstractions (Managed the harddisk and memory etc hardware resources)
    • process, thread, file, socket, memory page
  • Mechanisms (Application access to hardware resource)
    • create, schedule, open, write, allocate
  • Policies (How do mechanisms will be used to manage the access to hardware)
    • last-recently used (LRU), earliest deadline first (EDF)

Ubuntu 22.04 apt update でエラー "jammy-security/InRelease is not valid yet" の解決方法


はじめに

WSL2でUbuntu22.04を利用した際 apt update で日時設定が原因のエラーが発生したので解決方法を書き残します、

利用環境

・Windows10 Pro
WSL2からUbuntu22.04を利用しています。

原因

Ubuntuの日時が現在の日時と異なることでエラーが発生していました。
今回は時刻のみ異なっていて、正しい時刻は18:16ですがUbuntuでは1:34になっていました。

解決方法

dateコマンドを使用してUbuntuの日時に現在の正しい日時を設定します。
今回は 2022/5/4 18:24:00 に設定しました。

sudo date -s "05/04 18:24 2022"

正しい日時を設定したらapt updateが正常に実行できることを確認します。

他に試したこと

以下は解決方法とならなかった内容ですが、書き残しておきます。

1. Windowsの日時に現在の正しい日時を設定
ホストOSとなるWindowsの日時もUbuntuと同じようにずれていたのでWindowsの日時を現在時刻と合わせたのですが、WSL2のUbuntuと共有の設定では無いようで反映されませんでした。

2. hwclock --hctosys コマンドの実行
コマンドはUbuntuで実行できた様子ですが日時の変更まではできませんでした。
WSLのapt updateでRelease file is not valid yetと言われたらWSLの時刻がずれてるかも。 | Ginpen.com

AnsibleからPostfixを設定してcronからメールを送信する

f:id:knkomko:20210718235123p:plain:w250

はじめに

今回はcronの実行時にメールを送信する機能を使って死活監視を行います。

Postfix や cron の設定は最終的にAnsibleから行えるようにしました。
Ansible は以前に行ったcronの設定を参考にしています。
knkomko.hatenablog.com

Ansible の YAML は以下のリポジトリに保存しています。
github.com

利用環境

・Windows10 Pro
 WSLを使用してAnsibleのplaybookを実行しています

Ubuntu 20.04
 cron を実行するOSです

Postfix とは

メール転送エージェント (Mail Transfer Agent、略称 MTA) の一種です。

cron からメールを送信する為には、メール配信を行うMTA が必要になります。

初めはMTAが無い状態でメール送信を行い、以下のエラーが発生していました。

$sudo cat /var/log/cron.log

Aug 11 07:07:01 ubuntu-cron CRON[378]: (root) CMD (echo 'test')                                                                                              
Aug 11 07:07:01 ubuntu-cron CRON[377]: (CRON) info (No MTA installed, discarding output)  
1. playbook.yml 送信先メールアドレスの編集

job の sample@gmail.com を実在するメールアドレスに変更します。

  - name: Setup cron env
    cron:
      name: MAILTO
      user: root
      job: sample@gmail.com
      env: true
2. playbook.yml ドメイン名の編集

Postfix のインストール前に debconf を使用して設定値を保存しておきます。
debconf を使うとインストール時の設定画面を操作することなく自動で行えます。
今回ドメイン名の設定値は example.com としています。
このドメイン名は実在しなくてもメール送信が可能でした。

  - name: Setup postfix using debconf
    debconf:
      name: postfix
      question: "{{ item.question }}"
      value: "{{ item.value }}"
      vtype: "{{ item.vtype }}"
    with_items:
      - { question: postfix/main_mailer_type, value: "Internet Site", vtype: select }
      - { question: postfix/mailname, value: "example.com", vtype: string }
3. inventry.ini の編集

IPアドレス
 cron を実行するサーバのIPアドレスを変更します。
 今回は 192.168.11.41 に設定しています。
SSH接続ポート番号
 ansible_port でSSH接続のポート番号を接続先に合わせます。
 今回は 22 に設定しています。
SSH接続ユーザー
 ansible_ssh_user でSSH接続のユーザーを接続先に合わせます。
 今回は ubuntu に設定しています。

[target]
192.168.11.41

[target:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_port=22
ansible_ssh_user=ubuntu
4. playbook.yml の実行
$ ansible-playbook -i inventry.ini playbook.yml --ask-pass --ask-become-pass

今回 ansible-playbook を実行した時に以下のエラーが表示されました。

Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host.

管理対象サーバの fingerprint が登録されてないことが原因のようです。
今回 fingerprint の登録が無くても実行できるように ansible.cfg を変更しました。

$sudo vi /etc/ansible/ansible.cfg

# Add ssh_args option "-o StrictHostKeyChecking=no"
#ssh_args = -o ControlMaster=auto -o ControlPersist=60s
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no
5. メール送信の確認

playbook.yml で指定したメールアドレスに送信できていることを確認します。
Postfix で指定したドメインexample.com が送信元として記載されています。
f:id:knkomko:20210812213252p:plain

cron が1分間隔で実行されるため、実行に応じてメールが送信されます。
実行されている cron を確認すると MAILTO にアドレスが指定されています。

ubuntu@ubuntu-postfix:~$ sudo cat /var/spool/cron/crontabs/root                                                                                                                   
[sudo] password for ubuntu:                                                                                                                                                       
# DO NOT EDIT THIS FILE - edit the master and reinstall.                                                                                                                          
# (/tmp/crontabevts3ezv installed on Thu Aug 12 12:28:39 2021)                                                                                                                    
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)                                                                                                         
MAILTO="sample@gmail.com"                                                                                                                                                    
#Ansible: mailtest                                                                                                                                                                
* * * * * bash echo 'test'
cron メール送信ログ

cron からメール送信を行ったログは mail.log に保存されています。

$sudo cat /var/log/mail.log

以下はメール送信に成功したログを抜粋した内容になります。

Aug 12 10:48:12 ubuntu-cron postfix/pickup[14908]: 50FFA390386: uid=1000 from=<ubuntu>                                                                                                                                                                                                                                        
Aug 12 10:48:12 ubuntu-cron postfix/cleanup[14964]: 50FFA390386: message-id=<20210812104812.50FFA390386@example.com>                                                                                                                                                                                                          
Aug 12 10:48:12 ubuntu-cron postfix/qmgr[10365]: 50FFA390386: from=<ubuntu@example.com>, size=280, nrcpt=1 (queue active)                                                                                                                                                                                                     
Aug 12 10:48:12 ubuntu-cron postfix/smtp[14966]: connect to gmail-smtp-in.l.google.com:25: Network is unreachable                                                                                                                                                                                     
Aug 12 10:48:14 ubuntu-cron postfix/smtp[14966]: 50FFA390386: to=<sample@gmail.com>, relay=gmail-smtp-in.l.google.com:25, delay=62, delays=60/0.01/1/0.7, dsn=2.0.0, status=sent (250 2.0.0 OK  253 - gsmtp)                                                                    
Aug 12 10:48:14 ubuntu-cron postfix/qmgr[10365]: 50FFA390386: removed 
postfix 設定ファイル

メール送信等の設定を変更する場合は main.cf から変更を行います。

$sudo cat /etc/postfix/main.cf

手動で main.cf を変更した場合は postfix の再起動が必要です。

$sudo service postfix restart

今回 ansible から設定した内容になります。

# See /usr/share/postfix/main.cf.dist for a commented, more complete version                                                                                                      
                                                                                                                                                                                  
                                                                                                                                                                                  
# Debian specific:  Specifying a file name will cause the first                                                                                                                   
# line of that file to be used as the name.  The Debian default                                                                                                                   
# is /etc/mailname.                                                                                                                                                               
#myorigin = /etc/mailname                                                                                                                                                         
                                                                                                                                                                                  
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)                                                                                                                              
biff = no                                                                                                                                                                         
                                                                                                                                                                                  
# appending .domain is the MUA's job.                                                                                                                                             
append_dot_mydomain = no                                                                                                                                                          
                                                                                                                                                                                  
# Uncomment the next line to generate "delayed mail" warnings                                                                                                                     
#delay_warning_time = 4h                                                                                                                                                          
                                                                                                                                                                                  
readme_directory = no                                                                                                                                                             
                                                                                                                                                                                  
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on                                                                                                         
# fresh installs.                                                                                                                                                                 
compatibility_level = 2                                                                                                                                                           
                                                                                                                                                                                  
# TLS parameters                                                                                                                                                                  
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem                                                                                                                          
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key                                                                                                                         
smtpd_use_tls=yes                                                                                                                                                                 
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache                                                                                                           
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache                                                                                                             
                                                                                                                                                                                  
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for                                                                                                         
# information on enabling SSL in the smtp client.                                                                                                                                 
                                                                                                                                                                                  
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination                                                                                   
myhostname = ubuntu-postfix                                                                                                                                                       
alias_maps = hash:/etc/aliases                                                                                                                                                    
alias_database = hash:/etc/aliases                                                                                                                                                
myorigin = /etc/mailname                                                                                                                                                          
mydestination = $myhostname, example.com, ubuntu-postfix, localhost.localdomain, localhost                                                                                        
relayhost =                                                                                                                                                                       
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128                                                                                                                         
mailbox_size_limit = 0                                                                                                                                                            
recipient_delimiter = +                                                                                                                                                           
inet_interfaces = all                                                                                                                                                             
inet_protocols = all