# 將現有專案移入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 @@ ...