[環境]
作業系統版本: Ubuntu 22.04
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.1 LTS Release: 22.04 Codename: jammy
[安裝 Nginx]
查看系統儲存庫,內建的 Nginx 最新版為 1.18,不是 Nginx 官網目前最新的穩定版,後面安裝官網提供的版本
$ sudo apt update $ apt list nginx -a Listing... Done nginx/jammy-updates 1.18.0-6ubuntu14.4 s390x nginx/jammy-security 1.18.0-6ubuntu14.3 s390x nginx/jammy 1.18.0-6ubuntu14 s390x
依照 Nginx 官網說明,加入官網提供的套件庫
https://nginx.org/en/linux_packages.html#Ubuntu
安裝必要套件
下載官方 nginx 簽章金鑰導入
確認下載的金鑰指紋是否跟官網說明相同,如果指紋不同,刪除金鑰檔案
加入穩定版的套件庫
查看目前所有儲存庫,確認有剛剛加入的 Nginx 官方套件庫
設定儲存庫優先選擇剛剛加入的官網套件庫而不是系統發行版提供的
取得最新套件清單
看可安裝的 Nginx 版本
安裝最新穩定版 Nginx
查看是否已啟動
查看是否開機自動啟動
https://nginx.org/en/linux_packages.html#Ubuntu
安裝必要套件
$ sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
$ gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 uid nginx signing key <signing-key@nginx.com>
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
$ grep ^[^#] /etc/apt/sources.list /etc/apt/sources.list.d/*
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy main restricted
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy-updates main restricted
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy universe
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy-updates universe
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy multiverse
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy-updates multiverse
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy-backports main restricted universe multiverse
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy-security main restricted
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy-security universe
/etc/apt/sources.list:deb http://ports.ubuntu.com/ubuntu-ports jammy-security multiverse
/etc/apt/sources.list.d/nginx.list:deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu jammy nginx
$ echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx Package: * Pin: origin nginx.org Pin: release o=nginx Pin-Priority: 900
$ sudo apt update
$ apt list nginx -a Listing... Done nginx/stable 1.24.0-1~jammy s390x nginx/stable 1.22.1-1~jammy s390x nginx/stable 1.22.0-1~jammy s390x nginx/jammy-updates 1.18.0-6ubuntu14.4 s390x nginx/jammy-security 1.18.0-6ubuntu14.3 s390x nginx/jammy 1.18.0-6ubuntu14 s390x
$ sudo apt install nginx查看 Nginx 版本
$ nginx -v nginx version: nginx/1.24.0
$ systemctl status nginx若沒有,則手動啟動
$ sudo systemctl start nginx
$ systemctl is-enabled nginx若沒有,則設定開機自動啟動
$ sudo systemctl enable nginx
查看防火牆是否有開放 80 PORT
$ sudo iptables -L若沒有,設定防火牆開放 80 PORT
$ sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT此時遊覽器瀏覽 Server IP 應該可以看到 Nginx 預設頁面
[Nginx 新增 http://test.example.com 網站]
$ sudo vi /etc/nginx/conf.d/webA.conf server { listen 80; listen [::]:80; server_name test.example.com; root /var/www/webA; index index.html; location / { try_files $uri $uri/ =404; } }
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo mkdir -p /var/www/webA $ sudo vi /var/www/webA/index.html test webA
$ sudo systemctl reload nginx此時遊覽器瀏覽 http://test.example.com 應該可以看到 test webA 頁面
[Nginx 的 test.example.com 網站,申請設定 Let’s Encrypt 提供的 SSL 憑證]
安裝 certbot,一個管理 Let’s Encrypt 憑證的工具
註:certbot 官網是使用 snap 套件管理工具安裝,但我測試的 VPS 是 s390x 架構,不能跑 snap 內的 certbot
.....
使用 APT 安裝系統內建的版本
$ sudo apt update $ sudo apt install certbot查看 certbot 版本
$ certbot --version certbot 1.21.0安裝 nginx 使用的 plugin
$ sudo apt install python3-certbot-nginx
開始向 Let’s Encrypt 申請 SSL 憑證,並自動設定在 Nginx 設定檔
(注意:此操作會自動修改 Nginx 設定檔,加入申請的 SSL 憑證、變為 HTTPS 網站。
可先將 Nginx 設定檔備份,事後比對 certbot 做了何種更動。
如果只想申請憑證,自己修改 Nginx 設定檔,可使用加了 certonly 參數的指令
sudo certbot certonly --nginx -d test.example.com )
過程會問幾個問題:
- Email,用來緊急續訂和安全通知
- 是否同意向 ACME server 註冊,必須同意選 Y
Automatic Certificate Management Environment (ACME) 為自動證書管理環境
Let’s Encrypt 使用此方式,驗證欲申請憑證的網域是否為申請者所有
https://letsencrypt.org/zh-tw/docs/challenge-types/ - 自由選擇是否分享 Email,會發送相關郵件。此項我選 N
$ sudo certbot --nginx -d test.example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel):xyz@example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Account registered.
Requesting a certificate for test.example.com
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/test.example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/test.example.com/privkey.pem
This certificate expires on 2023-12-29.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Deploying certificate
Successfully deployed certificate for test.example.com to /etc/nginx/conf.d/webA.conf
Congratulations! You have successfully enabled HTTPS on https://test.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
執行後,便自動完成 SSL 憑證申請與 Nginx 設定
查看 Nginx 被 Certbot 改了那些設定
$ cat /etc/nginx/conf.d/webA.conf server { server_name test.example.com; root /var/www/webA; index index.html; location / { try_files $uri $uri/ =404; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/test.example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/test.example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = test.example.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name test.example.com; return 404; # managed by Certbot }
防火牆開啟 HTTPS 使用的 443 PORT
$ sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT此時遊覽器瀏覽 https://test.example.com/ 應該可以看到 test webA 頁面
Let’s Encrypt 的憑證有效期限為 90 天
而前面使用 Certbot 申請憑證完成後的訊息,有一段已設定自動更新憑證的排程說明
「...
Certbot has set up a scheduled task to automatically renew this certificate in the background.
...」
我這個版本,是使用 list-timers 設定 SSL 憑證更新排程 (也有可能是使用 crontab 設定排程)
$ systemctl list-timers -all NEXT LEFT LAST PASSED UNIT ACTIVATES ... Sun 2023-10-01 03:39:12 UTC 3h 13min left n/a n/a certbot.timer certbot.service ...
$ systemctl status certbot.timer ● certbot.timer - Run certbot twice daily Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled) Active: active (waiting) since Sat 2023-09-30 23:49:24 UTC; 37min ago Trigger: Sun 2023-10-01 03:39:12 UTC; 3h 11min left Triggers: ● certbot.service Sep 30 23:49:24 web systemd[1]: Started Run certbot twice daily.
$ cat /usr/lib/systemd/system/certbot.timer [Unit] Description=Run certbot twice daily [Timer] OnCalendar=*-*-* 00,12:00:00 RandomizedDelaySec=43200 Persistent=true [Install] WantedBy=timers.target
$ cat /usr/lib/systemd/system/certbot.service [Unit] Description=Certbot Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html Documentation=https://certbot.eff.org/docs [Service] Type=oneshot ExecStart=/usr/bin/certbot -q renew PrivateTmp=true
其他:
- 測試憑證的自動續訂
$ sudo certbot renew --dry-run Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/test.example.com.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Account registered. Simulating renewal of an existing certificate for test.example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/test.example.com/fullchain.pem (success) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- 列出所有憑證及到期日
$ sudo certbot certificates Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Found the following certs: Certificate Name: test.example.com Serial Number: ***************************** Key Type: RSA Domains: test.example.com Expiry Date: 2023-12-29 23:07:50+00:00 (VALID: 89 days) Certificate Path: /etc/letsencrypt/live/test.example.com/fullchain.pem Private Key Path: /etc/letsencrypt/live/test.example.com/privkey.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- 更新快到期的 SSL 憑證
$ sudo certbot renew
- 停用 ACME 帳號
$ sudo certbot unregister
[安裝 PHP FPM]
$ sudo apt update $ sudo apt install php-fpm查看 PHP 版本
$ php -v PHP 8.1.2-1ubuntu2.14 (cli) (built: Aug 18 2023 11:41:11) (NTS) Copyright (c) The PHP Group Zend Engine v4.1.2, Copyright (c) Zend Technologies with Zend OPcache v8.1.2-1ubuntu2.14, Copyright (c), by Zend Technologies(註:若想安裝更新的版本
可自行判斷,是否另外加入 ppa:ondrej/php 提供的 PPA (Personal Package Archives、個人套件庫)
此 PPA,開發者是一名 Debian 的開發人員,
加入 PPA
$ sudo add-apt-repository ppa:ondrej/php
移除 PPA
$ sudo add-apt-repository --remove ppa:ondrej/php
)
查看是否已啟動
$ sudo systemctl status php8.1-fpm若沒有,則手動啟動
$ sudo systemctl start php8.1-fpm
$ sudo systemctl is-enabled php8.1-fpm若沒有,則設定開機自動啟動
$ sudo systemctl enable php8.1-fpm
Nginx 在 HTTP 443 PORT 的 Server {...} 設定區段加入 PHP FPM 設定
$ sudo vi /etc/nginx/conf.d/webA.conf server { ..... location ~ \.php$ { fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } ..... }
Ubuntu 系統預設儲存庫安裝的 PHP FPM,執行使用者身份是 www-data
$ ps aux | grep php-fpm root 29093 0.0 0.4 200720 19232 ? Ss 00:59 0:00 php-fpm: master process (/etc/php/8.1/fpm/php-fpm.conf) www-data 29094 0.0 0.3 201196 14416 ? S 00:59 0:00 php-fpm: pool www www-data 29095 0.0 0.3 201196 13908 ? S 00:59 0:00 php-fpm: pool www從 Nginx 官方套件庫安裝的 Nginx,執行使用者身份是 nginx
$ ps aux | grep nginx root 11481 0.0 0.1 21732 8096 ? Ss Sep30 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf nginx 30754 0.0 0.2 22592 8776 ? S 02:01 0:00 nginx: worker process nginx 30755 0.0 0.1 22592 7752 ? S 02:01 0:00 nginx: worker process
將 Nginx 的執行者身份改為 www-data 跟 php-fpm 一樣,避免出現 502 Bad Gateway
(如果 Nginx 也是安裝系統預設的套件,執行者身份也會是 www-data)
$ sudo vi /etc/nginx/nginx.conf #user nginx; user www-data;
Nginx 重新載入
$ sudo nginx -t $ sudo systemctl reload nginx
[安裝 php-mysql Extension]
$ sudo apt install php-mysql啟用 pdo_mysql module
$ sudo phpenmod pdo_mysqlphpenmod 會自動將系統預設設定檔 link 到 conf.d 資料夾
$ ls -al /etc/php/8.1/fpm/conf.d/*pdo_mysql* lrwxrwxrwx 1 root root 41 Apr 27 08:40 /etc/php/8.1/fpm/conf.d/20-pdo_mysql.ini -> /etc/php/8.1/mods-available/pdo_mysql.ini
查看 PHP 的 pdo_mysql 模組是否已啟用
$ php -m | grep pdo_mysql pdo_mysql也可以使用 phpquery 查看 pdo_mysql 模組狀態
$ phpquery -v 8.1 -s fpm -m pdo_mysql pdo_mysql (Enabled for fpm by local administrator)
$ sudo phpdismod pdo_mysql
$ phpquery -v 8.1 -s fpm -m pdo_mysql No module matches pdo_mysql (Disabled for fpm by local administrator)
$ sudo apt install php-memcached php-bcmath php-redis
[安裝 MariaDB]
$ sudo apt update $ sudo apt install mariadb-server
使用 mysql_secure_installation 進行安全的相關設定
mysql_secure_installation 指令,會一步一步以問答方式進行 MySQL 的安全性設定
因為是新安裝的,還沒有密碼,所以要 Enter current password for root 時留空白,直接按 enter
設定過程如下,我都使用預設值 Y (設定 root 密碼、移除匿名帳號、移除 root 可以從其他電腦登入的設定、移除 test 資料庫、重新載入權限)
$ sudo mysql_secure_installation NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and haven't set the root password yet, you should just press enter here. Enter current password for root (enter for none): OK, successfully used password, moving on... Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation. You already have your root account protected, so you can safely answer 'n'. Switch to unix_socket authentication [Y/n] Enabled successfully! Reloading privilege tables.. ... Success! You already have your root account protected, so you can safely answer 'n'. Change the root password? [Y/n] New password: Re-enter new password: Password updated successfully! Reloading privilege tables.. ... Success! By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] ... Success! By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] ... Success! Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB!
確定已啟動、設定開機啟動
$ sudo systemctl start mariadb $ sudo systemctl status mariadb $ sudo systemctl enable mariadb $ sudo systemctl is-enabled mariadb
登入 mariadb
$ sudo mariadb Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 45 Server version: 10.6.12-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04 Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> SELECT version(); +----------------------------------+ | version() | +----------------------------------+ | 10.6.12-MariaDB-0ubuntu0.22.04.1 | +----------------------------------+ 1 row in set (0.000 sec) MariaDB [(none)]> SELECT user(),current_user(),system_user(),session_user(); +----------------+----------------+----------------+----------------+ | user() | current_user() | system_user() | session_user() | +----------------+----------------+----------------+----------------+ | root@localhost | root@localhost | root@localhost | root@localhost | +----------------+----------------+----------------+----------------+ 1 row in set (0.000 sec) MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.000 sec)
參考:
- https://askubuntu.com/questions/148932/how-can-i-get-a-list-of-all-repositories-and-ppas-from-the-command-line-into-an
How can I get a list of all repositories and PPAs from the command line into an install script? - Ask Ubuntu - https://manpages.ubuntu.com/manpages/xenial/en/man8/apt.8.html
Ubuntu Manpage: apt - command-line interface - https://www.nginx.com/blog/using-free-ssltls-certificates-from-lets-encrypt-with-nginx/
Update: Using Free Let’s Encrypt SSL/TLS Certificates with NGINX - NGINX - https://cc.nchu.edu.tw/sites/default/files/CentOS_7.x%E7%94%B3%E8%AB%8BLet%E2%80%99s_Encrypt_SSL%E6%86%91%E8%AD%89%E5%8F%8A%E6%8E%92%E7%A8%8B%E8%87%AA%E5%8B%95%E6%9B%B4%E6%96%B0%E6%86%91%E8%AD%89.pdf#page=2&zoom=100,45,162
CentOS 7.x 申請 Let's Encrypt SSL 憑證及排 程自動更新憑證 - https://hackmd.io/@kmo/notes_systemd_timer
使用 systemd timer 取代 crontab - HackMD - https://eff-certbot.readthedocs.io/en/stable/using.html#automated-renewals
User Guide — Certbot 2.6.0 documentation - https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal&tab=standard
Certbot Instructions | Certbot - https://tecadmin.net/enable-disable-php-modules-ubuntu/
How To Enable/Disable PHP Modules In Ubuntu - TecAdmi