Tommy 碎碎念
https://blog.teatime.com.tw/
Tommy Wu's blog
tommy
2024-03-19T21:11:17Z
-
遠端電源控制
https://blog.teatime.com.tw/1/post/496
<p>早期用過 <a href="https://aviosys.com/products/9258.php" target="_blank" rel="noopener">IP Power 9258</a>, 不過好像用了兩年就壞了, 因為廠商也在中和, 那時有送修過一次, 之後好像用一年多又壞了. 後來買了 LevelOne 的 IPS-0008 來用 (只是買了沒多久就結束國外的工作, 所以沒用幾次), 這個感覺品質有好一點, 印象中用了六年左右, 某天晚上突然鬼叫, 再也不能控制電源. 之後就沒使用類似的產品了.</p>
<p>最近, 因為家裡的 Utilite Pro 開始出現問題 (網路傳輸速度會突然變很慢), 加上之前用了 NanoPi 的 R4S/R2S, 印象不錯, 看到新的 <a href="https://www.friendlyelec.com/index.php?route=product/product&product_id=291" target="_blank" rel="noopener">R6C</a> 可以有 HDMI 輸出, 也把 Debug Console 直接接出來用, 不需要拆機才能接 Console, 所以就買了台 R6C 回家換. 不過.... 在幾次換非官方的 kernel 過程中, 碰到無法開機的情形, 都需要回家才能拔電源, 所以又懷念起之前用的遠端電源的設備.</p>
<p>上網看了一下, IP Power 還在賣, 不過價格貴了不少, 而 IPS-0008 之類的產品似乎就更少看到, 淘寶找了一下類似的產品, 看了一下價格, 實在下在了手. (畢竟目前沒有那麼急迫的需求, 以後做類似的動作就等著回家再處理就好)</p>
<p>後來突然想到小米有出過<a href="https://www.mi.com/tw/product/xiaomi-smart-plug-2/" target="_blank" rel="noopener">智慧插座</a>這個產品, 價格不貴, 只要有網路, 也能遠端開關. 找了一下, 發現 <a href="https://www.tp-link.com/tw/home-networking/smart-plug/hs300/" target="_blank" rel="noopener">TP-LINK 有出一個 HS300 的延長線</a>, 有類似的功能, 而且可以獨立控制六個插座, 算下來比一個個智慧插座買划算多了, 就買了一個回家試試.</p>
<p>這東西先在手機裝好 <a href="https://play.google.com/store/apps/details?id=com.tplink.kasa_android&hl=zh_TW&gl=US" target="_blank" rel="noopener">Kasa app</a>, 然後延長線插上電源後, 用 app 去新增就可以找到該設備去設定要使用的無線網路, 然後連上後, 就能用 app 來控制開關了.</p>
<p>跟之前用的那些遠端電源設備的差別, 應該就是在外頭要連上他們的伺服器才能控制開關, 如果那天他們的伺服器掛了, 就不能用了. 另外一個就是這東西沒有 reset 的動作 (就是關了再開), 要分開做. 所以如果關了電源會導致網路不通的話, 就沒辦法打開電源了.</p>
<p>不過還好這個產品有排程的功能, 可以去設定要關電源與開電源的時間, 設好後, 就算關了之後網路不通, 因為排程在設定會就送到延長線上頭, 不需要再透過伺服器連線來控制, 所以時間到了就會再開電源.</p>
<p>另外還有一個附帶的好處, 是這個 app 上面記錄使用的電量 (應該沒有完全正確, 但也應該差不到那去), 還可以看到那些設備平日運作要用多少電.</p>
<p>PS. 另外有一點不確定的是, 如果在同一個網路下, 似乎不需連到伺服器還是能控制開關的樣子 (沒真的斷網試, 只是在 firewall 把那個延長線的 ip 擋了, 發現擋了之後還能用的樣子)</p>
<p> </p>
碎碎念
2024-01-14T16:54:49Z
tommy
-
舊主機掛了, 換新主機了
https://blog.teatime.com.tw/1/post/495
<p>上星期六傍晚, 在客廳看電視時, 突然收到一堆 line 的通知, 說家裡的主機連不上了. </p>
<p>進房間一看, 果然燈號全熄, 按了電源重開一樣開不起來. 拆了側板, 發現開機時, 風扇轉一下後就斷電. 依據經驗來看, 電源供應品, 主機板, CPU 可能是這幾個東西有些壞掉. 看主機板的電容也沒爆, 最後拔了 CPU 8PIN 的供電, 發現就不會開了馬上就斷電.</p>
<p>我是懷疑主機板壞了, 因為幾年前有次清灰塵時沒關機, 不小心晃動了一下主機, 那時就有跳電重開, 而且重開後內顯就不能用, 後來重開了幾次就有花花綠綠的畫面, 好像關機一陣子後再開就有正常的畫面. 這樣又用了幾年, 這次就完全開不了機了. 不過.... 我完全沒設備可以交叉測試, 加上主機用了超過 10 年了, 通通沒保固了. 好像也沒修的必要了.</p>
<p>年紀大了, 這次就不打算自己組裝了, 上原價屋的網站選了要買的東西, 就直接請他們組裝好再去拿. 最後選了下面的東西:</p>
<ul>
<li>AMD 5700G</li>
<li>技嘉 B550M AORUS ELITE</li>
<li>美光 Micron Crucial 64GB(雙通32GB*2)*2</li>
<li>金士頓 KC3000 2TB</li>
<li>Antec P101 Silent</li>
<li>全漢 HYDRO G PRO 650W</li>
</ul>
<p>星期六晚上訂, 星期天早上打電話來確認不含 OS, 就請我星期二過去拿. 取貨地點是光華的 TVBS 大樓二樓 (退伍工作的公司就在這邊五樓, 還算熟悉), 當天開車去就停樓下中庭 (好像能免費停 30 分, 不過, 重頭到尾沒人來管), 到樓上付錢, 開機測試後就打包載回家.</p>
<p>回家後把舊硬碟拆過去, 複製原本的系統到 SSD 上, 確定可以運作後, 再把舊主機上的 RAID 卡跟硬碟都換到新主機上. 這樣也花了一下午的時間才弄好.</p>
<p>新主機用了一星期, 感覺比舊主機快了許多, 轉檔或編譯 Android 都約 4-6 倍的速度. 而且滿載時看起來 UPS 的 loading 跟之前差不多. 或許之後電費也會省下一些.</p>
<p>這次也許是最後一次自己弄家裡的主機了, 如果一樣用個十年, 下次可能就不擺主機在家裡了.</p>
碎碎念
2023-08-14T10:32:31Z
tommy
-
hyper-v 突然無法啟動任何虛擬主機
https://blog.teatime.com.tw/1/post/494
<p>上星期把在 Windows 10 裡頭的 hyper-v 中的 Debian 主機由 11 升級到 12, 重開機後, 發現在 build android 時會有錯誤, 弄了一天才發現是<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1036755" target="_blank" rel="noopener"> kernel 的問題</a>, 換回原本 Debian 11 的舊 kernel 後, 果然可以正常運作.</p>
<p>今天試著自己加上 patch 後, 做了一個 6.1.27 的 kernel 來用, 結果重開機後, 發現無法正常開機, 想到自己做的 kernel 是 unsigned 的, 安全開機要關閉才可以. 結果關了之後, 反而整個 VM 就無法打開了. 試著弄一個空的 VM 也不行, 把安全開機改回去也不行.</p>
<p>上網 google 找了一下, 發現<a href="https://communities.vmware.com/t5/Nested-Virtualization/hyper-v-crashing/td-p/522812" target="_blank" rel="noopener">以前的版本有類似的問題</a>, 果然惡意探索保護中的流量控制防護 (CFG) 關閉之後就可以正常啟動 VM 了 (只針對 vmcompute.exe 關閉就可以).</p>
<p>不過上星期到剛剛, 也沒更新系統, 不知道為什麼重開 VM 就有這問題.</p>
Software
Windows 10
2023-06-27T20:32:57Z
tommy
-
讓 Nginx 的 real_ip 模組找不到對應的 header 時, 使用 proxy protocol 傳入的 IP
https://blog.teatime.com.tw/1/post/493
<p>最近把 DNS 轉到 <a href="https://www.cloudflare.com/" target="_blank" rel="noopener">Cloudflare</a> 使用, 原本在主機上使用 <a href="https://www.haproxy.org/" target="_blank" rel="noopener">HAProxy</a> 把 SSL 的封包轉到個別對應的軟體是使用 Proxy Protocol 將來源 IP 通知處理的軟體. 在改用 Cloudflare 之後, 這個 IP 就變成 Cloudflare 的 IP 了. 這個在需要知道來源 IP 的軟體上, 就反而造成問題.</p>
<p>通常會走 Cloudflare 進來的, 也都是網頁的服務 (其他同樣使用 SSL 走 443 的服務, 也不需要透過 Cloudflare 處理, 通常可以在 DNS 上另外設定來避開). 依據 Cloudflare 的作法, 是應該使用 HTTP 的 header CF-Connecting-IP 來取得真實的來源 IP. 不過.... 由於我這邊是先透過 HAProxy 處理過, 混雜了來自 Cloudflare 與沒經過 Cloudflare 的封包 (例如內部網路的機器), 這時, 就變成使用 CF-Connecting-IP 時, 非來自 Cloudflare 的 IP 變成 HAProxy 的 127.0.0.1, 如果使用 Proxy Protocol 時, 那些透過 Cloudflare 的封包, 來源 IP 又全變成 Cloudflare 的 IP 了.</p>
<p>看了一下 <a href="https://nginx.org/" target="_blank" rel="noopener">Nginx</a> 的 real_ip 模組設定, <a href="http://nginx.org/en/docs/http/ngx_http_realip_module.html" target="_blank" rel="noopener">real_ip_header</a> 就只能設定一種, 不能有多重的設定, 所以就只好看一下 source, 自己動手來修改.</p>
<pre class="language-diff"><code>--- nginx-1.23.3/src/http/modules/ngx_http_realip_module.c.orig 2023-03-19 11:18:38.033783262 +0800
+++ nginx-1.23.3/src/http/modules/ngx_http_realip_module.c 2023-03-19 11:17:30.029338872 +0800
@@ -157,7 +157,8 @@
case NGX_HTTP_REALIP_XREALIP:
if (r->headers_in.x_real_ip == NULL) {
- return NGX_DECLINED;
+ //return NGX_DECLINED;
+ goto try_proxy_protocol;
}
value = &r->headers_in.x_real_ip->value;
@@ -170,7 +171,8 @@
xfwd = r->headers_in.x_forwarded_for;
if (xfwd == NULL) {
- return NGX_DECLINED;
+ //return NGX_DECLINED;
+ goto try_proxy_protocol;
}
value = NULL;
@@ -178,6 +180,7 @@
break;
case NGX_HTTP_REALIP_PROXY:
+try_proxy_protocol:
if (r->connection->proxy_protocol == NULL) {
return NGX_DECLINED;
}
@@ -219,7 +222,8 @@
}
}
- return NGX_DECLINED;
+ //return NGX_DECLINED;
+ goto try_proxy_protocol;
}
found:
</code></pre>
<p>修改的方式其實不難, 這邊的處理雖然是用 switch case 來獨立處理, 不過可以發現其實是不是透過 Proxy Protocol 處理過, 是有方法可以判斷的, 所以我們只要在其中每一種用來取得 real_ip 的 case 中, 如果最後沒有處理到, 就轉給 Proxy Protocol 那一段來處理就可以.</p>
<p>這樣子修改後, 我們依舊可以在 Nginx 中設定</p>
<pre class="language-nginx"><code>real_ip_header CF-Connecting-IP;</code></pre>
<p>就算是沒有這個 header 的來源, 一樣仍透過 Proxy Protocol 處理, 就算也沒透過 Proxy Protocol, 一樣可以判斷出來而不會造成問題.</p>
Linux
Patch
Nginx
2023-03-24T10:08:25Z
tommy
-
新玩具 NanoPi R2S/R4S
https://blog.teatime.com.tw/1/post/492
<p>由於家裡的其中一台 firewall 使用的 CompuLab 的 Intense-PC 這半年老是在執行 php script 時發生 coredump, 加上硬碟應該也有壞軌, smartd 每天都發信通知有問題, 所以想找機器來換掉它. 因為做的事不複雜, 也不需要太多的效能就能處理, 加上之前買來用的 <a href="https://blog.teatime.com.tw/1/post/462" target="_blank">Utilite</a> 都能運作, 所以考慮買個雙網卡的耗能低小機器來處理就可以.</p><p>上淘寶找了一下, x86 的機器有兩個網卡的有 celeron 847 (跟那個 Intense-PC 一樣, 不過看起來多數都沒貨, 都改成比較新的 CPU 了) 跟 1037U, 還是 J1800/J1900. 而 arm based 的機器, 雖然因為樹梅派的關係, 比以往多了不少, 不過多數都還是只有一個網卡. 後來突然想到, 可能是找的方向不對, 改用 "軟路由" 去找, 果然除了一堆 J1800 的機器外, 也出現了 NanoPi 的 <a href="https://wiki.friendlyarm.com/wiki/index.php/NanoPi_R2S" target="_blank">R2S</a> 跟 <a href="https://wiki.friendlyarm.com/wiki/index.php/NanoPi_R4S" target="_blank">R4S</a>. </p><p>比較了一下優缺點:</p><p> </p><ul><li>x86 的機器效能比較好, R2S/R4S 比較省電</li><li>x86 的機器有 VGA 可以接顯示器, R2S/R4S 只有 serial console 可以用</li><li>R2S/R4S 應該比較有可 "玩" 性, 如果買 x86 的機器, 可能直接硬碟複製一下就繼續使用了</li><li>R2S/R4S 比較便宜</li></ul><p> </p><p>最後決定買台 R2S 或 R4S 來玩. 不過要買比較便宜但只有 1G 記憶體的 R2S 還是比較貴, 但有 4G 記憶體的 R4S 呢? 後來為了怕被我玩壞, 乾脆各買一台回來試看看 (兩台加一起的錢跟一台 x86 的小機器差不多).<br />不過在玩過機器後, 如果目前讓我選, 應該只會選擇 R4S 就好, 理由如下:</p><p> </p><ul><li>R4S 的記憶體多了些</li><li>R4S 的速度快了一些</li><li>R4S 在同樣的環境下, 溫度比 R2S 少 8 度</li><li>最重要的是, R2S 其中一個網卡是使用 USB 介面的 R8153B, 在比較重度的使用 (其實我覺得一點都不 "重度"), 會有網卡 timeout 的問題 (雖然會恢復, 但總會有突然頓一下的感覺)</li></ul><p> </p><p>買的時候, 建議也買個 USB2ART 的設備回來當 console 用, 不然在一開始安裝系統時, 會不太方便使用 (怕開機有問題看不到, 到時網路連不上, 很難找到問題).<br />不過 USB2ART 這東西, 因為樹梅派的關係, 台灣的拍賣網站也有一堆, 價差不會很大, 也可以在台灣買就好 (不過 R2S/R4S 價差很大, 建議直接由淘寶買比較划算). </p><p>兩個都是使用 MicroSD 卡當儲存設備, 應該一般常見的 class 10 的卡就能用 (我是拿之前手機換下來的卡來用), 可能是有 cache 的關係, 實際使用並不會覺得 I/O 慢 (只有把系統複製過上去, 最後執行 sync 時會慢).<br />至於 rootfs 的製作, 可以參老<a href="https://wiki.debian.org/Arm64Port">這篇</a>, 使用 debootstrap 的方式處理, 或者參考<a href="https://www.kulesz.me/post/160-debian-bullseye-sysvinit-arm64-install/" target="_blank">這篇</a>, 使用 VM 的方式來處理.<br />使用 debootstrap 應該比較快, 不過如果習慣用 aptitude 來安裝軟體的話, 可能使用 VM 的方式會好一些, 因為在 x86-64 的 Debian 上用 chroot 的方式跑 arm/arm64 的環境時, 使用 aptitude 在最後執行安裝作業時, 常常有 coredump 的情形.</p><p>至於 bootloader/uboot 的部分, 可以由 <a href="https://github.com/friendlyarm/" target="_blank">friendlyarm 的 github</a> 抓 source code 回來編譯, 也可以抓別人做好的直接用.<br />我是建議直接用 <a href="https://www.armbian.com/" target="_blank">Armbian</a> 做好的版本. R2S 可以用<a href="https://imola.armbian.com/apt/pool/main/l/linux-u-boot-nanopi-r2s-current/" target="_blank">這個</a>, R4S 可以用<a href="https://imola.armbian.com/apt/pool/main/l/linux-u-boot-nanopi-r4s-current/" target="_blank">這個</a>.</p><p>SD 卡的前 16MB 是用來放 bootloader/uboot 的, 所以分割區要由 16M 之後開始用, 第一個分區是建議用一個 ext4 的分區放 kernel 跟 ramdisk, 我自己是給 1G 的空間, 不然可能裝個幾個 kerne/ramdisk 就放不下了.<br />uboot 支援 extlinux 的方式載入 kernel 跟 ramdisk, 所以建一個 extlinux/extlinux.conf 來載入會比使用 uboot 的 script 容易些.<br />至於實際的 linux 分區, 可以用 ext4/f2fs/btrfs/xfs 都可以, 我習慣是用 lvm 搭配 xfs 來使用, 比較方便做 snapshot 來備份.</p><p>Kernel 可以抓 <a href="https://github.com/friendlyarm/uboot-rockchip.git" target="_blank">friendlyarm 的 github</a> 上的 nanopi-r2-v5.10.y 分支來使用, R2S/R4S 可以共用相同的 kernel, 只不過 R2S 使用 rk3328-nanopi-r2-rev00.dtb, 而 R4S 使用 rk3399-nanopi-r4s.dtb.<br />上面的 kernel 是 5.10.60, 可以自己用 patch 到最新的 <a href="https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/log/?h=linux-5.10.y" target="_blank">linux-5.10.y 分支</a> (使用 git 或抓 patch 檔回來都可以).</p><p>另外關於 R2S 的 R8153B 網卡, 用的是 r8152 這個驅動程式, 在我的機器上, 直接用上面 kernel 含的 v1.11.11 版本, 會抓不到網卡, 所以抓<a href="https://github.com/wget/realtek-r8152-linux" target="_blank">這個</a>的 v2.15 回來用, 可以正常使用.<br />只不過這個網卡當成 LAN 使用時, 在透過 NFS 把系統備份到 NAS 上時, 會發生 timeout 的問題, 所以我就把 LAN 跟 WAN 互換來用.</p><p>網卡的名稱可以透過 udev 來改, 產生 /etc/udev/rules.d/70-persistent-net.rules 內容如下:</p><pre class="ini"><div class="insertcode"># R2S<br /># r8152 usb nic<br /><span class="re1">SUBSYSTEM</span><span class="sy0">=</span><span class="re2">=</span><span class="st0">"net"</span>, ACTION<span class="sy0">=</span><span class="re2">=</span><span class="st0">"add"</span>, DRIVERS<span class="sy0">=</span><span class="re2">=</span><span class="st0">"r8152"</span>, NAME<span class="sy0">=</span><span class="st0">"ethext"</span><br /># rockchip built-in nic<br /><span class="re1">SUBSYSTEM</span><span class="sy0">=</span><span class="re2">=</span><span class="st0">"net"</span>, ACTION<span class="sy0">=</span><span class="re2">=</span><span class="st0">"add"</span>, DRIVERS<span class="sy0">=</span><span class="re2">=</span><span class="st0">"rk_gmac-dwmac"</span>, NAME<span class="sy0">=</span><span class="st0">"ethint"</span></div></pre><p> </p><p> 如果是 R4S 的話, 內容如下:</p><pre class="ini"><div class="insertcode"># R4S<br /># r8169<br /><span class="re1">SUBSYSTEM</span><span class="sy0">=</span><span class="re2">=</span><span class="st0">"net"</span>, ACTION<span class="sy0">=</span><span class="re2">=</span><span class="st0">"add"</span>, DRIVERS<span class="sy0">=</span><span class="re2">=</span><span class="st0">"r8169"</span>, NAME<span class="sy0">=</span><span class="st0">"ethint"</span><br /># rockchip built-in nic<br /><span class="re1">SUBSYSTEM</span><span class="sy0">=</span><span class="re2">=</span><span class="st0">"net"</span>, ACTION<span class="sy0">=</span><span class="re2">=</span><span class="st0">"add"</span>, DRIVERS<span class="sy0">=</span><span class="re2">=</span><span class="st0">"rk_gmac-dwmac"</span>, NAME<span class="sy0">=</span><span class="st0">"ethext"</span></div></pre><p> </p><p>另外, R2S 的 r8152 網卡, 會在每次載入模組時, 重新設定 mac address, 如果需要固定的 mac address, 可以在 /etc/network/interfaces 中, 針對該網卡在 pre-up 時執行 ifconfig 去設定 mac address.<br />例如:</p><pre class="ini"><div class="insertcode">auto ethext<br />iface ethext inet static<br /> address 192.168.1.1<br /> netmask 255.255.255.0<br /> pre-up ifconfig ethext hw ether <span class="nu0">11</span>:<span class="nu0">22</span>:<span class="nu0">33</span>:<span class="nu0">44</span>:<span class="nu0">55</span>:<span class="nu0">66</span></div></pre><p> </p><p>依據之前使用 Utilite 的經驗, arm linux 在搞定 uboot/kernel/rootfs 之後, 使用上與 x86 的 linux 並沒有什麼不同. 所以後面 linux 的部份也沒什麼好提了.</p><p>在系統安裝測試正常後, 要把鋁合金的外殼裝上, 就沒辦法把 serial console 接出來用了 (建議以後設計外殼時, 把 serial console 也接出來吧, 不然沒畫面輸出, 又沒 console 可以接, 有問題實在很不方便. 我一度還想找個電鑽來挖洞把接線出來用).</p><div id="gtx-trans" style="position: absolute; left: 783px; top: 663px"><div class="gtx-trans-icon"></div></div>
Linux
2022-01-02T08:54:39Z
tommy
-
小米平板5 root 跟 system writable
https://blog.teatime.com.tw/1/post/491
<div>首先... 記得先解鎖 (一般的帳號應該都是等 168 小時).</div>
<div>目前沒有可以使用的 TWRP (<a href="https://github.com/mujianwu/Action-Recovery-builder/releases" target="_blank" rel="noopener">這邊</a>有一個可開機的版本, 不過只能用來透過 adb 連線使用).</div>
<div>要 root 就先裝 Magisk 的 apk 進去, 然後抓目前同版本的 fastboot rom 裡頭的 boot.img 給 Magisk 修改, 再用 fastboot 刷修改後的 boot.img 就有 root 了.</div>
<div>至於要通過 safetynet, 跟一般沒什麼不同, 相關的 Magisk 模組裝一裝就可通過.</div>
<div> </div>
<div>不過就算 root 之後, system 一樣是不可以寫入的 (新的 Android 應該都一樣, filesystem 有加上 shared_blocks, 所以無法再寫入).</div>
<div>一般如果有 TWRP 可以用, 可以刷 <a href="https://www.mobile01.com/externallink.php?url=https%3A%2F%2Fforum.xda-developers.com%2Ft%2Fscript-android-10-universal-mount-system-rw-super-rw-read-write.4247311%2F" target="_parent">systemrw</a> 移除 shared_blocks 就可以寫入.</div>
<div>不過, 因為還沒有 TWRP 可以用, 這方法目前還不能用.</div>
<div> </div>
<div>只好用另一個 <a href="https://www.mobile01.com/externallink.php?url=https%3A%2F%2Fforum.xda-developers.com%2Ft%2Ftool-win-lin-and-darw-super-image-tools-extract-or-make-partitions-rw-in-super-partition.4120963%2F" target="_parent">Super Image Tools</a> 來處理.</div>
<div>就把 superrepack.arm64_pie 放到 /data/local/tmp 下, 然後在 adb shell 或 terminal 下使用 root 執行下列的指令:</div>
<div>
<pre class="language-bash"><code>chmod +x superrepack.arm64_pie
stop
./superrepack /dev/block/bootdevice/by-name/super</code></pre>
</div>
<p>最後面那個指令執行可能會有錯誤, 要重複執行好幾次, 確定沒有出現錯誤後 (如果有錯誤, 重開機可能會進不去系統), 再執行</p>
<div class="insertcode">
<pre class="language-bash"><code>sync
reboot</code></pre>
</div>
<p>重開機後, 應該就可以寫入了.</p>
<div>如果改了之後有問題, 沒辦法正常開機進入系統, 就只能重刷 fastboot rom (選擇保留資料那一個, 並且把 boot.img 換成前面 Magisk 改過的那一個, 就不用重新再 root 一次).</div>
<div>對了, 照說只改了 super 分區的資料, 只重刷 super.img 應該就夠了, 不過我試了幾次都不行, 就選擇整個重刷.</div>
<div> </div>
<div>PS. 那個 TWRP 目前只是用來刷 win11 進去, 有興趣的可以參考<a href="https://uotan.cn/threads/5-windows11.1975/" target="_blank" rel="noopener">這邊</a>. </div>
Android
2021-12-26T13:25:25Z
tommy
-
知道小米版本號如何取得檔案下載網址的方式
https://blog.teatime.com.tw/1/post/490
<div>原作來自 XDA: <a href="https://forum.xda-developers.com/mi-mix-2/how-to/guide-reverse-engineering-xiaomi-ota-t3691612" target="_blank">https://forum.xda-developers.com/mi-mix-2/how-to/guide-reverse-engineering-xiaomi-ota-t3691612</a> </div><div>方法一不能用了, 不過方法二仍可以使用, 而且... 是目前的更新機制, 應該不容易改... 也許一直能用下去.</div><div><br /></div><div>不知道為什麼, 原作者的 python 程式碼在我的機器上無法正常執行, 在 decrypt 那一個部份一直無法成功.</div><div>所以... 就用 php 改寫一下.</div><div> </div><pre class="php"><div class="insertcode"><span class="kw2"><?php</span><br /> <br /><span class="re0">$cipher</span> <span class="sy0">=</span> <span class="st_h">'rijndael-128'</span><span class="sy0">;</span><br /><span class="re0">$mode</span> <span class="sy0">=</span> <span class="st_h">'cbc'</span><span class="sy0">;</span><br /><span class="re0">$miui_key</span> <span class="sy0">=</span> <span class="st_h">'miuiotavalided11'</span><span class="sy0">;</span><br /><span class="re0">$miui_iv</span> <span class="sy0">=</span> <span class="st_h">'0102030405060708'</span><span class="sy0">;</span><br /> <br /><span class="kw2">function</span> miui_decrypt<span class="br0">(</span><span class="re0">$s</span><span class="br0">)</span><br /><span class="br0">{</span><br /> <span class="kw2">global</span> <span class="re0">$cipher</span><span class="sy0">,</span> <span class="re0">$mode</span><span class="sy0">,</span> <span class="re0">$miui_key</span><span class="sy0">,</span> <span class="re0">$miui_iv</span><span class="sy0">;</span><br /> <br /> <span class="re0">$td</span> <span class="sy0">=</span> <a href="http://www.php.net/mcrypt_module_open"><span class="kw3">mcrypt_module_open</span></a><span class="br0">(</span><span class="re0">$cipher</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$mode</span><span class="sy0">,</span> <span class="st_h">''</span><span class="br0">)</span><span class="sy0">;</span><br /> <a href="http://www.php.net/mcrypt_generic_init"><span class="kw3">mcrypt_generic_init</span></a><span class="br0">(</span><span class="re0">$td</span><span class="sy0">,</span> <span class="re0">$miui_key</span><span class="sy0">,</span> <span class="re0">$miui_iv</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$decrypted</span> <span class="sy0">=</span> <a href="http://www.php.net/mdecrypt_generic"><span class="kw3">mdecrypt_generic</span></a><span class="br0">(</span><span class="re0">$td</span><span class="sy0">,</span> <a href="http://www.php.net/base64_decode"><span class="kw3">base64_decode</span></a><span class="br0">(</span><span class="re0">$s</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span><br /> <a href="http://www.php.net/mcrypt_generic_deinit"><span class="kw3">mcrypt_generic_deinit</span></a><span class="br0">(</span><span class="re0">$td</span><span class="br0">)</span><span class="sy0">;</span><br /> <a href="http://www.php.net/mcrypt_module_close"><span class="kw3">mcrypt_module_close</span></a><span class="br0">(</span><span class="re0">$td</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$pos</span> <span class="sy0">=</span> <a href="http://www.php.net/strrpos"><span class="kw3">strrpos</span></a><span class="br0">(</span><span class="re0">$decrypted</span><span class="sy0">,</span> <span class="st_h">'}'</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$pos</span> <span class="sy0">!==</span> <span class="kw4">false</span><span class="br0">)</span><br /> <span class="kw1">return</span> <a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">(</span><span class="re0">$decrypted</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="re0">$pos</span> <span class="sy0">+</span> <span class="nu0">1</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="re0">$decrypted</span><span class="sy0">;</span><br /><span class="br0">}</span><br /> <br /><span class="kw2">function</span> miui_encrypt<span class="br0">(</span><span class="re0">$s</span><span class="br0">)</span><br /><span class="br0">{</span><br /> <span class="kw2">global</span> <span class="re0">$cipher</span><span class="sy0">,</span> <span class="re0">$mode</span><span class="sy0">,</span> <span class="re0">$miui_key</span><span class="sy0">,</span> <span class="re0">$miui_iv</span><span class="sy0">;</span><br /> <br /> <span class="re0">$td</span> <span class="sy0">=</span> <a href="http://www.php.net/mcrypt_module_open"><span class="kw3">mcrypt_module_open</span></a><span class="br0">(</span><span class="re0">$cipher</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$mode</span><span class="sy0">,</span> <span class="st_h">''</span><span class="br0">)</span><span class="sy0">;</span><br /> <a href="http://www.php.net/mcrypt_generic_init"><span class="kw3">mcrypt_generic_init</span></a><span class="br0">(</span><span class="re0">$td</span><span class="sy0">,</span> <span class="re0">$miui_key</span><span class="sy0">,</span> <span class="re0">$miui_iv</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$bs</span> <span class="sy0">=</span> <a href="http://www.php.net/mcrypt_get_block_size"><span class="kw3">mcrypt_get_block_size</span></a><span class="br0">(</span><span class="re0">$cipher</span><span class="sy0">,</span> <span class="re0">$mode</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$n</span> <span class="sy0">=</span> <span class="re0">$bs</span> <span class="sy0">-</span> <span class="br0">(</span><a href="http://www.php.net/strlen"><span class="kw3">strlen</span></a><span class="br0">(</span><span class="re0">$s</span><span class="br0">)</span> <span class="sy0">%</span> <span class="re0">$bs</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">while</span> <span class="br0">(</span><span class="re0">$bs</span> <span class="sy0">-</span> <span class="br0">(</span><a href="http://www.php.net/strlen"><span class="kw3">strlen</span></a><span class="br0">(</span><span class="re0">$s</span><span class="br0">)</span> <span class="sy0">%</span> <span class="re0">$bs</span><span class="br0">)</span> <span class="sy0">!=</span> <span class="re0">$bs</span><span class="br0">)</span><br /> <span class="re0">$s</span> <span class="sy0">.=</span> <a href="http://www.php.net/chr"><span class="kw3">chr</span></a><span class="br0">(</span><span class="re0">$n</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$encrypted</span> <span class="sy0">=</span> <a href="http://www.php.net/base64_encode"><span class="kw3">base64_encode</span></a><span class="br0">(</span><a href="http://www.php.net/mcrypt_generic"><span class="kw3">mcrypt_generic</span></a><span class="br0">(</span><span class="re0">$td</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span><br /> <a href="http://www.php.net/mcrypt_generic_deinit"><span class="kw3">mcrypt_generic_deinit</span></a><span class="br0">(</span><span class="re0">$td</span><span class="br0">)</span><span class="sy0">;</span><br /> <a href="http://www.php.net/mcrypt_module_close"><span class="kw3">mcrypt_module_close</span></a><span class="br0">(</span><span class="re0">$td</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="re0">$encrypted</span><span class="sy0">;</span><br /><span class="br0">}</span><br /> <br /><span class="re0">$checkurl</span> <span class="sy0">=</span> <span class="st_h">'http://update.miui.com/updates/miotaV3.php'</span><span class="sy0">;</span><br /> <br /><span class="re0">$device_data</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><br /> <span class="st0">"a"</span> <span class="sy0">=></span> <span class="st0">"0"</span><span class="sy0">,</span> <span class="co2"># Don't know what this is.<br /></span> <span class="st0">"c"</span> <span class="sy0">=></span> <span class="st0">"7.0"</span><span class="sy0">,</span> <span class="co2"># Same as 'c' above, it's the Android version.<br /></span> <span class="st0">"b"</span> <span class="sy0">=></span> <span class="st0">"F"</span><span class="sy0">,</span> <span class="co2"># Same as above, 'X' for weekly build.<br /></span> <span class="st0">"d"</span> <span class="sy0">=></span> <span class="st0">"mido_global"</span><span class="sy0">,</span> <span class="co2"># The device name, same as above, chiron for Chinese, chiron_global for global.<br /></span> <span class="st0">"g"</span> <span class="sy0">=></span> <span class="st0">"00000000000000000000000000000000"</span><span class="sy0">,</span> <span class="co2"># This seems to be the android_id of the device. Maybe encoded somehow.<br /></span> <span class="st0">"cts"</span> <span class="sy0">=></span> <span class="st0">"0"</span><span class="sy0">,</span> <span class="co2"># I don't know what this is.<br /></span> <span class="st0">"i"</span> <span class="sy0">=></span> <span class="st0">"0000000000000000000000000000000000000000000000000000000000000000"</span><span class="sy0">,</span> <span class="co2"># This seems to be the imei of the device, obviously encoded somehow.<br /></span> <span class="st0">"isR"</span> <span class="sy0">=></span> <span class="st0">"0"</span><span class="sy0">,</span> <span class="co2"># I don't know what this is.<br /></span> <span class="st0">"f"</span> <span class="sy0">=></span> <span class="st0">"1"</span><span class="sy0">,</span> <span class="co2"># I don't know what this is.<br /></span> <span class="st0">"l"</span> <span class="sy0">=></span> <span class="st0">"en_US"</span><span class="sy0">,</span> <span class="co2"># The locale.<br /></span> <span class="st0">"n"</span> <span class="sy0">=></span> <span class="st0">""</span><span class="sy0">,</span> <span class="co2"># I don't know what this parameter is<br /></span> <span class="st0">"sys"</span> <span class="sy0">=></span> <span class="st0">"0"</span><span class="sy0">,</span> <span class="co2"># I don't know what this is.<br /></span> <span class="st0">"p"</span> <span class="sy0">=></span> <span class="st0">"msm8953"</span><span class="sy0">,</span> <span class="co2"># The chipset<br /></span> <span class="st0">"unlock"</span> <span class="sy0">=></span> <span class="st0">"1"</span><span class="sy0">,</span> <span class="co2"># 1 means bootloader is unlocked. 0 means locked.<br /></span> <span class="st0">"r"</span> <span class="sy0">=></span> <span class="st0">"CN"</span><span class="sy0">,</span> <span class="co2"># I don't know what this is, maybe region of device?<br /></span> <span class="st0">"sn"</span> <span class="sy0">=></span> <span class="st0">"0x00000000"</span><span class="sy0">,</span> <span class="co2"># Probably the serial number of the device, maybe encoded somehow.<br /></span> <span class="st0">"v"</span> <span class="sy0">=></span> <span class="st0">"MIUI-V9.0.5.0.NCFMIEI"</span><span class="sy0">,</span> <span class="co2"># The version of MIUI installed.<br /></span> <span class="co1">//"v" => "MIUI-V8.5.8.0.NCFMIED",</span><br /> <span class="st0">"bv"</span> <span class="sy0">=></span> <span class="st0">"9"</span><span class="sy0">,</span> <span class="co2"># I don't know what this is.<br /></span> <span class="st0">"id"</span> <span class="sy0">=></span> <span class="st0">""</span><span class="sy0">,</span> <span class="co2"># I don't' know what this is.<br /></span><span class="br0">)</span><span class="sy0">;</span><br /> <br /><span class="re0">$js</span> <span class="sy0">=</span> <a href="http://www.php.net/json_encode"><span class="kw3">json_encode</span></a><span class="br0">(</span><span class="re0">$device_data</span><span class="br0">)</span><span class="sy0">;</span><br /> <br /><span class="re0">$postdata</span> <span class="sy0">=</span> <span class="st0">"q="</span><span class="sy0">.</span><a href="http://www.php.net/urlencode"><span class="kw3">urlencode</span></a><span class="br0">(</span>miui_encrypt<span class="br0">(</span><span class="re0">$js</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">.</span><span class="st0">"&t=&s=1"</span><span class="sy0">;</span><br /> <br /><span class="re0">$curl</span> <span class="sy0">=</span> <a href="http://www.php.net/curl_init"><span class="kw3">curl_init</span></a><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span><br /><a href="http://www.php.net/curl_setopt"><span class="kw3">curl_setopt</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="sy0">,</span> CURLOPT_URL<span class="sy0">,</span> <span class="re0">$checkurl</span><span class="br0">)</span><span class="sy0">;</span><br /><a href="http://www.php.net/curl_setopt"><span class="kw3">curl_setopt</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="sy0">,</span> CURLOPT_RETURNTRANSFER<span class="sy0">,</span> <span class="nu0">1</span><span class="br0">)</span><span class="sy0">;</span><br /><a href="http://www.php.net/curl_setopt"><span class="kw3">curl_setopt</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="sy0">,</span> CURLOPT_FOLLOWLOCATION<span class="sy0">,</span> <span class="nu0">1</span><span class="br0">)</span><span class="sy0">;</span><br /><a href="http://www.php.net/curl_setopt"><span class="kw3">curl_setopt</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="sy0">,</span> CURLOPT_HEADER<span class="sy0">,</span> <span class="nu0">0</span><span class="br0">)</span><span class="sy0">;</span><br /><a href="http://www.php.net/curl_setopt"><span class="kw3">curl_setopt</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="sy0">,</span> CURLOPT_POST<span class="sy0">,</span> <span class="nu0">1</span><span class="br0">)</span><span class="sy0">;</span><br /><a href="http://www.php.net/curl_setopt"><span class="kw3">curl_setopt</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="sy0">,</span> CURLOPT_POSTFIELDS<span class="sy0">,</span> <span class="re0">$postdata</span><span class="br0">)</span><span class="sy0">;</span><br /><span class="re0">$data</span> <span class="sy0">=</span> <a href="http://www.php.net/curl_exec"><span class="kw3">curl_exec</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="br0">)</span><span class="sy0">;</span><br /><span class="kw1">if</span> <span class="br0">(</span><span class="re0">$data</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="kw1">echo</span> <span class="st0">"*** curl_exec() failed: "</span><span class="sy0">.</span><a href="http://www.php.net/curl_errno"><span class="kw3">curl_errno</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="br0">)</span><span class="sy0">.</span><span class="st0">" => "</span><span class="sy0">.</span><a href="http://www.php.net/curl_error"><span class="kw3">curl_error</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="br0">)</span><span class="sy0">.</span><span class="st0">"<span class="es1">\n</span>"</span><span class="sy0">;</span><br /> <a href="http://www.php.net/curl_close"><span class="kw3">curl_close</span></a><span class="br0">(</span><span class="re0">$curl</span><span class="br0">)</span><span class="sy0">;</span><br /> <a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="sy0">;</span><br /><span class="br0">}</span><br /> <br /><span class="re0">$r</span> <span class="sy0">=</span> miui_decrypt<span class="br0">(</span><span class="re0">$data</span><span class="br0">)</span><span class="sy0">;</span><br /><span class="re0">$result</span> <span class="sy0">=</span> <a href="http://www.php.net/json_decode"><span class="kw3">json_decode</span></a><span class="br0">(</span><span class="re0">$r</span><span class="br0">)</span><span class="sy0">;</span><br /><a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">(</span><span class="re0">$result</span><span class="br0">)</span><span class="sy0">;</span><br /> <br /><a href="http://www.php.net/exit"><span class="kw3">exit</span></a><span class="sy0">;</span></div></pre><p> </p><div> </div><div>上面那個是用紅米 Note4X 國際版為例子. 找 MIUI-V9.0.5.0.NCFMIEI 的升級版本.</div><div>如果要找其他的機型, 請改 c, d, v 這三個值, c 是 Android 版本, d 是機型代碼 (國際版加上 _global), v 是版本名稱.</div><div><br /></div><div>會列出該版本之後的版本 (如果是最新的, 就會列出目前這個版本).</div><div>所以... 我們就可以取得 V9.0.5.0.NCFMIEI 這個版本的檔名: miui_HMNote4XGlobal_V9.0.5.0.NCFMIEI_d6176de291_7.0.zip</div><div><br /></div><div>有檔名之後, 小米的路徑規則是 http://bigota.d.miui.com/版本/檔案</div><div>所以下載的網址就是 <a href="http://bigota.d.miui.com/V9.0.5.0.NCFMIEI/miui_HMNote4XGlobal_V9.0.5.0.NCFMIEI_d6176de291_7.0.zip" target="_blank">http://bigota.d.miui.com/V9.0.5.0.NCFMIEI/miui_HMNote4XGlobal_V9.0.5.0.NCFMIEI_d6176de291_7.0.zip</a> </div><div><br /></div>
Android
2017-11-26T11:28:04Z
tommy
-
讓 vsftpd 3.0.3 在 local 網路連線時, 不使用 pasv_address 的設定
https://blog.teatime.com.tw/1/post/487
<p>近來 (應該也有一陣子了) 發現用 <a href="https://filezilla-project.org/" target="_blank">FileZilla</a> 連到家裡的 ftp 時, 使用 TLS 連線會每隔 20 秒出現一次逾時錯誤訊息就離線. 而且在部網路直接連線時, 會有一樣的問題, 應該跟 firewall 沒關係. <a href="https://forum.filezilla-project.org/viewtopic.php?f=2&t=7688" target="_blank">在 FileZilla 的討論區有提到 Pure-ftpd <= 1.0.38 時會有問題</a>, 不過家裡的伺服器應該是 1.0.46 (印象中, 以前使用 1.0.3x 的版本並沒有這個錯誤). 所以試著換了 <a href="https://security.appspot.com/vsftpd.html" target="_blank">vsftpd</a> 3.0.3 來使用, 還真的就不會出現這個訊息了.</p><p>不過換上 vsftpd 之後, 就碰到之前在 <a href="https://www.pureftpd.org/project/pure-ftpd" target="_blank">pure-ftpd</a> 時相同的問題, 就是使用 passive 模式時, 如果指定使用外部的 ip 之後, 會造成內部的連線也收到外部的 ip 而無法使用. 如果不指定外部 ip 時, 會造成外部的連線收到內部的 ip 而無法連線 (使用 filezilla 時, 這情形會用連線的 ip 取代, 可以繼續使用).</p><p>所以... 就把之前給 pure-ftpd 的 patch 改了一下給 vsftpd 用:</p><pre class="diff"><div class="insertcode">diff --show-c-function -Nur vsftpd-3.0.3.orig/main.c vsftpd-3.0.3/main.c<br /><span class="re3">--- vsftpd-3.0.3.orig/main.c 2012-09-16 12:27:13.000000000 +0800</span><br /><span class="re4">+++ vsftpd-3.0.3/main.c 2017-09-28 21:10:16.620440681 +0800</span><br /><span class="re6">@@ -32,6 +32,70 @@ static void session_init<span class="br0">(</span>struct vsf_sess</span><br /> static void env_init<span class="br0">(</span>void<span class="br0">)</span>;<br /> static void limits_init<span class="br0">(</span>void<span class="br0">)</span>;<br /> <br /><span class="re8">+// add by twu2 20170928 begin</span><br /><span class="re8">+#include <stdio.h></span><br /><span class="re8">+#include "filestr.h"</span><br /><span class="re8">+// check local net in /etc/localnet</span><br /><span class="re8">+static int check_local_net<span class="br0">(</span>const struct vsf_sysutil_sockaddr * const addr<span class="br0">)</span></span><br /><span class="re8">+<span class="br0">{</span></span><br /><span class="re8">+ unsigned long a1 = 0U;</span><br /><span class="re8">+ unsigned long a2 = 0U;</span><br /><span class="re8">+ unsigned long mask = 0U;</span><br /><span class="re8">+ unsigned int b1, b2, b3, b4;</span><br /><span class="re8">+ unsigned int m1, m2, m3, m4;</span><br /><span class="re8">+ static struct mystr s_curr_line_str;</span><br /><span class="re8">+ unsigned int pos = <span class="nu0">0</span>;</span><br /><span class="re8">+ struct mystr localnet_file = INIT_MYSTR;</span><br /><span class="re8">+ int retval = -<span class="nu0">1</span>;</span><br /><span class="re8">+ const void* p_v4addr;</span><br /><span class="re8">+ int is_ipv6;</span><br /><span class="re8">+ const char *ip;</span><br /><span class="re8">+ int is_local;</span><br /><span class="re8">+</span><br /><span class="re8">+ if <span class="br0">(</span>!addr<span class="br0">)</span> return <span class="nu0">0</span>;</span><br /><span class="re8">+ is_ipv6 = vsf_sysutil_sockaddr_is_ipv6<span class="br0">(</span>addr<span class="br0">)</span>;</span><br /><span class="re8">+ if <span class="br0">(</span>is_ipv6<span class="br0">)</span> <span class="br0">{</span></span><br /><span class="re8">+ p_v4addr = vsf_sysutil_sockaddr_ipv6_v4<span class="br0">(</span>addr<span class="br0">)</span>;</span><br /><span class="re8">+ if <span class="br0">(</span>!p_v4addr<span class="br0">)</span> return <span class="nu0">0</span>;</span><br /><span class="re8">+ ip = vsf_sysutil_inet_ntoa<span class="br0">(</span>p_v4addr<span class="br0">)</span>;</span><br /><span class="re8">+ <span class="br0">}</span></span><br /><span class="re8">+ else</span><br /><span class="re8">+ ip = vsf_sysutil_inet_ntop<span class="br0">(</span>addr<span class="br0">)</span>;</span><br /><span class="re8">+ if <span class="br0">(</span>!ip<span class="br0">)</span> return <span class="nu0">0</span>;</span><br /><span class="re8">+ b1 = b2 = b3 = b4 = <span class="nu0">0</span>;</span><br /><span class="re8">+ if <span class="br0">(</span><span class="br0">(</span>sscanf<span class="br0">(</span>ip, "%u.%u.%u.%u", &b1, &b2, &b3, &b4<span class="br0">)</span> != <span class="nu0">4</span><span class="br0">)</span> ||</span><br /><span class="re8">+ b1 > 255U || b2 > 255U || b3 > 255U || b4 > 255U ||</span><br /><span class="re8">+ <span class="br0">(</span>b1 | b2 | b3 | b4<span class="br0">)</span> == 0U<span class="br0">)</span></span><br /><span class="re8">+ return <span class="nu0">0</span>;</span><br /><span class="re8">+ a1 = b1 << <span class="nu0">24</span> | b2 << <span class="nu0">16</span> | b3 << <span class="nu0">8</span> | b4;</span><br /><span class="re8">+ retval = str_fileread<span class="br0">(</span>&localnet_file, tunable_local_net_file,</span><br /><span class="re8">+ VSFTP_CONF_FILE_MAX<span class="br0">)</span>;</span><br /><span class="re8">+ // no localnet file</span><br /><span class="re8">+ if <span class="br0">(</span>vsf_sysutil_retval_is_error<span class="br0">(</span>retval<span class="br0">)</span><span class="br0">)</span></span><br /><span class="re8">+ return <span class="nu0">0</span>;</span><br /><span class="re8">+ is_local = <span class="nu0">0</span>;</span><br /><span class="re8">+ while <span class="br0">(</span>str_getline<span class="br0">(</span>&localnet_file, &s_curr_line_str, &pos<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span></span><br /><span class="re8">+ b1 = b2 = b3 = b4 = m1 = m2 = m3 = m4 = <span class="nu0">0</span>;</span><br /><span class="re8">+ if <span class="br0">(</span><span class="br0">(</span>sscanf<span class="br0">(</span>str_getbuf<span class="br0">(</span>&s_curr_line_str<span class="br0">)</span>, "%u.%u.%u.%u/%u.%u.%u.%u", &b1, &b2, &b3, &b4, &m1, &m2, &m3, &m4<span class="br0">)</span> != <span class="nu0">8</span><span class="br0">)</span> ||</span><br /><span class="re8">+ b1 > 255U || b2 > 255U || b3 > 255U || b4 > 255U ||</span><br /><span class="re8">+ <span class="br0">(</span>b1 | b2 | b3 | b4<span class="br0">)</span> == 0U ||</span><br /><span class="re8">+ m1 > 255U || m2 > 255U || m3 > 255U || m4 > 255U ||</span><br /><span class="re8">+ <span class="br0">(</span>m1 | m2 | m3 | m4<span class="br0">)</span> == 0U<span class="br0">)</span></span><br /><span class="re8">+ continue;</span><br /><span class="re8">+ a2 = b1 << <span class="nu0">24</span> | b2 << <span class="nu0">16</span> | b3 << <span class="nu0">8</span> | b4;</span><br /><span class="re8">+ mask = m1 << <span class="nu0">24</span> | m2 << <span class="nu0">16</span> | m3 << <span class="nu0">8</span> | m4;</span><br /><span class="re8">+ // correct format</span><br /><span class="re8">+ if <span class="br0">(</span><span class="br0">(</span>a1 & mask<span class="br0">)</span> == <span class="br0">(</span>a2 & mask<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span></span><br /><span class="re8">+ // same subnet</span><br /><span class="re8">+ is_local = <span class="nu0">1</span>;</span><br /><span class="re8">+ break;</span><br /><span class="re8">+ <span class="br0">}</span></span><br /><span class="re8">+ <span class="br0">}</span></span><br /><span class="re8">+ str_free<span class="br0">(</span>&localnet_file<span class="br0">)</span>;</span><br /><span class="re8">+ return is_local;</span><br /><span class="re8">+<span class="br0">}</span></span><br /><span class="re8">+// add by twu2 20170928 end</span><br /><span class="re8">+</span><br /> int<br /> main<span class="br0">(</span>int argc, const char* argv<span class="br0">[</span><span class="br0">]</span><span class="br0">)</span><br /> <span class="br0">{</span><br /><span class="re6">@@ -67,6 +131,12 @@ main<span class="br0">(</span>int argc, const char* argv<span class="br0">[</span><span class="br0">]</span><span class="br0">)</span></span><br /> <span class="nu0">0</span>, <span class="nu0">0</span>, <span class="nu0">0</span>, <span class="nu0">0</span>, <span class="nu0">0</span>, INIT_MYSTR, <span class="nu0">0</span>, -<span class="nu0">1</span>, -<span class="nu0">1</span>,<br /> /* Login fails */<br /> <span class="nu0">0</span><br /><span class="re8">+ // add by twu2 20170928 begin</span><br /><span class="re8">+ /* is_local */</span><br /><span class="re8">+ ,0</span><br /><span class="re8">+ /* nomaxrate */</span><br /><span class="re8">+ ,0</span><br /><span class="re8">+ // add by twu2 20170928 end</span><br /> <span class="br0">}</span>;<br /> int config_loaded = <span class="nu0">0</span>;<br /> int i;<br /><span class="re6">@@ -243,6 +313,9 @@ main<span class="br0">(</span>int argc, const char* argv<span class="br0">[</span><span class="br0">]</span><span class="br0">)</span></span><br /> tunable_chown_uploads = <span class="nu0">0</span>;<br /> <span class="br0">}</span><br /> <span class="br0">}</span><br /><span class="re8">+ // add by twu2 20170928 begin</span><br /><span class="re8">+ the_session.is_local = check_local_net<span class="br0">(</span>the_session.p_remote_addr<span class="br0">)</span>;</span><br /><span class="re8">+ // add by twu2 20170928 end</span><br /> if <span class="br0">(</span>tunable_one_process_model<span class="br0">)</span><br /> <span class="br0">{</span><br /> vsf_one_process_start<span class="br0">(</span>&the_session<span class="br0">)</span>;<br />diff --show-c-function -Nur vsftpd-3.0.3.orig/parseconf.c vsftpd-3.0.3/parseconf.c<br /><span class="re3">--- vsftpd-3.0.3.orig/parseconf.c 2017-09-28 14:40:29.000000000 +0800</span><br /><span class="re4">+++ vsftpd-3.0.3/parseconf.c 2017-09-28 21:10:31.892567245 +0800</span><br /><span class="re6">@@ -158,6 +158,10 @@ parseconf_str_array<span class="br0">[</span><span class="br0">]</span> =</span><br /> <span class="br0">{</span> "ftpd_banner", &tunable_ftpd_banner <span class="br0">}</span>,<br /> <span class="br0">{</span> "banned_email_file", &tunable_banned_email_file <span class="br0">}</span>,<br /> <span class="br0">{</span> "chroot_list_file", &tunable_chroot_list_file <span class="br0">}</span>,<br /><span class="re8">+ // add by twu2 20170928 begin</span><br /><span class="re8">+ <span class="br0">{</span> "local_net_file", &tunable_local_net_file <span class="br0">}</span>,</span><br /><span class="re8">+ <span class="br0">{</span> "nomaxrate_list_file", &tunable_nomaxrate_list_file <span class="br0">}</span>,</span><br /><span class="re8">+ // add by twu2 20170928 end</span><br /> <span class="br0">{</span> "pam_service_name", &tunable_pam_service_name <span class="br0">}</span>,<br /> <span class="br0">{</span> "guest_username", &tunable_guest_username <span class="br0">}</span>,<br /> <span class="br0">{</span> "userlist_file", &tunable_userlist_file <span class="br0">}</span>,<br />diff --show-c-function -Nur vsftpd-3.0.3.orig/postlogin.c vsftpd-3.0.3/postlogin.c<br /><span class="re3">--- vsftpd-3.0.3.orig/postlogin.c 2017-09-28 14:40:29.000000000 +0800</span><br /><span class="re4">+++ vsftpd-3.0.3/postlogin.c 2017-09-28 22:27:59.791545391 +0800</span><br /><span class="re6">@@ -94,6 +94,10 @@ process_post_login<span class="br0">(</span>struct vsf_session* p</span><br /> vsf_sysutil_set_umask<span class="br0">(</span>tunable_local_umask<span class="br0">)</span>;<br /> p_sess->bw_rate_max = tunable_local_max_rate;<br /> <span class="br0">}</span><br /><span class="re8">+ // modified by twu2 20170928 begin</span><br /><span class="re8">+ if <span class="br0">(</span>p_sess->nomaxrate<span class="br0">)</span></span><br /><span class="re8">+ p_sess->bw_rate_max = <span class="nu0">0</span>;</span><br /><span class="re8">+ // modified by twu2 20170928 end</span><br /> if <span class="br0">(</span>p_sess->is_http<span class="br0">)</span><br /> <span class="br0">{</span><br /> handle_http<span class="br0">(</span>p_sess<span class="br0">)</span>;<br /><span class="re6">@@ -606,8 +610,10 @@ handle_pasv<span class="br0">(</span>struct vsf_session* p_sess,</span><br /> str_append_text<span class="br0">(</span>&s_pasv_res_str, "|<span class="br0">)</span>"<span class="br0">)</span>;<br /> vsf_cmdio_write_str<span class="br0">(</span>p_sess, FTP_EPSVOK, &s_pasv_res_str<span class="br0">)</span>;<br /> return;<br /><span class="re7">- <span class="br0">}</span></span><br /><span class="re7">- if <span class="br0">(</span>tunable_pasv_address != 0<span class="br0">)</span></span><br /><span class="re8">+ <span class="br0">}</span> </span><br /><span class="re8">+ // modified by twu2 20170928 begin</span><br /><span class="re8">+ if <span class="br0">(</span>tunable_pasv_address != 0 && p_sess->is_local == 0<span class="br0">)</span></span><br /><span class="re8">+ // modified by twu2 20170928 end</span><br /> <span class="br0">{</span><br /> vsf_sysutil_sockaddr_alloc_ipv4<span class="br0">(</span>&s_p_sockaddr<span class="br0">)</span>;<br /> /* Report passive address as specified in configuration */<br /><span class="re6">@@ -1829,6 +1835,12 @@ handle_stat<span class="br0">(</span>struct vsf_session* p_sess<span class="br0">)</span></span><br /> vsf_cmdio_write_hyphen<span class="br0">(</span>p_sess, FTP_STATOK, "FTP server status:"<span class="br0">)</span>;<br /> vsf_cmdio_write_raw<span class="br0">(</span>p_sess, " Connected to "<span class="br0">)</span>;<br /> vsf_cmdio_write_raw<span class="br0">(</span>p_sess, str_getbuf<span class="br0">(</span>&p_sess->remote_ip_str<span class="br0">)</span><span class="br0">)</span>;<br /><span class="re8">+ // modified by twu2 20170928 begin</span><br /><span class="re8">+ if <span class="br0">(</span>p_sess->is_local<span class="br0">)</span></span><br /><span class="re8">+ vsf_cmdio_write_raw<span class="br0">(</span>p_sess, ", <span class="br0">(</span>LAN<span class="br0">)</span>"<span class="br0">)</span>;</span><br /><span class="re8">+ else</span><br /><span class="re8">+ vsf_cmdio_write_raw<span class="br0">(</span>p_sess, ", <span class="br0">(</span>WAN<span class="br0">)</span>"<span class="br0">)</span>;</span><br /><span class="re8">+ // modified by twu2 20170928 end</span><br /> vsf_cmdio_write_raw<span class="br0">(</span>p_sess, "\r\n"<span class="br0">)</span>;<br /> vsf_cmdio_write_raw<span class="br0">(</span>p_sess, " Logged in as "<span class="br0">)</span>;<br /> vsf_cmdio_write_raw<span class="br0">(</span>p_sess, str_getbuf<span class="br0">(</span>&p_sess->user_str<span class="br0">)</span><span class="br0">)</span>;<br />diff --show-c-function -Nur vsftpd-3.0.3.orig/session.h vsftpd-3.0.3/session.h<br /><span class="re3">--- vsftpd-3.0.3.orig/session.h 2012-04-05 09:27:19.000000000 +0800</span><br /><span class="re4">+++ vsftpd-3.0.3/session.h 2017-09-28 21:09:03.871838330 +0800</span><br /><span class="re6">@@ -99,6 +99,10 @@ struct vsf_session</span><br /> int ssl_slave_fd;<br /> int ssl_consumer_fd;<br /> unsigned int login_fails;<br /><span class="re8">+ // add by twu2 20170928 begin</span><br /><span class="re8">+ int is_local;</span><br /><span class="re8">+ int nomaxrate;</span><br /><span class="re8">+ // add by twu2 20170928 end</span><br /> <span class="br0">}</span>;<br /> <br /> #endif /* VSF_SESSION_H */<br />diff --show-c-function -Nur vsftpd-3.0.3.orig/tunables.c vsftpd-3.0.3/tunables.c<br /><span class="re3">--- vsftpd-3.0.3.orig/tunables.c 2017-09-28 14:40:29.000000000 +0800</span><br /><span class="re4">+++ vsftpd-3.0.3/tunables.c 2017-09-28 21:10:58.748789905 +0800</span><br /><span class="re6">@@ -<span class="nu0">121</span>,<span class="nu0">6</span> +<span class="nu0">121</span>,<span class="nu0">10</span> @@ const char* tunable_nopriv_user;</span><br /> const char* tunable_ftpd_banner;<br /> const char* tunable_banned_email_file;<br /> const char* tunable_chroot_list_file;<br /><span class="re8">+// add by twu2 20170928 begin</span><br /><span class="re8">+const char* tunable_local_net_file;</span><br /><span class="re8">+const char* tunable_nomaxrate_list_file;</span><br /><span class="re8">+// add by twu2 20170928 end</span><br /> const char* tunable_pam_service_name;<br /> const char* tunable_guest_username;<br /> const char* tunable_userlist_file;<br /><span class="re6">@@ -268,6 +272,10 @@ tunables_load_defaults<span class="br0">(</span><span class="br0">)</span></span><br /> install_str_setting<span class="br0">(</span><span class="nu0">0</span>, &tunable_ftpd_banner<span class="br0">)</span>;<br /> install_str_setting<span class="br0">(</span>"/etc/vsftpd.banned_emails", &tunable_banned_email_file<span class="br0">)</span>;<br /> install_str_setting<span class="br0">(</span>"/etc/vsftpd.chroot_list", &tunable_chroot_list_file<span class="br0">)</span>;<br /><span class="re8">+ // add by twu2 20170928 begin</span><br /><span class="re8">+ install_str_setting<span class="br0">(</span>"/etc/localnet", &tunable_local_net_file<span class="br0">)</span>;</span><br /><span class="re8">+ install_str_setting<span class="br0">(</span>"/etc/vsftpd.nomaxrate_list", &tunable_nomaxrate_list_file<span class="br0">)</span>;</span><br /><span class="re8">+ // add by twu2 20170928 end</span><br /> install_str_setting<span class="br0">(</span>"vsftpd", &tunable_pam_service_name<span class="br0">)</span>;<br /> install_str_setting<span class="br0">(</span>"ftp", &tunable_guest_username<span class="br0">)</span>;<br /> install_str_setting<span class="br0">(</span>"/etc/vsftpd.user_list", &tunable_userlist_file<span class="br0">)</span>;<br />diff --show-c-function -Nur vsftpd-3.0.3.orig/tunables.h vsftpd-3.0.3/tunables.h<br /><span class="re3">--- vsftpd-3.0.3.orig/tunables.h 2017-09-28 14:40:29.000000000 +0800</span><br /><span class="re4">+++ vsftpd-3.0.3/tunables.h 2017-09-28 20:57:15.750028392 +0800</span><br /><span class="re6">@@ -<span class="nu0">124</span>,<span class="nu0">6</span> +<span class="nu0">124</span>,<span class="nu0">10</span> @@ extern const char* tunable_nopriv_user;</span><br /> extern const char* tunable_ftpd_banner;<br /> extern const char* tunable_banned_email_file;<br /> extern const char* tunable_chroot_list_file;<br /><span class="re8">+// add by twu2 20170928 begin</span><br /><span class="re8">+extern const char* tunable_local_net_file;</span><br /><span class="re8">+extern const char* tunable_nomaxrate_list_file;</span><br /><span class="re8">+// add by twu2 20170928 end</span><br /> extern const char* tunable_pam_service_name;<br /> extern const char* tunable_guest_username;<br /> extern const char* tunable_userlist_file;<br />diff --show-c-function -Nur vsftpd-3.0.3.orig/twoprocess.c vsftpd-3.0.3/twoprocess.c<br /><span class="re3">--- vsftpd-3.0.3.orig/twoprocess.c 2012-09-16 15:15:49.000000000 +0800</span><br /><span class="re4">+++ vsftpd-3.0.3/twoprocess.c 2017-09-29 23:18:56.487053338 +0800</span><br /><span class="re6">@@ -358,6 +358,9 @@ process_login_req<span class="br0">(</span>struct vsf_session* p_</span><br /> if <span class="br0">(</span>do_chroot<span class="br0">)</span><br /> <span class="br0">{</span><br /> do_chroot = <span class="nu0">0</span>;<br /><span class="re8">+ // add by twu2 20170928 begin</span><br /><span class="re8">+ tunable_idle_session_timeout = <span class="nu0">0</span>;</span><br /><span class="re8">+ // add by twu2 20170928 end</span><br /> <span class="br0">}</span><br /> else<br /> <span class="br0">{</span><br /><span class="re6">@@ -366,6 +369,23 @@ process_login_req<span class="br0">(</span>struct vsf_session* p_</span><br /> <span class="br0">}</span><br /> str_free<span class="br0">(</span>&chroot_list_file<span class="br0">)</span>;<br /> <span class="br0">}</span><br /><span class="re8">+ // add by twu2 20170928 begin</span><br /><span class="re8">+ p_sess->nomaxrate = <span class="nu0">0</span>;</span><br /><span class="re8">+ if <span class="br0">(</span>tunable_nomaxrate_list_file<span class="br0">)</span></span><br /><span class="re8">+ <span class="br0">{</span></span><br /><span class="re8">+ struct mystr nomaxrate_list_file = INIT_MYSTR;</span><br /><span class="re8">+ int retval;</span><br /><span class="re8">+</span><br /><span class="re8">+ retval = str_fileread<span class="br0">(</span>&nomaxrate_list_file, tunable_nomaxrate_list_file,</span><br /><span class="re8">+ VSFTP_CONF_FILE_MAX<span class="br0">)</span>;</span><br /><span class="re8">+ if <span class="br0">(</span>!vsf_sysutil_retval_is_error<span class="br0">(</span>retval<span class="br0">)</span><span class="br0">)</span></span><br /><span class="re8">+ <span class="br0">{</span></span><br /><span class="re8">+ if <span class="br0">(</span>str_contains_line<span class="br0">(</span>&nomaxrate_list_file, &p_sess->user_str<span class="br0">)</span><span class="br0">)</span></span><br /><span class="re8">+ p_sess->nomaxrate = <span class="nu0">1</span>;</span><br /><span class="re8">+ <span class="br0">}</span></span><br /><span class="re8">+ str_free<span class="br0">(</span>&nomaxrate_list_file<span class="br0">)</span>;</span><br /><span class="re8">+ <span class="br0">}</span></span><br /><span class="re8">+ // add by twu2 20170928 end</span><br /> common_do_login<span class="br0">(</span>p_sess, &p_sess->user_str, do_chroot, <span class="nu0">0</span><span class="br0">)</span>;<br /> <span class="br0">}</span><br /> break;</div></pre><p> </p><p>檔案可以在這兒抓: <a href="https://www.teatime.com.tw/~tommy/mypatch/vsftpd-3.0.3-localnet.patch" target="_blank">https://www.teatime.com.tw/~tommy/mypatch/vsftpd-3.0.3-localnet.patch</a> </p><p>patch 的內容有三個部份:</p><p> </p><ol><li>主要是上面提到的 <a href="https://blog.teatime.com.tw/1/post/76" target="_blank">pasv_address 會依據 /etc/localnet 的內容決定是否使用</a> .</li><li>檢查 /etc/vsftpd.nomaxrate_list, 如果在裡頭就<a href="https://blog.teatime.com.tw/1/post/122" target="_blank">不限制傳輸的速度</a> </li><li>如果預設是 chroot, 而列在 /etc/vsftpd.chroot_list 是不使用 chroot 時, 則這些使用者也不會有 idle_timeout 的限制</li></ol>這些應該是之前也有寫給 pure-ftpd 使用的修改, 換回 vsftpd 之後, 順便就改回來了.<p> </p>
Patch
FTP
2017-10-01T09:26:26Z
tommy
-
Synology DSM 6.1 硬碟同步速度過慢的問題
https://blog.teatime.com.tw/1/post/486
<p>去年中的時候, 原本在 Synology DS1813+ 上面用的 WD 紅標 3TB 在過保後, SMART 出現了警告. 加上容量又快被我用光了, 所以... 就逐步汰換成 Toshiba 6TB. (壞第一顆時先把備用的 HSGT 4TB 換上去, 壞第二顆就開始換成 Toshiba 6TB 的硬碟) </p><p>在 Synology 的主機上, 原本同步時的速度不快, 但只要更改下面幾個設定值, 就能大幅提高同步的速度:</p><pre class="ini"><div class="insertcode">/proc/sys/dev/raid/speed_limit_min<br />/proc/sys/dev/raid/speed_limit_max<br />/sys/block/md2/md/stripe_cache_size</div></pre><p>我是把 speed_limit_min 設成 70000, 把 speed_limit_max 設成 0, 把 stripe_cache_size 設成 32768.</p>以我家的每個硬碟 3TB 的大小, 在 DS1813+上頭八個硬碟同步時, 原本同步的速度約要一星期才能同步完成, 改成上面的值之後, 約 12 小時就能同步完成. 當然, 同步時的效能也會降低不小, 只是就算沒改, 只要同步, 效能一樣會變差, 而且... RAID 最怕出問題的時間點就是在同步的時候, 同步時間越久就越不安全. 所以就算效能不佳, 但能越快完成同步越好.<br /><p>前陣子 Toshiba 6TB 在各大網站都出現特價, 所以就把剩下的硬碟補齊 (可惜只有剩兩顆). 換上後, 發現同步變很慢, 查了半天, 終於發現無論我把 stripe_cache_size 改成多大的數字, 都會被逐步降回 256, 這樣同步一顆硬碟要花上 2-3 個星期. 上網查了一下, 發現<a href="https://forum.synology.com/enu/viewtopic.php?t=127742" target="_blank">有人跟我同樣的問題</a>, 是發生在升級到 DSM 6.1 之後. </p><p>找了幾天都查不到解決方法 (有試過弄個 script 定時改回去, 不過.... 感覺上這樣改來改去的效能反而更差). 最後終於受不了, 在 DSM 上的技術支援中心發了一封信請求技術支援. 在 3 天後收到了回信, 有提到解決的方法.</p><p>在 DSM 6.1 上面, 可以在 /etc.defaults/synoinfo.conf 中新增下面兩個參數:</p><pre class="ini"><div class="insertcode">md_resync_cache_size<br />md_resync_disk_threshold</div></pre><p>md_resync_cache_size 是動態調整後的最小值, 預設是 256.</p><p>md_resync_disk_threshold 是上面這個動態調整的功能啟用的最小的同步硬碟數, 預設值是 8 (所以... 就是 8 個或 8 個以上的硬碟組成的 RAID 才會影響).</p><p>不打算用這個功能, 就把 md_resync_disk_threshold 設一個比你的硬碟數還大的值就可以. 如果要使用這功能,但是要把 stripe_cache_size 的值調大, 就改 md_resync_cahce_size 的值.</p><p>改了設定之後重開機就應該會生效了. 改好後, 同步一個硬碟的時間, 終於回到 12 小時左右的時間了. </p>
Synology
2017-04-10T10:02:51Z
tommy
-
Linux 上面的 samba 加入 AD 之後的一些問題
https://blog.teatime.com.tw/1/post/485
<p>記錄一下當 Linux 上面透過 krb5-user 與 winbind 加入 AD 之後的一些小問題.</p><ul><li>kinit 執行會失敗</li></ul>通常是因為.... 大小寫不一樣造成的. 要確定帳號 @ 後面的 domain 要跟 krb5.conf 中的完全一樣.<br /><ul><li>本機上的使用者無法透過 passwd 修改本機密碼</li></ul><p> 這個部份是在 /etc/pam.d/common-password (不同的系統可能名稱不一樣), 通常會加上一筆</p><pre class="bash"><div class="insertcode">password <span class="br0">[</span><span class="re2">success</span>=<span class="nu0">2</span> <span class="re2">default</span>=ignore<span class="br0">]</span> pam_krb5.so</div></pre><p>的設定在 pam_unix.so 之前. 所以在執行 passwd 時, 就會去異動 AD 上的密碼, 但該使用者又非 AD 帳號, 所以會有問題.</p><p>這時可以在 pam_krb5.so 後面加上 minimum_uid=10000 的參數 (數字自行決定, 就是 AD mapping 過來的帳號的最小值), 這樣子就可以避免這個問題了. </p><ul><li> 有些帳號與群組使用 wbinfo -g 或 wbinfo -u 時可以查到, 但無法在 samba 中使用</li></ul><p>通常出現這情形時, 使用 wbinfo -i (--user-info 或 --group-info) 時, 會無法正常取得資料. 透過 getent passwd 或 getent group 查詢時也會查不到 (所以設定好後, 建議用 getent passwd/group 來驗證是否可用, 不要用 wbinfo -u/-g).</p><p>這個問題有可能是因為在 smb.conf 中有加上這個參數造成的:</p><pre class="bash"><div class="insertcode">winbind normalize names = Yes</div></pre><p>移除後就應該會正常了 (當初不知是那兒抄來的參數... 想不起來為什麼會用到).</p><ul><li>samba 分享出來的路徑, 根目錄 (其他的也有可能) 無法寫入新的檔案或目錄.</li></ul><p>這個不確定是不是 samba 新版本造成的, 因為一直以來相同的設定都可以用.</p><p>我們習慣在 smb.conf 中對該分享設定</p><pre class="ini"><div class="insertcode"> create mode <span class="sy0">=</span><span class="re2"> 644</span><br /> directory mode <span class="sy0">=</span><span class="re2"> 755</span><br /> force user <span class="sy0">=</span><span class="re2"> nobody</span><br /> force group <span class="sy0">=</span><span class="re2"> nogroup</span><br /> force create mode <span class="sy0">=</span><span class="re2"> 644</span><br /> force directory mode <span class="sy0">=</span><span class="re2"> 755</span><br /> create mask <span class="sy0">=</span><span class="re2"> 0644</span></div></pre><p>發現在新的機器上會有這個問題. 後來是改成 664 與 775 的設定, 然後把該目錄下面的權限把 group 的寫入權限也加上後, 就可以正常使用了.</p>
Linux
Software
2017-03-23T10:00:34Z
tommy