moodle無法使用多個網域主控認證(Ldap server)
moodle 是目前最強開源線上學習系統,台灣學校在疫情期間紛紛安裝線上開課,當然也很適合公司當作知識管理系統、線上無紙化測驗使用;可惜只能認證一個ldap server,有多網域伺服器就很麻煩,除非上雲端或許還可以解決此問題。
好險我想到moodle支援oauth2,可以透過公司目前最常用的nextcloud 雲端檔案伺服器進行驗證,而nextcloud可以連結多個ldap server進行驗證,那這樣可以解決問題了。
moodle 是目前最強開源線上學習系統,台灣學校在疫情期間紛紛安裝線上開課,當然也很適合公司當作知識管理系統、線上無紙化測驗使用;可惜只能認證一個ldap server,有多網域伺服器就很麻煩,除非上雲端或許還可以解決此問題。
好險我想到moodle支援oauth2,可以透過公司目前最常用的nextcloud 雲端檔案伺服器進行驗證,而nextcloud可以連結多個ldap server進行驗證,那這樣可以解決問題了。
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 很常看到,好多容器都自帶這個服務,說是快取用的;今天問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 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的背景排程,預設為 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
我為了要測試教育訓練相關外掛程式「LearnPress」,必須先搞定員工能登入網站「上課」這件事。
參考以往經驗,我選擇在wordpress系統,安裝教育訓練外掛,而不使用moodle這類風評好又完全免費的系統,原因在於moodle太龐大了,很難駕馭;反之,wordpress可當作公司內部公告網站,讓平時員工習慣上此網站,也趁此加裝教育訓練模組,員工比較容接觸而上課。
wordpress系統要能連上網域主控站,才可讓員工登入,我找到的外掛為next-active-directory-integration。
搜尋以下外掛且安裝完畢,於外掛啟用之前,容器必須安裝相關套件,才能正確連線,否則會出現錯誤。
docker exec -it wordpress_wordpress_1 /bin/bash
#####
apt-get update
apt-get install -y libldap2-dev
docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/
docker-php-ext-install ldap
rm -rf /var/lib/apt/lists/*
apt-get purge -y --auto-remove libldap2-dev
/etc/init.d/apache2 restart
#http://www.jaqb.gda.pl/eng/Community/Blog/Enable-LDAP-support-in-Docker-image-of-Wordpress
進容器安裝相關套件後,就可以啟用外掛,通知使用者輸入「帳號@域名」 就可以登入了。
至於ldap設定部分我就不多說,請自行依情況處理。
自從我懂事以來,都是利用 certbot 進行 「HTTP-01 Challenge」,讓發證單位透過http方式驗證,以取得免費的https證書。
除非遇到Let’sEncrypt考驗伺服器秀逗,否則不可能出問題;長大後,我雄心壯志到各地歷練,發現有些主機 80、443 port 居然被封鎖,沒有了80 port (http),就無法透過HTTP-01考驗方式取得https證書。直到此時,我才知道「代誌不是我們憨人想的架甘丹」—事情不是我們想像的這麼簡單啊。
Let’s Encrypt的Challenge Types,列出支援的驗證類型,裡面提到若 HTTP-01 不能用,還有其他選擇,例如本文要說的:DNS-01 Challenge。
DNS-01 使用原理很簡單:DNS伺服器提供ACME DNS API,讓Let’s Encrypt能夠透過API進行考驗,就能取得https證書了。
2024-4-2
新作法 使用開源acme.sh專案
1. 線上安裝
# 若需要使用dns-01方式,email必須是提供API token相同帳號
curl https://get.acme.sh | sh -s email=xxx@test.com
# 安裝完畢程式會在 /root/.acme.sh/acme.sh ("root"因帳號而異)
2. 使用DNS方式授權
取得API Token 或 API Key (以 cloudflare 為例子)
3. 取得授權檔案
/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt
export CF_Key = "b0e689102efab2cf7a1547aaa8b57c4eb65ff"
export CF_Email = "提供API Key之email帳號"
/root/.acme.sh/acme.sh --issue --dns dns_cf -d remote.test.com
或
export CF_Token = "ibrxxFFlKZ5FrsBpisXRU7GzO_2KzSwRAQoAwbsT"
export CF_Email = "提供API Token之email帳號"
/root/.acme.sh/acme.sh --issue --dns dns_cf -d remote.test.com
# 因為我使用apache httpd、CentOS 7.9;httpd 最高到2.4.6,只能支援RAS加密,不支援ECC;
# 然而acme預設產生的是ECC加密檔案,所以指令需額外加上 -k 4096改成產生RSA加密檔案。
/root/.acme.sh/acme.sh --issue --dns dns_cf -k 4096 -d remote.test.com
# 產生完授權證書後,進行安裝到letsencrypt所在目錄
/root/.acme.sh/acme.sh --install-cert -d remote.test.com \
--cert-file /etc/letsencrypt/live/remote.test.com/cert.pem \
--key-file /etc/letsencrypt/live/remote.test.com/privkey.pem \
--fullchain-file /etc/letsencrypt/live/remote.test.com/fullchain.pem
#自動更新授權證書(會自動加到crontab) /root/.acme.sh/acme.sh --upgrade --auto-upgrade
# acme產生檔案與 Let's encrypt檔案對應如下
ACME <-> Let's Encrypt
==========================================================
ca.cer <-> cer.pem
fullchain.cer <-> fullchain.pem
remote.test.com.cer <-> chain.pem
remote.test.com.key <-> privkey.pem
==========================================================
(已失效)以google domains 為範例:(很可惜google賣掉網域代管業務)
1、先建立權杖(token)
登入google domain後,點選「安全性」->ACME DNS API 「建立權杖」
此權杖只會出現一次,因此複製後,要妥善保存。
2、我想使用certbot方式取得憑證,所以到 「certbot-dns-google-domains 」github ,取得執行方式。
2.1 新增權杖檔案
vi /var/lib/letsencrypt/dns_google_domains_credentials.ini
dns_google_domains_access_token = QWVpQWZjT1xxxxxxg2N3lrMi1LUQ==
dns_google_domains_zone = test.com
2.2 docker方式執行,輕鬆取得https證書。
docker run \
-v '/var/lib/letsencrypt:/var/lib/letsencrypt' \
-v '/etc/letsencrypt:/etc/letsencrypt' \
--cap-drop=all \
ghcr.io/aaomidi/certbot-dns-google-domains:latest \
certbot certonly \
--authenticator 'dns-google-domains' \
--dns-google-domains-credentials '/var/lib/letsencrypt/dns_google_domains_credentials.ini' \
--server 'https://acme-v02.api.letsencrypt.org/directory' \
--non-interactive \
--dns-google-domains-zone 'test.com' \
-d 'xxx.test.com'
3、還有其他取得證書方式(一樣是google domain)
請參考 List of known ACME clients to work the ACME DNS API
若使用的是阿里雲解析,可參考這篇文章,我自己測試結果沒問題;提醒一下,要使用let’s encrypt,dns需要有CAA record 允許let’s encrypt 發證,否則會出現 「Verify error : CAA ……」錯誤
未免忘記,節錄一些指令;
除了指令外,還需要在阿里雲加上RAM帳號,授權該帳號能透過阿里雲OpenAPI修改DNS,
並且取得該RAM帳號「Key」與「Secret」,以下指令需要用到。
yum install socat
curl https://get.acme.sh | sh
vim /root/.acme.sh/acme.sh.env
export LE_WORKING_DIR="/root/.acme.sh"
alias acme.sh="/root/.acme.sh/acme.sh"
export Ali_Key="xxxx"
export Ali_Secret="yyyy"
source ~/.bashrc
env
acme.sh --set-default-ca --server letsencrypt
acme.sh --issue --dns dns_ali --dnssleep 180 -d xxxx.test.com
#若以上指令不行,可改以下指令
acme.sh -f --use-wget --issue --dns dns_ali --dnssleep 180 -d xxxx.test.com
2023/6/16 我在RockyLinux 9.2安裝失敗出現以下問題(google代管之網域)
[Errno 13] Permission denied: '/etc/letsencrypt/.certbot.lock'
這很複雜,原因很多,我的解法如下:
解法1. selinux 放行,然後再關起門來 setenforce 0 ; docker run \ -v '/var/lib/letsencrypt:/var/lib/letsencrypt' \ -v '/etc/letsencrypt:/etc/letsencrypt' \ --cap-drop=all \ ghcr.io/aaomidi/certbot-dns-google-domains:latest \ certbot certonly \ --authenticator 'dns-google-domains' \ --dns-google-domains-credentials '/var/lib/letsencrypt/dns_google_domains_credentials.ini' \ --server 'https://acme-v02.api.letsencrypt.org/directory' \ --non-interactive \ --dns-google-domains-zone 'test.com' \ -d 'xxx.test.com' ; setenforce 1; 解法2. 確認相關套件是否安裝 dnf install httpd mod_ssl certbot --apache #若出現The requested apache plugin does not appear to be installed,則代表缺少套件 yum list installed|grep certbot certbot.noarch 2.6.0-1.el9 @epel python3-certbot.noarch 2.6.0-1.el9 @epel 這樣還缺少 python3-certbot-apache , 我再安裝一下 dnf install python3-certbot-apache
長期以來,我「HTTP反向代理伺服器」只使用「Apache Http」, 理由簡單:習慣了;然而,新興的代理伺服器總讓我有種「雖簡單卻很艱難」的感受,雖說採用新服務器是進步的象徵,但我考量自己管理的網站達數十個,非常在意網站穩定性,若貿然決定更換新「反向代理服務器」,則需要很大的勇氣,誰都無法知道被代理的服務器會不會水土不服,造成災難,因而作罷。
一般來說,apache httpd運作很穩定,沒事就不要動設定;但是我總是遇到代理服務器重啟很慢的問題,原本也沒有多想,訓練自己忍耐力XD,直到遇見”Linux技術手扎“,網站中有兩篇文章,對於apache http效能,防止阻斷攻擊(DoS)有詳細說明。我拜讀之後,受用不盡,因此也節錄下來,作為自己快速參考用。
1、解決apache http重啟慢問題
vi /usr/lib/systemd/system/httpd.service
[Service]
...
KillMode=none
systemctl daemon-reload
2、防止阻斷攻擊(Dos)
vi /etc/httpd/conf/httpd.conf
...
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
systemctl restart http
想知道修改原因、運作原理,請參考網站。
我在2023年4月6日,將網站升級到6.2.0(docker版本) : 回想起一開始升級時, 容器(container)為舊版, 我沒有採用拉取(pull)方式升級, 直接使用內建升級功能,可惜失敗了!出現找不到“sw-check-permissions-e2a8b.js”錯誤;於是我改用拉取最新容器方式升級, 而且成功了。
升級後,,我陸續寫了好幾篇文章,卻沒有發現網站已經有狀況了。直到今日(4月24日),我在同事電腦,瀏覽自己網站時,防毒軟體居然跳出”木馬”警告,我才意識到出事了!
警告內容為「bujerdaz.com」這個網站有木馬;既然有明確網站名稱,肯定網站內有這些字眼,我馬上登入網站伺服器,搜尋了一番, 還真的有找到:
找到問題後, 接下來就是決定解決方式: 1、刪掉這一行含木馬之語法;2、查看看容器是否有最新版。
第一種做法「刪掉木馬語法」通常逼不得已才做;於是我先選擇第二種「查看容器是否有新版」,沒想到,一模一樣的6.2.0版本,居然有不同內容,這明顯是官方犯了錯誤!一般我們不會懷疑同版本容器,內容會被異動;若內容不同,必須進一個版號,並且昭告天下有修補版本! (官方並沒有說明)
這讓我以後升級需要多一個心眼,要以防毒軟體進行掃描,至少不要影響用戶端瀏覽網站。
—
2023/4/25 雖然升級新版容器,自以為問題已解決,沒想到問題還是在!仔細一看,是plugin外掛所造成的,難怪用新版容器還是無法解決,因「外掛」程式我繼續沿用,不因容器更換而刪除,當然「木馬」一直存在。我發現阻擋垃圾留言的外掛「akismet」,出現兩個版本: 一個5.0;另一個1.2。(理論上不該存在兩個版本) 版本1.2裡面寫到要連線 bujerdaz.com ,看起來應該是進行一些確認才允許留言,我認定非木馬程式,可能wordpress系統用太多年了,這次大版本升級造成兩個版本並存之現象;最後移除1.2版akismet,只留下5.0版本,就恢復正常了。另外,依照這邏輯,我的網站應該「有問題」很久了,真的很不好意思。
#wordpress
#virus
#Trojan
今天公司有個網站, 到了每三個月要更新(renew)證書的日子, 沒想到卻出現「Certificat renewal failure during secondary validation: Remote PerformValidation RPC failed」這個錯誤訊息. 開始我還以為防火牆或網頁服務器出問題, 摸索一陣子卻找不出原因 XD
這麼多年來, 頭一遭遇到這問題; 隨著同仁瘋狂反應, 我緊張到瑟瑟發抖 ! 此時, 我突然想到可以到let’s encrypt官方論壇,查看有沒有人有相同問題. 幸運的是滿滿都是問題回報;原來是官網的主機出問題, 需要30~60分鐘時間修復.
經此風波, 我覺得有必要訂定SOP,用來解決發證書所造成的問題:
第一步: 發現renew失敗, 看log(/var/log/letsencrypt/letsencrypt.log).
第二步: 查看Let’s encrypt伺服器是否正常 https://letsencrypt.status.io/
第三步: 到let’s encrypt社群看看有沒有相同的問題反映