Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts

2015/12/12

Raspberry Pi:查詢IP位址

我的Raspberry Pi位於路由器之後,透過DHCP向路由器取得私有IP位址。

以瀏覽器登入路由器,查詢IP位址分配情況。

Raspbian開機後,可在主控台看到類似如下訊息:
My IP address is 192.168.1.15

Raspbian GNU/Linux 8 raspberrypi tty1

raspberrypi login: _

在rpi上執行指令ifconfig,可得知網路介面的狀態:
$ ifconfig
eth0      Link encap:Ethernet  HWaddr b8:27:eb:3c:ce:77
          inet addr:192.168.1.15  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::7814:89c2:cf8d:2018/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:68 errors:0 dropped:0 overruns:0 frame:0
          TX packets:97 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:7667 (7.4 KiB)  TX bytes:15216 (14.8 KiB)

在rpi上執行指令hostname加上參數-I,可直接得到IP位址:
$ hostname -I
192.168.1.15


從同一區域網路裡的其他台Linux電腦,使用指令nmap,查詢同網域內電腦的IP位址。參數-sn代表不掃描連接埠,192.168.1.0/24的24代表子網路遮罩部分有24個位元,因此會掃描256個IP位址,從.0到.255。
$ nmap -sn 192.168.1.0/24

Starting Nmap 6.47 ( http://nmap.org ) at 2015-12-10 14:23 CST
Nmap scan report for www.asusnetwork.net (192.168.1.1)
Host is up (0.0011s latency).
Nmap scan report for yehnanwinxp (192.168.1.2)
Host is up (0.00090s latency).
Nmap scan report for raspberrypi (192.168.1.15)
Host is up (0.00034s latency).
Nmap done: 256 IP addresses (3 hosts up) scanned in 2.57 seconds

若是Windows與Mac OS X,可到nmap.org下載nmap這支工具,也有圖形介面Zenmap。底下在Windows 7上的執行畫面。
從同一區域網路裡的其他台Linux電腦,使用指令fping,一次性ping多台電腦,在rpi開機前後執行此動作,便可得知rpi的IP位址。參數-a代表只秀出活著的電腦,參數-q代表安靜模式,不秀出額外的訊息,以參數-g指定想要ping的IP位址範圍。
$ fping -a -q -g 192.168.1.1 192.168.1.255
192.168.1.1
192.168.1.2
192.168.1.7


Windows版的fping,可到這裡下載。但參數不太一樣,-p代表使用多個執行緒,-g代表IP位址範圍(以斜線/隔開);沒有Linux版的-a參數,但一般來說,因為會比較快收到活著電腦的回應,所以fping指令就會先顯示這些電腦,然後顯示回應很慢或不存在的電腦。

> fping -p -g 192.168.1.1/192.168.1.255
Reply[101] from 192.168.1.101: bytes=32 time=5.4 ms TTL=64
Reply[110] from 192.168.1.110: bytes=32 time=5.2 ms TTL=128
Reply[1] from 192.168.1.1: bytes=32 time=8.2 ms TTL=64
192.168.1.146: request timed out
192.168.1.149: request timed out
192.168.1.179: request timed out
192.168.1.153: request timed out
...

使用Mac OS X的「IP Scanner」,執行畫面如下,也能掃描鄰近電腦的IP位址。
在Windows上使用指令arp,但因為種種原因(快取、有無連線、等等),不一定會完整顯示,其中B8-27-EB是Raspberry Pi的MAC起始位址。:
C:\>arp -a

Interface: 192.168.1.2 --- 0x2
  Internet Address      Physical Address      Type
  192.168.1.1           54-04-a6-5a-e9-78     dynamic
  192.168.1.7           a8-20-66-34-ec-5e     dynamic
  192.168.1.15          b8-27-eb-3c-ce-77     dynamic

在Mac OS X上有專門工具來尋找rpi的IP位址,叫做Pi Finder,尋找以B8:27:EB開頭的MAC位址。
其他:Adafruit的Adafruit-Pi-FinderAngry IP Scanner

2015/12/11

在Raspbian上安裝WordPress

安裝WordPress其實很簡單,照著Raspberry Pi基金會提供的文件,一步一步照做即可。所以這篇只是很簡單地記錄一下而已,分為四個部分:Apache、PHP、MySQL、WordPress。

我的環境是Raspberry Pi 2與Raspbian(2015-11-21)。

先更新套件清單,並升級原有套件:
$ sudo apt-get update; sudo apt-get upgrade -y

Apache的部份:

安裝Apache套件:
$ sudo apt-get install apache2 -y

安裝後,就會成為系統服務,開機後自動執行,以指令service可觀察其狀態:
$ service apache2 status
● apache2.service - LSB: Apache2 web server
   Loaded: loaded (/etc/init.d/apache2)
   Active: active (running) since Thu 2015-12-10 10:28:57 CST; 2min 1s ago
   CGroup: /system.slice/apache2.service
           ├─1785 /usr/sbin/apache2 -k start
           ├─1788 /usr/sbin/apache2 -k start
           └─1789 /usr/sbin/apache2 -k start

開啟瀏覽器,載入Apache所在電腦的IP位址或網址,譬如我的Pi 2的IP位址是192.168.1.15,應可看到如下畫面,該網頁檔位於/var/www/html/index.html,可試著修改。

PHP的部份:

安裝PHP 5與Apache的PHP模組:
$ sudo apt-get install php5 libapache2-mod-php5 -y

然後切換目錄到/var/www/html,刪除index.html,新增檔案index.php,內容如下:
<?php phpinfo(); ?>

開啟瀏覽器,載入Apache所在電腦的IP位址或網址,應可看到如下畫面:
MySQL的部份:

安裝MySQL資料庫伺服器,以及讓PHP能存取MySQL的功能模組:
$ sudo apt-get install mysql-server php5-mysql -y

安裝過程中,將會要求你為MySQL的帳號「root」設定密碼,這個帳號與密碼,之後將會交給WordPress使用:
安裝後,需要為WordPress建立資料庫,請執行指令mysql,指定帳號並輸入密碼:
$ mysql -uroot -p
Enter password: 在此輸入密碼

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 44
Server version: 5.5.44-0+deb8u1 (Raspbian)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

看到提示符號「mysql>」後,輸入底下指令,建立名為wordpress的資料庫:
mysql> create database wordpress;
Query OK, 1 row affected (0.00 sec)

如此即可,然後按Ctrl + d跳出。

WordPress的部份:

進入放網頁的目錄,修改擁有者與群組,刪除所有東西(或移到別的地方):
$ cd /var/www/html
$ sudo chown pi: .
$ rm *

下載WordPress原始檔,底下以正體中文4.3.1版作示範,我也試過英文的4.4版。
$ sudo wget https://tw.wordpress.org/wordpress-4.3.1-zh_TW.tar.gz

解壓縮,得到目錄wordpress,把裡頭的東西通通搬移到/var/www/html之下,然後就可以刪除目錄wordpress(已經沒東西了)以及原始檔。
$ tar zxvf wordpress-4.3.1-zh_TW.tar.gz
$ mv wordpress/* .
$ rm -rf wordpress wordpress-4.3.1-zh_TW.tar.gz

看看WordPress到底有些什麼東西吧:
$ ls -l
total 176
-rw-r--r--  1 pi pi   418 Sep  3 11:33 index.php
-rw-r--r--  1 pi pi 19930 Sep  3 11:33 license.txt
-rw-r--r--  1 pi pi  7284 Sep 21 19:33 readme.html
-rw-r--r--  1 pi pi  4951 Sep  3 11:33 wp-activate.php
drwxr-xr-x  9 pi pi  4096 Sep 21 19:33 wp-admin
-rw-r--r--  1 pi pi   271 Sep  3 11:33 wp-blog-header.php
-rw-r--r--  1 pi pi  5007 Sep  3 11:33 wp-comments-post.php
-rw-r--r--  1 pi pi  4046 Sep 21 19:33 wp-config-sample.php
drwxr-xr-x  5 pi pi  4096 Sep 21 19:33 wp-content
-rw-r--r--  1 pi pi  3286 Sep  3 11:33 wp-cron.php
drwxr-xr-x 12 pi pi  4096 Sep 21 19:33 wp-includes
-rw-r--r--  1 pi pi  2380 Sep  3 11:33 wp-links-opml.php
-rw-r--r--  1 pi pi  3123 Sep  3 11:33 wp-load.php
-rw-r--r--  1 pi pi 34669 Sep  3 11:33 wp-login.php
-rw-r--r--  1 pi pi  8252 Sep  3 11:33 wp-mail.php
-rw-r--r--  1 pi pi 11062 Sep  3 11:33 wp-settings.php
-rw-r--r--  1 pi pi 25124 Sep  3 11:33 wp-signup.php
-rw-r--r--  1 pi pi  4035 Sep  3 11:33 wp-trackback.php
-rw-r--r--  1 pi pi  3055 Sep  3 11:33 xmlrpc.php

然後以瀏覽器載入,咦,怎麼出現錯誤訊息呢?

「你的PHP似乎缺少WordPress需要的MySQL擴充元件。」
(Your PHP installation appears to be missing the MySQL extension which is required by WordPress.)

代表應該要安裝套件php5-mysql,可是之前已經安裝了啊,原因不明,不過我重開機後就解決了。

以瀏覽器載入,看到如下畫面,按下「衝吧!」,開始進行設定:
然後要輸入資料庫的名稱(wordpress)、帳號(root)、密碼,按下「送出」:
接著出現如下畫面,代表WordPress沒辦法新增檔案wp-config.php。
只好由我們自己手動建立,在/var/www/html下新增檔案wp-config.php,複製內容後貼上。然後按下「開始安裝」。

接著要設定網站的基本資訊,請輸入網站標題(自選)、帳號與密碼(自選)、電子郵件,然後按下「安裝WordPress」。
搞定啦,已新增你剛剛指定的帳號,按下「登入」。
輸入帳號與密碼,按下「登入」。
哇,成功了,看到WordPress控制台的畫面囉。
以及預設的部落格畫面。
看起來很陽春,接下來就靠你花時間進行設定、客製化囉,想辦法讓你的網站美輪美奐吧。

2015/12/09

在Raspbian上安裝nginx、PHP、Django與uWSGI

這篇要在Raspberry Pi 2與Raspbian(2015-11-21)上頭,安裝nginx、PHP、uWSGI、Django,都不算是小軟體,設定都很複雜,執行選項與參數眾多,非三言兩語能道盡,這一篇僅是簡短記錄我的安裝經驗;若有問題,還請查閱官方文件。

輕量型網站伺服器nginx(發音engine x),比起龐大的Apache,更適合用於資源受限的機器,如Raspberry Pi。前端的網站伺服器nginx搞定後,接下來會安裝PHP,以及Django與uWSGI。 底下記錄如何自行下載原始碼並編譯安裝,因為若是打包好的套件,其版本往往過於老舊。

以下分成三個部分:nginx、PHP、Django與uWSGI,後兩個部分各自獨立。

nginx的部份:

首先是nginx編譯時以及使用時需要的套件。
$ sudo apt-get install gcc build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev

其中gcc與build-essential是建置工具,libpcre3與libpcre3-dev是Perl Compatible Regular Expression(PCRE),zlib1g與zlib1g-dev是壓縮工具,openssl與libssl-dev則是SSL/TLS。

下載nginx原始檔並解壓縮。我下載的是1.9.7版(約865 KB),可到nginx官網查看最新版本。
$ wget http://nginx.org/download/nginx-1.9.7.tar.gz
$ tar zxvf nginx-1.9.7.tar.gz

然後進行組態設定,configure有很多參數可設定,此處都使用預設值,因此預設安裝路徑是/usr/local/nginx:
$ cd nginx-1.9.7
$ ./configure

但是最後卻出現底下訊息:
Configuration summary
  + using system PCRE library
  + OpenSSL is not used
  + md5: using system crypto library
  + sha1: using system crypto library
  + using system zlib library

呃,因為預設關閉SSL模組,所以把指令改成:
$ ./configure --with-http_ssl_module

訊息就會變成「+ using system OpenSSL library」。

然後進行編譯建置與安裝:
$ make
$ sudo make install

預設安裝到/usr/local/nginx,若欲修改,請在執行configure時加上參數--prefix,例如「--prefix=/usr/local/nginx-1.9.7」。

然後試著查詢看看吧,可看到版本編號與組態參數。
$ cd /usr/local/nginx
$ ./nginx -V
nginx version: nginx/1.9.7
built by gcc 4.9.2 (Raspbian 4.9.2-10)
built with OpenSSL 1.0.1k 8 Jan 2015
TLS SNI support enabled
configure arguments: --with-http_ssl_module

接著實際執行,若一切正常,nginx執行檔不會有任何輸出。
$ cd /usr/local/nginx
$ sudo ./nginx

然後請開啟瀏覽器,輸入nginx所在機器的IP位址,應可看到如下畫面,代表nginx動起來囉。

該網頁檔位於/usr/local/nginx/html/index.html,你可試著修改看看。

此時若再試著執行一次,將會出現錯誤,因為連接埠80已被佔用。
$ cd /usr/local/nginx
$ sudo ./nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
...
nginx: [emerg] still could not bind()

透過其他參數控制nginx的啟動與停止:
$ cd /usr/local/nginx
$ sudo ./nginx -s stop

stop代表停止(使用TERM訊號),quit也是停止(使用QUIT訊號),reopen是重新開啟記錄檔,reload是重新載入組態檔。

如果stop與quit都無法停止nginx的話,可到/usr/local/nginx/logs/nginx.pid,檔案裡放的是nginx形成的pid(另可以指令ps -ax | grep nginx查詢),然後以指令kill殺掉行程。

因為是自己從原始碼檔安裝,所以沒有init腳本檔,開機時不會自動執行;請另行下載這支init腳本檔,把/opt的部份改成你的安裝路徑(本篇使用預設值/usr/local);檔名取為nginx,放在/etc/init.d/裡,修改擁有者以及執行權限。

然後便能以底下指令(其中一個即可),啟動nginx作為系統服務。
$ sudo /etc/init.d/nginx start

$ sudo service nginx start

其他參數還有stop、restart、status等等。

若想在開機時自動執行,指令如下。
$ sudo update-rc.d -f nginx defaults

然後重開機,看看nginx是否已成為服務在背景執行。

PHP的部份:

安裝PHP之前,先安裝相依套件:
$ sudo apt-get install libxml2-dev libevent-dev

接著要安裝PHP,並使用PHP的FastCGI process manager(PHP-FPM)。首先要下載PHP原始碼檔,並無直接的網址,請到官網找尋下載連結,我下載的是5.6.16版,檔名是php-5.6.16.tar.gz。然後解壓縮,切換目錄:
$ tar zxvf php-5.6.16.tar.gz
$ cd php-5.6.16

然後進行組態設定、建置編譯、測試與安裝:
$ ./configure --enable-fpm
$ make -j4
$ make test
$ sudo make install

執行configure時應加上參數--enable-fpm,啟用PHP-FPM。make指令加上參數-j4,因為Pi 2有四個處理器核心。make test測試通過後,進行安裝動作。

然後複製相關設定檔:
$ sudo cp php.ini-development /usr/local/php/php.ini
$ sudo cp /usr/local/etc/php-fpm.conf.default /usr/local/etc/php-fpm.conf

把PHP-FPM的執行檔複製到正確的目錄:
$ sudo cp sapi/fpm/php-fpm /usr/local/bin

修改PHP設定檔/usr/local/php/php.ini,找到cgi.fix_pathinfo並設為0,可避免安全漏洞。
cgi.fix_pathinfo=0

修改PHP-FPM設定檔/usr/local/etc/php-fpm.conf,設定正確的擁有者與群組:
user = www-data
group = www-data

然後便可執行PHP-FPM,預設應會使用埠號9000:
$ sudo /usr/local/bin/php-fpm
(本篇不讓它成為系統服務、重開機時不會自動執行,有興趣者請自行動手。)

然後要修改nginx的設定檔/usr/local/nginx/conf/nginx.conf,讓它能處理.php的請求,轉交給PHP-FPM,大致上應含有底下兩個區塊。溫馨提醒:修改前應先備份。
location / {
    root html;
    index index.php index.html index.htm;
}

location ~* \.php$ {
    fastcgi_index index.php;
    fastcgi_pass 127.0.0.1:9000;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}

然後重新啟動nginx:
$ sudo service nginx restart

$ /usr/local/nginx/sbin/nginx -s reload

在/usr/local/nginx/html/下建立檔案index.php,放入如下內容:
<?php phpinfo(); ?>

以瀏覽器載入,應可看到如下畫面:
接著要換成Python語言,可先把nginx的設定檔/usr/local/nginx/conf/nginx.conf改回原狀。

Django與uWSGI的部份:

WSGI(Web Server Gateway Interface)由PEP 333與PEP 3333制定標準,乃是Python網頁應用程式(譬如Django專案)與外界(網站伺服器)溝通的介面。很久以前,Python網頁應用程式開發框架,都只能連接特定的介面與API,譬如CGI、FastCGI、mod_python等,甚至只能與某種網站伺服器溝通,若兩端能夠遵從WSGI規格,開發人員便可自由地選用想要的網站伺服器(如nginx、Apache)與Python網頁應用程式開發框架(如Django、Flask)。

安裝開發Python程式的相關套件:
$ sudo apt-get install python python-dev python-pip

python應是Python 2.x版,python-dev包含建置Python模組所需的標頭檔、靜態程式庫與開發工具,python-pip是Python的套件管理工具。

我本來想先試試FastCGI,於是安裝了python-flup,包含三套WSGI伺服器(閘道器)實作,分別是FastCGI、AJP(Apache JServ Protocol 1.3)、SCGI(Simple CGI)。照理說應可使用Django的指令runfcgi(它會使用flup),便可啟動測試用的伺服器,可惜沒成功。Django自1.7版開始揚棄FastCGI,於1.9版移除。

接著使用指令pip來安裝Django,我安裝的是1.9.0版:
$ sudo pip install Django==1.9.0
Collecting Django==1.9.0
  Downloading Django-1.9-py2.py3-none-any.whl (6.6MB) 
    100% |████████████████████████████████| 6.6MB 7.0kB/s
Installing collected packages: Django   
Successfully installed Django-1.9

建立Django專案,取名為mysite:
$ django-admin startproject mysite

切換目錄,並且執行測試用伺服器,請把192.168.1.15換成你的IP位址。
$ cd mysite
$ python manage.py runserver 192.168.1.15:8000
Performing system checks...

System check identified no issues (0 silenced).

You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.

December 08, 2015 - 14:14:34
Django version 1.9, using settings 'mysite.settings'
Starting development server at http://192.168.1.15:8000/
Quit the server with CONTROL-C.

啟動瀏覽器,輸入網址並加上埠號,例如「192.168.1.15:8000」,應會看到如下畫面。
同時runserver那端應會輸出類似底下的訊息:
[08/Dec/2015 14:16:22] "GET / HTTP/1.1" 200 1767

哇,以上已經成功建立Django專案,並且執行測試用伺服器,從瀏覽器(客戶端)存取。

接下來要安裝uWSGI伺服器:
$ sudo pip install uWSGI

先撰寫符合WSGI規範的簡單Python程式,取名為uWSGI_test.py:
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return ["Hello World"] # python2
    #return [b"Hello World"] # python3
   
然後直接讓uWSGI伺服器同時擔任網站伺服器的角色,並執行uWSGI_test.py:
$ uwsgi --http :8000 --wsgi-file uWSGI_test.py

開啟瀏覽器,載入網址,譬如「192.168.1.15:8000」,應可看到「Hello World」字樣,代表成功了。

測試過簡單的程式之後,該讓先前建立的Django專案登場了吧:
$ cd mysite
$ uwsgi --http :8000 --module mysite.wsgi

同樣以瀏覽器載入網址,應也會看到先前成功執行Django專案、寫著「It worked!」的畫面。

以上的作法是瀏覽器經由HTTP協定與uWSGI伺服器溝通,它把請求轉成符合WSGI協定的形式,交由uWSGI_test.py或Django專案處理並回應。

接下來要把nginx放進去,由uWSGI擔任nginx與Django之間的中介角色。nginx早已加入uWSGI模組提供支援,nginx透過uWSGI伺服器原生支援的uwsgi協定與之溝通(效率最高),然後uWSGI伺服器透過轉接功能轉成WSGI形式,交給Django處理。

修改nginx設定檔/usr/local/nginx/conf/nginx.conf,把底下內容放在http區塊之內:
    upstream django {
        server 127.0.0.1:8001;
    }

    server {
        listen 8000;
        server_name localhost;
        charset utf-8;
        location / {
            uwsgi_pass django;
            include uwsgi_params;
        }
    }

其中將透過埠號8001與uWSGI伺服器(以及它之後的WSGI程式,如Django專案)溝通,另開啟埠號8000供外界存取。

然後重新啟動nginx、載入新設定值:
$ sudo service nginx restart

接著先試試小小的測試程式:
$ uwsgi --socket :8001 --wsgi-file uWSGI_test.py

再試試Django專案:
$ cd mysite
$ uwsgi --socket :8001 --module mysite.wsgi

以瀏覽器載入網址,如「192.168.1.15:8000」,確認可看到如同先前的畫面,「Hello World」與「It worked!」,耶。

也可讓瀏覽器載入網址「192.168.1.15:8001」,直接存取uWSGI伺服器,但應會失敗,因為此時它不是說HTTP協定,瀏覽器應出現錯誤畫面,而uWSGI端大概會出現類似的錯誤訊息「invalid request block size: 21573 (max 4096)...skip」。

上述作法使用TCP socket,但也可改用Unix socket,照理說負擔較低。請修改nginx設定檔/usr/local/nginx/conf/nginx.conf:

    upstream django {
        # server 127.0.0.1:8001;
        server unix:///home/pi/mysite/mysite.sock;
    }

存檔後重新啟動nginx:
$ sudo service nginx restart

接著是uWSGI的部份,指令應改為:
$ uwsgi --socket mysite.sock --module mysite.wsgi

$ uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=666

因為必須給予適當權限,才能讓nginx使用該socket。若成功的話,以瀏覽器載入,應會出現「It worked!」的畫面。

架構如下:
瀏覽器 - 網站伺服器(nginx) - socket(uwsgi協定) - uWSGI伺服器 - Python程式(Django專案)

uWSGI還能讀取.ini設定檔、以emperor模式執行,也應該成為系統服務,在開機時自動啟動(或可參考此處的init腳本檔)。

參考資料: