2021年11月2日火曜日

heteml で設定した独自ドメインのメールを Gmailで差出人として利用する方法

手持ちのウェブサイトで heteml サーバーを試していたことに気づいて、実際にやって成功した設定を備忘録として残します。本設定は、2021年11月2日に確認しました。


STEP 1.  heteml のWebメールでメールを受信できることを確認する

ウェブメール:https://webmail.heteml.jp/

にログインして、自分自身にメールするなどして受信出来ることを確認してください。

これが出来ない場合には、ヘテムルに問い合わせてください。


STEP 2. 送信情報を取得する

メールソフトの設定方法(ヘテムル)

を参考に、

送信メールサーバーをチェックしてください。


STEP 3. Gmailに設定する

1. メールアドレスは、独自ドメインのメールアドレスを設定

2. SMTPサーバーは、STEP2でメモした送信サーバーを指定
ユーザー名:独自ドメインのメールアドレス
パスワード:STEP1で確認したWebメールのログインパスワード
ポート:465
暗号:SSL


3. 設定した独自ドメインメールアドレス宛に、確認メールが送信されます。ここにかかれた確認コードを入力します。



4. 設定した独自ドメインメールアドレス宛に、確認メールが送信されます。ここにかかれた確認コードを入力します。

下記のように設定が追加されていることを確認


2021年11月2日 @kimipooh

2021年7月5日月曜日

macOS版 Googleドライブアプリ - 複数アカウントに対応していた

 久しぶりに手持ちの Mac を再起動すると、Googleドライブアプリが刷新されて、下記のような画面が出てきました。無料版 Gmail のアカウントでも「ストリーミング」機能が使えるようになったのかぁという印象ですね。


機能比較

それはともかく本題はこちら。


複数アカウントでログインすると、各アカウントのドライブができる



macOS 版限定のようですが(手持ちの Windows10ではアカウント切り替えしかなかった)、Googleドライブアプリの設定から、アカウントの追加ができるようになっています。
試しに、2つのアカウント(Google Workspace と 無料版 Gmail)を設定すると、下図のように、メールアドレス - Google Drive のドライブがデスクトップに表示されます。


おっと!ドライブのフォルダ名が変わってしまったのか!と思ったのですが、


/Volumes を覗いてみると、最初に登録していたアカウントのほうは、 /Volumes/GoogleDrive とマウントされたドライブのアクセス先は変更していませんでした。いくつかシンボリックリンクをつかっているので、これは助かります。

2021年7月5日 @kimipooh

2021年4月12日月曜日

Redmineのサーバー移行(4.0→4.1.2)とGoogle認証プラグイン

サーバー移転したとき苦労したので、備忘録として残しておきます。

Redmime 利用しているGoogle認証プラグインは、「Redmine Omniauth Google plugin」に対して

の修正版を施したものです。こちらは、redmine 4.1.2 でも動作します。

移転先は、さくら VPS(CentOS Stream8)です。


関連情報


STEP 1. 新サーバーに Redmine 4.1.2 を新規導入


とても長い道のりがあります。
基本的には上記サイトの通りにセットアップするとよいです。
  1. DB: MariaDB 10.3.x
  2. Perl: perl 5.26
  3. Ruby :  2.6.x 
  4. Unicorn(自動起動)
  5. Nginx 1.18(非暗号, 自動起動)
ここまでうまくいけば、次に Let's Encrypt を使った常時SSLで redmine を動かしたいと思うはず。

STEP 2. 通知のためにメールサーバ(postfix)を導入しよう


Let's Encrypt の証明書通知のために、メールが送信できる環境が必要です。今回は他のメールサーバーを使わず、自前で完結することを想定しています。そのため postfix をインストールします。postfixをインストールしたなら、mailコマンドも使えるようにしておくとなにかと便利です。

dnf install postfix
dnf install mailx

上記2つコマンドで mailコマンドと postfixをインストールします。
今回は完全にローカルでしか使わないので、外部からの 25/tcp を許可する必要はありません。IPv4 のみで良い場合、下記のように inet_protocols を ipv4 にしておくとよいです。

/etc/postfix/main.cf を編集

inet_protocols = ipv4
myhostname = ホスト名(FQDN)
mydomain = ホスト名(FQDN)

上記3つを設定したら、

service postfix start
systemctl enable postfix

で自動起動しておけばよいです。
かりにホストが、hogehoge.example.com であるなら

echo test  | mail -s 'test'  自分のメールアドレス

として自分にメールしてみましょう。
たとえば root ユーザーで実行すると

root@hogehoge.example.com からメールが届くはずです。

また /etc/aliases を編集し
root: サーバーのシステム通知をうけるメールアドレス

をいれて
newaliases
にて、エイリアスデーターベースを更新しておきましょう。このあたりはサーバー管理の問題なので、詳細は割愛します。

STEP 3. Redmine を Let's Encrypt を使った常時SSL化してみよう



証明書発行に、certbot を利用する場合、

http://ホスト名(FQDN)

が外部からアクセスできる状況が必要です。実際には Let's Encrypt 側から http://ホスト名/.well-known/ 以下にアクセスができる必要があります。 

さくらVPSであれば、コントロールパネルのパケットフィルターから一時的に 80/tcp を外部から許可しましょう。なお 443/tcp (https://)については、IP制限をかけるなど限定接続可能なら、そのほうが安全です。

nginx の場合の Let's Encrpyt 設定方法

の設定が終わっているとします。

SSLサイト:https://hoge.sample.com 

とする場合、

https://hoge.sample.com/.well-known 以下に対するアクセス権限が必要です。常時SSLサイトにしているなら、上記フォルダ以外を https へ転送すればよいです。

server {
    listen 80;
    server_name hoge.sample.com;
 
    location /.well-known {
      root /var/www/certbot/;
    }
 
    location / {
      return 301 https://$host$request_uri;
    }
}

上記のように、http://hoge.sample.com/.well-known 専用の root ディレクトリを指定して、実際にそのディレクトリを作成してください。ここは certbot コマンドによって、一時的に証明書関連のデータが保存されます。実行完了後、データは削除されます。

また
/etc/letsencrypt/renewal/hoge.sample.com.conf の
[[webroot_map]]
hoge.sample.com = /var/www/certbot/

のように webroot_map を上記 http://hoge.sample.com/.well-known で指定したルートディレクトリにしておきましょう。

設定がうまくいっていれば、

/etc/cron.d/letsencrypt で設定されている コマンド
  • certbot renew --post-hook "systemctl restart nginx"
を実行して、うまく更新されていることを確認しましょう。

次に
を参考に nginx の設定を変更します。
 redmine 用の設定
/etc/nginx/conf.d/redmine.conf を上記リンク先にあるように編集します。

ただし、後ほどインストールする Google 認証プラグインのため、下記の赤部分を追加してください。これを追加することで redmine の back_url が http:// から https:// に切り替わってくれます。

    location @app {
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_connect_timeout 60;
        proxy_read_timeout 60;
        proxy_send_timeout 600;
        proxy_pass http://unicorn;
    }
    
これで、
https://ホスト名(FQDN)

としてアクセスできたら成功です。

STEP 4. Redmine データの移行


を参考に、元サーバーから
  1. files フォルダ
  2. themes フォルダ内の利用テーマフォルダ
  3. plugins フォルダ内の利用プラグインフォルダ
  4. redmine 用データベース
をバックアップしましょう。

新規インストールしたのと同じデータベース名(上記例だと redmine)にすると、
私の場合にはエラーがでたので
redmine2 など別のデータベースを作成して、そちらにインポートするのがよいと思います。

DBをインポートする、変更した場合にはその都度
redmine のトップフォルダで

bundle exec rails db:migrate RAILS_ENV=production
bundle exec rails redmine:plugins:migrate RAILS_ENV=production

をすること。

プラグインは個別に移行が必要かもしれないので、細かいところは省きます。
プラグインを出し入れした場合

redmine のトップフォルダで

bundle install
systemctl start redmine-unicorn
systemctl status redmine-unicorn

をしましょう。これで unicorn が fail になるようなら、そのプラグインが新しい redmine に対応していないことになります。それをフォルダから外すなりして、上記コマンドを実行しなおしてください。

files はそのまま入れ替えてください。

テーマ内の利用テーマフォルダもそのまま入れ替えてもいいですが、新しいバージョンが出ているなら更新することも検討すればよいです。

Google Developer Console にログインして、

https://ホスト名(FQDN)

を追加しておく必要があります。

今回ハマったのは、
  • proxy_set_header X-Forwarded-Proto $scheme;
の設定をいれていなくて

https://ホスト名(FQDN)/oauth_google?back_url=http%3A%2F%2Fホスト名(FQDN)%2F

のように back_urlが http なので、Google認証できないというものでした。

2021年7月2日 更新
2021年4月12日 @kimipooh

2021年3月2日火曜日

【macOS】Google Drive File Stream の対象ボリューム「Google Drive」を Spotlightの検索対象から外す

 普段はあまり気にしていないのですが、 macOS Big Sur にアップグレードしてから、手持ちの MacBookAir の動作が非常に遅くなったので、あれこれチェックしています。

その中でコンソールの system.log に

com.apple.xpc.launchd com.apple.mdworker.shared

に関連するエラーが短時間の間隔で大量にでているのに気が付きました。

こういうのを見てしまうと、気になるものです。

確かに、.Spotlight-V100というインデックスのためのフォルダができていますね。

いろいろ調べた結果、

にたどり着きました。
確かに .Spotlight-V100 というインデックス用の隠しフォルダがあるので、インデックスしているようにみえます。Google Driveはインデックス対象にしなくても https://drive.google.com から高速で検索できる仕組みが Googleにあるので、マシンパワーの無駄遣いです。

そのため、Google Drive File Stream(現行 Google Driveアプリ)がマウントする Google Drive (Google Workspace専用)ボリュームについては、Spotlight のインデックス対象から外しました。

すると、まだ時々の間隔でエラーは出るようですが、その間隔は時々になりました。

などのように、同じ問題に遭遇した人もいるみたいですね。

これで少しはパフォーマンスがよくなることを祈ります。

2021年3月2日 @kimipooh

2021年1月30日土曜日

【まめ知識】PC版Gmailにアクセスする(iOS編) 2021年度(Safari編)

 過去何度か、iPhone で PC版 Gmailを表示する方法を検証してブログに記事を書いてきました。しかし、現時点でいずれも使えなくなっています。

使えなくなった情報

【備忘録】iPhone (iOS) で Gmail を標準表示(2020年12月時点で使えず)

【まめ知識】PC版Gmailにアクセスする(iOS編)(2014年1月まで)

2021年1月30日時点で Safariを使った方法に成功したので、書き下しておきます。
ただ、またいつ使えなくなるか分かりません。

検証環境

iPhone 11 Pro

iOS 14.3

Safariブラウザを利用を利用して PC版Gmailにアクセスする

1. Gmail(https://gmail.com) にアクセスし、ログインする

2. 左上にある 三 をタップして一番下にスクロールします。

3. 下図の Gmailを次の UIで表示より「デスクトップ」のリンクをタップします。


4. 下図のように表示されるので「最新の Gmailを使用」をタップ


5. モバイル版 Gmailが表示されるので、アドレスバーの「ぁあ」をタップして、「デスクトップ用Webサイトを表示」をタップする


6. うまくいけば、 下図のように PC版 Gmailを表示することができます!


2021年1月30日 @kimipooh

2020年11月24日火曜日

Googleフォームのファイルアップロードデータを抽出し、ファイル名を変更して特定フォルダに一括保存する(Google Apps Script)

 Google フォームのファイルアップロードを使ってアップロードされたファイルは、下図のように、「ファイル名 - 名前(Googleアカウントのプロフィール).ファイルの拡張子」という名前になります。


しかしながら、
  1. 申請する人が、代理かもしれない
  2. いつ申請したかファイル名だけでは判別しづらい
という問題があり、ファイル名について

年-月-日_登録者名_ファイル名 - 申請者名(Googleアカウントのプロフィール).ファイルの拡張子

のように、ファイル名の目視だけでもう少しはっきりとわかるようにできたら便利です。
下図はその例です。
  • 登録者名1:テスト2
    • 3ファイル:test1.xlsx, test2.xlsx, test3.xlsx
  • 登録者名2:ほげほげ
    • 1ファイル: test.xlsx
これを、Google Apps Script で実装してみます。
ただし説明を容易にするために、極めてシンプルな構造にしています。

STEP 1. Googleフォームを作成する



今回は例のため、項目は2つ(名前、ファイルアップロード)にしています。メールアドレスの収集なども行いません。ただし、ファイルアップロードは、申請者の Googleアカウントのマイドライブ直下に一旦アップロードする手法になるため、Googleアカウントのログインが必須になります。

作成し終わったら、「回答」タブにある、「スプレットシートの作成」ボタンをクリックし、回答内容を Googleスプレットシートに保存できるようにします。



STEP 2. 一括保存するフォルダを作成


Googleドライブ内に、フォルダを作成します。
ここではサンプルとして、Googleフォームを作成したフォルダ直下に「Attached Documents」というフォルダを作成します。



STEP 3. Google Apps Script を用意する


回答先 Googleスプレットシートを開き、ツールメニューから「スクリプトエディタ」を開きます。


すると上図のようなサンプルコードが出てきます。
これらのコードはすべて削除した上で、下記のリンク先を開いて出てきたテキストを「すべて選択」しコピー、上記コードにペーストしてください。
すると、下図のようになるはずです。

次に Google Apps Scriptのプロジェクトを保存してファイル名をつけてください。
ここでは getAttachedDocuments という名前にします。


次に必要な4つのパラメーターの設定を行います。



OUTPUT_FOLDER_ID


一括出力先フォルダ(例だと、Attached Documents)のフォルダID(下図の赤枠)を調べてコピーし、


それを、Google Apps Script の === FOLDER ID === と置き換えます。

実際のコードは下記の通り
  • var OUTPUT_FOLDER_ID = '=== FOLDER ID ==='; 

INPUT_SpreadSheet_ID


Googleフォームの回答先 GoogleスプレットシートのIDを調べて、コピーし、


それを、Google Apps Script の === Google SpreadSheet ID === と置き換えます。

実際のコードは下記の通り
    •   var INPUT_SpreadSheet_ID ='=== Google SpreadSheet ID ===';
      

    INPUT_SpreadSheet_num


    アップロードされたファイルのURLされている項目の項目番号を調べます。
    今回の場合、項目番号は 0から始まり、A列 = 0、B列 = 1、、、と続きます。

    今回の例は、入力項目は「名前」「ファイルアップロード」の2つです。
    Googleフォームが最初に入力された時刻を自動保存(タイムスタンプ)を保存するため、
    • A列(項目番号 0) = タイムスタンプ
    • B列(項目番号 1) = 名前
    • C列(項目番号 2) = ファイルアップロード(URL、複数の場合にはコンマ区切り)
    となっています。

    そのためファイルアップロードのための項目番号は 2となり
    • var INPUT_SpreadSheet_num = 2; // Item of Attached File Link (start is 0)
    のように値を 2 に置き換えます。

    OUTOUT_FOLDER_name_num


    最終的に下記のファイル名になりますが、このうち「名前」(登録者名)にあたる項目番号を調べます。
    • 年-月-日_登録者名_ファイル名 - 申請者名(Googleアカウントのプロフィール).ファイルの拡張子

    今回の項目番号は 1 となります。
    • A列(項目番号 0) = タイムスタンプ
    • B列(項目番号 1) = 名前
    • C列(項目番号 2) = ファイルアップロード(URL、複数の場合にはコンマ区切り)
    したがって、値を 1 に置き換えます。
    •   var OUTOUT_FOLDER_name_num = 1; // Item of Name (start is 0)

    そしてプロジェクトを保存します。

    STEP 4. 作成した Google Apps Scriptを実行してみる

    まずはいくつかテスト的にフォームに入力します。

    今回のテスト例は下記のようになります。
    申請者のGoogleアカウントプロフィール名(Kimiya Kitani)
    • 登録者名1:テスト2
      • 3ファイル:test1.xlsx, test2.xlsx, test3.xlsx
    • 登録者名2:ほげほげ
      • 1ファイル: test.xlsx

    Google Apps Scirpt(ここでは getAttachedDocumentsで保存)の▶(実行)ボタンをクリックします。
    • 最初の1度だけ後述する許可設定が必要です。
      *Goolge Workspace や G Suite for Education アカウントの場合には、この許可設定を聞いてこないことがあるかもしれません。
    うまくいけば、Attached Documents フォルダ内に、下記のように意図したファイル名になっていると思います。
    いろいろカスタムしたい場合には、
    をダウンロードして、適当に自由に改変してみればよいでしょう。

    許可設定


    1. 「許可を確認」ボタンをクリック

    2. Google Apps Scriptを作成した Googleアカウントを選択


    3. 「詳細」リンクをクリックし、getAttachedDocuments(安全ではないページ)に移動リンクをクリック



    4. getAttachedDocuments に対して必要な権限を許可します。



    2020年11月24日 @kimipooh

    2020年8月28日金曜日

    【検証】Googleグループのメールアドレスを変更し、さらに元の名前に戻せるのか

     Googleグループは、無料版と G Suiteクラウドサービス版があります。それぞれどうなるか試してみます。


    無料版 Googleグループの場合


    古いUIのGoogleグループの場合、グループ名の変更(すなわちメーリングリストのアドレス変更)が可能です。検証の結果、古いグループは削除され、新規取得可能になっています。

    変更前:cseas-tech 

    変更後:cseas-tech2 

    変更自体は問題なくできました。


    Googleドライブの共有


    cseas-tech → cseas-tech2 へ自動変更されていました。


    変更前のGoogleグループは?


    存在しなくなっていました。Web版 Googleグループへのアクセスも「存在しません」となりました。

    Googleグループのアドレスをもとに戻せるか?


    戻せませんでした。
    cseas-tech2 → cseas-tech に名称変更しようとすると、「このグループのメールはすでに使用されています」と出ます。

    変更前のアドレスで Googleグループを「新規」作成できるのか?


    できてしまいました。
    名称変更ではすでに使用されているとでているのに、新規作成できたということは、なにか表示にバグがあるのかなぁと思います。名称を変更した時点で、前のアドレスは存在しなくなったと考えるのが妥当なためです。 



    ただバグだと思われますが、奇妙な事が起こりました。
    新しく作成した cseas-tech について、古い Googleグループの管理UIでは問題ないのに、新しいUIでは、なんと cseas-tech2 だと誤認識してしまっているのです。
    実際のメンバーやグループ名は区別できるようにしているので、 新規作成した cseas-tech であるのは間違いありません。また cseas-tech2 に変更した方は、新旧UIでちゃんと認識しているので、表記のバグだろうなぁとは思います。もしかしたら新しいUIではしばらくキャッシュに残ってしまうのかもしれませんね。




    G Suite の Googleグループの場合


    基本的な動作は無料版 Googleグループと同じでした。
    しかし、次の点で異なります。
    • 変更前のアドレスがエイリアスとして追加されている
    hogehoge @ 独自ドメイン → hogehoge2 @ 独自ドメイン
    に変更した場合

    メインアドレス:hogehoge2 @ 独自ドメイン
    エイリアス:hogehoge @ 独自ドメイン

    となってどちらにも届くということです。
    エイリアスは、G Suiteの特権管理者によって削除できます。
    しかし、もしドメインエイリアスを使っている場合には、そのアドレスは削除できません。

    ドメインエイリアス: hohoho.独自ドメイン

    だとするなら
    メインアドレス:hogehoge2 @ 独自ドメイン
    エイリアス:
     hogehoge @ 独自ドメイン(削除可能)
     hogehoge @ hohoho.独自ドメイン(削除不可)

    となるわけです。まぁドメインエイリアスのアドレスを使っていないのなら無視できる問題ではあります。

    もとのアドレスに戻した場合


    hogehoge2 @ 独自ドメイン → hogehoge @ 独自ドメイン

    と戻した場合
    メインアドレス:hogehoge @ 独自ドメイン
    エイリアス:hogehoge2 @ 独自ドメイン(削除可能)

    となります。
    ドメインエイリアス(hohoho.独自ドメイン)があるなら、

    メインアドレス:hogehoge @ 独自ドメイン
    エイリアス:
     hogehoge2 @ 独自ドメイン(削除可能)
     hogehoge2 @ hohoho.独自ドメイン(削除不可)
     hogehoge @ hohoho.独自ドメイン(削除不可)

    とまぁエイリアスが残っていくわけです。
    これは、hogehoge2 @ 独自ドメインのGoogleグループを新たにとったとしても、変化がありません(hogehoge @ 独自ドメインの方に、hogehoge2 @ hohoho.独自ドメイン が付与されたまま変更不可になってしまう)。これは少し厄介かもしれませんね。現状操作できる範囲でみると、これを解消するには一旦グループを削除して作り直す必要がありそうです。

    2020年8月28日 @kimipooh