飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 基础入门

    • Linux 命令概述与环境准备
    • 文件与目录操作(上):ls、cd、pwd
    • 文件与目录操作(下):cat、touch、mkdir、rm、cp、mv
    • 获取帮助与基础工具:man、help、clear、exit、sudo
  • 文件权限

    • 文件权限管理:chmod、chown
  • 系统与监控

    • 进程管理与系统监控:ps、top、kill、df、du、free
    • 用户与环境:whoami、id、env、echo、history
  • 网络命令

    • 网络诊断(上):ping、curl、wget
    • 网络诊断(下):netstat、ss、ip
    • 网络抓包与高级工具:traceroute、tcpdump、nc
    • DNS 与防火墙:nslookup、dig、iptables
  • 文本处理

    • 文本搜索:grep
    • 文本处理(上):awk
    • 文本处理(下):sed
    • 文本排序与统计:sort、uniq、wc
    • 文件查看与查找:head、tail、cut、find
    • 归档压缩与管道组合:tar、gzip、xargs
  • 开发工具

    • 开发工具链(上):gcc、make
    • 开发工具链(下):gdb、time
    • 版本控制:git
    • 远程操作:ssh、scp
    • 编辑器:vim、nano
  • Shell 编程

    • Shell 编程基础(上):变量、管道、重定向
    • Shell 编程基础(下):条件、循环、函数
  • 综合实战

    • 综合实战:日志分析

远程操作:ssh、scp

ssh:安全远程登录

ssh(Secure Shell)是加密的远程登录协议,替代了不安全的 telnet,是管理远程服务器的标准方式。

基础连接

# 基本连接(默认端口 22)
ssh user@hostname
ssh user@192.168.1.100

# 指定端口(-p port)
ssh -p 2222 user@hostname

# 使用私钥登录(-i identity)
ssh -i ~/.ssh/id_rsa user@hostname

# 执行远程命令(不登录交互式 Shell)
ssh user@hostname "ls -la"
ssh user@hostname "sudo apt update"

# 本地端口转发(-L local:remote)
ssh -L 8080:localhost:80 user@hostname
# 访问本机 8080 端口 = 访问远程服务器的 80 端口

# 远程端口转发(-R)
ssh -R 9090:localhost:3000 user@hostname
# 远程服务器访问 9090 端口 = 访问本机的 3000 端口

# 动态端口转发(SOCKS 代理,-D)
ssh -D 1080 user@hostname
# 配置浏览器使用 SOCKS5 代理 localhost:1080

SSH 密钥认证

密码登录不安全且繁琐,SSH 密钥认证是标准做法。

# 生成密钥对(-t type,-b bits)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 或更现代的算法
ssh-keygen -t ed25519 -C "your_email@example.com"

# 生成过程
# Enter file in which to save the key: (~/.ssh/id_rsa)
# Enter passphrase: (可选,建议设置)
# 生成:私钥 ~/.ssh/id_rsa,公钥 ~/.ssh/id_rsa.pub

# 复制公钥到远程服务器(自动配置 authorized_keys)
ssh-copy-id user@hostname

# 手动复制公钥
cat ~/.ssh/id_rsa.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# 配置 SSH 客户端(~/.ssh/config)
cat >> ~/.ssh/config
Host myserver
    HostName 192.168.1.100
    User admin
    Port 2222
    IdentityFile ~/.ssh/id_rsa
    ServerAliveInterval 60
# Ctrl+D

# 使用别名连接
ssh myserver

SSH 配置优化

# ~/.ssh/config 常用配置
Host *
    ServerAliveInterval 60      # 每 60 秒发送心跳包
    ServerAliveCountMax 3       # 最多 3 次无响应断开
    StrictHostKeyChecking no    # 首次连接不提示确认(仅内网)
    UserKnownHostsFile /dev/null # 不记录 known_hosts(仅测试环境)

Host prod
    HostName 203.0.113.10
    User deploy
    Port 22
    IdentityFile ~/.ssh/prod_key
    ForwardAgent yes            # 转发本地 SSH agent

scp:安全文件复制

scp(Secure Copy)基于 SSH 协议在本地和远程之间复制文件。

# 本地 → 远程
scp file.txt user@hostname:/path/to/dest/
scp file.txt user@hostname:/path/to/dest/newname.txt

# 远程 → 本地
scp user@hostname:/path/to/file.txt ./

# 指定端口(-P port,注意大写 P)
scp -P 2222 file.txt user@hostname:/path/

# 使用私钥(-i identity)
scp -i ~/.ssh/id_rsa file.txt user@hostname:/path/

# 复制目录(-r recursive)
scp -r local_dir/ user@hostname:/path/to/dest/

# 复制多个文件
scp file1.txt file2.txt user@hostname:/path/

# 保留文件属性(-p preserve)
scp -p file.txt user@hostname:/path/

# 显示进度(-v verbose)
scp -v file.txt user@hostname:/path/

scp vs rsync

特性scprsync
增量传输否(全量复制)是(只传差异部分)
断点续传否是
删除目标多余文件否是(--delete)
速度慢(大文件)快(增量)
适用场景简单复制同步、备份
# rsync 替代 scp(推荐用于大文件/目录)
rsync -avz local_dir/ user@hostname:/path/to/dest/
# -a = 归档模式(保留属性)
# -v = 详细
# -z = 压缩传输

# rsync 增量同步(只传修改过的文件)
rsync -avz --delete local_dir/ user@hostname:/path/to/dest/
# --delete = 删除目标端多余的文件

SSH 端口转发详解

本地端口转发(-L)

把本地端口映射到远程服务器的某个端口,常用于访问远程内网服务。

# 场景:远程服务器运行了 MySQL(端口 3306),但只监听 localhost
# 你想用本地的 MySQL 客户端连接

ssh -L 3307:localhost:3306 user@remote-server
# 本地 3307 → 远程 localhost:3306

# 现在可以在本地连接
mysql -h localhost -P 3307 -u root -p

远程端口转发(-R)

把远程服务器的端口映射到本地的某个端口,常用于让外网访问内网服务。

# 场景:你在内网开发机运行了 Web 服务(端口 3000)
# 想让外网通过远程服务器访问

ssh -R 8080:localhost:3000 user@remote-server
# 远程 8080 → 本地 localhost:3000

# 外网用户访问 remote-server:8080 = 访问你的本地 3000

动态端口转发(-D)

创建 SOCKS 代理,把所有流量通过 SSH 隧道转发。

# 创建 SOCKS5 代理
ssh -D 1080 user@remote-server

# 配置浏览器/系统使用 SOCKS5 代理 localhost:1080
# 所有流量通过远程服务器转发

本篇小结

  • ssh user@host:远程登录,-p 指定端口,-i 指定私钥
  • ssh-keygen:生成密钥对,ssh-copy-id:复制公钥到远程服务器
  • ~/.ssh/config:配置主机别名、端口、私钥,简化连接
  • scp:基于 SSH 的文件复制,-r 递归目录,-P 指定端口
  • rsync -avz:增量同步,比 scp 更高效,支持断点续传
  • 本地转发 -L:访问远程内网服务;远程转发 -R:让外网访问本地服务;动态转发 -D:SOCKS 代理

动手实践

  1. SSH 密钥配置:

    # 生成密钥(如果还没有)
    ssh-keygen -t ed25519 -C "your_email@example.com"
    
    # 查看公钥
    cat ~/.ssh/id_ed25519.pub
    
    # 配置别名(如果有远程服务器)
    cat >> ~/.ssh/config
    Host test
        HostName 192.168.1.100
        User testuser
        Port 22
    # Ctrl+D
    
  2. scp 文件传输:

    # 本地 → 远程(如果有远程服务器)
    # scp file.txt test:/tmp/
    
    # 远程 → 本地
    # scp test:/etc/passwd ./
    
    # 本地练习(复制到 /tmp)
    scp /etc/passwd /tmp/passwd.bak
    
  3. 端口转发实验(如果有两台机器):

    # 终端 1:建立隧道
    # ssh -L 8080:localhost:80 test
    
    # 终端 2:通过隧道访问
    # curl http://localhost:8080
    
  4. rsync 同步练习:

    mkdir -p source/{a,b,c}
    touch source/{a,b,c}/file.txt
    
    rsync -avz source/ dest/
    ls -R dest/
    
    # 修改 source 后再次同步
    touch source/newfile.txt
    rsync -avz source/ dest/
    
  5. SSH 配置优化:

    cat >> ~/.ssh/config
    Host *
        ServerAliveInterval 60
        ServerAliveCountMax 3
    # Ctrl+D
    
  6. 思考:为什么 SSH 密钥认证比密码认证更安全?如果私钥文件 ~/.ssh/id_rsa 被泄露,攻击者能直接登录你的服务器吗?如何保护私钥?

上一页
版本控制:git
下一页
编辑器:vim、nano