# 將現有專案移入WSL中
###### tags: `WSL`, `專案開發`, `未完成`
## 開啟服務與其他常用指令
```
# 開啟服務
service mysql start
service nginx start
service php8.0-fpm start
# 確認IP
hostname -I
# 設定mysql的sql_mode
mysql -uroot -p -D ovesc_sp_2 -e "SET GLOBAL sql_mode=''"
# 執行SQL檔案
mysql -uroot -p -D <db_name> < somedb.sql
```
## 安裝相依套件
本專案會用到第三方套件 GS、wkhtmltopdf
wkhtmltopdf意外點大,包含相依套件要614MB
`apt install wkhtmltopdf ghostscript`
### 查看正式機使用那些php模組
查詢指令: `php -m`
正式機 | WSL
--- | ---
[PHP Modules]<br>**bz2**<br>calendar<br>Core<br>ctype<br>**curl**<br>date<br>dom<br>exif<br>FFI<br>fileinfo<br>filter<br>ftp<br>**gd**<br>gettext<br>hash<br>iconv<br>json<br>libxml<br>**mbstring**<br>mysqli<br>mysqlnd<br>openssl<br>pcntl<br>pcre<br>PDO<br>pdo_mysql<br>Phar<br>posix<br>readline<br>Reflection<br>session<br>shmop<br>SimpleXML<br>sockets<br>sodium<br>SPL<br>standard<br>sysvmsg<br>sysvsem<br>sysvshm<br>tokenizer<br>xml<br>xmlreader<br>xmlwriter<br>xsl<br>Zend OPcache<br>**zip**<br>zlib<br><br>[Zend Modules]<br>Zend OPcache | [PHP Modules]<br>calendar<br>Core<br>ctype<br>date<br>dom<br>exif<br>FFI<br>fileinfo<br>filter<br>ftp<br>gettext<br>hash<br>iconv<br>json<br>libxml<br>mysqli<br>mysqlnd<br>openssl<br>pcntl<br>pcre<br>PDO<br>pdo_mysql<br>Phar<br>posix<br>readline<br>Reflection<br>session<br>shmop<br>SimpleXML<br>sockets<br>sodium<br>SPL<br>standard<br>sysvmsg<br>sysvsem<br>sysvshm<br>tokenizer<br>xml<br>xmlreader<br>xmlwriter<br>xsl<br>Zend OPcache<br>zlib<br><br>[Zend Modules]<br>Zend OPcache
不同的已經粗體標註
bz2好像有內建只是預設停用,
所以接著安裝
`sudo apt install php-curl php-gd php-mbstring php-zip`
因為是本地開發,在多加個xdebug
`sudo apt install php-xdebug`
然後發現缺少了xdebug.so,所以透過pecl在裝一次
`sudo pecl install xdebug`
服務記得重啟
`service php8.0-fpm restart`
## 設定DN對應
在host檔案中新增
```
<IP> <你的DN>
```
如果開發完畢要取消對應,
在該行前面加個`#`註解掉即可
但需要注意的是每次啟動的IP可能不太一樣,
確認IP的方式可以輸入 `hostname -I` 來查詢
## 阻擋外部驗證
本專案會使用外部驗證,
本地開發驗證不會過,也不需要去驗證
驗證失敗會被導去正式網站的登入頁,
所以乾脆直接把連線給阻擋
除了本章節外,還可以用ufw、iptables等方式實現
### 使用hosts進行阻擋
先說目前的結論:
只有domain有效...IP/URL要另外想辦法
**參考:**
[linux 網路安全管理 - 安全](/8mL0eZmORUK2kf6LstzY8w)
[鳥哥第九章、防火牆與 NAT 伺服器 > .2.2 /etc/hosts.\{allow|deny} 的設定方式](http://linux.vbird.org/linux_server/0250simple_firewall.php#tcp_wrappers_setup)
#### 規則
1. 先以 /etc/hosts.allow 為優先比對,該規則符合就予以放行;
1. 再以 /etc/hosts.deny 比對,規則符合就予以抵擋;
1. 若不在這兩個檔案內,亦即規則都不符合,最終則予以放行。
項目|差異
---|---
/etc/hosts|重新導向,但IP就沒辦法了<br>比如說正式機的DN 我們要把他回自己,不能用阻擋的,不然怎麼開發?
/etc/hosts.deny|阻擋,可用/etc/hosts替代其功能(僅DN)<br>比如說透過第三方寄簡訊,不擋下來就真的發簡訊了
#### 驗證方式
因hosts.XXXX只能處理tcp的協定,
所以不可以用ping(icmp協定)來測試,
可用curl、telnet指令去連連看
telnet可以參考[如何檢測 Port 是否有活著 (TCP, UDP)](http://taiwanwolf.blogspot.com/2011/06/port-tcp-udp.html)
>TCP:
>使用 telnet
>telnet IP tcpport
>如果成功會出現
> Connected to IP
> Escape character is '^]'
>此時就按 Ctrl + ] 即可跳開到 telnet> 再下 quit 指令即可回到命令列
#### 阻擋IP
先說結論
本小節設定完後進行測試沒效...
Distro關閉且host端重開機後...也沒效果 !!!
超級奇怪...
嘗試用ufw,
請直接跳到ufw小節
編輯hosts.deny
`vi /etc/hosts.deny`
輸入內容
```
ALL: some.host.name, .some.domain
ALL: ip
```
設定格式如下:
`daemon_list : client_list [: command]`
格式說明:
daemon_list:
設定的 daemons, 用逗號 (,) 分隔每個 daemons, 用 ALL 代表全部 daemons.
client_list:
客戶端的 IP / DN / hostname, ALL 代表全部, 用逗號 (,) 或空白分隔, 網域表示法不支援遮罩 bit 數值表示( ex: 192.168.1.0/24 要用 /255.255.255.0
command:
當客戶端符合以上規則存取網路時, 需要執行的指令, 可選擇是否填寫.
#### 阻擋DN
1. 編輯hosts:`vi /etc/hosts`
PS. 透過/etc/hosts.deny也行,但我沒成功...
3. 停止自動產生:
該文件的開頭有提到一段話
```
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf
# [network]
# generateHosts = false
```
如果要用此設定的話,這個設定也別忘了
不然下次重啟就被覆蓋掉了
如果/etc/wsl.conf不存在就自己新增一個
3. 輸入內容:
如果導去127.0.0.1則是導給自己,就不會到對方那邊,從而達到阻擋的目的
```
127.0.0.1 aaa.bbb.ccc.tw
```
4. 驗證
雖然nslookup會顯示原本對方IP
但ping、curl(加上-v參數會顯示IP)、telnet都顯示127.0.0.1,
所以ok有成功
#### 阻擋URL
我也想知道怎麼實現,
若有前輩們知道可以留言~~ 感謝
### 使用ufw防火牆進行阻擋
參考:
[[ Linux ] – ufw 防火牆基本設定](https://www.webteach.tw/?p=3822)
安裝
`sudo apt install ufw`
設定預設規則
`sudo ufw default allow`
阻擋IP
`sudo ufw deny to 210.59.13.233`
阻擋DN
已使用hosts進行阻擋
啟用防火牆
`sudo ufw enable`
出錯...
```
# sudo ufw enable
ERROR: problem running ufw-init
iptables-restore v1.8.4 (legacy): Couldn't load match `limit':No such file or directory
Error occurred at line: 63
Try `iptables-restore -h' or 'iptables-restore --help' for more information.
iptables-restore v1.8.4 (legacy): Couldn't load match `limit':No such file or directory
Error occurred at line: 24
Try `iptables-restore -h' or 'iptables-restore --help' for more information.
Problem running '/etc/ufw/before.rules'
Problem running '/etc/ufw/user.rules'
```
以後有空再回頭更新...... :pray:
## 資料庫轉移轉移與調整
透過匯出匯入的方式來匯入
然後出現`[Err] 1273 - Unknown collation: 'utf8mb4_0900_ai_ci'` 錯誤
奇怪,兩邊都是MySQL 8 怎麼會有這問題?
懶得去想...乾脆全部換成 utf8mb4_general_ci 好了
將`utf8mb4_0900_ai_ci` 取代為 `utf8mb4_general_ci`
接著把剛剛匯入一半的全部刪掉重來~
解決Lost connection to MySQL server during query錯誤方法
500MB緩衝還不夠大的話再增加~
```
max_allowed_packet= 500M
```
錯誤:`Lost connection to MySQL server at 'reading initial communication packet', system error: 0`
## nginx建立憑證
自建憑證
```
# 建立一個放置憑證的目錄,考量到這個憑證是 NGINX 專用的,所以跟 NGINX 的設定檔放在一起可能會比較好管理。
mkdir /etc/nginx/ssl
# 產生自行簽署的 SSL 憑證
# 其中有個選項 Common Name (e.g. server FQDN or YOUR name) []: 請填寫您的DN,其他隨便填
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
```
接著調整 NGINX 伺服器
```
server {
listen 80 default_server;
listen [::]:80 default_server;
# 加入 SSL 設定
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
# 憑證與金鑰的路徑
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
# ...
}
```
參考: https://blog.gtwang.org/linux/nginx-create-and-install-ssl-certificate-on-ubuntu-linux/
## PHP調整
我會用到argc / argv,
所以會需要開啟register_argc_argv
設定php.ini
```
register_argc_argv = On
zend.exception_ignore_args = Off
```
## 將專案搬移至指定資料夾
輸入指令`explorer.exe .`
則可從host端透過類似網路磁碟機的方式開啟資料夾,
這時候就搬資料進去吧~
指令最後面的"`.exe .`"不要漏掉了
## 排除異常方法
### 通用方法,用出現500連線失敗來示範
資料庫搬了,程式搬了,嘗試連線卻發現是 500
要知道發生什麼事有以下幾種方式,
1. 查了一下log檔案
Nginx Log:/var/log/nginx/error.log
PHP Log:/var/log/php8.0-fpm.log
...竟然是空的!!!!
發現一個新問題,
因為有緩衝,
需要等緩衝滿了才會實際做寫入動作,
所以直接看檔案一開始會看不到...
2. 運用即時監看持續成長的指令tail來查看 (預設輸出10行)
**`tail -f /var/log/nginx/error.log`**
直到用`ctrl + C`來中斷
```
2021/07/17 16:48:09 [error] 21511#21511: *1 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught TypeError: mysqli_fetch_array(): Argument #1 ($result) must be of type mysqli_result, bool given in /var/www/html/sp/main_services.php:1016
Stack trace:
#0 /var/www/html/sp/main_services.php(1016): mysqli_fetch_array()
#1 /var/www/html/sp/loader.php(188): require_once('...')
#2 {main}
thrown in /var/www/html/sp/main_services.php on line 1016" while reading response header from upstream, client: 172.30.64.1, server: _, request: "GET /sp/loader.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.0-fpm.sock:", host: "172.30.69.189"
```
得知出錯位置在sp/main_services.php的第1016行
錯誤原因為型態錯誤
Uncaught TypeError: mysqli_fetch_array(): Argument #1 ($result) must be of type mysqli_result
不過感覺這樣還是有點麻煩~
後來發現是我資料庫的有些資料表忘了匯出...@@
3. 調整一下php.ini,把display_errors打開
反正是開發環境,直接把錯誤顯示出來比較方便~~
### 排除重新導向太多次的問題
打開專案首頁發現一直被302自己導去自己,
然後瀏覽器報重新導向太多次的問題
查看一下錯誤訊息
Nginx error Log 目前沒看到東東
Nginx access Log 看到一堆302
php8.0-fpm.log 目前沒看到東東
php_errors.log 目前沒看到東東
那...應該是程式的問題了
### unable to bind listening socket for address '/run/php/php8.0-fpm.sock': No such file or directory
請確認php-fpm服務有無開啟
### Warning: mysqli_connect(): (HY000/2002): No such file or directory
### SELECT list is not in GROUP BY clause and contains nonaggregated column XXX which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
解決方法就是把only_full_group_by拿掉
臨時做法
```shell
mysql -uroot -p
# 輸入帳密
mysql> SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY,',''));
mysql> flush privileges;
```
永久做法
進my.cnf設定
一時間沒找到my.cnf @@
...