移除 SpringBoot JAR 优化指南并添加 Gitee SSH 设置文档

原来的 SpringBoot JAR 优化指南 (SpringBoot打包体积优化) 已被删除,以简化仓库内容。同时,新增了一份全面的指南,帮助开发者设置 Gitee 的 SSH 密钥,以便安全访问仓库。新文档涵盖了使用现代 ed25519 加密标准进行密钥生成、配置和管理。
This commit is contained in:
MangMang 2025-05-13 22:49:04 +08:00
parent fbfcfcaae2
commit deeeb41145
7 changed files with 1973 additions and 616 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,616 +0,0 @@
---
icon: bi:arrows-expand
date: 2025-05-13
category:
- 实用工具
- JAVA
- SpringBoot
- JAR
tag:
- JAR包瘦身
title: SpringBoot打包体积优化.md
---
SpringBoot打包体积优化
<!-- more -->
# Spring Boot JAR 瘦身与加密:构建安全高效的部署方案
在 Spring Boot 应用程序部署过程中,我们常常面临两个主要挑战:
1. **JAR 包体积过大**Spring Boot 应用打包时会将所有依赖一起打包,导致最终 JAR 文件臃肿
2. **代码安全性问题**:部署到客户环境或公开场合的 JAR 包可能被反编译,造成核心业务逻辑泄露
为了解决这些问题,本文将介绍一套完整的解决方案,包括 JAR 包瘦身和 JAR 包加密两部分,以及配套的自定义类加载器,实现高效安全的
Spring Boot 应用部署。
## 整体方案设计
该方案由两个主要项目组成:
1. **spring-boot-jar-slim-encrypt**:用于将 Spring Boot 应用 JAR 包瘦身和加密
2. **spring-boot-custom-classloader**:用于加载瘦身和加密后的 JAR 包
### 工作流程
```
┌────────────────────┐
│ 原始Spring Boot │
│ JAR包 │
└──────────┬─────────┘
┌────────────────────┐ ┌────────────────────┐
│ spring-boot-jar- │ │ │
│ slim-encrypt工具 ├───►│ 提取依赖到libs目录 │
└──────────┬─────────┘ └────────────────────┘
┌────────────────────┐
│ 瘦身后的JAR包 │
└──────────┬─────────┘
┌────────────────────┐
│ XJar加密处理 │
└──────────┬─────────┘
┌────────────────────┐
│ 加密后的JAR包 │
│ (.xjar) │
└──────────┬─────────┘
│ 部署
┌─────────────────────────────────────────┐
│ 运行时环境 │
│ ┌─────────────────┐ ┌───────────────┐ │
│ │ 加密JAR (.xjar) │ │ 提取的依赖库 │ │
│ └────────┬────────┘ └───────┬───────┘ │
│ │ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ PlainTextClassLoader │ │
│ │ (自定义类加载器) │ │
│ └─────────────┬─────────────┬─────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌───────────────┐ │
│ │ 解密JAR内容 │ │ 加载外部依赖 │ │
│ └─────────────────┘ └───────────────┘ │
│ │
└─────────────────────────────────────────┘
```
1. 使用 spring-boot-jar-slim-encrypt 工具提取原始 JAR 包中的依赖
2. 将依赖库单独存储在 libs 目录
3. 对精简后的 JAR 包进行加密
4. 使用自定义类加载器加载外部依赖和解密 JAR 包
## 项目一spring-boot-custom-classloader
这是一个自定义类加载器项目,它实现了两种类加载器:
### 1. JarClassLoader 接口
```java
package com.mangmang;
import java.io.File;
public interface JarClassLoader {
String JAR_EXTENSION = ".jar";
/**
* 从指定目录加载所有JAR文件
*
* @param jarDir 包含要加载的JAR文件的目录路径
* @throws IllegalArgumentException 如果jarDir为null或不存在
*/
default void loadJar(String jarDir) {
if (jarDir == null || jarDir.trim().isEmpty()) {
throw new IllegalArgumentException("JAR目录路径不能为空");
}
File directory = new File(jarDir);
if (!directory.exists() || !directory.isDirectory()) {
throw new IllegalArgumentException("指定路径不是有效目录: " + jarDir);
}
File[] jarFiles = directory.listFiles(this::isJarFile);
if (jarFiles == null) {
return;
}
for (File jarFile : jarFiles) {
System.out.println("加载 》" + jarFile.getName());
scanJarFile(jarFile);
}
}
/**
* 递归扫描文件或目录以查找JAR文件
*
* @param file 要扫描的文件或目录
* @throws IllegalArgumentException 如果file为null
*/
default void scanJarFile(File file) {
if (file == null) {
throw new IllegalArgumentException("文件不能为null");
}
if (!file.exists()) {
return;
}
if (isJarFile(file)) {
addJARFile(file);
} else if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File f : files) {
scanJarFile(f);
}
}
}
}
/**
* 检查文件是否为JAR文件
*/
default boolean isJarFile(File file) {
return file.isFile() && file.getName().endsWith(JAR_EXTENSION);
}
/**
* 将JAR文件添加到类加载器
*
* @param jar 要添加的JAR文件
* @throws IllegalArgumentException 如果jar为null或不是有效的JAR文件
*/
void addJARFile(File jar);
}
```
这是一个接口,定义了 JAR 文件加载的核心方法:
- `loadJar(String jarDir)`: 从指定目录加载所有 JAR 文件
- `scanJarFile(File file)`: 递归扫描文件或目录查找 JAR 文件
- `isJarFile(File file)`: 检查文件是否为 JAR 文件
- `addJARFile(File jar)`: 将 JAR 文件添加到类加载器
### 2. PlainTextClassLoader 实现
```java
package com.mangmang;
import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.lang.NonNull;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* 明文类加载器
* <p>
* 该类实现了自定义类加载器接口和Spring应用启动事件监听器接口。
* 主要功能是在应用启动时从JVM启动参数中查找指定路径的JAR文件并加载。
* 通过反射机制将JAR文件动态添加到当前线程的类加载器中实现运行时加载额外的类库。
* </p>
* <p>
* 使用方法:
* 1. 在JVM启动参数中添加 -Dexternal.jars.path=你的JAR文件目录路径
* 2. 系统将自动加载该目录下所有的JAR文件
* </p>
* <p>
* 示例:
* java -Dexternal.jars.path.path=/path/to/jars -jar your-application.jar
* </p>
*/
public class PlainTextClassLoader implements JarClassLoader, ApplicationListener<ApplicationStartingEvent> {
private final String findPath = "external.jars.path"; // 查找路径的键名
private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // 获取当前线程的类加载器
private final List<File> jarFiles = new ArrayList<>(); // 存储已加载的JAR文件列表
/**
* 构造函数
* <p>
* 在初始化时执行以下操作:
* 1. 设置当前线程的类加载器
* 2. 输出启动日志信息
* 3. 从JVM启动参数中检索包含"external.jars.path.path"的参数
* 4. 提取路径值并调用loadJar方法加载指定目录下的JAR文件
* </p>
*/
public PlainTextClassLoader() {
// 设置当前线程的类加载器
Thread.currentThread().setContextClassLoader(classLoader);
// 打印启动信息
System.out.println("启动自定义明文类加载器");
// 查找并加载外部JAR文件
loadExternalJarsFromSystemProperties();
}
/**
* 从系统属性中查找并加载外部JAR文件
*/
private void loadExternalJarsFromSystemProperties() {
List<String> inputArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
// 查找包含指定路径参数的启动参数
inputArguments.stream()
.filter(arg -> arg.contains(findPath))
.map(this::extractPathFromArgument)
.filter(Objects::nonNull)
.forEach(this::loadJar);
}
/**
* 从JVM参数中提取路径值
*
* @param argument JVM启动参数
* @return 提取的路径值如果提取失败则返回null
*/
private String extractPathFromArgument(String argument) {
String prefix = "-D" + findPath + "=";
if (argument.startsWith(prefix)) {
String path = argument.replace(prefix, "");
if (!path.isEmpty()) {
return path;
}
}
return null;
}
/**
* 处理应用程序启动事件
* <p>
* 当Spring应用启动时会触发此方法。
* 目前该方法为空实现,可以在此添加应用启动时需要执行的代码。
* </p>
*
* @param event Spring应用启动事件对象
*/
@Override
public void onApplicationEvent(@NonNull ApplicationStartingEvent event) {
// 应用程序启动事件的处理方法,目前为空
}
/**
* 将JAR文件添加到类加载器
* <p>
* 通过反射机制调用URLClassLoader的addURL方法将指定的JAR文件URL添加到当前类加载器。
* 添加成功后JAR文件中的类可以被当前JVM加载和使用。
* 同时将已加载的JAR文件记录到jarFiles列表中。
* </p>
*
* @param jar 要添加到类加载器的JAR文件对象
* @throws RuntimeException 如果添加过程中发生任何异常将抛出RuntimeException
*/
@Override
public void addJARFile(File jar) {
if (jar == null) {
throw new IllegalArgumentException("JAR文件不能为null");
}
try {
addUrlToClassLoader(jar);
jarFiles.add(jar);
System.out.println(jarFiles);
} catch (Exception e) {
throw new RuntimeException("添加JAR文件到类加载器失败: " + jar.getName(), e);
}
}
/**
* 通过反射将JAR文件URL添加到类加载器
*
* @param jar 要添加的JAR文件
* @throws Exception 如果反射操作失败
*/
private void addUrlToClassLoader(File jar) throws Exception {
Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
if (!addUrlMethod.isAccessible()) {
addUrlMethod.setAccessible(true);
}
URL jarUrl = jar.toURI().toURL();
addUrlMethod.invoke(classLoader, jarUrl);
}
```
这是一个明文类加载器,实现了 `JarClassLoader` 接口和 Spring 的 `ApplicationListener<ApplicationStartingEvent>` 接口,用于在
Spring Boot 应用启动时加载外部 JAR 文件:
主要特点:
- 在 Spring Boot 应用启动时自动执行
- 通过 JVM 参数 `-Dexternal.jars.path=你的JAR文件目录路径` 指定外部 JAR 文件目录
- 使用反射机制将 JAR 文件 URL 添加到当前线程的类加载器中
使用示例:
```bash
java -Dexternal.jars.path=/path/to/jars -jar your-application.jar
```
## 项目二spring-boot-jar-slim-encrypt
这个工具用于压缩和加密 Spring Boot JAR 文件,主要包含以下两个核心类:
### 1. JarUtil 工具类
```java
// 路径spring-boot-jar-slim-encrypt/src/main/java/com/mangmang/JarUtil.java
package com.sunri;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import io.xjar.XCryptos;
import io.xjar.XEncryption;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.compress.utils.Sets;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
public class JarUtil {
/**
* 表示UTF-8字符编码的常量。
* 该变量用于在各种文件操作中强制使用UTF-8编码
* 确保在整个应用程序中一致地处理文本数据。
*/
private static final String UTF_8 = "UTF-8";
/**
* 常量BOOT_INF_LIB表示JAR文件中通常存储依赖库的默认目录路径。
* 该路径主要用于在压缩或排除等操作中识别和处理库文件。
*/
private static final String BOOT_INF_LIB = "BOOT-INF/lib";
/**
* 用于标识JARJava归档文件的文件扩展名。
* 该常量表示JAR文件的标准扩展名通常用于
* 文件过滤、命名或在目录或归档中识别JAR文件的操作。
*/
private static final String JAR_EXTENSION = ".jar";
/**
* 定义在管理JAR过程中生成的需求文件的后缀
* 特别是在处理依赖项或排除项时使用。
* 该字符串用作特定的文件名模式,用于保存与特定服务
* 相关的排除依赖项或其他需求的列表。
* 默认值为"-requirements.txt"。
*/
private static final String REQUIREMENTS_SUFFIX = "-requirements.txt";
/**
* 预定义的、不可修改的特定jar文件名集合被视为
* "安全"或"始终包含"的文件。这些jar文件通常在
* 处理或压缩操作中免于排除过滤。
* 该集合包含以下jar标识符
* - "spring"
* - "logback-core"
* - "tomcat"
* 该变量用于根据jar文件名决定是否包含特定jar文件的操作中。
* 它作为应用程序关键或必要jar的白名单。
*/
private static final Set<String> WHITE_LIST_JARS = Sets.newHashSet("spring", "logback-core", "tomcat");
/**
* 通过排除和包含指定的条目来压缩给定的源JAR文件并将结果写入目标JAR文件。
* 它处理源JAR的条目应用排除和包含规则还可以将某些条目提取到指定的目录中。
* 在此过程中创建一个临时文件成功完成后将其重命名为目标JAR文件。
*
* @param serviceName 正在处理的服务名称,主要用于日志记录和创建其他相关文件。
* @param sourceJar 要压缩的源JAR文件。
* @param includes 指定应保留哪些条目的包含模式集合。可能会自动添加额外的默认包含项。
* @param exclusions 指定应排除哪些条目的排除模式集合。
* @param targetJar 将写入压缩JAR的文件。
* @param libDir 某些被排除的条目可能被提取到的目录(如适用)。
*/
public static void compress(String serviceName, File sourceJar, Set<String> includes, Set<String> exclusions, File targetJar, String libDir) {
includes.addAll(WHITE_LIST_JARS);
File tempJar = new File(targetJar.getAbsolutePath() + ".tmp");
Set<String> excludedJars = new HashSet<>();
if (processJarEntries(sourceJar, tempJar, includes, exclusions, libDir, excludedJars)) {
finalizeCompression(serviceName, targetJar, tempJar, excludedJars, libDir);
} else {
boolean delete = tempJar.delete();
System.out.println("删除临时文件:{" + delete + "}");
}
}
/**
* 处理源JAR文件中的条目以生成临时JAR文件
* 同时根据包含和排除规则过滤条目。如果需要,
* 还会将指定的JAR条目提取到库目录中。
*
* @param sourceJar 要处理的源JAR文件
* @param tempJar
```
这个工具类提供了两个主要功能:
#### JAR 包压缩功能
`compress` 方法实现了 JAR 瘦身功能:
- 根据包含列表和排除列表过滤 JAR 中的依赖
- 将被排除的依赖提取到指定的库目录
- 生成一个记录排除依赖的需求文件
- 创建一个只包含必要依赖的精简 JAR 文件
#### JAR 包加密功能
`encrypt` 方法利用 XJar 库实现了 JAR 加密:
- 支持指定加密密码
- 通过包含和排除模式选择性地加密 JAR 中的内容
- 生成加密后的 XJar 文件
### 2. SpringBootJarSlimEncryptApplication 主应用
```java
// 路径spring-boot-jar-slim-encrypt/src/main/java/com/mangmang/SpringBootJarSlimEncryptApplication.java
```
这是工具的主应用类,提供了完整的命令行接口来处理 JAR 文件的压缩和加密:
主要功能:
- 通过配置常量定义输入/输出目录、加密设置等
- 支持从 XML 配置文件加载要包含和排除的依赖项
- 批量处理多个 JAR 文件
- 支持通过系统属性覆盖默认配置
主要配置参数:
- `xml.dir`: 依赖项 XML 文件目录(默认: `./config/xml/`
- `raw.dir`: 原始 JAR 文件目录(默认: `./config/rawJars/`
- `compress.dir`: 压缩后 JAR 文件目录(默认: `./config/compressJars/`
- `libs.dir`: 提取的库文件目录(默认: `./config/libs/`
- `xjar.dir`: 加密后的 XJar 文件目录(默认: `./config/xJars/`
- `compress.enable`: 是否启用压缩功能(默认: `true`
## 使用步骤
### 步骤 1: 集成自定义类加载器
在你的 Spring Boot 项目中添加自定义类加载器依赖:
```xml
<dependency>
<groupId>com.mangmang</groupId>
<artifactId>spring-boot-custom-classloader</artifactId>
<version>1.0.0</version>
</dependency>
```
### 步骤 2: 构建 Spring Boot 应用
正常构建你的 Spring Boot 应用:
```bash
mvn clean package
```
### 步骤 3: 配置依赖排除和包含规则
创建两个 XML 文件以定义要排除和包含的依赖项:
**exclusions.xml**(要排除的依赖):
```xml
<?xml version="1.0" encoding="UTF-8"?>
<dependencies>
<dependency>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.0</version>
</dependency>
<!-- 其他要排除的依赖 -->
</dependencies>
```
**includes.xml**(要保留的依赖):
```xml
<?xml version="1.0" encoding="UTF-8"?>
<dependencies>
<dependency>
<artifactId>spring-boot-custom-classloader</artifactId>
</dependency>
<!-- 其他要保留的依赖 -->
</dependencies>
```
### 步骤 4: 执行 JAR 瘦身和加密工具
将你的 Spring Boot JAR 文件放入 `./config/rawJars/` 目录,然后运行瘦身加密工具:
```bash
java -jar spring-boot-jar-slim-encrypt.jar
```
你可以通过系统属性覆盖默认配置:
```bash
java -Dcompress.enable=true -Dlibs.dir=/custom/libs/path -jar spring-boot-jar-slim-encrypt.jar
```
### 步骤 5: 部署和运行
部署加密后的 JAR 文件和提取的库文件:
```bash
java -Dexternal.jars.path=/path/to/libs -jar your-application.xjar
```
## 技术原理解析
### JAR 瘦身原理
1. 扫描 Spring Boot JAR 中的 `BOOT-INF/lib` 目录
2. 根据配置的排除和包含规则过滤依赖
3. 将被排除的依赖提取到外部目录
4. 创建一个不包含被排除依赖的新 JAR 文件
### JAR 加密原理
1. 使用 XJar 库实现 JAR 文件内容的加密
2. 只加密指定的文件模式(如 Java 类文件、配置文件等)
3. 避免加密某些需要保持明文的资源
### 自定义类加载器原理
1. 在 Spring Boot 应用启动时初始化自定义类加载器
2. 扫描指定目录下的 JAR 文件
3. 使用反射机制将 JAR 文件 URL 添加到当前类加载器
## 方案优势
1. **减小 JAR 体积**:将大型依赖库外置,显著减小主 JAR 文件体积
2. **提高安全性**:通过加密保护核心业务逻辑和敏感配置
3. **灵活配置**:支持通过 XML 配置和系统属性灵活控制瘦身和加密过程
4. **无缝集成**:与 Spring Boot 应用无缝集成,无需修改应用代码
## 注意事项
1. 确保加密密码安全保存,丢失密码将导致无法运行加密的 JAR
2. 测试瘦身后的应用,确保所有需要的依赖都能正确加载
3. 部署时必须将提取的依赖库和加密后的 JAR 一起部署
4. 启动应用时必须指定外部库路径参数
## 结论
通过结合 JAR 瘦身、JAR 加密和自定义类加载器,我们成功构建了一套完整的 Spring Boot 应用优化和保护方案。这不仅有效减小了部署包的体积,还提高了应用的安全性,为企业级
Spring Boot 应用的部署提供了一种实用的解决方案。
在实际应用中,可以根据具体需求调整配置参数,以达到最佳的平衡点。例如,可以根据应用规模和安全需求调整要排除的依赖和加密的文件模式。
这套工具实现了将原本臃肿的 Spring Boot 应用拆分为核心加密 JAR 和外部依赖库的方案,使得应用部署更加灵活,也为应用分发和更新提供了更多可能性。
------
*注:本方案适用于需要保护核心业务逻辑或减小部署包体积的 Spring Boot
应用。对于简单应用或开源项目,可能不必使用这么复杂的方案。*

View File

@ -0,0 +1,558 @@
---
icon: bi:arrows-expand
date: 2025-05-08
category:
- win10
tag:
- wsl
- http
title: WSL2
---
# WSL2完全配置指南从安装到实用工具
Windows Subsystem for Linux (WSL2) 为Windows用户提供了无需双系统或虚拟机就能运行Linux环境的能力。本文将全面介绍WSL2的安装、配置和优化过程包括网络设置、常用工具安装和问题排查等内容。
<!-- more -->
## 安装WSL2
1. **启用WSL功能** 打开控制面板,启用"Windows Subsystem for Linux"和"虚拟机平台"功能,然后重启电脑。
2. **检查WSL版本**
```powershell
wsl --status
wsl --update
```
3. **设置默认为WSL2**
```powershell
wsl --set-default-version 2
```
4. **查看可用的Linux发行版**
```powershell
wsl --list --online
```
5. **安装Linux发行版**
```powershell
# 安装默认版本(Ubuntu)
wsl --install
# 或安装指定版本
wsl --install -d Ubuntu-24.04
```
6. **设置用户名和密码**,安装完成后系统会提示设置。
7. **更新系统**
```bash
sudo apt update && sudo apt upgrade
```
8. **验证安装**
```powershell
wsl -l -v
```
## 网络配置
### 配置DNS
WSL2使用的DNS服务器在`/etc/resolv.conf`文件中设置,为防止每次启动重置,需要进行以下配置:
1. 创建`/etc/wsl.conf`文件:
```bash
[network]
generateResolvConf = false
```
2. 删除原链接文件:
```bash
rm /etc/resolv.conf
```
3. 创建新配置:
```bash
vi /etc/resolv.conf
# 添加内容
nameserver 114.114.114.114
```
4. 重启WSL
```bash
exit
wsl --shutdown
wsl
```
5. 测试网络:
```bash
ping www.baidu.com
```
### 配置桥接网络
1. **开启Hyper-V**后执行以下命令:
```powershell
Get-NetAdapter
New-VMSwitch -SwitchName "VETH" -NetAdapterName "以太网" -AllowManagementOS $True
```
2. 创建`.wslconfig`配置文件:
```powershell
cd ~
New-Item .wslconfig
notepad .\.wslconfig
```
3. 添加以下内容:
```
[wsl2]
networkingMode=bridged
vmSwitch=VETH
ipv6=true
```
### 配置网络代理
1. 关闭自动更新DNS
```bash
#/etc/wsl.conf
[network]
generateResolvConf = false
```
2. 添加以下脚本至`.bashrc`或`.zshrc`
```bash
vi ~/.bashrc
# 添加代理配置
export hostip=10.6.212.22 # 替换为你的代理IP
export hostport=7890 # 替换为你的代理端口
alias proxy='
export HTTPS_PROXY="http://${hostip}:${hostport}";
export HTTP_PROXY="http://${hostip}:${hostport}";
export ALL_PROXY="http://${hostip}:${hostport}";
echo -e "Acquire::http::Proxy \"http://${hostip}:${hostport}\";" | sudo tee -a /etc/apt/apt.conf.d/proxy.conf > /dev/null;
echo -e "Acquire::https::Proxy \"http://${hostip}:${hostport}\";" | sudo tee -a /etc/apt/apt.conf.d/proxy.conf > /dev/null;
'
alias unproxy='
unset HTTPS_PROXY;
unset HTTP_PROXY;
unset ALL_PROXY;
sudo sed -i -e '/Acquire::http::Proxy/d' /etc/apt/apt.conf.d/proxy.conf;
sudo sed -i -e '/Acquire::https::Proxy/d' /etc/apt/apt.conf.d/proxy.conf;
'
```
3. 执行命令启用/禁用代理:
```bash
# 启用代理
proxy
# 禁用代理
unproxy
```
4. 固定DNS配置
```bash
sudo rm /etc/resolv.conf
sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
sudo bash -c 'echo "[network]" > /etc/wsl.conf'
sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'
sudo chattr +i /etc/resolv.conf
```
5. 测试代理:
```bash
curl -vv google.com
```
## 基础功能配置
### 开启SSH服务
1. 安装SSH服务
```bash
sudo apt update && sudo apt upgrade
sudo apt-get install openssh-server
```
2. 修改SSH配置
```bash
sudo vi /etc/ssh/sshd_config
```
找到`PasswordAuthentication`行,确保设置为`yes`
3. 启动并设置开机自启:
```bash
sudo systemctl status ssh
sudo systemctl start ssh
sudo systemctl enable ssh
```
### 安装桌面环境
```bash
sudo apt update
sudo apt install ubuntu-desktop
# 安装远程桌面服务
sudo apt-get install xrdp
sudo systemctl start xrdp
sudo systemctl enable xrdp
```
### 映射Windows目录至WSL
```bash
# 创建挂载点
sudo mkdir /mnt/z
# 挂载Windows目录
sudo mount -t drvfs C:/User/xxx/Desktop/挂载文件 /mnt/z
```
## 系统管理
### 查看端口
查询端口占用有两种常用方法:
1. 使用`netstat`
```bash
sudo apt-get install net-tools
sudo netstat -tunlp | grep 端口号
```
2. 使用`lsof`
```bash
sudo apt-get install lsof
sudo lsof -i:端口号
```
### 修改主机名
1. 使用`hostnamectl`命令:
```bash
sudo hostnamectl set-hostname 新主机名
```
2. 修改配置文件:
```bash
sudo vi /etc/hostname
sudo vi /etc/hosts
```
在hosts文件中将`127.0.1.1`对应的旧主机名替换为新主机名
3. 重启系统(可选):
```bash
sudo reboot
```
## 开发环境配置
### IDEA中文乱码修复
1. 安装语言包:
```bash
sudo apt install language-pack-zh-hans
```
2. 配置语言环境:
```bash
sudo dpkg-reconfigure locales
# 选择en_US.UTF-8和zh_CN.UTF-8并将zh_CN.UTF-8设为默认
```
3. 安装字体工具:
```bash
sudo apt install fontconfig
```
4. 配置Windows字体
```bash
sudo vi /etc/fonts/local.conf
```
添加内容:
```xml
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/mnt/c/Windows/Fonts</dir>
</fontconfig>
```
5. 刷新字体缓存:
```bash
fc-cache -f -v
```
6. 重启WSL
```bash
wsl --shutdown
```
### IDEA配置输入法
1. 安装fcitx输入法
```bash
sudo apt install fcitx dbus-x11 im-config fcitx-sunpinyin
```
2. 编辑`/etc/locale.gen`
```bash
vi /etc/locale.gen
# 取消注释行zh_CN.UTF-8
```
3. 配置环境变量:
```bash
vi ~/.profile
# 添加内容
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export DefaultIMModule=fcitx
fcitx-autostart &>/dev/null
```
4. 更新配置:
```bash
source ~/.profile
```
5. 配置快捷键:
```bash
fcitx-config-gtk3
```
6. IDEA支持编辑`idea.sh`启动脚本,添加:
```properties
export XMODIFIERS=@im=fcitx
export QT_IM_MODULE=fcitx
```
### 安装Docker
1. 更新系统包:
```bash
sudo apt update
```
2. 安装依赖:
```bash
sudo apt install ca-certificates curl gnupg lsb-release
```
3. 添加Docker官方GPG密钥
```bash
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
```
4. 添加Docker APT源
```bash
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
5. 更新包列表:
```bash
sudo apt update
```
6. 安装Docker引擎
```bash
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
7. 启动并验证:
```bash
sudo systemctl start docker
sudo systemctl enable docker
sudo docker --version
```
### 安装1Panel
一键安装:
```bash
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
```
查看管理员密码:
```bash
sudo 1pctl user-info
```
### 安装SVN
```bash
sudo apt update
sudo apt install subversion
svn --version # 验证安装
```
## 问题记录
### SSH连接异常
症状SSH服务启动失败出现以下错误
```
error: Bind to port 22 on 0.0.0.0 failed: Address already in use.
fatal: Missing privilege separation directory: /run/sshd
```
解决方法:
1. 检查端口占用:
```bash
sudo lsof -i:22
```
2. 终止占用进程:
```bash
sudo kill <PID>
```
3. 创建缺失目录:
```bash
sudo mkdir -p /run/sshd
sudo chmod 0755 /run/sshd
```
4. 重启SSH服务
```bash
sudo systemctl restart ssh
```
## 常用指令
```powershell
# 列出可用的Linux发行版
wsl --list --online
# 列出已安装的发行版
wsl --list --verbose # 或 wsl -l -v
# 设置WSL版本
wsl --set-version <发行版名称> <版本号>
# 设置默认WSL版本
wsl --set-default-version <版本号>
# 设置默认Linux发行版
wsl --set-default <发行版名称>
# 运行特定发行版
wsl --distribution <发行版名称> --user <用户名>
# 更新WSL
wsl --update
# 检查WSL状态
wsl --status
# 检查WSL版本
wsl --version
# 以特定用户身份运行
wsl --user <用户名>
# 卸载Linux发行版
wsl --unregister <发行版名称>
# 标识IP地址
wsl hostname -I # 返回WSL2 IP地址
ip route show | grep -i default | awk '{ print $3}' # 返回Windows主机IP
# 更改默认用户
<发行版名称> config --default-user <用户名>
```
## 实用软件安装
### 安装适用于 Linux 的 Google Chrome
```bash
cd /tmp
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install --fix-missing ./google-chrome-stable_current_amd64.deb
```
启动命令:`google-chrome`
### 安装 VLC
```bash
sudo apt install vlc -y
```
启动命令:`vlc`
### 安装 X11 应用
```bash
sudo apt install x11-apps -y
```
启动命令示例:`xcalc`、`xclock`、`xeyes`
------
通过本文的配置指南你可以构建一个功能完善的WSL2环境满足日常开发、学习和娱乐需求。WSL2的灵活性使得Windows用户无需切换操作系统就能享受Linux的强大功能是开发人员的理想工具。

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

View File

@ -0,0 +1,190 @@
---
icon: bi:arrows-expand
date: 2025-05-08
category:
- 实用工具
tag:
- gitee
- 码云
title: Gitee SSH
---
在Gitee上设置SSH公钥完整指南
<!-- more -->
# 在Gitee上设置SSH公钥完整指南
## 引言
在使用Git进行代码管理时SSH协议为开发者提供了一种安全且便捷的仓库访问方式。相比HTTPS协议SSH协议不需要每次操作都输入用户名和密码大大提高了开发效率。对于经常使用Gitee平台的Java开发者来说正确配置SSH公钥是日常工作流程中的重要一环。本文将详细介绍如何在Gitee平台上生成并设置SSH公钥帮助您实现更高效的代码管理。
## SSH公钥的基本概念
在深入了解操作步骤前我们先来理解一下SSH公钥认证的基本原理
- SSH认证基于非对称加密包含一对密钥私钥(保存在本地)和公钥(上传至服务器)
- 私钥必须安全保管,不可泄露;公钥则可以自由分享
- 当您使用SSH协议访问仓库时Gitee会验证您的身份确认您是否拥有与已注册公钥匹配的私钥
## 详细操作步骤
### 1. 生成SSH密钥对
首先我们需要生成SSH密钥对。对于Windows用户建议使用**Windows PowerShell**或**Git Bash**执行以下命令注意Windows的命令提示符中没有`cat`和`ls`命令)。
```bash
ssh-keygen -t ed25519 -C "Gitee SSH Key"
```
参数说明:
- `-t`指定密钥类型这里使用更安全的ed25519算法
- `-C`:添加注释,便于识别密钥的用途
执行命令后,系统会提示您输入保存密钥的位置和密码短语。一般情况下,直接按三次回车键即可使用默认设置:
```bash
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/git/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/git/.ssh/id_ed25519
Your public key has been saved in /home/git/.ssh/id_ed25519.pub
```
这样我们就成功生成了两个文件:
- `id_ed25519`:私钥文件(保密,不要分享)
- `id_ed25519.pub`公钥文件需要上传到Gitee
### 2. 获取公钥内容
执行以下命令查看生成的SSH公钥内容
```bash
cat ~/.ssh/id_ed25519.pub
```
命令会输出类似以下格式的公钥内容:
```
ssh-ed25519 AAAA***5B Gitee SSH Key
```
请完整复制这段输出的内容,包括开头的`ssh-ed25519`和末尾的注释`Gitee SSH Key`。
### 3. 将公钥添加到Gitee账户
获取到公钥内容后我们需要将其添加到Gitee账户中
1. 登录Gitee账户点击右上角头像
2. 选择「个人设置」->「安全设置」->「SSH 公钥」
3. 点击「添加公钥」按钮
4. 在表单中填入公钥标题(自定义,方便识别)和公钥内容
5. 输入Gitee账户密码进行验证
6. 点击「添加」按钮完成操作
![添加账户SSH公钥](./assert/sshkeys_create-8409f453e6780ca1a8db3ce33c74240b.png "添加用户SSH公钥")
### 4. 验证SSH连接
添加完成后可以通过以下命令测试SSH连接是否配置成功
```bash
ssh -T git@gitee.com
```
如果配置正确您将看到以下输出其中USERNAME是您的Gitee用户名
```bash
Hi USERNAME! You've successfully authenticated, but GITEE.COM does not provide shell access.
```
看到这个提示就说明SSH公钥已经成功配置您可以开始使用SSH协议来操作Gitee上的仓库了。
## SSH公钥的管理
在Gitee平台上您可以方便地管理已添加的SSH公钥
1. 浏览公钥列表:通过「个人设置」->「安全设置」->「SSH 公钥」页面查看所有已添加的SSH公钥
2. 查看公钥详情:点击具体的公钥可以查看其详细信息
3. 删除公钥当某个SSH公钥不再需要时可以直接删除它
![浏览SSH Key](./assert/sshkeys_list-bff1a324894abbdc3ab8f61c49bb63d5.png "浏览SSH Key")
![查看/删除SSH Key](./assert/sshkeys_show-a14cdfb89475debed237bfded2bd9848.png "查看/删除SSH Key")
## 账户SSH公钥vs仓库SSH公钥
在Gitee平台上存在两种不同类型的SSH公钥理解它们的区别对正确使用Git操作非常重要
### 账户SSH公钥
- 与您的Gitee账户绑定
- 当您的账户对仓库有推送/拉取权限时,可以使用这个公钥进行对应操作
- 验证时会显示您的用户名:`Hi USERNAME! You've successfully authenticated...`
- 适用于日常开发过程中的代码提交、拉取等操作
### 仓库SSH公钥部署公钥
- 仅针对特定仓库,与账户无关
- 仅具有仓库的**拉取**权限,无法进行推送操作
- 验证时显示为匿名用户:`Hi Anonymous! You've successfully authenticated...`
- 主要用于部署环境(如生产服务器)拉取代码,避免在服务器上存储个人账户凭证
> 注意如果您需要设置仓库的部署公钥请参考Gitee帮助文档中的"添加部署公钥"章节。
## 实用技巧与常见问题
### 使用不同的SSH密钥访问不同的Git服务
如果您同时使用多个Git平台如Gitee、GitHub、GitLab等可以为每个平台生成不同的SSH密钥对并在SSH配置文件中指定使用规则。
1. 为不同平台生成不同的密钥,例如:
```bash
ssh-keygen -t ed25519 -C "Gitee" -f ~/.ssh/gitee_id_ed25519
ssh-keygen -t ed25519 -C "GitHub" -f ~/.ssh/github_id_ed25519
```
2. 创建或编辑`~/.ssh/config`文件:
```
# Gitee平台
Host gitee.com
HostName gitee.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/gitee_id_ed25519
# GitHub平台
Host github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/github_id_ed25519
```
### SSH连接故障排查
如果在验证SSH连接时遇到问题可以尝试以下步骤
1. 使用`-v`参数获取详细信息:
```bash
ssh -vT git@gitee.com
```
2. 检查SSH密钥权限Unix/Linux/macOS系统
```bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
```
3. 确认SSH代理正在运行
```bash
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_ed25519
```
## 总结
正确设置和使用SSH公钥对于Java开发者在Gitee平台上进行高效的代码管理至关重要。通过本文介绍的步骤您可以轻松生成SSH密钥对、将公钥添加到Gitee账户并开始使用SSH协议访问您的代码仓库。这不仅提高了安全性还简化了您的日常工作流程避免了重复输入用户名和密码的繁琐过程。
对于团队开发和持续集成/持续部署CI/CD环境了解账户SSH公钥和仓库部署公钥的区别尤为重要这有助于您根据不同场景选择最合适的认证方式确保代码安全的同时提高开发和部署效率。
希望本指南能帮助您在Gitee平台上更加顺畅地使用Git进行项目管理和协作开发。如果在实际操作中遇到任何问题欢迎参考Gitee的官方帮助文档获取更多支持。