因nextcloud而認識F-Droid

nextcloud上面有個很讚的開源看板軟體「Deck」,看板(kanban)概念屬於敏捷(Agile)開發的一部分,既然是敏捷,我直覺想到Deck一定有mobile app版本;於是我查了一下,發現iOS, Android都有,而且Deck 行動版還開源,iOS直接在app store就可以免費下載安裝,Android Deck則須小收3.49 USD 辛苦費。

我的手機一向都使用android,若想要免費版還有一個方式,就是到 F-Droid 下載免費編譯好的Deck 安裝;後來甚至發現nextcloud建議聯絡人同步軟體 DAVx5 也開源,一樣可以在 F-Droid 下載安裝,非常方便。

F-Droid 理念

F-Droid 是一個可在 Android 平台上安裝的自由與開源FOSS(Free and Open Source Software)的應用程式目錄,可供您輕鬆瀏覽、安裝並持續追蹤裝置上應用程式的更新。

因為我有兩個軟體從F-Droid下載,沒有google商店,將會面臨更新問題,所以最後乾脆安裝 F-Droid App 商店,讓他幫我更新。

nextcloud(容器)連到windows檔案伺服器

nextcloud若能跟公司內部的檔案伺服器連線,在外面就能方便存取公司檔案,也不失為一個好方法;只要安裝「External Storage Support」這個app就能存取外部檔案。

External Storage support 預設無法連線windows檔案伺服器,我們需要額外安裝一些套件,安裝完畢就能支援了。

docker(podman) exec -it <nextcloud container> bash

apt update 
apt -y install libsmbclient-dev libmagickwand-dev 
pecl install smbclient 
pecl install inotify
echo "extension=smbclient.so" > /usr/local/etc/php/conf.d/docker-php-ext-smbclient.ini
echo "extension=inotify.so" > /usr/local/etc/php/conf.d/docker-php-ext-inotify.ini

安裝相關套件後,就能選取到「SMB/CIFS」

原本連線到\\10.1xxx.x.x\taipei 拆開成兩部分,帳號若屬於網域,也要填進去,最後還限制群組使用

nextcloud「通知(Notification)」功能兩三事

nextcloud 要做到系統通知,首先要確認是否安裝「Notification」與「Activity」兩個外掛app,安裝完畢還要確保自動排程(crontab)正常執行,請參考「捨棄nextcloud(容器)內背景排程,改用主機排程(cron)」。

我因為啟用nextcloud的「Deck看板」功能,被使用者要求email通知看板功能的進度,所以安裝了「通知」app,安裝完畢會有一個全域預設的設定值,可以設定那些事件需要通知。

現在問題來了,全域設定預設會通知一大推事件,例如行事曆異動、新增標籤、群組異動與新留言訊息等等,就算關掉這些設定,使用者還是抱怨持續收到一大堆通知;後來發現使用者可以自行設定這些設定值,原來是使用者登入後,就會把系統預設值謄一份到屬於使用者的基本設定上,當然關掉預設值是沒有用的,必須使用者自行更改通知方式才有用,無奈麻瓜就是醬子,很難請他們自己動手改,我只好自己研究系統資料庫內容,將所有使用者設定值改成跟我一樣

以下是例子,紅色須注意。

資料庫為mariadb

1. 取得我們帳號uid
select * from oc_accounts

2. 取消通知
update oc_preferences set configvalue = 0 where  appid='activity' and configkey like 'notify%' and configkey not in  (
select configkey from oc_preferences where userid='帳號uid' and appid='activity' and configkey like 'notify%' and configvalue='1'
)

3. 保留通知
update oc_preferences set configvalue = 1 where  appid='activity' and configkey like 'notify%' and configkey  in  (
select configkey from oc_preferences where userid='帳號uid' and appid='activity' and configkey like 'notify%' and configvalue='1'
)

使用者須自行設定通知

由網域主控站匯出VCARD 電子名片標準VERSION:3.0

一直以來公司的通訊錄使用ldap方式獲取。但是ldap缺點有二:

1、若連不上網域伺服器(越南夏天會停電還一次停兩天),就算我們使用outlook時,並不需要用到通訊錄,但outlook還是會一直出現錯誤,解決方式如下:outlook 關於ldap通訊錄的處理經驗

2、只能在內網使用,筆電拿到公司外就連不上網域主控站,outlook就會開始罵罵號。

這問題我滿頭痛的,好險最近我開始把重心放在nextcloud上,發現可以透過webdav連線方式,從網際網路直接獲取通訊錄以及行事曆,這樣可以解決上面兩個問題;雖然以後多了一個維護的地方,但這可以解決很多麻煩事,而且好處多多,例如可以透過手機、網頁等等多元方式,直接取得聯絡人以及行事曆。

說做就做,我連上公司nextcloud雲端系統後,原本打算一筆一筆「手動」輸入數百筆通訊錄,但是想想還是從三個廠的網域主控站匯出聯絡人比較實在,再由nextcloud提供的匯入功能匯入即可。

nextcloud提供匯入的檔案格式為vcf format,意即VCARD,而且規定要3.0或以上版本才能匯入,格式長這樣:

BEGIN:VCARD
VERSION:3.0
FN:william

ORG:HT
TITLE:
TEL;TYPE=WORK:
TEL;TYPE=HOME:
TEL;TYPE=CELL:
EMAIL;TYPE=WORK:william@test.com
CATEGORIES:test

NOTE:
UID:79996fd9-b2d6-1111-111e-85f7cd5896e5
END:VCARD

這種需求當然往github找尋解方,找了很久都是2.0的powershell腳本,後來終於在這裡找到,試跑了一次還ok,就差在沒有使用utf8輸出,匯入nextcloud會有亂碼,因此我改了一下寫法如下:

紅色部分請自行斟酌修改,存成xxx.ps1 並且在powershell裡執行;要注意屬性CATEGORIES,對應到nextcloud的聯絡人群組(Contact Group),這很重要。

<#
.SYNOPSIS

Export AD Users as single vcf file

#>

cls

$filename = "C:\temp\vCards.vcf"

remove-item $filename

Get-ADUser -filter {Enabled -eq $True} -Properties * | where {$_.enabled -eq $true} | Foreach-Object {

$user = $_.sAMAccountName
$email = $_.EmailAddress
$phone = $_.OfficePhone
$name = $_.Name
$short = $_.HomePhone
$mobile = $_.MobilePhone
$sede = $_.physicalDeliveryOfficeName
$ufficio = $_.Department
$qualifica = $_.title
$responsabile = ($_.manager -split ',*..=')[1]

if ($phone -or $email -or $mobile){
    write-host $user

    # Generate vCard
    Add-Content -Encoding UTF8 -Path $filename "BEGIN:VCARD"
    Add-Content -Encoding UTF8 -Path $filename "VERSION:3.0"
    Add-Content -Encoding UTF8 -Path $filename ("FN:" + $_.cn)
    Add-Content -Encoding UTF8 -Path $filename ("ORG:test")
    Add-Content -Encoding UTF8 -Path $filename ("TITLE:" + $qualifica)
    Add-Content -Encoding UTF8 -Path $filename ("TEL;TYPE=WORK:" + $phone)
    Add-Content -Encoding UTF8 -Path $filename ("TEL;TYPE=HOME:" + $short)
    Add-Content -Encoding UTF8 -Path $filename ("TEL;TYPE=CELL:" + $mobile)
    Add-Content -Encoding UTF8 -Path $filename ("EMAIL;TYPE=WORK:" + $email)
    Add-Content -Encoding UTF8 -Path $filename ("CATEGORIES:test")
    $notedate = (get-date).ToString('d/MM/yyyy')
    Add-Content -Encoding UTF8 -Path $filename ("NOTE:")
    Add-Content -Encoding UTF8 -Path $filename ("UID:" + $_.objectGUID )
    Add-Content -Encoding UTF8 -Path $filename "END:VCARD" #`r`n"
    }

}

讓moodle透過nextcloud提供的oauth2 服務進行登入認證

1. moodle與nextcloud需要有一樣名稱的管理者帳號
有點類似微軟網域伺服器之間的互信,我這邊兩方都建立admin這個有管理權限的帳號。

2. 管理者帳號登入nextcloud網站進行設定
新增客戶端
名稱: moodle
網址: https://xxxxx/admin/oauth2callback.php (xxxxx 為您moodle伺服器網址)

3.管理者帳號登入moodle網站,讓oauth2納入認證範圍
網站管理->外掛->身分認證->管理身分認帳

4.管理者帳號登入moodle網站,將nextcloud產生的帳密輸入進去

   

    

    

儲存變更後,點選以下小圖示,進行moodle與nextcloud的第一次交流驗證,成功後會出現一個綠色勾勾

   

4. 大功告成

最後建議安裝keepalive,延長已登入狀態,否則常常要登入,麻瓜會生氣氣(安裝時,要注意/bitnami/moodle/local目錄是否可讀寫)

安裝完畢,可以設定session存活時間,最多300分鐘

此時我們就可以設定外觀,隱藏需要登入帳號與密碼的畫面

在「原始初始化SCSS」輸入以下語法隱藏登入畫面,只剩下oauth2登入。

.login-form {display:none}

設定完登出,重新登入就只能透過oauth2登入了

moodle無法使用多個網域主控認證(Ldap server)

moodle 是目前最強開源線上學習系統,台灣學校在疫情期間紛紛安裝線上開課,當然也很適合公司當作知識管理系統、線上無紙化測驗使用;可惜只能認證一個ldap server,有多網域伺服器就很麻煩,除非上雲端或許還可以解決此問題。

好險我想到moodle支援oauth2,可以透過公司目前最常用的nextcloud 雲端檔案伺服器進行驗證,而nextcloud可以連結多個ldap server進行驗證,那這樣可以解決問題了。

nextcloud 加速:使用redis

1. 先準備好redis server
如何安裝redis

2.修改nextcloud 設定檔案

docker exec -it nextcloud bash
root@a764952ce51b:/var/www/html# vi config/config.php
###
<?php
$CONFIG = array (
  'htaccess.RewriteBase' => '/',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'redis' => array(
          'host' => '127.0.0.1',
          'port' => 6379,
  ),
...
...

3. 重啟nextcloud , 然後回到redis 可下指令查看

redis 好像很重要,應該裝一下

redis 很常看到,好多容器都自帶這個服務,說是快取用的;今天問google查一下為何nextcloud很慢,答案都指向redis,因此還是裝一下redis,再來研究怎讓nextcloud使用。

1. 修改容器本體主機 /etc/sysctl.conf

vm.overcommit_memory = 1
net.core.somaxconn = 65535

修改完執行 sysctl -p 讓設定生效。

2. 執行redis(很好運的是,新版本6.2.12 與 7.0.11 一直出現 Fatal: Can’t initialize Background Jobs ,只好降版改用 6.2.11 )

docker run --name redis --restart=always -d -p 6379:6379 --sysctl net.core.somaxconn=511 redis:6.2.11 redis-server

為何sysctl 已經設定 somaxconn,指令還要設定一次? 我也不知道,反正這樣可行,以後有空再說。

nextcloud如何刪除ldap使用者

nextcloud可以連接多個ldap server,這對於IT來說很方便。

隨著時間推移,越來越多使用者離職,帳號設定成停用,當我們確認可以刪除後,nextcloud卻無法正常透過UI介面刪除帳號,這會造成一些困擾;很懶的我後來我爬文,解方居然是下指令才能刪除,更麻煩的是只能一個一個帳號刪除,真真嚇死我。

好險有個神人寫shell script就能批次刪除。

for i in $(php occ ldap:show-remnants | awk -F'| ' '{print $2}'); do
    echo "Delete user: $i"
    php occ user:delete $i
done

因為我用的是容器(docker),指令如下:

for i in $(docker exec -u www-data -it nextcloud php occ ldap:show-remnants | awk -F'| ' '{print $2}'); do
  echo "Delete user: $i"
  docker exec -u www-data -it nextcloud php occ user:delete $i
done

Done.

警告:刪除帳號會導致該帳號所有檔案一併被刪除。

捨棄nextcloud(容器)內背景排程,改用主機排程(cron)

nextcloud的背景排程,預設為 AJAX,雖說nextcloud建議使用系統cron,但是nextcloud容器cron是「不啟用」的,每次改用Cron,還要進容器另外處哩,非常麻煩,容器升級又要做一次,折磨人啊 。 久而久之,nextcloud一律使用預設值AJAX,我測試過AJAX不會失敗(私、失敗しないので)。

直到最近我使用nextcloud的看板系統(Deck),需要有「email通知 Deck系統裡 卡片異動通知」之功能,因此AJAX單人用還可以,但公司用我就得改用Cron,可是一想到要進容器啟用cron就覺得好煩,才來才知道我錯了。

原來改用cron意外地簡單!

不管是RockLinux、CentOS還是ubuntu,只要在容器宿主(Host)裡的cron,加上一條指令就完事了。

/usr/bin/docker exec -t -u www-data <容器名稱> php -d memory_limit=512M  -f /var/www/html/cron.php

真是太棒了!

以下是排程我建議要執行的

docker exec -t -u www-data nextcloud php occ trashbin:expire --quiet
docker exec -t -u www-data nextcloud php occ versions:expire --quiet
docker exec -t -u www-data nextcloud php -d memory_limit=512M  -f /var/www/html/cron.php
docker exec -u www-data -it nextcloud php occ  files:scan --all
docker exec -u www-data -it nextcloud php occ  files:scan --unscanned --all

1 2 3 4