移除 SpringBoot JAR 优化指南并添加 Gitee SSH 设置文档
原来的 SpringBoot JAR 优化指南 (SpringBoot打包体积优化) 已被删除,以简化仓库内容。同时,新增了一份全面的指南,帮助开发者设置 Gitee 的 SSH 密钥,以便安全访问仓库。新文档涵盖了使用现代 ed25519 加密标准进行密钥生成、配置和管理。
This commit is contained in:
parent
fbfcfcaae2
commit
deeeb41145
1225
src/programming/java/工具箱/Spring Boot JAR 瘦身与加密.md
Normal file
1225
src/programming/java/工具箱/Spring Boot JAR 瘦身与加密.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -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";
|
|
||||||
/**
|
|
||||||
* 用于标识JAR(Java归档)文件的文件扩展名。
|
|
||||||
* 该常量表示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
|
|
||||||
应用。对于简单应用或开源项目,可能不必使用这么复杂的方案。*
|
|
558
src/programming/java/工具箱/WSL2.md
Normal file
558
src/programming/java/工具箱/WSL2.md
Normal 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 |
190
src/programming/java/工具箱/gitee-ssh.md
Normal file
190
src/programming/java/工具箱/gitee-ssh.md
Normal 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. 点击「添加」按钮完成操作
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 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公钥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的官方帮助文档获取更多支持。
|
Loading…
Reference in New Issue
Block a user