CentOS x Ubuntu

快速上手

Ubuntu 基于 Debian 架构,而 CentOS 与 Red Hat Enterprise Linux 同属 Red Hat 公司。在版本更新的频率上,Ubuntu 比 CentOS 更激进一点。

APT (Advanced Package Tool) and dpkg (Debian Package) are both package managers used in Debian-based Linux distributions. RPM and YUM are package management systems created for Red Hat-based Linux distributions.

systemctl and service

Linux 在启动时遵循一系列预定义的 boot sequences,而 init and inittab 作为其中重要的一环,负责启动其他重要的服务与进程。最为典型的 Init Systems In Linux 是 SysVInit(System V init or init) 和 SystemD。

SysVInit 初始化过程依赖于 /etc/init.d 目录下的各个脚本,并且是一个 start-once 的进程。命令 service 就是用于在终端来执行这些初始化脚本的。

与相对古老的 SysVInit 不同,SystemD 在初始化完成后还会继续作为 Daemon 进程来运行。而 systemctl 则正是用户与 SystemD 交互和配置的入口。

$ service SCRIPT COMMAND [OPTIONS] # run a System V init script
$ systemctl [OPTIONS...] COMMAND [UNIT...] # Control the systemd system and service manager

CentOS 中 chkconfig, service, systemctl 三者均可 manages services:

  • service
    • Function : Check/Start/Stop services
  • chkconfig
    • Before CentOS 7, it manages services.
    • Function : Check/Start/Stop services + Enable/Disable services + Register/Deregister services
  • systemctl
    • From CentOS 7('15~), it manages services.
    • Function : Check/Start/Stop services + Enable/Disable services

Managing system services: For RHEL 7, the systemctl command replaces service and chkconfig. - redhat

init.d & rc.d

可执行文件目录 /etc/init.d 是配置文件目录 /etc/init 的软链接。

Linux 启动时会寻找 /etc/init.d 里的脚本,根据其运行级别确定启动级别。

为保 Unix 的兼容,/etc/rc[0-6].d/etc/rc.d/rc[0-6].d 的软链接。

CentOS 与 Ubuntu 中除了服务脚本放置的位置相同外,服务脚本的编写以及服务的配置都是不同的。两者分别可使用 chkconfigsysv-rc-conf 进行配置。

/etc/rc.d/rc[0-6].d 文件中,Kxx 开头的代表杀死进程,通过 stop 参数调用;Sxx 开头的表示开始进程,用 start 参数调用。调用顺序按 xx 从小到大来执行。

许多的程序都有启动即开启的需要,这在 Windows 中称为服务 service,在 Linux 中称作守护进程 daemon。

初始化进程的任务就是去执行这些启动即开启的程序。在不同的场合中会分配不同的开机启动程序,这被称作运行级别 runlevel。

  • 运行级别 0:系统停机状态,默认运行级别不能设为 0
  • 运行级别 1:单用户工作状态,root 权限,用于系统维护,禁止远程登陆
  • 运行级别 2:多用户状态,没有 NFS
  • 运行级别 3:完全的多用户状态,有 NFS,登陆后进入控制台命令行模式
  • 运行级别 4:系统未使用,保留
  • 运行级别 5:X11 控制台,登陆后进入 GUI
  • 运行级别 6:系统正常关闭并重启,默认运行级别不能设为 6

su & sudo

执行 su 并输入 root 账户密码后可以取得 root 权限,但是环境变量不改变。

执行 su - 并输入 root 账户密码后所切换到的 root 用户,环境变量改变。

要求输入当前账户密码的 sudo 可以临时以特定权限执行命令,环境变量改变。

sudo 通过 /etc/sudoers 配置每个用户的操作权限。

Linux 未在配置 /etc/sudoers 中的用户运行 sudo 时可能会出现如下提示。

# xxx 当前用户无法执行 sudo 命令
$ xxx is not in the sudoers file.  This incident will be reported. 

此时需要通过 su - 切换用户后给文件 /etc/sudoers 添加用户对应的配置。

# 可使用 sudo 的帐号名称    来源主机=(可切换账户) 可执行的命令
icedamericano    ALL=(ALL) ALL

若在编辑配置文件时出现因权限问题而导致的操作被阻止的情况,可先追加对应的权限,在操作完成以后再移除对应的权限。

chmod u+w /etc/sudoers
chmod u-w /etc/sudoers

在使用 sudo 时的环境变量 environment variables 问题:

  • Defaults env_reset 默认重置环境变量
  • Defaults secure_path 指定的路径将作为 sudo 环境的 PATH 变量
  • Defaults env_keep 保留不被重置的环境变量,可在双引号中追加

在使用 sudo 命令时找不到所需的环境变量或者命令,查看此 SOF

cURL & Wget

cURL 是一个开源项目,主要的产品是 curl(命令行工具)和 libcurl(C 语言的 API 库),两者功能均是:基于网络协议,对指定 URL 进行数据传输。

GNU Wget,通常称为 Wget,是一个免费的命令行实用程序,用于使用 HTTP、HTTPS、FTP 传输文件。

从用途方面,wget 倾向于网络文件下载,而 curl 更倾向于网络接口调试。

curl 与 wget 的安装:

  • APT 作为 Debian 的默认包管理器,适用于 DEB 包格式
  • DNF 作为 RHEL8 中替代 yum 的包管理器,适用 RPM 包格式
  • Yum 是 Fedora 和 RedHat 中的包管理器
# Debian/Ubuntu
$ sudo apt-get install curl # 安装 curl
$ sudo apt-get install wget # 安装 wget
# REHL/CentOS/Fedora
sudo yum install curl # 安装 curl
sudo dnf install curl
sudo yum install wget # 安装 wget
sudo dnf install wget

SSH Secure Shell

SSH is a software package that enables secure system administration and file transfers over insecure networks.

ssh & openssh

Telnet uses the Transmission Control Protocol/Internet Protocol (TCP/IP) to connect to a remote system. Telnet data is sent in clear text.

Telnet 作为一款明文传输协议,在传输数据的过程中会有被窃取或篡改的风险。

由此,近来 Linux 系统的远程连接预设通常会采取更加安全的 SSH 代之。

最常见的 SSH implementations 莫过于 PuTTY 与 OpenSSH。

查看 OpenSSH 与 OpenSSL 版本。

$ ssh -V && openssl version

重新启动远程服务器 sshd 服务。

# Ubuntu 或 Debian Linux
sudo systemctl restart ssh.service
# RHEL/CentOS Linux
sudo systemctl restart sshd.service

ssh-copy-id 通过 Secure Shell Protocol 连接 Target Host 并更新用户的密钥。

ssh-copy-id 命令会编辑服务器上的 /root/.ssh/authorized_keys 文件。

$ ssh-copy-id -i ~/.ssh/id_rsa.pub <user>@<ip> -p 9527

ssh-add & ssh-agent

ssh-add 会将密钥添加到 ssh-agent,此命令位于 /usr/bin/ssh-add

ssh-agent 作为 SSH 的密钥管理器,能直接将密钥和证书保存在内存中。

The agent can then use the keys to log into other servers without having the user type in a password or passphrase again. This implements a form of single sign-on (SSO).

# Adding an Arbitrary Key
$ ssh-add ~/.ssh/???_id_rsa && ssh-add -l
  • -D Deletes all identities from the agent.
  • -d Deletes the given identities from the agent. The private key files for the identities to be deleted should be listed on the command line.
  • -L Lists public key parameters of all identities currently represented by the agent.
  • -l Lists fingerprints of all identities currently represented by the agent.

SSH config file

SSH client program 获取配置信息的方式:

  1. command line - take precedence over configuration files
  2. 用户配置文件 ~/.ssh/config - 优先级高于系统配置文件
  3. 系统配置文件 /etc/ssh/ssh_config

SSH 配置文件中的 configuration parameters:

  • Host 关键词:会以指定的模式匹配命令行所给出的 host name
  • HostName 真实主机名:默认为命令行输入的值,允许是 IP
  • AddKeysToAgent是否自动将私钥与密码添加到 ssh-agent:默认 no
  • AddressFamily 指定连接时所使用的地址族:可选 any|inet|inet6
  • IdentityFile 指定读取的认证文件路径:允许 DSA、Ed25519 或 RSA
  • Port 连接远程主机的端口:默认 22
  • ProxyCommand 连接服务器需执行的命令:%h、%p、%r
  • ...

scp & rsync

SCP (Secure Copy Protocol) is a network protocol used to securely copy files or folders between Linux (Unix) systems on a network.

Rsync is a free software utility for Unix- and Linux-like systems that copies files and directories from one host to another.

# scp [source] [target]
scp -P 2368 -r /Users/.../images root@x.xx.xx.xxx:/var/www/.../content

传输目录时未使用 -r 修饰,会出现 Error using SCP: "not a regular file" 异常。

在通过 scp 传输内容时不能过滤或者排除文件,有需要可以考虑 rsync 命令。

# rsync [OPTION]... SRC [SRC]... DEST
rsync -av -e ssh --exclude='*.env' ~/... root@centos7:/var/...
  • -v, --verbose increase verbosity
  • -a, --archive archive mode; same as -rlptgoD (no -H)

存档模式除了会递归同步目录以外,还会保留 users and groups、permissions、symbolic links(symlinks) 和时间戳 timestamps。

sftp & ftp

FTP File Transfer Protocol 使用客户端/服务器模型,可以支持 FTP 客户端与 Web 服务器之间直接传输文件。FTP Client 现较常见的是 FileZilla 与 Cyberduck。

SFTP 中的 S 可以理解为 SSH 或者 Secure。SFTP 的连接始终是安全的,客户端与服务器之间所传输的数据有进行加密的处理。

FTP 在最初连接时会进行身份的验证,但是在后续传递数据的过程中不会进行加密的处理,这意味着会存在数据被窃取的风险。

A socket is one endpoint of a two-way communication link between two programs running on the network.

Firewall Service

A firewall is a security device (hardware/software) that protects the network by filtering traffic and blocking unwanted/unauthorized access to private data.

Netfilter and iptables

netfilter 包过滤框架和 iptables 是 Linux 服务器上大部分防火墙解决方案的基础。

# 检查 iptables 服务是否正在运行
systemctl status iptables
# 停止正在执行的 iptables 服务
systemctl stop iptables
# 将 iptables 服务永久关闭
systemctl mask iptables
# 开启防火墙(重启后永久生效)
chkconfig iptables on
# 关闭防火墙(重启后永久生效)
chkconfig iptables off
# 开启防火墙(即时生效,重启后失效)
service iptables start
# 关闭防火墙(即时生效,重启后失效)
service iptables stop
# 重启防火墙
service iptables restartd

CentOS Firewalld

CentOS7 默认使用 firewalld 管理防火墙,而 CentOS6 及以下使用 iptables。

firewalld is firewall management software available for many Linux distributions, which acts as a frontend for Linux’s kernel-based nftables or iptables packet filtering systems.

在 RHEL 的衍生发行版、CentOS 以及 Fedora 中都会默认有安装 Firewalld。

与直接控制 nftables 或 iptables 相比,firewalld 有两个主要的特点:

  • firewalld 使用 zones 和 services 替代了 chain 和 rules
  • 动态管理规则集,可以在不中断现有会话和连接的情况下进行更新
# To start the service and enable firewalld on boot
sudo systemctl start firewalld
sudo systemctl enable firewalld
# To stop and disable firewalld
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# Check the firewall status. The output should say either running or not running
sudo firewall-cmd --state
# To view the status of the firewalld daemon
sudo systemctl status firewalld
# To reload a firewalld configuration
sudo firewall-cmd --reload

Firewalld 通过 XML 文件进行配置,常规用 firewall-cmd 命令进行操作即可:

  • 目录 /usr/lib/FirewallD 保存默认配置,如默认区域和公共服务
  • 目录 /etc/firewalld 保存系统配置文件,这些文件将覆盖默认配置

Firewalld 使用 Runtime 和 Permanent 两类配置集 configuration sets:

  • 运行时配置的改变不会在 reboot 或重启 firewalld 后保留
  • 持久配置不能起效于正在运行的系统上

默认情况下,firewall-cmd 适用于运行时配置,但可以通过 --permanent 来建立持久配置。具体可参阅 DOCfirewalld.org

Ubuntu UFW

UFW Uncomplicated Firewall 可以看作是 iptables 防火墙的直观界面。

对 UFW 指派的规则也都会出现在 iptables 所列的清单中。

开启与禁用 UFW。

$ sudo ufw enable
$ sudo ufw disable

展示 UFW 规则:

  • 运行 sudo ufw status verbose 以获取详细信息。输出将包含日志记录,默认策略和新配置文件信息。
  • 运行 sudo ufw status numbered 以获取当前所有规则(包含顺序和 ID)。若需要编辑现有的规则时,此命令很有用。

删除 UFW 规则:

  • 通过 sudo ufw delete <number> 按规则 ID 删除
  • 通过 sudo ufw delete allow <port> 按规则来删除开启的 port 规则
  • 通过 sudo ufw reset 直接重置 UFW

Linux Applications

NodeJS

下载官方编译的安装包,并将安装包解压至 /usr/local 目录。

$ wget https://nodejs.org/download/release/v14.17.1/node-v14.17.1-linux-x64.tar.gz
$ tar --strip-components 1 -xzvf node-v* -C /usr/local
$ node -v && npm -v # 输出 v14.17.1 与 6.14.13

也可以使用 EPEL —— Linux 额外的软件包进行安装。

# 由于 CentOS yum 预设并没有提供 Node.js,须通过 EPEL 安装
$ yum install epel-release
# 查看仓库源
$ yum repolist
Loaded plugins: fastestmirror, langpacks
Repository epel is listed more than once in the configuration
Loading mirror speeds from cached hostfile
repo id                                          repo name                                                status
docker-ce-stable/7/x86_64                        Docker CE Stable - x86_64                                     122
epel/7/x86_64                                    EPEL for redhat/centos 7 - x86_64                          13,674
extras/7/x86_64                                  Qcloud centos extras - x86_64                                 500
os/7/x86_64                                      Qcloud centos os - x86_64                                10,070+2
updates/7/x86_64                                 Qcloud centos updates - x86_64                              2,751
repolist: 27,117
# 查看 yum 能提供的软件包的全部版本 -> 此方式安装的 node 版本较旧
$ yum list nodejs  --showduplicates| sort -r
Loaded plugins: fastestmirror, langpacks
Repository epel is listed more than once in the configuration
Loading mirror speeds from cached hostfile
Available Packages
nodejs.x86_64                        1:6.17.1-1.el7
# EPEL 安装完成直接使用 yum 來安装 Node.js:
$ yum install nodejs

Nginx

区分 sites-available、sites-enabled 与 conf.d,可参考 serverfault

  • 目录 /etc/nginx/sites-available 用于放置页面的配置文件
  • 目录 /etc/nginx/sites-enabled 存放来自 sites-available 的软链接
  • 目录 /etc/nginx/conf.d 中以 .conf 结尾的配置文件都会被加载

要部署的代码文件的一般推荐存放位如下。

/home/<user_name>/<site_name>
/var/www/<site_name>
/var/www/html/<site_name>
/opt/<site_name>
/usr/share/nginx/html

Nginx 日志文件 access.log 与 error.log 一般位于 /var/log/nginx/ 目录;复用配置代码文件一般位于 /etc/nginx/snippets 目录;配置文件与主配置文件分别为于 /etc/nginx//etc/nginx/nginx.conf

常规 Nginx 安装与开启流程所涉及的主要命令如下。

# 安装 Nginx
sudo yum install nginx
# 设置开机启动|关闭
sudo systemctl enable|disable nginx # 运行此命令以后,会输出软连接关联信息
# 启动关闭重启 —— systemctl - Control the systemd system and service manager
sudo systemctl start|stop|restart nginx
# 查看运行状态
sudo systemctl status nginx
# 查看80口是否被占用
sudo lsof -i :80 # 查看80的nginx -> sudo lsof -i :80 | grep nginx
# 杀死端口
lsof -P | grep ':80' | awk '{print $2}' | xargs kill

Mongodb

配置包管理系统并安装 MongoDB 包。

vim /etc/yum.repos.d/mongodb-org-5.0.repo
# mongodb-org-5.0.repo
[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc
sudo yum install -y mongodb-org

包管理器在安装期间会创建默认目录,所有者和组名都是 mongod。MongoDB 使用 mongod 帐户使用以下的默认目录。

/var/lib/mongo (数据目录)
/var/log/mongodb (日志目录)

Linux 环境中使用 MongoDB 的常用命令如下。

# 启动、停止与重启
sudo systemctl start|stop|restart mongod
# 如果在启动时收到类似于以下内容的错误
# Failed to start mongod.service: Unit mongod.service not found.
# 需要先运行以下命令
sudo systemctl daemon-reload
# 验证 MongoDB 是否已成功启动
sudo systemctl status mongod
# 确保 MongoDB 在系统重新启动后启动
sudo systemctl enable mongod
# 开始连接 - 27017
mongosh

Java

默认 CentOS7 存储库包含最新的两个主要 Java LTS 版本,Java8 和 Java11,可以使用 yum 软件包管理器安装。

# => 以 root 或具有 sudo 权限的用户运行
# 安装 OpenJDK11
$ sudo yum install java-11-openjdk-devel
# CentOS7 支持 openjdk-headless 即适合于服务器应用程序的最小 Java 运行时
# 安装 OpenJDK headless => 现已包含在 java-11-openjdk-devel 依赖安装中
$ sudo yum install java-11-openjdk-headless
# 安装OpenJDK 8
$ sudo yum install java-1.8.0-openjdk-devel
# 检查 Java 版本验证安装
$ java -version
openjdk version "1.8.0_332"
OpenJDK Runtime Environment (build 1.8.0_332-b09)
OpenJDK 64-Bit Server VM (build 25.332-b09, mixed mode)

CentOS 系统上安装了多个 Java 版本,可以通过 alternatives 命令来设置终端默认版本。在改变 Java 版本的同时记得要改变 Java 编译的版本。

# 查看 Java 默认版本
$ java -version
# 更改默认版本 => alternatives => 输入用作默认版本的数字
$ sudo alternatives --config java
There are 2 programs which provide 'java'.
  Selection    Command
-----------------------------------------------
*+ 1           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.332.b09-1.el7_9.x86_64/jre/bin/java)
   2           java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.15.0.9-2.el7_9.x86_64/bin/java)
Enter to keep the current selection[+], or type selection number: 1
# 更改默认的 javac 版本,运行 alternatives 命令更改Java的编译器javac版本
sudo alternatives --config javac

Java 应用程序根据 JAVA_HOME 环境变量来确定 Java 的安装位置,并选择指定的版本来运行该程序。

针对当前用户配置 JAVA_HOME 环境变量如下。

echo 'export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk"' >> ~/.bashrc
source ~/.bashrc

为所有用户配置 JAVA_HOME 环境变量/系统范围如下。

echo 'export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk"' | sudo tee /etc/profile.d/java.sh
source /etc/profile.d/java.sh
# 验证是否正确设置 JAVA_HOME 环境变量
echo $JAVA_HOME
/usr/lib/jvm/java-1.8.0-openjdk

FAQ & Bugs

REMOTE HOST IDENTIFICATION HAS CHANGED

服务器在重装系统或者销毁实例后又新建实例并连接时可能会出现无法正常连接的情况,伴随终端提示 "REMOTE HOST IDENTIFICATION HAS CHANGED"。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is ...
Please contact your system administrator.
Add correct host key in /home/hostname /.ssh/known_hosts to get rid of this message.
Offending RSA key in /var/lib/sss/pubconf/known_hosts:4
RSA host key for pong has changed and you have requested strict checking.
Host key verification failed.

这是由于新的实例分配了与被销毁实例相同的地址,已经存储的旧实例主机密钥与新主机密钥发生了冲突。提供两种解决方案如下(原理都是一样的)。

  • 通过 ssh-keygen -R <ip> 删除已存储实例的 host key 后重新连接
  • ~/.ssh/known_hosts 中删除对应远程 IP 的信息

此外请确认服务器 /etc/ssh/sshd_config 文件里如下配置的准确。

PasswordAuthentication yes
PermitRootLogin yes

出现 "Permission denied (publickey,gssapi-keyex,gssapi-with-mic)" 的拒绝,也应同样进行上述操作更改,最后重启服务即可。

处理包含空格和特殊字符的文件名

在服务器运行 rm -rf 命令时出现异常 "rm: unrecognized option '--...'"。

$ sudo rm -rf --2019-08-06---4.50.33-1.png
rm: unrecognized option '--2019-08-06---4.50.33-1.png'
Try 'rm ./--2019-08-06---4.50.33-1.png' to remove the file '--2019-08-06---4.50.33-1.png'.
Try 'rm --help' for more information.

错误原因 => shell 将破折号 - 之后的内容解释为参数,但是明显没有这样的参数存在,所以出现报错。

解决方式:在以 - 开头的文件或目录前追加路径;在操作命令与待操作的文件之间加上 --

tomcat 启动成功却无法访问

服务器没有让对应的端口放行,需要对防火墙规则进行配置。需要注意的是:局域网没有固定的公网 IP,所以不能将局域网 IP (192.168.124.2) 设置为安全组。

结束

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议。转载请注明出处!