NETWORK ENGINEER BLOG

Tips and Reviews for Engineers

はてなブログに Google アナリティクス 4 プロパティを設定

はてなブログに Google アナリティクス 4 プロパティ(GA4)を設定する方法です。

Google アナリティクス 4 プロパティとは

Google アナリティクス 4 プロパティ(GA4)はアプリ計測ツール「Google アナリティクス For Firebase」の仕組みを土台として、データ構造から再設計された新しい Google アナリティクスです。2019年に発表された「アプリ+ウェブ プロパティ」が、正式に2020年10月に β 版から名称を「Google アナリティクス 4 プロパティ(GA4)」へ変えてリリースされました。
…(中略)…
Google アナリティクス 4 プロパティはプロパティの中に「データストリーム」という新しい概念が追加されました。データストリームは「ウェブ」「iOS」「Android」とそれぞれのデータストリームに分かれています。
ウェブは「GTM か gtag.js で新しい計測 ID をウェブサイトへ追加」することでGA4プロパティの「ウェブストリーム」にデータを収集することができ、iOS、Android は「Firebase プロジェクト」と Google アナリティクス 4 プロパティを連携することで「アプリストリーム」にデータを収集することができます。
f:id:FriendsNow:20210131223009p:plain:w650
出典:アユダンテ株式会社

はてなブログ設定方法

  • GA4 に接続して、左ペインの「管理」➡「データストリーム」をクリックします。
  • グローバルサイトタグ(gstag.js)をコピーして、はてなブログの「設定」➡「詳細設定」の「head に要素を追加」に貼り付けます。

f:id:FriendsNow:20210116175124p:plain

しばらく経過すると、測定結果が反映されます。
f:id:FriendsNow:20210131232301p:plain

以上

デュプレックス(duplex)について

全二重(Full-duplex) 半二重(Half-duplex)とは

  • 半二重モードでは、送信と受信を片方向ずつ、時間を分けて通信する。
    • 100BASE-TX の場合、送信と受信あわせて、最大100Mbps の通信が可能。
  • 全二重モードでは、送信と受信を両方向同時に通信する。
    • 100BASE-TX の場合、送信と受信それぞれ最大 100Mbps の通信が可能。
  • HUB は CSMA/CD 方式である半二重モードのみをサポートしており、送受信を同時に行えない。

f:id:FriendsNow:20210223132049p:plain

オートネゴシエーションについて

  • FLP(Fast Link Pulse)バーストと呼ばれるパルス信号を使用し、互いの通信速度とモードを検出する。
  • 相互の通信モードによっては、リンクダウンや、半二重通信になってしまう場合があるので、注意すること。

f:id:FriendsNow:20210124221424p:plain:w550

デュプレックスミスマッチについて

対向でデュプレックスがあっていない場合、デュプレックスミスマッチとなり、通信が正常にできない場合があります。
Cisco の場合は、CDP が有効になっていると、以下のエラーが出力されます。

%CDP-4-DUPLEX_MISMATCH: duplex mismatch discovered on FastEthernet0/1 (not full duplex), with R1 Ethernet0/0 (full duplex).

上記の表の「〇」となるように、対向の設定をあわせることが対策となります。

以上

Amazon RDS のパラメータ変更について

Amazon RDS(MySQL)において、パラメータグループを変更する際、以下のエラーが発生しました。

保存中のエラー: Cannot modify a default parameter group. (Service: AmazonRDS; Status Code: 400; Error Code: InvalidParameterValue; Request ID: xxxx-xxxx-xxxx-xxxx; Proxy: null)

原因は「デフォルトのパラメータグループの変更しようとしたこと」でした。
仕様上、デフォルトのパラメータグループは、変更不可のようです。
対策は、パラメータグループの作成になります。

パラメータグループの作成

パラメータグループを作成します。作成したパラメータグループは、設定変更が可能です。
f:id:FriendsNow:20210124121740p:plain

パラメータグループの適用

パラメータグループをデータベースに割り当てます。
f:id:FriendsNow:20210124121723p:plain

参考書籍

以上

Amazon RDS(MySQL)で名前解決を無効化

MySQL における名前解決について

MySQL において名前解決は、コネクションの確立・認証のフェーズで利用されます。デフォルト(名前解決が有効)な場合のシーケンスはざっくりと以下のようになります。

  1. IPアドレスが MySQL 内の名前解決キャッシュに載っているかどうかを確認する
  2. (載っていない場合)IP アドレスからホスト名に逆引きをかける(getnameinfo)
  3. 得られたホスト名を正引きし、IP アドレスを得る(getaddrinfo)
  4. IP アドレスとホスト名の両方を使って、接続元ホストの検証をする
  5. 検証に成功した場合、これ以降の「接続元ホスト」は IP アドレスまたはホスト名の「検証に成功したどちらか一方」を利用する
  6. ユーザー名、パスワードなどの認証に進む

名前解決が無効(skip-name-resolve オプションが有効)な場合、上記 1、2、3 のフェーズがスキップされ、4 で検証される対象は IP アドレスのみとなります。
出典:gihyo.jp

Amazon RDS の名前解決無効化

Amazon RDS(MySQL)のデフォルトの設定では、名前解決が有効(skip-name-resolve オプションが無効)となっています。
名前解決を無効化するは、パラメータグループで skip-name-resolve オプションの値を「0」から「1」に変更します。
f:id:FriendsNow:20210124003648p:plain

参考書籍

以上

Amazon RDS(MySQL)構築手順について

Amazon RDS とは

Amazon RDS(Amazon Relational Database Service)とは、その名称のとおり AWS のリレーショナル型のデータベースです。
Amazon RDS では、データベースのインストールやバックアップなどのセットアップをしなくても、データベースが利用できる環境が提供されているため、契約後すぐに AWS 上でデータベースを使用することができます。
出典:NTT 東日本

リレーショナル型データベースとは

リレーショナル型データベース(関係性データベース)とは、行と列の2つの軸で表されるデータベースのことです。イメージとしては、高機能な Excel のようなものです。
データベースは、特定の条件に基づいて複数のデータを管理し、必要に応じて目的のデータを検索したり、編集を行ったりするために必須です。なかでもリレーショナル型データベースは、情報の整合性や管理の効率化に優れているという特徴があります。
以上のことからリレーショナル型データベースは、顧客リスト、商品一覧データ、従業員リストなど幅広い種類のデータ管理に適しています。
出典:NTT 東日本

MySQL 構築例

本例では、インターネットからの接続を想定した場合に、ポイントとなる部分を抜粋しています。他の設定値はデフォルトを使用しています。
「データベースの作成」をクリックします。
f:id:FriendsNow:20210123212407p:plain

「標準作成」➡「MySQL」をクリックします。
f:id:FriendsNow:20210123213321p:plain

インターネットから、データーベースに直接接続する場合、「パブリックアクセス可能」を「あり」に設定します。
f:id:FriendsNow:20210123214027p:plain

「データベースポート」を「3306」に設定します。
f:id:FriendsNow:20210123214114p:plain

「最初のデータベース名」を設定し、「データベースの作成」をクリックします。
f:id:FriendsNow:20210123214157p:plain

データーベース作成後、「接続とセキュリティ」➡「VPC セキュリティグループ」をクリックします。
※外部から接続する「エンドポイント」を控えておきます。
f:id:FriendsNow:20210123215328p:plain

「インバウンドルールを編集」から、許可するグローバル IP を設定します。本例では、インターネットに接続したテスト端末の IP を設定します。
f:id:FriendsNow:20210123214600p:plain
設定は、以上です。

接続テスト

テスト端末に MySQL Workbench をインストールし、「Hostname」に「エンドポイント」を設定して「OK」をクリックします。
f:id:FriendsNow:20210123220140p:plain

以下のように接続できます。
f:id:FriendsNow:20210123220315p:plain

Python の mysql.connector.connect でも接続をテストしてみます。

> vi mysql.py
conn = mysql.connector.connect(
    host='HOSTNAME',
    port='3306',
    user='admin',
    password='PASSWORD',
    database='labdb'
)

print(conn.is_connected())

conn.close()

以下のように接続できます。

> python3 mysql.py
True

参考書籍

以上

Web Application に GA4 を実装する

Firebase で作成した Web Application に GA4(Google Analytics 4)を適用する手順について、ちょっとハマってしまったのでメモです。
Firebase web code lab で作成した Web アプリケーションに、以下のように、Index.html に SDK を読み込むように設定したのですが、機能しませんでした。*1

<!-- Import and configure the Firebase SDK -->
<!-- These scripts are made available when the app is served or deployed on Firebase Hosting -->
<!-- If you do not want to serve/host your project using Firebase Hosting see https://firebase.google.com/docs/web/setup -->
<script src="/__/firebase/8.2.1/firebase-analytics.js"></script>
<script src="/__/firebase/init.js"></script>
<script src="scripts/main.js"></script>

調べたところ、以下の記事に答えがありました。ありがとうございます。

【重要】アップデートされたGoogle Analytics 4にはトラッキングIDが存在しない【2020年10月以降ブログを始める方は要注意】
出典:静かに暮らしたい

Google Analytics 4 にイベントデータを送信するための API(gtag.js)を <head> の先頭に埋め込む必要があるようです。
f:id:FriendsNow:20210116175124p:plain

詳細は以下をご参照ください。
developers.google.com

以上

*1:設定は、こちらを参考にしました。

Firebase web codelab について

はじめに

Firebase でチャットアプリを作成するチュートリアル(Firebase web codelab)を試してみました。
チュートリアルでは、以下のことが学べます。

  • Cloud Firestore と Cloud Storage のデータ同期
  • Firebase Authentication のユーザー認証
  • Web アプリケーションのデプロイ
  • Firebase Cloud Messaging の通知送信
  • Web アプリケーションのパフォーマンスデータ収集

環境

・Firebase 8.2.1
・openSUSE Tumbleweed 20201229
・Virtual Machine:2vCPU, 4GB Memory, 40GB Disk
・VMware(R) Workstation 15 Pro

事前準備

root ユーザー移行

sudo su -

git インストール

zypper install git

npm インストール

zypper install npm

サンプルコードの入手

codelab のリポジトリを複製

git clone https://github.com/firebase/codelab-friendlychat-web

Firebase プロジェクト作成

Firebase にログインして、プロジェクトを作成します。
f:id:FriendsNow:20210101233700p:plain

Firebase Authentication の設定

ウェブアイコン をクリックして、Firebase Web アプリを作成します。
f:id:FriendsNow:20210101233914p:plain

左ペインの「Authentication」➡「Sign-in method」で「Google」をクリックして、有効化します。
f:id:FriendsNow:20210101235629p:plain

Google Cloud Console で OAuth 同意画面を設定します。*1
f:id:FriendsNow:20210102000111p:plain

Cloud Firestore の設定

左ペインの「Cloud FIrestore」から「データベース作成」をクリックして「テストモード」を有効化します。
f:id:FriendsNow:20210102000734p:plain

Firebase CLI インストール

CLI インストール

sudo su -
npm -g install firebase-tools

インストール確認

cd /home/hatkobelab/codelab-friendlychat-web/web-start/
firebase --version

Firebase CLI 承認

firebase login

※CLI をインストールした OS 上で実行する必要があります。それ以外の場合は、localhost に接続できずエラーとなります。本例では、以下のように openSUSE で実行しました。
f:id:FriendsNow:20210102001319p:plain

アプリと Firebase プロジェクトを紐づけ

firebase use --add
? Which project do you want to add? friendlychat-46e4f
? What alias do you want to use for this project? (e.g. staging) default

アプリをローカルで実行

アプリを実行

firebase serve --only hosting

※上述と同様に OS 上で実行します。

ブラウザから http://localhost:5000 に接続
f:id:FriendsNow:20210102001635p:plain
アプリの UI が接続されますが、認証がとおっていないため、まだ機能しません。

ユーザーサインイン設定

チュートリアルでは、Google サインインでユーザー認証するためのコードが用意されているので、対象の関数を置き換えます。ファイルは web-start/public/scripts/main.js です。

関数:signIn

// Signs-in Friendly Chat.
function signIn() {
  // Sign into Firebase using popup auth & Google as the identity provider.
  var provider = new firebase.auth.GoogleAuthProvider();
  firebase.auth().signInWithPopup(provider);
}

関数:signOut

// Signs-out of Friendly Chat.
function signOut() {
  // Sign out of Firebase.
  firebase.auth().signOut();
}

関数:initFirebaseAuth

// Initiate Firebase Auth.
function initFirebaseAuth() {
  // Listen to auth state changes.
  firebase.auth().onAuthStateChanged(authStateObserver);
}

関数:getProfilePicUrl

// Returns the signed-in user's profile pic URL.
function getProfilePicUrl() {
  return firebase.auth().currentUser.photoURL || '/images/profile_placeholder.png';
}

関数:getUserName

// Returns the signed-in user's display name.
function getUserName() {
  return firebase.auth().currentUser.displayName;
}

関数:isUserSignedIn

// Returns true if a user is signed-in.
function isUserSignedIn() {
  return !!firebase.auth().currentUser;
}

サインインのテストは、上述と同様に OS 上で実行します。

firebase serve --only hosting

以下のように Google でサインインができるようになります。
f:id:FriendsNow:20210102002202p:plain

メッセージの書き込み設定

アプリケーションの UI にデータ入力ができるように Cloud Firestore にデータを書き込みます。ユーザーが作成したメッセージは、Cloud Firestore に保存されます。
チュートリアルでは、ユーザーが「Send」ボタンをクリックすると、データベースに保存するコードが用意されているので、対象の関数を置き換えます。ファイルは web-start/public/scripts/main.js です。

関数:saveMessage

// Saves a new message to your Cloud Firestore database.
function saveMessage(messageText) {
  // Add a new message entry to the database.
  return firebase.firestore().collection('messages').add({
    name: getUserName(),
    text: messageText,
    profilePicUrl: getProfilePicUrl(),
    timestamp: firebase.firestore.FieldValue.serverTimestamp()
  }).catch(function(error) {
    console.error('Error writing new message to database', error);
  });
}

ブラウザから http://localhost:5000 に接続し「hello」などのメッセージを入力して「Send」ボタンをクリックすると、Firebase コンソールでメッセージを確認できます。
f:id:FriendsNow:20210102182214p:plain

メッセージの読み取り設定

アプリケーションでメッセージを読み取り、表示させます。
データベース内のメッセージが更新された際に、新しいメッセージをアプリケーションに表示させるように対象の関数を置き換えます。ファイルは web-start/public/scripts/main.js です。

関数:loadMessages

// Loads chat messages history and listens for upcoming ones.
function loadMessages() {
  // Create the query to load the last 12 messages and listen for new ones.
  var query = firebase.firestore()
                  .collection('messages')
                  .orderBy('timestamp', 'desc')
                  .limit(12);
  
  // Start listening to the query.
  query.onSnapshot(function(snapshot) {
    snapshot.docChanges().forEach(function(change) {
      if (change.type === 'removed') {
        deleteMessage(change.doc.id);
      } else {
        var message = change.doc.data();
        displayMessage(change.doc.id, message.timestamp, message.name,
                       message.text, message.profilePicUrl, message.imageUrl);
      }
    });
  });
}

画像送信設定

画像を共有する機能を追加します。
Cloud Firestore は、構造化データの保存に適していますが、Cloud Storage はファイルの保存に適しています。
ユーザーがアプリケーションを使用して共有する画像を Cloud Storage に保存するように対象の関数を置き換えます。ファイルは web-start/public/scripts/main.js です。

関数:saveImageMessage

// Saves a new message containing an image in Firebase.
// This first saves the image in Firebase storage.
function saveImageMessage(file) {
  // 1 - We add a message with a loading icon that will get updated with the shared image.
  firebase.firestore().collection('messages').add({
    name: getUserName(),
    imageUrl: LOADING_IMAGE_URL,
    profilePicUrl: getProfilePicUrl(),
    timestamp: firebase.firestore.FieldValue.serverTimestamp()
  }).then(function(messageRef) {
    // 2 - Upload the image to Cloud Storage.
    var filePath = firebase.auth().currentUser.uid + '/' + messageRef.id + '/' + file.name;
    return firebase.storage().ref(filePath).put(file).then(function(fileSnapshot) {
      // 3 - Generate a public URL for the file.
      return fileSnapshot.ref.getDownloadURL().then((url) => {
        // 4 - Update the chat message placeholder with the image's URL.
        return messageRef.update({
          imageUrl: url,
          storageUri: fileSnapshot.metadata.fullPath
        });
      });
    });
  }).catch(function(error) {
    console.error('There was an error uploading a file to Cloud Storage:', error);
  });
}

ブラウザから http://localhost:5000 に接続し「hello」などのメッセージを入力して「Send」ボタンをクリックすると、アプリケーションに表示されます。また、画像をアプリケーションにアップロードすることもできます。
f:id:FriendsNow:20210102221928p:plain

パフォーマンスデータ収集

Performance Monitoring SDK を使用して、アプリケーションからパフォーマンスデータを収集し、Firebase コンソールでデータの確認および分析ができます。

自動トレースの設定

アプリケーション利用時に自動的にパフォーマンスデータ監視を行うためには、main.js に以下を追加します。

// TODO: Initialize Firebase Performance Monitoring.
firebase.performance();

パフォーマンスデータの表示

Firebase コンソールからパフォーマンスデータを確認できます。通常は、この後の手順で実施するデプロイ後、12時間以内に表示されます。
f:id:FriendsNow:20210102223620p:plain

アプリケーションのデプロイ

Firebase Hosting を使用してアプリケーションを Firebase プロジェクトにデプロイします。
コマンドは以下を使用します。

> cd /home/hatkobelab/codelab-friendlychat-web/web-start/
> firebase deploy --except functions

デプロイ後、Firebase Hosting の URL(以下の2つの Firebase 独自サブドメイン)から、ウェブアプリケーションにアクセスできるようになります。

https://<firebase-projectId>.firebaseapp.com
https://<firebase-projectId>.web.app

f:id:FriendsNow:20210102225510p:plain

通知設定

Firebase Cloud Messaging を使用して、ウェブアプリに通知を配信することができます。

送信者 ID 許可

アプリケーション側で、通知を許可する送信 ID を設定する必要があります。 web-start/public/manifest.jsongcm_sender_id で設定します。※固定値で変更できません。

{
  "name": "Friendly Chat",
  "short_name": "Friendly Chat",
  "start_url": "/index.html",
  "display": "standalone",
  "orientation": "portrait",
  "gcm_sender_id": "103953800507"
}

Service Worker の追加

通知をアプリケーションに表示させるために必要な Service Worker を追加します。 web-start/public ディレクトリに irebase-messaging-sw.js という名前のファイルを作成して、以下のコンテンツを追加します。*2

// Import and configure the Firebase SDK
// These scripts are made available when the app is served or deployed on Firebase Hosting
// If you do not want to serve/host your project using Firebase Hosting see https://firebase.google.com/docs/web/setup
importScripts('/__/firebase/8.2.1/firebase-app.js');
importScripts('/__/firebase/8.2.1/firebase-messaging.js');
importScripts('/__/firebase/init.js');

firebase.messaging();

デバイストークンの取得

デバイスまたはブラウザで通知が有効になると、デバイストークンが提供されます。
ユーザーがサインインすると、ブラウザからデバイストークンを取得し、Cloud Firestore に保存するように設定します。ファイルは web-start/public/scripts/main.js です。

// Saves the messaging device token to the datastore.
function saveMessagingDeviceToken() {
  firebase.messaging().getToken().then(function(currentToken) {
    if (currentToken) {
      console.log('Got FCM device token:', currentToken);
      // Saving the Device Token to the datastore.
      firebase.firestore().collection('fcmTokens').doc(currentToken)
          .set({uid: firebase.auth().currentUser.uid});
    } else {
      // Need to request permissions to show notifications.
      requestNotificationsPermissions();
    }
  }).catch(function(error){
    console.error('Unable to get messaging token.', error);
  });
}

通知権限のリクエスト

ユーザーに通知許可を求めるダイアログをブラウザに表示させます。ユーザーで許可していない場合、デバイストークンは提供されません。

// Requests permission to show notifications.
function requestNotificationsPermissions() {
  console.log('Requesting notifications permission...');
  firebase.messaging().requestPermission().then(function() {
    // Notification permission granted.
    saveMessagingDeviceToken();
  }).catch(function(error) {
    console.error('Unable to get permission to notify.', error);
  });
}

サインイン後、通知許可ダイアログが表示されます。
f:id:FriendsNow:20210102234510p:plain
「許可」をクリックすると、ブラウザの JavaScript コンソールに次のメッセージが表示されます。

Got FCM device token: cWL6w:APA91bHP...4jDPL_A-wPP06GJp1OuekTaTZI5K2Tu

ブラウザに通知を送信

デバイストークンと、サーバーキーを設定し、次の cURL コマンドを実行します。
サーバーキーは、Firebase コンソール から「プロジェクトの概要」➡「プロジェクトを設定」➡「Cloud Messaging」 で確認できます。

curl -H "Content-Type: application/json" \
     -H "Authorization: key=YOUR_SERVER_KEY" \
     -d '{
           "notification": {
             "title": "New chat message!",
             "body": "There is a new message in FriendlyChat",
             "icon": "/images/profile_placeholder.png",
             "click_action": "http://localhost:5000"
           },
           "to": "YOUR_DEVICE_TOKEN"
         }' \
     https://fcm.googleapis.com/fcm/send

アプリケーションがバックグラウンドにある場合、次のようにブラウザに通知が表示されます。
f:id:FriendsNow:20210102235944p:plain

以上

*1:ロゴのアップロードが必須なので注意

*2:8.2.1 は Firebase のバージョンで最新化が必要です。最新のバージョンはこちら

Firebase について

Firebase とは

Google が提供しているモバイルおよび Web アプリケーションの BaaS(バックエンドサービス)
Firebase を使うことで、開発者はアプリケーションの開発に専念でき、バックエンドで動くサービスを作成・管理する必要がありません。

Firebase の機能

Firebase では主に以下の機能が提供されています。(2020年12月31日時点)
参考:株式会社トップゲート

Realtime Database

オブジェクト型のデータベースで、リアルタイムでクライアント全体の状態を同期します。

f:id:FriendsNow:20201231235159p:plain
出典:Md Munir Hossain – Medium

Cloud Firestore

Realtime Database の性能をさらに向上させたデータベース。 Realtime Database より高速でスケールアウトにも対応しています。Google は Realtime Database より Cloud Firestore を推奨していて、今後の主力となるデータベースのようです。

Cloud Storage for Firebase

写真や動画などバイナリーデータを保存します。保存先は Cloud Storage となっており、 Firebase と Google Cloud の両方からアクセスできます。

f:id:FriendsNow:20201231235226j:plain
出典:Md Munir Hossain – Medium

Firebase Authentication

Google のフェデレーション認証で、 Google, Facebook, Twitter などの認証情報を使用してクライアントアプリケーションにログインすることができます。
また、パスワード認証や電話番号認証にも対応しています。

f:id:FriendsNow:20201231235239p:plain
出典:Md Munir Hossain – Medium

Firebase Cloud Messaging(FCM)

様々なプラットホームで動いているアプリケーションに対してメッセージを送ることができます。

Google Cloud Functions for Firebase

イベントドリブンなアプリケーションを作成し SMS メッセージの送信処理のような外部サービス連携が可能となります。

Firebase Hosting

ウェブアプリ、静的コンテンツ、動的コンテンツなど、様々なコンテンツをホストします。

f:id:FriendsNow:20201231235318j:plain
出典:Md Munir Hossain – Medium

Firebase SDK

Firebase の主な機能(Realtime Database, Cloud Firestore, Firebase Hosting など)を使用できる SDK が提供されています。サポートされているプラットフォームには、 Android, iOS, Web, Unity, C++ などがあります。

以上

Google Cloud Shell のリセット手順

Cloud Shell とは

Google Cloud Shell は、debian ベースのオンライン bash シェルで、Web ブラウザ経由でアクセスできます。
無料利用枠で、$HOME ディレクトリに 5 GB の永続ディスク ストレージが提供されています。
インターネットと Web ブラウザがあれば、いつでもどこでも利用できるため、最近重宝しています。

リセット手順

Cloud Shell のホーム ディレクトリを空の状態に戻すには:
1. ホーム ディレクトリの個人ファイルを確認します。

ls -a $HOME

2. ホーム ディレクトリからすべてのファイルを削除します。

sudo rm -rf $HOME

3. Cloud Shell メニューで、その他メニュー アイコン、「Cloud Shell を再起動」の順にクリックします。

参考:Cloud Shell の無効化またはリセット

以上

openSUSE Tumbleweed で Cron 実行

openSUSE ソフトウェアで「cronie」を検索し、openSUSE Tumbleweed の「1クリックインストール」をクリックしてインストールします。
f:id:FriendsNow:20201228220810p:plain

crontab 設定

hostname:~# crontab -e 
# 30分毎に起動する
*/30 * * * * urlwatch

crontab 設定確認

hostname:~# crontab -l

crontab ステータス確認

hostname:~# systemctl status cron.service

crontab 実行確認

hostname:~# tail -f /var/spool/mail/[user_name] 

参考書籍

以上

openSUSE Tumbleweed インストール手順

openSUSE Tumbleweed 20201229 のざっくりしたインストール手順例です。
公式サイトから、DVD イメージをダウンロードし、イメージをマウント・実行します。
installation を選択します。
f:id:FriendsNow:20210209172739p:plain

言語/キーボード/ライセンスなど、基本的な設定は「次へ」をクリック
オンラインリポジトリは、必要なものが明確でなければ、デフォルトで OK です。
f:id:FriendsNow:20210209172835p:plain

システムの役割も特に指定がなければ、デフォルトで OK です。
f:id:FriendsNow:20210209172904p:plain

パーティションも同様です。
f:id:FriendsNow:20210209173121p:plain

タイムゾーンは「日本」で、「ハードウェアの時刻を UTC に設定する」にチェック
f:id:FriendsNow:20210209173133p:plain

ユーザーを設定します。
f:id:FriendsNow:20210209173203p:plain

設定内容を確認して「インストール」をクリックします。
f:id:FriendsNow:20210209173240p:plain

以上

オープンソースの WAF(ModSecurity)について

WAF とは

WAF は、ウェブアプリケーションの脆弱性を悪用した攻撃などからウェブアプリケーションを保護するソフトウェア、またはハードウェアです。
WAF を使用することで以下の効果を期待できます。

  • 脆弱性を悪用した攻撃からウェブアプリケーションを防御する。
  • 脆弱性を悪用した攻撃を検出する
  • 複数のウェブアプリケーションへの攻撃をまとめて防御する

また WAF は、検出パターンに基づき通信の中身を機械的に検査するため、実際に人の目で見る場合と異なる判定が生じる場合があります。この判定結果により、ウェブアプリケーションの脆弱性を悪用した攻撃などの悪意ある通信を遮断できない場合や、利用者がウェブサイトを閲覧する正常な通信を遮断してしまう場合があるため、導入時に考慮する必要があります。
出典:Web Application Firewall (WAF) 読本 改訂第2

ModSecurity とは

TrustWave 社が GPLv2 ライセンスのもと提供しているオープンソースの WAF です。
IPA で導入・運用を継続している実績があります。
出典: オープンソース WAF「ModSecurity」導入事例 ~ IPA はこう考えた ~

ModSecurity 構築例

本例では、以下の環境でテストします。

f:id:FriendsNow:20200329180205p:plain

また、本環境で対応する脆弱性は以下の 2 つのみとします。

  • XSS(クロスサイト・スクリプティング)
  • SQL インジェクション

Apache リバースプロキシ設定

以下をコメントアウト

[root@hostname ~]# vi /etc/httpd/conf/httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

以下を最終行に追加

[root@hostname ~]# vi /etc/httpd/conf/httpd.conf
ProxyRequests Off
ProxyPass /WebGoat http://10.1.23.253/WebGoat
ProxyPassReverse /WebGoat http://10.1.23.253/WebGoat
# 上記のように設定すると、例えば、 10.1.12.252/WebGoat のリクエストを http://10.1.23.253/WebGoat へ転送します。

ModSecurity インストール事前準備

EPEL リポジトリ追加

yum install epel-release

リポジトリ設定

[root@hostname ~]# vi /etc/yum.repos.d/epel.repo

# コメントイン
baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
# コメントアウト
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch

# コメントイン
baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug
# コメントアウト
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch

# コメントイン
baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS
# コメントアウト
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch

ModSecurity インストール

ModSecurity と CRS をインストール

[root@hostname ~]# yum --enablerepo=epel install -y mod_security mod_security_crs
[root@hostname ~]# service httpd restart

XSS と SQL インジェクションのルールのみ適用

[root@hostname ~]# vi /etc/httpd/conf.d/mod_security.conf

# コメントアウト
# Include modsecurity.d/activated_rules/*.conf
# 10~11 行目追加
Include modsecurity.d/activated_rules/modsecurity_crs_41_xss_attacks.conf
Include modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf

Apache 再起動

[root@hostname ~]# /etc/rc.d/init.d/httpd restart

WAF のテスト

ModSecurity 無効時

OWASP ZAP の動的スキャンを行うと、SQL インジェクションの脆弱性が見つかります。
※OWSAP ZAP については、こちらをご参照ください。
f:id:FriendsNow:20200329182250p:plain

ModSecurity 有効時

SQL インジェクションの脆弱性が検出されなくなりました。
f:id:FriendsNow:20200329181520p:plain

リアルタイムで診断状況を確認すると、ステータスコードが「Forbidden」となっていることが確認できます。
f:id:FriendsNow:20200329181052p:plain

参考: ModSecurity 無効化

一時的に無効化した場合は、以下の設定をします。

[root@hostname ~]# vi /etc/httpd/conf.d/mod_security.conf

# コメントアウト
#SecRuleEngine On
# 追加
SecRuleEngine Off

Apache 再起動

[root@hostname ~]# /etc/rc.d/init.d/httpd restart

参考書籍

以上

Internet Explorer 表示した PDF を保存できない

フォルダリダイレクトが有効になっている環境で、Internet Explorer 表示した PDF を保存しようとすると、以下のエラーが発生する場合があります。

保存しようとしたディスクまたは一時ファイルに使用するディスクがいっぱいです。このディスクの容量を空けてもう一度保存しなおすか、別のディスクに保存してください。

こちらによると、ディスク容量は問題なくても、Adobe Reader の保護モードの不具合が原因で発生する可能性があり、以下の手順で保護モードを無効にすると回避できるようです。

  1. 編集/環境設定を選択します。
  2. 左側の「分類」から、「セキュリティ(拡張)」を選択します。
  3. 「サンドボックスによる保護」領域で、「起動時に保護モードを有効にする」をオフにします。

helpx.adobe.com

なお、ドメイン管理下の PC は、GPO(レジストリ)を利用して一括で設定することも可能です。

キー:HKEY_CURRENT_USER\SOFTWARE\Adob<200b>e\Acrobat Reader\DC\Privledged
値:bProtectedMode
値のデータ:0

f:id:FriendsNow:20200704170040p:plain

以上

Horizon 7 に物理 PC に登録する方法

通常、Horizon に vCenter Server を登録し、vCenter 管理化の仮想 PC に VMware Horizo​​n View Agent をインストールすることで、Horizon に仮想 PC が(自動で)登録されますが、vCenter の管理化にない仮想 PC や、物理 PC を Horizon に登録することも可能です。
簡易検証環境等、vCenter をたてずに Horizon を検証する際に便利です。

対象の仮想 PC(または物理 PC)に Horizon View Agent をインストールする際、以下のオプションを付与してインストールします。

/v"VDM_VC_MANAGED_AGENT=0"

すると Horizon 接続サーバーを登録するボックスが表示されます。
f:id:FriendsNow:20200627234435p:plain

インストール完了後、View Administrator から仮想 PC を選択できるようになります。

以上

Apache の起動に失敗

Apache 2.2.15 でサービスを再起動した際、起動に失敗する事象に遭遇しました。

[root@hostname ~]# service httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中:                                            [失敗]

/var/log/httpd/error_log を確認すると以下のエラーが出力されていました。

 [alert] (EAI 2)Name or service not known: mod_unique_id: unable to find IPv4 address of "lablog01"
Configuration Failed

原因は、hostname と /etc/hosts が一致していないことのようです。

[root@hostname ~]# hostname
lablog01
[root@hostname ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

/etc/hosts に lablog01 を追加すると無事起動できました。

[root@hostname ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 lablog01
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

以上