NextCloud設定画面のセキュリティ&セットアップ警告に対応する

NextCloudでWEBストレージサービスを自前で作成する」でNextCloudのDocker環境を構築しましたが、そのままだと設定→概要でセキュリティ警告が表示されています。消せる警告は消していきたいと思います。

信頼できるプロキシーの設定

docker-compose.ymlにTRUSTED_PROXIESとOVERWRITEHOSTを追加します。

services:
  nextcloud:
    ...
    environment:
      ...
      - TRUSTED_PROXIES=127.0.0.1
      - OVERWRITEHOST=next.code-lab.net
      - OVERWRITEPROTOCOL=https
      ...

以下のコマンドを実行して設定を反映します。

sudo docker-compose up -d

「リバースプロキシヘッダーの構成が正しくないか、信頼できるプロキシからNextcloudにアクセスしています。そうでない場合、これはセキュリティに問題があり、攻撃者がNextcloudを表示できるようにIPアドレスを偽装することができます。詳細については、ドキュメント↗をご覧ください。」の警告が消えて居ることを確認して下さい。

Strict-Transport-Securityの設定

リバースプロキシサーバーにはNginxを使用しているので、/etc/nginx/sites-available/next.code-lab.net.confを編集して「add_header Strict-Transport-Security ‘max-age=15552000; includeSubDomains; preload’;」を追加します。

server {
    ...
    add_header Strict-Transport-Security 'max-age=15552000; includeSubDomains; preload';
    ...
}

以下のコマンドを実行して設定を反映します。

sudo service nginx restart

「Strict-Transport-Security “HTTP ヘッダーの秒数が少なくとも”15552000” に設定されていません。セキュリティを強化するには、セキュリティのヒント↗で説明されているようにHSTSを有効にすることをお勧めします。」 の警告が消えて居ることを確認して下さい。

default_phone_regionの設定

./html/config/config.phpを編集してdefault_phone_regionを追加します。残念ながらDockerの環境変数から指定する事はできないようです。

<?php
$CONFIG = array (
 ...
 'default_phone_region' => 'JP',
 ...
);

以下のコマンドを実行して設定を反映します。

sudo docker-compose restart

「ご使用のシステムには、デフォルトの電話地域が設定されていません。これは、国コードなしでプロファイル設定の電話番号を検証するために必要です。国コードなしで番号を許可するには、地域のそれぞれの ISO3166-1コード↗とともに “default_phone_region” を設定ファイルに追加してください。」 の警告が消えて居ることを確認して下さい。

DBにインデックスを作成する

以下のコマンドを実行します。

$ sudo docker-compose exec --user www-data nextcloud php occ db:add-missing-indices
Check indices of the share table.
Check indices of the filecache table.
Adding additional size index to the filecache table, this can take some time...
Filecache table updated successfully.
Adding additional path index to the filecache table, this can take some time...
Filecache table updated successfully.
Check indices of the twofactor_providers table.
Check indices of the login_flow_v2 table.
Check indices of the whats_new table.
Check indices of the cards table.
Check indices of the cards_properties table.
Check indices of the calendarobjects_props table.
Check indices of the schedulingobjects table.
Check indices of the oc_properties table.

「データベースにいくつかのインデックスがありません。~」 の警告が消えて居ることを確認して下さい。

「php-imagickモジュールはSVGをサポートしていません。」の警告が残っています。Dockerイメージを更新すれば良さそうですが、メリットが薄そうなのでこの警告は容認する事とします。

Nextcloudにアップロードできるファイルサイズ上限を増やす

デフォルトの設定のままだと512MBを超えるファイルサイズを扱うことが出来ません。以下の設定を変更してアップロードできるファイルサイズの上限を変更します。

Nginxの.confにclient_max_body_size 51200M;を追加します。

 server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ...
    client_max_body_size 51200M;
    ...
}

以下の通りdocker-compose.ymlにPHP_MEMORY_LIMIT=512MとPHP_UPLOAD_LIMIT=51200Mを追加します。

version: '3'

volumes:
  nextcloud:
  nextcloud-db:

services:
  nextcloud-db:
    image: mariadb
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
    restart: always
    ports:
      - 3307:3306
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${ENV_MYSQL_ROOT_PASSWORD}
      - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  nextcloud:
    image: nextcloud
    ports:
      - 8081:80
    links:
      - nextcloud-db
    volumes:
      - ./html:/var/www/html
    restart: always
    environment:
      - NEXTCLOUD_TRUSTED_DOMAINS='next.code-lab.net'
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
      - MYSQL_HOST=nextcloud-db:3306
      - OBJECTSTORE_S3_HOST=ewr1.vultrobjects.com
      - OBJECTSTORE_S3_BUCKET=nextcloud-root
      - OBJECTSTORE_S3_KEY=S3_KEY
      - OBJECTSTORE_S3_SECRET=S3_SECRET
      - OBJECTSTORE_S3_PORT=443
      - OBJECTSTORE_S3_SSL=true
      - OVERWRITEPROTOCOL=https
      - PHP_MEMORY_LIMIT=512M
      - PHP_UPLOAD_LIMIT=51200M

NginxとDockerコンポーネントを再起動します。

sudo service nginx restart
sudo docker-compose stop
duso docker-compose up -d

その後にNextcloud上で設定→システムを参照すると以下の様に最大アップロードサイズが大きくなっているかと思います。

NextCloudでWEBストレージサービスを自前で作成するよ

リモートワークや非PPAP対応のために、WEBストレージサービスが使われることが増えています。でもWEBストレージサービスの多くはユーザーライセンス方式・・・消費する容量が少なくとも、使用頻度が低くとも、ユーザー数が増えるとライセンス料がかさんでしまいます。そこでオープンソースのNextCloudを活用して時前のWEBストレージサービスを構築することを考えてみます。

NextCloudのインストール

NextCloudをインストールする方法はいくつかあります。AWSにはNextCloud公式のAMIファイル(355428426254/Nextcloud-21.0.1-RHEL8-ja_JP)があるので、これを使っても容易にサーバーを作ることが出来ます。

今回は運用の容易さを考えてNextCloud公式のDocker Image(https://hub.docker.com/_/nextcloud)を使って構築したいと思います。DockerおよびDocker-Composeが動作する環境を構築するところは割愛します。

NextCloudにアップロードしたファイルはプライマリストレージ(通常は”./html/data”)に保存されます。今回はストレージコストを抑えるために、プライマリストレージにはAWS S3を指定することにします。

docker-compose.ymlを用意します。

version: '3'

volumes:
  nextcloud:
  nextcloud-db:

services:
  nextcloud-db:
    image: mariadb
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
    restart: always
    ports:
      - 3306:3306
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${ENV_MYSQL_ROOT_PASSWORD}
      - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  nextcloud:
    image: nextcloud
    ports:
      - 8081:80
    links:
      - nextcloud-db
    volumes:
      - ./html:/var/www/html
    restart: always
    environment:
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
      - MYSQL_HOST=nextcloud-db:3306
      - OBJECTSTORE_S3_HOST=s3.region.amazonaws.com
      - OBJECTSTORE_S3_BUCKET=bucketname
      - OBJECTSTORE_S3_KEY=[accesskey]
      - OBJECTSTORE_S3_SECRET=[secretkey]
      - OBJECTSTORE_S3_PORT=443
      - OBJECTSTORE_S3_SSL=true
      - OVERWRITEPROTOCOL=https

.envファイルを用意します。

# docker-compose内で利用する環境変数をここで設定します。
# 下記2つの環境変数に、適当な文字列を設定してください。
ENV_MYSQL_ROOT_PASSWORD=root_password
ENV_MYSQL_PASSWORD=user_password

nginxでリバースプロキシを構成すためのconfファイル(/etc/nginx/sites-available/next.example.net.conf)を作成します。

server {
    listen 80;
    listen [::]:80;

    server_name next.example.net;
    return 301 https://$host$request_uri;
 }

 server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/next.example.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/next.example.net/privkey.pem;

    server_name next.example.net;

    client_max_body_size 20M;
    client_header_buffer_size 64k;
    large_client_header_buffers 4 64k;

    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-Proto  https;
    proxy_set_header    X-Forwarded-Host   $host;
    proxy_set_header    X-Forwarded-Server $host;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

    proxy_redirect      off;
    proxy_connect_timeout       3600;
    proxy_send_timeout          3600;
    proxy_read_timeout          3600;
    send_timeout                3600;

    location / {
        proxy_pass    http://localhost:8081/;
    }

    location /.well-known/carddav {
        return 301 $scheme://$host/remote.php/dav;
    }

    location /.well-known/caldav {
        return 301 $scheme://$host/remote.php/dav;
    }
}

以上、必要な設定の記述が終わりましたので、以下のコマンドを実行して起動します。

# sites-enabledにシンボリックリンクを作成
sudo ln -s /etc/nginx/sites-available/next.example.com /etc/nginx/sites-enabled/next.example.com
# nginxサービスを再起動
sudo service nginx restart
# dockerを起動
sudo docker-compose up

WEBブラウザでhttps://next.example.net/を開きます。

以下の画面で監理者アカウントのユーザー名とパスワードを指定しして「セットアップを完了します」をクリックしてください。しばらく待つと初期設定が終わり、NextCloudにログインできます。

NextCloudの基本的な初期設定

メールサーバーの指定

右上の○アイコンからメニューを開き設定を選択します。最初に個人情報タブのメールを設定しておきます。ここを設定しておかないとSMTPサーバーの設定をできません。

続いて基本設定タブを選択します。メールサーバーの設定を行います。

多要素認証の設定

右上の○アイコンからメニューを開き アプリを選択します。セキュリティタブから’OpenOTP Two Factor Authentication’と’Two-Factor Email’をダウンロードして有効にします。

これで設定のセキュリティタブに二要素認証の項目が追加されます。

Enabled Two Factor Emailをクリックすると認証用のメールが届きますので、認証コードを入力します。

TOTPの有効化のチェックをするとQRコードが表示されるので、TOTPに対応したGoogle Authenticater等のアプリでQRコードを読み取り、ワンタイムパスワードを入力して認証します。

外部ストレージの有効化

NextCloud上にアップロードしたファイルは’urn:oid:100’といったファイル名に保管されます。これらのファイルは NextCloud 上で無ければ確認する事ができません。これに対して外部ストレージのファイルは、画面上に表示されているファイル名そのままで保存されています。

外部ストレージ上のファイルはNextCloud以外からも読み書き出来ます。既存NASからのデータ移行や、NextCloud以外のシステムとの連携など、便利に使用する事ができます。ユーザー単位やユーザーグループ単位でアクセス制限をかける事が出来るので、部署単位での共有フォルダなども外部ストレージを使用すると便利です。

外部ストレージを使用するにはメニューからアプリを選択して無効なアプリタブにある’External storage support’を有効にします。その後、メニューから設定を開くと外部ストレージタブが追加されています。

上記では標準共有という名称でS3のバケットに接続しています。

Power Autoamte Desktopを導入

遅ればせながらPower Automate Desktop(以下PAD)を導入。

以前はPowershell + UIAutomation.dllでデスクトップアプリケーションの自動化を行っていた。同じ処理をPADで再実装してみたが、実装にかかる作業時間が1/5程度になっている感じでありがたい。Powershell + UIAutomation.dllで記述したときには画面が表示されるのを待つためのループ処理やディレイ処理が多く遅かったのだが、PADで記述したことでディレイ処理は1箇所のみに減り、大幅に早くなっている。

ただしいくつか気になる点もある。

1.複数のMicrosoftアカウントをWindowsに関連付けていると動作しない。実行時例外が発生して「The cache contains multiple tokens satisfying the requirements. Try to clear token cache.」となってしまう。あまり使わない方のMicrosoftアカウントの連携を解除して解決した。

2.圧縮→ZIPファイルが日本語ファイル名に対応しておらず、文字化けしてしまう。OSSのUnZip(http://infozip.sourceforge.net/UnZip.html)を子プロセスとして呼ぶことで対応した。

3.コードの見にくさ。WEB上のMicrosoft Flowも何度か使ってみた事はあるのだが、一画面に20ステップ程度しか表示出来ないので、やはり複雑な処理は書きにくい。

4.バグを見つけたのでレポートしたいが、お手軽なバグレポートツールが見当たらない。ヘルプ辺りにレポートメニューがあると有り難いのだが。

総じてデスクトップアプリの自動化を行うツールとして、無償でここまで扱いやすいツールは他に無く、とてもよいと思う。だがWEBアプリ操作やファイル処理を行おうとすると、なかなか厳しい。その辺りは適材適所、SeleniumやVBAを併用する事は続きそうだ。

Active Directory環境でDHCPを使用する。

Active Directory環境でDHCPを使用する場合には、DHCPサーバとADサーバとの間で信頼関係を結び、ADサーバ上のDNSに登録されているクライアントPCのIPアドレスを更新する必要があります。

ADサーバーとの間で認証する都合上、必然的に使用できるDHCPサーバーは限られます。LinuxとSMBを使っても出来るはずですが、実際に構築したという情報も少なく面倒そうです。

DHCP自体は負荷の高いサービスでは無いので、ADサーバーとDHCPサーバーを兼ねるのが良さそうです。各ネットワークセグメントにDHCP Relayサーバーを配置して、中央のADサーバにDHCPの問合せを送ります。

参考:More about authorizing DHCP servers in AD DS

Server 2003/2008からP2Vで仮想化したときにブルースクリーン(0x0000007B)が発生する。

Windows Server 2003やWindows Server 2008の環境でP2Vツールを使用して物理サーバーから仮想環境(Hyper-V等)に移行した場合に、OSの起動時にブルスクリーンが発生して0x0000007Bのエラーが発生する場合がある。これは元の物理サーバーの環境でRAIDやSCSIを使用していたために、標準のSATA関係のドライバが組み込まれていないことに原因があります。

C:\Windows\System32\に以下のドライバが無い場合には、正常な環境から複製してください。

C:\windows\system32\drivers\intelide.sys
C:\windows\system32\drivers\pciide.sys
C:\windows\system32\drivers\atapi.sys

ドライバを読み込ませるために、以下のレジストリエントリが無い場合には作成してください。

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#ven_8086&dev_7111
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#ven_8086&dev_7110&cc_0601
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\primary_ide_channel
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\secondary_ide_channel
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IntelIde
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\PCIIde
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\atapi

設定すべき値は以下を参照してください。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#ven_8086&dev_7111]
"Service"="intelide"
"ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\pci#ven_8086&dev_7110&cc_0601]
"ClassGUID"="{4D36E97D-E325-11CE-BFC1-08002BE10318}"
"Service"="isapnp"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\primary_ide_channel]
"Service"="atapi"
"ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\CriticalDeviceDatabase\secondary_ide_channel]
"Service"="atapi"
"ClassGUID"="{4D36E96A-E325-11CE-BFC1-08002BE10318}"

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IntelIde]
"ErrorControl"=dword:00000001
"Group"="System Bus Extender"
"Start"=dword:00000000
"Tag"=dword:00000004
"Type"=dword:00000001
"ImagePath"=hex(2):73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,44,00,\
  52,00,49,00,56,00,45,00,52,00,53,00,5c,00,69,00,6e,00,74,00,65,00,6c,00,69,\
  00,64,00,65,00,2e,00,73,00,79,00,73,00,00,00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\IntelIde]
"ErrorControl"=dword:00000001
"Group"="System Bus Extender"
"Start"=dword:00000000
"Tag"=dword:00000004
"Type"=dword:00000001
"ImagePath"=hex(2):73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,44,00,\
  52,00,49,00,56,00,45,00,52,00,53,00,5c,00,69,00,6e,00,74,00,65,00,6c,00,69,\
  00,64,00,65,00,2e,00,73,00,79,00,73,00,00,00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\atapi]
"ErrorControl"=dword:00000001
"Group"="SCSI miniport"
"Start"=dword:00000000
"Tag"=dword:00000019
"Type"=dword:00000001
"DisplayName"="標準 IDE/ESDI ハード ディスク コントローラ"
"ImagePath"=hex(2):73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,44,00,\
  52,00,49,00,56,00,45,00,52,00,53,00,5c,00,61,00,74,00,61,00,70,00,69,00,2e,\
  00,73,00,79,00,73,00,00,00

P2Vで仮想化する前の元の環境で設定を変更できれば良いのですが、それが出来ない場合には仮想ディスクファイル(*.VHD)をマウントして編集します。レジストリを編集するにはレジストリエディタを起動し”ファイル→ハイプの読み込み”から、マウントした仮想ディスクの”\windows\system32\config\system”を開きます。

参考:P2V Migration Issues with Hyper-V: STOP: 0x0000007B

「対象のパスが長すぎます」のエラーが出てファイルを操作できないとき。

「対象のパスが長すぎます」のエラーが出てエクスプーラー上からファイルを削除する事が出来なくなったとき、コマンドプロンプトからファイル名の先頭に\\?\を付けてDELコマンドで削除すると良い。

DEL \\.\C:\Users\hogehoge\Desktop\abc長いファイル名xyz.txt

Windowsは本来なら32768文字までのファイル名を扱うことが出来る。しかし古いアプリケーションとの互換性を維持するために、普段使用できるファイル名は260文字までに制限している。先頭の\\.\は互換性のための制限を解除する指示に当たる。

SharpZipLibの日本語対応

SharpZipLib 1.2.0以前でtarファイルを作成すると日本語が文字化けしていたけど、何時の間にか日本語に対応していたんですね。TarOutputStreamのConstructorでEncodingを指定できるではないですか。

github(https://github.com/icsharpcode/SharpZipLib)から最新のソースコードをダウンロードしてきて、自らビルドしましょう。

WevDAV上のExcelファイルを更新すると”アップロードできませんでした この場所の保存内容をアップロードするには、サインインする必要があります。”のエラーになる

QNAPのNASの機能を使ってWevDAVの共有フォルダを作成しました。共有フォルダ上のファイルををOffice 2016で開くとファイル更新時に「アップロードできませんでした この場所の保存内容をアップロードするには、サインインする必要があります。」と言うエラーが発生します。調べたところなかなか根の深い問題で、どうにもMicrosoft Officeアップローダーの仕様上の問題に起因するようです。

ちなみにWevDAV共有フォルダ上のファイルをエクスプローラーで操作したり、Office以外のアプリケーションから読み書きする場合には問題がありません。

Microsoft OfficeアップロードセンターはOffice 2013以降に追加された機能です。通信が不安定な環境において、更新されたWebDAV上のファイルをキャッシュして、非同期的にWebDAVサーバーに送信する機能を提供しています。MicrosoftはOneDrive上のOfficeファイルを開くときに、Microsoftが独自に認証周りを拡張したWebDAVを使用しています。OneDriveのファイルをOfficeで直接扱うためのモジュールとして広く使われています。この独自に拡張しているというところが曲者で、Windows統合認証やMicrosoft Liveアカウント認証に対応していないサーバーの場合に、認証に失敗してしまうようなのです。

Windows 10の場合はタスクトレイに常駐しているMicrosoft OneDrive設定から「ファイルのコラボレーション」を無効にすると、Microsoft Officeアップローダーを止められるようです。Googleから”UPLOAD FAILED: You are required to sign in to upload your changes to this location”で検索すると色々と情報が見つかりますが、OfficeやOSのバージョンによって設定すべき項目が異なったり、公式な対策でもないようなのでなかなか面倒そうです。

この辺りまで調べたところで、WebDAVの使用はあきらめる事にしました。

参考:UPLOAD FAILED: You are required to sign in to upload your changes to this location

letsencryptの証明書更新で”‘Namespace’ object has no attribute ‘standalone_supported_challenges'”が発生する

OSをUbuntu 18.04LTSからUbuntu 20.04LTSに移行したところ、旧システムから移行してきた証明書の更新に、以下のようなエラーを表示して失敗しました。

> sudo letsencrypt renew
...
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/www.example.net.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Renewal configuration file /etc/letsencrypt/renewal/www.example.net.conf (cert: www.example.net) produced an unexpected error: 'Namespace' object has no attribute 'standalone_supported_challenges'. Skipping.
...

letsencryptのバージョンが上がったことによりstandalone_supported_challengesオプションがサポートされなくなったことが原因です。

/etc/letsencrypt/renewal/www.example.net.confを編集して、最後の行のstandalone_supported_challengesをコメントアウトすると正常に動作するようになりました。

# renew_before_expiry = 30 days
cert = /etc/letsencrypt/live/www.example.net/cert.pem
privkey = /etc/letsencrypt/live/www.example.net/privkey.pem
chain = /etc/letsencrypt/live/www.example.net/chain.pem
fullchain = /etc/letsencrypt/live/www.example.net/fullchain.pem
version = 0.31.0
archive_dir = /etc/letsencrypt/archive/www.example.net

# Options and defaults used in the renewal process
[renewalparams]
authenticator = standalone
account = 52bc4f19233c146191f7f576945ed0d9
server = https://acme-v01.api.letsencrypt.org/directory
# standalone_supported_challenges = "tls-sni-01,http-01"

参考:https://github.com/certbot/certbot/issues/6984