服务器是什么
服务器(Server)本质上就是一台一直开着的电脑,专门用来提供服务。它可能在云端机房、也可能在你家里的角落,但核心特点是:
- 7×24 小时运行:不像你的笔记本,关机就没了
- 有公网 IP:互联网上的任何人都能访问到它(如果你允许的话)
- 运行服务:网站、API、数据库、文件存储……各种后台程序
你访问的每个网站、每个 App 背后,都有服务器在响应你的请求。
| 个人电脑 | 服务器 | |
|---|---|---|
| 运行时间 | 按需开关机 | 持续运行 |
| 访问方式 | 本地操作(键盘、鼠标、屏幕) | 远程连接(SSH、RDP) |
| 主要用途 | 开发、办公、娱乐 | 托管服务、处理请求、存储数据 |
| 操作系统 | Windows / macOS / Linux | 主要是 Linux(Ubuntu、CentOS 等) |
为什么需要服务器
作为开发者,你会在这些场景下用到服务器:
- 部署网站 / API:让别人能访问你的项目
- 运行长期任务:爬虫、数据处理、定时任务
- 学习 Linux:真实的生产环境体验
- 搭建个人服务:博客、网盘、代理、数据库
云服务器 vs 物理服务器:现在大部分人用的是云服务器(VPS),比如阿里云、腾讯云、AWS。它们本质是虚拟机,按需付费,几分钟就能开通。物理服务器需要自己买硬件、配网络,成本高,适合企业或特殊需求。
SSH 是什么
SSH(Secure Shell)是一种加密的网络协议,用来安全地远程登录和操作服务器。
想象一下:你的服务器在云端机房,没有屏幕、键盘、鼠标。怎么操作它?通过 SSH,你在自己电脑的终端里输入命令,SSH 把命令加密传输到服务器,服务器执行后把结果传回来——就像你坐在服务器前操作一样。
为什么要加密?因为你的命令、密码、数据都在互联网上传输。如果不加密,中间任何节点都能看到你的密码。SSH 用强加密算法保护这些信息,即使被截获也无法破解。
SSH 基础连接
密码认证(最简单的方式)
假设你有一台服务器:
- IP 地址:
123.45.67.89 - 用户名:
ubuntu - 密码:
your_password
在你的终端(WSL / Linux / macOS)里运行:
$ ssh ubuntu@123.45.67.89
命令格式解释:
ssh:SSH 客户端程序ubuntu:服务器上的用户名@:分隔符123.45.67.89:服务器的 IP 地址(也可以是域名)
第一次连接会提示:
The authenticity of host '123.45.67.89 (123.45.67.89)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
输入 yes 并回车,然后输入密码(输入时不会显示任何字符,这是正常的),回车后就登录成功了。
第一次连接时发生了什么
SSH 会把服务器的指纹(fingerprint)保存到你本地的 ~/.ssh/known_hosts 文件里。下次连接时,如果指纹变了,SSH 会警告你(可能是中间人攻击)。
安全提示:如果你不是第一次连接,却看到指纹变化的警告,不要继续连接。可能是服务器被重装了,也可能有人在中间劫持你的连接。联系服务器管理员确认。
SSH 密钥认证
密码认证虽然简单,但有几个问题:
- 每次都要输密码,麻烦
- 密码可能被暴力破解
- 密码在传输过程中(虽然加密了)仍然存在风险
密钥认证是更安全、更方便的方式。它的原理是非对称加密:
密钥对的概念
你会生成一对密钥:
- 私钥(Private Key):保存在你的电脑上,绝对不能泄露
- 公钥(Public Key):上传到服务器,可以公开
登录时的流程:
你发起连接,服务器发送一个随机挑战
你的电脑用私钥对挑战进行签名
服务器用你的公钥验证签名
验证通过,允许登录——全程不传输密码
为什么安全?因为私钥从不离开你的电脑,即使有人截获了通信内容,也无法伪造签名。只有持有私钥的人才能通过验证。
生成密钥对
在你的本地电脑(不是服务器)上运行:
# 生成 ED25519 密钥对(推荐,更安全更快)
$ ssh-keygen -t ed25519 -C "your_email@example.com"
# 如果系统不支持 ED25519,用 RSA(传统方式)
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
参数说明:
-t ed25519:指定密钥类型为 ED25519(现代、高效、安全)-t rsa -b 4096:RSA 类型,4096 位长度(传统但兼容性好)-C "email":添加注释,方便识别这个密钥是谁的
运行后会提示:
Enter file in which to save the key (/home/ubuntu/.ssh/id_ed25519):
直接回车使用默认路径,或者输入自定义路径(比如 ~/.ssh/my_server_key)。
Enter passphrase (empty for no passphrase):
这是给私钥加密的密码。建议设置,这样即使私钥文件被盗,没有这个密码也用不了。如果不想设置,直接回车留空。
生成完成后,~/.ssh/ 目录下会有两个文件:
~/.ssh/id_ed25519 # 私钥,保密!
~/.ssh/id_ed25519.pub # 公钥,可以公开
上传公钥到服务器
有两种方法:
方法一:使用 ssh-copy-id(推荐)
$ ssh-copy-id -i ~/.ssh/id_ed25519.pub ubuntu@123.45.67.89
输入服务器密码后,公钥会自动添加到服务器的 ~/.ssh/authorized_keys 文件里。
参数说明:-i ~/.ssh/id_ed25519.pub 指定要上传的公钥文件路径。如果不指定,会使用默认的 ~/.ssh/id_rsa.pub。
方法二:手动复制(如果 ssh-copy-id 不可用)
查看公钥内容:
$ cat ~/.ssh/id_ed25519.pub
复制输出的整行内容(以 ssh-ed25519 开头)
登录服务器(用密码):
$ ssh ubuntu@123.45.67.89
在服务器上创建 SSH 目录(如果不存在):
$ mkdir -p ~/.ssh
$ chmod 700 ~/.ssh
把公钥追加到 authorized_keys:
$ echo "你复制的公钥内容" >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
权限很重要!~/.ssh 必须是 700(只有所有者可读写执行),authorized_keys 必须是 600(只有所有者可读写)。权限不对,SSH 会拒绝密钥认证。
测试密钥登录
退出服务器(exit 或 Ctrl+D),然后重新连接:
$ ssh ubuntu@123.45.67.89
如果配置正确,应该不再要求输入服务器密码,直接登录成功。如果你给私钥设置了 passphrase,会要求输入私钥密码(这是本地验证,不是服务器密码)。
SSH 配置文件
每次都输入 ssh ubuntu@123.45.67.89 很麻烦,尤其是有多台服务器时。可以用 SSH 配置文件简化。
编辑 ~/.ssh/config(如果不存在就创建):
$ nano ~/.ssh/config
添加以下内容:
# 我的云服务器
Host myserver
HostName 123.45.67.89
User ubuntu
IdentityFile ~/.ssh/id_ed25519
Port 22
# 另一台服务器
Host workserver
HostName work.example.com
User admin
IdentityFile ~/.ssh/work_key
Port 2222
配置项说明:
Host:别名,你自己定义的简短名字HostName:实际的 IP 地址或域名User:登录用户名IdentityFile:使用的私钥文件路径Port:SSH 端口(默认 22,可省略)
保存后,连接就简单了:
# 不用再输入 IP、用户名、密钥路径
$ ssh myserver
# 连接另一台
$ ssh workserver
还可以配合 scp 和 rsync 使用:
# 复制文件到服务器
$ scp myfile.txt myserver:/home/ubuntu/
# 同步目录
$ rsync -avz ./myproject/ myserver:~/projects/
安全最佳实践
1. 禁用密码登录(只允许密钥)
配置好密钥认证后,应该禁用密码登录,防止暴力破解。
在服务器上编辑 SSH 配置:
$ sudo nano /etc/ssh/sshd_config
找到并修改这几行:
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
保存后重启 SSH 服务:
$ sudo systemctl restart sshd
警告:禁用密码登录前,务必确认密钥登录能正常工作!否则你会把自己锁在外面。建议先开一个新终端测试密钥登录,确认无误后再禁用密码。
2. 修改 SSH 默认端口
默认端口 22 是扫描器的首要目标。改成其他端口可以减少大量自动化攻击。
$ sudo nano /etc/ssh/sshd_config
修改:
Port 2222 # 改成 1024-65535 之间的任意端口
重启 SSH 后,连接时需要指定端口:
$ ssh -p 2222 ubuntu@123.45.67.89
# 或者在 ~/.ssh/config 里配置 Port 2222
3. 使用防火墙限制访问
# 只允许特定 IP 访问 SSH(推荐)
$ sudo ufw allow from 你的IP地址 to any port 22
# 或者限制连接速率(防止暴力破解)
$ sudo ufw limit 22/tcp
4. 定期更新系统
$ sudo apt update && sudo apt upgrade -y
5. 监控登录日志
# 查看最近的登录记录
$ last
# 查看失败的登录尝试
$ sudo grep "Failed password" /var/log/auth.log
常用服务器任务
文件传输
scp(简单复制)
# 上传文件到服务器
$ scp myfile.txt ubuntu@123.45.67.89:/home/ubuntu/
# 下载文件到本地
$ scp ubuntu@123.45.67.89:/home/ubuntu/data.csv ./
# 上传整个目录(-r 递归)
$ scp -r ./myproject ubuntu@123.45.67.89:~/projects/
# 使用配置文件的别名
$ scp myfile.txt myserver:~/
rsync(增量同步,更高效)
# 同步目录(只传输变化的文件)
$ rsync -avz ./myproject/ myserver:~/projects/
# 参数说明:
# -a: archive 模式(保留权限、时间戳等)
# -v: verbose(显示详细过程)
# -z: 压缩传输
# 排除某些文件
$ rsync -avz --exclude 'node_modules' --exclude '.git' ./myproject/ myserver:~/projects/
# 删除目标目录中源目录没有的文件(危险!)
$ rsync -avz --delete ./myproject/ myserver:~/projects/
进程管理
让程序在后台持续运行
SSH 断开后,普通进程会被终止。使用这些方法让程序持续运行:
方法一:nohup
# 后台运行,输出重定向到 nohup.out
$ nohup python app.py &
# 指定输出文件
$ nohup python app.py > app.log 2>&1 &
# 查看后台任务
$ jobs
# 查看进程
$ ps aux | grep python
方法二:screen(推荐)
# 安装 screen
$ sudo apt install screen
# 创建新会话
$ screen -S myapp
# 在会话里运行程序
$ python app.py
# 按 Ctrl+A 然后按 D 离开会话(程序继续运行)
# 重新连接到会话
$ screen -r myapp
# 列出所有会话
$ screen -ls
方法三:systemd(生产环境推荐)
创建系统服务,开机自启,崩溃自动重启:
$ sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
ExecStart=/usr/bin/python3 /home/ubuntu/myapp/app.py
Restart=always
[Install]
WantedBy=multi-user.target
# 启用并启动服务
$ sudo systemctl enable myapp
$ sudo systemctl start myapp
# 查看状态
$ sudo systemctl status myapp
# 查看日志
$ sudo journalctl -u myapp -f
端口转发
本地端口转发(访问服务器内网服务)
服务器上运行着一个只监听 localhost:5000 的服务,你想在本地浏览器访问:
$ ssh -L 8080:localhost:5000 myserver
现在访问本地的 http://localhost:8080 就等于访问服务器的 localhost:5000。
参数说明:-L 本地端口:目标主机:目标端口。目标主机是从服务器的视角看的,localhost 指服务器自己。
远程端口转发(让服务器访问你的本地服务)
你本地运行着一个服务(比如开发中的网站),想让服务器能访问:
$ ssh -R 9000:localhost:3000 myserver
服务器上访问 localhost:9000 就会转发到你本地的 localhost:3000。
动态端口转发(SOCKS 代理)
$ ssh -D 1080 myserver
在浏览器里配置 SOCKS5 代理 localhost:1080,所有流量都会通过服务器转发。
常见问题排查
问题 1:Permission denied (publickey)
原因:密钥认证失败。
排查步骤:
# 1. 确认公钥已上传到服务器
$ ssh myserver "cat ~/.ssh/authorized_keys"
# 2. 检查本地私钥权限(必须是 600)
$ ls -l ~/.ssh/id_ed25519
$ chmod 600 ~/.ssh/id_ed25519
# 3. 检查服务器上的权限
$ ssh myserver "ls -ld ~/.ssh && ls -l ~/.ssh/authorized_keys"
# ~/.ssh 应该是 700,authorized_keys 应该是 600
# 4. 用详细模式查看连接过程
$ ssh -v myserver
问题 2:Connection refused
原因:服务器 SSH 服务未运行,或防火墙阻止。
# 检查服务器 SSH 服务状态(需要先能登录)
$ sudo systemctl status sshd
# 检查防火墙
$ sudo ufw status
# 检查端口是否开放
$ sudo netstat -tlnp | grep :22
问题 3:Connection timed out
原因:网络不通,或 IP/端口错误。
# 测试网络连通性
$ ping 123.45.67.89
# 测试端口是否开放
$ telnet 123.45.67.89 22
# 或
$ nc -zv 123.45.67.89 22
问题 4:Host key verification failed
原因:服务器指纹变化(可能是服务器重装了,或中间人攻击)。
解决:如果确认是服务器重装,删除旧指纹:
$ ssh-keygen -R 123.45.67.89
下一步
掌握了 SSH 和服务器基础后,你可以:
- 部署你的第一个 Web 应用(Nginx + Flask / Node.js)
- 配置域名和 HTTPS 证书
- 学习 Docker 容器化部署
- 搭建 CI/CD 自动化流程
服务器是你项目的家,SSH 是你回家的钥匙。现在你已经掌握了这把钥匙的使用方法。