2007-07-14

以年月份做分類的導覽連結列 (Year & Month Breadcrumbs)

如果像我用 Daily Archive 來做日曆的 Hack,會發現一個問題:要怎麼找當月份或是當年份的備份文章呢?之前很多朋友都發現 Archive 其實只有一個能生效,即使手動 Hack 塞了兩個,還是會不大正常。其實目前為止這個問題並沒有好的解法(除非不用那個日曆的 Hack),能夠做的就是在一些小地方加上連結,讓讀者可以看到當年份或是當月份的文章。這裡介紹的 Hack 是文章上方的導覽列(要點進特定文章才會出現),這個導覽列英文叫 Breadcrumbs,是「覆蓋在麵包上的小屑屑」,英文用得其實比中文「導覽列」 (NavBar) 更貼切(我也不知道中文怎麼翻,總不能真的叫麵包屑吧),Hack 完或實際特定文章連結看範例就知道是怎麼回事了。

原作者做的 Hack 是導覽連結列是 首頁 -> 標籤 -> 文章標題,不過眼尖的人會發現兩個問題:第一,如果有多個標籤該怎麼辦?第二,進到單篇文章裡面,文章一開始就有文章標題、最後面會列出該文章所有標籤,這個導覽連結列完全沒有可用性啊!因此有了改良,改成以時間來導覽連結,變成像是 首頁 -> 年份 -> 月份 -> 文章標題,嗯嗯!就樣也算是有了該篇文章當月或當年的 Archive 作用了。但是我發現這份改良還是有問題,作者當月的 Archive 還是借用 Monthly Archive 的連結來做的,像我用 Daily Archive 還是會不正常啊!研究了一下,原來 Archive 是用 Blogger 自己搜尋引擎的語法,帶入時間範圍當變數達成的,所以我就又修改了一下,當月的 Archive 一樣比照辦理,做出來文首的導覽列連結就不受 Archive 的型態和設定影響了!

一樣打開範本->修改 HTML->勾選「展開小裝置範本」,在 Blog 文章的這個 widget 區段內(<b:widget id='Blog1' ....> </b:widget>),找到顯示文章的那一個子區段,應該是下面這一行開始:

<b:includable id='main' var='top'>

這行下面表示的是在產生文章的完整內容,由於我們這個文首的導覽列要放在文章內容的前面,因此在產生的文章迴圈後、產生發表日期和標題前塞入下面紅色那一行:

<b:loop values='data:posts' var='post'>
<b:include data='post' name='breadcrumbs'/>
<b:if cond='data:post.dateHeader'>

而這個新加進來的 include 定義 breadcrumbs,我們也要宣告,因此下面的程式碼請加在 <b:includable id='main' var='top'> 這行的前面:

<b:includable id='breadcrumbs' var='post'>
<!-- Year & Month Breadcrumbs -->
  <b:if cond='data:blog.pageType == "item"'>
    <p class='breadcrumbs'>
      導覽連結:  <a expr:href='data:blog.homepageUrl' rel='tag'>首頁</a>
      <script type='text/javascript'>
        generateBreadcrumbs();
      </script>
      <b:if cond='data:post.title'>
        -&gt;  標題: <data:post.title/>
      </b:if>
    </p>
  </b:if>
<!-- End of Breadcrumbs Hack -->
</b:includable>

而上面的程式碼裡,有用到一段 Javascript 的函式 generateBreadcrumbs(),因此接著要把這個函式的宣告和定義放到樣版裡面。和之前的 Hack 一樣,把下面的 Javascript 程式放到樣版 </head> 標籤前面,或是自己定義的 Javascript 區段:

<script type='text/javascript'>
//<![CDATA[
<!-- Functions used for generating Year & Month Breadcrumbs: generateBreadcrumbs() -->
function generateBreadcrumbs() {
  var strHref = location.href.toLowerCase();
  var intWhereAt = strHref.lastIndexOf('/', strHref.indexOf('.html'));
  var intYear = parseInt(strHref.substr(intWhereAt - 7, 4),10);
  var strCrumbOutput = ' -&gt; 年份: <a href="/search?updated-min=' + intYear;
  strCrumbOutput += '-01-01T00%3A00%3A00-08%3A00&updated-max=' + (intYear + 1);
  strCrumbOutput += '-01-01T00%3A00%3A00-08%3A00">' + intYear + '</a>';
  var intMonth = parseInt(strHref.substr(intWhereAt - 2, 2),10);
  var intNextMonthYear = intYear;
  var intNextMonth = intMonth + 1;
  if (intNextMonth > 11) {
    intNextMonth = 1;
    intNextMonthYear += 1;
  }
  var strMonth = intMonth;
  if (intMonth < 10) strMonth = "0" + intMonth;
  var strNextMonth = intNextMonth;
  if (intNextMonth < 10) strNextMonth = "0" + intNextMonth;
  strCrumbOutput += ' -&gt; 月份: <a href="/search?updated-min=' + intYear;
  strCrumbOutput += '-' + strMonth + '-01T00%3A00%3A00-08%3A00&updated-max=' + intNextMonthYear;
  strCrumbOutput += '-' + strNextMonth + '-01T00%3A00%3A00-08%3A00">' + strMonth + '</a>';
  document.write(strCrumbOutput);
}
//]]>
</script>

最後就是外觀了。原始碼裡面用到了一個新定義的 CSS 變數:breadcrumbs,這是用來顯示這個導覽連結區段的 Style,所以在 CSS 定義的區段 <head> 標籤後面、<style>區段裡加入以下的 CSS (樣式請自行根據自己的樣版調整顏色、字型大小和分隔線):

/* Style for Year & Month Breadcrumbs */
.breadcrumbs {
 color: $sidebarcolor;
 letter-spacing: .1em;
 font: $postfooterfont;
 border-bottom:1px dotted $bordercolor;
 margin:0 0 0.5em;
 padding:0 0 0.5em;
}

存檔搞定!檢視首頁的時候好像沒什麼改變,因為顯示這個連結列的條件是:

<b:if cond='data:blog.pageType == "item"'>

也就是要點入單篇文章的時候,效果才會出來,顯示在文章標題的上面,我想在其他地方應該沒有導覽的必要吧~

參考文章:
Adding a Breadcrumb Trail to your Blogger Post
Year & Month Breadcrumbs

註:已修正 8, 9 月文章月份導覽會變成 0 的問題,原因是 Javascript parseInt(08) 的問題,改成 parseInt(08, 10) 就沒事了。

回應: 22

 

2007-07-13

Blogger 整合了 FeedBurner !

之前寫過 FeedBurner介紹,後來也把我所有在 Blogger 的 RSS Feed 都去註冊了一份,而且在頁面裡留下訂閱的圖示和連結。但是,預設在 Blogger Meta 標籤裡的資訊還是 Blogger 提供的 Feed,除非你改掉樣版裡整個 Meta 的資料,或是像我這篇提到新增修改檔頭資訊,不然還真的找不到可以新增或取代預設 RSS Feed 的方法。用一些 RSS Reader 來偵測我的首頁(以這裡為例),可以找到三個 Feed 的網址連結,其實內容不大一樣,但都有人訂閱:

http://abintech.twidv.com/feeds/posts/default - 預設(ATOM 版本)
http://abintech.twidv.com/feeds/posts/default?alt=rss - 預設(RSS 版本)
http://feeds.feedburner.com/abinlee-tech - 自己燒的,被 FeedBurner 優化過

FeedBurner 後來被 Google 併購之後漸漸釋出利多,從之前大家大聲讚揚、FeedBurner Pro 的付費版本大放送外,又公告了與 Blogger 的整合、允許使用者在 Blogger 裡設定,將預設的 Feed URL 改成 FeedBurner 的,這樣網站的 RSS Feed 就變成單一窗口,也不用自己去 Hack 了!雖然上述三個 Feed 還是都存在,但是使用上全部都 Re-direct 到 FeedBurner 去,Feed 總算還是使用了統一窗口,而且被優化過的 Feed 不管哪種版本的 RSS Reader 都可以正確美觀地使用,還在用 BSP 或系統提供的預設 Feed 嗎?趕快轉到 FeedBurner 的懷抱吧!

設定很簡單,只要登入 Blogger 的後台管理介面,選擇設定->網站提供,在 Post Feed Redirect URL 填入要轉址到 FeedBurner 的 Feed 就好了。官方也有相關的使用說明,如果你已經有用過或註冊過 FeedBurner,可以直接跳到第三個步驟繼續設定。

另外,同一時間 Blogger 也新增了投票模組,該模組叫做「意見調查」,要針對自己的讀者做問卷嗎?直接在範本->網頁元素裡,找你想新增的位置加入網頁元素就好了!Blogger 真的是越來越棒啦!

回應: 4

 

2007-07-07

AMP (Apache + MySQL + PHP) 的安裝設定

要利用 LinkStation 來架各種網站(個人網頁、Blog、Wiki 還是討論區),不能或缺的是 Linux 上必備的 AMP (Apache + MySQL + PHP),有了這些基本服務,只要抓程式碼回來解壓縮、做點調整,就可以提供各種 Web-based 的服務和功能。

第一個動作先來裝 Apache 這個 Web Server:

apt-get install apache2

安裝完畢,系統會自動啟動 Apache 服務(啟動過程會看到一點錯誤訊息,先不管),可以用瀏覽器試連網址:http://機器的IP位址,連上成功瀏覽器上會有「It works!」字樣。因為還沒搞好設定的部分,我們先停掉服務:

/etc/init.d/apache2 stop

如果未來有執行 Perl/CGI 的需求,記得要順道安裝給 Apache 用的 Perl 套件:

apt-get install libapache2-mod-perl2

接下來是調整主要設定檔。所有 Apache2 相關的設定檔都在 /etc/apache2 目錄下,以前可以在 /etc/apache2/apache2.conf 裡面一次搞定,現在卻要分散到各處來設定 XD。首先是 Apache 服務執行時預設的編碼語系。目前主流預設都是 UTF-8,但是 Apache 卻是 ISO-8859-1,先編輯 charset 設定檔:

nano /etc/apache2/conf.d/charset

把 AddDefaultCharset UTF-8 前面的 # 刪掉,這樣服務器預設使用的編碼就會是 UTF-8 了。而 Apache 服務的連接埠設定,在檔案:/etc/apache2/ports.conf 裡面,預設是 80,沒要更動所以不用改。接下來設定需要用到的用戶和群組,看 apache2.conf 裡面提到它是連結到檔案 /etc/apache2/envvars,裡面的內容是:

export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data
...

顧名思義,它定義了執行時 Process 的身份、群組和 ID,預設用的是 www-data,為了好看 (?!)、還有和其他服務共享的目的,所以我新增一個帳號 www,並且更改群組到 users,要手動修改帳號資訊,要編輯 /etc/passwd:

nano /etc/passwd

在最後面新增一列:

www:x:106:100:www:/home/www:/bin/false

並且把 envvars 的內容改成:

export APACHE_RUN_USER=www
export APACHE_RUN_GROUP=users
....

新增的帳號名稱是 www,帳號 ID 是 106 (請自己找一個不重複的)、群組 ID 是 100 (屬於 users 這個群組,不確定可以看 /etc/group 內容)、帳號說明以及所屬根目錄 /home/www(這個目錄請自行建立、chown & chgrp 給 www & users),而且也不允許一般登入。以上非硬性規定,可以根據個人需要調整。還記得安裝完、服務自動啟動看到的錯誤訊息嗎?訊息像是:

Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName

原因是服務不認得所在機器的名稱,只要在設定檔裡加入機器的 alias 就能排除這個訊息(其實不影響服務啟動),編輯設定檔:

nano /etc/apache2/httpd.conf

加入一行(用系統預設的 hostname):

ServerName %h

該服務的基本設定到此差不多就搞定了,接下來要設定的是網站實際網頁檔案放置的目錄,也就是網頁對外提供服務的根目錄。這裡先處理預設的網站,系統裝好用的預設目錄是 /var/www,對應到網站的根目錄 (http://localhost),要修改關於預設站台的設定檔:

nano /etc/apache2/sites-available/default

範例的設定檔內容為:

<VirtualHost *:80>
        ServerAdmin root@localhost
        DocumentRoot /home/www/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /home/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>
        ScriptAlias /cgi/ /home/www/cgi-bin/
        <Directory /home/www/cgi-bin>
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
        ErrorLog /var/log/apache2/error.log
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn
        CustomLog /var/log/apache2/access.log combined
...
</VirtualHost>

以上已經把 www 的目錄指定到 /home/www,也就是把預設網站的網頁根目錄從 /var/www 改到 /home/www。原先的 cgi 目錄指定到 /usr/lib/cgi-bin/,這裡移到 /home/www/cgi-bin/ 下面(目錄也要記得自己建啊),方面網站檔案管理。最後有一段關於 doc 的 alias,完全沒用所以我就拿掉了。最後記得把剛剛那個會顯示「It works!」的網頁檔案複製到新目錄:

cp /var/www/index.html /home/www

啟動伺服器囉(以上設定都正確的話,應該沒有任何錯誤訊息):

/etc/init.d/apache2 start

接下來檢驗服務是否有啟動(每個服務驗證都適用喔):

nmap localhost

裡面應該要有一筆 Port 80 的記錄(像這樣:80/tcp open http),代表服務在跑囉~然後用你的瀏覽器直接連 http://機器的IP位址,一樣看到「It works!」就成功啦!既然上面有裝 CGI 用的 Perl,這裡一定也要測試一下,在設定放 CGI 的目錄下建立一個檔案:

nano /home/www/cgi-bin/test.pl

裡面的內容是:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, World!";

存檔後離開,記得更改成可執行檔的屬性(chmod a+x /home/www/cgi-bin/test.pl),然後用瀏覽器連網址:http://機器的IP位址/cgi/test.pl,如果有看到「Hello, World!」,那麼 Perl CGI 也運作正常啦!

如果要在 Apache 上面做 Virtual Host (不同網址、指定到同一個 IP、卻指向不同目錄的網頁目錄),在 /etc/apache2/sites-available 目錄下建立一個設定檔,假設以網域名稱當檔名 (範例的網域叫做 forum.test.com,而對應到的實體路徑是 /home/www/forum):

nano /etc/apache2/sites-available/forum.test.com.conf

然後貼入以下內容(請依網域名稱和網頁目錄更改):

<VirtualHost *>
        ServerAdmin webmaster@localhost
        Servername forum.test.com
        DocumentRoot /home/www/forum
        <Directory />
                Options FollowSymLinks
                AllowOverride All
        </Directory>
        <Directory /home/www/forum>
                Options -Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
</VirtualHost>

在 /home/www/forum 放入一個測試的首頁檔,接下來在 /etc/apache2/sites-enabled 目錄下建立虛擬網站的連結(該目錄應該已經有一個上述 default 的網站連結),以上面的設定檔為例:

ln -s /etc/apache2/sites-available/forum.test.com.conf ./001-forum.test.com

接著重啟 Apache (/etc/init.d/apache2 restart) ,虛擬站台 forum.test.com 就可以生效了(可以開瀏覽器連連看)!搞定網頁伺服器,依照順序 (A、M、P),接著來安裝 MySQL:

apt-get install mysql-server

安裝過程會要求你輸入 MySQL Server 資料管理員 root 的密碼(和系統 root 帳號不一樣),安裝完也會順便啟動服務,可以用下面的命令(和剛剛設定的密碼)去檢查:

mysqladmin -u root -p ping

如果想實際登入,用命令列操作本機的資料庫,可以用以下命令:

mysql -p

這樣預設是以管理者帳號 (root) 登入本機 (localhost),只要輸入剛剛建立的密碼就行了(登入後可以用命令 'show variables;' 看看目前預設的參數設定)。資料庫編碼和語系的問題很常見,尤其是中文亂碼,所以在裝完資料庫後直接設定 Daemon 和 Client 的編碼方式,強制全都用 UTF8,這樣就一勞永逸了~先編輯設定檔:

nano /etc/mysql/my.cnf

裡面找到兩個 Section,分別是 [mysqld] 和 [client],各加入以下設定:

[client]
....
default-character-set = utf8

[mysqld]
...
default-character-set = utf8
init-connect = 'SET NAMES UTF8'

編輯完後存檔,重新啟動 MySQL:

/etc/rc.d/init.d/mysql restart

這時候就搞定資料庫預設編碼的問題啦(一樣可以用 mysql -p 登入資料庫,用 'show variables;' 看看目前關於編碼的參數,原來 character_set_xx 和 collation_xx 後面有 latin1 字集的設定,應該都變成 utf8 了)!至於登入之後有什麼命令、怎麼使用資料庫,請參閱中文參考手冊。最後把 PHP 支援給裝上,主要包括 PHP5 (for Apache),對 MySQL 資料庫和加密功能的支援:

apt-get install php5 php5-mysql php5-mcrypt

完成之後就通通搞定了。以上套件都安裝完先不要重啟,還有設定要改。接下來對 PHP 做設定,編輯設定檔:

nano /etc/php5/apache2/php.ini

搜尋 (Ctrl+W) default_charset,原來是 iso-8859-1,改成:

default_charset = "utf-8"

現在可以重啟 Apache 了 (/etc/init.d/apache2 restart)。要驗證 PHP 能不能動,可以做一個測試檔,然後看看能不能顯示完整的 PHP 和相關功能。在網頁目錄下做一個 test.php (nano /home/www/test.php),填入下面的內容:

<?php
phpinfo();
?>

接著用瀏覽器連接 http://機器的IP位址/test.php,測試正常的話會秀出 PHP 的資訊。有了 PHP,我們來裝一套一套透過 PHP 來管理 MySQL 的網頁工具:PHPMyAdmin,為求安裝單純和程式的最新版,我們不用套件安裝的方法來做 (apt-get install phpmyadmin),抓最新版解壓縮就能用了。直接上官網、到下載頁面找最後的版本,複製連結後在 LinkStation 裡再 wget 下載。舉個例子來說明,我下載的是 3.1.4 全語系版,下載並解壓縮在 /tmp 下面(以下連結不一定能用,請確定官網的最新連結和檔名),把整個目錄改名稱搬到我們預設的網頁根目錄下 (/home/www)、最後刪除用不到了的壓縮檔:

cd /tmp
wget http://prdownloads.sourceforge.net/phpmyadmin/phpMyAdmin-3.1.4-all-languages.tar.bz2
tar -xjf phpMyAdmin-3.1.4-all-languages.tar.bz2
mv phpMyAdmin-3.1.4-all-languages /home/www/phpMyAdmin
rm -f phpMyAdmin-3.1.4-all-languages.tar.bz2

接下來要做個設定檔(預設沒有),並且自訂一個 cookie secret 這樣 phpMyAdmin 才能動(本步驟是參考官網的 Quick Install):

cp /home/www/phpMyAdmin/config.sample.inc.php /home/www/phpMyAdmin/config.inc.php
nano /home/www/phpMyAdmin/config.inc.php

找到下面這一行,填入一段十六進位的亂數,長度內容不限(下面紅色那個是範例,請訂自己專用的):

$cfg['blowfish_secret'] = 'ba17c1ec07d65003';  // use here a value of your choice

這樣就搞定了。 瀏覽器輸入 http://機器的IP位址/phpMyAdmin,用剛剛安裝 MySQL 那組帳號 (root) 和密碼就能登入。如果嫌 phpMyAdmin 名字太長,可以去更改網頁根目錄下面 phpMyAdmin 這個目錄名稱就行了。登入後,可以仿造 root 權限新增一個資料庫管理者帳號,像是 admin,設定完整權限後再砍掉原先的 root 帳號,會比較不容易和系統 root 搞混。(如果愛用命令列登入的,因為管理者帳號不是 root 改成 admin 了,記得用 mysql -u admin -p 來登入)

備註:後來發現登入 phpMyAdmin 常有奇怪的警告,雖然好像不理也沒關係,但一直有個問題總不大舒服,因此這邊加註解決方法。

1. 關聯資料表的附加功能未能啟動。這是因為預設 phpMyAdmin 需要在 mySQL 裡面有一個自己用的資料庫,剛灌完 mySQL 當然沒有、phpMyAdmin 也不會自己建,所以要自己手動處理。先用 mysql -p -u admin 登入 mySQL 資料庫,建立需要的資料庫:

create database phpmyadmin;

用 quit 登出後,用預先定義好的 table 資料匯入剛剛建好的資料庫 phpmyadmin:

mysql -p -u admin < /home/www/phpMyAdmin/scripts/create_tables.sql

接著編輯 phpMyAdmin 的設定檔(/home/www/phpMyAdmin/config.inc.php),移掉 Advanced phpMyAdmin features 下面十行前面的 "//" remark 符號,登出再重新用 phpmyadmin 登入就沒有這個訊息了。

2. Server running with Suhosin. Please refer to documentation for possible issues. 這是提示有啟用 Suhosin 的 PHP 保護機制,要你去調整一些參數有的沒的(請自行瞭解那是幹嘛的),討厭看到這個紅字的,可以到設定檔最後加上如下關閉 warning 提示的參數就行了。

$cfg['SuhosinDisableWarning'] = true;

相關軟體差不多都設定完了,為避免未來安裝其他程式和存取共用的問題,可以把整個網頁根目錄 (/home/www) 的使用者和群組通通設定成上述我們新增的那個工作帳號 (www) 及所屬群組 (users):

chown -R www:users /home/www

到此 AMP 就都安裝設定完畢,現在我們有一個強大的網頁伺服器 Apache、還可以設定虛擬站台,有 PHP5 的支援,還有一套 MySQL 資料庫,這個資料庫還有 Web 介面的管理工具:PHPMyAdmin,有了這些個軟體環境,不管單純做個網站,還是要架設討論區、Blog,都可以很容易地架設起來了。

回應: 7

 

2007-07-05

Samba Server 網路芳鄰共享的設定

Samba 是用來提供網路芳鄰服務、讓附近的電腦可以直接存取 LinkStation 裡面的檔案,甚至如果把 USB 印表機接上 LinkStation 的 USB Port,還可以透過它來分享印表機哩!這種存取檔案的方法雖然沒有直接用 FTP 來得快,但是如果用來變成網路硬碟,別的電腦不用複製就可以播放和分享這個網路硬碟的音樂或影片、燒錄或安裝放在 LinkStation 裡面的映象檔或程式,實用性更是大大地增加了,LinkStation 儼然成為家裡區域網路上的多媒體中心和檔案伺服器,讓內部分享和使用更加便利。再進階一點就變成 NAS (Network Attached Storage),可以作為中小企業的檔案伺服器,內建的目錄和權限管理,能因應一般公司大部分的檔案分享需求。

首先先安裝 Samba 的套件:

apt-get install samba

這樣會幫你安裝 Samba 所需的相關套件。接下來調整設定檔:

nano /etc/samba/smb.conf

Samba 設定檔主要是設定像是存取權限、連線效率、語系編碼(中文目錄和檔名)以及分享目錄等等,部分參數已經存在,要修改內容,部分參數是要整段新增的,以下是我的範例(可以用 Ctrl+W 尋找字串來修改):

#======================= 站台設定 =======================
[global]

# 更正編碼語系,除 DOS 外都改成 UTF8,不然就用 Big5
  display charset = UTF8
  dos charset = CP950
  unix charset = UTF8

# 伺服器描述
  server string = "Server"

# 預設工作群組
  workgroup = WORKGROUP

# WINS 支援
#  wins support = no
;  wins server = w.x.y.z
  dns proxy = no
;  name resolve order = lmhosts host wins bcast

# 封包傳遞項目設定,以提昇效能
  socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192

# Log 檔相關設定、Log 檔最大值 (KB)、要不要透過 syslog 來紀錄
  log file = /var/log/samba/log.%m
  max log size = 1000
  syslog = 0

# Samba 掛掉的處理
  panic action = /usr/share/samba/panic-action %d

#======================= 認證設定 =======================
# 登入認證設定
#  security = share
  security = user
 
# 密碼加密、與系統密碼同步
  encrypt passwords = true
  unix password sync = yes

# 密碼處理程式及相關限制
  passwd program = /usr/bin/passwd %u
  passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssucces$
  passdb backend = tdbsam
  obey pam restrictions = yes
  pam password change = yes

# 匿名登入(帳號、處理)
  guest account = samba
  map to guest = Bad User

解釋一下上面參數的意思。一開始是處理目錄檔名編碼語系的問題,現在安裝好的應該都是 Samba Server 3.x,在一開始我們裝 Debian 時有設定過系統預設語系是 zh_TW.UTF-8,所以預設顯示和操作都要設成 UTF-8,而外部 Dos 存取則設成 CP950(給 DOS 存取用的,反正 DOS 不支援 UTF、只支援 ANSI),這樣就能解決大部分中文目錄檔名在分享和存取上變成亂碼的問題。

重頭戲來了,要接著設定 Samba 分享的權限和存取控制。初步的概念是,希望能夠同時開放匿名存取、方便朋友或其他網路裝置來做不需認證的存取 (Read-only),另一方面又希望像檔案伺服器一樣,讓有帳號的人能在伺服器上有自己的目錄放些私人檔案,最後,還要有個分享目錄是專門給有帳號的人共用的,這些「會員專屬」的分享目錄當然不希望匿名存取的人看到,以上,聽起來相當複雜是吧~看看設定檔中關於認證設定的部份,要兼容匿名和帳號登入,首先要將安全層級設定為使用者 (security = user,如上述設定檔所設)、並設定密碼加密及與系統同步共用,這樣在 Debian 裡新增的帳號和密碼,就可以與 Samba 共用了(不需要另外設定 smbpasswd)!接下來我們需要一個匿名帳號,給沒帳號的訪客登入使用,設定檔裡我指定了一個匿名帳號叫 samba (guest account = samba),這個帳號預設不存在,所以要手動新增,我們直接修改 /etc/passwd:

nano /etc/passwd

加一筆資料像是這樣:

samba:x:103:100:samba:/etc/samba:/bin/false

其中 103 是 User ID,不能和 passwd 裡面存在的重複(所以要自己找一個沒人用的,103 是我系統還沒人用到的 ID),而 100 是 Group ID,預設應該是 users 這個群組才是(如果不是請自行調整)。到此,基本設定的部份算是完成了,緊接著要補上分享目錄的資訊和設定。根據以上需求,我需要三種目錄:第一種是有系統帳號的人,能夠在伺服器裡有自己專用的目錄放私人檔案,第二種是給有系統帳號的人,能夠做會員間分享存取使用,最後一種,不管你有沒有帳號,都可以具名或匿名存取的公用目錄。這三類目錄的分享設定如下(請把以下範例直接補到 /etc/samba/smb.conf 後面):

#======================= 分享設定 =======================
[Homes]
  comment = Home Directories
  valid users = %S
  browseable = no
  writeable = yes
  create mask = 0644
  directory mask = 0755

[Share]
  comment = Private Shared Folder
  path = /home/samba
  browsable = yes
  writable = yes
  valid users = @users
  create mask = 0664
  directory mask = 0775
 
[Files]
  comment = Public Shared Folder
  path = /home/ftp
  browsable = yes
  writable = no
  write list = abin
  public = yes
  create mask = 0664
  directory mask = 0775

第一段 [Homes],顧名思義就是每個帳號的「家目錄」,當使用者用自己的帳號密碼登入後,該目錄名稱就會變成自己的帳號名稱,假設系統裡有個帳號叫 abin、它在系統裡的家目錄是 /home/abin,那麼登入後 Samba 會連結目錄到 /home/abin、給這位使用者 abin 直接使用(很直覺吧)。第二段 [Share],分享目錄指定到 /home/samba(沒這個目錄自己建立,記得 chown -R samba:users /home/samba/),其中指定了 valid users = @users,意思是「只有合法登入的一般帳號」才能夠存取使用,這個目錄就是「會員專屬」的分享目錄。最後一段 [Files] 就是開放給所有人(包含匿名)的公用分享目錄(範例中指定到 FTP 的共用分享目錄),注意其中我關閉了公用目錄「寫入」的權限(也就是任何人透過 Samba 進來都只能讀取),而指定只有 abin 這個帳號的人可以寫入 (write list = abin),表示該目錄有限定管理者,這樣自己透過 Samba 進來進行存取,也方便做目錄檔案的管理。

特別注意的是,我這邊用同屬一般使用者群組 (user) 的帳號來做 Samba 分享目錄的管理者,用的是和 FTP 服務共用的分享目錄,以我設定的檔案目錄創建屬性(create 0664, directory 0775),一樣是「屬於同群組的帳號擁有完全的讀寫權限」、和 FTP 設定的管理權限一模一樣,所以從檔案屬性來看,可以知道分享目錄裡的檔案來源是從 FTP 還是 Samba 來的,而且不管從哪來,FTP 或 Samba 管理者都可以做目錄檔案的管理,不會被不同來源的權限給擋住,在跨服務、同目錄的管理才能有最大的彈性,同樣也兼顧了安全性。設定好設定檔和帳號存取問題,就可以啟動 Samba 服務囉!設定檔的部分,Samba 有提供一個驗證工具,啟動服務前可以執行 testparm,它會幫你檢驗設定的參數正不正確。沒問題的話就直接重新啟動 Samba:

/etc/init.d/samba restart

這時,其他的電腦就可以透過網路芳鄰存取 LinkStation 了。當有電腦來存取的時候,還可以用 smbstatus 這個命令查看連線的狀態,看那個機器正在使用 LinkStation 的資源。用以上分享的範例,到 Windows 網路芳鄰、開啟工作群組電腦,會看到多一台電腦,點進去裡面有兩個分享的資料夾:Share、Files,如果點進 Files,算是直接匿名登入,Log 會顯示有個 Guest 叫 samba 的連進來,如果改點 Share 目錄,這時候會要求你敲帳號密碼登入,不敲就看不到,而用帳號登入後除了可以看到 Share 的內容、可以存取檔案之外,回到上層目錄會看到多一個和自己帳號一樣的目錄出現,那個就是自己私人在伺服器上的目錄啦!這裡有一個 Windows 用網路芳鄰連線的小技巧,一般開完機用網芳連過,基本上就沒有「登出」「重新登入」的機會了,如果在測試時修改 Samba 設定然後用 Windows 測試時,不能反覆登入是很麻煩的事,這裡可以 DOS 開視窗、用下面的這個命令,強迫 Windows 的網路芳鄰斷線登出,這樣要測試匿名登入或帳號登入時,就不會受到 Windows 不給登入的限制:

net use * /delete

到此為止呢,在 LinkStation 上面已經完成 Samba 服務的設定,也可以透過網路芳鄰與區域網路內同個網段的電腦做檔案共享,但,人家可以透過網路芳鄰連進 LinkStation,那能不能登入 LinkStation 後透過機器去存取其他也有提供 Samba 服務的電腦、利用 LinkStation 使用網路芳鄰的資源呢?上面我們提到的安裝 Samba 服務,接下來我們來安裝透過 Samba 來存取其他電腦的 Client 程式:

apt-get install smbclient

裝完系統內會多了幾個公用程式,像是想要瀏覽網路芳鄰,可以用命令:

findsmb

它會幫你找整個區網、列出同一個 Workgroup 的電腦,找到電腦以後根據主機名稱 (hostname) 可以用:

smbclient -L '主機名稱'

這個命令會列出該電腦有分享出來的資源(直接用 smbtree 也行),假設分享的目錄名稱是 Files 目錄,要連進去該目錄用下述命令:

smbclient '\\主機名稱\Files' -U '登入帳號'

輸入密碼(匿名登入的話直接按 Enter)就登入了(確定匿名沒密碼可以直接用 smbclient -N '\\主機名稱\Files' 進去)。接著會出現操作的提示符號:smb: \>,你可以下和 ftp 接近的檔案操作命令 (get, mget, put, mput, mkdir, rmdir ....),進行檔案的相關操作。

最後一個和 Samba 有關係的就是「網路磁碟機」,在 Windows 下面我們可以把某個網路芳鄰分享的目錄掛載成一台網路磁碟機,並給它一個磁碟機代號,透過 smbclient,我們能存取別人電腦的分享目錄,那能不能也把那個目錄,掛載成 LinkStation 的某個路徑,像用網路磁碟機一樣?這時候我們要另外裝一個套件,裡面包含一些 Samba 檔案系統 (smbfs) 的公用程式:

apt-get install smbfs

裝完會多一個 smbmount 公用程式,或是預設的 mount 也會多支援 Samba 專用的檔案系統 (smbfs)。如果要掛載某個分享目錄到本地的路徑,命令是:

smbmount '//主機名稱/Files' /mnt/samba -o codepage=UTF8,iocharset=UTF8

這樣就是把網路某分享目錄掛載到自己的某個目錄啦 (/mnt/samba),這裡也可以用 mount -t smbfs 替代 smbmount 來操作。嗯,所有 Samba 的服務和工具差不多就這樣了,如果想玩網路印表機分享(驅動程式要支援)、更複雜像是 LDAP、AD 之類的管理機制,可以更深入去研究 Samba 的用法~

後記:現在主要的網芳 client 越來越多是 Windows 7 的了,偏偏 Windows 7 在傳統網路芳鄰的資源上很差,試了很多次改什麼 Windows 的 registry 通通不管用,敲什麼帳號密碼都沒辦法登入(Windows XP 就沒這些問題),最後直接在 samba 裡面新增專用帳號和密碼,這樣才能通過身分認證並連結系統的原生帳號。假設我們要允許帳號 admin 能存取有權限設置的目錄(必須登入),先在 samba 裡新增帳號:

smbpasswd -a admin

過程會要求設置密碼,這是用來登入 samba 用的帳號密碼,必須要是系統存在的帳號,但密碼可以和系統內的不一樣。如果要知道系統裡的 samba 已經被加了幾個這樣的帳號,可以用命令:pdbedit -L 列出來,如果要刪除則用 pdbedit -x。

參考文章:
鳥哥 - SAMBA 伺服器
使用 Samba 架設中小企業 File Server

回應: 13